basic custom variant fixing some issues with the STL. currently unstable and untested.
parent
2bac310e55
commit
f245b7531e
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -257,12 +317,14 @@ namespace blt
|
||||||
{
|
{
|
||||||
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:
|
||||||
|
using value_type = bool;
|
||||||
template <typename T>
|
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>...>;
|
||||||
};
|
};
|
||||||
|
@ -271,6 +333,7 @@ namespace blt
|
||||||
class variant_is_base_of<std::variant<Types...>>
|
class variant_is_base_of<std::variant<Types...>>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using value_type = bool;
|
||||||
template <typename T>
|
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>...>;
|
||||||
};
|
};
|
||||||
|
@ -278,10 +341,6 @@ namespace blt
|
||||||
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
|
||||||
|
|
Loading…
Reference in New Issue