Imported Upstream version 16.3.2
[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>TFunctor &</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 TFunctor::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 TFunctor, class res_type>
81         struct FunctorRef0
82         {
83           FunctorRef0( TFunctor & f_r )
84           : _f( f_r )
85           {}
86
87           res_type operator()() const
88           {
89           return _f();
90           }
91
92         private:
93           TFunctor & _f;
94         };
95
96       template <class TFunctor, class res_type, class arg1_type>
97         struct FunctorRef1 : public std::unary_function<arg1_type, res_type>
98         {
99           FunctorRef1( TFunctor & 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           TFunctor & _f;
110         };
111
112       template <class TFunctor, 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( TFunctor & 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           TFunctor & _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 TFunctor, class res_type, class arg1_type = functor_detail::nil,
137                                               class arg2_type = functor_detail::nil>
138       struct FunctorRef
139       : public functor_detail::FunctorRef2<TFunctor, res_type, arg1_type, arg2_type>
140       {
141         FunctorRef( TFunctor & f_r )
142         : functor_detail::FunctorRef2<TFunctor, 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 TFunctor, class res_type, class arg1_type>
150       struct FunctorRef<TFunctor, res_type, arg1_type>
151       : public functor_detail::FunctorRef1<TFunctor, res_type, arg1_type>
152       {
153         FunctorRef( TFunctor & f_r )
154         : functor_detail::FunctorRef1<TFunctor, 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 TFunctor, class res_type>
162       struct FunctorRef<TFunctor, res_type>
163       : public functor_detail::FunctorRef0<TFunctor, res_type>
164       {
165         FunctorRef( TFunctor & f_r )
166         : functor_detail::FunctorRef0<TFunctor, 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 TFunctor>
172       FunctorRef<TFunctor, res_type, arg1_type, arg2_type>
173       functorRef( TFunctor & f_r )
174       { return FunctorRef<TFunctor, res_type, arg1_type, arg2_type>( f_r ); }
175     template <class res_type, class arg1_type, class TFunctor>
176       FunctorRef<TFunctor, res_type, arg1_type>
177       functorRef( TFunctor & f_r )
178       { return FunctorRef<TFunctor, res_type, arg1_type>( f_r ); }
179     template <class res_type, class TFunctor>
180       FunctorRef<TFunctor, res_type>
181       functorRef( TFunctor & f_r )
182       { return FunctorRef<TFunctor, 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\<TCondition\>. TCondition is a functor, and
194      *     it's result is inverted.
195      * \li \ref Chain\<TACondition,TBCondition\>. \c TACondition and \c TBCondition
196      *     are functors, and Chain evaluates <tt>TACondition && TBCondition</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 value */
218     template<class TConst>
219     struct Constant
220     {
221       Constant( const TConst &value )
222         : _value(value)
223       {}
224
225       template<class Tp>
226       TConst operator()( Tp ) const
227       { return _value; }
228
229       TConst operator()() const
230       { return _value; }
231
232       TConst _value;
233     };
234
235     template<class TConst>
236     inline Constant<TConst> constant( const TConst &value )
237     { return Constant<TConst>(value); }
238
239     /** Logical functor always \c true. */
240     struct True
241     {
242       template<class Tp>
243         bool operator()( Tp ) const
244         {
245           return true;
246         }
247     };
248
249     /** Convenience function for creating a True. */
250     inline True true_c()
251     { return True(); }
252
253     /** Logical functor always \c false.
254     */
255     struct False
256     {
257       template<class Tp>
258         bool operator()( Tp ) const
259         {
260           return false;
261         }
262     };
263
264     /** Convenience function for creating a False. */
265     inline False false_c()
266     { return False(); }
267
268     /** Logical functor inverting \a TCondition.
269     */
270     template<class TCondition>
271       struct Not
272       {
273         Not( TCondition cond_r )
274         : _cond( cond_r )
275         {}
276
277         template<class Tp>
278           bool operator()( Tp t ) const
279           {
280             return ! _cond( t );
281           }
282
283         TCondition _cond;
284       };
285
286     /** Convenience function for creating a Not from \a TCondition. */
287     template<class TCondition>
288       inline Not<TCondition> not_c( TCondition cond_r )
289       {
290         return Not<TCondition>( cond_r );
291       }
292
293     /** Logical functor chaining \a TACondition \c OR \a TBCondition.
294     */
295     template<class TACondition, class TBCondition>
296       struct Or
297       {
298         Or( TACondition conda_r, TBCondition condb_r )
299         : _conda( conda_r )
300         , _condb( condb_r )
301         {}
302
303         template<class Tp>
304           bool operator()( Tp t ) const
305           {
306             return _conda( t ) || _condb( t );
307           }
308
309         TACondition _conda;
310         TBCondition _condb;
311       };
312
313     /** Convenience function for creating a Or from two conditions
314      *  \a conda_r OR \a condb_r.
315     */
316     template<class TACondition, class TBCondition>
317       inline Or<TACondition, TBCondition> or_c( TACondition conda_r, TBCondition condb_r )
318       {
319         return Or<TACondition, TBCondition>( conda_r, condb_r );
320       }
321
322     /** Logical functor chaining \a TACondition \c AND \a TBCondition.
323     */
324     template<class TACondition, class TBCondition>
325       struct Chain
326       {
327         Chain( TACondition conda_r, TBCondition condb_r )
328         : _conda( conda_r )
329         , _condb( condb_r )
330         {}
331
332         template<class Tp>
333           bool operator()( Tp t ) const
334           {
335             return _conda( t ) && _condb( t );
336           }
337
338         TACondition _conda;
339         TBCondition _condb;
340       };
341
342     /** Convenience function for creating a Chain from two conditions
343      *  \a conda_r and \a condb_r.
344     */
345     template<class TACondition, class TBCondition>
346       inline Chain<TACondition, TBCondition> chain( TACondition conda_r, TBCondition condb_r )
347       {
348         return Chain<TACondition, TBCondition>( conda_r, condb_r );
349       }
350
351     //@}
352     ///////////////////////////////////////////////////////////////////
353
354     /** \defgroup ACTIONFUNCTOR
355      * \ingroup g_Functor
356      */
357     //@{
358
359     /** Strore the 1st result found in the variable passed to the ctor.
360      * \code
361      *   PoolItem result;
362      *   invokeOnEach( pool.byIdentBegin(installed), pool.byIdentEnd(installed),
363      *                 filter::SameItem( installed ),
364      *                 getFirst( result ) );
365      * \endcode
366      */
367     template<class Tp>
368     struct GetFirst
369     {
370       GetFirst( Tp & result_r )
371         : _result( &result_r )
372       {}
373       bool operator()( const Tp & val_r )
374       { *_result = val_r; return false; }
375
376       private:
377         Tp * _result;
378     };
379
380     /** Convenience function for creating \ref GetFirst. */
381     template<class Tp>
382     GetFirst<Tp> getFirst( Tp & result_r )
383     { return GetFirst<Tp>( result_r ); }
384
385
386     /** Strore the last result found in the variable passed to the ctor.
387      */
388     template<class Tp>
389     struct GetLast
390     {
391       GetLast( Tp & result_r )
392         : _result( &result_r )
393       {}
394       bool operator()( const Tp & val_r )
395       { *_result = val_r; return true; }
396
397       private:
398         Tp * _result;
399     };
400
401     /** Convenience function for creating \ref GetLast. */
402     template<class Tp>
403     GetLast<Tp> getLast( Tp & result_r )
404     { return GetLast<Tp>( result_r ); }
405
406
407     /** Store all results found to some output_iterator.
408      * \code
409      * std::vector<parser::ProductFileData> result;
410      * parser::ProductFileReader::scanDir( functor::getAll( std::back_inserter( result ) ),
411                                            sysRoot / "etc/products.d" );
412      * \endcode
413      */
414     template<class TOutputIterator>
415     struct GetAll
416     {
417       GetAll( TOutputIterator result_r )
418         : _result( result_r )
419       {}
420
421       template<class Tp>
422       bool operator()(  const Tp & val_r ) const
423       { *(_result++) = val_r; return true; }
424
425       private:
426         mutable TOutputIterator _result;
427     };
428
429     /** Convenience function for creating \ref GetAll. */
430     template<class TOutputIterator>
431     GetAll<TOutputIterator> getAll( TOutputIterator result_r )
432     { return GetAll<TOutputIterator>( result_r ); }
433
434     //@}
435     ///////////////////////////////////////////////////////////////////
436
437    /////////////////////////////////////////////////////////////////
438   } // namespace functor
439   ///////////////////////////////////////////////////////////////////
440   /////////////////////////////////////////////////////////////////
441 } // namespace zypp
442 ///////////////////////////////////////////////////////////////////
443 #endif // ZYPP_BASE_FUNCTIONAL_H