1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/base/Functional.h
12 #ifndef ZYPP_BASE_FUNCTIONAL_H
13 #define ZYPP_BASE_FUNCTIONAL_H
15 //#include <functional>
16 #include <boost/functional.hpp>
18 ///////////////////////////////////////////////////////////////////
20 { /////////////////////////////////////////////////////////////////
22 /* http://www.boost.org/libs/functional/mem_fun.html
24 The header functional.hpp includes improved versions of
25 the full range of member function adapters from the
29 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 /** Logical functor always \c true.
222 bool operator()( _Tp ) const
228 /** Convenience function for creating a True. */
232 /** Logical functor always \c false.
237 bool operator()( _Tp ) const
243 /** Convenience function for creating a False. */
244 inline False false_c()
247 /** Logical functor inverting \a _Condition.
249 template<class _Condition>
252 Not( _Condition cond_r )
257 bool operator()( _Tp t ) const
265 /** Convenience function for creating a Not from \a _Condition. */
266 template<class _Condition>
267 inline Not<_Condition> not_c( _Condition cond_r )
269 return Not<_Condition>( cond_r );
272 /** Logical functor chaining \a _ACondition \c OR \a _BCondition.
274 template<class _ACondition, class _BCondition>
277 Or( _ACondition conda_r, _BCondition condb_r )
283 bool operator()( _Tp t ) const
285 return _conda( t ) || _condb( t );
292 /** Convenience function for creating a Or from two conditions
293 * \a conda_r OR \a condb_r.
295 template<class _ACondition, class _BCondition>
296 inline Or<_ACondition, _BCondition> or_c( _ACondition conda_r, _BCondition condb_r )
298 return Or<_ACondition, _BCondition>( conda_r, condb_r );
301 /** Logical functor chaining \a _ACondition \c AND \a _BCondition.
303 template<class _ACondition, class _BCondition>
306 Chain( _ACondition conda_r, _BCondition condb_r )
312 bool operator()( _Tp t ) const
314 return _conda( t ) && _condb( t );
321 /** Convenience function for creating a Chain from two conditions
322 * \a conda_r and \a condb_r.
324 template<class _ACondition, class _BCondition>
325 inline Chain<_ACondition, _BCondition> chain( _ACondition conda_r, _BCondition condb_r )
327 return Chain<_ACondition, _BCondition>( conda_r, condb_r );
331 ///////////////////////////////////////////////////////////////////
333 /////////////////////////////////////////////////////////////////
334 } // namespace functor
335 ///////////////////////////////////////////////////////////////////
336 /////////////////////////////////////////////////////////////////
338 ///////////////////////////////////////////////////////////////////
339 #endif // ZYPP_BASE_FUNCTIONAL_H