Library: adjust and fix semantics of nested 'value_type' binding

This is a subtle and far reaching fix, which hopefully removes
a roadblock regarding a Dispatcher pipeline: Our type rebinding
template used to pick up nested type definitions, especially
'value_type' and 'reference' from iterators and containers,
took an overly simplistic approach, which was then fixed
at various places driven by individual problems.

Now:
 - value_type is conceptually the "thing" exposed by the iterator
 - and pointers are treated as simple values, and no longer linked
   to their pointee type; rather we handle the twist regarding
   STL const_iterator direcly (it defines a non const value_type,
   which is sensible from the STL point of view, but breaks our
   generic iterator wrapping mechanism)
This commit is contained in:
Fischlurch 2023-05-21 02:15:02 +02:00
parent 46ab053b8a
commit e176e54004
16 changed files with 543 additions and 187 deletions

View file

@ -133,7 +133,7 @@ namespace util {
inline auto
stringify (IT&& src)
{
using Val = typename std::remove_reference<IT>::type::value_type;
using Val = typename lib::meta::ValueTypeBinding<IT>::value_type;
return lib::transformIterator(forward<IT>(src), util::toString<Val>);
}

View file

@ -58,9 +58,9 @@ namespace iter_stl {
class DistinctIter
{
public:
typedef typename IT::value_type value_type;
typedef typename IT::reference reference;
typedef typename IT::pointer pointer;
using value_type = typename IT::value_type;
using reference = typename IT::reference;
using pointer = typename IT::pointer;
private:
IT i_;
@ -135,10 +135,10 @@ namespace iter_stl {
template<typename IT>
struct Wrapped_Identity
{
typedef IT Iter;
typedef typename IT::value_type value_type;
typedef typename IT::reference reference;
typedef typename IT::pointer pointer;
using Iter = IT;
using value_type = typename IT::value_type;
using reference = typename IT::reference;
using pointer = typename IT::pointer;
static Iter get (Iter& it) { return & (*it); }
};
@ -150,10 +150,10 @@ namespace iter_stl {
template<typename IT>
struct Wrapped_PickKey
{
typedef IT Iter;
typedef typename IT::value_type::first_type value_type;
typedef value_type & reference;
typedef value_type * pointer;
using Iter = IT;
using value_type = typename IT::value_type::first_type;
using reference = value_type &;
using pointer = value_type *;
static pointer get (Iter& it) { return & (it->first); }
};
@ -165,10 +165,10 @@ namespace iter_stl {
template<typename IT>
struct Wrapped_PickVal
{
typedef IT Iter;
typedef typename IT::value_type::second_type value_type;
typedef value_type & reference;
typedef value_type * pointer;
using Iter = IT;
using value_type = typename IT::value_type::second_type;
using reference = value_type &;
using pointer = value_type *;
static pointer get (Iter& it) { return & (it->second); }
};
@ -176,10 +176,10 @@ namespace iter_stl {
template<typename IT>
struct Wrapped_PickConstVal
{
typedef IT Iter;
typedef typename IT::value_type::second_type value_type;
typedef value_type const& reference;
typedef value_type const* pointer;
using Iter = IT;
using value_type = const typename IT::value_type::second_type;
using reference = const value_type &;
using pointer = const value_type *;
static pointer get (Iter& it) { return & (it->second); }
};

View file

@ -174,7 +174,7 @@ namespace lib {
CON source_;
mutable POS pos_;
using _ValTrait = meta::TypeBinding<std::remove_pointer_t<POS>>;
using _ValTrait = meta::ValueTypeBinding<std::remove_pointer_t<POS>>;
public:
using value_type = typename _ValTrait::value_type;
@ -267,7 +267,7 @@ namespace lib {
protected:
using ConRef = typename meta::TypeBinding<CON>::reference;
using ConRef = typename meta::RefTraits<CON>::Reference;
/** allow derived classes to access backing container */
ConRef source() { return source_; }
@ -471,12 +471,14 @@ namespace lib {
IT p_;
IT e_;
using _ValTrait = meta::TypeBinding<std::remove_pointer_t<IT>>;
using _ValTrait = meta::ValueTypeBinding<meta::remove_pointer_t<IT>>;
public:
using value_type = typename _ValTrait::value_type;
using reference = typename _ValTrait::reference;
using pointer = typename _ValTrait::pointer;
using reference = typename _ValTrait::reference;
/// @note special twist, since a STL const_iterator would yield a non-const `value_type`
using value_type = typename std::remove_reference<reference>::type;
RangeIter (IT const& start, IT const& end)

View file

@ -65,9 +65,9 @@ namespace lib {
public:
typedef typename meta::TypeBinding<IT>::pointer pointer;
typedef typename meta::TypeBinding<IT>::reference reference;
typedef typename std::remove_reference<reference>::type value_type; ///< @note will be const for const iterators
using pointer = typename meta::ValueTypeBinding<IT>::pointer;
using reference = typename meta::ValueTypeBinding<IT>::reference;
using value_type = typename std::remove_reference<reference>::type; ///< @note will be const for const iterators (while const_iterator::value_type isn't)
CursorGear()

View file

@ -229,7 +229,7 @@ namespace lib {
* is passed to one of the IterSource's builder functions, thereby
* erasing the specific type information of the template parameter IT
*/
template<class IT, class ISO = IterSource<typename IT::value_type>>
template<class IT, class ISO = IterSource<typename meta::ValueTypeBinding<IT>::value_type>>
class WrappedLumieraIter
: public ISO
, util::NonCopyable

View file

@ -388,9 +388,9 @@ namespace lib {
{
using Res = remove_reference_t<decltype(std::declval<COR>().yield())>;
using value_type = typename meta::TypeBinding<Res>::value_type;
using reference = typename meta::TypeBinding<Res>::reference;
using pointer = typename meta::TypeBinding<Res>::pointer;
using value_type = typename meta::ValueTypeBinding<Res>::value_type;
using reference = typename meta::ValueTypeBinding<Res>::reference;
using pointer = typename meta::ValueTypeBinding<Res>::pointer;
};
@ -846,9 +846,9 @@ namespace lib {
TransformedItem treated_;
public:
using value_type = typename meta::TypeBinding<RES>::value_type;
using reference = typename meta::TypeBinding<RES>::reference;
using pointer = typename meta::TypeBinding<RES>::pointer;
using value_type = typename meta::ValueTypeBinding<RES>::value_type;
using reference = typename meta::ValueTypeBinding<RES>::reference;
using pointer = typename meta::ValueTypeBinding<RES>::pointer;
Transformer() =default;
@ -1347,9 +1347,9 @@ namespace lib {
public:
using value_type = typename meta::TypeBinding<SRC>::value_type;
using reference = typename meta::TypeBinding<SRC>::reference;
using pointer = typename meta::TypeBinding<SRC>::pointer;
using value_type = typename meta::ValueTypeBinding<SRC>::value_type;
using reference = typename meta::ValueTypeBinding<SRC>::reference;
using pointer = typename meta::ValueTypeBinding<SRC>::pointer;
/** pass-through ctor */
using SRC::SRC;

View file

@ -95,7 +95,7 @@ namespace lib {
using std::function;
using util::unConst;
using lib::meta::TypeBinding;
using lib::meta::ValueTypeBinding;
@ -754,9 +754,9 @@ namespace lib {
return bool(source_);
}
typedef typename TypeBinding<VAL>::pointer pointer;
typedef typename TypeBinding<VAL>::reference reference;
typedef typename TypeBinding<VAL>::value_type value_type;
using pointer = typename ValueTypeBinding<VAL>::pointer;
using reference = typename ValueTypeBinding<VAL>::reference;
using value_type = typename ValueTypeBinding<VAL>::value_type;
};
@ -833,8 +833,8 @@ namespace lib {
inline typename IT::value_type
pull_last (IT iter)
{
typedef typename IT::value_type Val;
typedef wrapper::ItemWrapper<Val> Item;
using Val = typename IT::value_type;
using Item = wrapper::ItemWrapper<Val>;
Item lastElm;
@ -860,7 +860,7 @@ namespace lib {
inline auto
filterRepetitions (IT const& source)
{
using Val = typename IT::value_type;
using Val = typename meta::ValueTypeBinding<IT>::value_type;
return filterIterator (source, SkipRepetition<Val>());
}
@ -868,8 +868,7 @@ namespace lib {
inline auto
filterRepetitions (IT&& source)
{
using SrcIT = typename std::remove_reference<IT>::type;
using Val = typename SrcIT::value_type;
using Val = typename meta::ValueTypeBinding<IT>::value_type;
return filterIterator (forward<IT>(source), SkipRepetition<Val>() );
}

View file

@ -94,8 +94,11 @@ namespace lib {
namespace meta {
using std::remove_cv;
using std::remove_cv_t;
using std::remove_pointer;
using std::remove_pointer_t;
using std::remove_reference;
using std::remove_reference_t;
using std::is_pointer;
using std::is_base_of;
using std::is_convertible;
@ -257,37 +260,40 @@ namespace meta {
/** Type definition helper for pointer and reference types.
* Allows to create a member field and to get the basic type
* irrespective if the given type is plain, pointer or reference
* @note we _do treat pointers specific_ though; a pointer is itself
* a value and the pointer-indirection is _not_ stripped.
* (use meta::Strip to radically strip all adornments)
*/
template<typename TY>
struct RefTraits
{
typedef TY* pointer;
typedef TY& reference;
typedef TY value_type;
typedef TY Value;
typedef TY* Pointer;
typedef TY& Reference;
};
template<typename TY>
struct RefTraits<TY *>
{
typedef TY* pointer;
typedef TY& reference;
typedef TY value_type;
typedef TY* Value;
typedef TY** Pointer;
typedef TY*& Reference;
};
template<typename TY>
struct RefTraits<TY &>
{
typedef TY* pointer;
typedef TY& reference;
typedef TY value_type;
typedef TY Value;
typedef TY* Pointer;
typedef TY& Reference;
};
template<typename TY>
struct RefTraits<TY &&>
{
typedef TY* pointer;
typedef TY& reference;
typedef TY value_type;
typedef TY Value;
typedef TY* Pointer;
typedef TY& Reference;
};
@ -474,7 +480,7 @@ namespace meta {
template<typename T>
class can_IterForEach
{
typedef typename Strip<T>::Type Type;
using Type = typename Strip<T>::Type;
META_DETECT_NESTED(value_type);
META_DETECT_OPERATOR_DEREF();
@ -496,7 +502,7 @@ namespace meta {
template<typename T>
class can_STL_ForEach
{
typedef typename Strip<T>::Type Type;
using Type = typename Strip<T>::Type;
struct is_iterable
{
@ -560,7 +566,7 @@ namespace meta {
template<typename T>
class can_STL_backIteration
{
typedef typename Strip<T>::Type Type;
using Type = typename Strip<T>::Type;
struct is_backIterable
{

View file

@ -36,7 +36,7 @@
** Within the STL, there is a convention to provide nested typedefs to indicate
** type variations in relation to the basic payload type of the container. We
** follow this convention and support especially the
** - `value_type`
** - `value_type` (what is conceived to be "in" the container or iterator)
** - a simple (LValue) reference to the payload
** - a pointer at the payload.
**
@ -47,6 +47,7 @@
** treatment, an explicit specialisation to this rebinding trait may be
** injected alongside with the definition of the payload type.
**
** @see ValueTypeBinding_test
** @see iter-adapter.hpp
** @see scope-path.hpp usage example (explicit specialisation)
*/
@ -88,39 +89,17 @@ namespace meta {
template<class X>
struct use_ValueTypebindings
: __and_<has_nested_ValueTypeBindings<X>
,__not_<is_StringLike<X>
: __and_<has_nested_ValueTypeBindings< remove_reference_t<X> >
,__not_<is_StringLike< remove_reference_t<X> >
>
>
{ };
}
/**
* @internal helper template to pick up nested value type definitions
*/
template<typename TY, typename SEL =void>
struct ValueTypeBinding
{
typedef TY value_type;
typedef TY& reference;
typedef TY* pointer;
};
/** specialisation for classes providing STL style type binding definitions */
template<typename TY>
struct ValueTypeBinding<TY, enable_if<use_ValueTypebindings<TY>> >
{
typedef typename TY::value_type value_type;
typedef typename TY::reference reference;
typedef typename TY::pointer pointer;
};
/**
* Type re-binding helper template for creating nested typedefs
* for use by custom containers and iterator adapters or similar.
* usable by custom containers and iterator adapters or similar.
* - this trait provides a value-, reference- and pointer type,
* similar to what the STL does.
* - references are stripped, otherwise the base type is passed through
@ -129,20 +108,24 @@ namespace meta {
* @note client code might define specialisations
* to handle tricky situations (like e.g. const_reverse_iter)
*/
template<typename TY>
struct TypeBinding
: ValueTypeBinding<TY>
{ };
template<typename TY, typename SEL =void>
struct ValueTypeBinding
{
using value_type = typename RefTraits<TY>::Value;
using reference = typename RefTraits<TY>::Reference;
using pointer = typename RefTraits<TY>::Pointer;
};
/** specialisation for classes providing STL style type binding definitions */
template<typename TY>
struct TypeBinding<TY &>
: TypeBinding<TY>
{ };
template<typename TY>
struct TypeBinding<TY &&>
: TypeBinding<TY>
{ };
struct ValueTypeBinding<TY, enable_if<use_ValueTypebindings<TY>> >
{
using _SrcType = typename RefTraits<TY>::Value;
using value_type = typename _SrcType::value_type;
using reference = typename _SrcType::reference;
using pointer = typename _SrcType::pointer;
};

View file

@ -452,7 +452,7 @@ namespace lib {
* This variant allows to "pull" elements from an iterator.
* Actually, the collection will try to create each element right away,
* by invoking the copy ctor and passing the value yielded by the iterator.
* @note anything in accordance to the Lumera Forward Iterator pattern is OK.
* @note anything in accordance to the Lumiera Forward Iterator pattern is OK.
* This rules out just passing a plain STL iterator (because these can't
* tell for themselves when they're exhausted). Use an suitable iter-adapter
* instead, e.g. by invoking lib::iter_stl::eachElm(stl_container)
@ -463,7 +463,7 @@ namespace lib {
{
IT iter_;
typedef typename meta::TypeBinding<IT>::value_type ElementType;
using ElementType = typename meta::ValueTypeBinding<IT>::value_type;
public:
PullFrom (IT source)

View file

@ -166,6 +166,13 @@ namespace test{
static constexpr auto postfix = "";
};
template<typename X>
struct TypeDiagnostics<const X>
{
using Type = X;
static constexpr auto prefix = "const ";
static constexpr auto postfix = "";
};
template<typename X>
struct TypeDiagnostics<X&>
{
using Type = X;

View file

@ -303,7 +303,7 @@ namespace wrapper {
/**
* Specialisation of the ItemWrapper to deal with references,
* as if they were pointer values. Allows the reference value
* to be default constructed to `NULL` and to be re-assigned.
* to be default constructed to (invalid) and to be re-assigned.
*/
template<typename TY>
class ItemWrapper<TY &>

View file

@ -185,18 +185,18 @@ namespace session {
unique_ptr<Table> pTab_;
typedef PlacementMO::ID _PID;
typedef std::unordered_multimap<_PID,_PID>::const_iterator ScopeIter;
typedef lib::RangeIter<ScopeIter> ScopeRangeIter;
typedef lib::TransformIter<ScopeRangeIter, PlacementMO&> _ID_TableIterator;
using _PID = PlacementMO::ID;
using ScopeIter = std::unordered_multimap<_PID,_PID>::const_iterator;
using ScopeRangeIter = lib::RangeIter<ScopeIter>;
using _ID_TableIterator = lib::TransformIter<ScopeRangeIter, PlacementMO&>;
public:
typedef PlacementRef<MObject> PRef;
typedef PlacementMO::ID const& ID;
using PRef = PlacementRef<MObject>;
using ID = PlacementMO::ID const&;
typedef _ID_TableIterator iterator;
using iterator = _ID_TableIterator;
/* == query operations == */

View file

@ -109,7 +109,7 @@ namespace meta{
* @see iter-adapter.hpp
*/
template<>
struct TypeBinding<vector<Scope>::const_reverse_iterator>
struct ValueTypeBinding<vector<Scope>::const_reverse_iterator>
{
typedef const Scope value_type;
typedef Scope const& reference;

View file

@ -84,103 +84,103 @@ namespace test{
run (Arg)
{
// verify the type diagnostics helper...
CHECK ("int" == showType<int >() );
CHECK ("int&" == showType<int& >() );
CHECK ("int &&" == showType<int&& >() );
CHECK ("int const&" == showType<int const& >() );
CHECK ("const int &&" == showType<int const&& >() );
CHECK ("int *" == showType<int * >() );
CHECK ("const int *" == showType<int const * >() );
CHECK ("const int * const" == showType<int const * const >() );
CHECK ("int const*&" == showType<int const * &>() );
CHECK ("int const* const&" == showType<int const * const&>() );
CHECK (showType<int >() == "int"_expect );
CHECK (showType<int& >() == "int&"_expect );
CHECK (showType<int&& >() == "int &&"_expect );
CHECK (showType<int const& >() == "int const&"_expect );
CHECK (showType<int const&& >() == "const int &&"_expect );
CHECK (showType<int * >() == "int *"_expect );
CHECK (showType<int const * >() == "const int *"_expect );
CHECK (showType<int const * const >() == "const int * const"_expect );
CHECK (showType<int const * &>() == "int const*&"_expect );
CHECK (showType<int const * const&>() == "int const* const&"_expect );
// Test fixture: the template Outer<T> provides nested value type bindings
using OuterSpace = Outer<Space>;
using Join = ulong;
CHECK (showType<Outer<Space>::value_type>() == "Space"_expect );
CHECK (showType<Outer<Space>::reference>() == "Outer<Space>::Inner&"_expect );
CHECK (showType<Outer<Space>::pointer>() == "shared_ptr<Space>"_expect );
CHECK ("Space" == showType<OuterSpace::value_type>() );
CHECK ("Outer<Space>::Inner&" == showType<OuterSpace::reference>() );
CHECK ("shared_ptr<Space>" == showType<OuterSpace::pointer>() );
// ...such nested type bindings will be picked up
CHECK ("Space" == showType<TypeBinding<OuterSpace>::value_type>() );
CHECK ("Outer<Space>::Inner&" == showType<TypeBinding<OuterSpace>::reference>() );
CHECK ("shared_ptr<Space>" == showType<TypeBinding<OuterSpace>::pointer>() );
CHECK (showType<ValueTypeBinding<Outer<Space>>::value_type>() == "Space"_expect );
CHECK (showType<ValueTypeBinding<Outer<Space>>::reference>() == "Outer<Space>::Inner&"_expect );
CHECK (showType<ValueTypeBinding<Outer<Space>>::pointer>() == "shared_ptr<Space>"_expect );
CHECK ("unsigned long" == showType<TypeBinding<Outer<Join>>::value_type>() );
CHECK ("Outer<unsigned long>::Inner&" == showType<TypeBinding<Outer<Join>>::reference>() );
CHECK ("shared_ptr<unsigned long>" == showType<TypeBinding<Outer<Join>>::pointer>() );
CHECK (showType<ValueTypeBinding<Outer<short>>::value_type>() == "short"_expect );
CHECK (showType<ValueTypeBinding<Outer<short>>::reference>() == "Outer<short>::Inner&"_expect );
CHECK (showType<ValueTypeBinding<Outer<short>>::pointer>() == "shared_ptr<short>"_expect );
// contrast this to a type without such nested bindings
CHECK ("Space" == showType<TypeBinding<Space>::value_type>() );
CHECK ("Space&" == showType<TypeBinding<Space>::reference>() );
CHECK ("Space *" == showType<TypeBinding<Space>::pointer>() );
CHECK (showType<ValueTypeBinding<Space>::value_type>() == "Space"_expect );
CHECK (showType<ValueTypeBinding<Space>::reference>() == "Space&"_expect );
CHECK (showType<ValueTypeBinding<Space>::pointer>() == "Space *"_expect );
// reference types will be levelled (reference stripped)
CHECK ("Space" == showType<TypeBinding<OuterSpace&>::value_type>() );
CHECK ("Outer<Space>::Inner&" == showType<TypeBinding<OuterSpace&>::reference>() );
CHECK ("shared_ptr<Space>" == showType<TypeBinding<OuterSpace&>::pointer>() );
// when checking for nested bindings, reference will be stripped and just the binding returned as-is
CHECK (showType<ValueTypeBinding<Outer<Space>&>::_SrcType>() == "Outer<Space>"_expect ); // internal: this is the type probed for nested bindings
CHECK (showType<ValueTypeBinding<Outer<Space>&>::value_type>() == "Space"_expect );
CHECK (showType<ValueTypeBinding<Outer<Space>&>::reference>() == "Outer<Space>::Inner&"_expect );
CHECK (showType<ValueTypeBinding<Outer<Space>&>::pointer>() == "shared_ptr<Space>"_expect );
CHECK ("Space" == showType<TypeBinding<OuterSpace&&>::value_type>() );
CHECK ("Outer<Space>::Inner&" == showType<TypeBinding<OuterSpace&&>::reference>() );
CHECK ("shared_ptr<Space>" == showType<TypeBinding<OuterSpace&&>::pointer>() );
CHECK (showType<ValueTypeBinding<Outer<Space>&&>::_SrcType>() == "Outer<Space>"_expect ); // likewise for &&
CHECK (showType<ValueTypeBinding<Outer<Space>&&>::value_type>() == "Space"_expect );
CHECK (showType<ValueTypeBinding<Outer<Space>&&>::reference>() == "Outer<Space>::Inner&"_expect );
CHECK (showType<ValueTypeBinding<Outer<Space>&&>::pointer>() == "shared_ptr<Space>"_expect );
CHECK ("Space" == showType<TypeBinding<OuterSpace const&>::value_type>() );
CHECK ("Outer<Space>::Inner&" == showType<TypeBinding<OuterSpace const&>::reference>() );
CHECK ("shared_ptr<Space>" == showType<TypeBinding<OuterSpace const&>::pointer>() );
CHECK (showType<ValueTypeBinding<Outer<Space> const&>::value_type>() == "Space"_expect );
CHECK (showType<ValueTypeBinding<Outer<Space> const&>::reference>() == "Outer<Space>::Inner&"_expect );
CHECK (showType<ValueTypeBinding<Outer<Space> const&>::pointer>() == "shared_ptr<Space>"_expect );
// but a pointer counts as a different, primitive type. No magic here
CHECK ("Outer<Space> *" == showType<TypeBinding<OuterSpace*>::value_type>() );
CHECK ("Outer<Space>*&" == showType<TypeBinding<OuterSpace*>::reference>() );
CHECK ("Outer<Space>* *" == showType<TypeBinding<OuterSpace*>::pointer>() );
// but a pointer counts as different, primitive type. No magic here
CHECK (showType<ValueTypeBinding< Outer<Space> * >::value_type>() == "Outer<Space> *"_expect );
CHECK (showType<ValueTypeBinding< Outer<Space> * >::reference>() == "Outer<Space>*&"_expect );
CHECK (showType<ValueTypeBinding< Outer<Space> * >::pointer>() == "Outer<Space>* *"_expect );
CHECK ("const Outer<Space> *" == showType<TypeBinding<const OuterSpace*>::value_type>() );
CHECK ("Outer<Space> const*&" == showType<TypeBinding<const OuterSpace*>::reference>() );
CHECK ("Outer<Space> const* *" == showType<TypeBinding<const OuterSpace*>::pointer>() );
CHECK (showType<ValueTypeBinding<const Outer<Space> * >::value_type>() == "const Outer<Space> *"_expect );
CHECK (showType<ValueTypeBinding<const Outer<Space> * >::reference>() == "Outer<Space> const*&"_expect );
CHECK (showType<ValueTypeBinding<const Outer<Space> * >::pointer>() == "Outer<Space> const* *"_expect );
CHECK ("const Outer<Space> * const" == showType<TypeBinding<const OuterSpace * const>::value_type>() );
CHECK ("Outer<Space> const* const&" == showType<TypeBinding<const OuterSpace * const>::reference>() );
CHECK ("Outer<Space> * const *" == showType<TypeBinding<const OuterSpace * const>::pointer>() );
CHECK (showType<ValueTypeBinding<const Outer<Space> * const>::value_type>() == "const Outer<Space> * const"_expect );
CHECK (showType<ValueTypeBinding<const Outer<Space> * const>::reference>() == "Outer<Space> const* const&"_expect );
CHECK (showType<ValueTypeBinding<const Outer<Space> * const>::pointer>() == "Outer<Space> * const *"_expect );
CHECK ("Outer<Space> * const" == showType<TypeBinding<OuterSpace * const>::value_type>() );
CHECK ("Outer<Space>* const&" == showType<TypeBinding<OuterSpace * const>::reference>() );
CHECK ("Outer<Space> * const *" == showType<TypeBinding<OuterSpace * const>::pointer>() );
CHECK (showType<ValueTypeBinding< Outer<Space> * const>::value_type>() == "Outer<Space> * const"_expect );
CHECK (showType<ValueTypeBinding< Outer<Space> * const>::reference>() == "Outer<Space>* const&"_expect );
CHECK (showType<ValueTypeBinding< Outer<Space> * const>::pointer>() == "Outer<Space> * const *"_expect );
// similar for a type without nested type bindings: references are levelled
CHECK ("unsigned long" == showType<TypeBinding<Join>::value_type>() );
CHECK ("unsigned long&" == showType<TypeBinding<Join>::reference>() );
CHECK ("unsigned long *" == showType<TypeBinding<Join>::pointer>() );
// yet for a type without nested type bindings: references are levelled
CHECK (showType<ValueTypeBinding<short>::value_type>() == "short"_expect );
CHECK (showType<ValueTypeBinding<short>::reference>() == "short&"_expect );
CHECK (showType<ValueTypeBinding<short>::pointer>() == "short *"_expect );
CHECK ("unsigned long" == showType<TypeBinding<Join&>::value_type>() );
CHECK ("unsigned long&" == showType<TypeBinding<Join&>::reference>() );
CHECK ("unsigned long *" == showType<TypeBinding<Join&>::pointer>() );
CHECK (showType<ValueTypeBinding<short&>::value_type>() == "short"_expect );
CHECK (showType<ValueTypeBinding<short&>::reference>() == "short&"_expect );
CHECK (showType<ValueTypeBinding<short&>::pointer>() == "short *"_expect );
CHECK ("unsigned long" == showType<TypeBinding<Join&&>::value_type>() );
CHECK ("unsigned long&" == showType<TypeBinding<Join&&>::reference>() );
CHECK ("unsigned long *" == showType<TypeBinding<Join&&>::pointer>() );
CHECK ("unsigned long" == showType<TypeBinding<Join const&>::value_type>() );
CHECK ("unsigned long const&" == showType<TypeBinding<Join const&>::reference>() );
CHECK ("const unsigned long *" == showType<TypeBinding<Join const&>::pointer>() );
CHECK (showType<ValueTypeBinding<short&&>::value_type>() == "short"_expect );
CHECK (showType<ValueTypeBinding<short&&>::reference>() == "short&"_expect );
CHECK (showType<ValueTypeBinding<short&&>::pointer>() == "short *"_expect );
CHECK (showType<ValueTypeBinding<short const&>::value_type>() == "const short"_expect );
CHECK (showType<ValueTypeBinding<short const&>::reference>() == "short const&"_expect );
CHECK (showType<ValueTypeBinding<short const&>::pointer>() == "const short *"_expect );
//... but pointer types are not treated special in any way
CHECK ("unsigned long *" == showType<TypeBinding<Join *>::value_type>() );
CHECK ("unsigned long*&" == showType<TypeBinding<Join *>::reference>() );
CHECK ("unsigned long* *" == showType<TypeBinding<Join *>::pointer>() );
CHECK (showType<ValueTypeBinding< short * >::value_type>() == "short *"_expect );
CHECK (showType<ValueTypeBinding< short * >::reference>() == "short*&"_expect );
CHECK (showType<ValueTypeBinding< short * >::pointer>() == "short* *"_expect );
CHECK ("const unsigned long *" == showType<TypeBinding<const Join *>::value_type>() );
CHECK ("unsigned long const*&" == showType<TypeBinding<const Join *>::reference>() );
CHECK ("unsigned long const* *" == showType<TypeBinding<const Join *>::pointer>() );
CHECK (showType<ValueTypeBinding<const short * >::value_type>() == "const short *"_expect );
CHECK (showType<ValueTypeBinding<const short * >::reference>() == "short const*&"_expect );
CHECK (showType<ValueTypeBinding<const short * >::pointer>() == "short const* *"_expect );
CHECK ("const unsigned long * const" == showType<TypeBinding<const Join * const>::value_type>() );
CHECK ("unsigned long const* const&" == showType<TypeBinding<const Join * const>::reference>() );
CHECK ("unsigned long * const *" == showType<TypeBinding<const Join * const>::pointer>() );
CHECK (showType<ValueTypeBinding<const short * const>::value_type>() == "const short * const"_expect );
CHECK (showType<ValueTypeBinding<const short * const>::reference>() == "short const* const&"_expect );
CHECK (showType<ValueTypeBinding<const short * const>::pointer>() == "short * const *"_expect );
CHECK ("unsigned long * const" == showType<TypeBinding<Join * const>::value_type>() );
CHECK ("unsigned long* const&" == showType<TypeBinding<Join * const>::reference>() );
CHECK ("unsigned long * const *" == showType<TypeBinding<Join * const>::pointer>() );
CHECK (showType<ValueTypeBinding< short * const>::value_type>() == "short * const"_expect );
CHECK (showType<ValueTypeBinding< short * const>::reference>() == "short* const&"_expect );
CHECK (showType<ValueTypeBinding< short * const>::pointer>() == "short * const *"_expect );
}
};

View file

@ -70480,7 +70480,25 @@
<icon BUILTIN="info"/>
</node>
<node CREATED="1684199007763" ID="ID_1119161771" MODIFIED="1684199048138" TEXT="demnach baut das Schema auf einem Modell auf: Container enth&#xe4;lt &#xbb;values&#xab;"/>
<node CREATED="1684199056069" ID="ID_1539617529" MODIFIED="1684199087165" TEXT="&#x27f9; value_type ist &#x201e;das was im Container liegt&#x201c;"/>
<node CREATED="1684199056069" ID="ID_1539617529" MODIFIED="1684199087165" TEXT="&#x27f9; value_type ist &#x201e;das was im Container liegt&#x201c;">
<node CREATED="1684459356366" ID="ID_734793626" MODIFIED="1684460165746" TEXT="Vorsicht: gilt auch f&#xfc;r const_iterator wenn Werte im Container nicht const">
<linktarget COLOR="#8a5067" DESTINATION="ID_734793626" ENDARROW="Default" ENDINCLINATION="365;14;" ID="Arrow_ID_139514882" SOURCE="ID_472589448" STARTARROW="None" STARTINCLINATION="510;-24;"/>
<icon BUILTIN="messagebox_warning"/>
</node>
<node CREATED="1684459431583" ID="ID_1927390361" MODIFIED="1684459550547" TEXT="f&#xfc;r meinen Ansatz w&#xe4;re das nicht korrekt">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...f&#252;r die STL schon, aber das ist genau meine Kritik: die STL ist hier zu konkret und zu sehr low-level &#8212; ein const_iterator ist demnach etwas Anderes als ein iterator von einem Container &#252;ber const-Werte, und das widerspricht meinem Konzept, einen Iterator als eine opaque Quelle zu betrachten
</p>
</body>
</html></richcontent>
<icon BUILTIN="stop-sign"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1684199284567" ID="ID_156863476" MODIFIED="1684280069405" TEXT="&#xdc;bertragung auf das Konzept &#xbb;Lumiera Forward Iterator&#xab;">
<arrowlink COLOR="#b76aa0" DESTINATION="ID_1930966790" ENDARROW="Default" ENDINCLINATION="643;27;" ID="Arrow_ID_1775444250" STARTARROW="None" STARTINCLINATION="-1192;-62;"/>
@ -70579,14 +70597,14 @@
<icon BUILTIN="messagebox_warning"/>
</node>
<node CREATED="1684284560186" ID="ID_525459774" MODIFIED="1684284573100" TEXT="reicht den Typ von CursorGear an den eigentlichen Iter durch"/>
<node CREATED="1684284575680" ID="ID_467685696" MODIFIED="1684284615275" TEXT="dieser Typ l&#xe4;uft aber genau nicht &#xfc;ber TypeBinding">
<node CREATED="1684284575680" ID="ID_467685696" MODIFIED="1684620273794" TEXT="dieser Typ l&#xe4;uft aber genau nicht &#xfc;ber ValueTypeBinding">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...was wohl genau daran liegt, da&#223; TypeBinding konzeptionell &quot;daneben&quot; ist
...was wohl genau daran liegt, da&#223; das TypeBinding bisher konzeptionell &quot;daneben&quot; war
</p>
</body>
</html>
@ -70676,6 +70694,347 @@
</node>
</node>
</node>
<node CREATED="1684285740036" ID="ID_265016247" MODIFIED="1684285746031" TEXT="Umbau-Plan">
<node COLOR="#338800" CREATED="1684285746921" ID="ID_453018815" MODIFIED="1684453850245" TEXT="erst einmal alles in TypeBinding zusammenf&#xfc;hren">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1684285761285" ID="ID_399824938" MODIFIED="1684453848315" TEXT="dort zus&#xe4;tzliche Variante base_type einf&#xfc;hren">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1684285782158" ID="ID_1046713320" MODIFIED="1684627513659" TEXT="dann Semantik von value_type &#xe4;ndern">
<icon BUILTIN="button_ok"/>
<node CREATED="1684457336456" ID="ID_668731240" MODIFIED="1684457339328" TEXT="Probleme">
<node CREATED="1684457340219" ID="ID_349629435" MODIFIED="1684457345698" TEXT="const-correctness">
<node CREATED="1684457356442" ID="ID_718673785" MODIFIED="1684457361150" TEXT="iter-curstor-test">
<node CREATED="1684457376306" ID="ID_1078884821" MODIFIED="1684457376306" TEXT="CIter = IterCursor&lt;Numz::const_iterator&gt;;"/>
<node CREATED="1684457442699" ID="ID_492340662" MODIFIED="1684457443679" TEXT="IterStateWrapper&lt;typename iter::CursorGear&lt;IT&gt;::value_type, iter::CursorGear&lt;IT&gt;&gt;"/>
<node CREATED="1684457445585" ID="ID_1783656179" MODIFIED="1684457469546" TEXT="die Core liefert einen int const&amp;, aber der IterStateWrapper baut eine int&amp;"/>
<node COLOR="#435e98" CREATED="1684457528365" ID="ID_581341012" MODIFIED="1684460086498" TEXT="was ist value_type = typename meta::ValueTypeBinding&lt;IT&gt;::value_type">
<icon BUILTIN="help"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1684458989282" ID="ID_9060398" MODIFIED="1684459000625" TEXT="const_iterator::value_type ist nicht const">
<icon BUILTIN="stop-sign"/>
</node>
<node CREATED="1684460102957" ID="ID_472589448" MODIFIED="1684460165746" TEXT="das ist eine Eigenschaft der STL">
<arrowlink COLOR="#8a5067" DESTINATION="ID_734793626" ENDARROW="Default" ENDINCLINATION="365;14;" ID="Arrow_ID_139514882" STARTARROW="None" STARTINCLINATION="510;-24;"/>
<icon BUILTIN="idea"/>
</node>
<node COLOR="#338800" CREATED="1684460116154" ID="ID_458968493" MODIFIED="1684460124620" TEXT="mu&#xdf; hier eigens darum herumarbeiten">
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
</node>
<node CREATED="1684457756467" ID="ID_1799112543" MODIFIED="1684457763201" TEXT="pointer strip">
<node CREATED="1684457764640" ID="ID_589412032" MODIFIED="1684457771969" TEXT="scoped-collection-test">
<node CREATED="1684457794295" ID="ID_1727116794" MODIFIED="1684457799167" TEXT="CollI = ScopedCollection&lt;uint&gt;"/>
<node CREATED="1684457816624" ID="ID_1452815222" MODIFIED="1684457817291" TEXT="CollI coll (20, CollI::pull(source.begin()));"/>
<node CREATED="1684457846811" ID="ID_1577579858" MODIFIED="1684457849143" TEXT="erzeugt PullFrom&lt;IT&gt; (iter)"/>
<node COLOR="#338800" CREATED="1684457919935" ID="ID_1908868537" MODIFIED="1684457982649" TEXT="iter = IterAdapter&lt;uint*, const ScopedCollection&lt;uint&gt;*&gt;">
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1684458334322" ID="ID_1259042868" MODIFIED="1684458359762" TEXT="ScopedCollection&lt;I,siz&gt;::PullFrom::operator()">
<icon BUILTIN="broken-line"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1684458361926" ID="ID_44705604" MODIFIED="1684458423543" TEXT="Fehler in der Verwendung von base_type">
<icon BUILTIN="broken-line"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1684458382800" ID="ID_1834051890" MODIFIED="1684458423543" TEXT="Fehler im Type-Forwarding aus dem Basis-Iter">
<icon BUILTIN="broken-line"/>
</node>
</node>
</node>
</node>
<node COLOR="#435e98" CREATED="1684459906255" ID="ID_1378023279" MODIFIED="1684626459648" TEXT="placement-Index">
<icon BUILTIN="flag-pink"/>
<node CREATED="1684459919427" ID="ID_1436515063" MODIFIED="1684626423578" TEXT="has_any (elementsInScope, equalsTheElement);">
<linktarget COLOR="#a9b4c1" DESTINATION="ID_1436515063" ENDARROW="Default" ENDINCLINATION="953;0;" ID="Arrow_ID_233825462" SOURCE="ID_845601504" STARTARROW="None" STARTINCLINATION="953;0;"/>
</node>
<node CREATED="1684459973590" ID="ID_484139471" MODIFIED="1684459977363" TEXT="enable_if&lt;lib::meta::can_IterForEach&lt;IT&gt; scheitert"/>
<node CREATED="1684459996401" ID="ID_990292148" MODIFIED="1684460058465" TEXT="f&#xfc;r IT = PlacementIndex::iterator">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
&#160;&#160;&#160;&#160;&#160;&#160;using&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;_PID = PlacementMO::ID;
</p>
<p>
&#160;&#160;&#160;&#160;&#160;&#160;using&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ScopeIter = std::unordered_multimap&lt;_PID,_PID&gt;::const_iterator;
</p>
<p>
&#160;&#160;&#160;&#160;&#160;&#160;using&#160;&#160;&#160;&#160;ScopeRangeIter = lib::RangeIter&lt;ScopeIter&gt;;
</p>
<p>
&#160;&#160;&#160;&#160;&#160;&#160;using _ID_TableIterator = lib::TransformIter&lt;ScopeRangeIter, PlacementMO&amp;&gt;;
</p>
</body>
</html></richcontent>
</node>
<node COLOR="#338800" CREATED="1684626148632" ID="ID_314534651" MODIFIED="1684626158039" TEXT="durch nachfolgende Korrekturen bereits behoben">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1684460327937" ID="ID_1243195068" MODIFIED="1684626167397" TEXT="JobTicket::buildProvisionSpec">
<icon BUILTIN="flag-pink"/>
<node CREATED="1684460427537" ID="ID_1226575987" MODIFIED="1684460443243" TEXT="von: MockSegmentation::buildTicketFromSpec(GenNode)">
<icon BUILTIN="idea"/>
</node>
<node CREATED="1684460342898" ID="ID_1631135246" MODIFIED="1684460349919" TEXT="can_IterForEach">
<node CREATED="1684460350803" ID="ID_860677112" MODIFIED="1684460364845" TEXT="funktioniert f&#xfc;r den direkt gegebenen IT">
<node CREATED="1684460591828" ID="ID_1373150141" MODIFIED="1684460608948" TEXT="SingleValIter&lt;tuple&lt;...&gt;&gt;"/>
</node>
<node CREATED="1684460365809" ID="ID_1079060296" MODIFIED="1684460376780" TEXT="funktioniert nicht f&#xfc;r die Prereq, die wir da rausziehen">
<node CREATED="1684460663671" ID="ID_990738534" MODIFIED="1684460782775">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
<font face="Monospaced" size="2">TransformIter&lt;RangeIter&lt;__normal_iterator&lt;const GenNode*,&#160;vector&lt;GenNode&gt; &gt; &gt; </font>
</p>
<p>
<font face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;,JobTicket&amp; </font>
</p>
<p>
<font face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&gt;</font>
</p>
</body>
</html></richcontent>
</node>
</node>
</node>
<node COLOR="#435e98" CREATED="1684626170197" ID="ID_1147513606" MODIFIED="1684626278079" TEXT="war eine Folge von dem ersten &#x201e;zu forschen&#x201c; L&#xf6;sungsansatz">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
Hatte zun&#228;chst gedacht, generell sollte value_type den Typparameter unver&#228;ndert durchreichen (sofern kein nested Binding erfolgt). Tats&#228;chlich bestand das Problem aber nur bei Pointern, und das l&#246;sen wir besser direkt in den RefTraits
</p>
</body>
</html></richcontent>
<linktarget COLOR="#a9b4c1" DESTINATION="ID_1147513606" ENDARROW="Default" ENDINCLINATION="782;0;" ID="Arrow_ID_803486255" SOURCE="ID_845601504" STARTARROW="None" STARTINCLINATION="782;0;"/>
<icon BUILTIN="idea"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1684539208804" ID="ID_1954674721" MODIFIED="1684626143751" TEXT="iter-source-test">
<icon BUILTIN="broken-line"/>
<node CREATED="1684539307546" ID="ID_1311972803" MODIFIED="1684539316978" TEXT="StrIter &#xfc;ber C-Strings"/>
<node CREATED="1684539269802" ID="ID_403304388" MODIFIED="1684539272922" TEXT="IT = lib::IterSource&lt;const char*&gt;::iterator"/>
<node CREATED="1684539477912" ID="ID_887047226" MODIFIED="1684546668213" TEXT="operator*() : *pos_ fordert const char* &#x27fc; char">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1684539640794" ID="ID_1199240443" MODIFIED="1684539642585" TEXT="IterAdapter&lt;POS, CON&gt;::operator*()"/>
<node CREATED="1684539670393" ID="ID_277475548" MODIFIED="1684539765410" TEXT="POS = const char**"/>
<node CREATED="1684539670393" ID="ID_310218838" MODIFIED="1684539778471" TEXT="CON = std::shared_ptr&lt;lib::IterSource&lt;const char*&gt; &gt;"/>
<node CREATED="1684539670393" ID="ID_1854935145" MODIFIED="1684539789446" TEXT="IterAdapter&lt;POS, CON&gt;::reference = const char&amp;"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1684539583917" ID="ID_112700804" MODIFIED="1684539611127" TEXT="hier werden Typen aber ziemlich falsch zugeornet">
<icon BUILTIN="stop-sign"/>
<node CREATED="1684540675424" ID="ID_1620874341" MODIFIED="1684540690953">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
IterAdapter selber <i>sieht sauber aus....</i>
</p>
</body>
</html></richcontent>
<node CREATED="1684540734860" ID="ID_1048473009" MODIFIED="1684540742573" TEXT="Pos = TY *"/>
<node CREATED="1684540868210" ID="ID_261008232" MODIFIED="1684540885946" TEXT="man k&#xf6;nnte hier noch remove_reference&lt;TY&gt; machen"/>
<node CREATED="1684540890766" ID="ID_1617257613" MODIFIED="1684540976683" TEXT="aber sicher keine weitere Magic">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
und im Besonderen kein automatisches Entfernen von Indirektionen, und kein R&#252;ckgriff auf interne Typdefinitionen (also <i>grade nicht</i>&#160; ValueTypeBinding verwenden!)
</p>
</body>
</html></richcontent>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1684540984894" ID="ID_71878097" MODIFIED="1684541006615" TEXT="also mu&#xdf; das Desaster wohl direkt in ValueTypeBinding passieren">
<icon BUILTIN="clanbomber"/>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1684541044909" ID="ID_829271566" MODIFIED="1684541051786" TEXT="was ist std::remove_pointer_t&lt;POS&gt;">
<icon BUILTIN="help"/>
</node>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1684541062585" ID="ID_690843749" MODIFIED="1684541091476" TEXT="und wie ergibt sich dann daraus reference = char const&amp;">
<icon BUILTIN="help"/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1684626148632" ID="ID_747512117" MODIFIED="1684626158039" TEXT="durch nachfolgende Korrekturen bereits behoben">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1684545378054" ID="ID_949809414" MODIFIED="1684626340506" TEXT="variadic-argument-picker-test">
<icon BUILTIN="broken-line"/>
<node CREATED="1684545421888" ID="ID_339637961" MODIFIED="1684545432171" TEXT="in der Test-Helper &quot;fun(Args....)&quot;">
<node CREATED="1684545465106" ID="ID_701958213" MODIFIED="1684545483864" TEXT="aufgerufen mit vier non-const-Referenzen auf Objekte">
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1684545757723" ID="ID_986888781" MODIFIED="1684545771325" TEXT="fehlt hier nicht ein std::forward&lt;&gt;??">
<icon BUILTIN="help"/>
</node>
</node>
<node CREATED="1684545504133" ID="ID_1380420727" MODIFIED="1684545531453" TEXT="ARGS = {N&lt;1&gt;&amp;, N&lt;2&gt;&amp;, N&lt;3&gt;&amp;, N&lt;3&gt;&amp;}"/>
<node CREATED="1684545687470" ID="ID_1546238335" MODIFIED="1684545710789" TEXT="join (initializer_list&lt;string&gt;&amp;&amp;)">
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1684545757723" ID="ID_1916732834" MODIFIED="1684545790142" TEXT="sollte hier nicht per std::forward&lt;&gt; weitergegeben werden??">
<icon BUILTIN="help"/>
</node>
<node CREATED="1684545909915" ID="ID_493146886" MODIFIED="1684545972282" TEXT="damit geht es an join(CON, delim) mit CON = initializer_list&lt;string&gt; const&amp;"/>
</node>
<node CREATED="1684546028926" ID="ID_34906560" MODIFIED="1684546088662" TEXT="stringify(IT&amp;&amp;) with IT = RangeIter&lt;const string *&gt;">
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1684546334838" ID="ID_547357409" MODIFIED="1684546350340" TEXT="woher kommt hier der const string* ?">
<icon BUILTIN="help"/>
<node CREATED="1684626094980" ID="ID_829378008" MODIFIED="1684626104491" TEXT="von einem direkt programmierten Type-Binding"/>
<node COLOR="#338800" CREATED="1684626105086" ID="ID_1025913285" MODIFIED="1684626122919" TEXT="durch ValueTypeBinding&lt;IT&gt;::value_type ersetzt">
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
<node CREATED="1684546214885" ID="ID_1713896865" MODIFIED="1684546216393" TEXT="TransformIter&lt;IT, VAL&gt;::TransformIter(IT&amp;&amp;, FUN)">
<node CREATED="1684546235557" ID="ID_713854770" MODIFIED="1684546245891" TEXT="VAL = string"/>
<node CREATED="1684546253025" ID="ID_645791486" MODIFIED="1684546274610" TEXT="IT = RangeIter&lt;const string *&gt;"/>
<node CREATED="1684546286956" ID="ID_28115946" MODIFIED="1684546318515" TEXT="FUN = string (*)(const string* const&amp;) noexcept"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1684546426129" ID="ID_1263412941" MODIFIED="1684546733339" TEXT="hier rufen wir bereits mit dem falschen Argument-Type (const string*) auf">
<icon BUILTIN="stop-sign"/>
</node>
<node CREATED="1684546449894" ID="ID_6052563" MODIFIED="1684546461940" TEXT="aber trotzdem sollte ein RangeIter dar&#xfc;ber funktionieren">
<icon BUILTIN="yes"/>
<node CREATED="1684546491857" ID="ID_1736947794" MODIFIED="1684546499939" TEXT="RangeIter&lt;const string *&gt;"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1684546581725" ID="ID_1681461344" MODIFIED="1684546725943" TEXT="also ValueTypeBinding&lt;TY *&gt; pa&#xdf;t hier nicht">
<arrowlink COLOR="#e12e5f" DESTINATION="ID_164341663" ENDARROW="Default" ENDINCLINATION="64;-2;" ID="Arrow_ID_926464248" STARTARROW="None" STARTINCLINATION="-265;16;"/>
<icon BUILTIN="messagebox_warning"/>
</node>
</node>
</node>
<node COLOR="#435e98" CREATED="1684546673741" ID="ID_164341663" MODIFIED="1684626063307" TEXT="RangeIter&lt;TY *&gt; geht nicht korrekt mit Pointern um">
<linktarget COLOR="#e12e5f" DESTINATION="ID_164341663" ENDARROW="Default" ENDINCLINATION="64;-2;" ID="Arrow_ID_926464248" SOURCE="ID_1681461344" STARTARROW="None" STARTINCLINATION="-265;16;"/>
<icon BUILTIN="broken-line"/>
<node CREATED="1684546753135" HGAP="35" ID="ID_1396741432" MODIFIED="1684546926029" TEXT="operator*() : *p_ fordert const string &#x27fc; const string * &amp;" VSHIFT="22"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1684546891740" HGAP="40" ID="ID_915912294" MODIFIED="1684626059090" TEXT="Hinweis: der Kommentar impliziert &quot;Magic&quot;" VSHIFT="7">
<icon BUILTIN="idea"/>
<node CREATED="1684546933543" ID="ID_179350313" MODIFIED="1684546938867" TEXT="nicht sicher ob beabsichtigt"/>
<node CREATED="1684546939486" ID="ID_6236284" MODIFIED="1684546950832" TEXT="oder erst nachtr&#xe4;glich zum Feature erkl&#xe4;rt">
<icon BUILTIN="ksmiletris"/>
</node>
<node CREATED="1684546974033" ID="ID_1477759961" MODIFIED="1684546991075" TEXT="Spec laut Kommentar">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
<font face="Monospaced">&#160;&#160;&#160;* @note </font>
</p>
<p>
<font face="Monospaced">&#160;&#160;&#160;*&#160;&#160;- when IT is just a pointer, we use the pointee as value type </font>
</p>
<p>
<font face="Monospaced">&#160;&#160;&#160;*&#160;&#160;- but when IT is a class, we expect the usual STL style nested typedefs </font>
</p>
<p>
<font face="Monospaced">&#160;&#160;&#160;*&#160;&#160;&#160;&#160;`value_type`, `reference` and `pointer` </font>
</p>
</body>
</html></richcontent>
<icon BUILTIN="info"/>
<node CREATED="1684547049166" ID="ID_52771462" MODIFIED="1684547121647" TEXT="IT &#x27f9; value_type &#x2254; IT::value_type"/>
<node CREATED="1684547024027" ID="ID_861935637" MODIFIED="1684547046420" TEXT="TY* &#x27f9; value_type &#x2254; TY">
<node CREATED="1684547257132" ID="ID_1641640973" MODIFIED="1684547283862" TEXT="demnach w&#xe4;re reference &#x2254; TY&amp;">
<icon BUILTIN="forward"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1684547123638" ID="ID_641824771" MODIFIED="1684547229342" TEXT="genau das wird aber durch die neueste &#xc4;nderung anders gehandhabt">
<linktarget COLOR="#af3f77" DESTINATION="ID_641824771" ENDARROW="Default" ENDINCLINATION="-189;8;" ID="Arrow_ID_697522858" SOURCE="ID_206554481" STARTARROW="None" STARTINCLINATION="110;-4;"/>
<icon BUILTIN="stop-sign"/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1684547353367" ID="ID_727759660" MODIFIED="1684626054719" TEXT="mu&#xdf; die &#xbb;Magic&#xab; nun explizit programmieren">
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
</node>
<node CREATED="1684621584827" ID="ID_1014436557" MODIFIED="1684621610333" TEXT="Zwischen-Befund / Reflexion">
<icon BUILTIN="yes"/>
<node COLOR="#338800" CREATED="1684621612562" ID="ID_641071847" MODIFIED="1684621699986" TEXT="diverse Probleme mit der const-correctness aufgekl&#xe4;rt">
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1684621626500" ID="ID_845601504" MODIFIED="1684627435369" TEXT="aber: ich schie&#xdf;e &#xfc;ber das Ziel hinaus!">
<arrowlink DESTINATION="ID_1147513606" ENDARROW="Default" ENDINCLINATION="782;0;" ID="Arrow_ID_803486255" STARTARROW="None" STARTINCLINATION="782;0;"/>
<arrowlink DESTINATION="ID_1436515063" ENDARROW="Default" ENDINCLINATION="953;0;" ID="Arrow_ID_233825462" STARTARROW="None" STARTINCLINATION="953;0;"/>
<linktarget COLOR="#ed2d5d" DESTINATION="ID_845601504" ENDARROW="Default" ENDINCLINATION="-127;9;" ID="Arrow_ID_564685689" SOURCE="ID_1176556358" STARTARROW="None" STARTINCLINATION="-328;-13;"/>
<icon BUILTIN="messagebox_warning"/>
</node>
<node CREATED="1684621638451" ID="ID_1737271679" MODIFIED="1684621694316" TEXT="das eigentliche Problem war, bei Pointern einen Level zu strippen">
<icon BUILTIN="idea"/>
</node>
<node CREATED="1684621672478" ID="ID_727658054" MODIFIED="1684621697414" TEXT="denn: es ist keine gute Idee, wenn value_type jemals eine Referenz tr&#xe4;gt">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1684626429769" ID="ID_1909166035" MODIFIED="1684626440198" TEXT="im Besonderen bricht das diverse Metafunktionen"/>
<node CREATED="1684626441042" ID="ID_15567636" MODIFIED="1684626451554" TEXT="vor allem can_IterForEach">
<icon BUILTIN="messagebox_warning"/>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1684460928713" ID="ID_781322960" MODIFIED="1684543483308" TEXT="Analyse">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1684543492882" ID="ID_1765561986" MODIFIED="1684627380924" TEXT="zun&#xe4;chst value-type-binding-test durchpr&#xfc;fen">
<icon BUILTIN="button_ok"/>
<node CREATED="1684543612090" ID="ID_847618892" MODIFIED="1684543794926" TEXT="Problem-1">
<node CREATED="1684543795935" ID="ID_693680608" MODIFIED="1684544154186" TEXT="Check auf nested bindings scheitert an Referenzen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
das hei&#223;t, wir erkennen gar nicht mehr, da&#223; der Typ m&#246;glicherweise nested Bindings hat, weil viele Konstrukte f&#252;r Klassen gar nicht valide sind f&#252;r Referenzen, und daher die Erkennungs-Mechanismen ins Leer laufen
</p>
</body>
</html></richcontent>
<icon BUILTIN="messagebox_warning"/>
</node>
<node COLOR="#338800" CREATED="1684543798547" ID="ID_144041413" MODIFIED="1684544080113" TEXT="brauche hier remove_reference_t&lt;TY&gt;">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node CREATED="1684544073327" ID="ID_33363993" MODIFIED="1684544077707" TEXT="Problem-2">
<node CREATED="1684544485429" ID="ID_78295540" MODIFIED="1684544500426" TEXT="eine Pointer-Indirektion wird absorbiert"/>
<node CREATED="1684544502202" ID="ID_1635049786" MODIFIED="1684544509486" TEXT="ja, genau so habe ich es implementiert"/>
<node CREATED="1684544517888" ID="ID_1457225235" MODIFIED="1684544533010" TEXT="das ist aber nicht sinnvoll...">
<node CREATED="1684544533985" ID="ID_259178564" MODIFIED="1684544541705" TEXT="TY ist was anderes als TY*"/>
<node CREATED="1684544543619" ID="ID_1302084338" MODIFIED="1684544559191" TEXT="f&#xfc;r das strikte Auspacken habe ich meta::Strip"/>
<node CREATED="1684544674884" ID="ID_1045605145" MODIFIED="1684544696800" TEXT="&quot;Pointer&quot; sollte wirklich wie ein Indirektions-Wrapper behandelt werden"/>
<node COLOR="#338800" CREATED="1684544698308" ID="ID_206554481" MODIFIED="1684547307830" TEXT="&#x27f9; die Spezialisierung meta::RefTraits&lt;TY*&gt; entsprechend umprogrammieren">
<arrowlink COLOR="#af3f77" DESTINATION="ID_641824771" ENDARROW="Default" ENDINCLINATION="-189;8;" ID="Arrow_ID_697522858" STARTARROW="None" STARTINCLINATION="110;-4;"/>
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
<node COLOR="#5b280f" CREATED="1684627391111" ID="ID_1176556358" MODIFIED="1684627440600" TEXT="dabei f&#xe4;llt auf: mein erster Ansatz ist zu aggressiv">
<arrowlink COLOR="#ed2d5d" DESTINATION="ID_845601504" ENDARROW="Default" ENDINCLINATION="-127;9;" ID="Arrow_ID_564685689" STARTARROW="None" STARTINCLINATION="-328;-13;"/>
<icon BUILTIN="stop-sign"/>
</node>
</node>
<node COLOR="#5b280f" CREATED="1684460931749" ID="ID_1257295046" MODIFIED="1684627468131" TEXT="unter Labor-Bedingungen nachbauen">
<icon BUILTIN="button_cancel"/>
<node CREATED="1684627469601" ID="ID_1556079989" MODIFIED="1684627476286" TEXT="nicht mehr n&#xf6;tig..."/>
<node CREATED="1684627476967" ID="ID_1636586185" MODIFIED="1684627499527" TEXT="mit der 2. L&#xf6;sung und den Fixes verschwinden die Probleme"/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1684453837677" ID="ID_870052730" MODIFIED="1684627517045" TEXT="Name &#xe4;ndern auf ValueTypeBinding">
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1684283073854" ID="ID_1161646513" MODIFIED="1684283082079" TEXT="Nutzung vereinheitlichen">
<icon BUILTIN="flag-yellow"/>