diff --git a/src/lib/meta/duck-detector.hpp b/src/lib/meta/duck-detector.hpp index 5bc33d937..8c5a4656a 100644 --- a/src/lib/meta/duck-detector.hpp +++ b/src/lib/meta/duck-detector.hpp @@ -170,4 +170,44 @@ namespace lib { +/** Detector for a dereferentiation operator. Works like member detection */ +#define META_DETECT_OPERATOR_DEREF() \ + template \ + class HasOperator_deref \ + { \ + template \ + struct Probe \ + { }; \ + \ + template \ + static Yes_t check(Probe * ); \ + template \ + static No_t check(...); \ + \ + public: \ + static const bool value = (sizeof(Yes_t)==sizeof(check(0))); \ + }; + + + +/** Detector for a prefix increment operator. Works like function detection */ +#define META_DETECT_OPERATOR_INC() \ + template \ + class HasOperator_inc \ + { \ + template \ + struct Probe \ + { }; \ + \ + template \ + static Yes_t check(Probe * ); \ + template \ + static No_t check(...); \ + \ + public: \ + static const bool value = (sizeof(Yes_t)==sizeof(check(0))); \ + }; + + + #endif diff --git a/tests/40components.tests b/tests/40components.tests index 1bc9b1717..9cf00634d 100644 --- a/tests/40components.tests +++ b/tests/40components.tests @@ -356,7 +356,27 @@ out: ::12::11::10::9::8::7::6::5::4::3 END -PLANNED "Iterable type detection" IterableClassification_test < : Yes +out: can_STL_ForEach : Yes +out: can_STL_ForEach : Yes +out: can_STL_ForEach : Yes +out: can_STL_ForEach : Yes +out: can_STL_ForEach : Yes +out: can_STL_ForEach : No +out: can_STL_ForEach : No +out: can_STL_ForEach : No +out: can_STL_ForEach : No +out: can_IterForEach : No +out: can_IterForEach : No +out: can_IterForEach : No +out: can_IterForEach : No +out: can_IterForEach : No +out: can_IterForEach : No +out: can_IterForEach : Yes +out: can_IterForEach : Yes +out: can_IterForEach : Yes +out: can_IterForEach : Yes END diff --git a/tests/lib/meta/iterable-classification-test.cpp b/tests/lib/meta/iterable-classification-test.cpp index b922d8db3..930630626 100644 --- a/tests/lib/meta/iterable-classification-test.cpp +++ b/tests/lib/meta/iterable-classification-test.cpp @@ -30,6 +30,9 @@ #include "lib/itertools.hpp" #include "lib/lumitime.hpp" +/////////////////////////////////////////////////////////////TODO draft +#include +/////////////////////////////////////////////////////////////TODO draft #include #include #include @@ -41,16 +44,54 @@ namespace lib { /////////////////////////////////////////////////////////////TODO draft - template - struct can_STL_ForEach + template + class can_STL_ForEach { - enum{ value = false }; ////////////////TODO unimplemented + struct is_iterable + { + META_DETECT_NESTED(iterator); + META_DETECT_FUNCTION(typename X::iterator, begin,(void)); + META_DETECT_FUNCTION(typename X::iterator, end ,(void)); + + enum { value = HasNested_iterator::value + && HasFunSig_begin::value + && HasFunSig_end::value + }; + }; + + struct is_const_iterable + { + META_DETECT_NESTED(const_iterator); + META_DETECT_FUNCTION(typename X::const_iterator, begin,(void) const); + META_DETECT_FUNCTION(typename X::const_iterator, end ,(void) const); + + enum { value = HasNested_const_iterator::value + && HasFunSig_begin::value + && HasFunSig_end::value + }; + }; + + + public: + enum { value = is_iterable::value + || is_const_iterable::value + }; }; - template - struct can_IterForEach + template + class can_IterForEach { - enum{ value = false }; ////////////////TODO unimplemented + + META_DETECT_NESTED(value_type); + META_DETECT_OPERATOR_DEREF(); + META_DETECT_OPERATOR_INC(); + + public: + enum{ value = boost::is_convertible::value + && HasNested_value_type::value + && HasOperator_deref::value + && HasOperator_inc::value + }; }; /////////////////////////////////////////////////////////////TODO draft @@ -95,34 +136,38 @@ namespace test{ * Currently (1/10) we're able to detect the following * - a STL like container with \c begin() and \c end() * - a Lumiera Forward Iterator + * This test just retrieves the results of a compile time execution + * of the type detection; thus we just define types and then access + * the generated meta function value. */ class IterableClassification_test : public Test { - - - + void run (Arg) { + // define a bunch of STL containers typedef std::vector LongVector; typedef std::multiset