diff --git a/src/lib/meta/trait.hpp b/src/lib/meta/trait.hpp index 3c5ecbe0d..22d6743e9 100644 --- a/src/lib/meta/trait.hpp +++ b/src/lib/meta/trait.hpp @@ -254,6 +254,31 @@ namespace meta { + /** Trait template to detect a type usable immediately as + * "Lumiera Forward Iterator" in a specialised for-each loop + * This is just a heuristic, based on some common properties + * of such iterators; it is enough to distinguish it from an + * STL container, but can certainly be refined. + */ + template + class can_IterForEach + { + typedef typename Strip::Type Type; + + 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 + }; + }; + + + /** Trait template to detect a type usable with the STL for-each loop. * Basically we're looking for the functions to get the begin/end iterator */ @@ -294,29 +319,44 @@ namespace meta { }; - /** Trait template to detect a type usable immediately as - * "Lumiera Forward Iterator" in a specialised for-each loop - * This is just a heuristic, based on some common properties - * of such iterators; it is enough to distinguish it from an - * STL container, but can certainly be refined. - */ + /** Trait template to detect a type also supporting STL-style backwards iteration */ template - class can_IterForEach + class can_STL_backIteration { typedef typename Strip::Type Type; - - META_DETECT_NESTED(value_type); - META_DETECT_OPERATOR_DEREF(); - META_DETECT_OPERATOR_INC(); + + struct is_backIterable + { + META_DETECT_NESTED(reverse_iterator); + META_DETECT_FUNCTION(typename X::reverse_iterator, rbegin,(void)); + META_DETECT_FUNCTION(typename X::reverse_iterator, rend ,(void)); + + enum { value = HasNested_reverse_iterator::value + && HasFunSig_rbegin::value + && HasFunSig_rend::value + }; + }; + + struct is_const_backIterable + { + META_DETECT_NESTED(const_reverse_iterator); + META_DETECT_FUNCTION(typename X::const_reverse_iterator, rbegin,(void) const); + META_DETECT_FUNCTION(typename X::const_reverse_iterator, rend ,(void) const); + + enum { value = HasNested_const_reverse_iterator::value + && HasFunSig_rbegin::value + && HasFunSig_rend::value + }; + }; + public: - enum{ value = boost::is_convertible::value - && HasNested_value_type::value - && HasOperator_deref::value - && HasOperator_inc::value - }; + enum { value = is_backIterable::value + || is_const_backIterable::value + }; }; + }} // namespace lib::meta #endif