From 636ab6e60872092da8bdae84d10e098b6faadd1d Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 29 Sep 2017 00:51:13 +0200 Subject: [PATCH] Metaprogramming: integrate the new facilities into the library --- research/try.cpp | 77 +----------------- src/lib/meta/variadic-helper.hpp | 78 +++++++++++++++++++ .../meta/variadic-argument-picker-test.cpp | 5 +- 3 files changed, 83 insertions(+), 77 deletions(-) diff --git a/research/try.cpp b/research/try.cpp index 666f54078..8371cc4f0 100644 --- a/research/try.cpp +++ b/research/try.cpp @@ -93,81 +93,8 @@ fun2 () using lib::meta::IndexSeq; using lib::meta::BuildIndexSeq; using lib::meta::BuildIdxIter; - - -namespace { -/** - * @internal pick a single argument from a variadic parameter pack - * @tparam i the index number (zero based) of the argument to select - * @warning i must be smaller than the number of arguments available - */ -template -struct SelectVararg - { - template - static auto - get (ARG, ARGS&& ...args) - { - return SelectVararg::get (std::forward (args)...); - } - }; - -template<> -struct SelectVararg<0> - { - template - static auto - get (ARG&& a, ARGS...) - { - return std::forward(a); - } - }; -} - - -/** - * Helper to single out one argument from a variadic argument pack. - * @tparam idx the index number (zero based) of the argument to select - * @remark typically this function is used "driven" by an likewise variadic index sequence, - * where the index sequence itself is picked up by a pattern match; this usage pattern - * allows arbitrarily to handle some of the arguments of a variable argument list, - * as determined by the index sequence passed in. - */ -template -constexpr inline auto -pickArg (ARGS&&... args) - { - static_assert (idx < sizeof...(args), "insufficient number of arguments"); - - return SelectVararg::get (std::forward (args)...); - } - -/** - * Helper to pick one initialisation argument from a variadic argument pack, - * falling back to a default constructed element of type `DEFAULT` in case of - * insufficient number of variadic arguments. - * @tparam idx the index number (zero based) of the argument to select - * @tparam DEFALUT type of the default element to construct as fallback - */ -template -constexpr inline auto -pickInit (ARGS&&... args) - { - enum{ - SIZ = sizeof...(args), - IDX = idx < SIZ? idx : 0 - }; - - return (idx < SIZ)? SelectVararg::get (std::forward (args)...) - : DEFAULT{}; - } - -template -constexpr inline DEFAULT -pickInit () - { - return DEFAULT{}; - } +using lib::meta::pickArg; +using lib::meta::pickInit; using Arr = std::array; diff --git a/src/lib/meta/variadic-helper.hpp b/src/lib/meta/variadic-helper.hpp index ca77ba6ab..e9c45df10 100644 --- a/src/lib/meta/variadic-helper.hpp +++ b/src/lib/meta/variadic-helper.hpp @@ -245,5 +245,83 @@ namespace meta { + /* ==== Manipulation of variadic arguments ==== **/ + + namespace { // Implementation delegate template... + /** + * @internal pick a single argument from a variadic parameter pack + * @tparam i the index number (zero based) of the argument to select + * @warning i must be smaller than the number of arguments available + */ + template + struct SelectVararg + { + template + static auto + get (ARG, ARGS&& ...args) + { + return SelectVararg::get (std::forward (args)...); + } + }; + + template<> + struct SelectVararg<0> + { + template + static auto + get (ARG&& a, ARGS...) + { + return std::forward(a); + } + }; + }//(End)Implementation + + + /** + * Helper to single out one argument from a variadic argument pack. + * @tparam idx the index number (zero based) of the argument to select + * @remark typically this function is used "driven" by an likewise variadic index sequence, + * where the index sequence itself is picked up by a pattern match; this usage pattern + * allows arbitrarily to handle some of the arguments of a variable argument list, + * as determined by the index sequence passed in. + */ + template + constexpr inline auto + pickArg (ARGS&&... args) + { + static_assert (idx < sizeof...(args), "insufficient number of arguments"); + + return SelectVararg::get (std::forward (args)...); + } + + /** + * Helper to pick one initialisation argument from a variadic argument pack, + * falling back to a default constructed element of type `DEFAULT` in case of + * insufficient number of variadic arguments. + * @tparam idx the index number (zero based) of the argument to select + * @tparam DEFALUT type of the default element to construct as fallback + */ + template + constexpr inline auto + pickInit (ARGS&&... args) + { + enum{ + SIZ = sizeof...(args), + IDX = idx < SIZ? idx : 0 + }; + + return (idx < SIZ)? SelectVararg::get (std::forward (args)...) + : DEFAULT{}; + } + + template + constexpr inline DEFAULT + pickInit () + { + return DEFAULT{}; + } + + + }} // namespace lib::meta #endif /*LIB_META_VARIADIC_HELPER_H*/ diff --git a/tests/library/meta/variadic-argument-picker-test.cpp b/tests/library/meta/variadic-argument-picker-test.cpp index 4e7bc7294..f0039965f 100644 --- a/tests/library/meta/variadic-argument-picker-test.cpp +++ b/tests/library/meta/variadic-argument-picker-test.cpp @@ -182,8 +182,9 @@ namespace test { CHECK (n1 == pickArg<0> (n1,n2,n3)); CHECK (n2 == pickArg<1> (n1,n2,n3)); CHECK (n3 == pickArg<2> (n1,n2,n3)); - - pickArg<3> (n1,n2,n3); + + // does not compile... +// pickArg<3> (n1,n2,n3); }