basic custom variant fixing some issues with the STL. currently unstable and untested.

main
Brett 2025-04-19 20:36:51 -04:00
parent 2bac310e55
commit f245b7531e
3 changed files with 71 additions and 37 deletions

View File

@ -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.3.8) set(BLT_VERSION 5.4.0)
set(BLT_TARGET BLT) set(BLT_TARGET BLT)

View File

@ -67,31 +67,6 @@ namespace blt
return typeid(T).name(); return typeid(T).name();
} }
//#define BLT_LAMBDA(type, var, code) [](const type& var) -> auto { return code; }
//#define BLT_LAMBDA(var, code) [](var) -> auto { return code; }
/*
* std::visit(blt::lambda_visitor{
* lambdas...
* }, data_variant);
*/
// TODO: WTF
template<class... TLambdas>
struct lambda_visitor : TLambdas ...
{
using TLambdas::operator()...;
};
#if __cplusplus < 202002L
// explicit deduction guide (not needed as of C++20)
template<class... TLambdas>
lambda_visitor(TLambdas...) -> lambda_visitor<TLambdas...>;
#endif
#if defined(__GNUC__) || defined(__llvm__) #if defined(__GNUC__) || defined(__llvm__)
#define BLT_UNREACHABLE __builtin_unreachable() #define BLT_UNREACHABLE __builtin_unreachable()
#define BLT_ATTRIB_NO_INLINE __attribute__ ((noinline)) #define BLT_ATTRIB_NO_INLINE __attribute__ ((noinline))

View File

@ -25,6 +25,26 @@
namespace blt namespace blt
{ {
/*
* std::visit(blt::lambda_visitor{
* lambdas...
* }, data_variant);
*/
template <typename... TLambdas>
struct lambda_visitor : TLambdas...
{
using TLambdas::operator()...;
};
#if __cplusplus < 202002L
// explicit deduction guide (not needed as of C++20)
template <typename... TLambdas>
lambda_visitor(TLambdas...) -> lambda_visitor<TLambdas...>;
#endif
template <typename... Types> template <typename... Types>
class variant_t class variant_t
{ {
@ -119,6 +139,46 @@ namespace blt
return std::visit(std::forward<T>(visitor), m_variant); return std::visit(std::forward<T>(visitor), m_variant);
} }
/**
* Automatic visitor generation with empty default behavior
* @param visitees user lambdas
*/
template <typename... Visitee>
constexpr void visit_empty(Visitee&&... visitees)
{
std::visit(lambda_visitor{
std::forward<Visitee>(visitees)...,
[](auto)
{
}
}, m_variant);
}
template <typename Default, typename... Visitee>
constexpr auto visit_value(Default&& default_value, Visitee&&... visitees) -> decltype(auto)
{
return std::visit(lambda_visitor{
std::forward<Visitee>(visitees)...,
[default_value=std::forward<Default>(default_value)](auto&& value)
{
return std::forward<decltype(value)>(value);
}
});
}
template <typename Default, typename... Visitee>
constexpr auto visit_lambda(Default&& default_lambda, Visitee&&... visitees) -> decltype(auto)
{
return std::visit(lambda_visitor{
std::forward<Visitee>(visitees)...,
[default_lambda=std::forward<Default>(default_lambda)](auto&& value)
{
return std::forward<Default>(default_lambda)(std::forward<decltype(value)>(value));
}
});
}
template <size_t I> template <size_t I>
[[nodiscard]] constexpr bool has_index() const noexcept [[nodiscard]] constexpr bool has_index() const noexcept
{ {
@ -255,33 +315,32 @@ namespace blt
namespace detail namespace detail
{ {
template<typename> template <typename>
class variant_is_base_of class variant_is_base_of
{}; {
};
template<typename... Types> template <typename... Types>
class variant_is_base_of<variant_t<Types...>> class variant_is_base_of<variant_t<Types...>>
{ {
public: public:
template<typename T> using value_type = bool;
template <typename T>
static constexpr bool value = std::conjunction_v<std::is_base_of<T, Types>...>; static constexpr bool value = std::conjunction_v<std::is_base_of<T, Types>...>;
}; };
template<typename... Types> template <typename... Types>
class variant_is_base_of<std::variant<Types...>> class variant_is_base_of<std::variant<Types...>>
{ {
public: public:
template<typename T> using value_type = bool;
template <typename T>
static constexpr bool value = std::conjunction_v<std::is_base_of<T, Types>...>; static constexpr bool value = std::conjunction_v<std::is_base_of<T, Types>...>;
}; };
template<typename T> template <typename T>
static constexpr bool variant_is_base_of_v = variant_is_base_of<T>::value; static constexpr bool variant_is_base_of_v = variant_is_base_of<T>::value;
} }
template<typename Variant_t, typename... Subclasses>
class variant_wrapper_t : public Subclasses...
{};
} }
#endif //BLT_STD_VARIANT_H #endif //BLT_STD_VARIANT_H