From 1420dca957bd08a70ff23e8986af5d2dc7b0a48d Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Wed, 23 Apr 2025 16:54:00 -0400 Subject: [PATCH] partially working --- CMakeLists.txt | 2 +- include/blt/meta/tuple_filters.h | 22 +++++++++++++++++----- include/blt/std/variant.h | 22 ++++++++++++++++++++-- tests/variant_tests.cpp | 23 ++++++++++++++++++++++- 4 files changed, 60 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a2601a..4e63557 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.9) +set(BLT_VERSION 5.4.10) set(BLT_TARGET BLT) diff --git a/include/blt/meta/tuple_filters.h b/include/blt/meta/tuple_filters.h index 033d35c..1df4219 100644 --- a/include/blt/meta/tuple_filters.h +++ b/include/blt/meta/tuple_filters.h @@ -24,6 +24,18 @@ namespace blt::meta { + template typename Func, typename Tuple> + struct apply_tuple; + + template typename Func, typename... Values> + struct apply_tuple> + { + using type = Func; + }; + + template typename Func, typename Tuple> + using apply_tuple_t = typename apply_tuple::type; + template struct filter_void; @@ -58,12 +70,13 @@ namespace blt::meta using type = std::tuple<>; }; - template typename Func, typename... Args, typename T, typename... Ts> - struct filter_func, T, Ts...> + template typename Func, typename ArgsTuple, typename T, typename... Ts> + struct filter_func { - using type = std::conditional_t::value, typename filter_func, Ts...>::type, decltype( + 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, Ts...>::type>()))>; + std::declval::type>()))>; }; template typename Func, typename ArgsTuple, typename... Ts> @@ -74,7 +87,6 @@ namespace blt::meta template typename Func, typename ArgsTuple, typename... Ts> using filter_func_t = typename filter_func::type; - } #endif //BLT_META_FILTER_VOID_H diff --git a/include/blt/std/variant.h b/include/blt/std/variant.h index da4c108..ffdfa75 100644 --- a/include/blt/std/variant.h +++ b/include/blt/std/variant.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -88,7 +89,13 @@ namespace blt static constexpr bool all_void = std::tuple_size_v == 0; static constexpr bool some_void = std::tuple_size_v != std::tuple_size_v; - static constexpr bool all_same = meta::filter_func_t, non_void_returns>::value; + using same_type = meta::filter_func_t, non_void_returns>; + static constexpr bool all_same = std::tuple_size_v == std::tuple_size_v; + + using variant_type = typename meta::apply_tuple::type; + + using base_type = std::conditional_t; + using return_type = std::conditional_t, base_type>>; }; } @@ -203,7 +210,18 @@ namespace blt template constexpr auto visit(Visitee&&... visitees) -> decltype(auto) { - return std::visit(lambda_visitor{std::forward(visitees)...}, m_variant); + using meta_t = detail::visit_return_type, std::tuple>; + if constexpr (meta_t::all_same) + { + 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); + } } template diff --git a/tests/variant_tests.cpp b/tests/variant_tests.cpp index 6d18ff1..d09b252 100644 --- a/tests/variant_tests.cpp +++ b/tests/variant_tests.cpp @@ -140,8 +140,13 @@ int main() BLT_TRACE("V1: {}", v1_result); auto v2_result = v2.call_member(&base_type::to_string); - + BLT_ASSERT_MSG(v2_result == type2{}.to_string(), ("Expected result to be " + type2{}.to_string() + " but found " + v2_result).c_str()); + BLT_ASSERT_MSG(typeid(v2_result) == typeid(std::string), "Result type expected to be string!"); BLT_TRACE("V2: {}", v2_result); + + auto v3_result = v3.call_member(&base_type::to_string); + BLT_ASSERT_MSG(v3_result == type3{}.to_string(), ("Expected result to be " + type3{}.to_string() + " but found " + v3_result).c_str()); + BLT_ASSERT_MSG(typeid(v3_result) == typeid(std::string), "Result type expected to be string!"); BLT_TRACE("V3: {}", v3.call_member(&base_type::to_string)); blt::variant_t member_missing_stored_member{type1{}}; @@ -150,6 +155,22 @@ int main() auto stored_member_result = member_missing_stored_member.call_member(&base_type::to_string); auto no_member_result = member_missing_stored_no_member.call_member(&base_type::to_string); + BLT_ASSERT(typeid(stored_member_result) == typeid(std::optional)); + BLT_ASSERT(stored_member_result.has_value()); + BLT_ASSERT(typeid(no_member_result) == typeid(std::optional)); + BLT_ASSERT(!no_member_result.has_value()); + 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) { + return t1.simple(); + }, [](const type2& t2) { + return t2.simple(); + }, [](const type3& t3) { + + }); + + BLT_TRACE(blt::type_string()); + } \ No newline at end of file