#ifndef ZYPP_BASE_FUNCTIONAL_H
#define ZYPP_BASE_FUNCTIONAL_H
-#include <functional>
+#include <boost/functional.hpp>
+
+#include "zypp/base/Function.h"
///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////
+
+ /* http://www.boost.org/libs/functional/mem_fun.html
+
+ The header functional.hpp includes improved versions of
+ the full range of member function adapters from the
+ C++ Standard Library.
+ */
+ using boost::mem_fun;
+ using boost::mem_fun_ref;
+
///////////////////////////////////////////////////////////////////
namespace functor
{ /////////////////////////////////////////////////////////////////
- /** An unary functor forwarding to some other <tt>_Functor &</tt>.
+ /** An unary functor forwarding to some other <tt>TFunctor &</tt>.
* \ingroup g_Functor
*
* Most algorithms take functor arguments by value. That's inconvenient
*
* \code
* // Counts invokations of operator().
- * template<class _Tp>
- * struct Counter : public std::unary_function<_Tp, void>
+ * template<class Tp>
+ * struct Counter : public std::unary_function<Tp, void>
* {
- * void operator()( _Tp )
+ * void operator()( Tp )
* { ++_value; }
*
* Counter() : _value( 0 ) {}
* \endcode
*
* \note FunctorRef must be able to deduce the signature of
- * \c _Functor::operator(). This is currently not automated,
+ * \c TFunctor::operator(). This is currently not automated,
* so you must specify the operator() signature as template
* arguments.
*
* \note The order is <result_type, arg1_type, ...> (this
* differs from std::, where the result comes last).
+ *
+ * \todo drop it an use boost::ref
*/
/////////////////////////////////////////////////////////////////
namespace functor_detail
{
- template <class _Functor, class res_type>
+ template <class TFunctor, class res_type>
struct FunctorRef0
{
- FunctorRef0( _Functor & f_r )
+ FunctorRef0( TFunctor & f_r )
: _f( f_r )
{}
}
private:
- _Functor & _f;
+ TFunctor & _f;
};
- template <class _Functor, class res_type, class arg1_type>
+ template <class TFunctor, class res_type, class arg1_type>
struct FunctorRef1 : public std::unary_function<arg1_type, res_type>
{
- FunctorRef1( _Functor & f_r )
+ FunctorRef1( TFunctor & f_r )
: _f( f_r )
{}
}
private:
- _Functor & _f;
+ TFunctor & _f;
};
- template <class _Functor, class res_type, class arg1_type, class arg2_type>
+ template <class TFunctor, class res_type, class arg1_type, class arg2_type>
struct FunctorRef2 : public std::binary_function<arg1_type, arg2_type, res_type>
{
- FunctorRef2( _Functor & f_r )
+ FunctorRef2( TFunctor & f_r )
: _f( f_r )
{}
}
private:
- _Functor & _f;
+ TFunctor & _f;
};
struct nil
/** A binary \ref FunctorRef.
* Create it using \ref functorRef convenience function.
*/
- template <class _Functor, class res_type, class arg1_type = functor_detail::nil,
+ template <class TFunctor, class res_type, class arg1_type = functor_detail::nil,
class arg2_type = functor_detail::nil>
struct FunctorRef
- : public functor_detail::FunctorRef2<_Functor, res_type, arg1_type, arg2_type>
+ : public functor_detail::FunctorRef2<TFunctor, res_type, arg1_type, arg2_type>
{
- FunctorRef( _Functor & f_r )
- : functor_detail::FunctorRef2<_Functor, res_type, arg1_type, arg2_type>( f_r )
+ FunctorRef( TFunctor & f_r )
+ : functor_detail::FunctorRef2<TFunctor, res_type, arg1_type, arg2_type>( f_r )
{}
};
/** A unary \ref FunctorRef.
* Create it using \ref functorRef convenience function.
*/
- template <class _Functor, class res_type, class arg1_type>
- struct FunctorRef<_Functor, res_type, arg1_type>
- : public functor_detail::FunctorRef1<_Functor, res_type, arg1_type>
+ template <class TFunctor, class res_type, class arg1_type>
+ struct FunctorRef<TFunctor, res_type, arg1_type>
+ : public functor_detail::FunctorRef1<TFunctor, res_type, arg1_type>
{
- FunctorRef( _Functor & f_r )
- : functor_detail::FunctorRef1<_Functor, res_type, arg1_type>( f_r )
+ FunctorRef( TFunctor & f_r )
+ : functor_detail::FunctorRef1<TFunctor, res_type, arg1_type>( f_r )
{}
};
/** A nullary \ref FunctorRef.
* Create it using \ref functorRef convenience function.
*/
- template <class _Functor, class res_type>
- struct FunctorRef<_Functor, res_type>
- : public functor_detail::FunctorRef0<_Functor, res_type>
+ template <class TFunctor, class res_type>
+ struct FunctorRef<TFunctor, res_type>
+ : public functor_detail::FunctorRef0<TFunctor, res_type>
{
- FunctorRef( _Functor & f_r )
- : functor_detail::FunctorRef0<_Functor, res_type>( f_r )
+ FunctorRef( TFunctor & f_r )
+ : functor_detail::FunctorRef0<TFunctor, res_type>( f_r )
{}
};
/** Convenience function creating a binary \ref FunctorRef. */
- template <class res_type, class arg1_type, class arg2_type, class _Functor>
- FunctorRef<_Functor, res_type, arg1_type, arg2_type>
- functorRef( _Functor & f_r )
- { return FunctorRef<_Functor, res_type, arg1_type, arg2_type>( f_r ); }
- /** Convenience function creating a unary \ref FunctorRef. */
- template <class res_type, class arg1_type, class _Functor>
- FunctorRef<_Functor, res_type, arg1_type>
- functorRef( _Functor & f_r )
- { return FunctorRef<_Functor, res_type, arg1_type>( f_r ); }
- /** Convenience function creating a nullary \ref FunctorRef. */
- template <class res_type, class _Functor>
- FunctorRef<_Functor, res_type>
- functorRef( _Functor & f_r )
- { return FunctorRef<_Functor, res_type>( f_r ); }
+ template <class res_type, class arg1_type, class arg2_type, class TFunctor>
+ FunctorRef<TFunctor, res_type, arg1_type, arg2_type>
+ functorRef( TFunctor & f_r )
+ { return FunctorRef<TFunctor, res_type, arg1_type, arg2_type>( f_r ); }
+ template <class res_type, class arg1_type, class TFunctor>
+ FunctorRef<TFunctor, res_type, arg1_type>
+ functorRef( TFunctor & f_r )
+ { return FunctorRef<TFunctor, res_type, arg1_type>( f_r ); }
+ template <class res_type, class TFunctor>
+ FunctorRef<TFunctor, res_type>
+ functorRef( TFunctor & f_r )
+ { return FunctorRef<TFunctor, res_type>( f_r ); }
/////////////////////////////////////////////////////////////////
*
* \li \ref True and \ref False. No supprise, they always return
* \c true or \c false.
- * \li \ref Not\<_Condition\>. _Condition is a functor, and
+ * \li \ref Not\<TCondition\>. TCondition is a functor, and
* it's result is inverted.
- * \li \ref Chain\<_ACondition,_BCondition\>. \c _ACondition and \c _BCondition
- * are functors, and Chain evaluates <tt>_ACondition && _BCondition</tt>.
+ * \li \ref Chain\<TACondition,TBCondition\>. \c TACondition and \c TBCondition
+ * are functors, and Chain evaluates <tt>TACondition && TBCondition</tt>.
*
* As it's no fun to get and write the correct template arguments,
* convenience functions creating the correct functor are provided.
* \ref Cain functor.
*
* \code
- * struct Print; // functor priniting elements
+ * struct Print; // functor printing elements
* struct Count; // functor counting number of elements
*
* std::for_each( c.begin(), c.end(),
*/
//@{
- /** Logical functor always \c true.
- */
+ /* functor that always returns a copied value */
+ template<class TConst>
+ struct Constant
+ {
+ Constant( const TConst &value )
+ : _value(value)
+ {}
+
+ template<class Tp>
+ TConst operator()( Tp ) const
+ { return _value; }
+
+ TConst operator()() const
+ { return _value; }
+
+ TConst _value;
+ };
+
+ template<class TConst>
+ inline Constant<TConst> constant( const TConst &value )
+ { return Constant<TConst>(value); }
+
+ /** Logical functor always \c true. */
struct True
{
- template<class _Tp>
- bool operator()( _Tp ) const
+ template<class Tp>
+ bool operator()( Tp ) const
{
return true;
}
*/
struct False
{
- template<class _Tp>
- bool operator()( _Tp ) const
+ template<class Tp>
+ bool operator()( Tp ) const
{
return false;
}
inline False false_c()
{ return False(); }
- /** Logical functor inverting \a _Condition.
+ /** Logical functor inverting \a TCondition.
*/
- template<class _Condition>
+ template<class TCondition>
struct Not
{
- Not( _Condition cond_r )
+ Not( TCondition cond_r )
: _cond( cond_r )
{}
- template<class _Tp>
- bool operator()( _Tp t ) const
+ template<class Tp>
+ bool operator()( Tp t ) const
{
return ! _cond( t );
}
- _Condition _cond;
+ TCondition _cond;
+ };
+
+ /** Convenience function for creating a Not from \a TCondition. */
+ template<class TCondition>
+ inline Not<TCondition> not_c( TCondition cond_r )
+ {
+ return Not<TCondition>( cond_r );
+ }
+
+ /** Logical functor chaining \a TACondition \c OR \a TBCondition.
+ */
+ template<class TACondition, class TBCondition>
+ struct Or
+ {
+ Or( TACondition conda_r, TBCondition condb_r )
+ : _conda( conda_r )
+ , _condb( condb_r )
+ {}
+
+ template<class Tp>
+ bool operator()( Tp t ) const
+ {
+ return _conda( t ) || _condb( t );
+ }
+
+ TACondition _conda;
+ TBCondition _condb;
};
- /** Convenience function for creating a Not from \a _Condition. */
- template<class _Condition>
- inline Not<_Condition> not_c( _Condition cond_r )
+ /** Convenience function for creating a Or from two conditions
+ * \a conda_r OR \a condb_r.
+ */
+ template<class TACondition, class TBCondition>
+ inline Or<TACondition, TBCondition> or_c( TACondition conda_r, TBCondition condb_r )
{
- return Not<_Condition>( cond_r );
+ return Or<TACondition, TBCondition>( conda_r, condb_r );
}
- /** Logical functor chaining \a _ACondition \c AND \a _BCondition.
+ /** Logical functor chaining \a TACondition \c AND \a TBCondition.
*/
- template<class _ACondition, class _BCondition>
+ template<class TACondition, class TBCondition>
struct Chain
{
- Chain( _ACondition conda_r, _BCondition condb_r )
+ Chain( TACondition conda_r, TBCondition condb_r )
: _conda( conda_r )
, _condb( condb_r )
{}
- template<class _Tp>
- bool operator()( _Tp t ) const
+ template<class Tp>
+ bool operator()( Tp t ) const
{
return _conda( t ) && _condb( t );
}
- _ACondition _conda;
- _BCondition _condb;
+ TACondition _conda;
+ TBCondition _condb;
};
/** Convenience function for creating a Chain from two conditions
* \a conda_r and \a condb_r.
*/
- template<class _ACondition, class _BCondition>
- inline Chain<_ACondition, _BCondition> chain( _ACondition conda_r, _BCondition condb_r )
+ template<class TACondition, class TBCondition>
+ inline Chain<TACondition, TBCondition> chain( TACondition conda_r, TBCondition condb_r )
{
- return Chain<_ACondition, _BCondition>( conda_r, condb_r );
+ return Chain<TACondition, TBCondition>( conda_r, condb_r );
}
//@}
///////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////
+ /** \defgroup ACTIONFUNCTOR
+ * \ingroup g_Functor
+ */
+ //@{
+
+ /** Strore the 1st result found in the variable passed to the ctor.
+ * \code
+ * PoolItem result;
+ * invokeOnEach( pool.byIdentBegin(installed), pool.byIdentEnd(installed),
+ * filter::SameItem( installed ),
+ * getFirst( result ) );
+ * \endcode
+ */
+ template<class Tp>
+ struct GetFirst
+ {
+ GetFirst( Tp & result_r )
+ : _result( &result_r )
+ {}
+ bool operator()( const Tp & val_r )
+ { *_result = val_r; return false; }
+
+ private:
+ Tp * _result;
+ };
+
+ /** Convenience function for creating \ref GetFirst. */
+ template<class Tp>
+ GetFirst<Tp> getFirst( Tp & result_r )
+ { return GetFirst<Tp>( result_r ); }
+
+
+ /** Strore the last result found in the variable passed to the ctor.
+ */
+ template<class Tp>
+ struct GetLast
+ {
+ GetLast( Tp & result_r )
+ : _result( &result_r )
+ {}
+ bool operator()( const Tp & val_r )
+ { *_result = val_r; return true; }
+
+ private:
+ Tp * _result;
+ };
+
+ /** Convenience function for creating \ref GetLast. */
+ template<class Tp>
+ GetLast<Tp> getLast( Tp & result_r )
+ { return GetLast<Tp>( result_r ); }
+
+
+ /** Store all results found to some output_iterator.
+ * \code
+ * std::vector<parser::ProductFileData> result;
+ * parser::ProductFileReader::scanDir( functor::getAll( std::back_inserter( result ) ),
+ sysRoot / "etc/products.d" );
+ * \endcode
+ */
+ template<class TOutputIterator>
+ struct GetAll
+ {
+ GetAll( TOutputIterator result_r )
+ : _result( result_r )
+ {}
+
+ template<class Tp>
+ bool operator()( const Tp & val_r ) const
+ { *(_result++) = val_r; return true; }
+
+ private:
+ mutable TOutputIterator _result;
+ };
+
+ /** Convenience function for creating \ref GetAll. */
+ template<class TOutputIterator>
+ GetAll<TOutputIterator> getAll( TOutputIterator result_r )
+ { return GetAll<TOutputIterator>( result_r ); }
+
+ //@}
+ ///////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////
} // namespace functor
///////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////