From fdc1fbf3ca74d6ef8f7df58b823c925cbfcfc4f7 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Thu, 24 Apr 2025 00:07:02 -0400 Subject: [PATCH] things seem to work. need to clean code. --- CMakeLists.txt | 2 +- include/blt/meta/function.h | 2 +- include/blt/meta/tuple_filters.h | 59 ++++++++++++++++++++++++++-- include/blt/std/variant.h | 67 ++++++++++++++++++++++++++++---- tests/variant_tests.cpp | 24 ++++++++++-- 5 files changed, 138 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e63557..9a3b96a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.20) include(cmake/color.cmake) -set(BLT_VERSION 5.4.10) +set(BLT_VERSION 5.4.11) set(BLT_TARGET BLT) diff --git a/include/blt/meta/function.h b/include/blt/meta/function.h index a64ebaa..e71e680 100644 --- a/include/blt/meta/function.h +++ b/include/blt/meta/function.h @@ -139,7 +139,7 @@ namespace blt::meta using class_type = Class; }; - using lambda_trait = lambda_traits; + using lambda_trait = lambda_traits::operator())>; public: using tag_type = lambda_tag; diff --git a/include/blt/meta/tuple_filters.h b/include/blt/meta/tuple_filters.h index 1df4219..3e106b7 100644 --- a/include/blt/meta/tuple_filters.h +++ b/include/blt/meta/tuple_filters.h @@ -33,7 +33,7 @@ namespace blt::meta using type = Func; }; - template typename Func, typename Tuple> + template typename Func, typename Tuple> using apply_tuple_t = typename apply_tuple::type; template @@ -74,9 +74,10 @@ namespace blt::meta struct filter_func { using ArgsTupleWithT = decltype(std::tuple_cat(std::declval(), std::declval>())); - using type = std::conditional_t::value, typename filter_func::type, decltype( - std::tuple_cat(std::declval>(), - std::declval::type>()))>; + using type = std::conditional_t::value, decltype( std::tuple_cat( + std::declval>(), + std::declval::type>())), typename filter_func< + Func, ArgsTuple, Ts...>::type>; }; template typename Func, typename ArgsTuple, typename... Ts> @@ -87,6 +88,56 @@ namespace blt::meta template typename Func, typename ArgsTuple, typename... Ts> using filter_func_t = typename filter_func::type; + + template + struct tuple_contains; + + template + struct tuple_contains> : std::false_type + {}; + + template + struct tuple_contains> : std::conditional_t< + std::is_same_v || tuple_contains>::value, std::true_type, std::false_type> + {}; + + template + constexpr static bool tuple_contains_v = tuple_contains::value; + + template + struct unique_types; + + template <> + struct unique_types<> + { + using type = std::tuple<>; + }; + + template + struct unique_types + { + using type = std::tuple; + }; + + template + struct unique_types + { + using rest_unique = typename unique_types::type; + using type = std::conditional_t, rest_unique, decltype(std::tuple_cat( + std::declval(), std::declval>()))>; + }; + + template + struct unique_tuple; + + template + struct unique_tuple> + { + using type = typename unique_types::type; + }; + + template + using unique_tuple_t = typename unique_tuple::type; } #endif //BLT_META_FILTER_VOID_H diff --git a/include/blt/std/variant.h b/include/blt/std/variant.h index ffdfa75..c100d26 100644 --- a/include/blt/std/variant.h +++ b/include/blt/std/variant.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -82,7 +83,7 @@ namespace blt { using return_tuple = std::tuple::return_type...>; - using non_void_returns = meta::filter_void_t; + using non_void_returns = meta::unique_tuple_t>; using first_return = std::tuple_element_t< 0, std::conditional_t == 0, std::tuple, non_void_returns>>; @@ -145,6 +146,15 @@ namespace blt std::forward(args)...) {} + // template , variant_t>, bool> = true> + // explicit constexpr variant_t(T&& t): m_variant(std::forward(t)) + // {} + + // template + // constexpr variant_t(std::initializer_list il): m_variant(*il.begin()) + // { + // } + template explicit constexpr variant_t(std::in_place_type_t, C_Args&&... args): m_variant(std::in_place_type, std::forward(args)...) {} @@ -211,16 +221,59 @@ namespace blt constexpr auto visit(Visitee&&... visitees) -> decltype(auto) { using meta_t = detail::visit_return_type, std::tuple>; + // BLT_TRACE(blt::type_string()); + BLT_TRACE(blt::type_string()); + BLT_TRACE(blt::type_string()); if constexpr (meta_t::all_same) { - return std::visit(lambda_visitor{std::forward(visitees)...}, m_variant); + if constexpr (meta_t::some_void) + { + return std::visit(lambda_visitor{ + [&](std::tuple_element_t<0, typename meta::function_like::args_tuple> value) { + if constexpr (std::is_void_v::return_type>) + { + std::forward(visitees)(std::forward(value)); + return typename meta_t::return_type{}; + } else + { + return typename meta_t::return_type( + std::forward(visitees)(std::forward(value)) + ); + } + }... + }, m_variant); + } else + { + return std::visit(lambda_visitor{std::forward(visitees)...}, m_variant); + } } else { - return std::visit(lambda_visitor{ - [&](std::tuple_element_t<0, typename meta::function_like::args_tuple> value) { - return typename meta_t::return_type{std::forward(visitees)(std::forward(value))}; - } - }..., m_variant); + if constexpr (meta_t::some_void) + { + return std::visit(lambda_visitor{ + [&](std::tuple_element_t<0, typename meta::function_like::args_tuple> value) { + if constexpr (std::is_void_v::return_type>) + { + std::forward(visitees)(std::forward(value)); + return typename meta_t::return_type{}; + } else + { + return typename meta_t::return_type( + typename meta_t::base_type(std::forward(visitees)(std::forward(value))) + ); + } + }... + }, m_variant); + } else + { + return std::visit(lambda_visitor{ + [&](std::tuple_element_t<0, typename meta::function_like::args_tuple> value) { + return typename meta_t::return_type{ + std::forward(visitees)(std::forward(value)) + }; + }... + }, m_variant); + } } } diff --git a/tests/variant_tests.cpp b/tests/variant_tests.cpp index d09b252..8aed3d0 100644 --- a/tests/variant_tests.cpp +++ b/tests/variant_tests.cpp @@ -163,14 +163,32 @@ int main() BLT_TRACE("Stored: has value? '{}' value: '{}'", stored_member_result.has_value(), *stored_member_result); BLT_TRACE("No Member: {}", no_member_result.has_value()); - auto vist_result_v1 = v1.visit([](const type1& t1) { + auto visit_result_v1 = v1.visit([](const type1& t1) { return t1.simple(); }, [](const type2& t2) { return t2.simple(); - }, [](const type3& t3) { + }, [](const type3&) { }); - BLT_TRACE(blt::type_string()); + auto visit_result_v2 = v2.visit([](const type1& t1) { + return static_cast(t1.simple()); + }, [](const type2& t2) { + return std::to_string(t2.simple()); + }, [] (const type3& t3) { + return t3.simple(); + }); + + auto visit_result_v3 = v2.visit([](const type1&) { + }, [](const type2& t2) { + return std::to_string(t2.simple()); + }, [] (const type3& t3) { + return t3.simple(); + }); + + if (visit_result_v1) + BLT_TRACE("Visit result: {}", *visit_result_v1); + + BLT_TRACE(blt::type_string()); } \ No newline at end of file