COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/matrix_maps.h @ 2085:1970a93dfaa8

Last change on this file since 2085:1970a93dfaa8 was 2084:59769591eb60, checked in by Balazs Dezso, 14 years ago

Documentation improvements

Rearrangements:

IO modules
Algorithms

New documentation:

SwapBpUGraphAdaptor

Demos:

strongly_connected_orientation.cc

Benchmarks:

swap_bipartite_bench.cc

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