things seem to work. need to clean code.
parent
1420dca957
commit
fdc1fbf3ca
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 3.20)
|
cmake_minimum_required(VERSION 3.20)
|
||||||
include(cmake/color.cmake)
|
include(cmake/color.cmake)
|
||||||
set(BLT_VERSION 5.4.10)
|
set(BLT_VERSION 5.4.11)
|
||||||
|
|
||||||
set(BLT_TARGET BLT)
|
set(BLT_TARGET BLT)
|
||||||
|
|
||||||
|
|
|
@ -139,7 +139,7 @@ namespace blt::meta
|
||||||
using class_type = Class;
|
using class_type = Class;
|
||||||
};
|
};
|
||||||
|
|
||||||
using lambda_trait = lambda_traits<decltype(&Func::operator())>;
|
using lambda_trait = lambda_traits<decltype(&std::decay_t<Func>::operator())>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using tag_type = lambda_tag;
|
using tag_type = lambda_tag;
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace blt::meta
|
||||||
using type = Func<Values...>;
|
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;
|
using apply_tuple_t = typename apply_tuple<Func, Tuple>::type;
|
||||||
|
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
@ -74,9 +74,10 @@ namespace blt::meta
|
||||||
struct filter_func<Func, ArgsTuple, T, Ts...>
|
struct filter_func<Func, ArgsTuple, T, Ts...>
|
||||||
{
|
{
|
||||||
using ArgsTupleWithT = decltype(std::tuple_cat(std::declval<ArgsTuple>(), std::declval<std::tuple<T>>()));
|
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(
|
using type = std::conditional_t<apply_tuple_t<Func, ArgsTupleWithT>::value, decltype( std::tuple_cat(
|
||||||
std::tuple_cat(std::declval<std::tuple<T>>(),
|
std::declval<std::tuple<T>>(),
|
||||||
std::declval<typename filter_func<Func, ArgsTuple, Ts...>::type>()))>;
|
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>
|
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>
|
template <template<typename...> typename Func, typename ArgsTuple, typename... Ts>
|
||||||
using filter_func_t = typename filter_func<Func, ArgsTuple, Ts...>::type;
|
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
|
#endif //BLT_META_FILTER_VOID_H
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
#include <blt/logging/logging.h>
|
||||||
#include <blt/meta/function.h>
|
#include <blt/meta/function.h>
|
||||||
#include <blt/meta/passthrough.h>
|
#include <blt/meta/passthrough.h>
|
||||||
#include <blt/meta/tuple_filters.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 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<
|
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>>;
|
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)...)
|
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>
|
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)...)
|
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)
|
constexpr auto visit(Visitee&&... visitees) -> decltype(auto)
|
||||||
{
|
{
|
||||||
using meta_t = detail::visit_return_type<std::tuple<Visitee...>, std::tuple<Types...>>;
|
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)
|
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
|
} else
|
||||||
{
|
{
|
||||||
return std::visit(lambda_visitor{
|
if constexpr (meta_t::some_void)
|
||||||
[&](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))};
|
return std::visit(lambda_visitor{
|
||||||
}
|
[&](std::tuple_element_t<0, typename meta::function_like<Visitee>::args_tuple> value) {
|
||||||
}..., m_variant);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -163,14 +163,32 @@ int main()
|
||||||
BLT_TRACE("Stored: has value? '{}' value: '{}'", stored_member_result.has_value(), *stored_member_result);
|
BLT_TRACE("Stored: has value? '{}' value: '{}'", stored_member_result.has_value(), *stored_member_result);
|
||||||
BLT_TRACE("No Member: {}", no_member_result.has_value());
|
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();
|
return t1.simple();
|
||||||
}, [](const type2& t2) {
|
}, [](const type2& t2) {
|
||||||
return t2.simple();
|
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)>());
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue