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:
Fischlurch 2026-03-25 23:51:32 +01:00
parent 68460d4900
commit fbda9baeb3
6 changed files with 84 additions and 47 deletions

View file

@ -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

View file

@ -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)

View file

@ -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;

View file

@ -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
>
{ };

View file

@ -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;
};

View file

@ -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&;