From 606def7c10524c2e577bc6f7bab595eb3d1fd9c4 Mon Sep 17 00:00:00 2001 From: Brett Date: Mon, 21 Apr 2025 01:23:39 -0400 Subject: [PATCH] some variant detail --- CMakeLists.txt | 2 +- include/blt/std/utility.h | 9 ++++ include/blt/std/variant.h | 97 +++++++++++++++++++++++++++++++++++---- 3 files changed, 99 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eeb3489..cac839c 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.2) +set(BLT_VERSION 5.4.3) set(BLT_TARGET BLT) diff --git a/include/blt/std/utility.h b/include/blt/std/utility.h index 49139bc..4572d75 100644 --- a/include/blt/std/utility.h +++ b/include/blt/std/utility.h @@ -108,6 +108,15 @@ namespace blt hell = (void*) &val; (void) hell; } + + template + BLT_ATTRIB_NO_INLINE T& black_box_ret(T& val) + { + static volatile void* hell; + hell = (void*) &val; + (void) hell; + return val; + } template BLT_ATTRIB_NO_INLINE const T& black_box_ret(const T& val) diff --git a/include/blt/std/variant.h b/include/blt/std/variant.h index 5ed5bb8..1b13a6f 100644 --- a/include/blt/std/variant.h +++ b/include/blt/std/variant.h @@ -21,15 +21,98 @@ #include #include -#include #include #include #include - -#include "blt/logging/logging.h" +#include namespace blt { + template + class variant_t; + + namespace detail + { + template + struct filter_void; + + template <> + struct filter_void<> + { + using type = std::tuple<>; + }; + + template + struct filter_void + { + using type = std::conditional_t< + std::is_same_v, + typename filter_void::type, + decltype(std::tuple_cat( + std::declval>(), + std::declval::type>() + )) + >; + }; + + template + using filter_void_t = typename filter_void::type; + + + template + struct member_func_detail; + + template + struct member_func_detail + { + template + using return_type = std::invoke_result_t; + + template + using can_invoke = std::is_invocable; + + template + using result_or_void = std::conditional::value, return_type, void>; + + constexpr static bool all_has_void = std::conjunction_v>...>; + + using ret_type = std::conditional_t( + std::declval, return_type...>>()))>; + + constexpr static bool all_has_ret = std::conjunction_v>...>; + constexpr static bool ret_or_void = std::conjunction_v>, std::is_void>>...>; + + template + static constexpr auto make_variant(std::index_sequence) + { + if constexpr (all_has_void) + return; + using tuple_type = filter_void_t; + using variant = variant_t(std::declval()))...>; + return std::declval(); + } + + using variant_type = decltype(make_variant(std::index_sequence_for{})); + + static constexpr auto make_return_type() + { + if constexpr (all_has_void) + return; + if constexpr (all_has_ret) + return std::declval(); + if constexpr (ret_or_void) + return std::declval>(); + return std::declval(); + } + }; + + template + struct member_func_detail + { + }; + } + /* * std::visit(blt::lambda_visitor{ * lambdas... @@ -190,7 +273,7 @@ namespace blt * @tparam should_throw Controls if the implementation should throw if the type stored in the variant doesn't have any matching member function * @return Result of calling the member functions. All functions should return the same value, otherwise this won't compile. */ - template + template constexpr auto call_member(const MemberFuncs... funcs) { static_assert(std::conjunction_v>...>, @@ -199,9 +282,8 @@ namespace blt { using ValueType = std::decay_t; - if constexpr (std::disjunction_v, ValueType>...> && should_throw) + if constexpr (std::disjunction_v, ValueType>...>) { - throw std::runtime_error("No matching member function found"); } return *(... || ([&](auto&& func) -> decltype(auto) @@ -222,8 +304,7 @@ namespace blt { return std::visit([=](auto&& value) { - using ValueType = std::decay_t; - return ((value).*(cast_member_ptr(func)))(std::forward(args)...); + return ((value).*(func))(std::forward(args)...); }, m_variant); }