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>TFunctor &</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 TFunctor::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 TFunctor, class res_type>
83 FunctorRef0( TFunctor & f_r )
87 res_type operator()() const
96 template <class TFunctor, class res_type, class arg1_type>
97 struct FunctorRef1 : public std::unary_function<arg1_type, res_type>
99 FunctorRef1( TFunctor & f_r )
103 res_type operator()( arg1_type a1 ) const
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>
115 FunctorRef2( TFunctor & 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 TFunctor, class res_type, class arg1_type = functor_detail::nil,
137 class arg2_type = functor_detail::nil>
139 : public functor_detail::FunctorRef2<TFunctor, res_type, arg1_type, arg2_type>
141 FunctorRef( TFunctor & f_r )
142 : functor_detail::FunctorRef2<TFunctor, res_type, arg1_type, arg2_type>( f_r )
146 /** A unary \ref FunctorRef.
147 * Create it using \ref functorRef convenience function.
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>
153 FunctorRef( TFunctor & f_r )
154 : functor_detail::FunctorRef1<TFunctor, res_type, arg1_type>( f_r )
158 /** A nullary \ref FunctorRef.
159 * Create it using \ref functorRef convenience function.
161 template <class TFunctor, class res_type>
162 struct FunctorRef<TFunctor, res_type>
163 : public functor_detail::FunctorRef0<TFunctor, res_type>
165 FunctorRef( TFunctor & f_r )
166 : functor_detail::FunctorRef0<TFunctor, res_type>( f_r )
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 ); }
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\<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>.
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 value */
218 template<class TConst>
221 Constant( const TConst &value )
226 TConst operator()( Tp ) const
229 TConst operator()() const
235 template<class TConst>
236 inline Constant<TConst> constant( const TConst &value )
237 { return Constant<TConst>(value); }
239 /** Logical functor always \c true. */
243 bool operator()( Tp ) const
249 /** Convenience function for creating a True. */
253 /** Logical functor always \c false.
258 bool operator()( Tp ) const
264 /** Convenience function for creating a False. */
265 inline False false_c()
268 /** Logical functor inverting \a TCondition.
270 template<class TCondition>
273 Not( TCondition cond_r )
278 bool operator()( Tp t ) const
286 /** Convenience function for creating a Not from \a TCondition. */
287 template<class TCondition>
288 inline Not<TCondition> not_c( TCondition cond_r )
290 return Not<TCondition>( cond_r );
293 /** Logical functor chaining \a TACondition \c OR \a TBCondition.
295 template<class TACondition, class TBCondition>
298 Or( TACondition conda_r, TBCondition condb_r )
304 bool operator()( Tp t ) const
306 return _conda( t ) || _condb( t );
313 /** Convenience function for creating a Or from two conditions
314 * \a conda_r OR \a condb_r.
316 template<class TACondition, class TBCondition>
317 inline Or<TACondition, TBCondition> or_c( TACondition conda_r, TBCondition condb_r )
319 return Or<TACondition, TBCondition>( conda_r, condb_r );
322 /** Logical functor chaining \a TACondition \c AND \a TBCondition.
324 template<class TACondition, class TBCondition>
327 Chain( TACondition conda_r, TBCondition condb_r )
333 bool operator()( Tp t ) const
335 return _conda( t ) && _condb( t );
342 /** Convenience function for creating a Chain from two conditions
343 * \a conda_r and \a condb_r.
345 template<class TACondition, class TBCondition>
346 inline Chain<TACondition, TBCondition> chain( TACondition conda_r, TBCondition condb_r )
348 return Chain<TACondition, TBCondition>( conda_r, condb_r );
352 ///////////////////////////////////////////////////////////////////
354 /** \defgroup ACTIONFUNCTOR
359 /** Strore the 1st result found in the variable passed to the ctor.
362 * invokeOnEach( pool.byIdentBegin(installed), pool.byIdentEnd(installed),
363 * filter::SameItem( installed ),
364 * getFirst( result ) );
370 GetFirst( Tp & result_r )
371 : _result( &result_r )
373 bool operator()( const Tp & val_r )
374 { *_result = val_r; return false; }
380 /** Convenience function for creating \ref GetFirst. */
382 GetFirst<Tp> getFirst( Tp & result_r )
383 { return GetFirst<Tp>( result_r ); }
386 /** Strore the last result found in the variable passed to the ctor.
391 GetLast( Tp & result_r )
392 : _result( &result_r )
394 bool operator()( const Tp & val_r )
395 { *_result = val_r; return true; }
401 /** Convenience function for creating \ref GetLast. */
403 GetLast<Tp> getLast( Tp & result_r )
404 { return GetLast<Tp>( result_r ); }
407 /** Store all results found to some output_iterator.
409 * std::vector<parser::ProductFileData> result;
410 * parser::ProductFileReader::scanDir( functor::getAll( std::back_inserter( result ) ),
411 sysRoot / "etc/products.d" );
414 template<class TOutputIterator>
417 GetAll( TOutputIterator result_r )
418 : _result( result_r )
422 bool operator()( const Tp & val_r ) const
423 { *(_result++) = val_r; return true; }
426 mutable TOutputIterator _result;
429 /** Convenience function for creating \ref GetAll. */
430 template<class TOutputIterator>
431 GetAll<TOutputIterator> getAll( TOutputIterator result_r )
432 { return GetAll<TOutputIterator>( result_r ); }
435 ///////////////////////////////////////////////////////////////////
437 /////////////////////////////////////////////////////////////////
438 } // namespace functor
439 ///////////////////////////////////////////////////////////////////
440 /////////////////////////////////////////////////////////////////
442 ///////////////////////////////////////////////////////////////////
443 #endif // ZYPP_BASE_FUNCTIONAL_H