COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/matrix_maps.h @ 2072:224d3781b00b

Last change on this file since 2072:224d3781b00b was 2072:224d3781b00b, checked in by Alpar Juttner, 18 years ago

Create a separate group for matrices

File size: 32.6 KB
Line 
1/* -*- C++ -*-
2 *
3 * This file is a part of LEMON, a generic C++ optimization library
4 *
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 *
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
12 *
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
15 * purpose.
16 *
17 */
18
19#ifndef LEMON_MATRIX_MAPS_H
20#define LEMON_MATRIX_MAPS_H
21
22
23#include <vector>
24#include <lemon/bits/utility.h>
25#include <lemon/maps.h>
26
27#include <lemon/concept/matrix_maps.h>
28
29/// \file
30/// \ingroup matrices
31/// \brief Maps indexed with pairs of items.
32///
33/// \todo This file has the same name as the concept file in concept/,
34///  and this is not easily detectable in docs...
35namespace lemon {
36
37  /// \brief Map for the coloumn view of the matrix
38  ///
39  /// \ingroup matrices
40  /// Map for the coloumn view of the matrix.
41  ///
42  template <typename _MatrixMap>
43  class MatrixRowMap : public MatrixMapTraits<_MatrixMap> {
44  public:
45    typedef _MatrixMap MatrixMap;
46    typedef typename MatrixMap::SecondKey Key;
47    typedef typename MatrixMap::Value Value;
48
49
50    MatrixRowMap(MatrixMap& _matrix, typename MatrixMap::FirstKey _row)
51      : matrix(_matrix), row(_row) {}
52
53    /// \brief Subscription operator
54    ///
55    /// Subscription operator.
56    typename MatrixMapTraits<MatrixMap>::ReturnValue
57    operator[](Key col) {
58      return matrix(row, col);
59    }
60
61    /// \brief Setter function
62    ///
63    /// Setter function.
64    void set(Key col, const Value& val) {
65      matrix.set(row, col, val);
66    }
67     
68    /// \brief Subscription operator
69    ///
70    /// Subscription operator.
71    typename MatrixMapTraits<MatrixMap>::ConstReturnValue
72    operator[](Key col) const {
73      return matrix(row, col);
74    }
75
76  private:
77    MatrixMap& matrix;
78    typename MatrixMap::FirstKey row;
79  };
80
81  /// \brief Map for the row view of the matrix
82  ///
83  /// \ingroup matrices
84  /// Map for the row view of the matrix.
85  ///
86  template <typename _MatrixMap>
87  class ConstMatrixRowMap : public MatrixMapTraits<_MatrixMap> {
88  public:
89    typedef _MatrixMap MatrixMap;
90    typedef typename MatrixMap::SecondKey Key;
91    typedef typename MatrixMap::Value Value;
92
93
94    ConstMatrixRowMap(const MatrixMap& _matrix,
95                      typename MatrixMap::FirstKey _row)
96      : matrix(_matrix), row(_row) {}
97
98    /// \brief Subscription operator
99    ///
100    /// Subscription operator.
101    typename MatrixMapTraits<MatrixMap>::ConstReturnValue
102    operator[](Key col) const {
103      return matrix(row, col);
104    }
105
106  private:
107    const MatrixMap& matrix;
108    typename MatrixMap::FirstKey row;
109  };
110
111  /// \brief Gives back a row view of the matrix map
112  ///
113  /// \ingroup matrices
114  /// Gives back a row view of the matrix map.
115  ///
116  template <typename MatrixMap>
117  MatrixRowMap<MatrixMap> matrixRowMap(MatrixMap& matrixMap,
118                                       typename MatrixMap::FirstKey row) {
119    return MatrixRowMap<MatrixMap>(matrixMap, row);
120  }
121
122  template <typename MatrixMap>
123  ConstMatrixRowMap<MatrixMap>
124  matrixRowMap(const MatrixMap& matrixMap, typename MatrixMap::FirstKey row) {
125    return ConstMatrixRowMap<MatrixMap>(matrixMap, row);
126  }
127
128  /// \brief Map for the column view of the matrix
129  ///
130  /// \ingroup matrices
131  /// Map for the column view of the matrix.
132  ///
133  template <typename _MatrixMap>
134  class MatrixColMap : public MatrixMapTraits<_MatrixMap> {
135  public:
136    typedef _MatrixMap MatrixMap;
137    typedef typename MatrixMap::FirstKey Key;
138    typedef typename MatrixMap::Value Value;
139
140    MatrixColMap(MatrixMap& _matrix, typename MatrixMap::SecondKey _col)
141      : matrix(_matrix), col(_col) {}
142
143    /// \brief Subscription operator
144    ///
145    /// Subscription operator.
146    typename MatrixMapTraits<MatrixMap>::ReturnValue
147    operator[](Key row) {
148      return matrix(row, col);
149    }
150
151    /// \brief Setter function
152    ///
153    /// Setter function.
154    void set(Key row, const Value& val) {
155      matrix.set(row, col, val);
156    }
157     
158    /// \brief Subscription operator
159    ///
160    /// Subscription operator.
161    typename MatrixMapTraits<MatrixMap>::ConstReturnValue
162    operator[](Key row) const {
163      return matrix(row, col);
164    }
165
166  private:
167    MatrixMap& matrix;
168    typename MatrixMap::SecondKey col;
169  };
170
171  /// \brief Map for the column view of the matrix
172  ///
173  /// \ingroup matrices
174  /// Map for the column view of the matrix.
175  ///
176  template <typename _MatrixMap>
177  class ConstMatrixColMap : public MatrixMapTraits<_MatrixMap> {
178  public:
179    typedef _MatrixMap MatrixMap;
180    typedef typename MatrixMap::FirstKey Key;
181    typedef typename MatrixMap::Value Value;
182
183    ConstMatrixColMap(const MatrixMap& _matrix,
184                      typename MatrixMap::SecondKey _col)
185      : matrix(_matrix), col(_col) {}
186
187    /// \brief Subscription operator
188    ///
189    /// Subscription operator.
190    typename MatrixMapTraits<MatrixMap>::ConstReturnValue
191    operator[](Key row) const {
192      return matrix(row, col);
193    }
194
195  private:
196    const MatrixMap& matrix;
197    typename MatrixMap::SecondKey col;
198  };
199
200  /// \brief Gives back a column view of the matrix map
201  ///
202  /// \ingroup matrices
203  /// Gives back a column view of the matrix map.
204  ///
205  template <typename MatrixMap>
206  MatrixColMap<MatrixMap> matrixColMap(MatrixMap& matrixMap,
207                                       typename MatrixMap::SecondKey col) {
208    return MatrixColMap<MatrixMap>(matrixMap, col);
209  }
210
211  template <typename MatrixMap>
212  ConstMatrixColMap<MatrixMap>
213  matrixColMap(const MatrixMap& matrixMap, typename MatrixMap::SecondKey col) {
214    return ConstMatrixColMap<MatrixMap>(matrixMap, col);
215  }
216
217  /// \brief Container for store values for each ordered pair of graph items
218  ///
219  /// \ingroup matrices
220  /// This data structure can strore for each pair of the same item
221  /// type a value. It increase the size of the container when the
222  /// associated graph modified, so it updated automaticly whenever
223  /// it is needed.
224  template <typename _Graph, typename _Item, typename _Value>
225  class DynamicMatrixMap
226    : protected ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
227  public:
228    typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase
229    Parent;
230
231    typedef _Graph Graph;
232    typedef _Item Key;
233
234    typedef _Item FirstKey;
235    typedef _Item SecondKey;
236    typedef _Value Value;
237
238    typedef True ReferenceMapTag;
239
240  private:
241               
242    typedef std::vector<Value> Container;
243
244  public:
245
246    typedef typename Container::reference Reference;
247    typedef typename Container::const_reference ConstReference;
248
249    /// \brief Creates an item matrix for the given graph
250    ///
251    /// Creates an item matrix for the given graph.
252    DynamicMatrixMap(const Graph& _graph)
253      : values(size(_graph.maxId(Key()) + 1)) {
254      Parent::attach(_graph.getNotifier(Key()));
255    }
256
257    /// \brief Creates an item matrix for the given graph
258    ///
259    /// Creates an item matrix for the given graph and assigns for each
260    /// pairs of keys the given parameter.
261    DynamicMatrixMap(const Graph& _graph, const Value& _val)
262      : values(size(_graph.maxId(Key()) + 1), _val) {
263      Parent::attach(_graph.getNotifier(Key()));
264    }
265
266    ///\brief The assignement operator.
267    ///
268    ///It allow to assign a map to an other.
269    DynamicMatrixMap& operator=(const DynamicMatrixMap& _cmap){
270      return operator=<DynamicMatrixMap>(_cmap);
271    }
272     
273    ///\brief Template assignement operator.
274    ///
275    ///It copy the element of the given map to its own container.  The
276    ///type of the two map shall be the same.
277    template <typename CMap>
278    DynamicMatrixMap& operator=(const CMap& _cmap){
279      checkConcept<concept::ReadMatrixMap<FirstKey, SecondKey, Value>, CMap>();
280      typename Parent::Notifier* notifier = Parent::getNotifier();
281      Key first, second;
282      for(notifier->first(first); first != INVALID;
283          notifier->next(first)){
284        for(notifier->first(second); second != INVALID;
285            notifier->next(second)){
286          set(first, second, _cmap(first, second));
287        }
288      }
289      return *this;
290    }
291
292    /// \brief Gives back the value assigned to the \c first - \c second
293    /// ordered pair.
294    ///
295    /// Gives back the value assigned to the \c first - \c second ordered pair.
296    ConstReference operator()(const Key& first, const Key& second) const {
297      return values[index(Parent::getNotifier()->id(first),
298                          Parent::getNotifier()->id(second))];
299    }
300   
301    /// \brief Gives back the value assigned to the \c first - \c second
302    /// ordered pair.
303    ///
304    /// Gives back the value assigned to the \c first - \c second ordered pair.
305    Reference operator()(const Key& first, const Key& second) {
306      return values[index(Parent::getNotifier()->id(first),
307                          Parent::getNotifier()->id(second))];
308    }
309
310    /// \brief Setter function for the matrix map.
311    ///
312    /// Setter function for the matrix map.
313    void set(const Key& first, const Key& second, const Value& val) {
314      values[index(Parent::getNotifier()->id(first),
315                   Parent::getNotifier()->id(second))] = val;
316    }
317
318  protected:
319
320    static int index(int i, int j) {
321      if (i < j) {
322        return j * j + i;
323      } else {
324        return i * i + i + j;
325      }
326    }
327
328    static int size(int s) {
329      return s * s;
330    }
331
332    virtual void add(const Key& key) {
333      if (size(Parent::getNotifier()->id(key) + 1) >= (int)values.size()) {
334        values.resize(size(Parent::getNotifier()->id(key) + 1));       
335      }
336    }
337
338    virtual void erase(const Key&) {}
339
340    virtual void build() {
341      values.resize(size(Parent::getNotifier()->maxId() + 1));
342    }
343
344    virtual void clear() {
345      values.clear();
346    }   
347   
348  private:
349    std::vector<Value> values;
350  };
351
352  /// \brief Container for store values for each unordered pair of graph items
353  ///
354  /// \ingroup matrices
355  /// This data structure can strore for each pair of the same item
356  /// type a value. It increase the size of the container when the
357  /// associated graph modified, so it updated automaticly whenever
358  /// it is needed.
359  template <typename _Graph, typename _Item, typename _Value>
360  class DynamicSymMatrixMap
361    : protected ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
362  public:
363    typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase
364    Parent;
365
366    typedef _Graph Graph;
367    typedef _Item Key;
368
369    typedef _Item FirstKey;
370    typedef _Item SecondKey;
371    typedef _Value Value;
372
373    typedef True ReferenceMapTag;
374
375  private:
376               
377    typedef std::vector<Value> Container;
378
379  public:
380
381    typedef typename Container::reference Reference;
382    typedef typename Container::const_reference ConstReference;
383
384    /// \brief Creates an item matrix for the given graph
385    ///
386    /// Creates an item matrix for the given graph.
387    DynamicSymMatrixMap(const Graph& _graph)
388      : values(size(_graph.maxId(Key()) + 1)) {
389      Parent::attach(_graph.getNotifier(Key()));
390    }
391
392    /// \brief Creates an item matrix for the given graph
393    ///
394    /// Creates an item matrix for the given graph and assigns for each
395    /// pairs of keys the given parameter.
396    DynamicSymMatrixMap(const Graph& _graph, const Value& _val)
397      : values(size(_graph.maxId(Key()) + 1), _val) {
398      Parent::attach(_graph.getNotifier(Key()));
399    }
400
401
402    ///\brief The assignement operator.
403    ///
404    ///It allow to assign a map to an other.
405    ///
406    DynamicSymMatrixMap& operator=(const DynamicSymMatrixMap& _cmap){
407      return operator=<DynamicSymMatrixMap>(_cmap);
408    }
409     
410    ///\brief Template assignement operator.
411    ///
412    ///It copy the element of the given map to its own container.  The
413    ///type of the two map shall be the same.
414    template <typename CMap>
415    DynamicSymMatrixMap& operator=(const CMap& _cmap){
416      checkConcept<concept::ReadMatrixMap<FirstKey, SecondKey, Value>, CMap>();
417      typename Parent::Notifier* notifier = Parent::getNotifier();
418      Key first, second;
419      for(notifier->first(first); first != INVALID;
420          notifier->next(first)){
421        for(notifier->first(second); second != first;
422            notifier->next(second)){
423          set(first, second, _cmap(first, second));
424        }
425        set(first, first, _cmap(first, first));       
426      }
427      return *this;
428    }
429
430    /// \brief Gives back the value assigned to the \c first - \c second
431    /// unordered pair.
432    ///
433    /// Gives back the value assigned to the \c first - \c second unordered
434    /// pair.
435    ConstReference operator()(const Key& first, const Key& second) const {
436      return values[index(Parent::getNotifier()->id(first),
437                          Parent::getNotifier()->id(second))];
438    }
439   
440    /// \brief Gives back the value assigned to the \c first - \c second
441    /// unordered pair.
442    ///
443    /// Gives back the value assigned to the \c first - \c second unordered
444    /// pair.
445    Reference operator()(const Key& first, const Key& second) {
446      return values[index(Parent::getNotifier()->id(first),
447                          Parent::getNotifier()->id(second))];
448    }
449
450    /// \brief Setter function for the matrix map.
451    ///
452    /// Setter function for the matrix map.
453    ///
454    void set(const Key& first, const Key& second, const Value& val) {
455      values[index(Parent::getNotifier()->id(first),
456                   Parent::getNotifier()->id(second))] = val;
457    }
458
459  protected:
460
461    static int index(int i, int j) {
462      if (i < j) {
463        return j * (j + 1) / 2 + i;
464      } else {
465        return i * (i + 1) / 2 + j;
466      }
467    }
468
469    static int size(int s) {
470      return s * (s + 1) / 2;
471    }
472
473    virtual void add(const Key& key) {
474      if (size(Parent::getNotifier()->id(key) + 1) >= (int)values.size()) {
475        values.resize(size(Parent::getNotifier()->id(key) + 1));       
476      }
477    }
478
479    virtual void erase(const Key&) {}
480
481    virtual void build() {
482      values.resize(size(Parent::getNotifier()->maxId() + 1));
483    }
484
485    virtual void clear() {
486      values.clear();
487    }   
488   
489  private:
490    std::vector<Value> values;
491  };
492 
493  ///\brief Dynamic Asymmetric Matrix Map.
494  ///
495  ///\ingroup matrices
496  ///Dynamic Asymmetric Matrix Map.  Container for store values for each
497  ///ordered pair of containers items.  This data structure can store
498  ///data with different key types from different container types. It
499  ///increases the size of the container if the linked containers
500  ///content change, so it is updated automaticly whenever it is
501  ///needed.
502  ///
503  ///This map meet with the concept::ReferenceMatrixMap<typename K1,
504  ///typename K2, typename V, typename R, typename CR> called as
505  ///"ReferenceMatrixMap".
506  ///
507  ///\param _FirstContainer the desired type of first container. It is
508  ///ususally a Graph type, but can be any type with alteration
509  ///property.
510  /// 
511  ///\param _FirstContainerItem the nested type of the
512  ///FirstContainer. It is usually a graph item as Node, Edge,
513  ///etc. This type will be the FirstKey type.
514  ///
515  ///\param _SecondContainer the desired type of the second
516  ///container. It is usualy a Graph type, but can be any type with
517  ///alteration property.
518  ///
519  ///\param _SecondContainerItem the nested type of the
520  ///SecondContainer. It is usually a graph item such as Node, Edge,
521  ///UEdge, etc. This type will be the SecondKey type.
522  ///
523  ///\param _Value the type of the strored values in the container.
524  ///
525  /// \author Janos Nagy
526  template <typename _FirstContainer, typename _FirstContainerItem,
527            typename _SecondContainer, typename _SecondContainerItem,
528            typename _Value>
529  class DynamicAsymMatrixMap{
530  public:
531
532    ///The first key type.
533    typedef _FirstContainerItem FirstKey;
534     
535    ///The second key type.
536    typedef _SecondContainerItem SecondKey;
537     
538    ///The value type of the map.
539    typedef _Value Value;
540     
541    ///Indicates it is a reference map.
542    typedef True ReferenceMapTag;
543   
544  protected:
545     
546    ///\brief Proxy class for the first key type.
547    ///
548    ///The proxy class belongs to the FirstKey type. It is necessary because
549    ///if one want use the same conatainer types and same nested types but on
550    ///other instances of containers than due to the type equiality of nested
551    ///types it requires a proxy mechanism.
552    class FirstKeyProxy
553      : protected
554    ItemSetTraits<_FirstContainer,_FirstContainerItem>::
555    ItemNotifier::ObserverBase
556    {
557       
558    public:
559
560      friend class DynamicAsymMatrixMap;
561         
562      ///Constructor.
563      FirstKeyProxy(DynamicAsymMatrixMap& _map) : _owner(_map) { }
564    protected:
565
566      ///\brief Add a new FirstKey to the map.
567      ///
568      ///It adds a new FirstKey to the map. It is called by the
569      ///observer notifier and it is ovverride the add() virtual
570      ///member function in the observer base. It will call the
571      ///maps addFirstKey() function.
572      virtual void add(const FirstKey& _firstKey){
573        _owner.addFirstKey(_firstKey);
574      }
575         
576      ///\brief Add more new FirstKey to the map.
577      ///
578      ///It adds more new FirstKey to the map. It is called by the
579      ///observer notifier and it is ovverride the add() virtual
580      ///member function in the observer base. It will call the
581      ///map's addFirstKeys() function.
582      virtual void add(const std::vector<FirstKey>& _firstKeys){
583        _owner.addFirstKeys(_firstKeys);
584      }
585         
586      ///\brief Erase a FirstKey from the map.
587      ///
588      ///Erase a FirstKey from the map. It called by the observer
589      ///notifier and it overrides the erase() virtual member
590      ///function of the observer base. It will call the map's
591      ///eraseFirstKey() function.
592      virtual void erase(const FirstKey& _firstKey){
593        _owner.eraseFirstKey(_firstKey);
594      }
595         
596      ///\brief Erase more FirstKey from the map.
597      ///
598      ///Erase more FirstKey from the map. It called by the
599      ///observer notifier and it overrides the erase() virtual
600      ///member function of the observer base. It will call the
601      ///map's eraseFirstKeys() function.
602      virtual void erase(const std::vector<FirstKey>& _firstKeys){
603        _owner.eraseFirstKeys(_firstKeys);
604      }
605         
606      ///\brief Builds the map.
607      ///
608      ///It buildes the map. It called by the observer notifier
609      ///and it overrides the build() virtual member function of
610      ///the observer base.  It will call the map's build()
611      ///function.
612      virtual void build() {
613        _owner.build();
614        //_owner.buildFirst();
615      }
616         
617      ///\brief Clear the map.
618      ///
619      ///It erases all items from the map. It called by the
620      ///observer notifier and it overrides the clear() virtual
621      ///memeber function of the observer base. It will call the
622      ///map's clear() function.
623      virtual void clear() {
624        _owner.clear();
625        //_owner.clearFirst();
626      }
627    private:
628         
629      ///The map type for it is linked.
630      DynamicAsymMatrixMap& _owner;
631    };//END OF FIRSTKEYPROXY
632     
633      ///\brief Proxy class for the second key type.
634      ///
635      ///The proxy class belongs to the SecondKey type. It is
636      ///necessary because if one want use the same conatainer types
637      ///and same nested types but on other instances of containers
638      ///than due to the type equiality of nested types it requires a
639      ///proxy mechanism.
640    class SecondKeyProxy
641      : protected
642    ItemSetTraits<_SecondContainer, _SecondContainerItem>::
643    ItemNotifier::ObserverBase {
644       
645    public:
646
647      friend class DynamicAsymMatrixMap;
648      ///Constructor.
649      SecondKeyProxy(DynamicAsymMatrixMap& _map) : _owner(_map) { }
650
651    protected:
652         
653      ///\brief Add a new SecondKey to the map.
654      ///
655      ///It adds a new SecondKey to the map. It is called by the
656      ///observer notifier and it is ovverride the add() virtual
657      ///member function in the observer base. It will call the
658      ///maps addSecondKey() function.
659      virtual void add(const SecondKey& _secondKey){
660        _owner.addSecondKey(_secondKey);
661      }
662   
663      ///\brief Add more new SecondKey to the map.
664      ///
665      ///It adds more new SecondKey to the map. It is called by
666      ///the observer notifier and it is ovverride the add()
667      ///virtual member function in the observer base. It will
668      ///call the maps addSecondKeys() function.
669      virtual void add(const std::vector<SecondKey>& _secondKeys){
670        _owner.addSecondKeys(_secondKeys);
671      }
672         
673      ///\brief Erase a SecondKey from the map.
674      ///
675      ///Erase a SecondKey from the map. It called by the observer
676      ///notifier and it overrides the erase() virtual member
677      ///function of the observer base. It will call the map's
678      ///eraseSecondKey() function.
679      virtual void erase(const SecondKey& _secondKey){
680        _owner.eraseSecondKey(_secondKey);
681      }
682         
683      ///\brief Erase more SecondKeys from the map.
684      ///
685      ///Erase more SecondKey from the map. It called by the
686      ///observer notifier and it overrides the erase() virtual
687      ///member function of the observer base. It will call the
688      ///map's eraseSecondKeys() function.
689      virtual void erase(const std::vector<SecondKey>& _secondKeys){
690        _owner.eraseSecondKeys(_secondKeys);
691      }
692         
693      ///\brief Builds the map.
694      ///
695      ///It buildes the map. It called by the observer notifier
696      ///and it overrides the build() virtual member function of
697      ///the observer base.  It will call the map's build()
698      ///function.
699      virtual void build() {
700        _owner.build();
701      }
702         
703      ///\brief Clear the map.
704      ///
705      ///It erases all items from the map. It called by the
706      ///observer notifier and it overrides the clear() virtual
707      ///memeber function of the observer base. It will call the
708      ///map's clear() function.
709      virtual void clear() {
710        _owner.clear();
711        //_owner.clearFirst();
712      }
713    private:
714         
715      ///The type of map for which it is attached.
716      DynamicAsymMatrixMap& _owner;
717    };//END OF SECONDKEYPROXY
718     
719  private:
720   
721    /// \e
722    typedef std::vector<Value> Container;
723     
724    ///The type of constainer which stores the values of the map.
725    typedef std::vector<Container> DContainer;
726
727    ///The std:vector type which contains the data
728    DContainer values;
729     
730    ///Member for the first proxy class
731    FirstKeyProxy _first_key_proxy;
732     
733    ///Member for the second proxy class
734    SecondKeyProxy _second_key_proxy;
735
736  public:
737   
738    ///The refernce type of the map.
739    typedef typename Container::reference Reference;
740     
741    ///The const reference type of the constainer.
742    typedef typename Container::const_reference ConstReference;
743
744    ///\brief Constructor what create the map for the two containers type.
745    ///
746    ///Creates the matrix map and initialize the values with Value()
747    DynamicAsymMatrixMap(const _FirstContainer& _firstContainer,
748                  const _SecondContainer& _secondContainer)
749      : values(DContainer(_firstContainer.maxId(FirstKey())+1,
750                          Container(_secondContainer.maxId(SecondKey())+1))),
751        _first_key_proxy(*this),
752        _second_key_proxy(*this)
753    {
754      _first_key_proxy.attach(_firstContainer.getNotifier(FirstKey()));
755      _second_key_proxy.attach(_secondContainer.getNotifier(SecondKey()));
756    }
757
758    ///\brief Constructor what create the map for the two containers type.
759    ///
760    ///Creates the matrix map and initialize the values with the given _value
761    DynamicAsymMatrixMap(const _FirstContainer& _firstContainer,
762                  const _SecondContainer& _secondContainer,
763                  const Value& _value)
764      : values(DContainer(_firstContainer.maxId(FirstKey())+1,
765                          Container(_secondContainer.maxId(SecondKey())+1,
766                                    _value))),
767        _first_key_proxy(*this),
768        _second_key_proxy(*this)
769    {
770      _first_key_proxy.attach(_firstContainer.getNotifier(FirstKey()));
771      _second_key_proxy.attach(_secondContainer.getNotifier(SecondKey()));
772    }
773     
774    ///\brief Copy constructor.
775    ///
776    ///The copy constructor of the map.
777    DynamicAsymMatrixMap(const DynamicAsymMatrixMap& _copy)
778      : _first_key_proxy(*this), _second_key_proxy(*this) {
779      if(_copy._first_key_proxy.attached() &&
780         _copy._second_key_proxy.attached()){
781        _first_key_proxy.attach(*_copy._first_key_proxy.getNotifier());
782        _second_key_proxy.attach(*_copy._second_key_proxy.getNotifier());
783        values = _copy.values;
784      }
785    }
786     
787    ///\brief Destructor
788    ///
789    ///Destructor what detach() from the attached objects.  May this
790    ///function is not necessary because the destructor of
791    ///ObserverBase do the same.
792    ~DynamicAsymMatrixMap() {
793      if(_first_key_proxy.attached()){
794        _first_key_proxy.detach();
795      }
796      if(_second_key_proxy.attached()){
797        _second_key_proxy.detach();
798      }
799    }
800     
801    ///\brief Gives back the value assigned to the \c first - \c
802    ///second ordered pair.
803    ///
804    ///Gives back the value assigned to the \c first - \c second
805    ///ordered pair.
806    Reference operator()(const FirstKey& _first, const SecondKey& _second) {
807      return values[_first_key_proxy.getNotifier()->id(_first)]
808        [_second_key_proxy.getNotifier()->id(_second)];
809    }
810
811    ///\brief Gives back the value assigned to the \c first - \c
812    ///second ordered pair.
813    ///
814    ///Gives back the value assigned to the \c first - \c second
815    ///ordered pair.
816    ConstReference operator()(const FirstKey& _first,
817                              const SecondKey& _second) const {
818      return values[_first_key_proxy.getNotifier()->id(_first)]
819        [_second_key_proxy.getNotifier()->id(_second)];
820    }
821
822    ///\brief Setter function for this matrix map.
823    ///
824    ///Setter function for this matrix map.
825    void set(const FirstKey& first, const SecondKey& second,
826             const Value& value){
827      values[_first_key_proxy.getNotifier()->id(first)]
828        [_second_key_proxy.getNotifier()->id(second)] = value;
829    }
830
831    ///\brief The assignement operator.
832    ///
833    ///It allow to assign a map to an other. It
834    DynamicAsymMatrixMap& operator=(const DynamicAsymMatrixMap& _cmap){
835      return operator=<DynamicAsymMatrixMap>(_cmap);
836    }
837     
838    ///\brief Template assignement operator.
839    ///
840    ///It copy the element of the given map to its own container.  The
841    ///type of the two map shall be the same.
842    template <typename CMap>
843    DynamicAsymMatrixMap& operator=(const CMap& _cdmap){
844      checkConcept<concept::ReadMatrixMap<FirstKey, SecondKey, Value>, CMap>();
845      const typename FirstKeyProxy::Notifier* notifierFirstKey =
846        _first_key_proxy.getNotifier();
847      const typename SecondKeyProxy::Notifier* notifierSecondKey =
848        _second_key_proxy.getNotifier();
849      FirstKey itemFirst;
850      SecondKey itemSecond;
851      for(notifierFirstKey->first(itemFirst); itemFirst != INVALID;
852          notifierFirstKey->next(itemFirst)){
853        for(notifierSecondKey->first(itemSecond); itemSecond != INVALID;
854            notifierSecondKey->next(itemSecond)){
855          set(itemFirst, itemSecond, _cdmap(itemFirst,itemSecond));
856        }
857      }
858      return *this;
859    }
860     
861  protected:
862   
863    ///\brief Add a new FirstKey to the map.
864    ///
865    ///It adds a new FirstKey to the map. It is called by the observer
866    ///class belongs to the FirstKey type.
867    void addFirstKey(const FirstKey& firstKey) {
868      int size = (int)values.size();
869      if( _first_key_proxy.getNotifier()->id(firstKey)+1 >= size ){
870        values.resize(_first_key_proxy.getNotifier()->id(firstKey)+1);
871        if( (int)values[0].size() != 0 ){
872          int innersize = (int)values[0].size();
873          for(int i=size; i!=(int)values.size();++i){
874            (values[i]).resize(innersize);
875          }
876        }else if(_second_key_proxy.getNotifier()->maxId() >= 0){
877          int innersize = _second_key_proxy.getNotifier()->maxId();
878          for(int i = 0; i != (int)values.size(); ++i){
879            values[0].resize(innersize);
880          }
881        }
882      }
883    }
884
885    ///\brief Adds more new FirstKeys to the map.
886    ///
887    ///It adds more new FirstKeys to the map. It called by the
888    ///observer class belongs to the FirstKey type.
889    void addFirstKeys(const std::vector<FirstKey>& firstKeys){
890      int max = values.size() - 1;
891      for(int i=0; i != (int)firstKeys.size(); ++i){
892        int id = _first_key_proxy.getNotifier()->id(firstKeys[i]);
893        if(max < id){
894          max = id;
895        }
896      }
897      int size = (int)values.size();
898      if(max >= size){
899        values.resize(max + 1);
900        if( (int)values[0].size() != 0){
901          int innersize = (int)values[0].size();
902          for(int i = size; i != (max + 1); ++i){
903            values[i].resize(innersize);
904          }
905        }else if(_second_key_proxy.getNotifier()->maxId() >= 0){
906          int innersize = _second_key_proxy.getNotifier()->maxId();
907          for(int i = 0; i != (int)values.size(); ++i){
908            values[i].resize(innersize);
909          }
910        }
911      }
912    }
913
914    ///\brief Add a new SecondKey to the map.
915    ///
916    ///It adds a new SecondKey to the map. It is called by the
917    ///observer class belongs to the SecondKey type.
918    void addSecondKey(const SecondKey& secondKey) {
919      if(values.size() == 0){
920        return;
921      }
922      int id = _second_key_proxy.getNotifier()->id(secondKey);
923      if(id >= (int)values[0].size()){
924        for(int i=0;i!=(int)values.size();++i){
925          values[i].resize(id+1);
926        }
927      }
928    }
929       
930    ///\brief Adds more new SecondKeys to the map.
931    ///
932    ///It adds more new SecondKeys to the map. It called by the
933    ///observer class belongs to the SecondKey type.
934    void addSecondKeys(const std::vector<SecondKey>& secondKeys){
935      if(values.size() == 0){
936        return;
937      }
938      int max = values[0].size();
939      for(int i = 0; i != (int)secondKeys.size(); ++i){
940        int id = _second_key_proxy.getNotifier()->id(secondKeys[i]);
941        if(max < id){
942          max = id;
943        }
944      }
945      if(max > (int)values[0].size()){
946        for(int i = 0; i != (int)values.size(); ++i){
947          values[i].resize(max + 1);
948        }
949      }
950    }
951   
952    ///\brief Erase a FirstKey from the map.
953    ///
954    ///Erase a FirstKey from the map. It called by the observer
955    ///class belongs to the FirstKey type.
956    void eraseFirstKey(const FirstKey& first) {
957      int id = _first_key_proxy.getNotifier()->id(first);
958      for(int i = 0; i != (int)values[id].size(); ++i){
959        values[id][i] = Value();
960      }
961    }
962       
963    ///\brief Erase more FirstKey from the map.
964    ///
965    ///Erase more FirstKey from the map. It called by the observer
966    ///class belongs to the FirstKey type.
967    void eraseFirstKeys(const std::vector<FirstKey>& firstKeys) {
968      for(int j = 0; j != (int)firstKeys.size(); ++j){
969        int id = _first_key_proxy.getNotifier()->id(firstKeys[j]);
970        for(int i = 0; i != (int)values[id].size(); ++i){
971          values[id][i] = Value();
972        }
973      }
974    }
975
976    ///\brief Erase a SecondKey from the map.
977    ///
978    ///Erase a SecondKey from the map. It called by the observer class
979    ///belongs to the SecondKey type.
980    void eraseSecondKey(const SecondKey& second) {
981      if(values.size() == 0){
982        return;
983      }
984      int id = _second_key_proxy.getNotifier()->id(second);
985      for(int i = 0; i != (int)values.size(); ++i){
986        values[i][id] = Value();
987      }
988    }
989       
990    ///\brief Erase more SecondKey from the map.
991    ///
992    ///Erase more SecondKey from the map. It called by the observer
993    ///class belongs to the SecondKey type.
994    void eraseSecondKeys(const std::vector<SecondKey>& secondKeys) {
995      if(values.size() == 0){
996        return;
997      }
998      for(int j = 0; j != (int)secondKeys.size(); ++j){
999        int id = _second_key_proxy.getNotifier()->id(secondKeys[j]);
1000        for(int i = 0; i != (int)values.size(); ++i){
1001          values[i][id] = Value();
1002        }
1003      }
1004    }
1005
1006    ///\brief Builds the map.
1007    ///
1008    ///It buildes the map. It is called by the observer class belongs
1009    ///to the FirstKey or SecondKey type.
1010    void build() {
1011      values.resize(_first_key_proxy.getNotifier()->maxId());
1012      for(int i=0; i!=(int)values.size(); ++i){
1013        values[i].resize(_second_key_proxy.getNotifier()->maxId());
1014      }
1015    }
1016   
1017    ///\brief Clear the map.
1018    ///
1019    ///It erases all items from the map. It is called by the observer class
1020    ///belongs to the FirstKey or SecondKey type.
1021    void clear() {
1022      for(int i=0; i!=(int)values.size(); ++i) {
1023        values[i].clear();
1024      }
1025      values.clear();
1026    }
1027 
1028  };
1029
1030
1031
1032}
1033
1034#endif
Note: See TracBrowser for help on using the repository browser.