Salome HOME
36e3309da75521b53a2825d342bbdf186d834618
[modules/gui.git] / src / Qtx / QtxMap.h
1 // Copyright (C) 2007-2023  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // File   : QtxMap.h
21 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
22 //
23 #ifndef QTXMAP_H
24 #define QTXMAP_H
25
26 template <class Key, class Value> class IMap;
27 template <class Key, class Value> class IMapIterator;
28 template <class Key, class Value> class IMapConstIterator;
29
30 /*!
31   \brief Indexed map template class.
32 */
33 template <class Key, class Value> class IMap
34 {
35 public:
36   typedef IMapIterator<Key,Value>      Iterator;
37   typedef IMapConstIterator<Key,Value> ConstIterator;
38
39 public:
40   IMap() {}
41   IMap( const IMap& m ) : myKeys( m.myKeys ), myData( m.myData ) {}
42   IMap& operator=( const IMap& m ) { myKeys = m.myKeys; myData = m.myData; return *this; }
43   
44   int  count() const   { return myData.count(); }
45   int  size() const    { return myData.count(); }
46   bool empty() const   { return myData.empty(); }
47   bool isEmpty() const { return myData.empty(); }
48   
49   void clear() { myKeys.clear(); myData.clear(); }
50   
51   QList<Key>   keys()   const { return myKeys; }
52   QList<Value> values() const { QList<Value> l; for ( int i = 0; i < count(); i++ ) l.append( value( i ) ); return l; }
53   bool         contains ( const Key& key ) const { return myData.contains( key ); }
54   
55   Iterator      begin()       { return Iterator( this );               }
56   Iterator      end()         { return Iterator( this, count() );      }
57   ConstIterator begin() const { return ConstIterator( this );          }
58   ConstIterator end() const   { return ConstIterator( this, count() ); }
59   
60   Iterator insert( const Key& key, const Value& value, bool overwrite = true )
61   { 
62     if ( myData.find( key ) == myData.end() || overwrite )
63     {
64       if ( myData.find( key ) != myData.end() && overwrite )
65         myKeys.removeAt( myKeys.indexOf( key ) );
66       myKeys.append( key );
67       myData[key] = value;
68     }
69     return Iterator( this, index( key ) );
70   }
71
72   Iterator replace( const Key& key, const Value& value )
73   { 
74     if ( myData.find( key ) == myData.end() )
75       myKeys.append( key );
76     myData[ key ] = value;
77     return Iterator( this, index( key ) );
78   }
79
80   int           index( const Key& key ) const { return myKeys.indexOf( key );      }
81   Iterator      at( const int index )         { return Iterator( this, index );      }
82   ConstIterator at( const int index ) const   { return ConstIterator( this, index ); }
83
84   Key& key( const int index )
85   {
86     if ( index < 0 || index >= (int)myKeys.count() ) 
87       return dummyKey;
88     return myKeys[index];
89   }
90
91   Value value( const int index )
92   {
93     if ( index < 0 || index >= (int)myKeys.count() ) 
94       return dummyValue;
95     return myData[ myKeys[index] ];
96   }
97
98   Value operator[]( const Key& key )
99   {
100     if ( myData.find( key ) == myData.end() )
101       insert( key, Value() );
102     return myData[ key ];
103   }
104
105   const Value operator[]( const Key& key ) const
106   {
107     if ( myData.find( key ) == myData.end() )
108       return dummyValue;
109     return myData[key];
110   }
111
112   void erase( Iterator it )     { remove( it );    }
113   void erase( const Key& key )  { remove( key );   }
114   void erase( const int index ) { remove( index ); }
115   void remove( Iterator it )    { if ( it.myMap != this ) return; remove( it.myIndex ); }
116   void remove( const Key& key ) { remove( index( key ) ); }
117   void remove( const int index )
118   {
119     if ( index >= 0 && index < (int)myKeys.count() )
120     {
121       myData.remove( myKeys[index] );
122       myKeys.removeAt( index );
123     }
124   }
125
126 private:
127   QList<Key>      myKeys;
128   QMap<Key,Value> myData;
129   Key             dummyKey;
130   Value           dummyValue;
131
132   friend class IMapIterator<Key,Value>;
133   friend class IMapConstIterator<Key,Value>;
134 };
135
136 /*!
137   \brief Indexed map iterator template class.
138 */
139 template <class Key, class Value> class IMapIterator
140 {
141 public:
142   IMapIterator()                           : myMap( 0 ), myIndex( 0 )                                   { init(); }
143   IMapIterator( const IMap<Key,Value>* m ) : myMap( const_cast< IMap<Key,Value>* >( m ) ), myIndex( 0 ) { init(); }
144   IMapIterator( const IMapIterator& i )    : myMap( i.myMap ), myIndex( i.myIndex )                     { init(); }
145
146   bool operator==( const IMapIterator& i ) { return !operator!=( i );                                   }
147   bool operator!=( const IMapIterator& i ) { return !myMap || myMap != i.myMap || myIndex != i.myIndex; }
148   
149   operator bool() const { return myIndex >= 0; }
150
151   const Key&   key() const  { return myMap->key( myIndex );   }
152   Value&       value()       { return myMap->value( myIndex ); }
153   const Value& value() const { return myMap->value( myIndex ); }
154
155   Value& operator*() { return value(); }
156
157   IMapIterator& operator++()      { myIndex++; init(); return *this;                     }
158   IMapIterator  operator++( int ) { IMapIterator i = *this; myIndex++; init(); return i; }
159   IMapIterator& operator--()      { myIndex--; init(); return *this;                     }
160   IMapIterator  operator--( int ) { IMapIterator i = *this; myIndex--; init(); return i; }
161
162 private:
163   IMapIterator( const IMap<Key,Value>* m, const int index ) : myMap( const_cast< IMap<Key,Value>* >( m ) ), myIndex( index ) { init(); }
164   void init() { if ( !myMap || myIndex >= myMap->count() ) myIndex = -1; }
165
166 private:
167   IMap<Key,Value>* myMap;
168   int              myIndex;
169
170   friend class IMap<Key, Value>;
171   friend class IMapConstIterator<Key, Value>;
172 };
173
174 /*!
175   \brief Indexed map const iterator template class.
176 */
177 template <class Key, class Value> class IMapConstIterator
178 {
179 public:
180   IMapConstIterator()                                    : myMap( 0 ), myIndex( 0 )                                    { init(); }
181   IMapConstIterator( const IMap<Key,Value>* m )          : myMap( const_cast< IMap<Key,Value>* >( m )  ), myIndex( 0 ) { init(); }
182   IMapConstIterator( const IMapConstIterator& i )        : myMap( i.myMap ), myIndex( i.myIndex )                      { init(); }
183   IMapConstIterator( const IMapIterator<Key, Value>& i ) : myMap( i.myMap ), myIndex( i.myIndex )                      { init(); }
184   
185   bool operator==( const IMapConstIterator& i ) { return !operator!=( i );                                   }
186   bool operator!=( const IMapConstIterator& i ) { return !myMap || myMap != i.myMap || myIndex != i.myIndex; }
187   
188   operator bool() const { return myIndex >= 0; }
189   
190   const Key&   key() const  { return myMap->key( myIndex );   }
191   const Value value() const { return myMap->value( myIndex ); }
192   
193   const Value operator*() const { return value(); }
194
195   IMapConstIterator& operator++()      { myIndex++; init(); return *this;                          }
196   IMapConstIterator  operator++( int ) { IMapConstIterator i = *this; myIndex++; init(); return i; }
197   IMapConstIterator& operator--()      { myIndex--; init(); return *this;                          }
198   IMapConstIterator  operator--( int ) { IMapConstIterator i = *this; myIndex--; init(); return i; }
199   
200 private:
201   IMapConstIterator( const IMap<Key,Value>* m, const int index ): myMap( const_cast< IMap<Key,Value>* >( m ) ), myIndex( index ) { init(); }
202   void init() { if ( !myMap || myIndex >= myMap->count() ) myIndex = -1; }
203   
204 private:
205   IMap<Key,Value>* myMap;
206   int              myIndex;
207   
208   friend class IMap<Key,Value>;
209 };
210
211 #endif // QTXMAP_H