- fixed some typos
[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 <functional>
16 #include <boost/functional.hpp>
17
18 ///////////////////////////////////////////////////////////////////
19 namespace zypp
20 { /////////////////////////////////////////////////////////////////
21
22   /* http://www.boost.org/libs/functional/mem_fun.html
23
24    The header functional.hpp includes improved versions of
25    the full range of member function adapters from the
26    C++ Standard Library.
27   */
28   using boost::mem_fun;
29   using boost::mem_fun_ref;
30
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     /** Logical functor always \c true.
218     */
219     struct True
220     {
221       template<class _Tp>
222         bool operator()( _Tp ) const
223         {
224           return true;
225         }
226     };
227
228     /** Convenience function for creating a True. */
229     inline True true_c()
230     { return True(); }
231
232     /** Logical functor always \c false.
233     */
234     struct False
235     {
236       template<class _Tp>
237         bool operator()( _Tp ) const
238         {
239           return false;
240         }
241     };
242
243     /** Convenience function for creating a False. */
244     inline False false_c()
245     { return False(); }
246
247     /** Logical functor inverting \a _Condition.
248     */
249     template<class _Condition>
250       struct Not
251       {
252         Not( _Condition cond_r )
253         : _cond( cond_r )
254         {}
255
256         template<class _Tp>
257           bool operator()( _Tp t ) const
258           {
259             return ! _cond( t );
260           }
261
262         _Condition _cond;
263       };
264
265     /** Convenience function for creating a Not from \a _Condition. */
266     template<class _Condition>
267       inline Not<_Condition> not_c( _Condition cond_r )
268       {
269         return Not<_Condition>( cond_r );
270       }
271
272     /** Logical functor chaining \a _ACondition \c OR \a _BCondition.
273     */
274     template<class _ACondition, class _BCondition>
275       struct Or
276       {
277         Or( _ACondition conda_r, _BCondition condb_r )
278         : _conda( conda_r )
279         , _condb( condb_r )
280         {}
281
282         template<class _Tp>
283           bool operator()( _Tp t ) const
284           {
285             return _conda( t ) || _condb( t );
286           }
287
288         _ACondition _conda;
289         _BCondition _condb;
290       };
291
292     /** Convenience function for creating a Or from two conditions
293      *  \a conda_r OR \a condb_r.
294     */
295     template<class _ACondition, class _BCondition>
296       inline Or<_ACondition, _BCondition> or_c( _ACondition conda_r, _BCondition condb_r )
297       {
298         return Or<_ACondition, _BCondition>( conda_r, condb_r );
299       }
300
301     /** Logical functor chaining \a _ACondition \c AND \a _BCondition.
302     */
303     template<class _ACondition, class _BCondition>
304       struct Chain
305       {
306         Chain( _ACondition conda_r, _BCondition condb_r )
307         : _conda( conda_r )
308         , _condb( condb_r )
309         {}
310
311         template<class _Tp>
312           bool operator()( _Tp t ) const
313           {
314             return _conda( t ) && _condb( t );
315           }
316
317         _ACondition _conda;
318         _BCondition _condb;
319       };
320
321     /** Convenience function for creating a Chain from two conditions
322      *  \a conda_r and \a condb_r.
323     */
324     template<class _ACondition, class _BCondition>
325       inline Chain<_ACondition, _BCondition> chain( _ACondition conda_r, _BCondition condb_r )
326       {
327         return Chain<_ACondition, _BCondition>( conda_r, condb_r );
328       }
329
330     //@}
331     ///////////////////////////////////////////////////////////////////
332
333     /////////////////////////////////////////////////////////////////
334   } // namespace functor
335   ///////////////////////////////////////////////////////////////////
336   /////////////////////////////////////////////////////////////////
337 } // namespace zypp
338 ///////////////////////////////////////////////////////////////////
339 #endif // ZYPP_BASE_FUNCTIONAL_H