extended for-each looping helpers. Closes #479

This commit is contained in:
Fischlurch 2010-01-04 14:48:00 +01:00
parent bf48ebc272
commit 330eb2c243
5 changed files with 217 additions and 153 deletions

View file

@ -42,7 +42,7 @@ namespace util {
/**
* Abstraction of the usual "int argc, int** argv"-Commandline,
* to be able to treat it as a vector of strings. Inherits from
* vector<std::string>, but provides convienient conversions to
* vector<std::string>, but provides convenient conversions to
* string (joining delimited by space)...
*/
class Cmdline : public VectS

View file

@ -21,6 +21,24 @@
*/
/** @file util-foreach.hpp
** Perform operations "for each element" of a collection.
** This header defines various flavours of these active iteration functions, which all take
** a functor and invoke it in some way over the collection's elements.
** - basic constructs
** - for_each
** - and_all (all quantisation)
** - has_any (existence quantisation)
** - kinds of collection
** - STL collections and anything which has an iterator, \c begin() and \c end()
** - "Lumiera Forward Iterator" instance to yield all the elements of the collection
** - support for on-the-fly binding up to 4 arguments of the functor
**
** @see util-foreach-test.cpp
**
*/
#ifndef UTIL_FOREACH_H
#define UTIL_FOREACH_H
@ -76,7 +94,11 @@ namespace util {
/* === specialisations for STL containers and Lumiera Forward Iterators === */
/** shortcut for operating on all elements of a STL container. */
/** operating on all elements of a STL container.
* @note this case is the default and kicks in
* \em unless we detect a Lumiera iterator.
* The handling is different for and_all
*/
template <typename Container
,typename FUN
>
@ -88,28 +110,215 @@ namespace util {
}
/** operating on a Lumiera Forward Iterator until exhaustion. */
template <typename IT
,typename FUN
>
inline typename enable_if< can_IterForEach<IT>,
FUN >::type
for_each (IT& ii, FUN doIt)
{
return std::for_each (ii, IT(), doIt);
}
template <typename Container
,typename FUN
>
inline typename enable_if< can_STL_ForEach<Container>,
bool >::type
bool >::type
and_all (Container& coll, FUN predicate)
{
return and_all (coll.begin(),coll.end(), predicate);
}
template <typename IT
,typename FUN
>
inline typename enable_if< can_IterForEach<IT>,
bool >::type
and_all (IT& ii, FUN predicate)
{
return and_all (ii, IT(), predicate);
}
template <typename Container
,typename FUN
>
inline typename enable_if< can_STL_ForEach<Container>,
bool >::type
bool >::type
has_any (Container& coll, FUN predicate)
{
return has_any (coll.begin(),coll.end(), predicate);
}
template <typename IT
,typename FUN
>
inline typename enable_if< can_IterForEach<IT>,
bool >::type
has_any (IT& ii, FUN predicate)
{
return has_any (ii, IT(), predicate);
}
/* === allow creating argument binders on-the-fly === */
template < typename CON, typename FUN
, typename P1
>
inline void //________________________________
for_each (CON& elements, FUN function, P1 bind1) ///< Accept binding for 1 Argument
{
for_each (elements, std::tr1::bind (function, bind1));
}
template < typename CON, typename FUN
, typename P1
, typename P2
>
inline void //________________________________
for_each (CON& elements, FUN function, P1 bind1, P2 bind2) ///< Accept binding for 2 Arguments
{
for_each (elements, std::tr1::bind (function, bind1, bind2));
}
template < typename CON, typename FUN
, typename P1
, typename P2
, typename P3
>
inline void //________________________________
for_each (CON& elements, FUN function, P1 bind1, P2 bind2, P3 bind3) ///< Accept binding for 3 Arguments
{
for_each (elements, std::tr1::bind (function, bind1, bind2, bind3));
}
template < typename CON, typename FUN
, typename P1
, typename P2
, typename P3
, typename P4
>
inline void //________________________________
for_each (CON& elements, FUN function, P1 bind1, P2 bind2, P3 bind3, P4 bind4) ///< Accept binding for 4 Arguments
{
for_each (elements, std::tr1::bind (function, bind1, bind2, bind3, bind4));
}
template < typename CON, typename FUN
, typename P1
>
inline bool //________________________________
and_all (CON& elements, FUN function, P1 bind1) ///< Accept binding for 1 Argument
{
return and_all (elements, std::tr1::bind<bool> (function, bind1));
}
template < typename CON, typename FUN
, typename P1
, typename P2
>
inline bool //________________________________
and_all (CON& elements, FUN function, P1 bind1, P2 bind2) ///< Accept binding for 2 Arguments
{
return and_all (elements, std::tr1::bind<bool> (function, bind1, bind2));
}
template < typename CON, typename FUN
, typename P1
, typename P2
, typename P3
>
inline bool //________________________________
and_all (CON& elements, FUN function, P1 bind1, P2 bind2, P3 bind3) ///< Accept binding for 3 Arguments
{
return and_all (elements, std::tr1::bind<bool> (function, bind1, bind2, bind3));
}
template < typename CON, typename FUN
, typename P1
, typename P2
, typename P3
, typename P4
>
inline bool //________________________________
and_all (CON& elements, FUN function, P1 bind1, P2 bind2, P3 bind3, P4 bind4) ///< Accept binding for 4 Arguments
{
return and_all (elements, std::tr1::bind<bool> (function, bind1, bind2, bind3, bind4));
}
template < typename CON, typename FUN
, typename P1
>
inline bool //________________________________
has_any (CON& elements, FUN function, P1 bind1) ///< Accept binding for 1 Argument
{
return has_any (elements, std::tr1::bind<bool> (function, bind1));
}
template < typename CON, typename FUN
, typename P1
, typename P2
>
inline bool //________________________________
has_any (CON& elements, FUN function, P1 bind1, P2 bind2) ///< Accept binding for 2 Arguments
{
return has_any (elements, std::tr1::bind<bool> (function, bind1, bind2));
}
template < typename CON, typename FUN
, typename P1
, typename P2
, typename P3
>
inline bool //________________________________
has_any (CON& elements, FUN function, P1 bind1, P2 bind2, P3 bind3) ///< Accept binding for 3 Arguments
{
return has_any (elements, std::tr1::bind<bool> (function, bind1, bind2, bind3));
}
template < typename CON, typename FUN
, typename P1
, typename P2
, typename P3
, typename P4
>
inline bool //________________________________
has_any (CON& elements, FUN function, P1 bind1, P2 bind2, P3 bind3, P4 bind4) ///< Accept binding for 4 Arguments
{
return has_any (elements, std::tr1::bind<bool> (function, bind1, bind2, bind3, bind4));
}
} // namespace util
#endif /*UTIL_FOREACH_H*/

View file

@ -249,7 +249,7 @@ namespace control {
/** @return number distinguishable registered command \em instances */
/** @return number of distinguishable registered command \em instances */
size_t
Command::instance_count()
{

View file

@ -23,6 +23,7 @@
#include "lib/test/run.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/util.hpp"
#include "lib/util-foreach.hpp"
@ -34,6 +35,7 @@
#include <boost/lexical_cast.hpp>
using boost::lexical_cast;
using lib::test::showSizeof;
using util::for_each;
using util::isnil;
using ::Test;
@ -177,7 +179,7 @@ namespace lib {
ASSERT (&ref2);
ASSERT (&ref3);
ASSERT (&rX);
TRACE (test, "sizeof( Dummy<1234> ) = %u", sizeof(rX));
TRACE (test, "%s", showSizeof(rX).c_str());
ASSERT (123==ref2.getID());
ASSERT (3+4+5==rX.getID());

View file

@ -49,153 +49,6 @@ using namespace boost::lambda;
namespace util {
///////////////////////////////////////////////////////////////////////////TODO: Implementation draft
template <typename IT
,typename FUN
>
inline typename enable_if< can_IterForEach<IT>,
FUN >::type
for_each (IT& ii, FUN doIt)
{
return std::for_each (ii, IT(), doIt);
}
template <typename IT
,typename FUN
>
inline typename enable_if< can_IterForEach<IT>,
bool >::type
and_all (IT& ii, FUN predicate)
{
return and_all (ii, IT(), predicate);
}
template <typename IT
,typename FUN
>
inline typename enable_if< can_IterForEach<IT>,
bool >::type
has_any (IT& ii, FUN predicate)
{
return has_any (ii, IT(), predicate);
}
using std::tr1::bind;
template < typename CON, typename FUN
, typename P1
>
inline void //________________________________
for_each (CON& elements, FUN function, P1 bind1) ///< Accept binding for 1 Argument
{
for_each (elements, std::tr1::bind (function, bind1));
}
template < typename CON, typename FUN
, typename P1
, typename P2
>
inline void //________________________________
for_each (CON& elements, FUN function, P1 bind1, P2 bind2) ///< Accept binding for 2 Arguments
{
for_each (elements, std::tr1::bind (function, bind1, bind2));
}
template < typename CON, typename FUN
, typename P1
, typename P2
, typename P3
>
inline void //________________________________
for_each (CON& elements, FUN function, P1 bind1, P2 bind2, P3 bind3) ///< Accept binding for 3 Arguments
{
for_each (elements, std::tr1::bind (function, bind1, bind2, bind3));
}
template < typename CON, typename FUN
, typename P1
>
inline bool //________________________________
and_all (CON& elements, FUN function, P1 bind1) ///< Accept binding for 1 Argument
{
return and_all (elements, std::tr1::bind<bool> (function, bind1));
}
template < typename CON, typename FUN
, typename P1
, typename P2
>
inline bool //________________________________
and_all (CON& elements, FUN function, P1 bind1, P2 bind2) ///< Accept binding for 2 Arguments
{
return and_all (elements, std::tr1::bind<bool> (function, bind1, bind2));
}
template < typename CON, typename FUN
, typename P1
, typename P2
, typename P3
>
inline bool //________________________________
and_all (CON& elements, FUN function, P1 bind1, P2 bind2, P3 bind3) ///< Accept binding for 3 Arguments
{
return and_all (elements, std::tr1::bind<bool> (function, bind1, bind2, bind3));
}
template < typename CON, typename FUN
, typename P1
>
inline bool //________________________________
has_any (CON& elements, FUN function, P1 bind1) ///< Accept binding for 1 Argument
{
return has_any (elements, std::tr1::bind<bool> (function, bind1));
}
template < typename CON, typename FUN
, typename P1
, typename P2
>
inline bool //________________________________
has_any (CON& elements, FUN function, P1 bind1, P2 bind2) ///< Accept binding for 2 Arguments
{
return has_any (elements, std::tr1::bind<bool> (function, bind1, bind2));
}
template < typename CON, typename FUN
, typename P1
, typename P2
, typename P3
>
inline bool //________________________________
has_any (CON& elements, FUN function, P1 bind1, P2 bind2, P3 bind3) ///< Accept binding for 3 Arguments
{
return has_any (elements, std::tr1::bind<bool> (function, bind1, bind2, bind3));
}
///////////////////////////////////////////////////////////////////////////TODO: Implementation draft (END)
namespace test {
typedef std::vector<int> VecI;