Upgrade: explore construction of a ''tuple-like'' concept
Motivated by the difficulties encountered with `std::apply` — which basically forced us to define our own alternative with conceptually more adequate limitations.... ...so these are the first attempts towards building a C++20 concept.
This commit is contained in:
parent
de066348af
commit
7d461adabc
5 changed files with 277 additions and 130 deletions
196
research/try.cpp
196
research/try.cpp
|
|
@ -1,6 +1,7 @@
|
|||
/* try.cpp - to try out and experiment with new features....
|
||||
* scons will create the binary bin/try
|
||||
*/
|
||||
// 06/25 - provide a concept to accept _tuple-like_ objects
|
||||
// 06/25 - investigate function type detection of std::bind Binders
|
||||
// 12/24 - investigate problem when perfect-forwarding into a binder
|
||||
// 12/24 - investigate overload resolution on a templated function similar to std::get
|
||||
|
|
@ -9,130 +10,123 @@
|
|||
|
||||
|
||||
/** @file try.cpp
|
||||
* Investigate ambiguities regarding the function type of standard binders.
|
||||
* The Binder objects returned from `std::bind` provide a set of overloaded
|
||||
* function call `operator()` (with variants for c/v). Unfortunately this defeats
|
||||
* the common techniques to detect a function signature from a callable, when
|
||||
* only a concrete instance of such a binder is given. Furthermore, looking
|
||||
* at the definition of `class _Bind_result<_Result, _Functor(_Bound_args...)>`
|
||||
* in my implementation of the C++ Stdlib, it seems we are pretty much out
|
||||
* of luck, and even `std::function` fails with the template argument detection.
|
||||
* A possible workaround could be to wrap the Binder object immediately into
|
||||
* a lambda, but only if the actual types for the argument list can be
|
||||
* provided directly to a template to generate this λ-wrapper.
|
||||
* @note there is a nasty twist regarding const-correctness, which almost made
|
||||
* this workaround fail altogether. The overloaded operator() from std::bind
|
||||
* serves the same purpose (to deal with const/volatile), and this is the
|
||||
* very reason that defeats the detection of the function signature.
|
||||
* The workaround attempts to expose precisely one function call operator,
|
||||
* and this becomes problematic as soon as the resulting object is processed
|
||||
* further, and maybe bound into another lambda capture. Thus we define the
|
||||
* wrapper class explicitly, so that any const-ness can be cast away.
|
||||
* This turns out to be necessary in tuple-closure.hpp.
|
||||
* Develop a concept to detect _tuple-like_ classes, based on the requirements
|
||||
* of the »tuple protocol«. Using some ideas from [Stackoverflow] as starting point.
|
||||
* [Stackoverflow]: https://stackoverflow.com/q/68443804/444796
|
||||
*/
|
||||
|
||||
|
||||
#include "lib/format-cout.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
#include "lib/test/diagnostic-output.hpp"
|
||||
#include "lib/meta/function.hpp"
|
||||
#include "lib/meta/variadic-rebind.hpp"
|
||||
#include "lib/meta/tuple-helper.hpp"
|
||||
#include "lib/hetero-data.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <concepts>
|
||||
|
||||
using std::forward;
|
||||
using std::placeholders::_1;
|
||||
using lib::meta::_Fun;
|
||||
using std::string;
|
||||
|
||||
namespace lib {
|
||||
namespace meta {
|
||||
|
||||
template<class TUP>
|
||||
concept tuple_sized = requires
|
||||
{
|
||||
{ std::tuple_size<TUP>::value } -> std::convertible_to<size_t>;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
fun (int& a)
|
||||
{
|
||||
std::cout << a << std::endl;
|
||||
}
|
||||
|
||||
short
|
||||
fup (long l, long long ll)
|
||||
{
|
||||
return short(l - ll);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** WORKAROUND: wrap a binder to yield clear function signature */
|
||||
template<typename...ARGS>
|
||||
struct AdaptInvokable
|
||||
{
|
||||
template<class FUN>
|
||||
static auto
|
||||
buildWrapper (FUN&& fun)
|
||||
{
|
||||
|
||||
struct Wrap
|
||||
{
|
||||
FUN fun_;
|
||||
|
||||
Wrap(FUN&& f) : fun_{forward<FUN>(f)} { }
|
||||
|
||||
auto
|
||||
operator() (ARGS... args)
|
||||
{
|
||||
return fun_(forward<ARGS>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
return Wrap{forward<FUN>(fun)};
|
||||
///////////////////////////////////////////////////////////// NOTE
|
||||
///////////////////////////////////////////////////////////// can not use a Lambda, since we're then trapped
|
||||
///////////////////////////////////////////////////////////// in an unsurmountable mixture of const and non-const
|
||||
// return [functor = forward<FUN>(fun)]
|
||||
// (ARGS... args) mutable
|
||||
// {
|
||||
// return functor (forward<ARGS> (args)...);
|
||||
// };
|
||||
}
|
||||
};
|
||||
|
||||
template<class TYPES, class FUN>
|
||||
auto
|
||||
buildInvokableWrapper (FUN&& fun)
|
||||
{
|
||||
using ArgTypes = typename TYPES::Seq;
|
||||
using Builder = typename lib::meta::RebindVariadic<AdaptInvokable, ArgTypes>::Type;
|
||||
template<class TUP, std::size_t N>
|
||||
concept tuple_adl_accessible = requires(TUP tup)
|
||||
{
|
||||
typename std::tuple_element_t<N, TUP>;
|
||||
{ get<N>(tup) } -> std::convertible_to<std::tuple_element_t<N, TUP>&>;
|
||||
};
|
||||
|
||||
return Builder::buildWrapper (forward<FUN> (fun));
|
||||
template<class TUP, std::size_t N>
|
||||
concept tuple_mem_accessible = requires(TUP tup)
|
||||
{
|
||||
typename std::tuple_element_t<N, TUP>;
|
||||
{ tup.template get<N>() } -> std::convertible_to<std::tuple_element_t<N, TUP>&>;
|
||||
};
|
||||
|
||||
template<class TUP, std::size_t N>
|
||||
concept tuple_accessible = tuple_mem_accessible<TUP,N> or tuple_adl_accessible<TUP,N>;
|
||||
|
||||
template<class TUP>
|
||||
class AndAll
|
||||
{
|
||||
template<size_t...idx>
|
||||
static constexpr bool
|
||||
canAccessAll (std::index_sequence<idx...>)
|
||||
{
|
||||
return (tuple_accessible<TUP, idx> and ...);
|
||||
}
|
||||
|
||||
using IdxSeq = typename ElmTypes<TUP>::Idx;
|
||||
|
||||
public:
|
||||
static constexpr bool can_AccessElement = canAccessAll(IdxSeq{});
|
||||
};
|
||||
|
||||
|
||||
template<class TUP>
|
||||
concept tuple_like = not is_reference_v<TUP>
|
||||
and tuple_sized<remove_cv_t<TUP>>
|
||||
and AndAll<remove_cv_t<TUP>>::can_AccessElement;
|
||||
|
||||
}}//namespace lib::meta
|
||||
|
||||
|
||||
|
||||
template<typename X>
|
||||
void
|
||||
show()
|
||||
{
|
||||
SHOW_TYPE(X)
|
||||
}
|
||||
|
||||
template<lib::meta::tuple_like X>
|
||||
void
|
||||
show()
|
||||
{
|
||||
cout << "Tup!! "<< lib::test::showType<X>() <<endl;
|
||||
lib::meta::forEachIDX<X> ([](auto i)
|
||||
{
|
||||
using Elm = std::tuple_element_t<i, X>;
|
||||
cout <<" "<<uint(i)<<": "<< lib::test::showType<Elm>() <<endl;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int, char**)
|
||||
{
|
||||
SHOW_EXPR (fup(2,3))
|
||||
auto bup = std::bind (fup, _1, 5);
|
||||
SHOW_EXPR (bup)
|
||||
using Bup = decltype(bup);
|
||||
using Fub = _Fun<Bup>;
|
||||
SHOW_TYPE (Bup)
|
||||
SHOW_TYPE (Fub)
|
||||
// using Sub = Fub::Sig; ////////////////Problem: does not compile
|
||||
using Tup = std::tuple<long>;
|
||||
using Arr = std::array<int,3>;
|
||||
using Hetero = lib::HeteroData<int,string>::Chain<short>::ChainExtent<bool,lib::meta::Nil>::ChainType;
|
||||
|
||||
using Fut = decltype(fun);
|
||||
SHOW_TYPE (_Fun<Fut>::Sig)
|
||||
SHOW_EXPR((lib::meta::tuple_sized<Tup> ))
|
||||
SHOW_EXPR((lib::meta::tuple_sized<Arr> ))
|
||||
SHOW_EXPR((lib::meta::tuple_sized<Hetero> ))
|
||||
SHOW_EXPR((lib::meta::tuple_sized<int> ))
|
||||
|
||||
auto wup = buildInvokableWrapper<lib::meta::Types<int>>(bup);
|
||||
SHOW_EXPR((lib::meta::tuple_accessible<Tup,0>))
|
||||
// SHOW_EXPR((lib::meta::tuple_accessible<Tup,2>))
|
||||
SHOW_EXPR((lib::meta::tuple_accessible<Hetero,0>))
|
||||
SHOW_EXPR((lib::meta::AndAll<Tup>::can_AccessElement))
|
||||
SHOW_EXPR((lib::meta::AndAll<Hetero>::can_AccessElement))
|
||||
|
||||
using Wup = decltype(wup);
|
||||
using WupSig = _Fun<Wup>::Sig;
|
||||
SHOW_TYPE (WupSig);
|
||||
SHOW_EXPR (wup(3))
|
||||
SHOW_EXPR (sizeof(bup))
|
||||
SHOW_EXPR (sizeof(wup))
|
||||
SHOW_EXPR((lib::meta::tuple_like<Tup> ))
|
||||
SHOW_EXPR((lib::meta::tuple_like<Arr> ))
|
||||
SHOW_EXPR((lib::meta::tuple_like<Hetero> ))
|
||||
SHOW_EXPR((lib::meta::tuple_like<int> ))
|
||||
|
||||
auto waua = buildInvokableWrapper<lib::meta::Types<>> (std::bind (fun, 55));
|
||||
waua ();
|
||||
SHOW_TYPE (_Fun<decltype(waua)>::Sig)
|
||||
show<Tup>();
|
||||
show<Arr>();
|
||||
show<Hetero>();
|
||||
show<int>();
|
||||
|
||||
cout << "\n.gulp." <<endl;
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -201,9 +201,9 @@ namespace lib {
|
|||
template<size_t slot>
|
||||
Elm_t<slot> const&
|
||||
get() const noexcept
|
||||
{
|
||||
return const_cast<HeteroData*>(this)->get<slot>();
|
||||
}
|
||||
{
|
||||
return const_cast<HeteroData*>(this)->get<slot>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
** So what is provided here is _not a parser library_ — yet aims at »making
|
||||
** simple things simple« and let you implement the complicated ones yourselves.
|
||||
** Several decisions were taken accordingly, like only supporting std::string_view
|
||||
** and automatically consuming any leading whitespace. And notably the focus was
|
||||
** and to consume any leading whitespace automatically. And notably the focus was
|
||||
** _not placed_ on the challenging aspects of parsing — while still allowing a
|
||||
** pathway towards definition of arbitrarily recursive grammars, if so desired.
|
||||
**
|
||||
|
|
@ -40,7 +40,7 @@
|
|||
** the C++ matcher object as result — and thus essentially some pointers into
|
||||
** the original sequence, which has to be passed in as C++ string_view.
|
||||
**
|
||||
** An essential concept of this parsing support framework is that each parser
|
||||
** An essential feature of this parsing support framework is that each parser
|
||||
** can be decorated by a _model transformation functor,_ which gets the result
|
||||
** of the wrapped parser and can return _any arbitrary value object._ In essence,
|
||||
** this framework does not provide the notion of an _abstract syntax tree_ — yet
|
||||
|
|
@ -57,7 +57,7 @@
|
|||
** - `accept_opt` builds a clause to optionally accept in accordance
|
||||
** to the given definition; if no match is found, parsing backtracks.
|
||||
** - `accept_repeated` builds a clause to accept a repetition of the
|
||||
** structure accepted by its argument, optionally with an explicit delimiter
|
||||
** structure accepted by its argument, optionally with an explicit separator
|
||||
** and possibly with a limited number of instances. The result values are
|
||||
** obviously all from the same type and will be collected into a IterModel,
|
||||
** which essentially is a std::vector<RES> (note: heap storage!).
|
||||
|
|
@ -68,24 +68,26 @@
|
|||
** described by the SPEC _after_ the structure already described by the syntax.
|
||||
** Both parts must succeed for the parse to be successful. The result value
|
||||
** is packaged into a parse::SeqModel, which essentially is a tuple; when
|
||||
** attaching several .seq() specifications, it can become a N-ary tuple.
|
||||
** attaching several .seq() specifications, it is extended to a N-ary tuple.
|
||||
** - `<syntax>.alt(SPEC)` adds an _alternative branch_ to the existing syntax.
|
||||
** Either part alone is sufficient for a successful parse. First the existing
|
||||
** branch(es) are tried, and only if those do not succeed, backtracking is
|
||||
** performed and then the alternative branch is tried. Once some match is
|
||||
** found, further branches will _not be attempted._ (short-circuit).
|
||||
** Thus there is _always one_ result model, is placed into an AltModel,
|
||||
** Thus there is _always one_ result model, placed into an AltModel,
|
||||
** which is a _variant data type_ with a common inline result buffer.
|
||||
** The _selector field_ must be checked to find out which branch of the
|
||||
** syntax succeeded, and then the result must be handled with its appropriate
|
||||
** type, because the various branches can possibly yield entirely different
|
||||
** result value types.
|
||||
** - `<syntax>.repeat()` _sequentially adds_ a repeated clause be accepted
|
||||
** _after_ what the existing syntax accepts. The result is thus a SeqModel.
|
||||
** - `<syntax>.repeat()` _sequentially adds_ a repeated clause to be accepted
|
||||
** _after_ what the existing syntax accepts. The result is thus a SeqModel,
|
||||
** with the result-model from the repetition in the last tuple element;
|
||||
** the repetition itself yields an IterModel.
|
||||
** - `<syntax>.bracket()` _sequentially adds_ a bracketing clause to be
|
||||
** accepted _after_ parsing with the existing syntax. Again, the result
|
||||
** is a SeqModel, with the result-model from the repetition in the last
|
||||
** tuple element. The repetition itself yields an IterModel.
|
||||
** is a SeqModel, with the result-model from the bracket contents
|
||||
** packaged into the last tuple element.
|
||||
** - `<syntax>.bind(FUN)` is a postfix-operator and decorates the existing
|
||||
** syntax with a result-binding functor `FUN`: The syntax's result value
|
||||
** is passed into this functor and whatever this functor returns will
|
||||
|
|
@ -99,8 +101,8 @@
|
|||
** A _recursive syntax definition_ is what unleashes the parsing technique's
|
||||
** full strength; but recursive grammars can be challenging to master at times
|
||||
** and may in fact lead to deadlock due to unlimited recursion. Since this
|
||||
** framework is focused on ease of use in simple situations, recursion is
|
||||
** considered an advanced usage and thus supported in a way that requires
|
||||
** framework is focused on ease of use for the simple situations, recursion
|
||||
** is considered an advanced usage and thus supported in a way that requires
|
||||
** some preparation and help by the user. In essence...
|
||||
** - a syntax clause to be referred recursively _must be pre-declared_
|
||||
** - this pre-declaration gives it a known, fixed result type and will
|
||||
|
|
|
|||
|
|
@ -187,19 +187,19 @@ namespace test{
|
|||
using Front = lib::HeteroData<uint,double>;
|
||||
using Cons2 = Front::Chain<bool,string>;
|
||||
using Data2 = Cons2::NewFrame;
|
||||
using List2 = Cons2::ChainType;
|
||||
using HeDa2 = Cons2::ChainType;
|
||||
using Acc4 = Cons2::AccessorFor<string>;
|
||||
using Acc3 = Cons2::AccessorFor<bool>;
|
||||
using Acc2 = Front::Accessor<1>;
|
||||
using Acc1 = Front::Accessor<0>;
|
||||
using Cons3 = Cons2::ChainExtent<CStr,string>;
|
||||
using Data3 = Cons3::NewFrame;
|
||||
using List3 = Cons3::ChainType;
|
||||
using HeDa3 = Cons3::ChainType;
|
||||
using Acc5 = Cons3::AccessorFor<CStr>;
|
||||
using Acc6 = Cons3::AccessorFor<string>;
|
||||
CHECK (2 == Front::size());
|
||||
CHECK (4 == List2::size());
|
||||
CHECK (6 == List3::size());
|
||||
CHECK (4 == HeDa2::size());
|
||||
CHECK (6 == HeDa3::size());
|
||||
//
|
||||
// Note: up to now, not a single actual data element has been created
|
||||
// Moreover, individual blocks can be created in any order...
|
||||
|
|
@ -278,7 +278,7 @@ namespace test{
|
|||
CHECK (not isSameAdr (d2, v3));
|
||||
CHECK (not isSameAdr (d3, v5));
|
||||
// we can directly re-cast into another typed front-end
|
||||
List3& fullChain = Cons3::recast(front);
|
||||
HeDa3& fullChain = Cons3::recast(front);
|
||||
CHECK (isSameAdr (fullChain.get<2>(), std::get<0>(d2)));
|
||||
CHECK (isSameAdr (fullChain.get<3>(), std::get<1>(d2)));
|
||||
CHECK (isSameAdr (fullChain.get<4>(), std::get<0>(d3)));
|
||||
|
|
@ -290,7 +290,7 @@ namespace test{
|
|||
CHECK (isSameAdr (fullChain.get<4>(), v5));
|
||||
CHECK (isSameAdr (fullChain.get<5>(), v6));
|
||||
// we can even use partially specified chains
|
||||
List2& partChain = Cons2::recast(fullChain);
|
||||
HeDa2& partChain = Cons2::recast(fullChain);
|
||||
CHECK (isSameAdr (partChain.get<0>(), v1));
|
||||
CHECK (isSameAdr (partChain.get<1>(), v2));
|
||||
CHECK (isSameAdr (partChain.get<2>(), v3));
|
||||
|
|
|
|||
|
|
@ -91601,7 +91601,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1733946409913" FOLDED="true" ID="ID_766490392" MODIFIED="1734041937846" TEXT="C++ »Tuple-Protocol«">
|
||||
<node COLOR="#338800" CREATED="1733946409913" FOLDED="true" ID="ID_766490392" MODIFIED="1750556525752" TEXT="C++ »Tuple-Protocol«">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1733946436854" ID="ID_1279626510" LINK="https://en.cppreference.com/w/cpp/utility/tuple/tuple-like" MODIFIED="1733946454891" TEXT="exposition-only concept »tuple-like«"/>
|
||||
<node CREATED="1733946456354" ID="ID_1814813251" MODIFIED="1733946486589">
|
||||
|
|
@ -91643,7 +91643,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1733946713943" FOLDED="true" ID="ID_1873953043" MODIFIED="1734020418870" TEXT="funktioniert nicht .... Compiler nimmt Overload für std::tuple">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1733946713943" FOLDED="true" ID="ID_1873953043" MODIFIED="1750556525770" TEXT="funktioniert nicht .... Compiler nimmt Overload für std::tuple">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node COLOR="#5b280f" CREATED="1733946765784" ID="ID_1087783493" MODIFIED="1734020236696" TEXT="das bekannte Problem mit Funktion Overloads??">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
|
|
@ -91783,6 +91783,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1750605910739" ID="ID_734827065" MODIFIED="1750605957925" TEXT="Problem besteht weiterhin mit GCC-14 (2025)">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -156835,6 +156838,7 @@ std::cout << tmpl.render({"what", "World"}) << s
|
|||
<node CREATED="1733950377664" ID="ID_242038986" LINK="https://en.cppreference.com/w/cpp/utility/tuple/tuple-like" MODIFIED="1733950483299" TEXT="verwendbar für alles was das »tuple protocoll« erfüllt"/>
|
||||
<node COLOR="#435e98" CREATED="1734017209791" ID="ID_141049889" LINK="https://en.cppreference.com/w/cpp/language/structured_binding#Binding_process" MODIFIED="1734017690782" TEXT="unterstützt darüber hinaus aber noch weitere Fälle">
|
||||
<linktarget COLOR="#608fc7" DESTINATION="ID_141049889" ENDARROW="Default" ENDINCLINATION="-1267;70;" ID="Arrow_ID_1556834813" SOURCE="ID_1154017972" STARTARROW="None" STARTINCLINATION="-716;33;"/>
|
||||
<linktarget COLOR="#4989d4" DESTINATION="ID_141049889" ENDARROW="Default" ENDINCLINATION="-494;29;" ID="Arrow_ID_789791822" SOURCE="ID_1129626446" STARTARROW="None" STARTINCLINATION="-1100;-64;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1734017307143" ID="ID_533210041" MODIFIED="1734017312267" TEXT="klassische C-Arrays"/>
|
||||
<node CREATED="1734017328298" ID="ID_897952923" MODIFIED="1734017340750" TEXT="das tuple-protocol">
|
||||
|
|
@ -157075,6 +157079,24 @@ std::cout << tmpl.render({"what", "World"}) << s
|
|||
<node CREATED="1617648902994" ID="ID_276316646" MODIFIED="1617648906362" TEXT="C++20">
|
||||
<node CREATED="1749407118772" ID="ID_1741477135" MODIFIED="1750347983055" TEXT="C++20 kennenlernen">
|
||||
<linktarget COLOR="#5b78d0" DESTINATION="ID_1741477135" ENDARROW="Default" ENDINCLINATION="-1445;183;" ID="Arrow_ID_120232332" SOURCE="ID_160865224" STARTARROW="None" STARTINCLINATION="714;86;"/>
|
||||
<node CREATED="1750442180561" ID="ID_1483771731" MODIFIED="1750442186844" TEXT="Tooling / Eclipse">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1750442188215" ID="ID_26311727" MODIFIED="1750442206176" TEXT="der klassische Editor unterstützt kein C++20">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1750442208883" ID="ID_639319394" MODIFIED="1750443928132" TEXT="ein neue LSP-basierter Editor ist eingebunden (unfertig)">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1750442236141" ID="ID_1373598733" MODIFIED="1750442259870">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
dazu im OS: <font face="Monospaced"><b>clangd</b></font> installieren
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1749407144792" ID="ID_1869633875" MODIFIED="1749407148565" TEXT="Richtlinien">
|
||||
<node CREATED="1749407149503" ID="ID_824791307" LINK="https://quuxplusone.github.io/blog/2021/04/03/static-constexpr-whittling-knife/" MODIFIED="1749407166664" TEXT="Reihenfolge der Deklarations-Qualifier">
|
||||
<node CREATED="1749407219192" ID="ID_1604663290" MODIFIED="1749407248162" TEXT="attributes-friendness-storage-constness-virtualness-explicitness-signedness-length-type id">
|
||||
|
|
@ -166104,8 +166126,141 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1750173439337" ID="ID_1832825819" MODIFIED="1750173477173" TEXT="Schritt-2 : concept tuple_like einführen">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1750173439337" ID="ID_1832825819" MODIFIED="1750437317253" TEXT="Schritt-2 : concept tuple_like einführen">
|
||||
<icon BUILTIN="full-2"/>
|
||||
<node CREATED="1750603208092" ID="ID_1027099855" MODIFIED="1750603215948" TEXT="Design-Fragen">
|
||||
<node BACKGROUND_COLOR="#d2a99c" COLOR="#683b31" CREATED="1750603078830" ID="ID_1129626446" MODIFIED="1750606092989" TEXT="Basis für Concept tuple_like ?">
|
||||
<arrowlink COLOR="#4989d4" DESTINATION="ID_141049889" ENDARROW="Default" ENDINCLINATION="-494;29;" ID="Arrow_ID_789791822" STARTARROW="None" STARTINCLINATION="-1100;-64;"/>
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1750603270220" ID="ID_1796957923" MODIFIED="1750603293611" TEXT="minimal-Heuristik : tuple_size"/>
|
||||
<node CREATED="1750603306121" ID="ID_1429160230" MODIFIED="1750603318670" TEXT="hinreichend vollständig: Zugriff"/>
|
||||
<node CREATED="1750603344042" ID="ID_1866646887" MODIFIED="1750603365810" TEXT="Zweck: Datenzugriff">
|
||||
<node CREATED="1750603367100" ID="ID_730035620" MODIFIED="1750603395784" TEXT="per structured Binding"/>
|
||||
<node CREATED="1750603384299" ID="ID_1020038748" MODIFIED="1750603392055" TEXT="per meta-Iteratrion"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1750603402218" ID="ID_470643972" MODIFIED="1750606109292" TEXT="Hindernisse">
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
<node CREATED="1750603406649" ID="ID_722727058" MODIFIED="1750604154381" TEXT="die Element-Typen sind heterogen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
das limitiert die Nutzbarkeit ohnehin sehr stark, da man mit <i>unlimitiert generischen</i> Typen wenig Gemeinsames anfangen kann
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1750604156028" ID="ID_1521006525" MODIFIED="1750604169583" TEXT="structued Bindings sind für den konkreten Einhzelfall gedacht"/>
|
||||
<node CREATED="1750604220710" ID="ID_440079383" MODIFIED="1750604274377" TEXT="structured Bindings und das Tupel-Protokoll sind zweierlei"/>
|
||||
<node CREATED="1750604614495" ID="ID_1340240394" MODIFIED="1750606165686" TEXT="es ist unklar wohin das überhaupt führt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...auch der Standard gibt keine klaren Ziele an — vermutlich deshalb auch diese Diskrepanz, daß »tuple-like« nun doch nur für bestimmte STL-Klassen gelten soll; für diese engere Auswahl synthetisiert der Compiler nun (C++20) auch Vergleichsoperatoren. Aber darüber hinaus? es bleibt eine Art Parameter-Satz oder generischer Datensatz, mit dem man letztlich wenig anfangen kann ohne zusätzliche Anhaltspunkte (Referenzen, Kopierbarkeit, semantisches...)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#845a67" DESTINATION="ID_326674613" ENDARROW="Default" ENDINCLINATION="21;-52;" ID="Arrow_ID_1130948047" STARTARROW="None" STARTINCLINATION="-77;5;"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1750606050049" ID="ID_326674613" MODIFIED="1750606165686" TEXT="als Experiment / Erweiterung betrachten">
|
||||
<linktarget COLOR="#845a67" DESTINATION="ID_326674613" ENDARROW="Default" ENDINCLINATION="21;-52;" ID="Arrow_ID_1130948047" SOURCE="ID_1340240394" STARTARROW="None" STARTINCLINATION="-77;5;"/>
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1750606352138" ID="ID_395333940" MODIFIED="1750606364459" TEXT="möglichst neben die bestehenden Strukturen bauen"/>
|
||||
<node CREATED="1750606379162" ID="ID_1298795914" MODIFIED="1750606392271" TEXT="beobachten was auf dieser Basis entsteht"/>
|
||||
<node CREATED="1750606452227" ID="ID_1156552141" MODIFIED="1750606760885" TEXT="an structured Bindings anlehnen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
aber nur auf den einen Fall, der <i>allgemeine Typen</i> betrifft...
|
||||
</p>
|
||||
<p>
|
||||
d.h. wir unterstützen auch eine Memberfunktion get<i>()
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1750606686156" ID="ID_900094987" MODIFIED="1750606706321" TEXT="get()-Adapter bereitstellen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
mit duck-typing
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1750443947483" ID="ID_58139169" MODIFIED="1750443961178" TEXT="schrittweise...">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1750443954960" ID="ID_750458131" MODIFIED="1750443959664" TEXT="has_tuple_size">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1750527186585" ID="ID_1525384931" MODIFIED="1750608058172" TEXT="Zugriff auf tuple_element_t">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1750527194686" ID="ID_505645521" MODIFIED="1750607802335" TEXT="Problem: CV-Varianten">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1750527215075" ID="ID_160799608" MODIFIED="1750527224453" TEXT="werden in der STL unterstützt"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#940109" CREATED="1750527225378" ID="ID_934892679" MODIFIED="1750607814794" TEXT="typischerweise nicht für custom-Typen?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1750527281789" ID="ID_270337751" MODIFIED="1750608012143" TEXT="eigentlich könnte das generisch sein">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...wenn man selber Typen für das »tuple-protocol« einrichtet, hat man i.d.R nicht die Zeit, sich um alle CV-Varianten + RValues zu kümmern (es gibt ja einen konkreten Use-case); allerdings spielen die CV-Varianten nur für eine get<i>()-Funktion tatsächlich eine Rolle, denn dort muß sich diese Variante auf den Ergebnistyp auswirken; man könnte diese Varianten komplett genersich per Library-Funktion aus einer Basis-Impl ableiten...
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1750527289637" ID="ID_416596147" MODIFIED="1750527297966" TEXT="sehe aber nicht, daß die STL sowas definiert"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1750527261050" ID="ID_11850475" MODIFIED="1750527277291" TEXT="sollte auf das Minimal-Kriterium beschränken">
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1750608204631" ID="ID_228997425" MODIFIED="1750608220478" STYLE="fork" TEXT="get()-Adapter entwerfen">
|
||||
<icon BUILTIN="pencil"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1750608171148" ID="ID_645315221" MODIFIED="1750608181337" TEXT="experimental-Test funktioniert">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1750608083733" ID="ID_801317220" MODIFIED="1750608187648" TEXT="Schritt-3 : bestehende Heuristiken ersetzen">
|
||||
<icon BUILTIN="full-3"/>
|
||||
<node CREATED="1750608225207" ID="ID_1091625286" MODIFIED="1750608242780" TEXT="auf tuple-helper.hpp konzentrieren">
|
||||
<node CREATED="1750608253290" ID="ID_1066975990" MODIFIED="1750608258692" TEXT="bestehendes is_Structured fällt weg"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1750613310659" ID="ID_1955387309" MODIFIED="1750613325702" TEXT="kann man forEachIDX erweitern auf AndAll ?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1750613329800" ID="ID_737752412" MODIFIED="1750613379696" TEXT="es stört mich, wenn ich jetzt den Namen AndAll verwende">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
und doch nur einen fest verdrahteten Spezialfall definiere, bloß weil's jetzt grade convenient ernscheint
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1750613385497" ID="ID_1466450048" MODIFIED="1750613415281" TEXT="könnte gehen ⟹ dazu die Aritäts-Erkennung in das Impl-Template"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1750613423187" ID="ID_1618598998" MODIFIED="1750613435979" TEXT="gefährlich: erst mal als Prototyp ausarbeiten">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1750608261914" ID="ID_235249081" MODIFIED="1750608264567" TEXT="ablösen">
|
||||
<node CREATED="1750608267425" ID="ID_1368025835" MODIFIED="1750608268258" TEXT="is_Structured"/>
|
||||
<node CREATED="1750608320496" ID="ID_575832691" MODIFIED="1750608321852" TEXT="enable_if_TupleProtocol"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -166122,9 +166277,7 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1750431808678" ID="ID_1965718984" MODIFIED="1750433611399" TEXT="reproduzierbar auf Minimum reduziert">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<div style="background-color: #eee0b5; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 2px">
|
||||
<div style="color: #202020; background-color: #eee0b5; font-family: Bitstream Vera Sans Mono; font-size: 9pt; white-space: pre">
|
||||
|
|
@ -166209,9 +166362,7 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
</node>
|
||||
<node CREATED="1750433674672" ID="ID_1918452895" MODIFIED="1750436510834">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
vermutlich ein <i>sehr spezieller</i> Compiler-Bug
|
||||
|
|
|
|||
Loading…
Reference in a new issue