From 3a1f64ec4107371dc7825d4b0e0848dd1417999f Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 23 Jun 2025 23:02:15 +0200 Subject: [PATCH] Upgrade: now able to reformulate the `tuple_like` concept Now this draft seems ready to be put into actual use in the code base. Furthermore, a generic ''get adapter'' is introduced to level the difference between both tolerated forms of element access, also working correctly for const and RValue references --- research/try.cpp | 116 +++++++++++++++++++++++++-------------- wiki/thinkPad.ichthyo.mm | 110 ++++++++++++++++++++++++------------- 2 files changed, 148 insertions(+), 78 deletions(-) diff --git a/research/try.cpp b/research/try.cpp index 7792e4308..7d435bdcf 100644 --- a/research/try.cpp +++ b/research/try.cpp @@ -12,6 +12,8 @@ /** @file try.cpp * Develop a concept to detect _tuple-like_ classes, based on the requirements * of the »tuple protocol«. Using some ideas from [Stackoverflow] as starting point. + * However, we model both a _friend function_ `get` and a similar member function + * as alternatives for element access, and we break down the checks into sub-concepts. * [Stackoverflow]: https://stackoverflow.com/q/68443804/444796 */ @@ -36,45 +38,63 @@ namespace meta { { std::tuple_size::value } -> std::convertible_to; }; - - template + + template concept tuple_adl_accessible = requires(TUP tup) { - typename std::tuple_element_t; - { get(tup) } -> std::convertible_to&>; + typename std::tuple_element_t; + { get(tup) } -> std::convertible_to&>; }; - - template + + template concept tuple_mem_accessible = requires(TUP tup) { - typename std::tuple_element_t; - { tup.template get() } -> std::convertible_to&>; + typename std::tuple_element_t; + { tup.template get() } -> std::convertible_to&>; }; - - template - concept tuple_accessible = tuple_mem_accessible or tuple_adl_accessible; + + template + concept tuple_element_accessible = tuple_mem_accessible or tuple_adl_accessible; template - class AndAll - { - template - static constexpr bool - canAccessAll (std::index_sequence) - { - return (tuple_accessible and ...); - } - - using IdxSeq = typename ElmTypes::Idx; - - public: - static constexpr bool can_AccessElement = canAccessAll(IdxSeq{}); - }; - - - template - concept tuple_like = not is_reference_v - and tuple_sized> - and AndAll>::can_AccessElement; + concept tuple_accessible = + tuple_sized and + WithIdxSeq>::andAll([](auto idx) + { + return tuple_element_accessible; + }); + + + template + concept tuple_like = not is_reference_v + and tuple_sized> + and tuple_accessible>; + + + template + requires(tuple_like>) + decltype(auto) + get (TUP&& tup) + { + using Tup = std::remove_reference_t; + static_assert (0 < std::tuple_size_v); + if constexpr (tuple_mem_accessible) + { + if constexpr (std::is_reference_v) + return tup.template get(); + else + { // return value copy when tuple given as RValue + using Elm = std::tuple_element_t; + Elm elm(tup.template get()); + return elm; + } + } + else + { + using std::get; + return get (std::forward (tup)); + } + } }}//namespace lib::meta @@ -103,7 +123,7 @@ show() int main (int, char**) { - using Tup = std::tuple; + using Tup = std::tuple; using Arr = std::array; using Hetero = lib::HeteroData::Chain::ChainExtent::ChainType; @@ -112,11 +132,11 @@ main (int, char**) SHOW_EXPR((lib::meta::tuple_sized )) SHOW_EXPR((lib::meta::tuple_sized )) - SHOW_EXPR((lib::meta::tuple_accessible)) -// SHOW_EXPR((lib::meta::tuple_accessible)) - SHOW_EXPR((lib::meta::tuple_accessible)) - SHOW_EXPR((lib::meta::AndAll::can_AccessElement)) - SHOW_EXPR((lib::meta::AndAll::can_AccessElement)) + SHOW_EXPR((lib::meta::tuple_element_accessible)) +// SHOW_EXPR((lib::meta::tuple_element_accessible)) + SHOW_EXPR((lib::meta::tuple_element_accessible)) + SHOW_EXPR((lib::meta::tuple_accessible)) + SHOW_EXPR((lib::meta::tuple_accessible)) SHOW_EXPR((lib::meta::tuple_like )) SHOW_EXPR((lib::meta::tuple_like )) @@ -128,9 +148,25 @@ main (int, char**) show(); show(); - SHOW_EXPR(bool(std::is_integral_v)) - SHOW_EXPR(bool(std::is_integral_v)) - SHOW_EXPR(bool(std::is_integral_v)) + SHOW_EXPR((std::tuple_size_v)) + using Elm1 = std::tuple_element_t<1, const Tup>; + SHOW_TYPE(Elm1) + using TupConstSeq = lib::meta::ElmTypes::Seq; + SHOW_TYPE(TupConstSeq) + + using T1 = decltype(lib::meta::get<0> (std::declval())); + SHOW_TYPE(T1) + using T2 = decltype(lib::meta::get<0> (std::declval())); + SHOW_TYPE(T2) + using T3 = decltype(lib::meta::get<0> (std::declval())); + SHOW_TYPE(T3) + + using H1 = decltype(lib::meta::get<4> (std::declval())); + SHOW_TYPE(H1) + using H2 = decltype(lib::meta::get<4> (std::declval())); + SHOW_TYPE(H2) + using H3 = decltype(lib::meta::get<4> (std::declval())); + SHOW_TYPE(H3) cout << "\n.gulp." < - + - - + + - - - - - + + + + + - + - + @@ -166150,9 +166150,9 @@ Since then others have made contributions, see the log for the history. - - - + + + @@ -166165,13 +166165,13 @@ Since then others have made contributions, see the log for the history. - + - - - + + + @@ -166184,7 +166184,7 @@ Since then others have made contributions, see the log for the history. - + @@ -166196,19 +166196,19 @@ Since then others have made contributions, see the log for the history. - - - + + + - + - + - - + + - + @@ -166218,18 +166218,18 @@ Since then others have made contributions, see the log for the history. - + - + - - + + - + @@ -166239,7 +166239,8 @@ Since then others have made contributions, see the log for the history. - + + @@ -166299,8 +166300,8 @@ Since then others have made contributions, see the log for the history. - - + + @@ -166316,17 +166317,50 @@ Since then others have made contributions, see the log for the history. - + + - - + + + + + + +

+ das ist nämlich eine Spezialisierung, die dann bereits auf dieses Concept aufsetzen würde... +

+

+ und die interne Impl ist mehr oder weniger genau dasselbe, als wir zu Fuß auch machen würden, nur daß wir dann an die Index-Seq gar nicht rankommen +

+ + +
+ +
+
+ + + + + + + + + + - + + + + + + +