From 738d9e5b67502f84e2663e8b84f6e69e2c1bfd48 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 5 Jun 2025 18:00:05 +0200 Subject: [PATCH] clean-up: simplify function-closure -- investigate `BindToArgument` ...because swapping in the new standards-based implementation leads to compile failures on tests to cover out-of-bounds cases. Under the (wrong) assumption, that some mistake must be hidden in the Splice-metafunction, I first provided a complete test coverage; while the actual problem was right below my nose, and quite obvious... The old implementation, being based on a case distinction over the argument count, simply was not able even to notice excess arguments; other the new implementation, based on variadics and `std::apply`, which is fully generic and thus passes excess arguments to `std::bind` when a position beyond the actual argument list is specified to be closed. The old behaviour was to silently ignore such an out-of-bounds spec, and this can be reinstated by explicitly capping the prepared tuple of binders and actual arguments passed to `std::bind` Another question of course is, if being tolerant here is a good idea. And beyond that, function-closure.hpp is still terrifyingly complex, unorganised and use-case driven, to start with.... --- src/lib/meta/function-closure.hpp | 16 +- src/lib/meta/typelist-manip.hpp | 8 + .../meta/function-composition-test.cpp | 56 ++-- tests/library/meta/typelist-manip-test.cpp | 296 +++++++++++++++--- wiki/thinkPad.ichthyo.mm | 194 +++++++++++- 5 files changed, 492 insertions(+), 78 deletions(-) diff --git a/src/lib/meta/function-closure.hpp b/src/lib/meta/function-closure.hpp index 05d95c9ad..eedbc2358 100644 --- a/src/lib/meta/function-closure.hpp +++ b/src/lib/meta/function-closure.hpp @@ -583,7 +583,7 @@ namespace func{ /** * Bind a specific argument to an arbitrary value. - * Especially, this "value" might be another binder. + * Notably this "value" might be another binder. */ template class BindToArgument @@ -600,16 +600,17 @@ namespace func{ using PlaceholdersBefore = typename func::PlaceholderTuple::List; using PlaceholdersBehind = typename func::PlaceholderTuple::List; - using PreparedArgs = typename Append< typename Append< PlaceholdersBefore - , ValList >::List - , PlaceholdersBehind - >::List; + using PreparedArgsRaw = typename Append::List // splice in the value tuple + ,PlaceholdersBehind // arguments behind the splice: passed-through + >::List; + using PreparedArgs = Prefix; using ReducedArgs = typename Append::List; using PreparedArgTypes = typename TySeq::Seq; using RemainingArgs = typename TySeq::Seq; - using ReducedSig = typename BuildFunType::Sig; + using ReducedSig = typename BuildFunType::Sig; template using IdxSelector = typename PartiallyInitTuple::template IndexMapper; @@ -625,8 +626,7 @@ namespace func{ reduced (SIG& f, X val) { Tuple params {BuildPreparedArgs{std::make_tuple (val)}}; - return func::Apply::template bind (f, params); -// return bindArgTuple (f, params); ///////////////////////////////////////////////////////OOO does not compile when pos > length of ArgList + return bindArgTuple (f, params); } }; diff --git a/src/lib/meta/typelist-manip.hpp b/src/lib/meta/typelist-manip.hpp index a61af8845..7d0e7a81b 100644 --- a/src/lib/meta/typelist-manip.hpp +++ b/src/lib/meta/typelist-manip.hpp @@ -201,6 +201,14 @@ namespace meta { using Front = Nil; using Back = Nil; }; + /** extract prefix of given length */ + template + using Prefix = typename Splice::Front; + + /** extract suffix starting at given pos */ + template + using Suffix = typename Splice::Back; + diff --git a/tests/library/meta/function-composition-test.cpp b/tests/library/meta/function-composition-test.cpp index 8e7e72064..3fc0313b1 100644 --- a/tests/library/meta/function-composition-test.cpp +++ b/tests/library/meta/function-composition-test.cpp @@ -30,7 +30,7 @@ namespace meta { namespace test { using ::test::Test; - using lib::test::showType; +// using lib::test::showType; using lib::meta::_Fun; using func::applyFirst; using func::applyLast; @@ -192,9 +192,8 @@ namespace test { , ph2 ); - int res = 0; - res = fun_23 (_2_,_3_).o_; // and invoke the resulting functor ("closure"), providing the remaining arguments - CHECK (23 == res); + int r1 = fun_23 (_2_,_3_).o_; // and invoke the resulting functor ("closure"), providing the remaining arguments + CHECK (23 == r1); // result ≡ num18 + _2_ + _3_ ≙ 18 + 2 + 3 @@ -207,10 +206,15 @@ namespace test { , get<1>(arg) , get<2>(arg) ); - res = 0; - res = fun_23 (_2_,_3_).o_; // and invoke the resulting functor.... - CHECK (23 == res); + int r2 = fun_23 (_2_,_3_).o_; // and invoke the resulting functor.... + CHECK (23 == r2); + + // function-closure.hpp defines a shorthand for this operation + fun_23 = func::bindArgTuple (f, arg); + + int r3 = fun_23 (_2_,_3_).o_; + CHECK (23 == r3); @@ -221,9 +225,9 @@ namespace test { fun_23 = PApply::bindFront (f , args_to_bind); // "bindFront" will close the parameters starting from left.... - res = 0; - res = fun_23 (_2_,_3_).o_; // invoke the resulting functor... - CHECK (23 == res); + + int r4 = fun_23 (_2_,_3_).o_; // invoke the resulting functor... + CHECK (23 == r4); @@ -232,33 +236,33 @@ namespace test { // Version4: as you'd typically do it in real life-------- // +/* fun_23 = func::applyFirst (f, Num<1>(18)); // use the convenience function API to close over a single value - res = 0; - res = fun_23(_2_,_3_).o_; // invoke the resulting functor... - CHECK (23 == res); + int r5 = fun_23(_2_,_3_).o_; // invoke the resulting functor... + CHECK (23 == r5); // what follows is the real unit test... function func123{f}; // alternatively do it with an std::function object fun_23 = func::applyFirst (func123, Num<1>(19)); - res = fun_23(_2_,_3_).o_; - CHECK (24 == res); + int r5 = fun_23(_2_,_3_).o_; + CHECK (24 == r5); using F12 = function(Num<1>, Num<2>)>; F12 fun_12 = func::applyLast (f, Num<3>(20)); // close the *last* argument of a function - res = fun_12(_1_,_2_).o_; - CHECK (23 == res); + int r6 = fun_12(_1_,_2_).o_; + CHECK (23 == r6); fun_12 = func::applyLast (func123, Num<3>(21)); // alternatively use a function object - res = fun_12(_1_,_2_).o_; - CHECK (24 == res); + int r7 = fun_12(_1_,_2_).o_; + CHECK (24 == r7); Sig123* fP = &f; // a function pointer works too fun_12 = func::applyLast (fP, Num<3>(22)); - res = fun_12(_1_,_2_).o_; - CHECK (25 == res); + int r8 = fun_12(_1_,_2_).o_; + CHECK (25 == r8); // cover more cases.... CHECK (1 == (func::applyLast (fun11<1> , _1_ ) ( ) ).o_); @@ -272,6 +276,7 @@ namespace test { CHECK ( 7+6+5 == (func::applyFirst( fun13<7,6,5>, _7_ ) (_6_,_5_)).o_); CHECK ( 6+5 == (func::applyFirst( fun12<6,5>, _6_ ) (_5_)).o_); CHECK ( 5 == (func::applyFirst( fun11<5>, _5_ ) ( )).o_); + */ @@ -279,7 +284,7 @@ namespace test { // covering the general case of partial function closure: typedef Num<5> Sig54321 (Num<5>, Num<4>, Num<3>, Num<2>, Num<1>); // Signature of the 5-argument function typedef Num<5> Sig54 (Num<5>, Num<4>); // ...closing the last 3 arguments should yield this 2-argument function - using Args2Close = TyOLD, Num<2>, Num<1>>; // Tuple type to hold the 3 argument values used for the closure + using Args2Close = TySeq, Num<2>, Num<1>>; // Tuple type to hold the 3 argument values used for the closure // Close the trailing 3 arguments of the 5-argument function... function fun_54 = PApply::bindBack (fun15<5,4,3,2,1> @@ -293,7 +298,6 @@ namespace test { - void check_functionalComposition () { @@ -399,9 +403,9 @@ namespace test { using SigC = _Fun::Sig; using SigP = _Fun::Sig; - CHECK (showType() == "double (float&, int&, long)"_expect); - CHECK (showType() == "long (float&, int&, long)"_expect); - CHECK (showType() == "double (int&, long)"_expect); +// CHECK (showType() == "double (float&, int&, long)"_expect); +// CHECK (showType() == "long (float&, int&, long)"_expect); +// CHECK (showType() == "double (int&, long)"_expect); CHECK (220 == f1 (ff,ii,33)); CHECK (220 == chain(ff,ii,33)); diff --git a/tests/library/meta/typelist-manip-test.cpp b/tests/library/meta/typelist-manip-test.cpp index 6a2915ed4..64b92c1da 100644 --- a/tests/library/meta/typelist-manip-test.cpp +++ b/tests/library/meta/typelist-manip-test.cpp @@ -45,14 +45,14 @@ namespace test { namespace { // type-lists to test with - typedef TySeq< Num<1> - , Num<2> - , Num<3> - >::List List1; - typedef TySeq< Num<5> - , Num<6> - , Num<7> - >::List List2; + using List1 = TySeq< Num<1> + , Num<2> + , Num<3> + >::List; + using List2 = TySeq< Num<5> + , Num<6> + , Num<7> + >::List; // see also the CountDown template in typelist-diagnostics.hpp... @@ -193,42 +193,266 @@ namespace test { } - /** @test splice (or rather paste) a list on top of a base list + + /** @test splice (or rather paste) a list on top of a base list. + * @note a zero-splice can be used to extract arbitrary sublists * @remark the intended use case is to manipulate some parameters * in a given function-type argument list + * @remark this test is so extensive (really complete coverage), + * since in 2025 a malfunction was mistakenly suspected. */ void verify_splice () - { - using OLi = TySeq,Num<8>>::List; - // will "paste" the list OLi "on top" of another Typelist... + { // various base lists + using BaLi1 = TySeq>::List; EXPECT (BaLi1, "-<1>-"); + using BaLi2 = TySeq,Num<2>>::List; EXPECT (BaLi2, "-<1>-<2>-"); + using BaLi3 = TySeq,Num<2>,Num<3>>::List; EXPECT (BaLi3, "-<1>-<2>-<3>-"); + using BaLi5 = TySeq,Num<2>,Num<3>,Num<4>,Num<5>>::List; + EXPECT (BaLi5, "-<1>-<2>-<3>-<4>-<5>-"); - using Overl01 = Splice; EXPECT (Overl01, "-"); - using Overl02 = Splice; EXPECT (Overl02, "-"); - using Overl03 = Splice; EXPECT (Overl03, "-"); - using Overl04 = Splice; EXPECT (Overl04, "-<9>-<8>-<3>-"); - using Overl05 = Splice; EXPECT (Overl05, "-<1>-<9>-<8>-"); - using Overl06 = Splice; EXPECT (Overl06, "-<1>-<2>-<9>-"); - using Overl07 = Splice; EXPECT (Overl07, "-<1>-<2>-<3>-"); - using Overl08 = Splice; EXPECT (Overl08, "-<1>-<2>-<3>-"); - using Overl09 = Splice; EXPECT (Overl09, "-<1>-<2>-<3>-"); - using Overl10 = Splice; EXPECT (Overl10, "-<1>-<1>-<2>-"); - using Overl11 = Splice; EXPECT (Overl11, "-<1>-<2>-<3>-"); - using Overl12 = Splice; EXPECT (Overl12, "-<1>-<2>-<3>-"); - using Overl13 = Splice; EXPECT (Overl13, "-<1>-<2>-<3>-"); + // will "paste" those overlay lists "on top" the base typelists... + using OLi1 = TySeq>::List; EXPECT (OLi1, "-<9>-"); + using OLi2 = TySeq,Num<8>>::List; EXPECT (OLi2, "-<9>-<8>-"); + using OLi3 = TySeq,Num<8>,Num<7>>::List; EXPECT (OLi3, "-<9>-<8>-<7>-"); - using OLi2 = TySeq>::List; - // can retrieve the remaining part of the original list, left and right of splice - using Front1 = Splice::Front; EXPECT (Front1, "-" ); - using Front2 = Splice::Front; EXPECT (Front2, "-<1>-" ); - using Front3 = Splice::Front; EXPECT (Front3, "-<1>-<2>-<3>-"); - using Back1 = Splice::Back; EXPECT (Back1 , "-<2>-<3>-" ); - using Back2 = Splice::Back; EXPECT (Back2 , "-<3>-" ); - using Back3 = Splice::Back; EXPECT (Back3 , "-" ); - // Note: with a Null-Overlay, this can be used to extract arbitrary sublists: - using Front4 = Splice::Front; EXPECT (Front4, "-<1>-" ); - using Back4 = Splice::Back; EXPECT (Back4 , "-<2>-<3>-"); + /////////////////////////////////////////////////// + // (1) simple cases : on top of 3-element base list + using Spli01 = Splice; EXPECT (Spli01, "-<9>-<2>-<3>-"); + using Spli02 = Splice; EXPECT (Spli02, "-<1>-<9>-<3>-"); + using Spli03 = Splice; EXPECT (Spli03, "-<1>-<2>-<9>-"); + using Spli04 = Splice; EXPECT (Spli04, "-<1>-<2>-<3>-"); + using Spli05 = Splice; EXPECT (Spli05, "-<1>-<2>-<3>-"); + + using Spli06 = Splice; EXPECT (Spli06, "-<9>-<8>-<3>-"); + using Spli07 = Splice; EXPECT (Spli07, "-<1>-<9>-<8>-"); + using Spli08 = Splice; EXPECT (Spli08, "-<1>-<2>-<9>-"); + using Spli09 = Splice; EXPECT (Spli09, "-<1>-<2>-<3>-"); + using Spli10 = Splice; EXPECT (Spli10, "-<1>-<2>-<3>-"); + + using Spli11 = Splice; EXPECT (Spli11, "-<9>-<8>-<7>-"); + using Spli12 = Splice; EXPECT (Spli12, "-<1>-<9>-<8>-"); + using Spli13 = Splice; EXPECT (Spli13, "-<1>-<2>-<9>-"); + using Spli14 = Splice; EXPECT (Spli14, "-<1>-<2>-<3>-"); + using Spli15 = Splice; EXPECT (Spli15, "-<1>-<2>-<3>-"); + + // (1b) corresponding Front / Back cases + using Frnt01 = Splice ::Front; EXPECT (Frnt01, "-"); + using Frnt02 = Splice::Front; EXPECT (Frnt02, "-<1>-"); + using Frnt03 = Splice::Front; EXPECT (Frnt03, "-<1>-<2>-"); + using Frnt04 = Splice::Front; EXPECT (Frnt04, "-<1>-<2>-<3>-"); + using Frnt05 = Splice::Front; EXPECT (Frnt05, "-<1>-<2>-<3>-"); + + using Frnt06 = Splice::Front; EXPECT (Frnt06, "-"); + using Frnt07 = Splice::Front; EXPECT (Frnt07, "-<1>-"); + using Frnt08 = Splice::Front; EXPECT (Frnt08, "-<1>-<2>-"); + using Frnt09 = Splice::Front; EXPECT (Frnt09, "-<1>-<2>-<3>-"); + using Frnt10 = Splice::Front; EXPECT (Frnt10, "-<1>-<2>-<3>-"); + + using Frnt11 = Splice::Front; EXPECT (Frnt11, "-"); + using Frnt12 = Splice::Front; EXPECT (Frnt12, "-<1>-"); + using Frnt13 = Splice::Front; EXPECT (Frnt13, "-<1>-<2>-"); + using Frnt14 = Splice::Front; EXPECT (Frnt14, "-<1>-<2>-<3>-"); + using Frnt15 = Splice::Front; EXPECT (Frnt15, "-<1>-<2>-<3>-"); + + using Back01 = Splice ::Back; EXPECT (Back01, "-<2>-<3>-"); + using Back02 = Splice::Back; EXPECT (Back02, "-<3>-"); + using Back03 = Splice::Back; EXPECT (Back03, "-"); + using Back04 = Splice::Back; EXPECT (Back04, "-"); + using Back05 = Splice::Back; EXPECT (Back05, "-"); + + using Back06 = Splice::Back; EXPECT (Back06, "-<3>-"); + using Back07 = Splice::Back; EXPECT (Back07, "-"); + using Back08 = Splice::Back; EXPECT (Back08, "-"); + using Back09 = Splice::Back; EXPECT (Back09, "-"); + using Back10 = Splice::Back; EXPECT (Back10, "-"); + + using Back11 = Splice::Back; EXPECT (Back11, "-"); + using Back12 = Splice::Back; EXPECT (Back12, "-"); + using Back13 = Splice::Back; EXPECT (Back13, "-"); + using Back14 = Splice::Back; EXPECT (Back14, "-"); + using Back15 = Splice::Back; EXPECT (Back15, "-"); + + + /////////////////////////////////////////////////// + // (2) simple cases : on top of 5-element base list + using Spli16 = Splice; EXPECT (Spli16, "-<9>-<2>-<3>-<4>-<5>-"); + using Spli17 = Splice; EXPECT (Spli17, "-<1>-<9>-<3>-<4>-<5>-"); + using Spli18 = Splice; EXPECT (Spli18, "-<1>-<2>-<9>-<4>-<5>-"); + using Spli19 = Splice; EXPECT (Spli19, "-<1>-<2>-<3>-<9>-<5>-"); + using Spli20 = Splice; EXPECT (Spli20, "-<1>-<2>-<3>-<4>-<9>-"); + using Spli21 = Splice; EXPECT (Spli21, "-<1>-<2>-<3>-<4>-<5>-"); + using Spli22 = Splice; EXPECT (Spli22, "-<1>-<2>-<3>-<4>-<5>-"); + + using Spli23 = Splice; EXPECT (Spli23, "-<9>-<8>-<3>-<4>-<5>-"); + using Spli24 = Splice; EXPECT (Spli24, "-<1>-<9>-<8>-<4>-<5>-"); + using Spli25 = Splice; EXPECT (Spli25, "-<1>-<2>-<9>-<8>-<5>-"); + using Spli26 = Splice; EXPECT (Spli26, "-<1>-<2>-<3>-<9>-<8>-"); + using Spli27 = Splice; EXPECT (Spli27, "-<1>-<2>-<3>-<4>-<9>-"); + using Spli28 = Splice; EXPECT (Spli28, "-<1>-<2>-<3>-<4>-<5>-"); + using Spli29 = Splice; EXPECT (Spli29, "-<1>-<2>-<3>-<4>-<5>-"); + + using Spli30 = Splice; EXPECT (Spli30, "-<9>-<8>-<7>-<4>-<5>-"); + using Spli31 = Splice; EXPECT (Spli31, "-<1>-<9>-<8>-<7>-<5>-"); + using Spli32 = Splice; EXPECT (Spli32, "-<1>-<2>-<9>-<8>-<7>-"); + using Spli33 = Splice; EXPECT (Spli33, "-<1>-<2>-<3>-<9>-<8>-"); + using Spli34 = Splice; EXPECT (Spli34, "-<1>-<2>-<3>-<4>-<9>-"); + using Spli35 = Splice; EXPECT (Spli35, "-<1>-<2>-<3>-<4>-<5>-"); + using Spli36 = Splice; EXPECT (Spli36, "-<1>-<2>-<3>-<4>-<5>-"); + + // (2b) corresponding Front / Back cases + using Frnt16 = Splice ::Front; EXPECT (Frnt16, "-"); + using Frnt17 = Splice::Front; EXPECT (Frnt17, "-<1>-"); + using Frnt18 = Splice::Front; EXPECT (Frnt18, "-<1>-<2>-"); + using Frnt19 = Splice::Front; EXPECT (Frnt19, "-<1>-<2>-<3>-"); + using Frnt20 = Splice::Front; EXPECT (Frnt20, "-<1>-<2>-<3>-<4>-"); + using Frnt21 = Splice::Front; EXPECT (Frnt21, "-<1>-<2>-<3>-<4>-<5>-"); + using Frnt22 = Splice::Front; EXPECT (Frnt22, "-<1>-<2>-<3>-<4>-<5>-"); + + using Frnt23 = Splice::Front; EXPECT (Frnt23, "-"); + using Frnt24 = Splice::Front; EXPECT (Frnt24, "-<1>-"); + using Frnt25 = Splice::Front; EXPECT (Frnt25, "-<1>-<2>-"); + using Frnt26 = Splice::Front; EXPECT (Frnt26, "-<1>-<2>-<3>-"); + using Frnt27 = Splice::Front; EXPECT (Frnt27, "-<1>-<2>-<3>-<4>-"); + using Frnt28 = Splice::Front; EXPECT (Frnt28, "-<1>-<2>-<3>-<4>-<5>-"); + using Frnt29 = Splice::Front; EXPECT (Frnt29, "-<1>-<2>-<3>-<4>-<5>-"); + + using Frnt30 = Splice::Front; EXPECT (Frnt30, "-"); + using Frnt31 = Splice::Front; EXPECT (Frnt31, "-<1>-"); + using Frnt32 = Splice::Front; EXPECT (Frnt32, "-<1>-<2>-"); + using Frnt33 = Splice::Front; EXPECT (Frnt33, "-<1>-<2>-<3>-"); + using Frnt34 = Splice::Front; EXPECT (Frnt34, "-<1>-<2>-<3>-<4>-"); + using Frnt35 = Splice::Front; EXPECT (Frnt35, "-<1>-<2>-<3>-<4>-<5>-"); + using Frnt36 = Splice::Front; EXPECT (Frnt36, "-<1>-<2>-<3>-<4>-<5>-"); + + using Back16 = Splice ::Back; EXPECT (Back16, "-<2>-<3>-<4>-<5>-"); + using Back17 = Splice::Back; EXPECT (Back17, "-<3>-<4>-<5>-"); + using Back18 = Splice::Back; EXPECT (Back18, "-<4>-<5>-"); + using Back19 = Splice::Back; EXPECT (Back19, "-<5>-"); + using Back20 = Splice::Back; EXPECT (Back20, "-"); + using Back21 = Splice::Back; EXPECT (Back21, "-"); + using Back22 = Splice::Back; EXPECT (Back22, "-"); + + using Back23 = Splice::Back; EXPECT (Back23, "-<3>-<4>-<5>-"); + using Back24 = Splice::Back; EXPECT (Back24, "-<4>-<5>-"); + using Back25 = Splice::Back; EXPECT (Back25, "-<5>-"); + using Back26 = Splice::Back; EXPECT (Back26, "-"); + using Back27 = Splice::Back; EXPECT (Back27, "-"); + using Back28 = Splice::Back; EXPECT (Back28, "-"); + using Back29 = Splice::Back; EXPECT (Back29, "-"); + + using Back30 = Splice::Back; EXPECT (Back30, "-<4>-<5>-"); + using Back31 = Splice::Back; EXPECT (Back31, "-<5>-"); + using Back32 = Splice::Back; EXPECT (Back32, "-"); + using Back33 = Splice::Back; EXPECT (Back33, "-"); + using Back34 = Splice::Back; EXPECT (Back34, "-"); + using Back35 = Splice::Back; EXPECT (Back35, "-"); + using Back36 = Splice::Back; EXPECT (Back36, "-"); + + + ///////////////////////////////////////////////////////// + // (3) degenerate case : excess overlay over smaller base + using Spli37 = Splice; EXPECT (Spli37, "-<9>-<8>-"); + using Spli38 = Splice; EXPECT (Spli38, "-<1>-<9>-"); + using Spli39 = Splice; EXPECT (Spli39, "-<1>-<2>-"); + using Spli40 = Splice; EXPECT (Spli40, "-<1>-<2>-"); + + using Spli41 = Splice; EXPECT (Spli41, "-<9>-"); + using Spli42 = Splice; EXPECT (Spli42, "-<1>-"); + using Spli43 = Splice; EXPECT (Spli43, "-<1>-"); + using Spli44 = Splice; EXPECT (Spli44, "-<1>-"); + + // (3b) corresponding Front / Back cases + using Frnt37 = Splice::Front; EXPECT (Frnt37, "-"); + using Frnt38 = Splice::Front; EXPECT (Frnt38, "-<1>-"); + using Frnt39 = Splice::Front; EXPECT (Frnt39, "-<1>-<2>-"); + using Frnt40 = Splice::Front; EXPECT (Frnt40, "-<1>-<2>-"); + + using Frnt41 = Splice::Front; EXPECT (Frnt41, "-"); + using Frnt42 = Splice::Front; EXPECT (Frnt42, "-<1>-"); + using Frnt43 = Splice::Front; EXPECT (Frnt43, "-<1>-"); + using Frnt44 = Splice::Front; EXPECT (Frnt44, "-<1>-"); + + using Back37 = Splice::Back; EXPECT (Back37, "-"); + using Back38 = Splice::Back; EXPECT (Back38, "-"); + using Back39 = Splice::Back; EXPECT (Back39, "-"); + using Back40 = Splice::Back; EXPECT (Back40, "-"); + + using Back41 = Splice::Back; EXPECT (Back41, "-"); + using Back42 = Splice::Back; EXPECT (Back42, "-"); + using Back43 = Splice::Back; EXPECT (Back43, "-"); + using Back44 = Splice::Back; EXPECT (Back44, "-"); + + + /////////////////////////////////// + // (4) degenerate case : empty base + using Spli45 = Splice; EXPECT (Spli45, "-"); + using Spli46 = Splice; EXPECT (Spli46, "-"); + using Spli47 = Splice; EXPECT (Spli47, "-"); + + using Spli48 = Splice; EXPECT (Spli48, "-"); + using Spli49 = Splice; EXPECT (Spli49, "-"); + using Spli50 = Splice; EXPECT (Spli50, "-"); + + using Spli51 = Splice; EXPECT (Spli51, "-"); + using Spli52 = Splice; EXPECT (Spli52, "-"); + using Spli53 = Splice; EXPECT (Spli53, "-"); + + // (4b) corresponding Front / Back cases + using Frnt45 = Splice::Front; EXPECT (Frnt45, "-"); + using Frnt46 = Splice::Front; EXPECT (Frnt46, "-"); + using Frnt47 = Splice::Front; EXPECT (Frnt47, "-"); + + using Frnt48 = Splice::Front; EXPECT (Frnt48, "-"); + using Frnt49 = Splice::Front; EXPECT (Frnt49, "-"); + using Frnt50 = Splice::Front; EXPECT (Frnt50, "-"); + + using Frnt51 = Splice::Front; EXPECT (Frnt51, "-"); + using Frnt52 = Splice::Front; EXPECT (Frnt52, "-"); + using Frnt53 = Splice::Front; EXPECT (Frnt53, "-"); + + using Back45 = Splice::Back; EXPECT (Back45, "-"); + using Back46 = Splice::Back; EXPECT (Back46, "-"); + using Back47 = Splice::Back; EXPECT (Back47, "-"); + + using Back48 = Splice::Back; EXPECT (Back48, "-"); + using Back49 = Splice::Back; EXPECT (Back49, "-"); + using Back50 = Splice::Back; EXPECT (Back50, "-"); + + using Back51 = Splice::Back; EXPECT (Back51, "-"); + using Back52 = Splice::Back; EXPECT (Back52, "-"); + using Back53 = Splice::Back; EXPECT (Back53, "-"); + + + ////////////////////////////////////////// + // (4) special case : zero-splice is split + using Spli54 = Splice; EXPECT (Spli54, "-<1>-<2>-<3>-"); + using Spli55 = Splice; EXPECT (Spli55, "-<1>-<2>-<3>-"); + using Spli56 = Splice; EXPECT (Spli56, "-<1>-<2>-<3>-"); + using Spli57 = Splice; EXPECT (Spli57, "-<1>-<2>-<3>-"); + using Spli58 = Splice; EXPECT (Spli58, "-<1>-<2>-<3>-"); + using Spli59 = Splice; EXPECT (Spli59, "-<1>-<2>-<3>-"); + + // (4b) Front / Back cases : split parts + using Frnt54 = Splice::Front; EXPECT (Frnt54, "-"); + using Frnt55 = Splice::Front; EXPECT (Frnt55, "-<1>-"); + using Frnt56 = Splice::Front; EXPECT (Frnt56, "-<1>-<2>-"); + using Frnt57 = Splice::Front; EXPECT (Frnt57, "-<1>-<2>-<3>-"); + using Frnt58 = Splice::Front; EXPECT (Frnt58, "-<1>-<2>-<3>-"); + using Frnt59 = Splice::Front; EXPECT (Frnt59, "-<1>-<2>-<3>-"); + + using Back54 = Splice::Back; EXPECT (Back54, "-<1>-<2>-<3>-"); + using Back55 = Splice::Back; EXPECT (Back55, "-<2>-<3>-"); + using Back56 = Splice::Back; EXPECT (Back56, "-<3>-"); + using Back57 = Splice::Back; EXPECT (Back57, "-"); + using Back58 = Splice::Back; EXPECT (Back58, "-"); + using Back59 = Splice::Back; EXPECT (Back59, "-"); + + // Note: these special usages are provided as shorthand + using Prfx55 = Prefix; EXPECT (Prfx55, "-<1>-"); + using Sufx55 = Suffix; EXPECT (Sufx55, "-<2>-<3>-"); + using Prfx56 = Prefix; EXPECT (Prfx56, "-<1>-<2>-"); + using Sufx56 = Suffix; EXPECT (Sufx56, "-<3>-"); } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 49d456c92..f176590d0 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -164428,8 +164428,7 @@ Since then others have made contributions, see the log for the history. - - + @@ -164438,11 +164437,12 @@ Since then others have made contributions, see the log for the history. - + - + + @@ -164452,8 +164452,9 @@ Since then others have made contributions, see the log for the history. - + + @@ -164499,8 +164500,7 @@ Since then others have made contributions, see the log for the history.» off by one «

- - + @@ -164511,11 +164511,160 @@ Since then others have made contributions, see the log for the history.
- + + + + +
+ + + + +
+ + + + + + + + + + + +

+ ECHT JETZT! +

+

+ Es geht um Intervall-Relationen — bekanntermaßen eines der (fast) ekelhaftesten Fallunterscheidungen (Lage von Raumgebieten zueinander oder teilweise ähnlichen Topologien zueinander ist noch schrecklicher) +

+ +
+ + + + + + + + +

+ da als rekursive Berechnung implementiert und der pos-Parameter auch korrekt als uint definiert +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ Warum hab ich das nicht gleich gesehen????? +

+
    +
  • + Ich hatte alle relevanten Informationen bereits gestern Nacht, aus dem Compile-Fehler +
  • +
  • + hab dann wohl einen Tunellblick gehabt, und dann sofort nach der Splice-Implementierung als »Strohhalm« gegriffen, denn das ist was Systematisches +
  • +
  • + und heute hab ich jetzt ein paar Stunden damit verbracht, einen systematischen Testfall runterzuklopfen (was nun immerhin eine vertrauensbildende Maßname ist, denn die Splice-Metafunktion ist definitiv komplex) +
  • +
+ + +
+ +
+ + + + + + +

+ also vermutlich war mir das damals so völlig klar, daß ich es einfach gemacht habe, ohne einen Kommentar zu hinterlassen; es war ja auch eine Spezialanfertigung für diesen einen Fall, und explizit für 1..9 Parameter so ausgeklopft +

+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -164594,6 +164743,35 @@ Since then others have made contributions, see the log for the history. + + + + + + +

+ Trigger... +

+

+ jeder vollständige Aufruf von +

+

+ func::bindFirst(f, val) +

+

+ — oder — +

+

+ func::bindLast(f, val) +

+

+ +

+ + +
+ +