diff --git a/research/try.cpp b/research/try.cpp index 59eb6397b..818929e1c 100644 --- a/research/try.cpp +++ b/research/try.cpp @@ -68,7 +68,9 @@ using lib::diff::GenNode; using lib::diff::DataValues; using lib::meta::Types; using lib::meta::Tuple; +using lib::meta::Pick; using lib::meta::IndexSeq; +using lib::meta::IndexIter; using lib::meta::BuildIndexSeq; using lib::meta::InstantiateChained; using lib::meta::Filter; @@ -80,86 +82,6 @@ using std::tuple; namespace error = lumiera::error; - //////////////////////////////////////TODO traits -namespace lib { -namespace meta { - using std::is_constructible; - using std::is_unsigned; - using std::is_signed; - using std::is_floating_point; - - - template - struct is_nonFloat - : __and_ - ,__not_> - > - { }; - - /** temporary workaround for GCC [Bug-63723], necessary until CGG-5 - * @remarks The problem is that GCC emits a warning on narrowing conversion, - * instead of letting the SFINAE substitution fail. This can be considered - * questionable behaviour, since the usual implementation of a `is_convertible` - * trait uses initialisation from a brace enclosed list, where C++11 prohibits - * narrowing conversions. Now the problem is, that we'll use such traits checks - * to remove such _impossble_ cases from generated trampoline tables or visitor - * double dispatch implementations. Thus, for one we get lots of warnings at that - * point when generating those trampoline tables (at initialisation), while it - * is not clear we'll trigger those cases, and, when we do, we'll get narrowing - * conversions in a context where we're unable to cope with them or protect - * ourselves against spurious conversions. - * What follows is a quick-n-dirty hack to remove such unwanted conversions. - * - * [Bug-63723]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63723 - */ - template - struct is_narrowingInit - : __or_<__and_, is_signed> - ,__and_, is_unsigned> - ,__and_, is_floating_point> - ,__and_, is_nonFloat> - ,__not_> - > - { }; - -#define TRAIT_IS_NARROWING(_SRC_, _TAR_) \ - template<> \ - struct is_narrowingInit<_SRC_, _TAR_> \ - : std::true_type \ - { }; - - TRAIT_IS_NARROWING (int64_t, int32_t) - TRAIT_IS_NARROWING (int64_t, int16_t) - TRAIT_IS_NARROWING (int64_t, int8_t) - TRAIT_IS_NARROWING (int32_t, int16_t) - TRAIT_IS_NARROWING (int32_t, int8_t) - TRAIT_IS_NARROWING (int16_t, int8_t) - TRAIT_IS_NARROWING (int16_t, short) - TRAIT_IS_NARROWING (int16_t, char) - - TRAIT_IS_NARROWING (uint64_t, uint32_t) - TRAIT_IS_NARROWING (uint64_t, uint16_t) - TRAIT_IS_NARROWING (uint64_t, uint8_t) - TRAIT_IS_NARROWING (uint32_t, uint16_t) - TRAIT_IS_NARROWING (uint32_t, uint8_t) - TRAIT_IS_NARROWING (uint16_t, uint8_t) - TRAIT_IS_NARROWING (uint16_t, ushort) - - TRAIT_IS_NARROWING (double, float) - - TRAIT_IS_NARROWING (lib::hash::LuidH, int64_t) - TRAIT_IS_NARROWING (lib::hash::LuidH, int32_t) - TRAIT_IS_NARROWING (lib::hash::LuidH, int16_t) - TRAIT_IS_NARROWING (lib::hash::LuidH, int8_t) - TRAIT_IS_NARROWING (lib::hash::LuidH, char) - TRAIT_IS_NARROWING (lib::hash::LuidH, uint16_t) - TRAIT_IS_NARROWING (lib::hash::LuidH, uint8_t) - TRAIT_IS_NARROWING (lib::hash::LuidH, double) - TRAIT_IS_NARROWING (lib::hash::LuidH, float) - -#undef TRAIT_IS_NARROWING - -}} //////////////////////////////////////TODO traits using std::__not_; using std::__and_; using std::__or_; @@ -175,6 +97,19 @@ template struct GenNodeAccessor : boost::noncopyable { + + template + struct allow_Conversion + : __and_ + ,__not_::TypePlain + ,typename Strip::TypePlain>> + > + { }; + + using SupportedSourceTypes = typename Filter::List; + + + struct ConverterBase : DataCapPredicate { @@ -193,15 +128,6 @@ struct GenNodeAccessor }; }; - template - struct allow_Conversion - : __and_ - ,__not_::TypePlain - ,typename Strip::TypePlain>> - > - { }; - - using SupportedSourceTypes = typename Filter::List; using ConversionBuffer = InstantiateChained< SupportedSourceTypes , Converter @@ -225,23 +151,14 @@ struct GenNodeAccessor } }; -//////////TODO this goes into typeseq-util.hpp -template -struct Pick; - -template -struct Pick, i> - { - using Type = typename lib::meta::Shifted, i>::Head; - }; template -struct ElementMapper; +struct ElementExtractor; template -struct ElementMapper> +struct ElementExtractor> { template using TargetType = typename Pick, i>::Type; @@ -263,47 +180,42 @@ struct ElementMapper> -template -struct IdxIter; -template -struct IdxIter> + + +template< typename TYPES + , template class _ElmMapper_ + , class SEQ + > +struct TupleConstructor; + +template< typename TYPES + , template class _ElmMapper_ + , size_t...idx + > +struct TupleConstructor> + : Tuple { - /////TODO as long as Types is not variadic (#987), we need to strip NullType here (instead of just using sizeof...(TYPES) - enum {SIZ = lib::meta::count::List>::value }; - - using Seq = typename BuildIndexSeq::Ascending; - }; - - - -template -class TupleBuilder; - -template -class TupleBuilder> - : public Tuple - { - template - using PickArg = typename ElementMapper::template Access; - public: template - TupleBuilder (SRC values) - : Tuple (PickArg{values}...) + TupleConstructor (SRC values) + : Tuple (_ElmMapper_, idx>{values}...) { } }; - + + +template +using PickArg = typename ElementExtractor::template Access; template Tuple buildTuple (SRC values) { - using IndexSeq = typename IdxIter::Seq; + using IndexSeq = typename IndexIter::Seq; - return TupleBuilder (values); + return TupleConstructor (values); } diff --git a/src/lib/meta/trait.hpp b/src/lib/meta/trait.hpp index 189207a67..2f25bd4eb 100644 --- a/src/lib/meta/trait.hpp +++ b/src/lib/meta/trait.hpp @@ -74,10 +74,14 @@ namespace std { } namespace lib{ template class P; -} + + namespace hash { + class LuidH; +}} +namespace proc { namespace mobject{ template class Placement; -} +}} namespace lib { @@ -87,7 +91,11 @@ namespace meta { using std::remove_pointer; using std::remove_reference; using std::is_convertible; + using std::is_constructible; + using std::is_floating_point; using std::is_arithmetic; + using std::is_unsigned; + using std::is_signed; using std::is_same; using std::__not_; using std::__and_; @@ -309,6 +317,82 @@ namespace meta { + + template + struct is_nonFloat + : __and_ + ,__not_> + > + { }; + + /** temporary workaround for GCC [Bug-63723], necessary until CGG-5 + * @remarks The problem is that GCC emits a warning on narrowing conversion, + * instead of letting the SFINAE substitution fail. This can be considered + * questionable behaviour, since the usual implementation of a `is_convertible` + * trait uses initialisation from a brace enclosed list, where C++11 prohibits + * narrowing conversions. Now the problem is, that we'll use such traits checks + * to remove such _impossble_ cases from generated trampoline tables or visitor + * double dispatch implementations. Thus, for one we get lots of warnings at that + * point when generating those trampoline tables (at initialisation), while it + * is not clear we'll trigger those cases, and, when we do, we'll get narrowing + * conversions in a context where we're unable to cope with them or protect + * ourselves against spurious conversions. + * What follows is a quick-n-dirty hack to remove such unwanted conversions. + * + * [Bug-63723]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63723 + */ + template + struct is_narrowingInit + : __or_<__and_, is_signed> + ,__and_, is_unsigned> + ,__and_, is_floating_point> + ,__and_, is_nonFloat> + ,__not_> + > + { }; + +#define TRAIT_IS_NARROWING(_SRC_, _TAR_) \ + template<> \ + struct is_narrowingInit<_SRC_, _TAR_> \ + : std::true_type \ + { }; + + TRAIT_IS_NARROWING (int64_t, int32_t) + TRAIT_IS_NARROWING (int64_t, int16_t) + TRAIT_IS_NARROWING (int64_t, int8_t) + TRAIT_IS_NARROWING (int32_t, int16_t) + TRAIT_IS_NARROWING (int32_t, int8_t) + TRAIT_IS_NARROWING (int16_t, int8_t) + TRAIT_IS_NARROWING (int16_t, short) + TRAIT_IS_NARROWING (int16_t, char) + + TRAIT_IS_NARROWING (uint64_t, uint32_t) + TRAIT_IS_NARROWING (uint64_t, uint16_t) + TRAIT_IS_NARROWING (uint64_t, uint8_t) + TRAIT_IS_NARROWING (uint32_t, uint16_t) + TRAIT_IS_NARROWING (uint32_t, uint8_t) + TRAIT_IS_NARROWING (uint16_t, uint8_t) + TRAIT_IS_NARROWING (uint16_t, ushort) + + TRAIT_IS_NARROWING (double, float) + + TRAIT_IS_NARROWING (lib::hash::LuidH, int64_t) + TRAIT_IS_NARROWING (lib::hash::LuidH, int32_t) + TRAIT_IS_NARROWING (lib::hash::LuidH, int16_t) + TRAIT_IS_NARROWING (lib::hash::LuidH, int8_t) + TRAIT_IS_NARROWING (lib::hash::LuidH, char) + TRAIT_IS_NARROWING (lib::hash::LuidH, uint16_t) + TRAIT_IS_NARROWING (lib::hash::LuidH, uint8_t) + TRAIT_IS_NARROWING (lib::hash::LuidH, double) + TRAIT_IS_NARROWING (lib::hash::LuidH, float) + +#undef TRAIT_IS_NARROWING + + + + + + /* ====== generic iteration support ====== */ /** Trait template to detect a type usable immediately as diff --git a/src/lib/meta/tuple-helper.hpp b/src/lib/meta/tuple-helper.hpp index db65c34bd..3fc5d47fc 100644 --- a/src/lib/meta/tuple-helper.hpp +++ b/src/lib/meta/tuple-helper.hpp @@ -228,6 +228,22 @@ namespace meta { }; + + /** build an index number sequence from a structured reference type */ + template + struct IndexIter; + + /** build an index number sequence from a type sequence */ + template + struct IndexIter> + { + /////TODO as long as Types is not variadic (#987), we need to strip NullType here (instead of just using sizeof...(TYPES) + enum {SIZ = lib::meta::count::List>::value }; + + using Seq = typename BuildIndexSeq::Ascending; + }; + + diff --git a/src/lib/meta/typelist-manip.hpp b/src/lib/meta/typelist-manip.hpp index 536630e13..b6ab6ca9d 100644 --- a/src/lib/meta/typelist-manip.hpp +++ b/src/lib/meta/typelist-manip.hpp @@ -63,7 +63,7 @@ namespace meta { /** pick the n-th element from a typelist */ - template + template struct Pick { typedef NullType Type; @@ -73,7 +73,7 @@ namespace meta { { typedef TY Type; }; - template + template struct Pick, i> { typedef typename Pick::Type Type; diff --git a/src/lib/meta/typeseq-util.hpp b/src/lib/meta/typeseq-util.hpp index 79c76e878..88f4d9ba1 100644 --- a/src/lib/meta/typeseq-util.hpp +++ b/src/lib/meta/typeseq-util.hpp @@ -201,6 +201,18 @@ namespace meta { + /** + * specialisation: pick n-th element from a type sequence + * @see typelist-manip.hpp + */ + template + struct Pick, i> + { + using Type = typename lib::meta::Shifted, i>::Head; + }; + + + }} // namespace lib::meta