From 89e08ad75635e56654cdc3c9889aa81709d91ff2 Mon Sep 17 00:00:00 2001 From: Luke Valenty Date: Sat, 30 Apr 2022 21:56:03 -0600 Subject: [PATCH 01/15] implement indexed_tuple with different get method --- include/cib/detail/conditional.hpp | 1 - include/cib/detail/config_item.hpp | 1 - include/cib/detail/extend.hpp | 3 +- include/cib/detail/indexed_tuple.hpp | 153 +++++++++++++++++++++++++++ include/cib/detail/meta.hpp | 27 +++++ include/cib/detail/nexus_details.hpp | 20 ++-- include/cib/detail/ordered_set.hpp | 14 +-- include/cib/nexus.hpp | 8 +- test/CMakeLists.txt | 1 + test/detail/indexed_tuple.cpp | 93 ++++++++++++++++ test/nexus.cpp | 8 +- 11 files changed, 299 insertions(+), 30 deletions(-) create mode 100644 include/cib/detail/indexed_tuple.hpp create mode 100644 test/detail/indexed_tuple.cpp diff --git a/include/cib/detail/conditional.hpp b/include/cib/detail/conditional.hpp index 4bd87347..7eb223f8 100644 --- a/include/cib/detail/conditional.hpp +++ b/include/cib/detail/conditional.hpp @@ -1,7 +1,6 @@ #include "compiler.hpp" #include "config_item.hpp" #include "config_details.hpp" -#include "ordered_set.hpp" #include "type_list.hpp" #include diff --git a/include/cib/detail/config_item.hpp b/include/cib/detail/config_item.hpp index 7ec96e73..3cc1cb8d 100644 --- a/include/cib/detail/config_item.hpp +++ b/include/cib/detail/config_item.hpp @@ -1,5 +1,4 @@ #include "compiler.hpp" -#include "ordered_set.hpp" #include "type_list.hpp" #include diff --git a/include/cib/detail/extend.hpp b/include/cib/detail/extend.hpp index 63e49163..735a37b3 100644 --- a/include/cib/detail/extend.hpp +++ b/include/cib/detail/extend.hpp @@ -1,4 +1,5 @@ #include "config_item.hpp" +#include "indexed_tuple.hpp" #include "ordered_set.hpp" #include @@ -76,7 +77,7 @@ namespace cib::detail { (is_same_v>::Service> + ... + 0) <= 1, "Extension matched more than 1 service"); - return detail::ordered_set(add(ExtensionPath{}, builders)...); + return detail::make_indexed_tuple(detail::index_metafunc_{}, add(ExtensionPath{}, builders)...); }, builders_tuple); } diff --git a/include/cib/detail/indexed_tuple.hpp b/include/cib/detail/indexed_tuple.hpp new file mode 100644 index 00000000..b2cb8815 --- /dev/null +++ b/include/cib/detail/indexed_tuple.hpp @@ -0,0 +1,153 @@ +#include +#include +#include + + +#ifndef COMPILE_TIME_INIT_BUILD_INDEXED_TUPLE_HPP +#define COMPILE_TIME_INIT_BUILD_INDEXED_TUPLE_HPP + + +namespace cib::detail { + template + struct tag_ {}; + + template + struct index_ {}; + + template + struct index_metafunc_ {}; + + template + struct indexed_tuple_element; + + template + struct indexed_tuple_element { + T value; + + [[nodiscard]] constexpr T const & get(index_) const { + return value; + } + }; + + template + struct indexed_tuple_element { + T value; + + [[nodiscard]] constexpr T const & get(index_) const { + return value; + } + + [[nodiscard]] constexpr T const & get(tag_) const { + return value; + } + }; + + template + struct indexed_tuple_element { + T value; + + [[nodiscard]] constexpr T const & get(index_) const { + return value; + } + + [[nodiscard]] constexpr T const & get(tag_) const { + return value; + } + + [[nodiscard]] constexpr T const & get(tag_) const { + return value; + } + }; + + template + struct indexed_tuple : public IndexedTupleElementTs... { + constexpr indexed_tuple(IndexedTupleElementTs... values) + : IndexedTupleElementTs{values}... + {} + + using IndexedTupleElementTs::get...; + +// template +// constexpr void get(T) const {} + + [[nodiscard]] constexpr int size() const { + return sizeof...(IndexedTupleElementTs); + } + }; + + template + [[nodiscard]] constexpr auto make_indexed_tuple(std::integer_sequence, Ts const & ... values) { + return indexed_tuple{indexed_tuple_element{values}...}; + } + + template + [[nodiscard]] constexpr auto make_indexed_tuple(std::integer_sequence, index_metafunc_, Ts const & ... values) { + return indexed_tuple{indexed_tuple_element>{values}...}; + } + + template + [[nodiscard]] constexpr auto make_indexed_tuple(Ts const & ... values) { + return make_indexed_tuple(std::make_integer_sequence{}, values...); + } + + template + [[nodiscard]] constexpr auto make_indexed_tuple(index_metafunc_, Ts const & ... values) { + return make_indexed_tuple(std::make_integer_sequence{}, index_metafunc_{}, values...); + } + + + template + constexpr auto apply(Callable operation, indexed_tuple const & t) { + return operation(t.Elements::value...); + } + + struct indexed_tuple_pair { + unsigned int outer; + unsigned int inner; + }; + + template< + int... Indices, + typename... Tuples> + constexpr auto indexed_tuple_cat_impl( + std::integer_sequence, + Tuples... tuples + ) { + constexpr auto num_tuples = sizeof...(tuples); + constexpr std::array tuple_sizes{tuples.size()...}; + constexpr auto element_indices = [&](){ + constexpr auto total_num_elements = (tuples.size() + ...); + std::array indices{}; + unsigned int flat_index = 0; + for (unsigned int outer_index = 0; outer_index < num_tuples; outer_index++) { + for (unsigned int inner_index = 0; inner_index < tuple_sizes[outer_index]; inner_index++) { + indices[flat_index] = {outer_index, inner_index}; + flat_index += 1; + } + } + return indices; + }(); + + auto const outer_tuple = make_indexed_tuple(tuples...); + + return make_indexed_tuple( + outer_tuple.get(index_{}).get(index_{})... + ); + } + + template + constexpr auto indexed_tuple_cat(Tuples... tuples) { + constexpr auto total_num_elements = (tuples.size() + ...); + return indexed_tuple_cat_impl(std::make_integer_sequence{}, tuples...); + } +} + +namespace std { + template + struct tuple_size> + : std::integral_constant + {}; +} + + +#endif //COMPILE_TIME_INIT_BUILD_INDEXED_TUPLE_HPP diff --git a/include/cib/detail/meta.hpp b/include/cib/detail/meta.hpp index 6a3b44d7..a711355e 100644 --- a/include/cib/detail/meta.hpp +++ b/include/cib/detail/meta.hpp @@ -1,5 +1,6 @@ #include "compiler.hpp" #include "ordered_set.hpp" +#include "indexed_tuple.hpp" #include #include @@ -116,6 +117,20 @@ namespace cib::detail { }, elements); } + template< + typename... ElementTypes, + typename InitType, + typename CallableType> + [[nodiscard]] CIB_CONSTEXPR inline static auto fold_right( + indexed_tuple const & elements, + InitType const & initial_state, + CallableType const & operation + ) { + return apply([&](auto const & ... element_pack){ + return (fold_helper{element_pack.value, operation} + ... + initial_state); + }, elements); + } + /** * Perform an operation on each element of an integral sequence. * @@ -187,6 +202,18 @@ namespace cib::detail { (operation(element_pack) , ...); }, elements); } + + template< + typename... ElementTypes, + typename CallableType> + CIB_CONSTEXPR inline void for_each( + indexed_tuple const & elements, + CallableType const & operation + ) { + apply([&](auto const & ... element_pack){ + (operation(element_pack) , ...); + }, elements); + } } diff --git a/include/cib/detail/nexus_details.hpp b/include/cib/detail/nexus_details.hpp index 5c95be8d..227bb93b 100644 --- a/include/cib/detail/nexus_details.hpp +++ b/include/cib/detail/nexus_details.hpp @@ -1,7 +1,7 @@ #include "compiler.hpp" #include "meta.hpp" #include "type_list.hpp" -#include "ordered_set.hpp" +#include "indexed_tuple.hpp" #include "exports.hpp" #include "find.hpp" @@ -11,13 +11,18 @@ namespace cib { + struct extract_service_tag { + template + using invoke = typename T::Service; + }; + template struct to_tuple; template struct to_tuple> { - using type = detail::ordered_set; - constexpr static inline auto value = type{ServiceBuilders{}...}; + using type = decltype(detail::make_indexed_tuple(detail::index_metafunc_{}, ServiceBuilders{}...)); + constexpr static inline type value = detail::make_indexed_tuple(detail::index_metafunc_{}, ServiceBuilders{}...); }; template @@ -32,15 +37,10 @@ namespace cib { template CIB_CONSTEXPR static auto & initialized_builders_v = initialized_builders::value; - struct ServiceTagMetaFunc { - template - using invoke = typename T::Service; - }; - - template + template struct initialized { CIB_CONSTEXPR static auto value = - initialized_builders_v.template get().builder; + initialized_builders_v.template get(cib::detail::tag_{}).builder; }; } diff --git a/include/cib/detail/ordered_set.hpp b/include/cib/detail/ordered_set.hpp index a68777bb..5a65e4e5 100644 --- a/include/cib/detail/ordered_set.hpp +++ b/include/cib/detail/ordered_set.hpp @@ -11,25 +11,25 @@ namespace cib::detail { template - struct tuple_element { + struct ordered_set_element { T value; }; template - struct ordered_set : public tuple_element... { + struct ordered_set : public ordered_set_element... { constexpr ordered_set(Tn... values) - : tuple_element{values}... + : ordered_set_element{values}... {} template constexpr auto const & get() const { using T = type_pack_element; - return tuple_element::value; + return ordered_set_element::value; } template constexpr T const & get() const { - return tuple_element::value; + return ordered_set_element::value; } constexpr static auto size() { @@ -37,7 +37,7 @@ namespace cib::detail { } CIB_CONSTEXPR bool operator==(ordered_set const & rhs) const { - return ((tuple_element::value == rhs.tuple_element::value) && ... && true); + return ((ordered_set_element::value == rhs.ordered_set_element::value) && ... && true); } template @@ -53,7 +53,7 @@ namespace cib::detail { template constexpr auto apply(Callable operation, ordered_set const & t) { - return operation(t.tuple_element::value...); + return operation(t.ordered_set_element::value...); } struct index_pair { diff --git a/include/cib/nexus.hpp b/include/cib/nexus.hpp index a2941250..c99ae85d 100644 --- a/include/cib/nexus.hpp +++ b/include/cib/nexus.hpp @@ -26,15 +26,11 @@ namespace cib { private: using this_t = nexus; - template - using service_name_to_raw_type_t = - typename std::remove_const_t(cib::initialized_builders_v))>>; - // Workaround unfortunate bug in clang where it can't deduce "auto" sometimes - #define CIB_BUILD_SERVICE initialized>::value.template build>>() + #define CIB_BUILD_SERVICE initialized::value.template build>() public: - template + template constexpr static decltype(CIB_BUILD_SERVICE) service = CIB_BUILD_SERVICE; #undef CIB_BUILD_SERVICE diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ff6f5bc7..724c2fbc 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -9,6 +9,7 @@ add_executable(tests callback.cpp nexus.cpp detail/ordered_set.cpp + detail/indexed_tuple.cpp readme_hello_world.cpp ) diff --git a/test/detail/indexed_tuple.cpp b/test/detail/indexed_tuple.cpp new file mode 100644 index 00000000..f8dde2c2 --- /dev/null +++ b/test/detail/indexed_tuple.cpp @@ -0,0 +1,93 @@ +#include + +#include + +using cib::detail::tag_; +using cib::detail::index_; +using cib::detail::indexed_tuple_element; +using cib::detail::indexed_tuple; +using cib::detail::make_indexed_tuple; + +template +using int_t = std::integral_constant; + +struct A {}; +struct B {}; +struct C {}; +struct D {}; + +template +struct map_entry { + using Key = KeyT; + using Value = ValueT; + + ValueT value; +}; + +TEST_CASE("make empty indexed_tuple", "[indexed_tuple]") { + auto const t = indexed_tuple<>{}; + REQUIRE(t.size() == 0); +} + +TEST_CASE("make small indexed_tuple", "[indexed_tuple]") { + auto const t = + indexed_tuple{ + indexed_tuple_element{5}, + indexed_tuple_element{10} + }; + + REQUIRE(t.size() == 2); + REQUIRE(t.get(index_<0>{}) == 5); + REQUIRE(t.get(index_<1>{}) == 10); + REQUIRE(t.get(tag_{}) == 5); + REQUIRE(t.get(tag_{}) == 10); +} + +struct extract_key { + template + using invoke = typename T::Key; +}; + +TEST_CASE("make_indexed_tuple with calculated index", "[indexed_tuple]") { + auto const t = + make_indexed_tuple( + cib::detail::index_metafunc_{}, + map_entry{42}, + map_entry{12}, + map_entry{55}, + map_entry{99} + ); + + REQUIRE(t.size() == 4); + + REQUIRE(t.get(index_<0>{}).value == 42); + REQUIRE(t.get(index_<1>{}).value == 12); + REQUIRE(t.get(index_<2>{}).value == 55); + REQUIRE(t.get(index_<3>{}).value == 99); + + REQUIRE(t.get(tag_{}).value == 42); + REQUIRE(t.get(tag_{}).value == 12); + REQUIRE(t.get(tag_{}).value == 55); + REQUIRE(t.get(tag_{}).value == 99); +} + +TEST_CASE("simple make_indexed_tuple", "[indexed_tuple]") { + auto const t = make_indexed_tuple(5, 10); + + REQUIRE(t.size() == 2); + REQUIRE(t.get(index_<0>{}) == 5); + REQUIRE(t.get(index_<1>{}) == 10); +} + +TEST_CASE("indexed_tuple_cat", "[indexed_tuple]") { + auto const t0 = make_indexed_tuple(5, 10); + auto const t1 = make_indexed_tuple(12, 30); + + auto const t = indexed_tuple_cat(t0, t1); + + REQUIRE(t.size() == 4); + REQUIRE(t.get(index_<0>{}) == 5); + REQUIRE(t.get(index_<1>{}) == 10); + REQUIRE(t.get(index_<2>{}) == 12); + REQUIRE(t.get(index_<3>{}) == 30); +} diff --git a/test/nexus.cpp b/test/nexus.cpp index ad317693..a98f70c0 100644 --- a/test/nexus.cpp +++ b/test/nexus.cpp @@ -8,10 +8,10 @@ struct EmptyConfig { constexpr static auto config = cib::config<>(); }; -TEST_CASE("an empty configuration should compile and initialize") { - cib::nexus nexus{}; - nexus.init(); -} +//TEST_CASE("an empty configuration should compile and initialize") { +// cib::nexus nexus{}; +// nexus.init(); +//} From f94077d6e9c7829798c8a43c7f9ed662c7bd32be Mon Sep 17 00:00:00 2001 From: Luke Valenty Date: Mon, 2 May 2022 22:53:19 -0600 Subject: [PATCH 02/15] workaround clang bug with base class pack --- include/cib/detail/indexed_tuple.hpp | 10 ++++++---- include/cib/detail/nexus_details.hpp | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/include/cib/detail/indexed_tuple.hpp b/include/cib/detail/indexed_tuple.hpp index b2cb8815..95d3dc69 100644 --- a/include/cib/detail/indexed_tuple.hpp +++ b/include/cib/detail/indexed_tuple.hpp @@ -67,12 +67,14 @@ namespace cib::detail { using IndexedTupleElementTs::get...; -// template -// constexpr void get(T) const {} - [[nodiscard]] constexpr int size() const { return sizeof...(IndexedTupleElementTs); } + + template + constexpr auto apply(Callable operation) const { + return operation(IndexedTupleElementTs::value...); + } }; template @@ -98,7 +100,7 @@ namespace cib::detail { template constexpr auto apply(Callable operation, indexed_tuple const & t) { - return operation(t.Elements::value...); + return t.apply(operation); } struct indexed_tuple_pair { diff --git a/include/cib/detail/nexus_details.hpp b/include/cib/detail/nexus_details.hpp index 227bb93b..d452607d 100644 --- a/include/cib/detail/nexus_details.hpp +++ b/include/cib/detail/nexus_details.hpp @@ -40,7 +40,7 @@ namespace cib { template struct initialized { CIB_CONSTEXPR static auto value = - initialized_builders_v.template get(cib::detail::tag_{}).builder; + initialized_builders_v.get(cib::detail::tag_{}).builder; }; } From 84fdf41a76acc1fa82b0f52bcd0b3c8ef4187778 Mon Sep 17 00:00:00 2001 From: Luke Valenty Date: Mon, 2 May 2022 22:58:50 -0600 Subject: [PATCH 03/15] fix indexed_tuple.cpp includes --- test/detail/indexed_tuple.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/detail/indexed_tuple.cpp b/test/detail/indexed_tuple.cpp index f8dde2c2..0bb56856 100644 --- a/test/detail/indexed_tuple.cpp +++ b/test/detail/indexed_tuple.cpp @@ -1,4 +1,4 @@ -#include +#include #include From e09deac582b9135400613edd11adaf03196a33a0 Mon Sep 17 00:00:00 2001 From: Luke Valenty Date: Mon, 2 May 2022 23:31:42 -0600 Subject: [PATCH 04/15] replace all usage of std::tuple with indexed_tuple --- include/cib/config.hpp | 1 - include/cib/detail/conditional.hpp | 10 ++++-- include/cib/detail/config_details.hpp | 6 ++-- include/cib/detail/config_item.hpp | 2 -- include/cib/detail/exports.hpp | 1 - include/cib/detail/extend.hpp | 1 - include/cib/detail/meta.hpp | 52 +-------------------------- test/CMakeLists.txt | 1 - test/detail/meta.cpp | 27 -------------- test/nexus.cpp | 4 +-- 10 files changed, 13 insertions(+), 92 deletions(-) delete mode 100644 test/detail/meta.cpp diff --git a/include/cib/config.hpp b/include/cib/config.hpp index 37325e41..415f45e3 100644 --- a/include/cib/config.hpp +++ b/include/cib/config.hpp @@ -10,7 +10,6 @@ #include "detail/extend.hpp" #include "detail/config_item.hpp" -#include #include diff --git a/include/cib/detail/conditional.hpp b/include/cib/detail/conditional.hpp index 7eb223f8..afd356ff 100644 --- a/include/cib/detail/conditional.hpp +++ b/include/cib/detail/conditional.hpp @@ -2,8 +2,7 @@ #include "config_item.hpp" #include "config_details.hpp" #include "type_list.hpp" - -#include +#include "indexed_tuple.hpp" #ifndef COMPILE_TIME_INIT_BUILD_CONDITIONAL_HPP @@ -62,6 +61,11 @@ namespace cib::detail { } }; + struct self_type { + template + using invoke = T; + }; + template struct arg { template @@ -71,7 +75,7 @@ namespace cib::detail { template CIB_CONSTEVAL auto operator()(Args... args) const { - return detail::fold_right(std::make_tuple(args...), detail::int_<0>, [=](auto elem, [[maybe_unused]] auto state){ + return detail::fold_right(make_indexed_tuple(index_metafunc_{}, args...), detail::int_<0>, [=](auto elem, [[maybe_unused]] auto state){ using ElemType = typename std::remove_cv_t>::value_type; if constexpr (std::is_same_v) { diff --git a/include/cib/detail/config_details.hpp b/include/cib/detail/config_details.hpp index 2ac7b0f3..b61d4b5d 100644 --- a/include/cib/detail/config_details.hpp +++ b/include/cib/detail/config_details.hpp @@ -2,9 +2,9 @@ #include "config_item.hpp" #include "meta.hpp" #include "ordered_set.hpp" +#include "indexed_tuple.hpp" #include "type_list.hpp" -#include #ifndef COMPILE_TIME_INIT_BUILD_DETAIL_CONFIG_HPP @@ -22,13 +22,13 @@ namespace cib::detail { template struct config : public detail::config_item { - std::tuple configs_tuple; + decltype(make_indexed_tuple(std::declval()...)) configs_tuple; CIB_CONSTEVAL explicit config( ConfigArgs, ConfigTs const & ... configs ) - : configs_tuple{configs...} + : configs_tuple{make_indexed_tuple(configs...)} { // pass } diff --git a/include/cib/detail/config_item.hpp b/include/cib/detail/config_item.hpp index 3cc1cb8d..abb6ecde 100644 --- a/include/cib/detail/config_item.hpp +++ b/include/cib/detail/config_item.hpp @@ -1,8 +1,6 @@ #include "compiler.hpp" #include "type_list.hpp" -#include - #ifndef COMPILE_TIME_INIT_BUILD_CONFIG_DETAIL_HPP #define COMPILE_TIME_INIT_BUILD_CONFIG_DETAIL_HPP diff --git a/include/cib/detail/exports.hpp b/include/cib/detail/exports.hpp index 6c187805..b85de475 100644 --- a/include/cib/detail/exports.hpp +++ b/include/cib/detail/exports.hpp @@ -3,7 +3,6 @@ #include "type_list.hpp" #include "builder_traits.hpp" -#include #include diff --git a/include/cib/detail/extend.hpp b/include/cib/detail/extend.hpp index 735a37b3..694d893b 100644 --- a/include/cib/detail/extend.hpp +++ b/include/cib/detail/extend.hpp @@ -2,7 +2,6 @@ #include "indexed_tuple.hpp" #include "ordered_set.hpp" -#include #include diff --git a/include/cib/detail/meta.hpp b/include/cib/detail/meta.hpp index a711355e..02ba001e 100644 --- a/include/cib/detail/meta.hpp +++ b/include/cib/detail/meta.hpp @@ -2,7 +2,6 @@ #include "ordered_set.hpp" #include "indexed_tuple.hpp" -#include #include @@ -55,37 +54,6 @@ namespace cib::detail { } }; - /** - * fold_right a ordered_set of elements. - * - * Fold operations are sometimes called accumulate or reduce in other - * languages or libraries. - * - * https://en.wikipedia.org/wiki/Fold_%28higher-order_function%29 - * - * @param operation - * A callable that takes the current element being processed - * and the current state, and returns the state to be used - * to process the next element. Called for each element in - * the ordered_set. - * - * @return - * The final state of all of the operations. - */ - template< - typename... ElementTypes, - typename InitType, - typename CallableType> - [[nodiscard]] CIB_CONSTEXPR inline static auto fold_right( - std::tuple const & elements, - InitType const & initial_state, - CallableType const & operation - ) { - return apply([&](auto const & ... element_pack){ - return (fold_helper{element_pack, operation} + ... + initial_state); - }, elements); - } - /** * fold_right a ordered_set of elements. * @@ -127,7 +95,7 @@ namespace cib::detail { CallableType const & operation ) { return apply([&](auto const & ... element_pack){ - return (fold_helper{element_pack.value, operation} + ... + initial_state); + return (fold_helper{element_pack, operation} + ... + initial_state); }, elements); } @@ -167,24 +135,6 @@ namespace cib::detail { for_each(seq, operation); } - /** - * Perform an operation on each element of a ordered_set. - * - * @param operation - * The operation to perform. Must be a callable that accepts a single parameter. - */ - template< - typename... ElementTypes, - typename CallableType> - CIB_CONSTEXPR inline void for_each( - std::tuple const & elements, - CallableType const & operation - ) { - apply([&](auto const & ... element_pack){ - (operation(element_pack) , ...); - }, elements); - } - /** * Perform an operation on each element of a ordered_set. * diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 724c2fbc..67d894cc 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -4,7 +4,6 @@ project(compile_time_init_build) add_executable(tests detail/type_list.cpp - detail/meta.cpp builder_meta.cpp callback.cpp nexus.cpp diff --git a/test/detail/meta.cpp b/test/detail/meta.cpp deleted file mode 100644 index e3b96b35..00000000 --- a/test/detail/meta.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include - -#include - -auto const sum = [](int elem, int state){ - return elem + state; -}; - -TEST_CASE("fold_right empty tuple", "[meta]") { - auto const t = std::make_tuple(); - - REQUIRE(cib::detail::fold_right(t, 9, sum) == 9); -} - -TEST_CASE("fold_right single element tuple", "[meta]") { - auto const t = std::make_tuple(42); - - REQUIRE(cib::detail::fold_right(t, 0, sum) == 42); - REQUIRE(cib::detail::fold_right(t, 10, sum) == 52); -} - -TEST_CASE("fold_right multi-element tuple", "[meta]") { - auto const t = std::make_tuple(1, 2, 3, 4, 5); - - REQUIRE(cib::detail::fold_right(t, 0, sum) == 15); - REQUIRE(cib::detail::fold_right(t, 5, sum) == 20); -} diff --git a/test/nexus.cpp b/test/nexus.cpp index a98f70c0..606b7001 100644 --- a/test/nexus.cpp +++ b/test/nexus.cpp @@ -136,12 +136,12 @@ TEST_CASE("test conditional expressions") { } SECTION("true evaluation with std::apply") { - constexpr bool true_result = std::apply(exp, std::make_tuple(int_<42>)); + constexpr bool true_result = apply(exp, cib::detail::make_indexed_tuple(int_<42>)); REQUIRE(true_result); } SECTION("false evaluation") { - constexpr bool false_result = std::apply(exp, std::make_tuple(int_<8>)); + constexpr bool false_result = apply(exp, cib::detail::make_indexed_tuple(int_<8>)); REQUIRE_FALSE(false_result); } } From 42d73b096616b97a5fcb415e72a94f1f256066df Mon Sep 17 00:00:00 2001 From: Luke Valenty Date: Mon, 2 May 2022 23:47:12 -0600 Subject: [PATCH 05/15] replace ordered_set with indexed_tuple --- include/cib/detail/components.hpp | 4 +- include/cib/detail/conditional.hpp | 7 +- include/cib/detail/config_details.hpp | 4 +- include/cib/detail/extend.hpp | 5 +- include/cib/detail/find.hpp | 137 -------------------------- include/cib/detail/indexed_tuple.hpp | 7 ++ include/cib/detail/meta.hpp | 33 +------ include/cib/detail/nexus_details.hpp | 1 - include/cib/detail/ordered_set.hpp | 105 -------------------- include/cib/detail/quicksort.hpp | 45 --------- include/cib/detail/type_list.hpp | 12 +-- test/CMakeLists.txt | 1 - test/detail/ordered_set.cpp | 89 ----------------- 13 files changed, 22 insertions(+), 428 deletions(-) delete mode 100644 include/cib/detail/find.hpp delete mode 100644 include/cib/detail/ordered_set.hpp delete mode 100644 include/cib/detail/quicksort.hpp delete mode 100644 test/detail/ordered_set.cpp diff --git a/include/cib/detail/components.hpp b/include/cib/detail/components.hpp index fce5fa5b..24400050 100644 --- a/include/cib/detail/components.hpp +++ b/include/cib/detail/components.hpp @@ -1,7 +1,7 @@ #include "compiler.hpp" #include "config_item.hpp" #include "meta.hpp" -#include "ordered_set.hpp" +#include "indexed_tuple.hpp" #include "type_list.hpp" #include @@ -19,7 +19,7 @@ namespace cib::detail { Builders const & builders_tuple, Args const & ... args ) const { - return detail::fold_right(ordered_set{Components{}...}, builders_tuple, [&](auto const & c, auto const & builders){ + return detail::fold_right(make_indexed_tuple(Components{}...), builders_tuple, [&](auto const & c, auto const & builders){ return c.config.init(builders, args...); }); } diff --git a/include/cib/detail/conditional.hpp b/include/cib/detail/conditional.hpp index afd356ff..3de52594 100644 --- a/include/cib/detail/conditional.hpp +++ b/include/cib/detail/conditional.hpp @@ -61,11 +61,6 @@ namespace cib::detail { } }; - struct self_type { - template - using invoke = T; - }; - template struct arg { template @@ -75,7 +70,7 @@ namespace cib::detail { template CIB_CONSTEVAL auto operator()(Args... args) const { - return detail::fold_right(make_indexed_tuple(index_metafunc_{}, args...), detail::int_<0>, [=](auto elem, [[maybe_unused]] auto state){ + return detail::fold_right(make_indexed_tuple(self_type_index, args...), detail::int_<0>, [=](auto elem, [[maybe_unused]] auto state){ using ElemType = typename std::remove_cv_t>::value_type; if constexpr (std::is_same_v) { diff --git a/include/cib/detail/config_details.hpp b/include/cib/detail/config_details.hpp index b61d4b5d..aafef4e3 100644 --- a/include/cib/detail/config_details.hpp +++ b/include/cib/detail/config_details.hpp @@ -1,12 +1,10 @@ #include "compiler.hpp" #include "config_item.hpp" #include "meta.hpp" -#include "ordered_set.hpp" #include "indexed_tuple.hpp" #include "type_list.hpp" - #ifndef COMPILE_TIME_INIT_BUILD_DETAIL_CONFIG_HPP #define COMPILE_TIME_INIT_BUILD_DETAIL_CONFIG_HPP @@ -17,7 +15,7 @@ namespace cib::detail { template struct args { - static CIB_CONSTEXPR auto value = ordered_set{as_constant_v...}; + static CIB_CONSTEXPR auto value = make_indexed_tuple(self_type_index, as_constant_v...); }; template diff --git a/include/cib/detail/extend.hpp b/include/cib/detail/extend.hpp index 694d893b..03ce23e6 100644 --- a/include/cib/detail/extend.hpp +++ b/include/cib/detail/extend.hpp @@ -1,6 +1,5 @@ #include "config_item.hpp" #include "indexed_tuple.hpp" -#include "ordered_set.hpp" #include @@ -14,12 +13,12 @@ namespace cib::detail { typename ExtensionPath, typename... Args> struct extend : public config_item { - ordered_set args_tuple; + decltype(make_indexed_tuple(std::declval()...)) args_tuple; CIB_CONSTEVAL explicit extend( Args const & ... args ) - : args_tuple{args...} + : args_tuple{make_indexed_tuple(args...)} { // pass } diff --git a/include/cib/detail/find.hpp b/include/cib/detail/find.hpp deleted file mode 100644 index 93fc9ff1..00000000 --- a/include/cib/detail/find.hpp +++ /dev/null @@ -1,137 +0,0 @@ -#include "ordered_set.hpp" -#include "quicksort.hpp" - -#include -#include - - -#ifndef COMPILE_TIME_INIT_BUILD_FIND_HPP -#define COMPILE_TIME_INIT_BUILD_FIND_HPP - - -namespace cib::detail { - struct typename_map_entry { - std::string_view name; - unsigned int index; - - CIB_CONSTEVAL bool operator<(typename_map_entry rhs) const { - return name < rhs.name; - } - - CIB_CONSTEVAL bool operator>(typename_map_entry rhs) const { - return name > rhs.name; - } - }; - - // clang-8 and below don't have constexpr find_first_of on std::string_view - CIB_CONSTEVAL std::string_view::size_type find_first_of(std::string_view str, char c) { - using size_type = std::string_view::size_type; - for (size_type i = 0; i < str.size(); i++) { - if (str[i] == c) { - return i; - } - } - - return 0; - } - - // clang-8 and below don't have constexpr find_last_of on std::string_view - CIB_CONSTEVAL std::string_view::size_type find_last_of(std::string_view str, char c) { - using size_type = std::string_view::size_type; - size_type match = str.size(); - for (size_type i = 0; i < str.size(); i++) { - if (str[i] == c) { - match = i; - } - } - - return match; - } - - template - CIB_CONSTEVAL static std::string_view name() { - constexpr std::string_view function_name = __PRETTY_FUNCTION__; - constexpr auto lhs = find_first_of(function_name, '<'); - constexpr auto rhs = find_last_of(function_name, '>'); - constexpr auto service_name = function_name.substr(lhs, rhs - lhs); - return service_name; - } - - - template - CIB_CONSTEXPR static auto create_type_names() { - unsigned int i = 0; - std::array names = { - typename_map_entry{name>(), i++}... - }; - - quicksort(names); - return names; - } - - template - constexpr static std::array type_names = - create_type_names(); - - template - CIB_CONSTEVAL static auto binary_search( - ElemType const * elems, - std::size_t num_elems, - ElemType const & search_key - ) { - // https://en.wikipedia.org/wiki/Binary_search_algorithm#Procedure - - std::size_t left = 0; - std::size_t right = num_elems - 1; - - while (left <= right) { - auto const middle = (left + right) / 2; - if (elems[middle] < search_key) { - left = middle + 1; - } else if (elems[middle] > search_key) { - right = middle - 1; - } else { - return elems[middle]; - } - } - - return ElemType{}; - } - - template - CIB_CONSTEVAL static auto binary_search( - ContainerType const & container, - ElemType const & search_key - ) { - return binary_search(container.begin(), std::size(container), search_key); - } - - template - constexpr auto const & find(ordered_set const & t) { - - #if defined(__GNUC__) - // g++-9 doesn't compile when we use type_names<...> directly, so we have - // to use the function again instead. - // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64989 - constexpr auto index = - binary_search( - create_type_names(), - typename_map_entry{name(), 0} - ).index; - #else - constexpr auto index = - binary_search( - type_names, - typename_map_entry{name(), 0} - ).index; - #endif - - return t.template get(); - } - - - -} - - -#endif //COMPILE_TIME_INIT_BUILD_FIND_HPP diff --git a/include/cib/detail/indexed_tuple.hpp b/include/cib/detail/indexed_tuple.hpp index 95d3dc69..76b55223 100644 --- a/include/cib/detail/indexed_tuple.hpp +++ b/include/cib/detail/indexed_tuple.hpp @@ -20,6 +20,13 @@ namespace cib::detail { template struct indexed_tuple_element; + struct self_type { + template + using invoke = T; + } ; + + constexpr static index_metafunc_ self_type_index{}; + template struct indexed_tuple_element { T value; diff --git a/include/cib/detail/meta.hpp b/include/cib/detail/meta.hpp index 02ba001e..06e30ed5 100644 --- a/include/cib/detail/meta.hpp +++ b/include/cib/detail/meta.hpp @@ -1,5 +1,4 @@ #include "compiler.hpp" -#include "ordered_set.hpp" #include "indexed_tuple.hpp" #include @@ -55,7 +54,7 @@ namespace cib::detail { }; /** - * fold_right a ordered_set of elements. + * fold_right a indexed_tuple of elements. * * Fold operations are sometimes called accumulate or reduce in other * languages or libraries. @@ -66,25 +65,11 @@ namespace cib::detail { * A callable that takes the current element being processed * and the current state, and returns the state to be used * to process the next element. Called for each element in - * the ordered_set. + * the indexed_tuple. * * @return * The final state of all of the operations. */ - template< - typename... ElementTypes, - typename InitType, - typename CallableType> - [[nodiscard]] CIB_CONSTEXPR inline static auto fold_right( - ordered_set const & elements, - InitType const & initial_state, - CallableType const & operation - ) { - return apply([&](auto const & ... element_pack){ - return (fold_helper{element_pack, operation} + ... + initial_state); - }, elements); - } - template< typename... ElementTypes, typename InitType, @@ -136,23 +121,11 @@ namespace cib::detail { } /** - * Perform an operation on each element of a ordered_set. + * Perform an operation on each element of a indexed_tuple. * * @param operation * The operation to perform. Must be a callable that accepts a single parameter. */ - template< - typename... ElementTypes, - typename CallableType> - CIB_CONSTEXPR inline void for_each( - ordered_set const & elements, - CallableType const & operation - ) { - apply([&](auto const & ... element_pack){ - (operation(element_pack) , ...); - }, elements); - } - template< typename... ElementTypes, typename CallableType> diff --git a/include/cib/detail/nexus_details.hpp b/include/cib/detail/nexus_details.hpp index d452607d..fce7c8fc 100644 --- a/include/cib/detail/nexus_details.hpp +++ b/include/cib/detail/nexus_details.hpp @@ -3,7 +3,6 @@ #include "type_list.hpp" #include "indexed_tuple.hpp" #include "exports.hpp" -#include "find.hpp" #ifndef COMPILE_TIME_INIT_BUILD_NEXUS_DETAILS_HPP diff --git a/include/cib/detail/ordered_set.hpp b/include/cib/detail/ordered_set.hpp deleted file mode 100644 index 5a65e4e5..00000000 --- a/include/cib/detail/ordered_set.hpp +++ /dev/null @@ -1,105 +0,0 @@ -#include "type_pack_element.hpp" - -#include -#include -#include - - -#ifndef COMPILE_TIME_INIT_BUILD_TUPLE_HPP -#define COMPILE_TIME_INIT_BUILD_TUPLE_HPP - - -namespace cib::detail { - template - struct ordered_set_element { - T value; - }; - - template - struct ordered_set : public ordered_set_element... { - constexpr ordered_set(Tn... values) - : ordered_set_element{values}... - {} - - template - constexpr auto const & get() const { - using T = type_pack_element; - return ordered_set_element::value; - } - - template - constexpr T const & get() const { - return ordered_set_element::value; - } - - constexpr static auto size() { - return sizeof...(Tn); - } - - CIB_CONSTEXPR bool operator==(ordered_set const & rhs) const { - return ((ordered_set_element::value == rhs.ordered_set_element::value) && ... && true); - } - - template - CIB_CONSTEXPR bool operator==(ordered_set) const { - return false; - } - - template - CIB_CONSTEXPR bool operator!=(ordered_set const & rhs) const { - return !(*this == rhs); - } - }; - - template - constexpr auto apply(Callable operation, ordered_set const & t) { - return operation(t.ordered_set_element::value...); - } - - struct index_pair { - unsigned int outer; - unsigned int inner; - }; - - template< - int... Indices, - typename... Tuples> - constexpr auto tuple_cat_impl( - std::integer_sequence, - Tuples... tuples - ) { - constexpr auto num_tuples = sizeof...(tuples); - constexpr std::array tuple_sizes{tuples.size()...}; - constexpr auto element_indices = [&](){ - constexpr auto total_num_elements = (tuples.size() + ...); - std::array indices{}; - unsigned int flat_index = 0; - for (unsigned int outer_index = 0; outer_index < num_tuples; outer_index++) { - for (unsigned int inner_index = 0; inner_index < tuple_sizes[outer_index]; inner_index++) { - indices[flat_index] = {outer_index, inner_index}; - flat_index += 1; - } - } - return indices; - }(); - - auto const outer_tuple = ordered_set{tuples...}; - return ordered_set{outer_tuple.template get().template get()...}; - } - - template - constexpr auto tuple_cat(Tuples... tuples) { - constexpr auto total_num_elements = (tuples.size() + ...); - return tuple_cat_impl(std::make_integer_sequence{}, tuples...); - } -} - -namespace std { - template - struct tuple_size> - : std::integral_constant - {}; -} - - -#endif //COMPILE_TIME_INIT_BUILD_TUPLE_HPP diff --git a/include/cib/detail/quicksort.hpp b/include/cib/detail/quicksort.hpp deleted file mode 100644 index 4ba528af..00000000 --- a/include/cib/detail/quicksort.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#include - - -#ifndef COMPILE_TIME_INIT_BUILD_QUICKSORT_HPP -#define COMPILE_TIME_INIT_BUILD_QUICKSORT_HPP - - -namespace cib::detail { - // https://en.wikipedia.org/wiki/Quicksort#Hoare_partition_scheme - - template - CIB_CONSTEVAL static std::size_t partition(T * elems, std::size_t lo, std::size_t hi) { - auto const pivot = elems[(hi + lo) / 2]; - - auto i = lo - 1; - auto j = hi + 1; - - while (true) { - do {i = i + 1;} while (elems[i] < pivot); - do {j = j - 1;} while (elems[j] > pivot); - if (i >= j) {return j;} - - auto const temp = elems[i]; - elems[i] = elems[j]; - elems[j] = temp; - } - } - - template - CIB_CONSTEVAL static void quicksort(T * elems, std::size_t lo, std::size_t hi) { - if (lo < hi) { - auto const p = partition(elems, lo, hi); - quicksort(elems, lo, p); - quicksort(elems, p + 1, hi); - } - } - - template - CIB_CONSTEVAL static void quicksort(T & collection) { - quicksort(std::begin(collection), 0, std::size(collection) - std::size_t{1}); - } -} - - -#endif //COMPILE_TIME_INIT_BUILD_QUICKSORT_HPP diff --git a/include/cib/detail/type_list.hpp b/include/cib/detail/type_list.hpp index bf93852b..1947cc0d 100644 --- a/include/cib/detail/type_list.hpp +++ b/include/cib/detail/type_list.hpp @@ -20,11 +20,11 @@ namespace cib::detail { return value; } }; -// -// struct index_pair { -// unsigned int outer; -// unsigned int inner; -// }; + + struct type_list_index_pair { + unsigned int outer; + unsigned int inner; + }; template< unsigned int... Indices, @@ -39,7 +39,7 @@ namespace cib::detail { // gcc thinks this is unused [[maybe_unused]] constexpr auto element_indices = [&](){ constexpr auto total_num_elements = (type_lists.size + ... + 0); - std::array indices{}; + std::array indices{}; unsigned int flat_index = 0; for (unsigned int outer_index = 0; outer_index < num_type_lists; outer_index++) { for (unsigned int inner_index = 0; inner_index < type_list_sizes[outer_index]; inner_index++) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 67d894cc..d1a00319 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,7 +7,6 @@ add_executable(tests builder_meta.cpp callback.cpp nexus.cpp - detail/ordered_set.cpp detail/indexed_tuple.cpp readme_hello_world.cpp ) diff --git a/test/detail/ordered_set.cpp b/test/detail/ordered_set.cpp deleted file mode 100644 index c8896d7a..00000000 --- a/test/detail/ordered_set.cpp +++ /dev/null @@ -1,89 +0,0 @@ -#include - -#include - -using cib::detail::int_; -using cib::detail::ordered_set; - -template -using int_t = std::integral_constant; - -TEST_CASE("make empty set", "[ordered_set]") { - auto const t = ordered_set<>(); - REQUIRE(t.size() == 0); -} - -TEST_CASE("make set with a single element", "[ordered_set]") { - auto const t = ordered_set(int{54}); - REQUIRE(t.size() == 1); - REQUIRE(t.get<0>() == 54); - REQUIRE(t.get() == 54); -} - -TEST_CASE("make set with a multiple elements", "[ordered_set]") { - auto const t = ordered_set(int{54}, long{12}, bool{false}, char{'3'}); - - REQUIRE(t.size() == 4); - - REQUIRE(t.get<0>() == 54); - REQUIRE(t.get<1>() == 12); - REQUIRE(t.get<2>() == false); - REQUIRE(t.get<3>() == '3'); - - REQUIRE(t.get() == 54); - REQUIRE(t.get() == 12); - REQUIRE(t.get() == false); - REQUIRE(t.get() == '3'); -} - -TEST_CASE("compare equality of empty sets", "[ordered_set]") { - auto const lhs = ordered_set<>(); - auto const rhs = ordered_set<>(); - - REQUIRE(lhs == rhs); - REQUIRE_FALSE(lhs != rhs); -} - -TEST_CASE("compare equality of sets with different types", "[ordered_set]") { - auto const lhs = ordered_set<>(); - auto const rhs = ordered_set(12); - - REQUIRE_FALSE(lhs == rhs); - REQUIRE(lhs != rhs); -} - -TEST_CASE("compare equality of sets with same types and values", "[ordered_set]") { - auto const lhs = ordered_set(12, true, 'c'); - auto const rhs = ordered_set(12, true, 'c'); - - REQUIRE(lhs == rhs); - REQUIRE_FALSE(lhs != rhs); -} - -TEST_CASE("compare equality of sets with same types and different values", "[ordered_set]") { - auto const lhs = ordered_set(3, true, 'c'); - auto const rhs = ordered_set(12, true, 'c'); - - REQUIRE_FALSE(lhs == rhs); - REQUIRE(lhs != rhs); -} - -TEST_CASE("concatenate two sets", "[ordered_set]") { - auto const t = - cib::detail::tuple_cat( - ordered_set(3), - ordered_set('c')); - - REQUIRE(t == ordered_set(3, 'c')); -} - -TEST_CASE("concatenate empty set with non-empty set", "[ordered_set]") { - auto const t = - cib::detail::tuple_cat( - ordered_set(3), - ordered_set<>()); - - REQUIRE(t == ordered_set(3)); -} - - From 577c1d5ae23d1b7e403fd28f9fd1de6d269d3863 Mon Sep 17 00:00:00 2001 From: Luke Valenty Date: Tue, 3 May 2022 10:11:16 -0600 Subject: [PATCH 06/15] cleanup tuple --- include/cib/detail/components.hpp | 4 +- include/cib/detail/conditional.hpp | 4 +- include/cib/detail/config_details.hpp | 8 +- include/cib/detail/extend.hpp | 8 +- include/cib/detail/meta.hpp | 12 +-- include/cib/detail/nexus_details.hpp | 8 +- .../detail/{indexed_tuple.hpp => tuple.hpp} | 67 +++++++------ test/CMakeLists.txt | 2 +- test/detail/indexed_tuple.cpp | 93 ------------------ test/detail/tuple.cpp | 94 +++++++++++++++++++ test/nexus.cpp | 4 +- 11 files changed, 157 insertions(+), 147 deletions(-) rename include/cib/detail/{indexed_tuple.hpp => tuple.hpp} (60%) delete mode 100644 test/detail/indexed_tuple.cpp create mode 100644 test/detail/tuple.cpp diff --git a/include/cib/detail/components.hpp b/include/cib/detail/components.hpp index 24400050..883527c8 100644 --- a/include/cib/detail/components.hpp +++ b/include/cib/detail/components.hpp @@ -1,7 +1,7 @@ #include "compiler.hpp" #include "config_item.hpp" #include "meta.hpp" -#include "indexed_tuple.hpp" +#include "tuple.hpp" #include "type_list.hpp" #include @@ -19,7 +19,7 @@ namespace cib::detail { Builders const & builders_tuple, Args const & ... args ) const { - return detail::fold_right(make_indexed_tuple(Components{}...), builders_tuple, [&](auto const & c, auto const & builders){ + return detail::fold_right(make_tuple(Components{}...), builders_tuple, [&](auto const & c, auto const & builders){ return c.config.init(builders, args...); }); } diff --git a/include/cib/detail/conditional.hpp b/include/cib/detail/conditional.hpp index 3de52594..7dce034b 100644 --- a/include/cib/detail/conditional.hpp +++ b/include/cib/detail/conditional.hpp @@ -2,7 +2,7 @@ #include "config_item.hpp" #include "config_details.hpp" #include "type_list.hpp" -#include "indexed_tuple.hpp" +#include "tuple.hpp" #ifndef COMPILE_TIME_INIT_BUILD_CONDITIONAL_HPP @@ -70,7 +70,7 @@ namespace cib::detail { template CIB_CONSTEVAL auto operator()(Args... args) const { - return detail::fold_right(make_indexed_tuple(self_type_index, args...), detail::int_<0>, [=](auto elem, [[maybe_unused]] auto state){ + return detail::fold_right(make_tuple(self_type_index, args...), detail::int_<0>, [=](auto elem, [[maybe_unused]] auto state){ using ElemType = typename std::remove_cv_t>::value_type; if constexpr (std::is_same_v) { diff --git a/include/cib/detail/config_details.hpp b/include/cib/detail/config_details.hpp index aafef4e3..1cbc4b3e 100644 --- a/include/cib/detail/config_details.hpp +++ b/include/cib/detail/config_details.hpp @@ -1,7 +1,7 @@ #include "compiler.hpp" #include "config_item.hpp" #include "meta.hpp" -#include "indexed_tuple.hpp" +#include "tuple.hpp" #include "type_list.hpp" @@ -15,18 +15,18 @@ namespace cib::detail { template struct args { - static CIB_CONSTEXPR auto value = make_indexed_tuple(self_type_index, as_constant_v...); + static CIB_CONSTEXPR auto value = make_tuple(self_type_index, as_constant_v...); }; template struct config : public detail::config_item { - decltype(make_indexed_tuple(std::declval()...)) configs_tuple; + decltype(make_tuple(std::declval()...)) configs_tuple; CIB_CONSTEVAL explicit config( ConfigArgs, ConfigTs const & ... configs ) - : configs_tuple{make_indexed_tuple(configs...)} + : configs_tuple{make_tuple(configs...)} { // pass } diff --git a/include/cib/detail/extend.hpp b/include/cib/detail/extend.hpp index 03ce23e6..595a3a90 100644 --- a/include/cib/detail/extend.hpp +++ b/include/cib/detail/extend.hpp @@ -1,5 +1,5 @@ #include "config_item.hpp" -#include "indexed_tuple.hpp" +#include "tuple.hpp" #include @@ -13,12 +13,12 @@ namespace cib::detail { typename ExtensionPath, typename... Args> struct extend : public config_item { - decltype(make_indexed_tuple(std::declval()...)) args_tuple; + decltype(make_tuple(std::declval()...)) args_tuple; CIB_CONSTEVAL explicit extend( Args const & ... args ) - : args_tuple{make_indexed_tuple(args...)} + : args_tuple{make_tuple(args...)} { // pass } @@ -75,7 +75,7 @@ namespace cib::detail { (is_same_v>::Service> + ... + 0) <= 1, "Extension matched more than 1 service"); - return detail::make_indexed_tuple(detail::index_metafunc_{}, add(ExtensionPath{}, builders)...); + return detail::make_tuple(detail::index_metafunc_, add(ExtensionPath{}, builders)...); }, builders_tuple); } diff --git a/include/cib/detail/meta.hpp b/include/cib/detail/meta.hpp index 06e30ed5..81ae1a4f 100644 --- a/include/cib/detail/meta.hpp +++ b/include/cib/detail/meta.hpp @@ -1,5 +1,5 @@ #include "compiler.hpp" -#include "indexed_tuple.hpp" +#include "tuple.hpp" #include @@ -54,7 +54,7 @@ namespace cib::detail { }; /** - * fold_right a indexed_tuple of elements. + * fold_right a tuple of elements. * * Fold operations are sometimes called accumulate or reduce in other * languages or libraries. @@ -65,7 +65,7 @@ namespace cib::detail { * A callable that takes the current element being processed * and the current state, and returns the state to be used * to process the next element. Called for each element in - * the indexed_tuple. + * the tuple. * * @return * The final state of all of the operations. @@ -75,7 +75,7 @@ namespace cib::detail { typename InitType, typename CallableType> [[nodiscard]] CIB_CONSTEXPR inline static auto fold_right( - indexed_tuple const & elements, + tuple const & elements, InitType const & initial_state, CallableType const & operation ) { @@ -121,7 +121,7 @@ namespace cib::detail { } /** - * Perform an operation on each element of a indexed_tuple. + * Perform an operation on each element of a tuple. * * @param operation * The operation to perform. Must be a callable that accepts a single parameter. @@ -130,7 +130,7 @@ namespace cib::detail { typename... ElementTypes, typename CallableType> CIB_CONSTEXPR inline void for_each( - indexed_tuple const & elements, + tuple const & elements, CallableType const & operation ) { apply([&](auto const & ... element_pack){ diff --git a/include/cib/detail/nexus_details.hpp b/include/cib/detail/nexus_details.hpp index fce7c8fc..17b48429 100644 --- a/include/cib/detail/nexus_details.hpp +++ b/include/cib/detail/nexus_details.hpp @@ -1,7 +1,7 @@ #include "compiler.hpp" #include "meta.hpp" #include "type_list.hpp" -#include "indexed_tuple.hpp" +#include "tuple.hpp" #include "exports.hpp" @@ -20,8 +20,8 @@ namespace cib { template struct to_tuple> { - using type = decltype(detail::make_indexed_tuple(detail::index_metafunc_{}, ServiceBuilders{}...)); - constexpr static inline type value = detail::make_indexed_tuple(detail::index_metafunc_{}, ServiceBuilders{}...); + using type = decltype(detail::make_tuple(detail::index_metafunc_, ServiceBuilders{}...)); + constexpr static inline type value = detail::make_tuple(detail::index_metafunc_, ServiceBuilders{}...); }; template @@ -39,7 +39,7 @@ namespace cib { template struct initialized { CIB_CONSTEXPR static auto value = - initialized_builders_v.get(cib::detail::tag_{}).builder; + initialized_builders_v.get(cib::detail::tag_).builder; }; } diff --git a/include/cib/detail/indexed_tuple.hpp b/include/cib/detail/tuple.hpp similarity index 60% rename from include/cib/detail/indexed_tuple.hpp rename to include/cib/detail/tuple.hpp index 76b55223..6a59ab88 100644 --- a/include/cib/detail/indexed_tuple.hpp +++ b/include/cib/detail/tuple.hpp @@ -9,66 +9,75 @@ namespace cib::detail { template - struct tag_ {}; + struct tag_t {}; + + template + constexpr static tag_t tag_{}; + + template + struct index_t {}; template - struct index_ {}; + constexpr static index_t index_{}; + + template + struct index_metafunc_t {}; template - struct index_metafunc_ {}; + constexpr static index_metafunc_t index_metafunc_{}; template - struct indexed_tuple_element; + struct tuple_element; struct self_type { template using invoke = T; } ; - constexpr static index_metafunc_ self_type_index{}; + constexpr static index_metafunc_t self_type_index{}; template - struct indexed_tuple_element { + struct tuple_element { T value; - [[nodiscard]] constexpr T const & get(index_) const { + [[nodiscard]] constexpr T const & get(index_t) const { return value; } }; template - struct indexed_tuple_element { + struct tuple_element { T value; - [[nodiscard]] constexpr T const & get(index_) const { + [[nodiscard]] constexpr T const & get(index_t) const { return value; } - [[nodiscard]] constexpr T const & get(tag_) const { + [[nodiscard]] constexpr T const & get(tag_t) const { return value; } }; template - struct indexed_tuple_element { + struct tuple_element { T value; - [[nodiscard]] constexpr T const & get(index_) const { + [[nodiscard]] constexpr T const & get(index_t) const { return value; } - [[nodiscard]] constexpr T const & get(tag_) const { + [[nodiscard]] constexpr T const & get(tag_t) const { return value; } - [[nodiscard]] constexpr T const & get(tag_) const { + [[nodiscard]] constexpr T const & get(tag_t) const { return value; } }; template - struct indexed_tuple : public IndexedTupleElementTs... { - constexpr indexed_tuple(IndexedTupleElementTs... values) + struct tuple : public IndexedTupleElementTs... { + constexpr tuple(IndexedTupleElementTs... values) : IndexedTupleElementTs{values}... {} @@ -85,28 +94,28 @@ namespace cib::detail { }; template - [[nodiscard]] constexpr auto make_indexed_tuple(std::integer_sequence, Ts const & ... values) { - return indexed_tuple{indexed_tuple_element{values}...}; + [[nodiscard]] constexpr auto make_tuple(std::integer_sequence, Ts const & ... values) { + return tuple{tuple_element{values}...}; } template - [[nodiscard]] constexpr auto make_indexed_tuple(std::integer_sequence, index_metafunc_, Ts const & ... values) { - return indexed_tuple{indexed_tuple_element>{values}...}; + [[nodiscard]] constexpr auto make_tuple(std::integer_sequence, index_metafunc_t, Ts const & ... values) { + return tuple{tuple_element>{values}...}; } template - [[nodiscard]] constexpr auto make_indexed_tuple(Ts const & ... values) { - return make_indexed_tuple(std::make_integer_sequence{}, values...); + [[nodiscard]] constexpr auto make_tuple(Ts const & ... values) { + return make_tuple(std::make_integer_sequence{}, values...); } template - [[nodiscard]] constexpr auto make_indexed_tuple(index_metafunc_, Ts const & ... values) { - return make_indexed_tuple(std::make_integer_sequence{}, index_metafunc_{}, values...); + [[nodiscard]] constexpr auto make_tuple(index_metafunc_t, Ts const & ... values) { + return make_tuple(std::make_integer_sequence{}, index_metafunc_, values...); } template - constexpr auto apply(Callable operation, indexed_tuple const & t) { + constexpr auto apply(Callable operation, tuple const & t) { return t.apply(operation); } @@ -137,10 +146,10 @@ namespace cib::detail { return indices; }(); - auto const outer_tuple = make_indexed_tuple(tuples...); + auto const outer_tuple = make_tuple(tuples...); - return make_indexed_tuple( - outer_tuple.get(index_{}).get(index_{})... + return make_tuple( + outer_tuple.get(index_).get(index_)... ); } @@ -153,7 +162,7 @@ namespace cib::detail { namespace std { template - struct tuple_size> + struct tuple_size> : std::integral_constant {}; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d1a00319..0290b367 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,7 +7,7 @@ add_executable(tests builder_meta.cpp callback.cpp nexus.cpp - detail/indexed_tuple.cpp + detail/tuple.cpp readme_hello_world.cpp ) diff --git a/test/detail/indexed_tuple.cpp b/test/detail/indexed_tuple.cpp deleted file mode 100644 index 0bb56856..00000000 --- a/test/detail/indexed_tuple.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include - -#include - -using cib::detail::tag_; -using cib::detail::index_; -using cib::detail::indexed_tuple_element; -using cib::detail::indexed_tuple; -using cib::detail::make_indexed_tuple; - -template -using int_t = std::integral_constant; - -struct A {}; -struct B {}; -struct C {}; -struct D {}; - -template -struct map_entry { - using Key = KeyT; - using Value = ValueT; - - ValueT value; -}; - -TEST_CASE("make empty indexed_tuple", "[indexed_tuple]") { - auto const t = indexed_tuple<>{}; - REQUIRE(t.size() == 0); -} - -TEST_CASE("make small indexed_tuple", "[indexed_tuple]") { - auto const t = - indexed_tuple{ - indexed_tuple_element{5}, - indexed_tuple_element{10} - }; - - REQUIRE(t.size() == 2); - REQUIRE(t.get(index_<0>{}) == 5); - REQUIRE(t.get(index_<1>{}) == 10); - REQUIRE(t.get(tag_{}) == 5); - REQUIRE(t.get(tag_{}) == 10); -} - -struct extract_key { - template - using invoke = typename T::Key; -}; - -TEST_CASE("make_indexed_tuple with calculated index", "[indexed_tuple]") { - auto const t = - make_indexed_tuple( - cib::detail::index_metafunc_{}, - map_entry{42}, - map_entry{12}, - map_entry{55}, - map_entry{99} - ); - - REQUIRE(t.size() == 4); - - REQUIRE(t.get(index_<0>{}).value == 42); - REQUIRE(t.get(index_<1>{}).value == 12); - REQUIRE(t.get(index_<2>{}).value == 55); - REQUIRE(t.get(index_<3>{}).value == 99); - - REQUIRE(t.get(tag_{}).value == 42); - REQUIRE(t.get(tag_{}).value == 12); - REQUIRE(t.get(tag_{}).value == 55); - REQUIRE(t.get(tag_{}).value == 99); -} - -TEST_CASE("simple make_indexed_tuple", "[indexed_tuple]") { - auto const t = make_indexed_tuple(5, 10); - - REQUIRE(t.size() == 2); - REQUIRE(t.get(index_<0>{}) == 5); - REQUIRE(t.get(index_<1>{}) == 10); -} - -TEST_CASE("indexed_tuple_cat", "[indexed_tuple]") { - auto const t0 = make_indexed_tuple(5, 10); - auto const t1 = make_indexed_tuple(12, 30); - - auto const t = indexed_tuple_cat(t0, t1); - - REQUIRE(t.size() == 4); - REQUIRE(t.get(index_<0>{}) == 5); - REQUIRE(t.get(index_<1>{}) == 10); - REQUIRE(t.get(index_<2>{}) == 12); - REQUIRE(t.get(index_<3>{}) == 30); -} diff --git a/test/detail/tuple.cpp b/test/detail/tuple.cpp new file mode 100644 index 00000000..3b745fc4 --- /dev/null +++ b/test/detail/tuple.cpp @@ -0,0 +1,94 @@ +#include + +#include + +using cib::detail::tag_; +using cib::detail::index_; +using cib::detail::index_metafunc_; +using cib::detail::tuple_element; +using cib::detail::tuple; +using cib::detail::make_tuple; + +template +using int_t = std::integral_constant; + +struct A {}; +struct B {}; +struct C {}; +struct D {}; + +template +struct map_entry { + using Key = KeyT; + using Value = ValueT; + + ValueT value; +}; + +TEST_CASE("make empty tuple", "[tuple]") { + auto const t = tuple<>{}; + REQUIRE(t.size() == 0); +} + +TEST_CASE("make small tuple", "[tuple]") { + auto const t = + tuple{ + tuple_element{5}, + tuple_element{10} + }; + + REQUIRE(t.size() == 2); + REQUIRE(t.get(index_<0>) == 5); + REQUIRE(t.get(index_<1>) == 10); + REQUIRE(t.get(tag_) == 5); + REQUIRE(t.get(tag_) == 10); +} + +struct extract_key { + template + using invoke = typename T::Key; +}; + +TEST_CASE("make_tuple with calculated index", "[tuple]") { + auto const t = + make_tuple( + index_metafunc_, + map_entry{42}, + map_entry{12}, + map_entry{55}, + map_entry{99} + ); + + REQUIRE(t.size() == 4); + + REQUIRE(t.get(index_<0>).value == 42); + REQUIRE(t.get(index_<1>).value == 12); + REQUIRE(t.get(index_<2>).value == 55); + REQUIRE(t.get(index_<3>).value == 99); + + REQUIRE(t.get(tag_).value == 42); + REQUIRE(t.get(tag_).value == 12); + REQUIRE(t.get(tag_).value == 55); + REQUIRE(t.get(tag_).value == 99); +} + +TEST_CASE("simple make_tuple", "[tuple]") { + auto const t = make_tuple(5, 10); + + REQUIRE(t.size() == 2); + REQUIRE(t.get(index_<0>) == 5); + REQUIRE(t.get(index_<1>) == 10); +} + +TEST_CASE("indexed_tuple_cat", "[tuple]") { + auto const t0 = make_tuple(5, 10); + auto const t1 = make_tuple(12, 30); + + auto const t = indexed_tuple_cat(t0, t1); + + REQUIRE(t.size() == 4); + REQUIRE(t.get(index_<0>) == 5); + REQUIRE(t.get(index_<1>) == 10); + REQUIRE(t.get(index_<2>) == 12); + REQUIRE(t.get(index_<3>) == 30); +} diff --git a/test/nexus.cpp b/test/nexus.cpp index 606b7001..1ceb64d7 100644 --- a/test/nexus.cpp +++ b/test/nexus.cpp @@ -136,12 +136,12 @@ TEST_CASE("test conditional expressions") { } SECTION("true evaluation with std::apply") { - constexpr bool true_result = apply(exp, cib::detail::make_indexed_tuple(int_<42>)); + constexpr bool true_result = apply(exp, cib::detail::make_tuple(int_<42>)); REQUIRE(true_result); } SECTION("false evaluation") { - constexpr bool false_result = apply(exp, cib::detail::make_indexed_tuple(int_<8>)); + constexpr bool false_result = apply(exp, cib::detail::make_tuple(int_<8>)); REQUIRE_FALSE(false_result); } } From 8f96b195c27a4be8380bc1acd4ab204efc0db27c Mon Sep 17 00:00:00 2001 From: Luke Valenty Date: Tue, 3 May 2022 10:29:28 -0600 Subject: [PATCH 07/15] make cib::detail::tuple cib::tuple --- include/cib/detail/components.hpp | 2 +- include/cib/detail/conditional.hpp | 2 +- include/cib/detail/config_details.hpp | 2 +- include/cib/detail/extend.hpp | 4 +-- include/cib/detail/meta.hpp | 12 ++++----- include/cib/detail/nexus_details.hpp | 8 +++--- include/cib/{detail => }/tuple.hpp | 38 +++++++++++++-------------- test/detail/tuple.cpp | 33 +++++++++++------------ test/nexus.cpp | 4 +-- 9 files changed, 51 insertions(+), 54 deletions(-) rename include/cib/{detail => }/tuple.hpp (81%) diff --git a/include/cib/detail/components.hpp b/include/cib/detail/components.hpp index 883527c8..78715da1 100644 --- a/include/cib/detail/components.hpp +++ b/include/cib/detail/components.hpp @@ -1,7 +1,7 @@ #include "compiler.hpp" #include "config_item.hpp" #include "meta.hpp" -#include "tuple.hpp" +#include "../tuple.hpp" #include "type_list.hpp" #include diff --git a/include/cib/detail/conditional.hpp b/include/cib/detail/conditional.hpp index 7dce034b..d20ebf39 100644 --- a/include/cib/detail/conditional.hpp +++ b/include/cib/detail/conditional.hpp @@ -2,7 +2,7 @@ #include "config_item.hpp" #include "config_details.hpp" #include "type_list.hpp" -#include "tuple.hpp" +#include "../tuple.hpp" #ifndef COMPILE_TIME_INIT_BUILD_CONDITIONAL_HPP diff --git a/include/cib/detail/config_details.hpp b/include/cib/detail/config_details.hpp index 1cbc4b3e..33215204 100644 --- a/include/cib/detail/config_details.hpp +++ b/include/cib/detail/config_details.hpp @@ -1,7 +1,7 @@ #include "compiler.hpp" #include "config_item.hpp" #include "meta.hpp" -#include "tuple.hpp" +#include "../tuple.hpp" #include "type_list.hpp" diff --git a/include/cib/detail/extend.hpp b/include/cib/detail/extend.hpp index 595a3a90..8c345d6e 100644 --- a/include/cib/detail/extend.hpp +++ b/include/cib/detail/extend.hpp @@ -1,5 +1,5 @@ #include "config_item.hpp" -#include "tuple.hpp" +#include "../tuple.hpp" #include @@ -75,7 +75,7 @@ namespace cib::detail { (is_same_v>::Service> + ... + 0) <= 1, "Extension matched more than 1 service"); - return detail::make_tuple(detail::index_metafunc_, add(ExtensionPath{}, builders)...); + return make_tuple(index_metafunc_, add(ExtensionPath{}, builders)...); }, builders_tuple); } diff --git a/include/cib/detail/meta.hpp b/include/cib/detail/meta.hpp index 81ae1a4f..2106c7d5 100644 --- a/include/cib/detail/meta.hpp +++ b/include/cib/detail/meta.hpp @@ -1,5 +1,5 @@ #include "compiler.hpp" -#include "tuple.hpp" +#include "../tuple.hpp" #include @@ -75,9 +75,9 @@ namespace cib::detail { typename InitType, typename CallableType> [[nodiscard]] CIB_CONSTEXPR inline static auto fold_right( - tuple const & elements, - InitType const & initial_state, - CallableType const & operation + tuple const & elements, + InitType const & initial_state, + CallableType const & operation ) { return apply([&](auto const & ... element_pack){ return (fold_helper{element_pack, operation} + ... + initial_state); @@ -130,8 +130,8 @@ namespace cib::detail { typename... ElementTypes, typename CallableType> CIB_CONSTEXPR inline void for_each( - tuple const & elements, - CallableType const & operation + tuple const & elements, + CallableType const & operation ) { apply([&](auto const & ... element_pack){ (operation(element_pack) , ...); diff --git a/include/cib/detail/nexus_details.hpp b/include/cib/detail/nexus_details.hpp index 17b48429..ceb57c6e 100644 --- a/include/cib/detail/nexus_details.hpp +++ b/include/cib/detail/nexus_details.hpp @@ -1,7 +1,7 @@ #include "compiler.hpp" #include "meta.hpp" #include "type_list.hpp" -#include "tuple.hpp" +#include "../tuple.hpp" #include "exports.hpp" @@ -20,8 +20,8 @@ namespace cib { template struct to_tuple> { - using type = decltype(detail::make_tuple(detail::index_metafunc_, ServiceBuilders{}...)); - constexpr static inline type value = detail::make_tuple(detail::index_metafunc_, ServiceBuilders{}...); + using type = decltype(make_tuple(index_metafunc_, ServiceBuilders{}...)); + constexpr static inline type value = make_tuple(index_metafunc_, ServiceBuilders{}...); }; template @@ -39,7 +39,7 @@ namespace cib { template struct initialized { CIB_CONSTEXPR static auto value = - initialized_builders_v.get(cib::detail::tag_).builder; + initialized_builders_v.get(cib::tag_).builder; }; } diff --git a/include/cib/detail/tuple.hpp b/include/cib/tuple.hpp similarity index 81% rename from include/cib/detail/tuple.hpp rename to include/cib/tuple.hpp index 6a59ab88..55345d04 100644 --- a/include/cib/detail/tuple.hpp +++ b/include/cib/tuple.hpp @@ -3,11 +3,11 @@ #include -#ifndef COMPILE_TIME_INIT_BUILD_INDEXED_TUPLE_HPP -#define COMPILE_TIME_INIT_BUILD_INDEXED_TUPLE_HPP +#ifndef COMPILE_TIME_INIT_BUILD_TUPLE_HPP +#define COMPILE_TIME_INIT_BUILD_TUPLE_HPP -namespace cib::detail { +namespace cib { template struct tag_t {}; @@ -75,21 +75,21 @@ namespace cib::detail { } }; - template - struct tuple : public IndexedTupleElementTs... { - constexpr tuple(IndexedTupleElementTs... values) - : IndexedTupleElementTs{values}... + template + struct tuple : public TupleElementTs... { + constexpr tuple(TupleElementTs... values) + : TupleElementTs{values}... {} - using IndexedTupleElementTs::get...; + using TupleElementTs::get...; [[nodiscard]] constexpr int size() const { - return sizeof...(IndexedTupleElementTs); + return sizeof...(TupleElementTs); } template constexpr auto apply(Callable operation) const { - return operation(IndexedTupleElementTs::value...); + return operation(TupleElementTs::value...); } }; @@ -119,7 +119,7 @@ namespace cib::detail { return t.apply(operation); } - struct indexed_tuple_pair { + struct tuple_pair { unsigned int outer; unsigned int inner; }; @@ -127,7 +127,7 @@ namespace cib::detail { template< int... Indices, typename... Tuples> - constexpr auto indexed_tuple_cat_impl( + constexpr auto tuple_cat_impl( std::integer_sequence, Tuples... tuples ) { @@ -135,7 +135,7 @@ namespace cib::detail { constexpr std::array tuple_sizes{tuples.size()...}; constexpr auto element_indices = [&](){ constexpr auto total_num_elements = (tuples.size() + ...); - std::array indices{}; + std::array indices{}; unsigned int flat_index = 0; for (unsigned int outer_index = 0; outer_index < num_tuples; outer_index++) { for (unsigned int inner_index = 0; inner_index < tuple_sizes[outer_index]; inner_index++) { @@ -154,18 +154,18 @@ namespace cib::detail { } template - constexpr auto indexed_tuple_cat(Tuples... tuples) { + constexpr auto tuple_cat(Tuples... tuples) { constexpr auto total_num_elements = (tuples.size() + ...); - return indexed_tuple_cat_impl(std::make_integer_sequence{}, tuples...); + return tuple_cat_impl(std::make_integer_sequence{}, tuples...); } } namespace std { - template - struct tuple_size> - : std::integral_constant + template + struct tuple_size> + : std::integral_constant {}; } -#endif //COMPILE_TIME_INIT_BUILD_INDEXED_TUPLE_HPP +#endif //COMPILE_TIME_INIT_BUILD_TUPLE_HPP diff --git a/test/detail/tuple.cpp b/test/detail/tuple.cpp index 3b745fc4..f39aa2b4 100644 --- a/test/detail/tuple.cpp +++ b/test/detail/tuple.cpp @@ -2,12 +2,9 @@ #include -using cib::detail::tag_; -using cib::detail::index_; -using cib::detail::index_metafunc_; -using cib::detail::tuple_element; -using cib::detail::tuple; -using cib::detail::make_tuple; +using cib::tag_; +using cib::index_; +using cib::index_metafunc_; template using int_t = std::integral_constant; @@ -25,16 +22,16 @@ struct map_entry { ValueT value; }; -TEST_CASE("make empty tuple", "[tuple]") { - auto const t = tuple<>{}; +TEST_CASE("make empty cib::tuple", "[tuple]") { + auto const t = cib::tuple<>{}; REQUIRE(t.size() == 0); } -TEST_CASE("make small tuple", "[tuple]") { +TEST_CASE("make small cib::tuple", "[tuple]") { auto const t = - tuple{ - tuple_element{5}, - tuple_element{10} + cib::tuple{ + cib::tuple_element{5}, + cib::tuple_element{10} }; REQUIRE(t.size() == 2); @@ -51,7 +48,7 @@ struct extract_key { TEST_CASE("make_tuple with calculated index", "[tuple]") { auto const t = - make_tuple( + cib::make_tuple( index_metafunc_, map_entry{42}, map_entry{12}, @@ -73,18 +70,18 @@ TEST_CASE("make_tuple with calculated index", "[tuple]") { } TEST_CASE("simple make_tuple", "[tuple]") { - auto const t = make_tuple(5, 10); + auto const t = cib::make_tuple(5, 10); REQUIRE(t.size() == 2); REQUIRE(t.get(index_<0>) == 5); REQUIRE(t.get(index_<1>) == 10); } -TEST_CASE("indexed_tuple_cat", "[tuple]") { - auto const t0 = make_tuple(5, 10); - auto const t1 = make_tuple(12, 30); +TEST_CASE("tuple_cat", "[tuple]") { + auto const t0 = cib::make_tuple(5, 10); + auto const t1 = cib::make_tuple(12, 30); - auto const t = indexed_tuple_cat(t0, t1); + auto const t = tuple_cat(t0, t1); REQUIRE(t.size() == 4); REQUIRE(t.get(index_<0>) == 5); diff --git a/test/nexus.cpp b/test/nexus.cpp index 1ceb64d7..e62e3396 100644 --- a/test/nexus.cpp +++ b/test/nexus.cpp @@ -136,12 +136,12 @@ TEST_CASE("test conditional expressions") { } SECTION("true evaluation with std::apply") { - constexpr bool true_result = apply(exp, cib::detail::make_tuple(int_<42>)); + constexpr bool true_result = apply(exp, cib::make_tuple(int_<42>)); REQUIRE(true_result); } SECTION("false evaluation") { - constexpr bool false_result = apply(exp, cib::detail::make_tuple(int_<8>)); + constexpr bool false_result = apply(exp, cib::make_tuple(int_<8>)); REQUIRE_FALSE(false_result); } } From a151cc268ce3536673cb64e913e1417cb408737a Mon Sep 17 00:00:00 2001 From: Luke Valenty Date: Tue, 3 May 2022 14:21:38 -0600 Subject: [PATCH 08/15] cleanup cib::tuple --- include/cib/detail/config_details.hpp | 2 +- include/cib/detail/extend.hpp | 2 +- include/cib/detail/meta.hpp | 4 +- include/cib/detail/nexus_details.hpp | 4 +- include/cib/detail/tuple_details.hpp | 13 +++ include/cib/tuple.hpp | 121 ++++++++++++++++++++--- test/detail/tuple.cpp | 137 +++++++++++++++++++++++--- test/readme_hello_world.cpp | 2 +- 8 files changed, 249 insertions(+), 36 deletions(-) create mode 100644 include/cib/detail/tuple_details.hpp diff --git a/include/cib/detail/config_details.hpp b/include/cib/detail/config_details.hpp index 33215204..35f41cd5 100644 --- a/include/cib/detail/config_details.hpp +++ b/include/cib/detail/config_details.hpp @@ -20,7 +20,7 @@ namespace cib::detail { template struct config : public detail::config_item { - decltype(make_tuple(std::declval()...)) configs_tuple; + tuple configs_tuple; CIB_CONSTEVAL explicit config( ConfigArgs, diff --git a/include/cib/detail/extend.hpp b/include/cib/detail/extend.hpp index 8c345d6e..02d9d3ba 100644 --- a/include/cib/detail/extend.hpp +++ b/include/cib/detail/extend.hpp @@ -13,7 +13,7 @@ namespace cib::detail { typename ExtensionPath, typename... Args> struct extend : public config_item { - decltype(make_tuple(std::declval()...)) args_tuple; + tuple args_tuple; CIB_CONSTEVAL explicit extend( Args const & ... args diff --git a/include/cib/detail/meta.hpp b/include/cib/detail/meta.hpp index 2106c7d5..0e1711a2 100644 --- a/include/cib/detail/meta.hpp +++ b/include/cib/detail/meta.hpp @@ -75,7 +75,7 @@ namespace cib::detail { typename InitType, typename CallableType> [[nodiscard]] CIB_CONSTEXPR inline static auto fold_right( - tuple const & elements, + tuple_impl const & elements, InitType const & initial_state, CallableType const & operation ) { @@ -130,7 +130,7 @@ namespace cib::detail { typename... ElementTypes, typename CallableType> CIB_CONSTEXPR inline void for_each( - tuple const & elements, + tuple_impl const & elements, CallableType const & operation ) { apply([&](auto const & ... element_pack){ diff --git a/include/cib/detail/nexus_details.hpp b/include/cib/detail/nexus_details.hpp index ceb57c6e..9fc3997d 100644 --- a/include/cib/detail/nexus_details.hpp +++ b/include/cib/detail/nexus_details.hpp @@ -20,8 +20,8 @@ namespace cib { template struct to_tuple> { - using type = decltype(make_tuple(index_metafunc_, ServiceBuilders{}...)); - constexpr static inline type value = make_tuple(index_metafunc_, ServiceBuilders{}...); + using type = tuple, ServiceBuilders...>; + constexpr static inline type value{}; }; template diff --git a/include/cib/detail/tuple_details.hpp b/include/cib/detail/tuple_details.hpp new file mode 100644 index 00000000..6787fb13 --- /dev/null +++ b/include/cib/detail/tuple_details.hpp @@ -0,0 +1,13 @@ + + + +#ifndef CIB_TUPLE_DETAILS_HPP +#define CIB_TUPLE_DETAILS_HPP + + +namespace cib::detail { + +} + + +#endif //CIB_TUPLE_DETAILS_HPP diff --git a/include/cib/tuple.hpp b/include/cib/tuple.hpp index 55345d04..2e7b2614 100644 --- a/include/cib/tuple.hpp +++ b/include/cib/tuple.hpp @@ -2,6 +2,8 @@ #include #include +#include "detail/tuple_details.hpp" + #ifndef COMPILE_TIME_INIT_BUILD_TUPLE_HPP #define COMPILE_TIME_INIT_BUILD_TUPLE_HPP @@ -26,8 +28,6 @@ namespace cib { template constexpr static index_metafunc_t index_metafunc_{}; - template - struct tuple_element; struct self_type { template @@ -36,6 +36,10 @@ namespace cib { constexpr static index_metafunc_t self_type_index{}; + + template + struct tuple_element; + template struct tuple_element { T value; @@ -75,15 +79,42 @@ namespace cib { } }; + template + struct tuple_element { + T value; + + [[nodiscard]] constexpr T const & get(index_t) const { + return value; + } + + [[nodiscard]] constexpr T const & get(tag_t) const { + return value; + } + + [[nodiscard]] constexpr T const & get(tag_t) const { + return value; + } + + [[nodiscard]] constexpr T const & get(tag_t) const { + return value; + } + }; + + template - struct tuple : public TupleElementTs... { - constexpr tuple(TupleElementTs... values) + struct tuple_impl : public TupleElementTs... { + constexpr tuple_impl(TupleElementTs... values) : TupleElementTs{values}... {} + template = 0), bool> = true> + constexpr tuple_impl() + : TupleElementTs{}... + {} + using TupleElementTs::get...; - [[nodiscard]] constexpr int size() const { + [[nodiscard]] constexpr static int size() { return sizeof...(TupleElementTs); } @@ -94,28 +125,92 @@ namespace cib { }; template - [[nodiscard]] constexpr auto make_tuple(std::integer_sequence, Ts const & ... values) { - return tuple{tuple_element{values}...}; + [[nodiscard]] constexpr auto make_tuple_impl(std::integer_sequence, Ts const & ... values) { + return tuple_impl{tuple_element{values}...}; } template - [[nodiscard]] constexpr auto make_tuple(std::integer_sequence, index_metafunc_t, Ts const & ... values) { - return tuple{tuple_element>{values}...}; + [[nodiscard]] constexpr auto make_tuple_impl(std::integer_sequence, index_metafunc_t, Ts const & ... values) { + return tuple_impl{tuple_element>{values}...}; + } + + template + [[nodiscard]] constexpr auto make_tuple_impl( + std::integer_sequence, + index_metafunc_t, + index_metafunc_t, + Ts const & ... values + ) { + return tuple_impl{ + tuple_element, + typename IndexMetafuncT1::template invoke + >{values}... + }; + } + + template + [[nodiscard]] constexpr auto make_tuple_impl( + std::integer_sequence, + index_metafunc_t, + index_metafunc_t, + index_metafunc_t, + Ts const & ... values + ) { + return tuple_impl{ + tuple_element, + typename IndexMetafuncT1::template invoke, + typename IndexMetafuncT2::template invoke + >{values}... + }; } template [[nodiscard]] constexpr auto make_tuple(Ts const & ... values) { - return make_tuple(std::make_integer_sequence{}, values...); + return make_tuple_impl(std::make_integer_sequence{}, values...); } template [[nodiscard]] constexpr auto make_tuple(index_metafunc_t, Ts const & ... values) { - return make_tuple(std::make_integer_sequence{}, index_metafunc_, values...); + return make_tuple_impl(std::make_integer_sequence{}, index_metafunc_, values...); + } + + template + [[nodiscard]] constexpr auto make_tuple( + index_metafunc_t, + index_metafunc_t, + Ts const & ... values + ) { + return make_tuple_impl( + std::make_integer_sequence{}, + index_metafunc_, + index_metafunc_, + values... + ); } + template + [[nodiscard]] constexpr auto make_tuple( + index_metafunc_t, + index_metafunc_t, + index_metafunc_t, + Ts const & ... values + ) { + return make_tuple_impl( + std::make_integer_sequence{}, + index_metafunc_, + index_metafunc_, + index_metafunc_, + values... + ); + } + + template + using tuple = decltype(make_tuple(std::declval()...)); template - constexpr auto apply(Callable operation, tuple const & t) { + constexpr auto apply(Callable operation, tuple_impl const & t) { return t.apply(operation); } @@ -162,7 +257,7 @@ namespace cib { namespace std { template - struct tuple_size> + struct tuple_size> : std::integral_constant {}; } diff --git a/test/detail/tuple.cpp b/test/detail/tuple.cpp index f39aa2b4..22c86793 100644 --- a/test/detail/tuple.cpp +++ b/test/detail/tuple.cpp @@ -23,29 +23,58 @@ struct map_entry { }; TEST_CASE("make empty cib::tuple", "[tuple]") { - auto const t = cib::tuple<>{}; + auto const t = cib::make_tuple(); REQUIRE(t.size() == 0); } -TEST_CASE("make small cib::tuple", "[tuple]") { - auto const t = - cib::tuple{ - cib::tuple_element{5}, - cib::tuple_element{10} - }; +TEST_CASE("single make_tuple", "[tuple]") { + auto const t = cib::make_tuple(42); + + REQUIRE(t.size() == 1); + REQUIRE(t.get(index_<0>) == 42); +} + +TEST_CASE("simple make_tuple", "[tuple]") { + auto const t = cib::make_tuple(5, 10); REQUIRE(t.size() == 2); REQUIRE(t.get(index_<0>) == 5); REQUIRE(t.get(index_<1>) == 10); - REQUIRE(t.get(tag_) == 5); - REQUIRE(t.get(tag_) == 10); } +TEST_CASE("self_type_index", "[tuple]") { + auto const t = cib::make_tuple( + cib::self_type_index, + 5, + false, + 10l + ); + + REQUIRE(t.size() == 3); + REQUIRE(t.get(index_<0>) == 5); + REQUIRE(t.get(index_<1>) == false); + REQUIRE(t.get(index_<2>) == 10); + + REQUIRE(t.get(tag_) == 5); + REQUIRE(t.get(tag_) == false); + REQUIRE(t.get(tag_) == 10); +} + + struct extract_key { template using invoke = typename T::Key; }; +TEST_CASE("make empty tuple with calculated index", "[tuple]") { + auto const t = + cib::make_tuple( + index_metafunc_ + ); + + REQUIRE(t.size() == 0); +} + TEST_CASE("make_tuple with calculated index", "[tuple]") { auto const t = cib::make_tuple( @@ -69,13 +98,6 @@ TEST_CASE("make_tuple with calculated index", "[tuple]") { REQUIRE(t.get(tag_).value == 99); } -TEST_CASE("simple make_tuple", "[tuple]") { - auto const t = cib::make_tuple(5, 10); - - REQUIRE(t.size() == 2); - REQUIRE(t.get(index_<0>) == 5); - REQUIRE(t.get(index_<1>) == 10); -} TEST_CASE("tuple_cat", "[tuple]") { auto const t0 = cib::make_tuple(5, 10); @@ -89,3 +111,86 @@ TEST_CASE("tuple_cat", "[tuple]") { REQUIRE(t.get(index_<2>) == 12); REQUIRE(t.get(index_<3>) == 30); } + +TEST_CASE("tuple_cat left empty", "[tuple]") { + auto const t0 = cib::make_tuple(); + auto const t1 = cib::make_tuple(12, 30); + + auto const t = tuple_cat(t0, t1); + + REQUIRE(t.size() == 2); + REQUIRE(t.get(index_<0>) == 12); + REQUIRE(t.get(index_<1>) == 30); +} + +TEST_CASE("tuple_cat right empty", "[tuple]") { + auto const t0 = cib::make_tuple(12, 30); + auto const t1 = cib::make_tuple(); + + auto const t = tuple_cat(t0, t1); + + REQUIRE(t.size() == 2); + REQUIRE(t.get(index_<0>) == 12); + REQUIRE(t.get(index_<1>) == 30); +} + +TEST_CASE("tuple_cat both empty", "[tuple]") { + auto const t0 = cib::make_tuple(); + auto const t1 = cib::make_tuple(); + + auto const t = tuple_cat(t0, t1); + + REQUIRE(t.size() == 0); +} + +TEST_CASE("tuple_cat three empty", "[tuple]") { + auto const t0 = cib::make_tuple(); + auto const t1 = cib::make_tuple(); + auto const t2 = cib::make_tuple(); + + auto const t = tuple_cat(t0, t1, t2); + + REQUIRE(t.size() == 0); +} + +TEST_CASE("tuple_cat middle empty", "[tuple]") { + auto const t0 = cib::make_tuple(1, 2); + auto const t1 = cib::make_tuple(); + auto const t2 = cib::make_tuple(3, 4); + + auto const t = tuple_cat(t0, t1, t2); + + REQUIRE(t.size() == 4); + REQUIRE(t.get(index_<0>) == 1); + REQUIRE(t.get(index_<1>) == 2); + REQUIRE(t.get(index_<2>) == 3); + REQUIRE(t.get(index_<3>) == 4); +} + +TEST_CASE("tuple_cat first empty", "[tuple]") { + auto const t0 = cib::make_tuple(); + auto const t1 = cib::make_tuple(1, 2); + auto const t2 = cib::make_tuple(3, 4); + + auto const t = tuple_cat(t0, t1, t2); + + REQUIRE(t.size() == 4); + REQUIRE(t.get(index_<0>) == 1); + REQUIRE(t.get(index_<1>) == 2); + REQUIRE(t.get(index_<2>) == 3); + REQUIRE(t.get(index_<3>) == 4); +} + +TEST_CASE("tuple_cat last empty", "[tuple]") { + auto const t0 = cib::make_tuple(1, 2); + auto const t1 = cib::make_tuple(3, 4); + auto const t2 = cib::make_tuple(); + + auto const t = tuple_cat(t0, t1, t2); + + REQUIRE(t.size() == 4); + REQUIRE(t.get(index_<0>) == 1); + REQUIRE(t.get(index_<1>) == 2); + REQUIRE(t.get(index_<2>) == 3); + REQUIRE(t.get(index_<3>) == 4); +} diff --git a/test/readme_hello_world.cpp b/test/readme_hello_world.cpp index f177e812..46286db8 100644 --- a/test/readme_hello_world.cpp +++ b/test/readme_hello_world.cpp @@ -26,7 +26,7 @@ struct hello_world { }; // the nexus instantiates the project -cib::nexus nexus{}; +static cib::nexus nexus{}; TEST_CASE("make sure the simple hello world example compiles") { From 39e8baea26bb4758c035842ab9edeba5f77304cd Mon Sep 17 00:00:00 2001 From: Luke Valenty Date: Tue, 3 May 2022 14:34:27 -0600 Subject: [PATCH 09/15] multi index testcase for tuple --- test/detail/tuple.cpp | 84 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 6 deletions(-) diff --git a/test/detail/tuple.cpp b/test/detail/tuple.cpp index 22c86793..37353a75 100644 --- a/test/detail/tuple.cpp +++ b/test/detail/tuple.cpp @@ -13,14 +13,17 @@ struct A {}; struct B {}; struct C {}; struct D {}; +struct E {}; +struct F {}; +struct G {}; +struct H {}; +struct I {}; +struct J {}; +struct K {}; +struct L {}; + -template -struct map_entry { - using Key = KeyT; - using Value = ValueT; - ValueT value; -}; TEST_CASE("make empty cib::tuple", "[tuple]") { auto const t = cib::make_tuple(); @@ -61,6 +64,14 @@ TEST_CASE("self_type_index", "[tuple]") { } +template +struct map_entry { + using Key = KeyT; + using Value = ValueT; + + ValueT value; +}; + struct extract_key { template using invoke = typename T::Key; @@ -194,3 +205,64 @@ TEST_CASE("tuple_cat last empty", "[tuple]") { REQUIRE(t.get(index_<2>) == 3); REQUIRE(t.get(index_<3>) == 4); } + +template +struct multi_map_entry { + using Key0 = KeyT0; + using Key1 = KeyT1; + using Key2 = KeyT2; + using Value = ValueT; + + ValueT value; +}; + +struct extract_key_0 { + template + using invoke = typename T::Key0; +}; + +struct extract_key_1 { + template + using invoke = typename T::Key1; +}; + +struct extract_key_2 { + template + using invoke = typename T::Key2; +}; + +TEST_CASE("make_tuple with multiple calculated index", "[tuple]") { + auto const t = + cib::make_tuple( + index_metafunc_, + index_metafunc_, + index_metafunc_, + multi_map_entry{42}, + multi_map_entry{12}, + multi_map_entry{55}, + multi_map_entry{99} + ); + + REQUIRE(t.size() == 4); + + REQUIRE(t.get(index_<0>).value == 42); + REQUIRE(t.get(index_<1>).value == 12); + REQUIRE(t.get(index_<2>).value == 55); + REQUIRE(t.get(index_<3>).value == 99); + + REQUIRE(t.get(tag_).value == 42); + REQUIRE(t.get(tag_).value == 42); + REQUIRE(t.get(tag_).value == 42); + + REQUIRE(t.get(tag_).value == 12); + REQUIRE(t.get(tag_).value == 12); + REQUIRE(t.get(tag_).value == 12); + + REQUIRE(t.get(tag_).value == 55); + REQUIRE(t.get(tag_).value == 55); + REQUIRE(t.get(tag_).value == 55); + + REQUIRE(t.get(tag_).value == 99); + REQUIRE(t.get(tag_).value == 99); + REQUIRE(t.get(tag_).value == 99); +} From 725620074fb87a12919ab13d6043e9706923eb7c Mon Sep 17 00:00:00 2001 From: Luke Valenty Date: Tue, 3 May 2022 15:44:05 -0600 Subject: [PATCH 10/15] remove unused tuple_details.hpp --- include/cib/detail/tuple_details.hpp | 13 ------------- include/cib/tuple.hpp | 2 -- 2 files changed, 15 deletions(-) delete mode 100644 include/cib/detail/tuple_details.hpp diff --git a/include/cib/detail/tuple_details.hpp b/include/cib/detail/tuple_details.hpp deleted file mode 100644 index 6787fb13..00000000 --- a/include/cib/detail/tuple_details.hpp +++ /dev/null @@ -1,13 +0,0 @@ - - - -#ifndef CIB_TUPLE_DETAILS_HPP -#define CIB_TUPLE_DETAILS_HPP - - -namespace cib::detail { - -} - - -#endif //CIB_TUPLE_DETAILS_HPP diff --git a/include/cib/tuple.hpp b/include/cib/tuple.hpp index 2e7b2614..4ec58ea2 100644 --- a/include/cib/tuple.hpp +++ b/include/cib/tuple.hpp @@ -2,8 +2,6 @@ #include #include -#include "detail/tuple_details.hpp" - #ifndef COMPILE_TIME_INIT_BUILD_TUPLE_HPP #define COMPILE_TIME_INIT_BUILD_TUPLE_HPP From 5bf4ee1cbbc69da7068bdedc39fad8090d17bdc0 Mon Sep 17 00:00:00 2001 From: Luke Valenty Date: Thu, 5 May 2022 20:18:11 -0600 Subject: [PATCH 11/15] add support for cib::tuple set operations --- include/cib/cib.hpp | 2 + include/cib/detail/conditional.hpp | 2 +- include/cib/detail/config_details.hpp | 4 +- include/cib/set.hpp | 303 ++++++++++++++++++++++++++ include/cib/tuple.hpp | 6 +- test/CMakeLists.txt | 3 +- test/nexus.cpp | 6 +- test/set.cpp | 75 +++++++ test/{detail => }/tuple.cpp | 0 9 files changed, 393 insertions(+), 8 deletions(-) create mode 100644 include/cib/set.hpp create mode 100644 test/set.cpp rename test/{detail => }/tuple.cpp (100%) diff --git a/include/cib/cib.hpp b/include/cib/cib.hpp index accee6e5..3b1c00c3 100644 --- a/include/cib/cib.hpp +++ b/include/cib/cib.hpp @@ -43,6 +43,8 @@ #include "built.hpp" #include "config.hpp" #include "builder_meta.hpp" +#include "set.hpp" +#include "tuple.hpp" #endif //COMPILE_TIME_INIT_BUILD_CIB_HPP diff --git a/include/cib/detail/conditional.hpp b/include/cib/detail/conditional.hpp index d20ebf39..2360b6e4 100644 --- a/include/cib/detail/conditional.hpp +++ b/include/cib/detail/conditional.hpp @@ -70,7 +70,7 @@ namespace cib::detail { template CIB_CONSTEVAL auto operator()(Args... args) const { - return detail::fold_right(make_tuple(self_type_index, args...), detail::int_<0>, [=](auto elem, [[maybe_unused]] auto state){ + return detail::fold_right(cib::make_tuple(self_type_index, args...), detail::int_<0>, [=](auto elem, [[maybe_unused]] auto state){ using ElemType = typename std::remove_cv_t>::value_type; if constexpr (std::is_same_v) { diff --git a/include/cib/detail/config_details.hpp b/include/cib/detail/config_details.hpp index 35f41cd5..24190864 100644 --- a/include/cib/detail/config_details.hpp +++ b/include/cib/detail/config_details.hpp @@ -20,13 +20,13 @@ namespace cib::detail { template struct config : public detail::config_item { - tuple configs_tuple; + cib::tuple configs_tuple; CIB_CONSTEVAL explicit config( ConfigArgs, ConfigTs const & ... configs ) - : configs_tuple{make_tuple(configs...)} + : configs_tuple{cib::make_tuple(configs...)} { // pass } diff --git a/include/cib/set.hpp b/include/cib/set.hpp new file mode 100644 index 00000000..fc3cd7b2 --- /dev/null +++ b/include/cib/set.hpp @@ -0,0 +1,303 @@ +#include "tuple.hpp" + + +#ifndef CIB_SET_HPP +#define CIB_SET_HPP + + +#include +#include + +#include + +namespace cib::detail { + // https://en.wikipedia.org/wiki/Quicksort#Hoare_partition_scheme + + template + CIB_CONSTEVAL static std::size_t partition(T * elems, std::size_t lo, std::size_t hi) { + auto const pivot = elems[(hi + lo) / 2]; + + auto i = lo - 1; + auto j = hi + 1; + + while (true) { + do {i = i + 1;} while (elems[i] < pivot); + do {j = j - 1;} while (elems[j] > pivot); + if (i >= j) {return j;} + + auto const temp = elems[i]; + elems[i] = elems[j]; + elems[j] = temp; + } + } + + template + CIB_CONSTEVAL static void quicksort(T * elems, std::size_t lo, std::size_t hi) { + if (lo < hi) { + auto const p = partition(elems, lo, hi); + quicksort(elems, lo, p); + quicksort(elems, p + 1, hi); + } + } + + template + CIB_CONSTEVAL static void quicksort(T & collection) { + quicksort(std::begin(collection), 0, std::size(collection) - std::size_t{1}); + } +} + +namespace cib::detail { + struct typename_map_entry { + std::string_view name; + unsigned int index; + unsigned int src; + + constexpr auto operator<(typename_map_entry rhs) const { + return name < rhs.name; + } + + constexpr auto operator<=(typename_map_entry rhs) const { + return name <= rhs.name; + } + + constexpr auto operator>(typename_map_entry rhs) const { + return name > rhs.name; + } + + constexpr auto operator>=(typename_map_entry rhs) const { + return name >= rhs.name; + } + + constexpr auto operator==(typename_map_entry rhs) const { + return name == rhs.name; + } + + constexpr auto operator!=(typename_map_entry rhs) const { + return name != rhs.name; + } + }; + + template + constexpr static std::string_view name() { + #if defined(__clang__) + constexpr std::string_view function_name = __PRETTY_FUNCTION__; + constexpr auto lhs = 44; + constexpr auto rhs = function_name.size() - 2; + + #elif defined(__GNUC__) || defined(__GNUG__) + constexpr std::string_view function_name = __PRETTY_FUNCTION__; + constexpr auto lhs = 59; + constexpr auto rhs = function_name.size() - 51; + + #elif #elif defined(_MSC_VER) + constexpr std::string_view function_name = __FUNCSIG__; + constexpr auto lhs = 0; + constexpr auto rhs = function_name.size(); + #else + static_assert(false, "Unknown compiler, can't build cib::tuple name."); + #endif + + return function_name.substr(lhs, rhs - lhs + 1); + } + + template + constexpr static auto create_type_names(unsigned int src) { + if constexpr (sizeof...(Types) == 0) { + return std::array{}; + + } else { + unsigned int i = 0; + std::array names = { + typename_map_entry{name>(), i++, src}... + }; + + detail::quicksort(names); + + return names; + } + } + + template + constexpr static std::array type_names = + create_type_names(src); + +} + + +namespace cib { + template + struct data_and_size { + DataT data; + SizeT size; + + constexpr data_and_size(DataT data_arg, SizeT size_arg) + : data{data_arg} + , size{size_arg} + {} + }; + + + + template + struct set_operation_impl_t; + + + template< + typename Algorithm, + typename MetaFunc, + typename... LhsElems, + typename... RhsElems> + struct set_operation_impl_t, tuple_impl> { + constexpr static auto lhs_tags = detail::type_names; + constexpr static auto rhs_tags = detail::type_names; + + constexpr static auto result = [](){ + constexpr auto max_size = + lhs_tags.size() + rhs_tags.size(); + + std::array out{}; + + auto const out_end = + Algorithm::invoke( + lhs_tags.begin(), lhs_tags.end(), + rhs_tags.begin(), rhs_tags.end(), + out.begin()); + + auto const out_size = + std::distance(out.begin(), out_end); + + return data_and_size{out, out_size}; + }(); + }; + + template< + int... Indices, + typename IndexList, + typename LhsTuple, + typename RhsTuple> + [[nodiscard]] constexpr auto merge_tuple_impl( + std::integer_sequence, + IndexList, + LhsTuple lhs, + RhsTuple rhs + ) { + constexpr auto index_list = + IndexList::result.data; + + auto const tuples = + cib::make_tuple(lhs, rhs); + + return make_tuple(tuples.get(index_).get(index_)...); + } + + template< + typename Algorithm, + typename MetaFunc, + typename LhsTuple, + typename RhsTuple> + [[nodiscard]] constexpr auto set_operation_impl( + Algorithm, + MetaFunc, + LhsTuple lhs, + RhsTuple rhs + ) { + using index_list_t = + set_operation_impl_t; + + constexpr auto result = + index_list_t::result; + + return merge_tuple_impl( + std::make_integer_sequence{}, + index_list_t{}, + lhs, + rhs + ); + } + + struct set_union_algorithm { + template + constexpr static auto invoke( + ArgTs... args + ) { + return std::set_union(args...); + } + }; + + template< + typename LhsTuple, + typename RhsTuple, + typename MetaFunc = self_type> + [[nodiscard]] constexpr auto set_union( + LhsTuple lhs, + RhsTuple rhs, + MetaFunc meta_func = self_type{} + ) { + return set_operation_impl(set_union_algorithm{}, meta_func, lhs, rhs); + } + + struct set_intersection_algorithm { + template + constexpr static auto invoke( + ArgTs... args + ) { + return std::set_intersection(args...); + } + }; + + template< + typename LhsTuple, + typename RhsTuple, + typename MetaFunc = self_type> + [[nodiscard]] constexpr auto set_intersection( + LhsTuple lhs, + RhsTuple rhs, + MetaFunc meta_func = self_type{} + ) { + return set_operation_impl(set_intersection_algorithm{}, meta_func, lhs, rhs); + } + + struct set_difference_algorithm { + template + constexpr static auto invoke( + ArgTs... args + ) { + return std::set_difference(args...); + } + }; + + template< + typename LhsTuple, + typename RhsTuple, + typename MetaFunc = self_type> + [[nodiscard]] constexpr auto set_difference( + LhsTuple lhs, + RhsTuple rhs, + MetaFunc meta_func = self_type{} + ) { + return set_operation_impl(set_difference_algorithm{}, meta_func, lhs, rhs); + } + + struct set_symmetric_difference_algorithm { + template + constexpr static auto invoke( + ArgTs... args + ) { + return std::set_symmetric_difference(args...); + } + }; + + template< + typename LhsTuple, + typename RhsTuple, + typename MetaFunc = self_type> + [[nodiscard]] constexpr auto set_symmetric_difference( + LhsTuple lhs, + RhsTuple rhs, + MetaFunc meta_func = self_type{} + ) { + return set_operation_impl(set_symmetric_difference_algorithm{}, meta_func, lhs, rhs); + } +} + +#endif //CIB_SET_HPP diff --git a/include/cib/tuple.hpp b/include/cib/tuple.hpp index 4ec58ea2..0ab836f3 100644 --- a/include/cib/tuple.hpp +++ b/include/cib/tuple.hpp @@ -40,6 +40,7 @@ namespace cib { template struct tuple_element { + using value_type = T; T value; [[nodiscard]] constexpr T const & get(index_t) const { @@ -49,6 +50,7 @@ namespace cib { template struct tuple_element { + using value_type = T; T value; [[nodiscard]] constexpr T const & get(index_t) const { @@ -62,6 +64,7 @@ namespace cib { template struct tuple_element { + using value_type = T; T value; [[nodiscard]] constexpr T const & get(index_t) const { @@ -79,6 +82,7 @@ namespace cib { template struct tuple_element { + using value_type = T; T value; [[nodiscard]] constexpr T const & get(index_t) const { @@ -205,7 +209,7 @@ namespace cib { } template - using tuple = decltype(make_tuple(std::declval()...)); + using tuple = decltype(cib::make_tuple(std::declval()...)); template constexpr auto apply(Callable operation, tuple_impl const & t) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0290b367..5d0e3d7e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,7 +7,8 @@ add_executable(tests builder_meta.cpp callback.cpp nexus.cpp - detail/tuple.cpp + tuple.cpp + set.cpp readme_hello_world.cpp ) diff --git a/test/nexus.cpp b/test/nexus.cpp index e62e3396..4a3fc5cc 100644 --- a/test/nexus.cpp +++ b/test/nexus.cpp @@ -135,13 +135,13 @@ TEST_CASE("test conditional expressions") { REQUIRE(true_result); } - SECTION("true evaluation with std::apply") { - constexpr bool true_result = apply(exp, cib::make_tuple(int_<42>)); + SECTION("true evaluation with cib::apply") { + constexpr bool true_result = cib::apply(exp, cib::make_tuple(int_<42>)); REQUIRE(true_result); } SECTION("false evaluation") { - constexpr bool false_result = apply(exp, cib::make_tuple(int_<8>)); + constexpr bool false_result = cib::apply(exp, cib::make_tuple(int_<8>)); REQUIRE_FALSE(false_result); } } diff --git a/test/set.cpp b/test/set.cpp new file mode 100644 index 00000000..6dfa694e --- /dev/null +++ b/test/set.cpp @@ -0,0 +1,75 @@ +#include + +#include + +#include + + +using cib::tag_; +using cib::index_; +using cib::index_metafunc_; + +template +using int_t = std::integral_constant; + +struct A {}; +struct B {}; +struct C {}; +struct D {}; +struct E {}; +struct F {}; +struct G {}; +struct H {}; +struct I {}; +struct J {}; +struct K {}; +struct L {}; + + + + +TEST_CASE("union empty sets", "[set]") { + auto t = cib::set_union( + cib::make_tuple(), + cib::make_tuple() + ); + + REQUIRE((std::is_same_v)); +} + +TEST_CASE("union tiny sets", "[set]") { + auto t = cib::set_union( + cib::make_tuple(A{}), + cib::make_tuple(B{}) + ); + + REQUIRE((std::is_same_v)); +} + +TEST_CASE("union tiny sets with same types", "[set]") { + auto t = cib::set_union( + cib::make_tuple(A{}), + cib::make_tuple(A{}) + ); + + REQUIRE((std::is_same_v)); +} + +TEST_CASE("union less tiny sets", "[set]") { + auto t = cib::set_union( + cib::make_tuple(A{}, C{}, E{}), + cib::make_tuple(B{}, D{}, F{}) + ); + + REQUIRE((std::is_same_v)); +} + +TEST_CASE("union less tiny sets with same types", "[set]") { + auto t = cib::set_union( + cib::make_tuple(A{}, B{}, C{}), + cib::make_tuple(A{}, B{}, C{}) + ); + + REQUIRE((std::is_same_v)); +} + diff --git a/test/detail/tuple.cpp b/test/tuple.cpp similarity index 100% rename from test/detail/tuple.cpp rename to test/tuple.cpp From decbae31a2b6776e94c26923786fe448d99f6891 Mon Sep 17 00:00:00 2001 From: Luke Valenty Date: Sun, 8 May 2022 09:33:00 -0700 Subject: [PATCH 12/15] workarounds for gcc --- include/cib/detail/set_details.hpp | 267 +++++++++++++++++++++++++++++ include/cib/set.hpp | 256 +-------------------------- test/set.cpp | 140 +++++++++++++++ 3 files changed, 412 insertions(+), 251 deletions(-) create mode 100644 include/cib/detail/set_details.hpp diff --git a/include/cib/detail/set_details.hpp b/include/cib/detail/set_details.hpp new file mode 100644 index 00000000..7d63c0df --- /dev/null +++ b/include/cib/detail/set_details.hpp @@ -0,0 +1,267 @@ +#include "../tuple.hpp" + +#include +#include + + +#ifndef CIB_SET_DETAILS_HPP +#define CIB_SET_DETAILS_HPP + + +namespace cib::detail { + // https://en.wikipedia.org/wiki/Quicksort#Hoare_partition_scheme + + template + CIB_CONSTEVAL static std::size_t partition(T * elems, std::size_t lo, std::size_t hi) { + auto const pivot = elems[(hi + lo) / 2]; + + auto i = lo - 1; + auto j = hi + 1; + + while (true) { + do {i = i + 1;} while (elems[i] < pivot); + do {j = j - 1;} while (elems[j] > pivot); + if (i >= j) {return j;} + + auto const temp = elems[i]; + elems[i] = elems[j]; + elems[j] = temp; + } + } + + template + CIB_CONSTEVAL static void quicksort(T * elems, std::size_t lo, std::size_t hi) { + if (lo < hi) { + auto const p = partition(elems, lo, hi); + quicksort(elems, lo, p); + quicksort(elems, p + 1, hi); + } + } + + template + CIB_CONSTEVAL static void quicksort(T & collection) { + quicksort(std::begin(collection), 0, std::size(collection) - std::size_t{1}); + } +} + +namespace cib::detail { + struct typename_map_entry { + std::string_view name; + unsigned int index; + unsigned int src; + + constexpr auto operator<(typename_map_entry rhs) const { + return name < rhs.name; + } + + constexpr auto operator<=(typename_map_entry rhs) const { + return name <= rhs.name; + } + + constexpr auto operator>(typename_map_entry rhs) const { + return name > rhs.name; + } + + constexpr auto operator>=(typename_map_entry rhs) const { + return name >= rhs.name; + } + + constexpr auto operator==(typename_map_entry rhs) const { + return name == rhs.name; + } + + constexpr auto operator!=(typename_map_entry rhs) const { + return name != rhs.name; + } + }; + + template + constexpr static std::string_view name() { + #if defined(__clang__) + constexpr std::string_view function_name = __PRETTY_FUNCTION__; + constexpr auto lhs = 44; + constexpr auto rhs = function_name.size() - 2; + + #elif defined(__GNUC__) || defined(__GNUG__) + constexpr std::string_view function_name = __PRETTY_FUNCTION__; + constexpr auto lhs = 59; + constexpr auto rhs = function_name.size() - 51; + + #elif #elif defined(_MSC_VER) + constexpr std::string_view function_name = __FUNCSIG__; + constexpr auto lhs = 0; + constexpr auto rhs = function_name.size(); + #else + static_assert(false, "Unknown compiler, can't build cib::tuple name."); + #endif + + return function_name.substr(lhs, rhs - lhs + 1); + } + + template + constexpr static auto create_type_names(unsigned int src) { + if constexpr (sizeof...(Types) == 0) { + return std::array{}; + + } else { + unsigned int i = 0; + std::array names = { + typename_map_entry{name>(), i++, src}... + }; + + detail::quicksort(names); + + return names; + } + } + + template + struct data_and_size { + DataT data; + SizeT size; + + constexpr data_and_size(DataT data_arg, SizeT size_arg) + : data{data_arg} + , size{size_arg} + {} + }; + + + + template + struct set_operation_impl_t; + + + template< + typename Algorithm, + typename MetaFunc, + typename... LhsElems, + typename... RhsElems> + struct set_operation_impl_t, tuple_impl> { + + + constexpr static auto result = [](){ + constexpr auto lhs_tags = create_type_names(0); + constexpr auto rhs_tags = create_type_names(1); + + constexpr auto max_size = + lhs_tags.size() + rhs_tags.size(); + + std::array out{}; + + auto const out_end = + Algorithm::invoke( + lhs_tags.begin(), lhs_tags.end(), + rhs_tags.begin(), rhs_tags.end(), + out.begin()); + + auto const out_size = + std::distance(out.begin(), out_end); + + return data_and_size{out, out_size}; + }; + }; + + template< + int... Indices, + typename IndexList, + typename LhsTuple, + typename RhsTuple> + [[nodiscard]] constexpr auto merge_tuple_impl( + std::integer_sequence, + IndexList, + LhsTuple lhs, + RhsTuple rhs + ) { +// constexpr auto index_list = +// IndexList::result().data; + + auto const tuples = + cib::make_tuple(lhs, rhs); + + return make_tuple(tuples.get(index_).get(index_)...); + } + + template< + typename Algorithm, + typename MetaFunc, + typename LhsTuple, + typename RhsTuple> + [[nodiscard]] constexpr auto set_operation_impl( + Algorithm, + MetaFunc, + LhsTuple lhs, + RhsTuple rhs + ) { + using index_list_t = + set_operation_impl_t; + + constexpr auto result_size = + index_list_t::result().size; + + return merge_tuple_impl( + std::make_integer_sequence{}, + index_list_t{}, + lhs, + rhs + ); + } + + template< + bool keep_left_difference, + bool keep_intersection, + bool keep_right_difference> + struct set_operation_algorithm { + template + constexpr static OutputIt invoke( + InputIt1 first1, InputIt1 last1, + InputIt2 first2, InputIt2 last2, + OutputIt d_first + ) { + while ( + first1 != last1 && + first2 != last2 + ) { + if (*first1 < *first2) { + if constexpr (keep_left_difference) { + *d_first++ = *first1; + } + + first1++; + + } else if (*first1 > *first2) { + if constexpr (keep_right_difference) { + *d_first++ = *first2; + } + + first2++; + + } else { + if constexpr (keep_intersection) { + *d_first++ = *first1; + } + + first1++; + first2++; + } + } + + if constexpr (keep_left_difference) { + while (first1 != last1) { + *d_first++ = *first1++; + } + } + + if constexpr (keep_right_difference) { + while (first2 != last2) { + *d_first++ = *first2++; + } + } + + return d_first; + } + }; +} + + +#endif //CIB_SET_DETAILS_HPP diff --git a/include/cib/set.hpp b/include/cib/set.hpp index fc3cd7b2..cd54c34e 100644 --- a/include/cib/set.hpp +++ b/include/cib/set.hpp @@ -1,229 +1,10 @@ -#include "tuple.hpp" - +#include "detail/set_details.hpp" #ifndef CIB_SET_HPP #define CIB_SET_HPP -#include -#include - -#include - -namespace cib::detail { - // https://en.wikipedia.org/wiki/Quicksort#Hoare_partition_scheme - - template - CIB_CONSTEVAL static std::size_t partition(T * elems, std::size_t lo, std::size_t hi) { - auto const pivot = elems[(hi + lo) / 2]; - - auto i = lo - 1; - auto j = hi + 1; - - while (true) { - do {i = i + 1;} while (elems[i] < pivot); - do {j = j - 1;} while (elems[j] > pivot); - if (i >= j) {return j;} - - auto const temp = elems[i]; - elems[i] = elems[j]; - elems[j] = temp; - } - } - - template - CIB_CONSTEVAL static void quicksort(T * elems, std::size_t lo, std::size_t hi) { - if (lo < hi) { - auto const p = partition(elems, lo, hi); - quicksort(elems, lo, p); - quicksort(elems, p + 1, hi); - } - } - - template - CIB_CONSTEVAL static void quicksort(T & collection) { - quicksort(std::begin(collection), 0, std::size(collection) - std::size_t{1}); - } -} - -namespace cib::detail { - struct typename_map_entry { - std::string_view name; - unsigned int index; - unsigned int src; - - constexpr auto operator<(typename_map_entry rhs) const { - return name < rhs.name; - } - - constexpr auto operator<=(typename_map_entry rhs) const { - return name <= rhs.name; - } - - constexpr auto operator>(typename_map_entry rhs) const { - return name > rhs.name; - } - - constexpr auto operator>=(typename_map_entry rhs) const { - return name >= rhs.name; - } - - constexpr auto operator==(typename_map_entry rhs) const { - return name == rhs.name; - } - - constexpr auto operator!=(typename_map_entry rhs) const { - return name != rhs.name; - } - }; - - template - constexpr static std::string_view name() { - #if defined(__clang__) - constexpr std::string_view function_name = __PRETTY_FUNCTION__; - constexpr auto lhs = 44; - constexpr auto rhs = function_name.size() - 2; - - #elif defined(__GNUC__) || defined(__GNUG__) - constexpr std::string_view function_name = __PRETTY_FUNCTION__; - constexpr auto lhs = 59; - constexpr auto rhs = function_name.size() - 51; - - #elif #elif defined(_MSC_VER) - constexpr std::string_view function_name = __FUNCSIG__; - constexpr auto lhs = 0; - constexpr auto rhs = function_name.size(); - #else - static_assert(false, "Unknown compiler, can't build cib::tuple name."); - #endif - - return function_name.substr(lhs, rhs - lhs + 1); - } - - template - constexpr static auto create_type_names(unsigned int src) { - if constexpr (sizeof...(Types) == 0) { - return std::array{}; - - } else { - unsigned int i = 0; - std::array names = { - typename_map_entry{name>(), i++, src}... - }; - - detail::quicksort(names); - - return names; - } - } - - template - constexpr static std::array type_names = - create_type_names(src); - -} - - namespace cib { - template - struct data_and_size { - DataT data; - SizeT size; - - constexpr data_and_size(DataT data_arg, SizeT size_arg) - : data{data_arg} - , size{size_arg} - {} - }; - - - - template - struct set_operation_impl_t; - - - template< - typename Algorithm, - typename MetaFunc, - typename... LhsElems, - typename... RhsElems> - struct set_operation_impl_t, tuple_impl> { - constexpr static auto lhs_tags = detail::type_names; - constexpr static auto rhs_tags = detail::type_names; - - constexpr static auto result = [](){ - constexpr auto max_size = - lhs_tags.size() + rhs_tags.size(); - - std::array out{}; - - auto const out_end = - Algorithm::invoke( - lhs_tags.begin(), lhs_tags.end(), - rhs_tags.begin(), rhs_tags.end(), - out.begin()); - - auto const out_size = - std::distance(out.begin(), out_end); - - return data_and_size{out, out_size}; - }(); - }; - - template< - int... Indices, - typename IndexList, - typename LhsTuple, - typename RhsTuple> - [[nodiscard]] constexpr auto merge_tuple_impl( - std::integer_sequence, - IndexList, - LhsTuple lhs, - RhsTuple rhs - ) { - constexpr auto index_list = - IndexList::result.data; - - auto const tuples = - cib::make_tuple(lhs, rhs); - - return make_tuple(tuples.get(index_).get(index_)...); - } - - template< - typename Algorithm, - typename MetaFunc, - typename LhsTuple, - typename RhsTuple> - [[nodiscard]] constexpr auto set_operation_impl( - Algorithm, - MetaFunc, - LhsTuple lhs, - RhsTuple rhs - ) { - using index_list_t = - set_operation_impl_t; - - constexpr auto result = - index_list_t::result; - - return merge_tuple_impl( - std::make_integer_sequence{}, - index_list_t{}, - lhs, - rhs - ); - } - - struct set_union_algorithm { - template - constexpr static auto invoke( - ArgTs... args - ) { - return std::set_union(args...); - } - }; - template< typename LhsTuple, typename RhsTuple, @@ -233,18 +14,9 @@ namespace cib { RhsTuple rhs, MetaFunc meta_func = self_type{} ) { - return set_operation_impl(set_union_algorithm{}, meta_func, lhs, rhs); + return set_operation_impl(detail::set_operation_algorithm{}, meta_func, lhs, rhs); } - struct set_intersection_algorithm { - template - constexpr static auto invoke( - ArgTs... args - ) { - return std::set_intersection(args...); - } - }; - template< typename LhsTuple, typename RhsTuple, @@ -254,18 +26,9 @@ namespace cib { RhsTuple rhs, MetaFunc meta_func = self_type{} ) { - return set_operation_impl(set_intersection_algorithm{}, meta_func, lhs, rhs); + return set_operation_impl(detail::set_operation_algorithm{}, meta_func, lhs, rhs); } - struct set_difference_algorithm { - template - constexpr static auto invoke( - ArgTs... args - ) { - return std::set_difference(args...); - } - }; - template< typename LhsTuple, typename RhsTuple, @@ -275,18 +38,9 @@ namespace cib { RhsTuple rhs, MetaFunc meta_func = self_type{} ) { - return set_operation_impl(set_difference_algorithm{}, meta_func, lhs, rhs); + return set_operation_impl(detail::set_operation_algorithm{}, meta_func, lhs, rhs); } - struct set_symmetric_difference_algorithm { - template - constexpr static auto invoke( - ArgTs... args - ) { - return std::set_symmetric_difference(args...); - } - }; - template< typename LhsTuple, typename RhsTuple, @@ -296,7 +50,7 @@ namespace cib { RhsTuple rhs, MetaFunc meta_func = self_type{} ) { - return set_operation_impl(set_symmetric_difference_algorithm{}, meta_func, lhs, rhs); + return set_operation_impl(detail::set_operation_algorithm{}, meta_func, lhs, rhs); } } diff --git a/test/set.cpp b/test/set.cpp index 6dfa694e..e638d512 100644 --- a/test/set.cpp +++ b/test/set.cpp @@ -73,3 +73,143 @@ TEST_CASE("union less tiny sets with same types", "[set]") { REQUIRE((std::is_same_v)); } + + + +TEST_CASE("intersection empty sets", "[set]") { + auto t = cib::set_intersection( + cib::make_tuple(), + cib::make_tuple() + ); + + REQUIRE((std::is_same_v)); +} + +TEST_CASE("intersection tiny sets, same", "[set]") { + auto t = cib::set_intersection( + cib::make_tuple(A{}), + cib::make_tuple(A{}) + ); + + REQUIRE((std::is_same_v)); +} + +TEST_CASE("intersection tiny sets, different", "[set]") { + auto t = cib::set_intersection( + cib::make_tuple(A{}), + cib::make_tuple(B{}) + ); + + REQUIRE((std::is_same_v)); +} + +TEST_CASE("intersection less tiny sets", "[set]") { + auto t = cib::set_intersection( + cib::make_tuple(A{}, C{}, E{}), + cib::make_tuple(B{}, D{}, F{}) + ); + + REQUIRE((std::is_same_v)); +} + +TEST_CASE("intersection less tiny sets with same types", "[set]") { + auto t = cib::set_intersection( + cib::make_tuple(A{}, B{}, C{}), + cib::make_tuple(A{}, B{}, C{}) + ); + + REQUIRE((std::is_same_v)); +} + + +TEST_CASE("difference empty sets", "[set]") { + auto t = cib::set_difference( + cib::make_tuple(), + cib::make_tuple() + ); + + REQUIRE((std::is_same_v)); +} + +TEST_CASE("difference one empty set", "[set]") { + auto t = cib::set_difference( + cib::make_tuple(A{}), + cib::make_tuple() + ); + + REQUIRE((std::is_same_v)); +} + +TEST_CASE("difference other empty set", "[set]") { + auto t = cib::set_difference( + cib::make_tuple(), + cib::make_tuple(A{}) + ); + + REQUIRE((std::is_same_v)); +} + +TEST_CASE("difference first item", "[set]") { + auto t = cib::set_difference( + cib::make_tuple(A{}, B{}), + cib::make_tuple(A{}) + ); + + REQUIRE((std::is_same_v)); +} + +TEST_CASE("difference last item", "[set]") { + auto t = cib::set_difference( + cib::make_tuple(A{}, B{}), + cib::make_tuple(B{}) + ); + + REQUIRE((std::is_same_v)); +} + + +TEST_CASE("symmetric difference empty sets", "[set]") { + auto t = cib::set_symmetric_difference( + cib::make_tuple(), + cib::make_tuple() + ); + + REQUIRE((std::is_same_v)); +} + +TEST_CASE("symmetric difference left empty set", "[set]") { + auto t = cib::set_symmetric_difference( + cib::make_tuple(), + cib::make_tuple(A{}) + ); + + REQUIRE((std::is_same_v)); +} + +TEST_CASE("symmetric difference right empty set", "[set]") { + auto t = cib::set_symmetric_difference( + cib::make_tuple(A{}), + cib::make_tuple() + ); + + REQUIRE((std::is_same_v)); +} + +TEST_CASE("symmetric difference both same", "[set]") { + auto t = cib::set_symmetric_difference( + cib::make_tuple(A{}), + cib::make_tuple(A{}) + ); + + REQUIRE((std::is_same_v)); +} + +TEST_CASE("symmetric difference both different", "[set]") { + auto t = cib::set_symmetric_difference( + cib::make_tuple(A{}), + cib::make_tuple(B{}) + ); + + REQUIRE((std::is_same_v)); +} + From 1ed0ca73f7abce5e6b3fc6ac1b1cb219b5304cba Mon Sep 17 00:00:00 2001 From: Luke Valenty Date: Wed, 11 May 2022 10:05:49 -0700 Subject: [PATCH 13/15] fully qualify calls to cib::make_tuple --- include/cib/detail/components.hpp | 2 +- include/cib/detail/config_details.hpp | 2 +- include/cib/detail/extend.hpp | 6 +++--- include/cib/detail/nexus_details.hpp | 2 +- include/cib/detail/set_details.hpp | 2 +- include/cib/tuple.hpp | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/cib/detail/components.hpp b/include/cib/detail/components.hpp index 78715da1..81f05903 100644 --- a/include/cib/detail/components.hpp +++ b/include/cib/detail/components.hpp @@ -19,7 +19,7 @@ namespace cib::detail { Builders const & builders_tuple, Args const & ... args ) const { - return detail::fold_right(make_tuple(Components{}...), builders_tuple, [&](auto const & c, auto const & builders){ + return detail::fold_right(cib::make_tuple(Components{}...), builders_tuple, [&](auto const & c, auto const & builders){ return c.config.init(builders, args...); }); } diff --git a/include/cib/detail/config_details.hpp b/include/cib/detail/config_details.hpp index 24190864..e7cc1b8d 100644 --- a/include/cib/detail/config_details.hpp +++ b/include/cib/detail/config_details.hpp @@ -15,7 +15,7 @@ namespace cib::detail { template struct args { - static CIB_CONSTEXPR auto value = make_tuple(self_type_index, as_constant_v...); + static CIB_CONSTEXPR auto value = cib::make_tuple(self_type_index, as_constant_v...); }; template diff --git a/include/cib/detail/extend.hpp b/include/cib/detail/extend.hpp index 02d9d3ba..4a228c03 100644 --- a/include/cib/detail/extend.hpp +++ b/include/cib/detail/extend.hpp @@ -13,12 +13,12 @@ namespace cib::detail { typename ExtensionPath, typename... Args> struct extend : public config_item { - tuple args_tuple; + cib::tuple args_tuple; CIB_CONSTEVAL explicit extend( Args const & ... args ) - : args_tuple{make_tuple(args...)} + : args_tuple{cib::make_tuple(args...)} { // pass } @@ -75,7 +75,7 @@ namespace cib::detail { (is_same_v>::Service> + ... + 0) <= 1, "Extension matched more than 1 service"); - return make_tuple(index_metafunc_, add(ExtensionPath{}, builders)...); + return cib::make_tuple(index_metafunc_, add(ExtensionPath{}, builders)...); }, builders_tuple); } diff --git a/include/cib/detail/nexus_details.hpp b/include/cib/detail/nexus_details.hpp index 9fc3997d..b4ff25e7 100644 --- a/include/cib/detail/nexus_details.hpp +++ b/include/cib/detail/nexus_details.hpp @@ -20,7 +20,7 @@ namespace cib { template struct to_tuple> { - using type = tuple, ServiceBuilders...>; + using type = cib::tuple, ServiceBuilders...>; constexpr static inline type value{}; }; diff --git a/include/cib/detail/set_details.hpp b/include/cib/detail/set_details.hpp index 7d63c0df..3f30a267 100644 --- a/include/cib/detail/set_details.hpp +++ b/include/cib/detail/set_details.hpp @@ -179,7 +179,7 @@ namespace cib::detail { auto const tuples = cib::make_tuple(lhs, rhs); - return make_tuple(tuples.get(index_).get(index_)...); + return cib::make_tuple(tuples.get(index_).get(index_)...); } template< diff --git a/include/cib/tuple.hpp b/include/cib/tuple.hpp index 0ab836f3..decadfba 100644 --- a/include/cib/tuple.hpp +++ b/include/cib/tuple.hpp @@ -243,9 +243,9 @@ namespace cib { return indices; }(); - auto const outer_tuple = make_tuple(tuples...); + auto const outer_tuple = cib::make_tuple(tuples...); - return make_tuple( + return cib::make_tuple( outer_tuple.get(index_).get(index_)... ); } From 4076e03d4c13872a95ffbfdaa715f99c10bd1af1 Mon Sep 17 00:00:00 2001 From: Luke Valenty Date: Wed, 11 May 2022 10:39:01 -0700 Subject: [PATCH 14/15] add test case for cib::detail::name --- test/CMakeLists.txt | 1 + test/detail/type_to_string_view.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+) create mode 100644 test/detail/type_to_string_view.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a62e212f..bb5a4887 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,6 +6,7 @@ add_executable(tests detail/type_list.cpp detail/type_pack_element.cpp detail/meta.cpp + detail/type_to_string_view.cpp builder_meta.cpp callback.cpp nexus.cpp diff --git a/test/detail/type_to_string_view.cpp b/test/detail/type_to_string_view.cpp new file mode 100644 index 00000000..d4f2cfc6 --- /dev/null +++ b/test/detail/type_to_string_view.cpp @@ -0,0 +1,11 @@ +#include + +#include + +#include + + +TEST_CASE("ensure types are converted to full string", "[type_to_string_view]") { + //using std::string_view_literals::sv; + REQUIRE(cib::detail::name() == "ABCDEFG"); +} \ No newline at end of file From d19c7ed316a7d1a27c6b25cbcdfcb9f576a1688e Mon Sep 17 00:00:00 2001 From: Luke Valenty Date: Mon, 25 Jul 2022 20:15:36 -0700 Subject: [PATCH 15/15] fix test case --- test/detail/type_to_string_view.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/detail/type_to_string_view.cpp b/test/detail/type_to_string_view.cpp index d4f2cfc6..8ae51023 100644 --- a/test/detail/type_to_string_view.cpp +++ b/test/detail/type_to_string_view.cpp @@ -4,8 +4,9 @@ #include +struct ABCDEFG; TEST_CASE("ensure types are converted to full string", "[type_to_string_view]") { //using std::string_view_literals::sv; - REQUIRE(cib::detail::name() == "ABCDEFG"); + REQUIRE(cib::detail::name() == "ABCDEFG"); } \ No newline at end of file