/* try.cpp - to try out and experiment with new features.... * scons will create the binary bin/try */ // 03/26 - runtime index access and iteration over tuple-likes // 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 // 11/24 - how to define a bare object location comparison predicate // 11/23 - prototype for grouping from iterator /** @file try.cpp * Work out a construction scheme to build an efficient element-accessor to data * in a tuple-like with run-time indexing. As an extension, run-time pulled iteration * can be established, using the IterExplorer framework. * @see lib::meta::FunTrampoline * @see lib::meta::TupleIdxAdaptor */ #include "lib/format-cout.hpp" #include "lib/format-util.hpp" #include "test/test-helper.hpp" #include "test/diagnostic-output.hpp" #include "lib/meta/common-result.hpp" #include "lib/meta/tuple-concept.hpp" #include "lib/meta/tuple-helper.hpp" #include "lib/meta/function.hpp" #include "lib/iter-adapter.hpp" #include "lib/hetero-data.hpp" #include "lib/meta/trait.hpp" #include "lib/util.hpp" #include using std::string; template void show() { SHOW_TYPE(X) } template void show() { cout << "Tulik!! "<< ::test::showType() < ([](auto i) { using Elm = std::tuple_element_t; cout <<" "<() <` */ template concept typeseq = requires (TSEQ seq) { // TSEQ can invoke a function with a Types subclass [](Types&){/*placeholder*/}(seq); }; #endif ///////////////////////////////////////////////////////////////////////////////////////////////////(End) : new generic library functions template class BUILD, typeseq TSEQ> class FunTrampoline { using AllElm = ElmTypes; using Indices = AllElm::Idx; using Builder = BUILD; using Functor = Builder::Functor; using Table = std::array; template static constexpr Table buildFunctors (std::index_sequence) { return {Builder().template build()...}; } static constexpr Table functors = buildFunctors (Indices{}); public: static constexpr size_t size() { return functors.size(); } static constexpr size_t memSiz() { return sizeof(functors); } static Functor const& dispatch (size_t idx) { ENSURE (idx < functors.size()); return functors[idx]; } using ResType = _Fun::Ret; }; #if false ///////////////////////////////////////////////////////////////////////////////////////////////////TODO : new generic library functions template using isConst = std::is_const>; template using isLRef = std::is_lvalue_reference; template using Any_Const = ElmTypes::template OrAll; template using All_LRef = ElmTypes::template AndAll; template static constexpr bool Any_Const_v = Any_Const::value; template static constexpr bool All_LRef_v = All_LRef::value; template struct ProbeCommonType { template using Reconciled = decltype(true ? std::declval() : std::declval()); template struct FoundResult : std::true_type { using Type = RES; }; struct NoResultFound : std::false_type { }; template> static FoundResult> check(int); template static NoResultFound check(...); using FirstResult = decltype(check(0)); template struct Join { using Result = FirstResult; }; template struct Join { //wenn RES erfolgreich using CT = FirstResult::Type; using Result = ProbeCommonType::Result; }; using Result = Join::Result; }; template struct CommonResult : ProbeCommonType::Result { }; template struct CommonResult : CommonResult { }; template<> struct CommonResult<> : std::false_type { }; template struct CommonResult> : CommonResult { }; template using CommonResult_t = CommonResult::Type; template static constexpr bool has_CommonResult_v = CommonResult::value; template concept reconcilable = requires { typename CommonResult::Type; }; template concept reconcilable_ref = reconcilable and isLRef_v>; template struct CommonResultTraits { static_assert (reconcilable, "unable to reconcile these types"); using CommonVal = std::common_type_t; using ResType = CommonResult_t; //NOTE: std::common_type decays (strips CV and ref) static constexpr bool makeConst = isConst_v; static constexpr bool exposeRef = isLRef_v; }; #endif ///////////////////////////////////////////////////////////////////////////////////////////////////(End) : new generic library functions template class TupleIndexAdaptor : public TUP { template struct SubscriptBuilder { using Tuple = RefTraits::value_type; using AddRefs = ElmTypes::template Apply; using ResType = CommonResult_t; using Functor = ResType(*)(Tuple&); template constexpr auto build() { return [](Tuple& tuple) -> ResType { return getElm (tuple); }; } }; using TypeSeq = ElmTypes::Seq; using Accessor = FunTrampoline; public: using ResType = Accessor::ResType; using reference = ResType; using value_Type = RefTraits::value_type; template TupleIndexAdaptor(T&& dataSrc) : TUP{forward (dataSrc)} { } using TUP::TUP; static constexpr size_t size() { return Accessor::size(); } ResType operator[] (size_t idx) { return Accessor::dispatch(idx)(*this); } }; template TupleIndexAdaptor(TUP) -> TupleIndexAdaptor>; }} using namespace lib::meta; template struct Stringify { using Tuple = ElmTypes::Tup; using Functor = string(*)(Tuple const&); template constexpr auto build() { using ElmT = std::tuple_element_t; return [](Tuple const& tuple) { return util::toString (getElm (tuple)); }; } }; struct Uber { }; struct Untr : Uber { }; struct Unta : Uber { }; int main (int, char**) { using Tup = std::tuple; using Arr = std::array; using Hetero = lib::HeteroData::Chain::ChainExtent::ChainType; SHOW_EXPR((lib::meta::tuple_like )) SHOW_EXPR((lib::meta::tuple_like )) SHOW_EXPR((lib::meta::tuple_like )) SHOW_EXPR((lib::meta::tuple_like )) SHOW_EXPR((lib::meta::tuple_like )) show(); show(); show(); show(); using TupStringy = FunTrampoline::Seq>; SHOW_EXPR(TupStringy::size()) Tup tup23{2,3}; Tup tup42{4,2}; SHOW_TYPE(decltype(std::get<1>(tup42))) SHOW_EXPR(std::get<1>(tup42)) SHOW_EXPR(TupStringy::dispatch(0)(tup23)) SHOW_EXPR(TupStringy::dispatch(0)(tup42)) SHOW_EXPR(TupStringy::dispatch(1)(tup23)) SHOW_EXPR(TupStringy::dispatch(1)(tup42)) using T1 = Types; using T2 = Types; using T3 = Types; SHOW_EXPR((has_CommonResult_v)) SHOW_EXPR((has_CommonResult_v)) SHOW_EXPR((has_CommonResult_v)) SHOW_EXPR((has_CommonResult_v<>)) SHOW_EXPR((has_CommonResult_v)) SHOW_EXPR((has_CommonResult_v)) SHOW_TYPE(CommonResult_t) SHOW_TYPE(CommonResult_t) SHOW_TYPE(CommonResult_t) using CoTx = CommonResult_t; SHOW_TYPE(CoTx) TupleIndexAdaptor idxAdapt{tup42}; SHOW_EXPR(sizeof(tup42)) SHOW_EXPR(sizeof(idxAdapt)) SHOW_TYPE(TupleIndexAdaptor::ResType) SHOW_EXPR(idxAdapt.size()) SHOW_EXPR(idxAdapt[0]) SHOW_EXPR(idxAdapt[1]) SHOW_EXPR(getElm<0>(static_cast (idxAdapt))) SHOW_EXPR(getElm<1>(static_cast (idxAdapt))) SHOW_TYPE(decltype(idxAdapt[1])) using Tup2 = std::tuple; int ii{23}; Tup2 tup21{-1,ii,55}; TupleIndexAdaptor idxApt2{tup21}; SHOW_TYPE(decltype(tup21)) using IdxApt2 = decltype(idxApt2); SHOW_TYPE(IdxApt2) SHOW_TYPE(IdxApt2::ResType) SHOW_EXPR(idxApt2[0]) SHOW_EXPR(idxApt2[1]) SHOW_EXPR(idxApt2[2]) SHOW_EXPR(++idxApt2[0]) SHOW_EXPR(idxApt2[1]++) SHOW_EXPR(++++idxApt2[2]) SHOW_EXPR(tup21) SHOW_EXPR(Tup2(idxApt2)) SHOW_EXPR(ii) using TupIt = lib::IterableDecorator>; TupIt tupIt{move(idxApt2)}; SHOW_EXPR( bool(tupIt) ) SHOW_EXPR( *tupIt ) SHOW_TYPE(decltype(*tupIt)) ++*tupIt; --ii; SHOW_EXPR( *tupIt ) SHOW_EXPR(util::join(tupIt, "▶▶")) SHOW_EXPR(( reconcilable )) SHOW_EXPR(( reconcilable )) SHOW_EXPR(( reconcilable )) SHOW_EXPR(( reconcilable )) SHOW_EXPR(( reconcilable_ref )) SHOW_EXPR(( reconcilable_ref )) SHOW_EXPR(( reconcilable_ref )) SHOW_EXPR(( reconcilable_ref )) using TX = CommonResult_t; SHOW_TYPE(TX) SHOW_EXPR(( reconcilable )) SHOW_EXPR(( reconcilable )) SHOW_EXPR(( reconcilable )) using TX2 = CommonResult_t; SHOW_TYPE(TX2) SHOW_EXPR(( reconcilable )) SHOW_EXPR(( reconcilable )) SHOW_EXPR(( reconcilable )) SHOW_EXPR(( reconcilable )) SHOW_EXPR(( reconcilable_ref )) SHOW_EXPR(( reconcilable_ref )) SHOW_EXPR(( reconcilable )) SHOW_EXPR(( reconcilable )) using TX3 = CommonResult_t; SHOW_TYPE(TX3) using TX4 = CommonResult_t; SHOW_TYPE(TX4) SHOW_EXPR(( reconcilable )) using TX5 = CommonResult_t; SHOW_TYPE(TX5) using TX6 = CommonResult_t; SHOW_TYPE(TX6) SHOW_EXPR(( CommonResult::value )) SHOW_EXPR(( CommonResult::value )) SHOW_EXPR(( CommonResult::value )) SHOW_EXPR(( reconcilable )) SHOW_EXPR(( reconcilable )) SHOW_EXPR(( reconcilable )) cout << "\n.gulp." <