diff --git a/src/lib/diff/mutation-message.hpp b/src/lib/diff/mutation-message.hpp index 735c6ca07..b4ae1a1bc 100644 --- a/src/lib/diff/mutation-message.hpp +++ b/src/lib/diff/mutation-message.hpp @@ -100,7 +100,7 @@ namespace diff{ using std::__and_; using std::__not_; using lib::meta::enable_if; - using lib::meta::can_IterForEach; + using lib::meta::can_LumieraIter; using lib::meta::can_STL_ForEach; using DiffStep = TreeDiffLanguage::DiffStep; @@ -168,7 +168,7 @@ namespace diff{ * @note source iterator is copied into a heap allocated IterSource */ template - MutationMessage(IT&& ii, enable_if< can_IterForEach, void*> =nullptr) + MutationMessage(IT&& ii, enable_if< can_LumieraIter, void*> =nullptr) : _FrontEnd{iter_source::wrapIter (std::forward(ii))} { } @@ -179,7 +179,7 @@ namespace diff{ */ template MutationMessage(CON& container, enable_if< __and_< can_STL_ForEach - ,__not_>>, void*> =nullptr) + ,__not_>>, void*> =nullptr) : _FrontEnd{iter_source::eachEntry(container)} { } diff --git a/src/lib/format-util.hpp b/src/lib/format-util.hpp index 9a1e65ae2..80d044666 100644 --- a/src/lib/format-util.hpp +++ b/src/lib/format-util.hpp @@ -46,7 +46,7 @@ namespace util { - using lib::meta::can_IterForEach; + using lib::meta::lum_iter; using std::string; using std::forward; using std::move; @@ -141,7 +141,7 @@ namespace util { namespace { // helper to build range iterator on demand - template + template struct _RangeIter { using StlIter = CON::const_iterator; @@ -153,8 +153,8 @@ namespace util { { } }; - template - struct _RangeIter> > + template + struct _RangeIter { IT iter; diff --git a/src/lib/iter-adapter-stl.hpp b/src/lib/iter-adapter-stl.hpp index d0c3b2aca..8fa6617ac 100644 --- a/src/lib/iter-adapter-stl.hpp +++ b/src/lib/iter-adapter-stl.hpp @@ -431,11 +431,14 @@ namespace iter_stl { /** create empty snapshot */ IterSnapshot() { } + // standard copy operations acceptable + + /** take snapshot by discharging the given Lumiera Forward iterator * @warning depending on the implementation backing the source iterator, * this might or might not yield side-effects. */ - template + template> IterSnapshot (IT&& src) { for ( ; src; ++src) @@ -446,7 +449,7 @@ namespace iter_stl { * @warning depending on the implementation backing the source iterator, * this might or might not yield side-effects. */ - template + template> IterSnapshot (IT const& src) { for (IT copy{src}; copy; ++copy) @@ -469,11 +472,6 @@ namespace iter_stl { buffer_.emplace_back (*pos); } - IterSnapshot(IterSnapshot &&) = default; - IterSnapshot(IterSnapshot const&) = default; - IterSnapshot& operator= (IterSnapshot const&) = default; - IterSnapshot& operator= (IterSnapshot &&) = default; - explicit operator bool() const { diff --git a/src/lib/iter-adapter.hpp b/src/lib/iter-adapter.hpp index a7f85a150..7d3d85875 100644 --- a/src/lib/iter-adapter.hpp +++ b/src/lib/iter-adapter.hpp @@ -193,7 +193,7 @@ namespace lib { namespace iter { using meta::is_StateCore; - using meta::can_IterForEach; + using meta::can_LumieraIter; using meta::can_STL_ForEach; using meta::ValueTypeBinding; using meta::RefTraits; @@ -223,7 +223,7 @@ namespace lib { template struct Trait { - static constexpr bool is_LumieraIter = can_IterForEach::value; + static constexpr bool is_LumieraIter = meta::is_LumieraIter_v; static constexpr bool is_STLIter = std::input_iterator; static constexpr bool is_Legacy = legacy_traits_marked; @@ -579,7 +579,7 @@ namespace lib { class IterStateCore : public IT { - static_assert (iter::can_IterForEach::value + static_assert (iter::can_LumieraIter::value ,"Lumiera Iterator required as source"); protected: IT& diff --git a/src/lib/iter-explorer.hpp b/src/lib/iter-explorer.hpp index ea2349199..33a366f34 100644 --- a/src/lib/iter-explorer.hpp +++ b/src/lib/iter-explorer.hpp @@ -250,7 +250,7 @@ namespace lib { using std::is_lvalue_reference; using std::remove_reference_t; using meta::is_StateCore; - using meta::can_IterForEach; + using meta::can_LumieraIter; using meta::can_STL_ForEach; using meta::ValueTypeBinding; using meta::has_TypeResult; @@ -259,20 +259,20 @@ namespace lib { template struct shall_wrap_STL_Iter : __and_ - ,__not_> + ,__not_> > { }; template struct shall_use_Lumiera_Iter - : __and_ + : __and_ ,__not_> > { }; template struct shall_use_StateCore - : __and_<__not_> + : __and_<__not_> ,is_StateCore > { }; @@ -361,12 +361,12 @@ namespace lib { }; template - struct _FlatteningTraits, can_IterForEach >>> + struct _FlatteningTraits, can_LumieraIter >>> { using SrcAdapter = meta::RefTraits::value_type; }; template - struct _FlatteningTraits>, can_IterForEach >>> + struct _FlatteningTraits>, can_LumieraIter >>> { using NestedIter = meta::RefTraits::value_type; using SrcAdapter = iter_explorer::WrapperAdapter; @@ -612,7 +612,7 @@ namespace lib { class RedressAdapter : public SRC { - static_assert(can_IterForEach::value, "Lumiera Iterator required as source."); + static_assert(can_LumieraIter::value, "Lumiera Iterator required as source."); using SrcRes = iter::Yield; static_assert(meta::isLRef_v, "Source iterator must yield its result by-ref."); @@ -678,7 +678,7 @@ namespace lib { class Expander : public SRC { - static_assert(can_IterForEach::value, "Lumiera Iterator required as source"); + static_assert(can_LumieraIter::value, "Lumiera Iterator required as source"); using _Trait = _ExpanderTraits; using ResIter = _Trait::ResIter; @@ -897,10 +897,10 @@ namespace lib { class Flattener : public SRC { - static_assert(can_IterForEach::value, "Lumiera Iterator required as source"); + static_assert(can_LumieraIter::value, "Lumiera Iterator required as source"); using NestedIT = iter::Yield; - static_assert(can_IterForEach::value, "flatten() operation expects nested iterator"); + static_assert(can_LumieraIter::value, "flatten() operation expects nested iterator"); public: using value_type = meta::ValueTypeBinding::value_type; @@ -986,7 +986,7 @@ namespace lib { class Transformer : public SRC { - static_assert(can_IterForEach::value, "Lumiera Iterator required as source"); + static_assert(can_LumieraIter::value, "Lumiera Iterator required as source"); using TransformFunctor = function; using TransformedItem = wrapper::ItemWrapper; @@ -1216,7 +1216,7 @@ namespace lib { class Grouping : public SRC { - static_assert(can_IterForEach::value, "Lumiera Iterator required as source"); + static_assert(can_LumieraIter::value, "Lumiera Iterator required as source"); protected: using Group = std::array; @@ -1350,7 +1350,7 @@ namespace lib { class GroupAggregator : public SRC { - static_assert(can_IterForEach::value, "Lumiera Iterator required as source"); + static_assert(can_LumieraIter::value, "Lumiera Iterator required as source"); protected: using SrcValue = meta::ValueTypeBinding::value_type; @@ -1439,7 +1439,7 @@ namespace lib { class Filter : public SRC { - static_assert(can_IterForEach::value, "Lumiera Iterator required as source"); + static_assert(can_LumieraIter::value, "Lumiera Iterator required as source"); protected: using FilterPredicate = function; @@ -1540,7 +1540,7 @@ namespace lib { : public Filter { using _Filter = Filter; - static_assert(can_IterForEach::value, "Lumiera Iterator required as source"); + static_assert(can_LumieraIter::value, "Lumiera Iterator required as source"); public: MutableFilter() =default; @@ -1705,7 +1705,7 @@ namespace lib { class StopTrigger : public IterStateCore { - static_assert(can_IterForEach::value, "Lumiera Iterator required as source"); + static_assert(can_LumieraIter::value, "Lumiera Iterator required as source"); using Core = IterStateCore; using Cond = function; @@ -1905,7 +1905,7 @@ namespace lib { class IterExplorer : public SRC { - static_assert(can_IterForEach::value, "Lumiera Iterator required as source"); + static_assert(can_LumieraIter::value, "Lumiera Iterator required as source"); public: diff --git a/src/lib/itertools.hpp b/src/lib/itertools.hpp index 2fd3ca90a..405fd9ce6 100644 --- a/src/lib/itertools.hpp +++ b/src/lib/itertools.hpp @@ -405,7 +405,7 @@ namespace lib { class ValueAdapter : public SRC { - static_assert (can_IterForEach::value, "Lumiera Iterator required as source."); + static_assert (can_LumieraIter::value, "Lumiera Iterator required as source."); public: SRC::value_type diff --git a/src/lib/meta/trait.hpp b/src/lib/meta/trait.hpp index 9f2be1927..cb58b4a98 100644 --- a/src/lib/meta/trait.hpp +++ b/src/lib/meta/trait.hpp @@ -506,7 +506,7 @@ namespace meta { * @see IterableClassification_test */ template - class can_IterForEach + class can_LumieraIter { using Type = Strip::TypeReferred; @@ -524,6 +524,12 @@ namespace meta { }; }; + template + constexpr bool is_LumieraIter_v = meta::can_LumieraIter::value; + + template + concept lum_iter = is_LumieraIter_v; + /** Trait template to detect a type exposing a »state core« API. @@ -531,10 +537,10 @@ namespace meta { * with the help of lib::IterStateWrapper or lib::IterableDecorator. * This check is heuristic, based on the presence of function names. */ - template + template class is_StateCore { - using Type = Strip::TypeReferred; + using Type = Strip::TypeReferred; META_DETECT_FUNCTION_ARGLESS(checkPoint); META_DETECT_FUNCTION_ARGLESS(iterNext); @@ -547,10 +553,19 @@ namespace meta { }; }; + template + constexpr bool is_StateCore_v = is_StateCore::value; + + template + concept state_core = is_StateCore_v; + /** 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 + * @remark many Lumiera Iterators define those additional functions any + * can thus be used in a for-each loop, since a default-constructed + * Lumiera Iterator can act as an "end" sentinel. */ template class can_STL_ForEach diff --git a/src/lib/meta/tuple-accessor.hpp b/src/lib/meta/tuple-accessor.hpp deleted file mode 100644 index ad6e8de6a..000000000 --- a/src/lib/meta/tuple-accessor.hpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - TUPLE-ACCESSOR.hpp - metaprogramming utilities for type and data tuples - - Copyright (C) - 2016 Hermann Vosseler - -  **Lumiera** is free software; you can redistribute it and/or modify it -  under the terms of the GNU General Public License as published by the -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -*/ - - -/** @file tuple-accessor.hpp - ** Helper templates to access parts of a tuple. - ** - ** @todo 2026 this is old metaprogramming code, largely obsoleted by newer features of the C++ language. - ** However, since this code is still used in some basic support facilities, it was separated out, - ** so that it can be refactored as time permits. - ** - ** @see TupleHelper_test - ** - */ - - -#ifndef LIB_META_TUPLE_ACCESSOR_H -#define LIB_META_TUPLE_ACCESSOR_H - -#include "lib/meta/tuple-helper.hpp" -#include "lib/format-obj.hpp" - -#include - -namespace lib { -namespace meta { - - - - /** - * Decorating a tuple type with auxiliary data access operations. - * This helper template builds up a subclass of the given TUP (base) type - * (which is assumed to be a Tuple or at least need to be copy constructible - * from `Tuple` ). The purpose is to use the Tuple as storage record, but - * to add a layer of access functions, which in turn might rely on the exact - * type of the individual elements within the Tuple. To achieve this, for each - * type within the Tuple, the TUP type is decorated with an instance of the - * template passed in as template template parameter _X_. Each of these - * decorating instances is provided with an index number, allowing to - * access "his" specific element within the underlying tuple. - * - * The decorating template _X_ need to take its own base class as template - * parameter. Typically, operations on _X_ will be defined in a recursive fashion, - * calling down into this templated base class. To support this, an instantiation - * of _X_ with the empty type sequence is generated for detecting recursion end - * (built as innermost decorator, i.e. the immediate subclass of TUP) - */ - template - < template class _X_ ///< user provided template - , typename TYPES ///< Sequence of types to use within the Accessor - , class TUP =Tuple ///< the tuple type to build on - , uint i = 0 ///< tuple element index counter - > - class BuildTupleAccessor - { - // prepare recursion... - using Head = Split::Head; - using Tail = Split::Tail; - using NextBuilder = BuildTupleAccessor<_X_, Tail,TUP, i+1>; - using NextAccessor = NextBuilder::Product; - public: - - /** type of the product created by this template. - * Will be a subclass of TUP */ - using Product = _X_< Head // the type to use for this accessor - , NextAccessor // the base type to inherit from - , TUP // the tuple type we build upon - , i // current element index - >; - }; - - - template - < template class _X_ - , class TUP - , uint i - > - class BuildTupleAccessor< _X_, Types<>, TUP, i> - { - public: - using Product = _X_; // Note: i == tuple size - }; - - - - /** - * Helper to dump tuple contents. - * Defined to act as "Accessor" for BuildTupleAccessor, this helper template - * allows to create a recursive operation to invoke string conversion on - * all elements within any given tuple. - */ - template - < typename TY - , class BASE - , class TUP - , uint idx - > - struct TupleElementDisplayer - : BASE - { - using BASE::BASE; - - std::string - dump (std::string const& prefix ="(") const - { - return BASE::dump (prefix + util::toString(std::get(*this))+","); - } - }; - - template - struct TupleElementDisplayer - : TUP - { - TupleElementDisplayer (TUP const& tup) - : TUP(tup) - { } - - std::string - dump (std::string const& prefix ="(") const - { - if (1 < prefix.length()) - // remove the trailing comma - return prefix.substr (0, prefix.length()-1) +")"; - else - return prefix+")"; - } - }; - - - /** - * convenience function to dump a given tuple's contents. - * Using the BuildTupleAccessor, we layer a stack of Instantiations of - * the TupleElementDisplayer temporarily on top of the given tuple, - * just to invoke a recursive call chain through these layers - * and get a string representation of each element in the - * tuple. - */ - template - inline std::string - dump (std::tuple const& tuple) - { - using BuildAccessor = BuildTupleAccessor>; - using Displayer = BuildAccessor::Product ; - - return static_cast (tuple) - .dump(); - } - - - -}} // namespace lib::meta - - -// add a specialisation to enable tuple string conversion -namespace util { - - template - struct StringConv> - { - static std::string - invoke (std::tuple const& tuple) noexcept - try { - return "«"+typeStr(tuple) - + "»──" + lib::meta::dump (tuple); - } - catch(...) { return FAILURE_INDICATOR; } - }; - - -} // namespace util -#endif /*LIB_META_TUPLE_ACCESSOR_H*/ diff --git a/src/lib/meta/tuple-helper.hpp b/src/lib/meta/tuple-helper.hpp index b3a95b392..01b9f0c67 100644 --- a/src/lib/meta/tuple-helper.hpp +++ b/src/lib/meta/tuple-helper.hpp @@ -70,6 +70,7 @@ #include #include +#include #include diff --git a/src/lib/util-coll.hpp b/src/lib/util-coll.hpp index 06d819994..b06c01323 100644 --- a/src/lib/util-coll.hpp +++ b/src/lib/util-coll.hpp @@ -57,14 +57,14 @@ namespace util { typedef lib::meta::Unwrap::Type TaT; enum{ value = lib::meta::can_STL_ForEach::value - &&!lib::meta::can_IterForEach::value + &&!lib::meta::can_LumieraIter::value }; }; template struct treat_as_LumieraIterator { - enum{ value = lib::meta::can_IterForEach::value + enum{ value = lib::meta::can_LumieraIter::value }; }; diff --git a/src/lib/util-foreach.hpp b/src/lib/util-foreach.hpp index 438936a14..b67b785eb 100644 --- a/src/lib/util-foreach.hpp +++ b/src/lib/util-foreach.hpp @@ -56,7 +56,7 @@ namespace util { using lib::meta::disable_if; using lib::meta::can_STL_ForEach; - using lib::meta::can_IterForEach; + using lib::meta::can_LumieraIter; @@ -108,7 +108,7 @@ namespace util { template - inline disable_if< can_IterForEach, + inline disable_if< can_LumieraIter, FUN > for_each (Container const& coll, FUN doIt) { @@ -124,7 +124,7 @@ namespace util { template - inline enable_if< can_IterForEach, + inline enable_if< can_LumieraIter, FUN > for_each (IT const& ii, FUN doIt) { @@ -152,7 +152,7 @@ namespace util { template - inline enable_if< can_IterForEach, + inline enable_if< can_LumieraIter, bool > and_all (IT const& ii, FUN predicate) { @@ -179,7 +179,7 @@ namespace util { template - inline enable_if< can_IterForEach, + inline enable_if< can_LumieraIter, bool > has_any (IT const& ii, FUN predicate) { diff --git a/tests/lib/iter-zip-test.cpp b/tests/lib/iter-zip-test.cpp index f02280397..4df8e964f 100644 --- a/tests/lib/iter-zip-test.cpp +++ b/tests/lib/iter-zip-test.cpp @@ -20,6 +20,7 @@ #include "test/run.hpp" #include "lib/iter-zip.hpp" #include "lib/iter-explorer.hpp" +#include "lib/meta/tuple-helper.hpp" #include "test/test-helper.hpp" #include "lib/format-util.hpp" #include "lib/util.hpp" diff --git a/tests/lib/meta/iterable-classification-test.cpp b/tests/lib/meta/iterable-classification-test.cpp index 3cc500262..2206560a6 100644 --- a/tests/lib/meta/iterable-classification-test.cpp +++ b/tests/lib/meta/iterable-classification-test.cpp @@ -131,20 +131,20 @@ namespace test { CHECK (false == can_STL_ForEach::value ); // detect Lumiera Forward Iterator - CHECK (false == can_IterForEach::value ); - CHECK (false == can_IterForEach ::value ); - CHECK (false == can_IterForEach ::value ); - CHECK (false == can_IterForEach ::value ); - CHECK (false == can_IterForEach::value ); - CHECK (false == can_IterForEach::value ); + CHECK (false == can_LumieraIter::value ); + CHECK (false == can_LumieraIter ::value ); + CHECK (false == can_LumieraIter ::value ); + CHECK (false == can_LumieraIter ::value ); + CHECK (false == can_LumieraIter::value ); + CHECK (false == can_LumieraIter::value ); - CHECK ( true == can_IterForEach ::value ); - CHECK ( true == can_IterForEach ::value ); - CHECK ( true == can_IterForEach::value ); - CHECK ( true == can_IterForEach ::value ); + CHECK ( true == can_LumieraIter ::value ); + CHECK ( true == can_LumieraIter ::value ); + CHECK ( true == can_LumieraIter::value ); + CHECK ( true == can_LumieraIter ::value ); - CHECK (false == can_IterForEach::value ); - CHECK ( true == can_IterForEach::value ); // Note: Lumiera iterator capability added as wrapper + CHECK (false == can_LumieraIter::value ); + CHECK ( true == can_LumieraIter::value ); // Note: Lumiera iterator capability added as wrapper // detect State Core CHECK (false == is_StateCore::value ); diff --git a/tests/lib/stat/data-csv-test.cpp b/tests/lib/stat/data-csv-test.cpp index e16dcd1f1..a1aa0d4e6 100644 --- a/tests/lib/stat/data-csv-test.cpp +++ b/tests/lib/stat/data-csv-test.cpp @@ -283,7 +283,7 @@ namespace test{ CHECK (horror.isParseFail()); // CsvParser is a »Lumiera Forward Iterator« - CHECK (meta::can_IterForEach::value); + CHECK (meta::lum_iter); } diff --git a/tests/lib/util-collection-test.cpp b/tests/lib/util-collection-test.cpp index a5c142ec7..f98897cc8 100644 --- a/tests/lib/util-collection-test.cpp +++ b/tests/lib/util-collection-test.cpp @@ -33,7 +33,7 @@ using util::first; using util::last; using lib::meta::can_STL_ForEach; -using lib::meta::can_IterForEach; +using lib::meta::can_LumieraIter; using lib::meta::can_STL_backIteration; using boost::lexical_cast; @@ -131,8 +131,8 @@ namespace test { CHECK (!can_STL_ForEach::value); CHECK (!can_STL_backIteration::value); - CHECK (!can_IterForEach::value); - CHECK ( can_IterForEach::value); + CHECK (!can_LumieraIter::value); + CHECK ( can_LumieraIter::value); } };