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