From 6661cc346f45bd6196658d22af87b2ad41d6f023 Mon Sep 17 00:00:00 2001 From: Liss Heidrich <31625940+liss-h@users.noreply.github.com> Date: Fri, 8 May 2026 06:56:33 +0200 Subject: [PATCH 1/2] Fix: misc fixes and features required upstream (#181) Co-authored-by: Alex Co-authored-by: Nikolaos Karalis --- include/dice/template-library/type_list.hpp | 35 +++++++++ include/dice/template-library/variant2.hpp | 24 +++++- tests/tests_type_list.cpp | 17 +++++ tests/tests_variant2.cpp | 81 ++++++++++++++------- 4 files changed, 127 insertions(+), 30 deletions(-) diff --git a/include/dice/template-library/type_list.hpp b/include/dice/template-library/type_list.hpp index d1799b7..cf843cc 100644 --- a/include/dice/template-library/type_list.hpp +++ b/include/dice/template-library/type_list.hpp @@ -293,6 +293,22 @@ namespace dice::template_library::type_list { using filter_t = typename filter::type; + /** + * Flatten a type list of type lists of types into a type list of types. + * @tparam TL type list of type lists + */ + template + struct flatten; + + template + struct flatten> { + using type = concat_t; + }; + + template + using flatten_t = typename flatten::type; + + namespace detail_generate { template struct generate_impl; @@ -506,6 +522,25 @@ namespace dice::template_library::type_list { using integer_sequence_to_type_list_t = typename integer_sequence_to_type_list::type; + /** + * Convert a tuple-like thing into a type list of its component types. + */ + template + struct tuple_to_type_list; + + template + requires requires { + { std::tuple_size_v } -> std::convertible_to; + } + struct tuple_to_type_list { + using type = decltype([](std::index_sequence) { + return type_list...>{}; + }(std::make_index_sequence>{})); + }; + + template + using tuple_to_type_list_t = typename tuple_to_type_list::type; + /** * A marker type to indicate a failed operation * when using opt diff --git a/include/dice/template-library/variant2.hpp b/include/dice/template-library/variant2.hpp index 4cadd35..9f672f8 100644 --- a/include/dice/template-library/variant2.hpp +++ b/include/dice/template-library/variant2.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -720,7 +721,7 @@ namespace dice::template_library { rhs = std::move(tmp); } - constexpr bool operator==(variant2 const &other) const noexcept { + constexpr bool operator==(variant2 const &other) const noexcept requires (std::equality_comparable && std::equality_comparable) { if (discriminant_ != other.discriminant_) { return false; } @@ -742,7 +743,7 @@ namespace dice::template_library { } } - constexpr auto operator<=>(variant2 const &other) const noexcept { + constexpr auto operator<=>(variant2 const &other) const noexcept requires (std::three_way_comparable && std::three_way_comparable) { using ret_type = std::common_comparison_category_t, std::compare_three_way_result_t>; if (discriminant_ != other.discriminant_) { @@ -903,4 +904,23 @@ namespace dice::template_library { } // namespace dice::template_library +template requires (std::formattable && std::formattable) +struct std::formatter<::dice::template_library::variant2> { + template + constexpr auto parse(Ctx &ctx) { + return ctx.begin(); + } + + template + auto format(::dice::template_library::variant2 const &var, Ctx &ctx) const { + // formatting the same way libfmt does + if (var.valueless_by_exception()) { + return std::format_to(ctx.out(), "variant(valueless by exception)"); + } + return ::dice::template_library::visit([&ctx](auto const &value) { + return std::format_to(ctx.out(), "variant({})", value); + }, var); + } +}; + #endif // DICE_TEMPLATELIBRARY_VARIANT2_HPP diff --git a/tests/tests_type_list.cpp b/tests/tests_type_list.cpp index ee48ef3..0942084 100644 --- a/tests/tests_type_list.cpp +++ b/tests/tests_type_list.cpp @@ -159,6 +159,13 @@ TEST_SUITE("type_list") { static_assert(std::is_same_v, tl::type_list>); } + TEST_CASE("flatten") { + static_assert(std::is_same_v, empty_t>); + static_assert(std::is_same_v>, empty_t>); + static_assert(std::is_same_v, empty_t, tl::type_list>>, tl::type_list>); + static_assert(std::is_same_v>>>, tl::type_list>>); + } + TEST_CASE("generate") { static_assert(std::is_same_v, empty_t>); @@ -302,6 +309,16 @@ TEST_SUITE("type_list") { static_assert(std::is_same_v, expected_iseq_tl>); } + TEST_CASE("tuple_to_type_list") { + using empty_tuple = std::tuple<>; + using pair = std::pair; + using tuple = std::tuple; + + static_assert(std::is_same_v, empty_t>); + static_assert(std::is_same_v, tl::type_list>); + static_assert(std::is_same_v, tl::type_list>); + } + TEST_CASE("for_each") { using t1 = tl::type_list; diff --git a/tests/tests_variant2.cpp b/tests/tests_variant2.cpp index c4476bc..d478768 100644 --- a/tests/tests_variant2.cpp +++ b/tests/tests_variant2.cpp @@ -7,6 +7,47 @@ using namespace std::string_literals; +struct make_valueless { + make_valueless() { + throw std::runtime_error{"aaa"}; + } + + explicit make_valueless(std::nothrow_t) noexcept {} + + make_valueless(make_valueless const &) { + throw std::runtime_error{"aaa"}; + } + + make_valueless(make_valueless &&) { + throw std::runtime_error{"aaa"}; + } + + make_valueless &operator=(make_valueless const &) { + throw std::runtime_error{"aaa"}; + } + + make_valueless &operator=(make_valueless &&) { + throw std::runtime_error{"aaa"}; + } + + ~make_valueless() noexcept = default; + + auto operator<=>(make_valueless const &) const noexcept = default; +}; + +template<> +struct std::formatter { + template + constexpr auto parse(Ctx &parse_ctx) { + return parse_ctx.begin(); + } + + template + auto format(make_valueless const &, Ctx &format_ctx) const { + return std::format_to(format_ctx.out(), "make_valueluess"); + } +}; + TEST_SUITE("variant2") { using namespace dice::template_library; @@ -29,34 +70,6 @@ TEST_SUITE("variant2") { && std::is_const_v> == std::is_const_v>; - struct make_valueless { - make_valueless() { - throw std::runtime_error{"aaa"}; - } - - explicit make_valueless(std::nothrow_t) noexcept {} - - make_valueless(make_valueless const &) { - throw std::runtime_error{"aaa"}; - } - - make_valueless(make_valueless &&) { - throw std::runtime_error{"aaa"}; - } - - make_valueless &operator=(make_valueless const &) { - throw std::runtime_error{"aaa"}; - } - - make_valueless &operator=(make_valueless &&) { - throw std::runtime_error{"aaa"}; - } - - ~make_valueless() noexcept = default; - - auto operator<=>(make_valueless const &) const noexcept = default; - }; - template void check_acessors(Variant &&x, T const &expected_val) { static constexpr size_t index = variant_index>::value; @@ -289,4 +302,16 @@ TEST_SUITE("variant2") { static_assert(!std::is_trivially_destructible_v); static_assert(!std::is_trivially_copyable_v); } + + TEST_CASE("formatting") { + CHECK(std::format("{}", variant2{42}) == "variant(42)"); + CHECK(std::format("{}", variant2{1.5}) == "variant(1.5)"); + + variant2 valueless{}; + try { + valueless = make_valueless{std::nothrow}; + } catch (...) { + } + CHECK(std::format("{}", valueless) == "variant(valueless by exception)"); + } } From bbeeb61a55eea237285b95e146407d77629ff595 Mon Sep 17 00:00:00 2001 From: Liss Heidrich <31625940+liss-h@users.noreply.github.com> Date: Fri, 8 May 2026 07:00:08 +0200 Subject: [PATCH 2/2] version bump --- CMakeLists.txt | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b25e427..4ae8ced 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.24) project( dice-template-library - VERSION 2.3.0 + VERSION 2.4.0 DESCRIPTION "This template library is a collection of template-oriented code that we, the Data Science Group at UPB, found pretty handy. It contains: `switch_cases` (Use runtime values in compile-time context), `integral_template_tuple` (Create a tuple-like structure that instantiates a template for a range of values), `integral_template_variant` (A wrapper type for `std::variant` guarantees to only contain variants of the form `T` and `for_{types,values,range}` (Compile time for loops for types, values or ranges))." HOMEPAGE_URL "https://dice-research.org/") diff --git a/README.md b/README.md index f7fd8dc..79cb3c9 100644 --- a/README.md +++ b/README.md @@ -259,7 +259,7 @@ A C++23 compatible compiler. Code was only tested on x86_64. ## Include it in your projects ### Conan You can use it with [conan](https://conan.io/). -To do so, you need to add `dice-template-library/2.3.0` to the `[requires]` section of your conan file. +To do so, you need to add `dice-template-library/2.4.0` to the `[requires]` section of your conan file. ## Build and Run Tests and Examples