9d6de50231773651aa380d7a26afdf3434893916
[platform/upstream/libzypp.git] / zypp / base / Functional.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/base/Functional.h
10  *
11 */
12 #ifndef ZYPP_BASE_FUNCTIONAL_H
13 #define ZYPP_BASE_FUNCTIONAL_H
14
15 #include <boost/functional.hpp>
16
17 #include "zypp/base/Function.h"
18
19 ///////////////////////////////////////////////////////////////////
20 namespace zypp
21 { /////////////////////////////////////////////////////////////////
22
23   /* http://www.boost.org/libs/functional/mem_fun.html
24
25    The header functional.hpp includes improved versions of
26    the full range of member function adapters from the
27    C++ Standard Library.
28   */
29   using boost::mem_fun;
30   using boost::mem_fun_ref;
31
32   ///////////////////////////////////////////////////////////////////
33   namespace functor
34   { /////////////////////////////////////////////////////////////////
35
36     /** An unary functor forwarding to some other <tt>_Functor &</tt>.
37      * \ingroup g_Functor
38      *
39      * Most algorithms take functor arguments by value. That's inconvenient
40      * if the functor wants to collect and return data. Creating and
41      * passing a \ref FunctorRef to the algorithm, may help you out of this.
42      *
43      * \code
44      *   // Counts invokations of operator().
45      *   template<class _Tp>
46      *     struct Counter : public std::unary_function<_Tp, void>
47      *     {
48      *       void operator()( _Tp )
49      *       { ++_value; }
50      *
51      *       Counter() : _value( 0 ) {}
52      *
53      *       unsigned _value;
54      *     };
55      *
56      *   std::set<SomeType> c;
57      *   Counter<SomeType> counter;
58      *   // Invokations of FunctorRef are forwarded to counter:
59      *   std::for_each( c.begin, c.end(),
60      *                  // currently you must specify the
61      *                  // operator() signature:
62      *                  functorRef<void,SomeType>(counter)
63      *                );
64      * \endcode
65      *
66      * \note FunctorRef must be able to deduce the signature of
67      * \c _Functor::operator(). This is currently not automated,
68      * so you must specify the operator() signature as template
69      * arguments.
70      *
71      * \note The order is <result_type, arg1_type, ...> (this
72      * differs from std::, where the result comes last).
73      *
74      * \todo drop it an use boost::ref
75     */
76
77     /////////////////////////////////////////////////////////////////
78     namespace functor_detail
79     {
80       template <class _Functor, class res_type>
81         struct FunctorRef0
82         {
83           FunctorRef0( _Functor & f_r )
84           : _f( f_r )
85           {}
86
87           res_type operator()() const
88           {
89           return _f();
90           }
91
92         private:
93           _Functor & _f;
94         };
95
96       template <class _Functor, class res_type, class arg1_type>
97         struct FunctorRef1 : public std::unary_function<arg1_type, res_type>
98         {
99           FunctorRef1( _Functor & f_r )
100           : _f( f_r )
101           {}
102
103           res_type operator()( arg1_type a1 ) const
104           {
105             return _f( a1 );
106           }
107
108         private:
109           _Functor & _f;
110         };
111
112       template <class _Functor, class res_type, class arg1_type, class arg2_type>
113         struct FunctorRef2 : public std::binary_function<arg1_type, arg2_type, res_type>
114         {
115           FunctorRef2( _Functor & f_r )
116           : _f( f_r )
117           {}
118
119           res_type operator()( arg1_type a1, arg2_type a2 ) const
120           {
121             return _f( a1, a2 );
122           }
123
124         private:
125           _Functor & _f;
126         };
127
128       struct nil
129       {};
130     }
131     /////////////////////////////////////////////////////////////////
132
133     /** A binary \ref FunctorRef.
134      * Create it using \ref functorRef convenience function.
135     */
136     template <class _Functor, class res_type, class arg1_type = functor_detail::nil,
137                                               class arg2_type = functor_detail::nil>
138       struct FunctorRef
139       : public functor_detail::FunctorRef2<_Functor, res_type, arg1_type, arg2_type>
140       {
141         FunctorRef( _Functor & f_r )
142         : functor_detail::FunctorRef2<_Functor, res_type, arg1_type, arg2_type>( f_r )
143         {}
144       };
145
146     /** A unary \ref FunctorRef.
147      * Create it using \ref functorRef convenience function.
148     */
149     template <class _Functor, class res_type, class arg1_type>
150       struct FunctorRef<_Functor, res_type, arg1_type>
151       : public functor_detail::FunctorRef1<_Functor, res_type, arg1_type>
152       {
153         FunctorRef( _Functor & f_r )
154         : functor_detail::FunctorRef1<_Functor, res_type, arg1_type>( f_r )
155         {}
156       };
157
158     /** A nullary \ref FunctorRef.
159      * Create it using \ref functorRef convenience function.
160     */
161     template <class _Functor, class res_type>
162       struct FunctorRef<_Functor, res_type>
163       : public functor_detail::FunctorRef0<_Functor, res_type>
164       {
165         FunctorRef( _Functor & f_r )
166         : functor_detail::FunctorRef0<_Functor, res_type>( f_r )
167         {}
168       };
169
170     /** Convenience function creating a binary \ref FunctorRef. */
171     template <class res_type, class arg1_type, class arg2_type, class _Functor>
172       FunctorRef<_Functor, res_type, arg1_type, arg2_type>
173       functorRef( _Functor & f_r )
174       { return FunctorRef<_Functor, res_type, arg1_type, arg2_type>( f_r ); }
175     template <class res_type, class arg1_type, class _Functor>
176       FunctorRef<_Functor, res_type, arg1_type>
177       functorRef( _Functor & f_r )
178       { return FunctorRef<_Functor, res_type, arg1_type>( f_r ); }
179     template <class res_type, class _Functor>
180       FunctorRef<_Functor, res_type>
181       functorRef( _Functor & f_r )
182       { return FunctorRef<_Functor, res_type>( f_r ); }
183
184     /////////////////////////////////////////////////////////////////
185
186     /** \defgroup LOGICALFILTERS Functors for building compex queries.
187      * \ingroup g_Functor
188      *
189      * Some logical functors to build more complex queries:
190      *
191      * \li \ref True and \ref False. No supprise, they always return
192      *     \c true or \c false.
193      * \li \ref Not\<_Condition\>. _Condition is a functor, and
194      *     it's result is inverted.
195      * \li \ref Chain\<_ACondition,_BCondition\>. \c _ACondition and \c _BCondition
196      *     are functors, and Chain evaluates <tt>_ACondition && _BCondition</tt>.
197      *
198      * As it's no fun to get and write the correct template arguments,
199      * convenience functions creating the correct functor are provided.
200      *
201      * \li \c true_c and \c false_c. (provided just to match the schema)
202      * \li \c not_c. Takes a functor as argument and returns the appropriate
203      *     \ref Not functor.
204      * \li \c chain. Takes two functors and returns the appropriate
205      *     \ref Cain functor.
206      *
207      * \code
208      *  struct Print; // functor printing elements
209      *  struct Count; // functor counting number of elements
210      *
211      *  std::for_each( c.begin(), c.end(),
212      *                 chain( Print(), Count() ) );
213      * \endcode
214     */
215     //@{
216
217     /* functor that always returns a copied
218        value */
219     template<class T>
220     struct Constant
221     {
222       Constant( const T &value )
223         : _value(value)
224       {}
225
226       template<class _Tp>
227       T operator()( _Tp ) const
228       { return _value; }
229
230       T operator()() const
231       { return _value; }
232
233       T _value;
234     };
235
236     template<class T>
237     inline Constant<T> constant( const T &value )
238     { return Constant<T>(value); }
239
240     /** Logical functor always \c true.
241     */
242     struct True
243     {
244       template<class _Tp>
245         bool operator()( _Tp ) const
246         {
247           return true;
248         }
249     };
250
251     /** Convenience function for creating a True. */
252     inline True true_c()
253     { return True(); }
254
255     /** Logical functor always \c false.
256     */
257     struct False
258     {
259       template<class _Tp>
260         bool operator()( _Tp ) const
261         {
262           return false;
263         }
264     };
265
266     /** Convenience function for creating a False. */
267     inline False false_c()
268     { return False(); }
269
270     /** Logical functor inverting \a _Condition.
271     */
272     template<class _Condition>
273       struct Not
274       {
275         Not( _Condition cond_r )
276         : _cond( cond_r )
277         {}
278
279         template<class _Tp>
280           bool operator()( _Tp t ) const
281           {
282             return ! _cond( t );
283           }
284
285         _Condition _cond;
286       };
287
288     /** Convenience function for creating a Not from \a _Condition. */
289     template<class _Condition>
290       inline Not<_Condition> not_c( _Condition cond_r )
291       {
292         return Not<_Condition>( cond_r );
293       }
294
295     /** Logical functor chaining \a _ACondition \c OR \a _BCondition.
296     */
297     template<class _ACondition, class _BCondition>
298       struct Or
299       {
300         Or( _ACondition conda_r, _BCondition condb_r )
301         : _conda( conda_r )
302         , _condb( condb_r )
303         {}
304
305         template<class _Tp>
306           bool operator()( _Tp t ) const
307           {
308             return _conda( t ) || _condb( t );
309           }
310
311         _ACondition _conda;
312         _BCondition _condb;
313       };
314
315     /** Convenience function for creating a Or from two conditions
316      *  \a conda_r OR \a condb_r.
317     */
318     template<class _ACondition, class _BCondition>
319       inline Or<_ACondition, _BCondition> or_c( _ACondition conda_r, _BCondition condb_r )
320       {
321         return Or<_ACondition, _BCondition>( conda_r, condb_r );
322       }
323
324     /** Logical functor chaining \a _ACondition \c AND \a _BCondition.
325     */
326     template<class _ACondition, class _BCondition>
327       struct Chain
328       {
329         Chain( _ACondition conda_r, _BCondition condb_r )
330         : _conda( conda_r )
331         , _condb( condb_r )
332         {}
333
334         template<class _Tp>
335           bool operator()( _Tp t ) const
336           {
337             return _conda( t ) && _condb( t );
338           }
339
340         _ACondition _conda;
341         _BCondition _condb;
342       };
343
344     /** Convenience function for creating a Chain from two conditions
345      *  \a conda_r and \a condb_r.
346     */
347     template<class _ACondition, class _BCondition>
348       inline Chain<_ACondition, _BCondition> chain( _ACondition conda_r, _BCondition condb_r )
349       {
350         return Chain<_ACondition, _BCondition>( conda_r, condb_r );
351       }
352
353     //@}
354     ///////////////////////////////////////////////////////////////////
355
356     /** \defgroup ACTIONFUNCTOR
357      * \ingroup g_Functor
358      */
359     //@{
360
361     /** Strore the 1st result found in the variable passed to the ctor.
362      * \code
363      *   PoolItem result;
364      *   invokeOnEach( pool.byIdentBegin(installed), pool.byIdentEnd(installed),
365      *                 filter::SameItem( installed ),
366      *                 getFirst( result ) );
367      * \endcode
368      */
369     template<class _Tp>
370     struct GetFirst
371     {
372       GetFirst( _Tp & result_r )
373         : _result( &result_r )
374       {}
375       bool operator()( const _Tp & val_r )
376       { *_result = val_r; return false; }
377
378       private:
379         _Tp * _result;
380     };
381
382     /** Convenience function for creating \ref GetFirst. */
383     template<class _Tp>
384     GetFirst<_Tp> getFirst( _Tp & result_r )
385     { return GetFirst<_Tp>( result_r ); }
386
387
388     /** Strore the last result found in the variable passed to the ctor.
389      */
390     template<class _Tp>
391     struct GetLast
392     {
393       GetLast( _Tp & result_r )
394         : _result( &result_r )
395       {}
396       bool operator()( const _Tp & val_r )
397       { *_result = val_r; return true; }
398
399       private:
400         _Tp * _result;
401     };
402
403     /** Convenience function for creating \ref GetLast. */
404     template<class _Tp>
405     GetLast<_Tp> getLast( _Tp & result_r )
406     { return GetLast<_Tp>( result_r ); }
407
408
409     /** Store all results found to some output_iterator.
410      * \code
411      * std::vector<parser::ProductFileData> result;
412      * parser::ProductFileReader::scanDir( functor::getAll( std::back_inserter( result ) ),
413                                            sysRoot / "etc/products.d" );
414      * \endcode
415      */
416     template<class _OutputIterator>
417     struct GetAll
418     {
419       GetAll( _OutputIterator result_r )
420         : _result( result_r )
421       {}
422
423       template<class _Tp>
424       bool operator()(  const _Tp & val_r ) const
425       { *(_result++) = val_r; return true; }
426
427       private:
428         mutable _OutputIterator _result;
429     };
430
431     /** Convenience function for creating \ref GetAll. */
432     template<class _OutputIterator>
433     GetAll<_OutputIterator> getAll( _OutputIterator result_r )
434     { return GetAll<_OutputIterator>( result_r ); }
435
436     //@}
437     ///////////////////////////////////////////////////////////////////
438
439    /////////////////////////////////////////////////////////////////
440   } // namespace functor
441   ///////////////////////////////////////////////////////////////////
442   /////////////////////////////////////////////////////////////////
443 } // namespace zypp
444 ///////////////////////////////////////////////////////////////////
445 #endif // ZYPP_BASE_FUNCTIONAL_H