things seem to work. need to clean code.

main
Brett 2025-04-24 00:07:02 -04:00
parent 1420dca957
commit fdc1fbf3ca
5 changed files with 138 additions and 16 deletions

View File

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

View File

@ -139,7 +139,7 @@ namespace blt::meta
using class_type = Class;
};
using lambda_trait = lambda_traits<decltype(&Func::operator())>;
using lambda_trait = lambda_traits<decltype(&std::decay_t<Func>::operator())>;
public:
using tag_type = lambda_tag;

View File

@ -33,7 +33,7 @@ namespace blt::meta
using type = Func<Values...>;
};
template<template<typename...> typename Func, typename Tuple>
template <template<typename...> typename Func, typename Tuple>
using apply_tuple_t = typename apply_tuple<Func, Tuple>::type;
template <typename... Ts>
@ -74,9 +74,10 @@ namespace blt::meta
struct filter_func<Func, ArgsTuple, T, Ts...>
{
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, ArgsTuple, Ts...>::type>()))>;
using type = std::conditional_t<apply_tuple_t<Func, ArgsTupleWithT>::value, decltype( std::tuple_cat(
std::declval<std::tuple<T>>(),
std::declval<typename filter_func<Func, ArgsTuple, Ts...>::type>())), typename filter_func<
Func, ArgsTuple, Ts...>::type>;
};
template <template<typename...> typename Func, typename ArgsTuple, typename... Ts>
@ -87,6 +88,56 @@ namespace blt::meta
template <template<typename...> typename Func, typename ArgsTuple, typename... Ts>
using filter_func_t = typename filter_func<Func, ArgsTuple, Ts...>::type;
template <typename...>
struct tuple_contains;
template <typename T>
struct tuple_contains<T, std::tuple<>> : std::false_type
{};
template <typename T, typename T1, typename... Ts>
struct tuple_contains<T, std::tuple<T1, Ts...>> : std::conditional_t<
std::is_same_v<T, T1> || tuple_contains<T, std::tuple<Ts...>>::value, std::true_type, std::false_type>
{};
template <typename T, typename Tuple>
constexpr static bool tuple_contains_v = tuple_contains<T, Tuple>::value;
template <typename... Ts>
struct unique_types;
template <>
struct unique_types<>
{
using type = std::tuple<>;
};
template <typename T>
struct unique_types<T>
{
using type = std::tuple<T>;
};
template <typename T, typename... Rest>
struct unique_types<T, Rest...>
{
using rest_unique = typename unique_types<Rest...>::type;
using type = std::conditional_t<tuple_contains_v<T, rest_unique>, rest_unique, decltype(std::tuple_cat(
std::declval<rest_unique>(), std::declval<std::tuple<T>>()))>;
};
template <typename Tuple>
struct unique_tuple;
template <typename... Ts>
struct unique_tuple<std::tuple<Ts...>>
{
using type = typename unique_types<Ts...>::type;
};
template <typename Tuple>
using unique_tuple_t = typename unique_tuple<Tuple>::type;
}
#endif //BLT_META_FILTER_VOID_H

View File

@ -24,6 +24,7 @@
#include <tuple>
#include <type_traits>
#include <variant>
#include <blt/logging/logging.h>
#include <blt/meta/function.h>
#include <blt/meta/passthrough.h>
#include <blt/meta/tuple_filters.h>
@ -82,7 +83,7 @@ namespace blt
{
using return_tuple = std::tuple<typename visit_func_meta<Funcs, Types...>::return_type...>;
using non_void_returns = meta::filter_void_t<return_tuple>;
using non_void_returns = meta::unique_tuple_t<meta::filter_void_t<return_tuple>>;
using first_return = std::tuple_element_t<
0, std::conditional_t<std::tuple_size_v<non_void_returns> == 0, std::tuple<void>, non_void_returns>>;
@ -145,6 +146,15 @@ namespace blt
std::forward<Types>(args)...)
{}
// template <typename T, std::enable_if_t<!std::is_same_v<std::decay_t<T>, variant_t>, bool> = true>
// explicit constexpr variant_t(T&& t): m_variant(std::forward<T>(t))
// {}
// template<typename T>
// constexpr variant_t(std::initializer_list<T> il): m_variant(*il.begin())
// {
// }
template <typename T, typename... C_Args>
explicit constexpr variant_t(std::in_place_type_t<T>, C_Args&&... args): m_variant(std::in_place_type<T>, std::forward<C_Args>(args)...)
{}
@ -211,16 +221,59 @@ namespace blt
constexpr auto visit(Visitee&&... visitees) -> decltype(auto)
{
using meta_t = detail::visit_return_type<std::tuple<Visitee...>, std::tuple<Types...>>;
// BLT_TRACE(blt::type_string<typename meta_t::return_tuple>());
BLT_TRACE(blt::type_string<typename meta_t::non_void_returns>());
BLT_TRACE(blt::type_string<typename meta_t::same_type>());
if constexpr (meta_t::all_same)
{
return std::visit(lambda_visitor{std::forward<Visitee>(visitees)...}, m_variant);
if constexpr (meta_t::some_void)
{
return std::visit(lambda_visitor{
[&](std::tuple_element_t<0, typename meta::function_like<Visitee>::args_tuple> value) {
if constexpr (std::is_void_v<typename meta::function_like<decltype(visitees)>::return_type>)
{
std::forward<Visitee>(visitees)(std::forward<decltype(value)>(value));
return typename meta_t::return_type{};
} else
{
return typename meta_t::return_type(
std::forward<Visitee>(visitees)(std::forward<decltype(value)>(value))
);
}
}...
}, m_variant);
} else
{
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);
if constexpr (meta_t::some_void)
{
return std::visit(lambda_visitor{
[&](std::tuple_element_t<0, typename meta::function_like<Visitee>::args_tuple> value) {
if constexpr (std::is_void_v<typename meta::function_like<decltype(visitees)>::return_type>)
{
std::forward<Visitee>(visitees)(std::forward<decltype(value)>(value));
return typename meta_t::return_type{};
} else
{
return typename meta_t::return_type(
typename meta_t::base_type(std::forward<Visitee>(visitees)(std::forward<decltype(value)>(value)))
);
}
}...
}, 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);
}
}
}

View File

@ -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<decltype(vist_result_v1)>());
auto visit_result_v2 = v2.visit([](const type1& t1) {
return static_cast<float>(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<decltype(visit_result_v1)>());
}