partially working

main
Brett 2025-04-23 16:54:00 -04:00
parent 84921fffa7
commit 1420dca957
4 changed files with 60 additions and 9 deletions

View File

@ -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)

View File

@ -24,6 +24,18 @@
namespace blt::meta
{
template <template<typename...> typename Func, typename Tuple>
struct apply_tuple;
template <template<typename...> typename Func, typename... Values>
struct apply_tuple<Func, std::tuple<Values...>>
{
using type = Func<Values...>;
};
template<template<typename...> typename Func, typename Tuple>
using apply_tuple_t = typename apply_tuple<Func, Tuple>::type;
template <typename... Ts>
struct filter_void;
@ -58,12 +70,13 @@ namespace blt::meta
using type = std::tuple<>;
};
template <template<typename...> typename Func, typename... Args, typename T, typename... Ts>
struct filter_func<Func, std::tuple<Args...>, T, Ts...>
template <template<typename...> typename Func, typename ArgsTuple, typename T, typename... Ts>
struct filter_func<Func, ArgsTuple, T, Ts...>
{
using type = std::conditional_t<Func<T, Args...>::value, typename filter_func<Func, std::tuple<Args...>, Ts...>::type, decltype(
using ArgsTupleWithT = decltype(std::tuple_cat(std::declval<ArgsTuple>(), std::declval<std::tuple<T>>()));
using type = std::conditional_t<apply_tuple_t<Func, ArgsTupleWithT>::value, typename filter_func<Func, ArgsTuple, Ts...>::type, decltype(
std::tuple_cat(std::declval<std::tuple<T>>(),
std::declval<typename filter_func<Func, std::tuple<Args...>, Ts...>::type>()))>;
std::declval<typename filter_func<Func, ArgsTuple, Ts...>::type>()))>;
};
template <template<typename...> typename Func, typename ArgsTuple, typename... Ts>
@ -74,7 +87,6 @@ namespace blt::meta
template <template<typename...> typename Func, typename ArgsTuple, typename... Ts>
using filter_func_t = typename filter_func<Func, ArgsTuple, Ts...>::type;
}
#endif //BLT_META_FILTER_VOID_H

View File

@ -24,6 +24,7 @@
#include <tuple>
#include <type_traits>
#include <variant>
#include <blt/meta/function.h>
#include <blt/meta/passthrough.h>
#include <blt/meta/tuple_filters.h>
#include <blt/std/types.h>
@ -88,7 +89,13 @@ namespace blt
static constexpr bool all_void = std::tuple_size_v<non_void_returns> == 0;
static constexpr bool some_void = std::tuple_size_v<non_void_returns> != std::tuple_size_v<return_tuple>;
static constexpr bool all_same = meta::filter_func_t<std::is_same, std::tuple<first_return>, non_void_returns>::value;
using same_type = meta::filter_func_t<std::is_same, std::tuple<first_return>, non_void_returns>;
static constexpr bool all_same = std::tuple_size_v<same_type> == std::tuple_size_v<non_void_returns>;
using variant_type = typename meta::apply_tuple<variant_t, non_void_returns>::type;
using base_type = std::conditional_t<all_same, first_return, variant_type>;
using return_type = std::conditional_t<all_void, void, std::conditional_t<some_void, std::optional<base_type>, base_type>>;
};
}
@ -203,7 +210,18 @@ namespace blt
template <typename... Visitee>
constexpr auto visit(Visitee&&... visitees) -> decltype(auto)
{
return std::visit(lambda_visitor{std::forward<Visitee>(visitees)...}, m_variant);
using meta_t = detail::visit_return_type<std::tuple<Visitee...>, std::tuple<Types...>>;
if constexpr (meta_t::all_same)
{
return std::visit(lambda_visitor{std::forward<Visitee>(visitees)...}, m_variant);
} else
{
return std::visit(lambda_visitor{
[&](std::tuple_element_t<0, typename meta::function_like<Visitee>::args_tuple> value) {
return typename meta_t::return_type{std::forward<Visitee>(visitees)(std::forward<decltype(value)>(value))};
}
}..., m_variant);
}
}
template <typename Default, typename... Visitee>

View File

@ -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<type1, type2, no_members> 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<std::string>));
BLT_ASSERT(stored_member_result.has_value());
BLT_ASSERT(typeid(no_member_result) == typeid(std::optional<std::string>));
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<decltype(vist_result_v1)>());
}