1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/base/Functional.h
12 #ifndef ZYPP_BASE_FUNCTIONAL_H
13 #define ZYPP_BASE_FUNCTIONAL_H
15 #include <boost/functional.hpp>
17 #include "zypp/base/Function.h"
19 ///////////////////////////////////////////////////////////////////
21 { /////////////////////////////////////////////////////////////////
23 /* http://www.boost.org/libs/functional/mem_fun.html
25 The header functional.hpp includes improved versions of
26 the full range of member function adapters from the
30 using boost::mem_fun_ref;
32 ///////////////////////////////////////////////////////////////////
34 { /////////////////////////////////////////////////////////////////
36 /** An unary functor forwarding to some other <tt>_Functor &</tt>.
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.
44 * // Counts invokations of operator().
46 * struct Counter : public std::unary_function<_Tp, void>
48 * void operator()( _Tp )
51 * Counter() : _value( 0 ) {}
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)
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
71 * \note The order is <result_type, arg1_type, ...> (this
72 * differs from std::, where the result comes last).
74 * \todo drop it an use boost::ref
77 /////////////////////////////////////////////////////////////////
78 namespace functor_detail
80 template <class _Functor, class res_type>
83 FunctorRef0( _Functor & f_r )
87 res_type operator()() const
96 template <class _Functor, class res_type, class arg1_type>
97 struct FunctorRef1 : public std::unary_function<arg1_type, res_type>
99 FunctorRef1( _Functor & f_r )
103 res_type operator()( arg1_type a1 ) const
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>
115 FunctorRef2( _Functor & f_r )
119 res_type operator()( arg1_type a1, arg2_type a2 ) const
131 /////////////////////////////////////////////////////////////////
133 /** A binary \ref FunctorRef.
134 * Create it using \ref functorRef convenience function.
136 template <class _Functor, class res_type, class arg1_type = functor_detail::nil,
137 class arg2_type = functor_detail::nil>
139 : public functor_detail::FunctorRef2<_Functor, res_type, arg1_type, arg2_type>
141 FunctorRef( _Functor & f_r )
142 : functor_detail::FunctorRef2<_Functor, res_type, arg1_type, arg2_type>( f_r )
146 /** A unary \ref FunctorRef.
147 * Create it using \ref functorRef convenience function.
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>
153 FunctorRef( _Functor & f_r )
154 : functor_detail::FunctorRef1<_Functor, res_type, arg1_type>( f_r )
158 /** A nullary \ref FunctorRef.
159 * Create it using \ref functorRef convenience function.
161 template <class _Functor, class res_type>
162 struct FunctorRef<_Functor, res_type>
163 : public functor_detail::FunctorRef0<_Functor, res_type>
165 FunctorRef( _Functor & f_r )
166 : functor_detail::FunctorRef0<_Functor, res_type>( f_r )
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 ); }
184 /////////////////////////////////////////////////////////////////
186 /** \defgroup LOGICALFILTERS Functors for building compex queries.
189 * Some logical functors to build more complex queries:
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>.
198 * As it's no fun to get and write the correct template arguments,
199 * convenience functions creating the correct functor are provided.
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
204 * \li \c chain. Takes two functors and returns the appropriate
208 * struct Print; // functor printing elements
209 * struct Count; // functor counting number of elements
211 * std::for_each( c.begin(), c.end(),
212 * chain( Print(), Count() ) );
217 /* functor that always returns a copied
222 Constant( const T &value )
227 T operator()( _Tp ) const
237 inline Constant<T> constant( const T &value )
238 { return Constant<T>(value); }
240 /** Logical functor always \c true.
245 bool operator()( _Tp ) const
251 /** Convenience function for creating a True. */
255 /** Logical functor always \c false.
260 bool operator()( _Tp ) const
266 /** Convenience function for creating a False. */
267 inline False false_c()
270 /** Logical functor inverting \a _Condition.
272 template<class _Condition>
275 Not( _Condition cond_r )
280 bool operator()( _Tp t ) const
288 /** Convenience function for creating a Not from \a _Condition. */
289 template<class _Condition>
290 inline Not<_Condition> not_c( _Condition cond_r )
292 return Not<_Condition>( cond_r );
295 /** Logical functor chaining \a _ACondition \c OR \a _BCondition.
297 template<class _ACondition, class _BCondition>
300 Or( _ACondition conda_r, _BCondition condb_r )
306 bool operator()( _Tp t ) const
308 return _conda( t ) || _condb( t );
315 /** Convenience function for creating a Or from two conditions
316 * \a conda_r OR \a condb_r.
318 template<class _ACondition, class _BCondition>
319 inline Or<_ACondition, _BCondition> or_c( _ACondition conda_r, _BCondition condb_r )
321 return Or<_ACondition, _BCondition>( conda_r, condb_r );
324 /** Logical functor chaining \a _ACondition \c AND \a _BCondition.
326 template<class _ACondition, class _BCondition>
329 Chain( _ACondition conda_r, _BCondition condb_r )
335 bool operator()( _Tp t ) const
337 return _conda( t ) && _condb( t );
344 /** Convenience function for creating a Chain from two conditions
345 * \a conda_r and \a condb_r.
347 template<class _ACondition, class _BCondition>
348 inline Chain<_ACondition, _BCondition> chain( _ACondition conda_r, _BCondition condb_r )
350 return Chain<_ACondition, _BCondition>( conda_r, condb_r );
354 ///////////////////////////////////////////////////////////////////
356 /** \defgroup ACTIONFUNCTOR
361 /** Strore the 1st result found in the variable passed to the ctor.
364 * invokeOnEach( pool.byIdentBegin(installed), pool.byIdentEnd(installed),
365 * filter::SameItem( installed ),
366 * getFirst( result ) );
372 GetFirst( _Tp & result_r )
373 : _result( &result_r )
375 bool operator()( const _Tp & val_r )
376 { *_result = val_r; return false; }
382 /** Convenience function for creating \ref GetFirst. */
384 GetFirst<_Tp> getFirst( _Tp & result_r )
385 { return GetFirst<_Tp>( result_r ); }
388 /** Strore the last result found in the variable passed to the ctor.
393 GetLast( _Tp & result_r )
394 : _result( &result_r )
396 bool operator()( const _Tp & val_r )
397 { *_result = val_r; return true; }
403 /** Convenience function for creating \ref GetLast. */
405 GetLast<_Tp> getLast( _Tp & result_r )
406 { return GetLast<_Tp>( result_r ); }
409 /** Store all results found to some output_iterator.
411 * std::vector<parser::ProductFileData> result;
412 * parser::ProductFileReader::scanDir( functor::getAll( std::back_inserter( result ) ),
413 sysRoot / "etc/products.d" );
416 template<class _OutputIterator>
419 GetAll( _OutputIterator result_r )
420 : _result( result_r )
424 bool operator()( const _Tp & val_r ) const
425 { *(_result++) = val_r; return true; }
428 mutable _OutputIterator _result;
431 /** Convenience function for creating \ref GetAll. */
432 template<class _OutputIterator>
433 GetAll<_OutputIterator> getAll( _OutputIterator result_r )
434 { return GetAll<_OutputIterator>( result_r ); }
437 ///////////////////////////////////////////////////////////////////
439 /////////////////////////////////////////////////////////////////
440 } // namespace functor
441 ///////////////////////////////////////////////////////////////////
442 /////////////////////////////////////////////////////////////////
444 ///////////////////////////////////////////////////////////////////
445 #endif // ZYPP_BASE_FUNCTIONAL_H