Create unittest for i18n_noop[s]
[libi2ncommon] / utils / containerfunc.hpp
1 /*
2 The software in this package is distributed under the GNU General
3 Public License version 2 (with a special exception described below).
4
5 A copy of GNU General Public License (GPL) is included in this distribution,
6 in the file COPYING.GPL.
7
8 As a special exception, if other files instantiate templates or use macros
9 or inline functions from this file, or you compile this file and link it
10 with other works to produce a work based on this file, this file
11 does not by itself cause the resulting work to be covered
12 by the GNU General Public License.
13
14 However the source code for this file must still be made available
15 in accordance with section (3) of the GNU General Public License.
16
17 This exception does not invalidate any other reasons why a work based
18 on this file might be covered by the GNU General Public License.
19 */
20 /** @file
21  * @brief some helper for handling (STL) data structures.
22  *
23  * @author Reinhard Pfau
24  *
25  * (c) Copyright 2007-2008 by Intra2net AG
26  */
27
28 #ifndef _I2N_CONTAINERFUNC_HPP_
29 #define _I2N_CONTAINERFUNC_HPP_
30
31 #include <map>
32 #include <list>
33 #include <set>
34 #include <boost/shared_ptr.hpp>
35 #include <boost/weak_ptr.hpp>
36
37
38 namespace I2n {
39
40
41 /**
42  * convenience class to insert key-value pairs into a map.
43  */
44 template<typename K, typename V>
45 class MapFiller
46 {
47         std::map<K,V> & MapRef;
48
49     public:
50         MapFiller( std::map<K,V> & map_ref)
51         : MapRef(map_ref)
52         {
53         }
54
55         MapFiller& operator () (const K& key, const V& value)
56         {
57             MapRef[key]= value;
58             return *this;
59         }
60
61 }; // eo class MapFiller
62
63
64 /**
65  * convenience class to fill values into a container (using push_back).
66  */
67 template<
68     typename T,
69     template< typename, typename> class C= std::list,
70     typename Alloc = std::allocator< T >
71 >
72 class PushBackFiller
73 {
74         C< T, Alloc > &CRef;
75     public:
76         PushBackFiller( C<T, Alloc > & c )
77         : CRef(c)
78         {}
79
80         PushBackFiller& operator () (const T& value)
81         {
82             CRef.push_back(value);
83             return *this;
84         } // eo operator ()
85
86 }; // eo class PushBackFiller
87
88
89 template<
90     typename T,
91     template< typename, typename > class C,
92     typename Alloc
93 >
94 PushBackFiller< T, C, Alloc > get_push_back_filler( C< T, Alloc >& c)
95 {
96     return PushBackFiller< T, C, Alloc >(c);
97 } // eo get_push_back_filler(C< T, Alloc >&)
98
99
100 /**
101  * convenience class for transient construction of a container including values.
102  */
103 template<
104     typename T,
105     template< typename, typename> class C= std::list,
106     typename Alloc = std::allocator< T >
107 >
108 class TransientPushBackFiller
109 {
110         C< T, Alloc > MyC;
111     public:
112         typedef C< T, Alloc > CType;
113     
114         TransientPushBackFiller()
115         {}
116         
117         TransientPushBackFiller& operator () (const T& value)
118         {
119             MyC.push_back(value);
120             return *this;
121         } // eo operator ()
122         
123         operator CType () const { return MyC; }
124 }; // eo class TransientPushBackFiller
125
126
127 /**
128  * convenience class for transient construction of a map including values.
129  */
130 template<typename K, typename V>
131 class TransientMapFiller
132 {
133         std::map<K,V> Map;
134     
135     public:
136         typedef std::map< K, V > CType;
137     
138     
139         TransientMapFiller( )
140         {
141         }
142         
143         TransientMapFiller& operator () (const K& key, const V& value)
144         {
145             Map[key]= value;
146             return *this;
147         }
148         
149         operator CType () const { return Map; }
150 }; // eo class MapFiller
151
152
153
154
155 /**
156  * returns the keys of a map as a list.
157  * @param the_map the map.
158  * @param the_keys the list where the keys are added to.
159  * @return @a true.
160  */
161 template< typename K, typename V >
162 bool get_key_list( const std::map< K, V >& the_map, std::list< K >& the_keys )
163 {
164     for(typename std::map< K, V >::const_iterator it= the_map.begin();
165         it != the_map.end();
166         ++it )
167     {
168         the_keys.push_back( it->first );
169     }
170     return true;
171 }  // eo get_key_list(const std::map< K,V >, std::list< K >&)
172
173
174 /**
175  * returns the keys of a map as a list.
176  * @param the_map the map.
177  * @return the list of keys.
178  */
179 template< typename K, typename V >
180 std::list< K > get_key_list( const std::map< K, V>& the_map)
181 {
182     std::list< K > result;
183     get_key_list(the_map, result);
184     return result;
185 } // eo get_key_list(const std::map< K,V >)
186
187
188 /**
189  * returns the keys of a map as a set.
190  * @param the_map the map.
191  * @param the_keys the set where the keys are added to.
192  * @return @a true.
193  */
194 template< typename K, typename V >
195 bool get_key_set( const std::map< K, V >& the_map, std::set< K >& the_keys )
196 {
197     for(typename std::map< K, V >::const_iterator it= the_map.begin();
198         it != the_map.end();
199         ++it )
200     {
201         the_keys.insert( it->first );
202     }
203     return true;
204 }  // eo get_key_set(const std::map< K,V >, std::set< K >&)
205
206
207 /**
208  * returns the keys of a map as a set.
209  * @param the_map the map.
210  * @return the set of keys.
211  */
212 template< typename K, typename V >
213 std::list< K > get_key_set( const std::map< K, V>& the_map)
214 {
215     std::set< K > result;
216     get_key_set(the_map, result);
217     return result;
218 } // eo get_key_set(const std::map< K,V >)
219
220
221 /**
222  * functor version of new().
223  * can be used for deferred instantiation of objects.
224  */
225 template<
226     typename T
227 >
228 struct New
229 {
230     typedef T* result_type;
231     
232     result_type operator() () 
233     {
234         return new T;
235     }
236     
237     template<typename Arg1>
238     result_type operator() (Arg1 arg1)
239     {
240         return new T(arg1);
241     }
242     
243     template<typename Arg1, typename Arg2>
244     result_type operator() (Arg1 arg1,Arg2 arg2)
245     {
246         return new T(arg1,arg2);
247     }
248     
249     template<typename Arg1, typename Arg2, typename Arg3>
250     result_type operator() (Arg1 arg1,Arg2 arg2,Arg3 arg3)
251     {
252         return new T(arg1,arg2,arg3);
253     }
254     
255     template<typename Arg1, typename Arg2, typename Arg3, typename Arg4>
256     result_type operator() (Arg1 arg1,Arg2 arg2,Arg3 arg3,Arg4 arg4)
257     {
258         return new T(arg1,arg2,arg3,arg4);
259     }
260     
261     template<typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
262     result_type operator() (Arg1 arg1,Arg2 arg2,Arg3 arg3,Arg4 arg4,Arg5 arg5)
263     {
264         return new T(arg1,arg2,arg3,arg4,arg5);
265     }
266     
267 }; // eo struct New
268
269
270
271
272 /**
273  * functor version of boost::shared_ptr = new().
274  * can be used for deferred instantiation of objects.
275  */
276 template<
277     typename T
278 >
279 struct SharedPtrNew
280 {
281     typedef boost::shared_ptr<T> result_type;
282     
283     result_type operator() () 
284     {
285         return result_type(new T);
286     }
287     
288     template<typename Arg1>
289     result_type operator() (Arg1 arg1)
290     {
291         return result_type(new T(arg1));
292     }
293     
294     template<typename Arg1, typename Arg2>
295     result_type operator() (Arg1 arg1,Arg2 arg2)
296     {
297         return result_type(new T(arg1,arg2));
298     }
299     
300     template<typename Arg1, typename Arg2, typename Arg3>
301     result_type operator() (Arg1 arg1,Arg2 arg2,Arg3 arg3)
302     {
303         return result_type(new T(arg1,arg2,arg3));
304     }
305     
306     template<typename Arg1, typename Arg2, typename Arg3, typename Arg4>
307     result_type operator() (Arg1 arg1,Arg2 arg2,Arg3 arg3,Arg4 arg4)
308     {
309         return result_type(new T(arg1,arg2,arg3,arg4));
310     }
311     
312     template<typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
313     result_type operator() (Arg1 arg1,Arg2 arg2,Arg3 arg3,Arg4 arg4,Arg5 arg5)
314     {
315         return result_type(new T(arg1,arg2,arg3,arg4,arg5));
316     }
317     
318 }; // eo struct SharedPtrNew
319
320
321
322 /*
323 ** classes holding a shared or weak pointer.
324 ** designed to be used as policy classes...
325 ** (but may be used for other purposes, too)
326 */
327
328 template<
329     class X
330 >
331 class SharedOwnership
332 {
333     public:
334     
335         SharedOwnership( boost::shared_ptr< X > ptr)
336         : StoredPtr(ptr)
337         {}
338         
339         
340         boost::shared_ptr< X > get_ptr() const { return StoredPtr; }
341     
342     public:
343     
344         boost::shared_ptr< X > StoredPtr;
345 }; // eo class SharedOwnership
346
347
348
349 template<
350     class X
351 >
352 class WeakOwnership
353 {
354     public:
355     
356         WeakOwnership( boost::shared_ptr< X > ptr)
357         : StoredPtr(ptr)
358         {}
359         
360         
361         boost::shared_ptr< X > get_ptr() const { return StoredPtr.lock(); }
362     
363     public:
364     
365         boost::weak_ptr< X > StoredPtr;
366 }; // eo class WeakOwnership
367
368
369
370 /*
371 ** NoOperation
372 ** ===========
373 */
374
375
376 /**
377  * @brief the ultimate class for doing nothing :-)
378  *
379  * Even it sounds odd to have a functor class which is doing nothing it makes
380  * sense to use this class in some situations.
381  *
382  * One example is the usage as Deleter for shared pointers which "own" a pointer to
383  * a static object (i.e. it is not allowed to be really deleted...). Using this class
384  * as Deleter in these pointers enables us to use interfaces which expect a shared pointer
385  * even if we want(/must) to pass pointers to static objects.
386  */
387 struct NoOperation
388 {
389     NoOperation() {};
390
391     template<
392         typename Arg1
393     >
394     NoOperation(Arg1) {}
395
396     template<
397         typename Arg1, typename Arg2
398     >
399     NoOperation(Arg1, Arg2) {}
400
401     template<
402         typename Arg1, typename Arg2, typename Arg3
403     >
404     NoOperation(Arg1, Arg2, Arg3) {}
405
406     void operator() () const {}
407
408     template<
409         typename Arg1
410     >
411     void operator() (Arg1) const {}
412
413     template<
414         typename Arg1, typename Arg2
415     >
416     void operator() (Arg1, Arg2) const {}
417
418     template<
419         typename Arg1, typename Arg2, typename Arg3
420     >
421     void operator() (Arg1, Arg2, Arg3) const {}
422
423 }; // eo struct NoOperation
424
425
426
427 } // eo namespace I2n
428
429 #endif