COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/matrix_maps.h @ 2039:dacc4ce9474d

Last change on this file since 2039:dacc4ce9474d was 2039:dacc4ce9474d, checked in by Balazs Dezso, 14 years ago

Commiting The DynamicAsymMatrixMap? from Nagy Jano

+ MatrixMapTraits?

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