4265f36f5eba4fb080134348de00423a29e2256d
[platform/upstream/libzypp.git] / devel / devel.ma / ExplicitMap.h
1 /*---------------------------------------------------------------------\
2  |                          ____ _   __ __ ___                          |
3  |                         |__  / \ / / . \ . \                         |
4  |                           / / \ V /|  _/  _/                         |
5  |                          / /__ | | | | | |                           |
6  |                         /_____||_| |_| |_|                           |
7  |                                                                      |
8  \---------------------------------------------------------------------*/
9 /** \file zypp/ExplicitMap.h
10  *
11 */
12 #ifndef ZYPP_EXPLICITMAP_H
13 #define ZYPP_EXPLICITMAP_H
14
15 #include <iosfwd>
16 #include <map>
17
18 #include <boost/call_traits.hpp>
19
20 ///////////////////////////////////////////////////////////////////
21 namespace zypp
22 { /////////////////////////////////////////////////////////////////
23
24   ///////////////////////////////////////////////////////////////////
25   //
26   //    CLASS NAME : ExplicitMap<_Key, _Tp>
27   //
28   /** A simple lookup map using default value for not existing entries.
29    *
30    * A std::map providing <tt>operator[] const</tt> only. Nor existing
31    * entries are mapped to a default value. Entries are maipulated vis
32    * methods \ref set and \ref unset. Helper classes \ref TmpSet,
33    * \ref TmpUnset and \ref TmpSetDefault are provided to temporarily
34    * change and automaticlly restore values.
35    */
36   template<class _Key, class _Tp>
37     class ExplicitMap
38     {
39     public:
40       typedef typename boost::call_traits<_Tp>::value_type       value_type;
41       typedef typename boost::call_traits<_Tp>::reference        reference;
42       typedef typename boost::call_traits<_Tp>::const_reference  const_reference;
43       typedef typename boost::call_traits<_Tp>::param_type       param_type;
44
45     private:
46       typedef typename std::map<_Key,value_type> map_type;
47       typedef typename map_type::iterator        iterator;
48
49     public:
50       typedef typename map_type::key_type       key_type;
51       typedef typename map_type::size_type      size_type;
52       typedef typename map_type::const_iterator const_iterator;
53
54     public:
55       ExplicitMap()
56       {}
57
58       explicit
59       ExplicitMap( param_type mapDefault_r )
60       : _mapDefault( mapDefault_r )
61       {}
62
63       template <class _InputIterator>
64         ExplicitMap( _InputIterator first_r, _InputIterator last_r )
65         : _map( first_r, last_r )
66         {}
67
68       template <class _InputIterator>
69         ExplicitMap( _InputIterator first_r, _InputIterator last_r,
70                      param_type mapDefault_r )
71         : _map( first_r, last_r )
72         , _mapDefault( mapDefault_r )
73         {}
74
75     public:
76       size_type size() const
77       { return _map.size(); }
78
79       bool empty() const
80       { return _map.empty(); }
81
82       const_iterator begin() const
83       { return _map.begin(); }
84
85       const_iterator end() const
86       { return _map.end(); }
87
88       const_iterator find( const key_type & key_r ) const
89       { return _map.find( key_r ); }
90
91       bool has( const key_type & key_r ) const
92       { return _map.find( key_r ) != end(); }
93
94       const_reference get( const key_type & key_r ) const
95       {
96         const_iterator it = _map.find( key_r );
97         return( it == _map.end() ? _mapDefault : it->second );
98       }
99
100       const_reference getDefault() const
101       { return _mapDefault; }
102
103       const_reference operator[]( const key_type & key_r ) const
104       { return get( key_r ); }
105
106     public:
107       void clear()
108       { _map.clear(); }
109
110       void set( const key_type & key_r, param_type value_r )
111       { _map[key_r] = value_r; }
112
113       template <typename _InputIterator>
114         void set( _InputIterator first_r, _InputIterator last_r )
115         { _map.insert( first_r, last_r ); }
116
117       void unset( const key_type & key_r )
118       { _map.erase( key_r ); }
119
120       void setDefault( param_type value_r )
121       { _mapDefault = value_r; }
122
123     public:
124       class TmpSet;
125       class TmpUnset;
126       class TmpSetDefault;
127
128       //private:
129       value_type _mapDefault;
130       map_type   _map;
131     };
132   ///////////////////////////////////////////////////////////////////
133
134   ///////////////////////////////////////////////////////////////////
135   //
136   //    CLASS NAME : ExplicitMap<_Key, _Tp>::TmpSet
137   //
138   /** Temporarily set a value. */
139   template<class _Key, class _Tp>
140     class ExplicitMap<_Key, _Tp>::TmpSet
141     {
142     public:
143       TmpSet( ExplicitMap & map_r, const key_type & key_r, param_type value_r )
144       : _map( map_r )
145       , _key( key_r )
146       {
147         const_iterator it = _map.find( _key );
148         if ( it == _map.end() )
149           {
150             _wasDefault = true;
151           }
152         else
153           {
154             _wasDefault = false;
155             _value = it->second;
156           }
157         _map.set( _key, value_r );
158       }
159
160       ~TmpSet()
161       {
162         if ( _wasDefault )
163           {
164             _map.unset( _key );
165           }
166         else
167           {
168             _map.set( _key, _value );
169           }
170       }
171
172     private:
173       ExplicitMap & _map;
174       key_type      _key;
175       param_type    _value;
176       bool          _wasDefault;
177     };
178   ///////////////////////////////////////////////////////////////////
179
180   ///////////////////////////////////////////////////////////////////
181   //
182   //    CLASS NAME : ExplicitMap<_Key, _Tp>::TmpUnset
183   //
184   /** Temporarily unset a value. */
185   template<class _Key, class _Tp>
186     class ExplicitMap<_Key, _Tp>::TmpUnset
187     {
188     public:
189       TmpUnset( ExplicitMap & map_r, const key_type & key_r )
190       : _map( map_r )
191       , _key( key_r )
192       {
193         const_iterator it = _map.find( _key );
194         if ( it == _map.end() )
195           {
196             _wasDefault = true;
197           }
198         else
199           {
200             _wasDefault = false;
201             _value = it->second;
202             _map.unset( _key );
203           }
204       }
205
206       ~TmpUnset()
207       {
208         if ( ! _wasDefault )
209           {
210             _map.set( _key, _value );
211           }
212       }
213
214     private:
215       ExplicitMap & _map;
216       key_type      _key;
217       param_type    _value;
218       bool          _wasDefault;
219     };
220   ///////////////////////////////////////////////////////////////////
221
222   ///////////////////////////////////////////////////////////////////
223   //
224   //    CLASS NAME : ExplicitMap<_Key, _Tp>::TmpSetDefault
225   //
226   /** Temporarily change the default value. */
227   template<class _Key, class _Tp>
228     class ExplicitMap<_Key, _Tp>::TmpSetDefault
229     {
230     public:
231       TmpSetDefault( ExplicitMap & map_r, param_type value_r )
232       : _map( map_r )
233       , _value( _map.getDefault() )
234       {
235         _map.setDefault( value_r );
236       }
237
238       ~TmpSetDefault()
239       {
240         _map.setDefault( _value );
241       }
242
243     private:
244       ExplicitMap & _map;
245       param_type    _value;
246     };
247   ///////////////////////////////////////////////////////////////////
248
249   /////////////////////////////////////////////////////////////////
250 } // namespace zypp
251 ///////////////////////////////////////////////////////////////////
252 #endif // ZYPP_EXPLICITMAP_H