COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/matrix_maps.h @ 2305:4a2236cc98a0

Last change on this file since 2305:4a2236cc98a0 was 2305:4a2236cc98a0, checked in by Balazs Dezso, 13 years ago

Keeping order of alteration observers

Removing some automatic callback generation
exception safety reason

File size: 34.0 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/concepts/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 concepts/,
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<concepts::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 add(const std::vector<Key>& keys) {
358      int new_size = 0;
359      for (int i = 0; i < (int)keys.size(); ++i) {
360        if (size(Parent::getNotifier()->id(keys[i]) + 1) >= new_size) {
361          new_size = size(Parent::getNotifier()->id(keys[i]) + 1);     
362        }
363      }
364      if (new_size > (int)values.size()) {
365        values.resize(new_size);
366      }
367    }
368
369    virtual void erase(const Key&) {}
370
371    virtual void erase(const std::vector<Key>&) {}
372
373    virtual void build() {
374      values.resize(size(Parent::getNotifier()->maxId() + 1));
375    }
376
377    virtual void clear() {
378      values.clear();
379    }   
380   
381  private:
382    std::vector<Value> values;
383  };
384
385  /// \brief Container for store values for each unordered pair of graph items
386  ///
387  /// \ingroup matrices
388  /// This data structure can strore for each pair of the same item
389  /// type a value. It increase the size of the container when the
390  /// associated graph modified, so it updated automaticly whenever
391  /// it is needed.
392  template <typename _Graph, typename _Item, typename _Value>
393  class DynamicSymMatrixMap
394    : protected ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
395  public:
396    typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase
397    Parent;
398
399    typedef _Graph Graph;
400    typedef _Item Key;
401
402    typedef _Item FirstKey;
403    typedef _Item SecondKey;
404    typedef _Value Value;
405
406    typedef True ReferenceMapTag;
407
408  private:
409               
410    typedef std::vector<Value> Container;
411
412  public:
413
414    typedef typename Container::reference Reference;
415    typedef typename Container::const_reference ConstReference;
416
417    /// \brief Creates an item matrix for the given graph
418    ///
419    /// Creates an item matrix for the given graph.
420    DynamicSymMatrixMap(const Graph& _graph)
421      : values(size(_graph.maxId(Key()) + 1)) {
422      Parent::attach(_graph.getNotifier(Key()));
423    }
424
425    /// \brief Creates an item matrix for the given graph
426    ///
427    /// Creates an item matrix for the given graph and assigns for each
428    /// pairs of keys the given parameter.
429    DynamicSymMatrixMap(const Graph& _graph, const Value& _val)
430      : values(size(_graph.maxId(Key()) + 1), _val) {
431      Parent::attach(_graph.getNotifier(Key()));
432    }
433
434
435    ///\brief The assignement operator.
436    ///
437    ///It allow to assign a map to an other.
438    ///
439    DynamicSymMatrixMap& operator=(const DynamicSymMatrixMap& _cmap){
440      return operator=<DynamicSymMatrixMap>(_cmap);
441    }
442     
443    ///\brief Template assignement operator.
444    ///
445    ///It copy the element of the given map to its own container.  The
446    ///type of the two map shall be the same.
447    template <typename CMap>
448    DynamicSymMatrixMap& operator=(const CMap& _cmap){
449      checkConcept<concepts::ReadMatrixMap<FirstKey, SecondKey, Value>, CMap>();
450      typename Parent::Notifier* notifier = Parent::getNotifier();
451      Key first, second;
452      for(notifier->first(first); first != INVALID;
453          notifier->next(first)){
454        for(notifier->first(second); second != first;
455            notifier->next(second)){
456          set(first, second, _cmap(first, second));
457        }
458        set(first, first, _cmap(first, first));       
459      }
460      return *this;
461    }
462
463    /// \brief Gives back the value assigned to the \c first - \c second
464    /// unordered pair.
465    ///
466    /// Gives back the value assigned to the \c first - \c second unordered
467    /// pair.
468    ConstReference operator()(const Key& first, const Key& second) const {
469      return values[index(Parent::getNotifier()->id(first),
470                          Parent::getNotifier()->id(second))];
471    }
472   
473    /// \brief Gives back the value assigned to the \c first - \c second
474    /// unordered pair.
475    ///
476    /// Gives back the value assigned to the \c first - \c second unordered
477    /// pair.
478    Reference operator()(const Key& first, const Key& second) {
479      return values[index(Parent::getNotifier()->id(first),
480                          Parent::getNotifier()->id(second))];
481    }
482
483    /// \brief Setter function for the matrix map.
484    ///
485    /// Setter function for the matrix map.
486    ///
487    void set(const Key& first, const Key& second, const Value& val) {
488      values[index(Parent::getNotifier()->id(first),
489                   Parent::getNotifier()->id(second))] = val;
490    }
491
492  protected:
493
494    static int index(int i, int j) {
495      if (i < j) {
496        return j * (j + 1) / 2 + i;
497      } else {
498        return i * (i + 1) / 2 + j;
499      }
500    }
501
502    static int size(int s) {
503      return s * (s + 1) / 2;
504    }
505
506    virtual void add(const Key& key) {
507      if (size(Parent::getNotifier()->id(key) + 1) >= (int)values.size()) {
508        values.resize(size(Parent::getNotifier()->id(key) + 1));       
509      }
510    }
511
512    virtual void add(const std::vector<Key>& keys) {
513      int new_size = 0;
514      for (int i = 0; i < (int)keys.size(); ++i) {
515        if (size(Parent::getNotifier()->id(keys[i]) + 1) >= new_size) {
516          new_size = size(Parent::getNotifier()->id(keys[i]) + 1);     
517        }
518      }
519      if (new_size > (int)values.size()) {
520        values.resize(new_size);
521      }
522    }
523
524    virtual void erase(const Key&) {}
525
526    virtual void erase(const std::vector<Key>&) {}
527
528    virtual void build() {
529      values.resize(size(Parent::getNotifier()->maxId() + 1));
530    }
531
532    virtual void clear() {
533      values.clear();
534    }   
535   
536  private:
537    std::vector<Value> values;
538  };
539 
540  ///\brief Dynamic Asymmetric Matrix Map.
541  ///
542  ///\ingroup matrices
543  ///Dynamic Asymmetric Matrix Map.  Container for store values for each
544  ///ordered pair of containers items.  This data structure can store
545  ///data with different key types from different container types. It
546  ///increases the size of the container if the linked containers
547  ///content change, so it is updated automaticly whenever it is
548  ///needed.
549  ///
550  ///This map meet with the concepts::ReferenceMatrixMap<typename K1,
551  ///typename K2, typename V, typename R, typename CR> called as
552  ///"ReferenceMatrixMap".
553  ///
554  ///\param _FirstContainer the desired type of first container. It is
555  ///ususally a Graph type, but can be any type with alteration
556  ///property.
557  /// 
558  ///\param _FirstContainerItem the nested type of the
559  ///FirstContainer. It is usually a graph item as Node, Edge,
560  ///etc. This type will be the FirstKey type.
561  ///
562  ///\param _SecondContainer the desired type of the second
563  ///container. It is usualy a Graph type, but can be any type with
564  ///alteration property.
565  ///
566  ///\param _SecondContainerItem the nested type of the
567  ///SecondContainer. It is usually a graph item such as Node, Edge,
568  ///UEdge, etc. This type will be the SecondKey type.
569  ///
570  ///\param _Value the type of the strored values in the container.
571  ///
572  /// \author Janos Nagy
573  template <typename _FirstContainer, typename _FirstContainerItem,
574            typename _SecondContainer, typename _SecondContainerItem,
575            typename _Value>
576  class DynamicAsymMatrixMap{
577  public:
578
579    ///The first key type.
580    typedef _FirstContainerItem FirstKey;
581     
582    ///The second key type.
583    typedef _SecondContainerItem SecondKey;
584     
585    ///The value type of the map.
586    typedef _Value Value;
587     
588    ///Indicates it is a reference map.
589    typedef True ReferenceMapTag;
590   
591  protected:
592     
593    ///\brief Proxy class for the first key type.
594    ///
595    ///The proxy class belongs to the FirstKey type. It is necessary because
596    ///if one want use the same conatainer types and same nested types but on
597    ///other instances of containers than due to the type equiality of nested
598    ///types it requires a proxy mechanism.
599    class FirstKeyProxy
600      : protected
601    ItemSetTraits<_FirstContainer,_FirstContainerItem>::
602    ItemNotifier::ObserverBase
603    {
604       
605    public:
606
607      friend class DynamicAsymMatrixMap;
608         
609      ///Constructor.
610      FirstKeyProxy(DynamicAsymMatrixMap& _map) : _owner(_map) { }
611    protected:
612
613      ///\brief Add a new FirstKey to the map.
614      ///
615      ///It adds a new FirstKey to the map. It is called by the
616      ///observer notifier and it is ovverride the add() virtual
617      ///member function in the observer base. It will call the
618      ///maps addFirstKey() function.
619      virtual void add(const FirstKey& _firstKey){
620        _owner.addFirstKey(_firstKey);
621      }
622         
623      ///\brief Add more new FirstKey to the map.
624      ///
625      ///It adds more new FirstKey to the map. It is called by the
626      ///observer notifier and it is ovverride the add() virtual
627      ///member function in the observer base. It will call the
628      ///map's addFirstKeys() function.
629      virtual void add(const std::vector<FirstKey>& _firstKeys){
630        _owner.addFirstKeys(_firstKeys);
631      }
632         
633      ///\brief Erase a FirstKey from the map.
634      ///
635      ///Erase a FirstKey from the map. It called by the observer
636      ///notifier and it overrides the erase() virtual member
637      ///function of the observer base. It will call the map's
638      ///eraseFirstKey() function.
639      virtual void erase(const FirstKey& _firstKey){
640        _owner.eraseFirstKey(_firstKey);
641      }
642         
643      ///\brief Erase more FirstKey from the map.
644      ///
645      ///Erase more FirstKey from the map. It called by the
646      ///observer notifier and it overrides the erase() virtual
647      ///member function of the observer base. It will call the
648      ///map's eraseFirstKeys() function.
649      virtual void erase(const std::vector<FirstKey>& _firstKeys){
650        _owner.eraseFirstKeys(_firstKeys);
651      }
652         
653      ///\brief Builds the map.
654      ///
655      ///It buildes the map. It called by the observer notifier
656      ///and it overrides the build() virtual member function of
657      ///the observer base.  It will call the map's build()
658      ///function.
659      virtual void build() {
660        _owner.build();
661        //_owner.buildFirst();
662      }
663         
664      ///\brief Clear the map.
665      ///
666      ///It erases all items from the map. It called by the
667      ///observer notifier and it overrides the clear() virtual
668      ///memeber function of the observer base. It will call the
669      ///map's clear() function.
670      virtual void clear() {
671        _owner.clear();
672        //_owner.clearFirst();
673      }
674    private:
675         
676      ///The map type for it is linked.
677      DynamicAsymMatrixMap& _owner;
678    };//END OF FIRSTKEYPROXY
679     
680      ///\brief Proxy class for the second key type.
681      ///
682      ///The proxy class belongs to the SecondKey type. It is
683      ///necessary because if one want use the same conatainer types
684      ///and same nested types but on other instances of containers
685      ///than due to the type equiality of nested types it requires a
686      ///proxy mechanism.
687    class SecondKeyProxy
688      : protected
689    ItemSetTraits<_SecondContainer, _SecondContainerItem>::
690    ItemNotifier::ObserverBase {
691       
692    public:
693
694      friend class DynamicAsymMatrixMap;
695      ///Constructor.
696      SecondKeyProxy(DynamicAsymMatrixMap& _map) : _owner(_map) { }
697
698    protected:
699         
700      ///\brief Add a new SecondKey to the map.
701      ///
702      ///It adds a new SecondKey to the map. It is called by the
703      ///observer notifier and it is ovverride the add() virtual
704      ///member function in the observer base. It will call the
705      ///maps addSecondKey() function.
706      virtual void add(const SecondKey& _secondKey){
707        _owner.addSecondKey(_secondKey);
708      }
709   
710      ///\brief Add more new SecondKey to the map.
711      ///
712      ///It adds more new SecondKey to the map. It is called by
713      ///the observer notifier and it is ovverride the add()
714      ///virtual member function in the observer base. It will
715      ///call the maps addSecondKeys() function.
716      virtual void add(const std::vector<SecondKey>& _secondKeys){
717        _owner.addSecondKeys(_secondKeys);
718      }
719         
720      ///\brief Erase a SecondKey from the map.
721      ///
722      ///Erase a SecondKey from the map. It called by the observer
723      ///notifier and it overrides the erase() virtual member
724      ///function of the observer base. It will call the map's
725      ///eraseSecondKey() function.
726      virtual void erase(const SecondKey& _secondKey){
727        _owner.eraseSecondKey(_secondKey);
728      }
729         
730      ///\brief Erase more SecondKeys from the map.
731      ///
732      ///Erase more SecondKey from the map. It called by the
733      ///observer notifier and it overrides the erase() virtual
734      ///member function of the observer base. It will call the
735      ///map's eraseSecondKeys() function.
736      virtual void erase(const std::vector<SecondKey>& _secondKeys){
737        _owner.eraseSecondKeys(_secondKeys);
738      }
739         
740      ///\brief Builds the map.
741      ///
742      ///It buildes the map. It called by the observer notifier
743      ///and it overrides the build() virtual member function of
744      ///the observer base.  It will call the map's build()
745      ///function.
746      virtual void build() {
747        _owner.build();
748      }
749         
750      ///\brief Clear the map.
751      ///
752      ///It erases all items from the map. It called by the
753      ///observer notifier and it overrides the clear() virtual
754      ///memeber function of the observer base. It will call the
755      ///map's clear() function.
756      virtual void clear() {
757        _owner.clear();
758        //_owner.clearFirst();
759      }
760    private:
761         
762      ///The type of map for which it is attached.
763      DynamicAsymMatrixMap& _owner;
764    };//END OF SECONDKEYPROXY
765     
766  private:
767   
768    /// \e
769    typedef std::vector<Value> Container;
770     
771    ///The type of constainer which stores the values of the map.
772    typedef std::vector<Container> DContainer;
773
774    ///The std:vector type which contains the data
775    DContainer values;
776     
777    ///Member for the first proxy class
778    FirstKeyProxy _first_key_proxy;
779     
780    ///Member for the second proxy class
781    SecondKeyProxy _second_key_proxy;
782
783  public:
784   
785    ///The refernce type of the map.
786    typedef typename Container::reference Reference;
787     
788    ///The const reference type of the constainer.
789    typedef typename Container::const_reference ConstReference;
790
791    ///\brief Constructor what create the map for the two containers type.
792    ///
793    ///Creates the matrix map and initialize the values with Value()
794    DynamicAsymMatrixMap(const _FirstContainer& _firstContainer,
795                  const _SecondContainer& _secondContainer)
796      : values(DContainer(_firstContainer.maxId(FirstKey())+1,
797                          Container(_secondContainer.maxId(SecondKey())+1))),
798        _first_key_proxy(*this),
799        _second_key_proxy(*this)
800    {
801      _first_key_proxy.attach(_firstContainer.getNotifier(FirstKey()));
802      _second_key_proxy.attach(_secondContainer.getNotifier(SecondKey()));
803    }
804
805    ///\brief Constructor what create the map for the two containers type.
806    ///
807    ///Creates the matrix map and initialize the values with the given _value
808    DynamicAsymMatrixMap(const _FirstContainer& _firstContainer,
809                  const _SecondContainer& _secondContainer,
810                  const Value& _value)
811      : values(DContainer(_firstContainer.maxId(FirstKey())+1,
812                          Container(_secondContainer.maxId(SecondKey())+1,
813                                    _value))),
814        _first_key_proxy(*this),
815        _second_key_proxy(*this)
816    {
817      _first_key_proxy.attach(_firstContainer.getNotifier(FirstKey()));
818      _second_key_proxy.attach(_secondContainer.getNotifier(SecondKey()));
819    }
820     
821    ///\brief Copy constructor.
822    ///
823    ///The copy constructor of the map.
824    DynamicAsymMatrixMap(const DynamicAsymMatrixMap& _copy)
825      : _first_key_proxy(*this), _second_key_proxy(*this) {
826      if(_copy._first_key_proxy.attached() &&
827         _copy._second_key_proxy.attached()){
828        _first_key_proxy.attach(*_copy._first_key_proxy.getNotifier());
829        _second_key_proxy.attach(*_copy._second_key_proxy.getNotifier());
830        values = _copy.values;
831      }
832    }
833     
834    ///\brief Destructor
835    ///
836    ///Destructor what detach() from the attached objects.  May this
837    ///function is not necessary because the destructor of
838    ///ObserverBase do the same.
839    ~DynamicAsymMatrixMap() {
840      if(_first_key_proxy.attached()){
841        _first_key_proxy.detach();
842      }
843      if(_second_key_proxy.attached()){
844        _second_key_proxy.detach();
845      }
846    }
847     
848    ///\brief Gives back the value assigned to the \c first - \c
849    ///second ordered pair.
850    ///
851    ///Gives back the value assigned to the \c first - \c second
852    ///ordered pair.
853    Reference operator()(const FirstKey& _first, const SecondKey& _second) {
854      return values[_first_key_proxy.getNotifier()->id(_first)]
855        [_second_key_proxy.getNotifier()->id(_second)];
856    }
857
858    ///\brief Gives back the value assigned to the \c first - \c
859    ///second ordered pair.
860    ///
861    ///Gives back the value assigned to the \c first - \c second
862    ///ordered pair.
863    ConstReference operator()(const FirstKey& _first,
864                              const SecondKey& _second) const {
865      return values[_first_key_proxy.getNotifier()->id(_first)]
866        [_second_key_proxy.getNotifier()->id(_second)];
867    }
868
869    ///\brief Setter function for this matrix map.
870    ///
871    ///Setter function for this matrix map.
872    void set(const FirstKey& first, const SecondKey& second,
873             const Value& value){
874      values[_first_key_proxy.getNotifier()->id(first)]
875        [_second_key_proxy.getNotifier()->id(second)] = value;
876    }
877
878    ///\brief The assignement operator.
879    ///
880    ///It allow to assign a map to an other. It
881    DynamicAsymMatrixMap& operator=(const DynamicAsymMatrixMap& _cmap){
882      return operator=<DynamicAsymMatrixMap>(_cmap);
883    }
884     
885    ///\brief Template assignement operator.
886    ///
887    ///It copy the element of the given map to its own container.  The
888    ///type of the two map shall be the same.
889    template <typename CMap>
890    DynamicAsymMatrixMap& operator=(const CMap& _cdmap){
891      checkConcept<concepts::ReadMatrixMap<FirstKey, SecondKey, Value>, CMap>();
892      const typename FirstKeyProxy::Notifier* notifierFirstKey =
893        _first_key_proxy.getNotifier();
894      const typename SecondKeyProxy::Notifier* notifierSecondKey =
895        _second_key_proxy.getNotifier();
896      FirstKey itemFirst;
897      SecondKey itemSecond;
898      for(notifierFirstKey->first(itemFirst); itemFirst != INVALID;
899          notifierFirstKey->next(itemFirst)){
900        for(notifierSecondKey->first(itemSecond); itemSecond != INVALID;
901            notifierSecondKey->next(itemSecond)){
902          set(itemFirst, itemSecond, _cdmap(itemFirst,itemSecond));
903        }
904      }
905      return *this;
906    }
907     
908  protected:
909   
910    ///\brief Add a new FirstKey to the map.
911    ///
912    ///It adds a new FirstKey to the map. It is called by the observer
913    ///class belongs to the FirstKey type.
914    void addFirstKey(const FirstKey& firstKey) {
915      int size = (int)values.size();
916      if( _first_key_proxy.getNotifier()->id(firstKey)+1 >= size ){
917        values.resize(_first_key_proxy.getNotifier()->id(firstKey)+1);
918        if( (int)values[0].size() != 0 ){
919          int innersize = (int)values[0].size();
920          for(int i=size; i!=(int)values.size();++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[0].resize(innersize);
927          }
928        }
929      }
930    }
931
932    ///\brief Adds more new FirstKeys to the map.
933    ///
934    ///It adds more new FirstKeys to the map. It called by the
935    ///observer class belongs to the FirstKey type.
936    void addFirstKeys(const std::vector<FirstKey>& firstKeys){
937      int max = values.size() - 1;
938      for(int i=0; i != (int)firstKeys.size(); ++i){
939        int id = _first_key_proxy.getNotifier()->id(firstKeys[i]);
940        if(max < id){
941          max = id;
942        }
943      }
944      int size = (int)values.size();
945      if(max >= size){
946        values.resize(max + 1);
947        if( (int)values[0].size() != 0){
948          int innersize = (int)values[0].size();
949          for(int i = size; i != (max + 1); ++i){
950            values[i].resize(innersize);
951          }
952        }else if(_second_key_proxy.getNotifier()->maxId() >= 0){
953          int innersize = _second_key_proxy.getNotifier()->maxId();
954          for(int i = 0; i != (int)values.size(); ++i){
955            values[i].resize(innersize);
956          }
957        }
958      }
959    }
960
961    ///\brief Add a new SecondKey to the map.
962    ///
963    ///It adds a new SecondKey to the map. It is called by the
964    ///observer class belongs to the SecondKey type.
965    void addSecondKey(const SecondKey& secondKey) {
966      if(values.size() == 0){
967        return;
968      }
969      int id = _second_key_proxy.getNotifier()->id(secondKey);
970      if(id >= (int)values[0].size()){
971        for(int i=0;i!=(int)values.size();++i){
972          values[i].resize(id+1);
973        }
974      }
975    }
976       
977    ///\brief Adds more new SecondKeys to the map.
978    ///
979    ///It adds more new SecondKeys to the map. It called by the
980    ///observer class belongs to the SecondKey type.
981    void addSecondKeys(const std::vector<SecondKey>& secondKeys){
982      if(values.size() == 0){
983        return;
984      }
985      int max = values[0].size();
986      for(int i = 0; i != (int)secondKeys.size(); ++i){
987        int id = _second_key_proxy.getNotifier()->id(secondKeys[i]);
988        if(max < id){
989          max = id;
990        }
991      }
992      if(max > (int)values[0].size()){
993        for(int i = 0; i != (int)values.size(); ++i){
994          values[i].resize(max + 1);
995        }
996      }
997    }
998   
999    ///\brief Erase a FirstKey from the map.
1000    ///
1001    ///Erase a FirstKey from the map. It called by the observer
1002    ///class belongs to the FirstKey type.
1003    void eraseFirstKey(const FirstKey& first) {
1004      int id = _first_key_proxy.getNotifier()->id(first);
1005      for(int i = 0; i != (int)values[id].size(); ++i){
1006        values[id][i] = Value();
1007      }
1008    }
1009       
1010    ///\brief Erase more FirstKey from the map.
1011    ///
1012    ///Erase more FirstKey from the map. It called by the observer
1013    ///class belongs to the FirstKey type.
1014    void eraseFirstKeys(const std::vector<FirstKey>& firstKeys) {
1015      for(int j = 0; j != (int)firstKeys.size(); ++j){
1016        int id = _first_key_proxy.getNotifier()->id(firstKeys[j]);
1017        for(int i = 0; i != (int)values[id].size(); ++i){
1018          values[id][i] = Value();
1019        }
1020      }
1021    }
1022
1023    ///\brief Erase a SecondKey from the map.
1024    ///
1025    ///Erase a SecondKey from the map. It called by the observer class
1026    ///belongs to the SecondKey type.
1027    void eraseSecondKey(const SecondKey& second) {
1028      if(values.size() == 0){
1029        return;
1030      }
1031      int id = _second_key_proxy.getNotifier()->id(second);
1032      for(int i = 0; i != (int)values.size(); ++i){
1033        values[i][id] = Value();
1034      }
1035    }
1036       
1037    ///\brief Erase more SecondKey from the map.
1038    ///
1039    ///Erase more SecondKey from the map. It called by the observer
1040    ///class belongs to the SecondKey type.
1041    void eraseSecondKeys(const std::vector<SecondKey>& secondKeys) {
1042      if(values.size() == 0){
1043        return;
1044      }
1045      for(int j = 0; j != (int)secondKeys.size(); ++j){
1046        int id = _second_key_proxy.getNotifier()->id(secondKeys[j]);
1047        for(int i = 0; i != (int)values.size(); ++i){
1048          values[i][id] = Value();
1049        }
1050      }
1051    }
1052
1053    ///\brief Builds the map.
1054    ///
1055    ///It buildes the map. It is called by the observer class belongs
1056    ///to the FirstKey or SecondKey type.
1057    void build() {
1058      values.resize(_first_key_proxy.getNotifier()->maxId());
1059      for(int i=0; i!=(int)values.size(); ++i){
1060        values[i].resize(_second_key_proxy.getNotifier()->maxId());
1061      }
1062    }
1063   
1064    ///\brief Clear the map.
1065    ///
1066    ///It erases all items from the map. It is called by the observer class
1067    ///belongs to the FirstKey or SecondKey type.
1068    void clear() {
1069      for(int i=0; i!=(int)values.size(); ++i) {
1070        values[i].clear();
1071      }
1072      values.clear();
1073    }
1074 
1075  };
1076
1077
1078
1079}
1080
1081#endif
Note: See TracBrowser for help on using the repository browser.