COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/matrix_maps.h @ 2116:b6a68c15a6a3

Last change on this file since 2116:b6a68c15a6a3 was 2088:68f8d17ced51, checked in by Alpar Juttner, 18 years ago

Fix Bug #45: Missing include

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