Library: streamline value-type bindings
- use uniform naming scheme - extract type-binding from RangeIter into a trait-template - use the C++20 iterator concept and trait to detect a STL iterator
This commit is contained in:
parent
68460d4900
commit
fbda9baeb3
6 changed files with 84 additions and 47 deletions
|
|
@ -50,8 +50,8 @@ namespace lib {
|
|||
|
||||
using ResVal = decltype(data_->operator[](0));
|
||||
|
||||
using value_type = meta::RefTraits<ResVal>::Value;
|
||||
using reference = meta::RefTraits<ResVal>::Reference;
|
||||
using value_type = meta::RefTraits<ResVal>::value_type;
|
||||
using reference = meta::RefTraits<ResVal>::reference;
|
||||
|
||||
bool
|
||||
checkPoint() const
|
||||
|
|
|
|||
|
|
@ -120,6 +120,9 @@ namespace util { // see lib/util.hpp
|
|||
|
||||
namespace lib {
|
||||
|
||||
using std::is_pointer_v;
|
||||
using std::remove_pointer_t;
|
||||
using std::remove_reference_t;
|
||||
|
||||
namespace { // internal helpers
|
||||
inline void
|
||||
|
|
@ -149,6 +152,13 @@ namespace lib {
|
|||
|
||||
|
||||
namespace iter {
|
||||
using meta::is_StateCore;
|
||||
using meta::can_IterForEach;
|
||||
using meta::can_STL_ForEach;
|
||||
using meta::ValueTypeBinding;
|
||||
using meta::RefTraits;
|
||||
|
||||
|
||||
/** type binding helper: an iterato's actual result type */
|
||||
template<class IT>
|
||||
using Yield = decltype(std::declval<IT>().operator*());
|
||||
|
|
@ -157,6 +167,34 @@ namespace lib {
|
|||
template<class COR>
|
||||
using CoreYield = decltype(std::declval<COR>().yield());
|
||||
|
||||
|
||||
template<class IT>
|
||||
concept legacy_traits_marked = requires
|
||||
{
|
||||
typename std::iterator_traits<IT>::value_type;
|
||||
};
|
||||
|
||||
template<class IT>
|
||||
concept stl_iter = std::input_iterator<IT> or legacy_traits_marked<IT>;
|
||||
|
||||
|
||||
/** Iterator-Traits: definitions to level the difference between
|
||||
* Lumiera-Iterators and the STL usage of ranges / iterators.
|
||||
*/
|
||||
template<class IT>
|
||||
struct Trait
|
||||
{
|
||||
static constexpr bool is_LumieraIter = can_IterForEach<IT>::value;
|
||||
static constexpr bool is_STLIter = stl_iter<IT>;
|
||||
|
||||
// static_assert(is_LumieraIter or is_STLIter);
|
||||
|
||||
using _ValTrait = std::conditional_t<is_LumieraIter, ValueTypeBinding<IT>
|
||||
, RefTraits<std::iter_reference_t<IT>>>;
|
||||
using value_type = _ValTrait::value_type;
|
||||
using reference = _ValTrait::reference;
|
||||
using pointer = _ValTrait::pointer;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -302,7 +340,7 @@ namespace lib {
|
|||
|
||||
|
||||
protected:
|
||||
using ConRef = meta::RefTraits<CON>::Reference;
|
||||
using ConRef = meta::RefTraits<CON>::reference;
|
||||
|
||||
/** allow derived classes to access backing container */
|
||||
ConRef source() { return source_; }
|
||||
|
|
@ -376,9 +414,9 @@ namespace lib {
|
|||
ST core_;
|
||||
|
||||
public:
|
||||
using value_type = meta::RefTraits<T>::Value;
|
||||
using reference = meta::RefTraits<T>::Reference;
|
||||
using pointer = meta::RefTraits<T>::Pointer;
|
||||
using value_type = meta::RefTraits<T>::value_type;
|
||||
using reference = meta::RefTraits<T>::reference;
|
||||
using pointer = meta::RefTraits<T>::pointer;
|
||||
|
||||
IterStateWrapper (ST&& initialState)
|
||||
: core_(std::forward<ST>(initialState))
|
||||
|
|
@ -500,7 +538,7 @@ namespace lib {
|
|||
class IterStateCore
|
||||
: public IT
|
||||
{
|
||||
static_assert (lib::meta::can_IterForEach<IT>::value
|
||||
static_assert (iter::can_IterForEach<IT>::value
|
||||
,"Lumiera Iterator required as source");
|
||||
protected:
|
||||
IT&
|
||||
|
|
@ -545,7 +583,7 @@ namespace lib {
|
|||
class CheckedCore
|
||||
: public COR
|
||||
{
|
||||
static_assert (lib::meta::is_StateCore<COR>::value
|
||||
static_assert (iter::is_StateCore<COR>::value
|
||||
,"Adapted type must expose a »state core« API");
|
||||
protected:
|
||||
COR&
|
||||
|
|
@ -694,9 +732,9 @@ namespace lib {
|
|||
|
||||
public:
|
||||
using YieldRes = iter::CoreYield<COR>;
|
||||
using value_type = meta::RefTraits<YieldRes>::Value;
|
||||
using reference = meta::RefTraits<YieldRes>::Reference;
|
||||
using pointer = meta::RefTraits<YieldRes>::Pointer;
|
||||
using value_type = meta::RefTraits<YieldRes>::value_type;
|
||||
using reference = meta::RefTraits<YieldRes>::reference;
|
||||
using pointer = meta::RefTraits<YieldRes>::pointer;
|
||||
|
||||
|
||||
/** by default, pass anything down for initialisation of the core.
|
||||
|
|
@ -805,16 +843,12 @@ namespace lib {
|
|||
IT p_;
|
||||
IT e_;
|
||||
|
||||
static constexpr bool _is_LumieraIter = meta::can_IterForEach<IT>::value;
|
||||
using _ValTrait = std::conditional_t<_is_LumieraIter, meta::ValueTypeBinding<IT>
|
||||
, meta::ValueTypeBinding<meta::remove_pointer_t<IT>>>;
|
||||
|
||||
public:
|
||||
using pointer = _ValTrait::pointer;
|
||||
using reference = _ValTrait::reference;
|
||||
using pointer = iter::Trait<IT>::pointer;
|
||||
using reference = iter::Trait<IT>::reference;
|
||||
|
||||
/// @note special twist, since a STL const_iterator would yield a non-const `value_type`
|
||||
using value_type = std::remove_reference<reference>::type;
|
||||
using value_type = std::remove_reference_t<reference>;
|
||||
|
||||
|
||||
RangeIter (IT const& start, IT const& end)
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ namespace lib {
|
|||
struct _DecoratorTraits<SRC, enable_if<is_StateCore<SRC>>>
|
||||
{
|
||||
using SrcRaw = lib::meta::Strip<SRC>::Type;
|
||||
using SrcVal = meta::RefTraits<iter::CoreYield<SrcRaw>>::Value;
|
||||
using SrcVal = meta::RefTraits<iter::CoreYield<SrcRaw>>::value_type;
|
||||
using SrcIter = lib::IterableDecorator<lib::CheckedCore<SrcRaw>>;
|
||||
};
|
||||
|
||||
|
|
@ -478,7 +478,7 @@ namespace lib {
|
|||
struct _ReduceTraits
|
||||
{
|
||||
using Result = iter_explorer::_FunTraits<FUN,SRC>::Res;
|
||||
using ResVal = lib::meta::RefTraits<Result>::Value;
|
||||
using ResVal = lib::meta::RefTraits<Result>::value_type;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1038,9 +1038,9 @@ namespace lib {
|
|||
Aggregator aggregate_;
|
||||
|
||||
public:
|
||||
using value_type = meta::RefTraits<AGG>::Value;
|
||||
using reference = meta::RefTraits<AGG>::Reference;
|
||||
using pointer = meta::RefTraits<AGG>::Pointer;
|
||||
using value_type = meta::RefTraits<AGG>::value_type;
|
||||
using reference = meta::RefTraits<AGG>::reference;
|
||||
using pointer = meta::RefTraits<AGG>::pointer;
|
||||
|
||||
GroupAggregator() =default;
|
||||
// inherited default copy operations
|
||||
|
|
@ -1698,6 +1698,9 @@ namespace lib {
|
|||
}
|
||||
|
||||
|
||||
auto
|
||||
flatten();
|
||||
|
||||
/** adapt this IterExplorer to pipe each result value through a transformation function.
|
||||
* Several "layers" of mapping can be piled on top of each other, possibly mixed with the
|
||||
* other types of adaptation, like the child-expanding operation, or a filter. Obviously,
|
||||
|
|
@ -1760,7 +1763,7 @@ namespace lib {
|
|||
|
||||
static_assert (meta::is_BinaryFun<FAGG>());
|
||||
using ArgType1 = _Fun<FAGG>::Args::List::Head;
|
||||
using Aggregate = meta::RefTraits<ArgType1>::Value;
|
||||
using Aggregate = meta::RefTraits<ArgType1>::value_type;
|
||||
|
||||
using ResCore = iter_explorer::GroupAggregator<SRC, Aggregate, GroupVal>;
|
||||
using ResIter = _DecoratorTraits<ResCore>::SrcIter;
|
||||
|
|
|
|||
|
|
@ -258,33 +258,33 @@ namespace meta {
|
|||
template<typename TY>
|
||||
struct RefTraits
|
||||
{
|
||||
typedef TY Value;
|
||||
typedef TY* Pointer;
|
||||
typedef TY& Reference;
|
||||
typedef TY value_type;
|
||||
typedef TY& reference;
|
||||
typedef TY* pointer;
|
||||
};
|
||||
|
||||
template<typename TY>
|
||||
struct RefTraits<TY *>
|
||||
{
|
||||
typedef TY* Value;
|
||||
typedef TY** Pointer;
|
||||
typedef TY*& Reference;
|
||||
typedef TY* value_type;
|
||||
typedef TY*& reference;
|
||||
typedef TY** pointer;
|
||||
};
|
||||
|
||||
template<typename TY>
|
||||
struct RefTraits<TY &>
|
||||
{
|
||||
typedef TY Value;
|
||||
typedef TY* Pointer;
|
||||
typedef TY& Reference;
|
||||
typedef TY value_type;
|
||||
typedef TY& reference;
|
||||
typedef TY* pointer;
|
||||
};
|
||||
|
||||
template<typename TY>
|
||||
struct RefTraits<TY &&>
|
||||
{
|
||||
typedef TY Value;
|
||||
typedef TY* Pointer;
|
||||
typedef TY& Reference;
|
||||
typedef TY value_type;
|
||||
typedef TY& reference;
|
||||
typedef TY* pointer;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -327,8 +327,8 @@ namespace meta {
|
|||
/** verify the first (special) type can stand-in for the second */
|
||||
template<typename S, typename G>
|
||||
struct can_StandIn
|
||||
: std::is_convertible<typename RefTraits<S>::Reference
|
||||
,typename RefTraits<G>::Reference
|
||||
: std::is_convertible<typename RefTraits<S>::reference
|
||||
,typename RefTraits<G>::reference
|
||||
>
|
||||
{ };
|
||||
|
||||
|
|
|
|||
|
|
@ -107,16 +107,16 @@ namespace meta {
|
|||
template<typename TY, typename SEL =void>
|
||||
struct ValueTypeBinding
|
||||
{
|
||||
using value_type = RefTraits<TY>::Value;
|
||||
using reference = RefTraits<TY>::Reference;
|
||||
using pointer = RefTraits<TY>::Pointer;
|
||||
using value_type = RefTraits<TY>::value_type;
|
||||
using reference = RefTraits<TY>::reference;
|
||||
using pointer = RefTraits<TY>::pointer;
|
||||
};
|
||||
|
||||
/** specialisation for classes providing STL style type binding definitions */
|
||||
template<typename TY>
|
||||
struct ValueTypeBinding<TY, enable_if<use_ValueTypebindings<TY>> >
|
||||
{
|
||||
using _SrcType = RefTraits<TY>::Value;
|
||||
using _SrcType = RefTraits<TY>::value_type;
|
||||
|
||||
using value_type = _SrcType::value_type;
|
||||
using reference = _SrcType::reference;
|
||||
|
|
@ -159,9 +159,9 @@ namespace meta {
|
|||
>;
|
||||
|
||||
using ResType = _ValRef;
|
||||
using value_type = RefTraits<ResType>::Value;
|
||||
using reference = RefTraits<ResType>::Reference;
|
||||
using pointer = RefTraits<ResType>::Pointer;
|
||||
using value_type = RefTraits<ResType>::value_type;
|
||||
using reference = RefTraits<ResType>::reference;
|
||||
using pointer = RefTraits<ResType>::pointer;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -231,8 +231,8 @@ namespace lib {
|
|||
friend auto begin (Several const& svl) { return svl.begin();}
|
||||
friend auto end (Several const& svl) { return svl.end(); }
|
||||
|
||||
using value_type = meta::RefTraits<I>::Value;
|
||||
using reference = meta::RefTraits<I>::Reference;
|
||||
using value_type = meta::RefTraits<I>::value_type;
|
||||
using reference = meta::RefTraits<I>::reference;
|
||||
using const_reference = value_type const&;
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue