From 330eb2c243d63547655cc15aec9fa57830f45d08 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 4 Jan 2010 14:48:00 +0100 Subject: [PATCH] extended for-each looping helpers. Closes #479 --- src/lib/cmdline.hpp | 2 +- src/lib/util-foreach.hpp | 215 +++++++++++++++++++++++++++- src/proc/control/command.cpp | 2 +- tests/lib/allocationclustertest.cpp | 4 +- tests/lib/util-foreach-test.cpp | 147 ------------------- 5 files changed, 217 insertions(+), 153 deletions(-) diff --git a/src/lib/cmdline.hpp b/src/lib/cmdline.hpp index 31d49acff..1353a9d1d 100644 --- a/src/lib/cmdline.hpp +++ b/src/lib/cmdline.hpp @@ -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, but provides convienient conversions to + * vector, but provides convenient conversions to * string (joining delimited by space)... */ class Cmdline : public VectS diff --git a/src/lib/util-foreach.hpp b/src/lib/util-foreach.hpp index b0a3f9989..692328372 100644 --- a/src/lib/util-foreach.hpp +++ b/src/lib/util-foreach.hpp @@ -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 @@ -88,28 +110,215 @@ namespace util { } + /** operating on a Lumiera Forward Iterator until exhaustion. */ + template + inline typename enable_if< can_IterForEach, + FUN >::type + for_each (IT& ii, FUN doIt) + { + return std::for_each (ii, IT(), doIt); + } + + + template inline typename enable_if< can_STL_ForEach, - bool >::type + bool >::type and_all (Container& coll, FUN predicate) { return and_all (coll.begin(),coll.end(), predicate); } + template + inline typename enable_if< can_IterForEach, + bool >::type + and_all (IT& ii, FUN predicate) + { + return and_all (ii, IT(), predicate); + } + + + template inline typename enable_if< can_STL_ForEach, - bool >::type + bool >::type has_any (Container& coll, FUN predicate) { return has_any (coll.begin(),coll.end(), predicate); } + template + inline typename enable_if< can_IterForEach, + 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 (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 (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 (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 (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 (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 (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 (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 (function, bind1, bind2, bind3, bind4)); + } + + + + } // namespace util #endif /*UTIL_FOREACH_H*/ diff --git a/src/proc/control/command.cpp b/src/proc/control/command.cpp index fd6068316..55d9a1ef0 100644 --- a/src/proc/control/command.cpp +++ b/src/proc/control/command.cpp @@ -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() { diff --git a/tests/lib/allocationclustertest.cpp b/tests/lib/allocationclustertest.cpp index ffbba08cd..42ea6fcca 100644 --- a/tests/lib/allocationclustertest.cpp +++ b/tests/lib/allocationclustertest.cpp @@ -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 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()); diff --git a/tests/lib/util-foreach-test.cpp b/tests/lib/util-foreach-test.cpp index 2691b7ecf..fbf9a8cb2 100644 --- a/tests/lib/util-foreach-test.cpp +++ b/tests/lib/util-foreach-test.cpp @@ -49,153 +49,6 @@ using namespace boost::lambda; namespace util { -///////////////////////////////////////////////////////////////////////////TODO: Implementation draft - - template - inline typename enable_if< can_IterForEach, - FUN >::type - for_each (IT& ii, FUN doIt) - { - return std::for_each (ii, IT(), doIt); - } - - - - template - inline typename enable_if< can_IterForEach, - bool >::type - and_all (IT& ii, FUN predicate) - { - return and_all (ii, IT(), predicate); - } - - - template - inline typename enable_if< can_IterForEach, - 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 (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 (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 (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 (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 (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 (function, bind1, bind2, bind3)); - } - - - -///////////////////////////////////////////////////////////////////////////TODO: Implementation draft (END) namespace test { typedef std::vector VecI;