Resolved issues with universal references in construction and assignment.

Added 'in_place' structures.
Added etl::overload.
Updated sanity check cmake files.
Added alignment for const void.
This commit is contained in:
John Wellbelove 2021-07-11 20:36:01 +01:00
parent 0b321d21e8
commit c54bf63a76
20 changed files with 1411 additions and 303 deletions

View File

@ -232,7 +232,6 @@ namespace etl
}
//***************************************************************************
template <typename TFunction >
class binder2nd : public etl::unary_function<typename TFunction::first_argument_type, typename TFunction::result_type>
{

View File

@ -781,6 +781,7 @@ namespace etl
/// Specialisation of 'alignment_of' for 'void'.
///\ingroup type_traits
template <> struct alignment_of<void> : integral_constant <size_t, 0> {};
template <> struct alignment_of<const void> : integral_constant <size_t, 0> {};
#if ETL_CPP17_SUPPORTED
template <typename T>

View File

@ -32,46 +32,23 @@ SOFTWARE.
#define ETL_OVERLOAD_INCLUDED
#include "platform.h"
#include "utility.h"
#include "type_traits.h"
namespace etl
{
#if ETL_CPP11_SUPPORTED
#if ETL_CPP17_SUPPORTED && !defined(ETL_OVERLOAD_FORCE_CPP11)
#if ETL_CPP14_SUPPORTED
#if ETL_CPP17_SUPPORTED && !defined(ETL_OVERLOAD_FORCE_CPP14)
//*************************************************************************
/// Variadic template definition of overload.
/// Variadic template definition of overload for C++17 and above.
//*************************************************************************
template<class... TOverloads>
template<typename... TOverloads>
struct overload : TOverloads...
{
using TOverloads::operator()...;
};
//*************************************************************************
/// Template deduction guide.
//*************************************************************************
template<class... TOverloads> overload(TOverloads...)->overload<TOverloads...>;
#else
//*************************************************************************
/// Variadic template definition of overload.
//*************************************************************************
template <typename TOverload, typename... TOthers>
struct overload : TOverload, overload<TOthers...>
{
using TOverload::operator();
using overload<TOthers...>::operator();
};
//*************************************************************************
/// Template specialisation of overload for one type.
//*************************************************************************
template <typename TOverload>
struct overload<TOverload> : TOverload
{
using TOverload::operator();
};
#endif
//*************************************************************************
/// Make an overload.
//*************************************************************************
@ -80,7 +57,75 @@ namespace etl
{
return overload<TOverloads...>{ etl::forward<TOverloads>(overloads)... };
}
}
//*************************************************************************
/// Template deduction guide.
//*************************************************************************
template<typename... TOverloads> overload(TOverloads...)->overload<TOverloads...>;
#else
//*************************************************************************
/// Variadic template definition of overload for C++14.
//*************************************************************************
//namespace private_overload
//{
// //***********************************
// // Overload helper templates.
// //***********************************
// template <typename... TOverloads>
// struct overload_helper;
// template <>
// struct overload_helper<>
// {
// };
// template <typename TFirst, typename... TOthers>
// struct overload_helper<TFirst, TOthers...> : TFirst, overload_helper<TOthers...>
// {
// using TFirst::operator();
// template <typename UFirst, typename... UOthers>
// overload_helper(UFirst&& u, UOthers&&... others)
// : TFirst{ etl::forward<UFirst>(u) }, overload_helper<TOthers...>{ etl::forward<UOthers>(others)... }
// {
// }
// };
//}
////***********************************
///// Make an overload.
////***********************************
//template <typename... TOverloads>
//constexpr auto make_overload(TOverloads&&... overloads)
//{
// return private_overload::overload_helper<TOverloads...>{ etl::forward<TOverloads>(overloads)... };
//}
template <typename TFirst, typename... TOthers>
struct overload : TFirst, overload<TOthers...>
{
using TFirst::operator();
using overload<TOthers...>::operator();
};
template <typename TFirst> struct overload<TFirst> : TFirst
{
using TFirst::operator();
};
//*************************************************************************
/// Make an overload.
//*************************************************************************
template <typename... TOthers>
constexpr auto make_overload(TOthers&&... overloads)
{
return overload<TOthers...>{ etl::forward<TOthers>(overloads)... };
}
#endif
#endif
}
#endif

View File

@ -43,57 +43,19 @@ SOFTWARE.
#include "../parameter_pack.h"
#include "../placement_new.h"
#include "../visitor.h"
#include <utility>
#include "../memory.h"
#if defined(ETL_COMPILER_KEIL)
#pragma diag_suppress 940
#pragma diag_suppress 111
#endif
namespace etl
{
//template <typename T, T... Integers>
//class integer_sequence
//{
//public:
//
// ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Integral types only");
// typedef T value_type;
//
// static ETL_CONSTEXPR size_t size() ETL_NOEXCEPT
// {
// return sizeof...(Integers);
// }
//};
//namespace private_integer_sequence
//{
// template <size_t N, typename IndexSeq>
// struct make_index_sequence;
// template <size_t N, size_t... Indices>
// struct make_index_sequence<N, integer_sequence<size_t, Indices...>>
// {
// typedef typename make_index_sequence<N - 1, integer_sequence<size_t, N - 1, Indices...>>::type type;
// };
// template <size_t... Indices>
// struct make_index_sequence<0, integer_sequence<size_t, Indices...>>
// {
// typedef integer_sequence<size_t, Indices...> type;
// };
//}
//template <size_t N>
//using make_index_sequence = typename private_integer_sequence::make_index_sequence<N, integer_sequence<size_t>>::type;
//template <size_t... Indices>
//using index_sequence = integer_sequence<size_t, Indices...>;
}
#if ETL_CPP11_NOT_SUPPORTED
#if !defined(ETL_IN_UNIT_TEST)
#error NOT SUPPORTED FOR C++03 OR BELOW
#endif
#else
//*****************************************************************************
///\defgroup variant variant
/// A class that can contain one a several specified types in a type safe manner.
@ -102,10 +64,95 @@ namespace etl
namespace etl
{
static_assert(ETL_CPP11_SUPPORTED, "Only supported for C++11 or above");
namespace private_variant
{
//***************************************************************************
// This is a copy of the normal etl::parameter_pack, but without the static_assert
// so that the C++11 versions of do_accept() & do_operator() do not throw a compile time error.
//***************************************************************************
template <typename... TTypes>
class parameter_pack
{
public:
static constexpr size_t size = sizeof...(TTypes);
//***************************************************************************
/// index_of_type
//***************************************************************************
template <typename T>
class index_of_type
{
private:
using type = etl::remove_reference_t<T>;
//***********************************
template <typename Type, typename T1, typename... TRest>
struct index_of_type_helper
{
static constexpr size_t value = etl::is_same<Type, T1>::value ? 1 : 1 + index_of_type_helper<Type, TRest...>::value;
};
//***********************************
template <typename Type, typename T1>
struct index_of_type_helper<Type, T1>
{
static constexpr size_t value = 1;
};
public:
static_assert(etl::is_one_of_v<type, TTypes...>, "T is not in parameter pack");
/// The index value.
static constexpr size_t value = index_of_type_helper<type, TTypes...>::value - 1;
};
//***************************************************************************
/// type_from_index
//***************************************************************************
template <size_t I>
class type_from_index
{
private:
//***********************************
template <size_t II, size_t N, typename T1, typename... TRest>
struct type_from_index_helper
{
using type = typename etl::conditional<II == N, T1, typename type_from_index_helper<II, N + 1, TRest...>::type>::type;
};
//***********************************
template <size_t II, size_t N, typename T1>
struct type_from_index_helper<II, N, T1>
{
using type = T1;
};
public:
/// Template alias
using type = typename type_from_index_helper<I, 0, TTypes...>::type;
};
//***********************************
template <size_t I>
using type_from_index_t = typename type_from_index<I>::type;
};
}
/// Definition of variant_npos.
constexpr size_t variant_npos = etl::integral_limits<size_t>::max;
// Forward declarations.
template <typename... TTypes>
class variant;
template <typename T, typename... TTypes>
ETL_CONSTEXPR14 bool holds_alternative(const etl::variant<TTypes...>& v) noexcept;
//***************************************************************************
/// Monostate for variants.
///\ingroup variant
@ -142,7 +189,7 @@ namespace etl
{
public:
variant_incorrect_type_exception(string_type file_name_, numeric_type line_number_)
: variant_exception(ETL_ERROR_TEXT("variant: unsupported type", ETL_VARIANT_FILE_ID"A"), file_name_, line_number_)
: variant_exception(ETL_ERROR_TEXT("variant:unsupported type", ETL_VARIANT_FILE_ID"A"), file_name_, line_number_)
{
}
};
@ -167,9 +214,8 @@ namespace etl
// The type of actions we can perform.
enum class action_type : char
{
Construct,
Destruct,
Move
Create,
Destroy
};
// All types of variant are friends.
@ -197,48 +243,113 @@ namespace etl
/// The internal storage.
/// Aligned on a suitable boundary, which should be good for all types.
//***************************************************************************
typename etl::aligned_storage<Size, Alignment>::type data;
etl::uninitialized_buffer<Size, 1U, Alignment> data;
//***************************************************************************
/// Default constructor.
/// Sets the state of the instance to containing no valid data.
//***************************************************************************
constexpr variant()
ETL_CONSTEXPR14 variant()
: data()
{
using type = typename etl::parameter_pack<TTypes...>::template type_from_index<0>::type;
using type = typename etl::private_variant::parameter_pack<TTypes...>::template type_from_index<0>::type;
type temp;
operation = do_operation<type>;
operation(action_type::Construct, data, &temp);
operation = do_operation_default_construct<type>;
operation(action_type::Create, data, nullptr);
type_id = 0;
}
//***************************************************************************
/// Constructor for lvalues
/// Constructor from a value.
//***************************************************************************
template <typename T>
constexpr variant(const T& value)
template <typename T, etl::enable_if_t<!etl::is_same<etl::remove_reference_t<T>, variant>::value, int> = 0>
ETL_CONSTEXPR14 variant(T&& value)
: data()
, operation(do_operation<T>)
, type_id(etl::parameter_pack<TTypes...>::template index_of_type<T>::value)
, operation(operation_type<T, etl::is_rvalue_reference<decltype(value)>::value>::do_operation)
, type_id(etl::private_variant::parameter_pack<TTypes...>::template index_of_type<etl::remove_reference_t<T>>::value)
{
static_assert(etl::is_one_of<T, TTypes...>::value, "Unsupported type");
static_assert(etl::is_one_of<etl::remove_reference_t<T>, TTypes...>::value, "Unsupported type");
operation(action_type::Construct, data, &const_cast<T&>(value));
operation(action_type::Create, data, &value);
}
//***************************************************************************
/// Construct from arguments.
//***************************************************************************
template <typename T, typename... TArgs>
ETL_CONSTEXPR14 explicit variant(etl::in_place_type_t<T>, TArgs&&... args)
: data()
, type_id(etl::private_variant::parameter_pack<TTypes...>::template index_of_type<etl::remove_reference_t<T>>::value)
{
T temp(std::forward<TArgs>(args)...);
operation = operation_type<T, etl::is_rvalue_reference<decltype(temp)>::value>::do_operation;
operation(action_type::Create, data, &temp);
}
//***************************************************************************
/// Construct from arguments.
//***************************************************************************
template <size_t Index, typename... TArgs>
ETL_CONSTEXPR14 explicit variant(etl::in_place_index_t<Index>, TArgs&&... args)
: data()
{
using type = private_variant::parameter_pack<TTypes...>::type_from_index_t<Index>;
type temp(std::forward<TArgs>(args)...);
operation = operation_type<type, etl::is_rvalue_reference<decltype(temp)>::value>::do_operation;
operation(action_type::Create, data, &temp);
type_id = Index;
}
//***************************************************************************
/// Copy constructor.
///\param other The other variant object to copy.
//***************************************************************************
constexpr variant(const variant& other)
ETL_CONSTEXPR14 variant(const variant& other)
: data()
, operation(other.operation)
, type_id(other.type_id)
{
operation(action_type::Construct, data, other.data);
if (this != &other)
{
if (other.index() == variant_npos)
{
type_id = variant_npos;
}
else
{
operation(action_type::Create, data, other.data);
}
}
}
//***************************************************************************
/// Move constructor.
///\param other The other variant object to copy.
//***************************************************************************
ETL_CONSTEXPR14 variant(variant&& other)
: data()
, operation(other.operation)
, type_id(other.type_id)
{
if (this != &other)
{
if (other.index() == variant_npos)
{
type_id = variant_npos;
}
else
{
operation(action_type::Create, data, other.data);
}
}
else
{
type_id = variant_npos;
}
}
//***************************************************************************
@ -246,9 +357,12 @@ namespace etl
//***************************************************************************
~variant()
{
operation(action_type::Destruct, data, nullptr);
operation = null_operation;
if (index() != variant_npos)
{
operation(action_type::Destroy, data, nullptr);
}
operation = null_operation;
type_id = variant_npos;
}
@ -260,33 +374,32 @@ namespace etl
{
static_assert(etl::is_one_of<T, TTypes...>::value, "Unsupported type");
operation(action_type::Destruct, data, nullptr);
operation = do_operation<T>;
operation(action_type::Destroy, data, nullptr);
T temp(etl::forward<TArgs>(args)...);
operation(action_type::Construct, data, &temp);
operation = operation_type<T, etl::is_rvalue_reference<decltype(temp)>::value>::do_operation;
operation(action_type::Create, data, &temp);
type_id = etl::parameter_pack<TTypes...>::template index_of_type<T>::value;
type_id = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
return *static_cast<T*>(data);
}
//***************************************************************************
/// Assignment operator for type.
/// Move assignment operator for type.
///\param value The value to assign.
//***************************************************************************
template <typename T>
variant& operator =(const T& value)
template <typename T, etl::enable_if_t<!etl::is_same_v<etl::remove_reference_t<T>, variant>, int> = 0>
variant& operator =(T&& value)
{
static_assert(etl::is_one_of<T, TTypes...>::value, "Unsupported type");
static_assert(etl::is_one_of<etl::remove_reference_t<T>, TTypes...>::value, "Unsupported type");
operation(action_type::Destruct, data, nullptr);
operation(action_type::Destroy, data, nullptr);
operation = do_operation<T>;
operation(action_type::Construct, data, &value);
operation = operation_type<T, etl::is_rvalue_reference<decltype(value)>::value>::do_operation;
operation(action_type::Create, data, &value);
type_id = etl::parameter_pack<TTypes...>::template index_of_type<T>::value;
type_id = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
return *this;
}
@ -299,12 +412,45 @@ namespace etl
{
if (this != &other)
{
operation(action_type::Destruct, data, nullptr);
if (other.index() == variant_npos)
{
type_id = variant_npos;
}
else
{
operation(action_type::Destroy, data, nullptr);
operation = other.operation;
operation(action_type::Construct, data, other.data);
operation = other.operation;
operation(action_type::Create, data, other.data);
type_id = other.type_id;
type_id = other.type_id;
}
}
return *this;
}
//***************************************************************************
/// Assignment operator for variant type.
///\param other The variant to assign.
//***************************************************************************
variant& operator =(variant&& other)
{
if (this != &other)
{
if (other.index() == variant_npos)
{
type_id = variant_npos;
}
else
{
operation(action_type::Destroy, data, nullptr);
operation = other.operation;
operation(action_type::Create, data, other.data);
type_id = other.type_id;
}
}
return *this;
@ -316,7 +462,7 @@ namespace etl
//***************************************************************************
constexpr bool valueless_by_exception() const noexcept
{
return type_id != variant_npos;
return type_id == variant_npos;
}
//***************************************************************************
@ -337,41 +483,17 @@ namespace etl
rhs = temp;
}
//***************************************************************************
/// Gets the value stored as the specified template type.
/// Throws a variant_incorrect_type_exception if the actual type is not that specified.
///\return A reference to the value.
//***************************************************************************
template <typename T>
T& get()
{
static_assert(etl::is_one_of<T, TTypes...>::value, "Unsupported type");
ETL_ASSERT(etl::holds_alternative<T>(*this), ETL_ERROR(variant_incorrect_type_exception));
return static_cast<T&>(data);
}
//***************************************************************************
/// Gets the value stored as the specified template type.
/// Throws a variant_incorrect_type_exception if the actual type is not that specified.
///\return A const reference to the value.
//***************************************************************************
template <typename T>
const T& get() const
{
static_assert(etl::is_one_of<T, TTypes...>::value, "Unsupported type");
ETL_ASSERT(is_type<T>(), ETL_ERROR(variant_incorrect_type_exception));
return static_cast<const T&>(data);
}
//***************************************************************************
/// Accept an etl::visitor.
//***************************************************************************
template <typename... Types>
void accept(etl::visitor<TTypes...>& v)
{
do_accept(v, std::make_index_sequence<sizeof...(TTypes)>{});
#if ETL_CPP17_SUPPORTED && !defined(ETL_VARIANT_FORCE_CPP11)
do_accept(v, etl::make_index_sequence<sizeof...(TTypes)>{});
#else
do_accept(v);
#endif
}
//***************************************************************************
@ -380,48 +502,168 @@ namespace etl
template <typename TVisitor>
void operator()(TVisitor& v)
{
do_operator(v, std::make_index_sequence<sizeof...(TTypes)>{});
#if ETL_CPP17_SUPPORTED && !defined(ETL_VARIANT_FORCE_CPP11)
do_operator(v, etl::make_index_sequence<sizeof...(TTypes)>{});
#else
do_operator(v);
#endif
}
private:
using operation_type = void(*)(action_type, void*, const void*);
using operation_function = void(*)(action_type, void*, const void*);
//***************************************************************************
/// Do an operation determined by type.
//***************************************************************************
template <typename T, typename... TArgs>
static void do_operation(action_type action, void* pstorage, const void* pvalue)
template <typename T>
static void do_operation_default_construct(action_type action, void* pstorage, const void* pvalue)
{
switch (action)
{
case action_type::Construct:
{
::new (pstorage) T(*reinterpret_cast<const T*>(pvalue));
break;
}
case action_type::Create:
{
::new (pstorage) T();
break;
}
case action_type::Destruct:
{
reinterpret_cast<T*>(pstorage)->~T();
break;
}
case action_type::Destroy:
{
reinterpret_cast<const T*>(pstorage)->~T();
break;
}
default:
{
break;
}
default:
{
break;
}
}
}
// Declaration.
template <typename T, bool IsRValueRef>
struct operation_type;
// Specialisation for lvalue rreferences
template <typename T>
struct operation_type<T, false>
{
static void do_operation(variant::action_type action, void* pstorage, const void* pvalue)
{
using type = etl::remove_reference_t<T>;
switch (action)
{
case variant::action_type::Create:
{
::new (pstorage) type(*reinterpret_cast<const type*>(pvalue));
break;
}
case variant::action_type::Destroy:
{
reinterpret_cast<const type*>(pstorage)->~type();
break;
}
default:
{
break;
}
}
}
};
// Specialisation for rvalue rreferences
template <typename T>
struct operation_type<T, true>
{
static void do_operation(variant::action_type action, void* pstorage, const void* pvalue)
{
using type = etl::remove_reference_t<T>;
switch (action)
{
case variant::action_type::Create:
{
::new (pstorage) type(etl::move(*reinterpret_cast<type*>(const_cast<void*>(pvalue))));
break;
}
case variant::action_type::Destroy:
{
reinterpret_cast<const type*>(pstorage)->~type();
break;
}
default:
{
break;
}
}
}
};
#if ETL_CPP17_SUPPORTED && !defined(ETL_VARIANT_FORCE_CPP11)
//***************************************************************************
/// Loop through the types until a match is found.
/// Call the relevent visitor by attemptng each one.
//***************************************************************************
template <typename TVisitor, size_t... I>
void do_accept(TVisitor& visitor, std::index_sequence<I...>)
void do_accept(TVisitor& visitor, etl::index_sequence<I...>)
{
(attempt_visitor<I>(visitor) || ...);
}
#else
//***************************************************************************
/// /// Call the relevent visitor.
//***************************************************************************
template <typename TVisitor>
void do_accept(TVisitor& visitor)
{
switch (index())
{
case 0: visitor.visit(etl::get<0>(*this)); break;
case 1: visitor.visit(etl::get<1>(*this)); break;
case 2: visitor.visit(etl::get<2>(*this)); break;
case 3: visitor.visit(etl::get<3>(*this)); break;
case 4: visitor.visit(etl::get<4>(*this)); break;
case 5: visitor.visit(etl::get<5>(*this)); break;
case 6: visitor.visit(etl::get<6>(*this)); break;
case 7: visitor.visit(etl::get<7>(*this)); break;
#if !defined(ETL_VARIANT_CPP11_MAX_8_TYPES)
case 8: visitor.visit(etl::get<8>(*this)); break;
case 9: visitor.visit(etl::get<9>(*this)); break;
case 10: visitor.visit(etl::get<10>(*this)); break;
case 11: visitor.visit(etl::get<11>(*this)); break;
case 12: visitor.visit(etl::get<12>(*this)); break;
case 13: visitor.visit(etl::get<13>(*this)); break;
case 14: visitor.visit(etl::get<14>(*this)); break;
case 15: visitor.visit(etl::get<15>(*this)); break;
#if !defined(ETL_VARIANT_CPP11_MAX_16_TYPES)
case 16: visitor.visit(etl::get<16>(*this)); break;
case 17: visitor.visit(etl::get<17>(*this)); break;
case 18: visitor.visit(etl::get<18>(*this)); break;
case 19: visitor.visit(etl::get<19>(*this)); break;
case 20: visitor.visit(etl::get<20>(*this)); break;
case 21: visitor.visit(etl::get<21>(*this)); break;
case 22: visitor.visit(etl::get<22>(*this)); break;
case 23: visitor.visit(etl::get<23>(*this)); break;
#if !defined(ETL_VARIANT_CPP11_MAX_24_TYPES)
case 24: visitor.visit(etl::get<24>(*this)); break;
case 25: visitor.visit(etl::get<25>(*this)); break;
case 26: visitor.visit(etl::get<26>(*this)); break;
case 27: visitor.visit(etl::get<27>(*this)); break;
case 28: visitor.visit(etl::get<28>(*this)); break;
case 29: visitor.visit(etl::get<29>(*this)); break;
case 30: visitor.visit(etl::get<30>(*this)); break;
case 31: visitor.visit(etl::get<31>(*this)); break;
#endif
#endif
#endif
default: break;
}
}
#endif
//***************************************************************************
/// Attempt to call a visitor.
@ -440,14 +682,78 @@ namespace etl
}
}
#if ETL_CPP17_SUPPORTED && !defined(ETL_VARIANT_FORCE_CPP11)
//***************************************************************************
/// Loop through the types until a match is found.
/// Call the relevent visitor by attemptng each one.
//***************************************************************************
template <typename TVisitor, size_t... I>
void do_operator(TVisitor& visitor, std::index_sequence<I...>)
void do_operator(TVisitor& visitor, etl::index_sequence<I...>)
{
(attempt_operator<I>(visitor) || ...);
}
#else
//***************************************************************************
/// Call the relevent visitor.
//***************************************************************************
template <typename TVisitor>
void do_operator(TVisitor& visitor)
{
#if defined(ETL_VARIANT_CPP11_MAX_8_TYPES)
ETL_STATIC_ASSERT(sizeof...(TTypes) <= 8U, "???");
#endif
#if defined(ETL_VARIANT_CPP11_MAX_16_TYPES)
ETL_STATIC_ASSERT(sizeof...(TTypes) <= 16U, "???");
#endif
#if defined(ETL_VARIANT_CPP11_MAX_24_TYPES)
ETL_STATIC_ASSERT(sizeof...(TTypes) <= 24U, "???");
#endif
switch (index())
{
case 0: visitor(etl::get<0>(*this)); break;
case 1: visitor(etl::get<1>(*this)); break;
case 2: visitor(etl::get<2>(*this)); break;
case 3: visitor(etl::get<3>(*this)); break;
case 4: visitor(etl::get<4>(*this)); break;
case 5: visitor(etl::get<5>(*this)); break;
case 6: visitor(etl::get<6>(*this)); break;
case 7: visitor(etl::get<7>(*this)); break;
#if !defined(ETL_VARIANT_CPP11_MAX_8_TYPES)
case 8: visitor(etl::get<8>(*this)); break;
case 9: visitor(etl::get<9>(*this)); break;
case 10: visitor(etl::get<10>(*this)); break;
case 11: visitor(etl::get<11>(*this)); break;
case 12: visitor(etl::get<12>(*this)); break;
case 13: visitor(etl::get<13>(*this)); break;
case 14: visitor(etl::get<14>(*this)); break;
case 15: visitor(etl::get<15>(*this)); break;
#if !defined(ETL_VARIANT_CPP11_MAX_16_TYPES)
case 16: visitor(etl::get<16>(*this)); break;
case 17: visitor(etl::get<17>(*this)); break;
case 18: visitor(etl::get<18>(*this)); break;
case 19: visitor(etl::get<19>(*this)); break;
case 20: visitor(etl::get<20>(*this)); break;
case 21: visitor(etl::get<21>(*this)); break;
case 22: visitor(etl::get<22>(*this)); break;
case 23: visitor(etl::get<23>(*this)); break;
#if !defined(ETL_VARIANT_CPP11_MAX_24_TYPES)
case 24: visitor(etl::get<24>(*this)); break;
case 25: visitor(etl::get<25>(*this)); break;
case 26: visitor(etl::get<26>(*this)); break;
case 27: visitor(etl::get<27>(*this)); break;
case 28: visitor(etl::get<28>(*this)); break;
case 29: visitor(etl::get<29>(*this)); break;
case 30: visitor(etl::get<30>(*this)); break;
case 31: visitor(etl::get<31>(*this)); break;
#endif
#endif
#endif
default: break;
}
}
#endif
//***************************************************************************
/// Attempt to call a visitor.
@ -477,7 +783,7 @@ namespace etl
//***************************************************************************
/// The operation function.
//***************************************************************************
operation_type operation;
operation_function operation;
//***************************************************************************
/// The id of the current stored type.
@ -489,9 +795,9 @@ namespace etl
/// Checks if the variant v holds the alternative T.
//***************************************************************************
template <typename T, typename... TTypes>
constexpr bool holds_alternative(const etl::variant<TTypes...>& v) noexcept
ETL_CONSTEXPR14 bool holds_alternative(const etl::variant<TTypes...>& v) noexcept
{
constexpr size_t Index = etl::parameter_pack<TTypes...>::template index_of_type<T>::value;
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
return (Index == variant_npos) ? false : (v.index() == Index);
}
@ -505,7 +811,7 @@ namespace etl
template <size_t Index, typename... TTypes>
struct variant_alternative<Index, etl::variant<TTypes...>>
{
using type = typename etl::parameter_pack<TTypes...>::template type_from_index<Index>::type;
using type = typename etl::private_variant::parameter_pack<TTypes...>::template type_from_index<Index>::type;
};
template <size_t Index, typename T>
@ -521,10 +827,13 @@ namespace etl
/// get
//***************************************************************************
template <size_t Index, typename... TTypes>
constexpr etl::variant_alternative_t<Index, etl::variant<TTypes...>>&
ETL_CONSTEXPR14 etl::variant_alternative_t<Index, etl::variant<TTypes...>>&
get(etl::variant<TTypes...>& v)
{
//static_assert(Index < sizeof...(TTypes), "Index out of range");
#if ETL_CPP17_SUPPORTED && !defined(ETL_VARIANT_FORCE_CPP11)
static_assert(Index < sizeof...(TTypes), "Index out of range");
#endif
ETL_ASSERT(Index == v.index(), ETL_ERROR(etl::variant_incorrect_type_exception));
using type = etl::variant_alternative_t<Index, etl::variant<TTypes...>>;
@ -534,10 +843,12 @@ namespace etl
//***********************************
template <size_t Index, typename... TTypes>
constexpr etl::variant_alternative_t<Index, etl::variant<TTypes...>>&&
ETL_CONSTEXPR14 etl::variant_alternative_t<Index, etl::variant<TTypes...>>&&
get(etl::variant<TTypes...>&& v)
{
#if ETL_CPP17_SUPPORTED && !defined(ETL_VARIANT_FORCE_CPP11)
static_assert(Index < sizeof...(TTypes), "Index out of range");
#endif
using type = etl::variant_alternative_t<Index, etl::variant<TTypes...>>;
@ -546,10 +857,13 @@ namespace etl
//***********************************
template <size_t Index, typename... TTypes>
constexpr const etl::variant_alternative_t<Index, const etl::variant<TTypes...>>&
ETL_CONSTEXPR14 const etl::variant_alternative_t<Index, const etl::variant<TTypes...>>&
get(const etl::variant<TTypes...>& v)
{
#if ETL_CPP17_SUPPORTED && !defined(ETL_VARIANT_FORCE_CPP11)
static_assert(Index < sizeof...(TTypes), "Index out of range");
#endif
ETL_ASSERT(Index == v.index(), ETL_ERROR(etl::variant_incorrect_type_exception));
using type = etl::variant_alternative_t<Index, etl::variant<TTypes...>>;
@ -559,10 +873,13 @@ namespace etl
//***********************************
template <size_t Index, typename... TTypes>
constexpr const etl::variant_alternative_t<Index, const etl::variant<TTypes...>>&&
ETL_CONSTEXPR14 const etl::variant_alternative_t<Index, const etl::variant<TTypes...>>&&
get(const etl::variant<TTypes...>&& v)
{
#if ETL_CPP17_SUPPORTED & !defined(ETL_VARIANT_FORCE_CPP11)
static_assert(Index < sizeof...(TTypes), "Index out of range");
#endif
ETL_ASSERT(Index == v.index(), ETL_ERROR(etl::variant_incorrect_type_exception));
using type = etl::variant_alternative_t<Index, etl::variant<TTypes...>>;
@ -572,45 +889,45 @@ namespace etl
//***********************************
template <typename T, typename... TTypes>
constexpr T& get(etl::variant<TTypes...>& v)
ETL_CONSTEXPR14 T& get(etl::variant<TTypes...>& v)
{
constexpr size_t Index = etl::parameter_pack<TTypes...>::template index_of_type<T>::value;
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
return get<Index>(v);
}
//***********************************
template <typename T, typename... TTypes>
constexpr T&& get(etl::variant<TTypes...>&& v)
ETL_CONSTEXPR14 T&& get(etl::variant<TTypes...>&& v)
{
constexpr size_t Index = etl::parameter_pack<TTypes...>::template index_of_type<T>::value;
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
return get<Index>(v);
}
//***********************************
template <typename T, typename... TTypes>
constexpr const T& get(const etl::variant<TTypes...>& v)
ETL_CONSTEXPR14 const T& get(const etl::variant<TTypes...>& v)
{
constexpr size_t Index = etl::parameter_pack<TTypes...>::template index_of_type<T>::value;
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
return get<Index>(v);
}
//***********************************
template <typename T, typename... TTypes>
constexpr const T&& get(const etl::variant<TTypes...>&& v)
ETL_CONSTEXPR14 const T&& get(const etl::variant<TTypes...>&& v)
{
constexpr size_t Index = etl::parameter_pack<TTypes...>::template index_of_type<T>::value;
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
return get<Index>(v);
}
//***************************************************************************
/// get_if
/// get_if (pointer parameter)
//***************************************************************************
template < size_t Index, typename... TTypes >
constexpr etl::add_pointer_t<etl::variant_alternative_t<Index, etl::variant<TTypes...>>>
ETL_CONSTEXPR14 etl::add_pointer_t<etl::variant_alternative_t<Index, etl::variant<TTypes...>>>
get_if(etl::variant<TTypes...>* pv) noexcept
{
if ((pv != nullptr) && (pv->index() == Index))
@ -625,7 +942,7 @@ namespace etl
//***********************************
template< size_t Index, typename... TTypes >
constexpr etl::add_pointer_t<const etl::variant_alternative_t<Index, etl::variant<TTypes...>>>
ETL_CONSTEXPR14 etl::add_pointer_t<const etl::variant_alternative_t<Index, etl::variant<TTypes...>>>
get_if(const etl::variant<TTypes...>* pv) noexcept
{
if ((pv != nullptr) && (pv->index() == Index))
@ -640,22 +957,96 @@ namespace etl
//***********************************
template< class T, typename... TTypes >
constexpr etl::add_pointer_t<T> get_if(etl::variant<TTypes...>* pv) noexcept
ETL_CONSTEXPR14 etl::add_pointer_t<T> get_if(etl::variant<TTypes...>* pv) noexcept
{
constexpr size_t Index = etl::parameter_pack<TTypes...>::template index_of_type<T>::value;
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
return etl::get_if<Index>(pv);
}
//***********************************
template< class T, typename... TTypes >
constexpr etl::add_pointer_t<const T> get_if(const etl::variant<TTypes...>* pv) noexcept
ETL_CONSTEXPR14 etl::add_pointer_t<const T> get_if(const etl::variant<TTypes...>* pv) noexcept
{
constexpr size_t Index = etl::parameter_pack<TTypes...>::template index_of_type<T>::value;
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
return etl::get_if<Index>(pv);
}
//***************************************************************************
/// get_if (reference parameter)
//***************************************************************************
template < size_t Index, typename... TTypes >
ETL_CONSTEXPR14 etl::add_pointer_t<etl::variant_alternative_t<Index, etl::variant<TTypes...>>>
get_if(etl::variant<TTypes...>& v) noexcept
{
if (v.index() == Index)
{
return &etl::get<Index>(v);
}
else
{
return nullptr;
}
}
//***********************************
template< size_t Index, typename... TTypes >
ETL_CONSTEXPR14 etl::add_pointer_t<const etl::variant_alternative_t<Index, etl::variant<TTypes...>>>
get_if(const etl::variant<TTypes...>& v) noexcept
{
if (v.index() == Index)
{
return &etl::get<Index>(v);
}
else
{
return nullptr;
}
}
//***********************************
template< size_t Index, typename... TTypes >
ETL_CONSTEXPR14 etl::add_pointer_t<const etl::variant_alternative_t<Index, etl::variant<TTypes...>>>
get_if(etl::variant<TTypes...>&& v) noexcept
{
if (v.index() == Index)
{
return &etl::get<Index>(v);
}
else
{
return nullptr;
}
}
//***********************************
template< class T, typename... TTypes >
ETL_CONSTEXPR14 etl::add_pointer_t<T> get_if(etl::variant<TTypes...>& v) noexcept
{
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
return etl::get_if<Index>(v);
}
//***********************************
template< class T, typename... TTypes >
ETL_CONSTEXPR14 etl::add_pointer_t<const T> get_if(const etl::variant<TTypes...>& v) noexcept
{
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
return etl::get_if<Index>(v);
}
//***********************************
template< class T, typename... TTypes >
ETL_CONSTEXPR14 etl::add_pointer_t<const T> get_if(etl::variant<TTypes...>&& v) noexcept
{
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
return etl::get_if<Index>(v);
}
//***************************************************************************
/// swap
//***************************************************************************
@ -682,4 +1073,10 @@ namespace etl
: etl::integral_constant<size_t, variant_size<T>::value>
{
};
#if ETL_CPP17_SUPPORTED
template <typename... TTypes>
inline constexpr size_t variant_size_v = variant_size<TTypes...>::value;
#endif
}
#endif

View File

@ -769,6 +769,7 @@ namespace etl
/// Specialisation of 'alignment_of' for 'void'.
///\ingroup type_traits
template <> struct alignment_of<void> : integral_constant <size_t, 0> {};
template <> struct alignment_of<const void> : integral_constant <size_t, 0> {};
#if ETL_CPP17_SUPPORTED
template <typename T>

View File

@ -332,8 +332,55 @@ namespace etl
return t;
}
//******************************************************************************
//***************************************************************************
/// integer_sequence
//***************************************************************************
#if ETL_CPP11_SUPPORTED
template <typename T, T... Integers>
class integer_sequence
{
public:
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Integral types only");
typedef T value_type;
static ETL_CONSTEXPR size_t size() ETL_NOEXCEPT
{
return sizeof...(Integers);
}
};
namespace private_integer_sequence
{
template <size_t N, typename IndexSeq>
struct make_index_sequence;
template <size_t N, size_t... Indices>
struct make_index_sequence<N, etl::integer_sequence<size_t, Indices...>>
{
typedef typename make_index_sequence<N - 1, etl::integer_sequence<size_t, N - 1, Indices...>>::type type;
};
template <size_t... Indices>
struct make_index_sequence<0, etl::integer_sequence<size_t, Indices...>>
{
typedef etl::integer_sequence<size_t, Indices...> type;
};
}
//***********************************
template <size_t N>
using make_index_sequence = typename private_integer_sequence::make_index_sequence<N, etl::integer_sequence<size_t>>::type;
//***********************************
template <size_t... Indices>
using index_sequence = etl::integer_sequence<size_t, Indices...>;
#endif
//***************************************************************************
/// 2D coordinate type.
//***************************************************************************
template <typename T>
struct coordinate_2d
{
@ -362,6 +409,36 @@ namespace etl
T x;
T y;
};
//***************************************************************************
/// in_place disambiguation tags.
//***************************************************************************
//*************************
struct in_place_t
{
explicit ETL_CONSTEXPR in_place_t() {}
};
inline ETL_CONSTEXPR in_place_t in_place{};
//*************************
template <typename T> struct in_place_type_t
{
explicit ETL_CONSTEXPR in_place_type_t(){};
};
template <typename T>
inline ETL_CONSTEXPR in_place_type_t<T> in_place_type{};
//*************************
template <std::size_t I> struct in_place_index_t
{
explicit ETL_CONSTEXPR in_place_index_t() {}
};
template <std::size_t I>
inline ETL_CONSTEXPR in_place_index_t<I> in_place_index{};
}
#endif

View File

@ -31,7 +31,7 @@ SOFTWARE.
#ifndef ETL_VARIANT_INCLUDED
#define ETL_VARIANT_INCLUDED
#if 1 //ETL_USE_LEGACY_VARIANT
#if ETL_USE_LEGACY_VARIANT
#include "private/variant_legacy.h"
#else
#include "private/variant_new.h"

View File

@ -98,7 +98,9 @@ SOFTWARE.
#define ETL_MEM_CAST_FORCE_CPP03
#endif
//#define ETL_OVERLOAD_FORCE_CPP11
#define ETL_OVERLOAD_FORCE_CPP14
#define ETL_VARIANT_FORCE_CPP11
#define ETL_VARIANT_CPP11_MAX_16_TYPES
#if defined(ETL_NO_STL)
#define ETL_TIMER_SEMAPHORE_TYPE uint32_t

View File

@ -173,6 +173,7 @@ target_sources(t98 PRIVATE etl_profile.h
../numeric.h.t.cpp
../observer.h.t.cpp
../optional.h.t.cpp
../overload.h.t.cpp
../packet.h.t.cpp
../parameter_pack.h.t.cpp
../parameter_type.h.t.cpp
@ -242,7 +243,8 @@ target_sources(t98 PRIVATE etl_profile.h
../user_type.h.t.cpp
../utility.h.t.cpp
../variance.h.t.cpp
../variant.h.t.cpp
../variant_legacy.h.t.cpp
../variant_new.h.t.cpp
../variant_pool.h.t.cpp
../vector.h.t.cpp
../version.h.t.cpp

View File

@ -173,6 +173,7 @@ target_sources(t11 PRIVATE etl_profile.h
../numeric.h.t.cpp
../observer.h.t.cpp
../optional.h.t.cpp
../overload.h.t.cpp
../packet.h.t.cpp
../parameter_pack.h.t.cpp
../parameter_type.h.t.cpp
@ -242,7 +243,8 @@ target_sources(t11 PRIVATE etl_profile.h
../user_type.h.t.cpp
../utility.h.t.cpp
../variance.h.t.cpp
../variant.h.t.cpp
../variant_legacy.h.t.cpp
../variant_new.h.t.cpp
../variant_pool.h.t.cpp
../vector.h.t.cpp
../version.h.t.cpp

View File

@ -173,6 +173,7 @@ target_sources(t14 PRIVATE etl_profile.h
../numeric.h.t.cpp
../observer.h.t.cpp
../optional.h.t.cpp
../overload.h.t.cpp
../packet.h.t.cpp
../parameter_pack.h.t.cpp
../parameter_type.h.t.cpp
@ -242,7 +243,8 @@ target_sources(t14 PRIVATE etl_profile.h
../user_type.h.t.cpp
../utility.h.t.cpp
../variance.h.t.cpp
../variant.h.t.cpp
../variant_legacy.h.t.cpp
../variant_new.h.t.cpp
../variant_pool.h.t.cpp
../vector.h.t.cpp
../version.h.t.cpp

View File

@ -173,6 +173,7 @@ target_sources(t17 PRIVATE etl_profile.h
../numeric.h.t.cpp
../observer.h.t.cpp
../optional.h.t.cpp
../overload.h.t.cpp
../packet.h.t.cpp
../parameter_pack.h.t.cpp
../parameter_type.h.t.cpp
@ -242,7 +243,8 @@ target_sources(t17 PRIVATE etl_profile.h
../user_type.h.t.cpp
../utility.h.t.cpp
../variance.h.t.cpp
../variant.h.t.cpp
../variant_legacy.h.t.cpp
../variant_new.h.t.cpp
../variant_pool.h.t.cpp
../vector.h.t.cpp
../version.h.t.cpp

View File

@ -0,0 +1,29 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include <etl/overload.h>

View File

@ -0,0 +1,29 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include <etl/private/variant_legacy.h>

View File

@ -0,0 +1,29 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include <etl/private/variant_new.h>

View File

@ -0,0 +1,29 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include <etl/private/variant_old.h>

164
test/test_overload.cpp Normal file
View File

@ -0,0 +1,164 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2015 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "unit_test_framework.h"
#include "etl/overload.h"
#include <iostream>
namespace
{
struct Result
{
Result()
: bi(false)
, bd(false)
, bs(false)
{
}
void clear()
{
bi = false;
bd = false;
bs = false;
}
bool bi;
bool bd;
bool bs;
};
Result result;
struct Visitor
{
void operator ()(int i) { result.bi = true; }
void operator ()(double d) { result.bd = true; }
void operator ()(const std::string& s) { result.bs = true; }
};
template <typename T, typename TOverload>
void Function(T value, TOverload& ol)
{
ol(value);
}
SUITE(test_overload)
{
//*************************************************************************
TEST(test_overload_lambdas)
{
auto overload = etl::make_overload([](int i) { result.bi = true; },
[](double d) { result.bd = true; },
[](const std::string& s) { result.bs = true; });
result.clear();
Function(int(1), overload);
CHECK(result.bi == true);
CHECK(result.bd == false);
CHECK(result.bs == false);
result.clear();
Function(double(2.0), overload);
CHECK(result.bi == false);
CHECK(result.bd == true);
CHECK(result.bs == false);
result.clear();
Function(std::string("3"), overload);
CHECK(result.bi == false);
CHECK(result.bd == false);
CHECK(result.bs == true);
}
//*************************************************************************
TEST(test_overload_lambdas_cpp17)
{
#if !defined(ETL_OVERLOAD_FORCE_CPP14)
result.clear();
Function(int(1), etl::overload
{
[](int i) { result.bi = true; },
[](double d) { result.bd = true; },
[](const std::string& s) { result.bs = true; }
});
CHECK(result.bi == true);
CHECK(result.bd == false);
CHECK(result.bs == false);
result.clear();
Function(double(2.0), etl::overload
{
[](int i) { result.bi = true; },
[](double d) { result.bd = true; },
[](const std::string& s) { result.bs = true; }
});
CHECK(result.bi == false);
CHECK(result.bd == true);
CHECK(result.bs == false);
result.clear();
Function(std::string("3"), etl::overload
{
[](int i) { result.bi = true; },
[](double d) { result.bd = true; },
[](const std::string& s) { result.bs = true; }
});
CHECK(result.bi == false);
CHECK(result.bd == false);
CHECK(result.bs == true);
#endif
}
//*************************************************************************
TEST(test_visitor_overload)
{
auto overload = etl::make_overload(Visitor());
result.clear();
Function(int(1), overload);
CHECK(result.bi == true);
CHECK(result.bd == false);
CHECK(result.bs == false);
result.clear();
Function(double(2.0), overload);
CHECK(result.bi == false);
CHECK(result.bd == true);
CHECK(result.bs == false);
result.clear();
Function(std::string("3"), overload);
CHECK(result.bi == false);
CHECK(result.bd == false);
CHECK(result.bs == true);
}
};
}

View File

@ -36,11 +36,13 @@ SOFTWARE.
#include <algorithm>
#include <string>
#include <variant>
#include <type_traits>
namespace
{
// Test variant types.
typedef etl::variant<char, int, std::string> test_variant_3;
// Test variant_etl types.
using test_variant_etl_3 = etl::variant<char, int, std::string>;
using test_variant_std_3 = std::variant<char, int, std::string>;
struct D1
{
@ -162,6 +164,67 @@ namespace
typedef etl::variant<etl::monostate, D1, D2, D3, D4> test_variant_emplace;
//*********************************************
struct Copyable
{
Copyable()
: copied_from(false)
, copied_to(false)
{
}
Copyable(const Copyable& other) noexcept
{
copied_to = true;
copied_from = false;
}
Copyable& operator =(const Copyable& rhs) noexcept
{
copied_to = true;
copied_from = false;
return *this;
}
bool copied_from;
bool copied_to;
};
//*********************************************
struct Moveable
{
Moveable()
: moved_from(false)
, moved_to(false)
{
}
Moveable(Moveable&& other) noexcept
{
moved_to = true;
moved_from = false;
other.moved_to = false;
other.moved_from = true;
}
Moveable& operator =(Moveable&& rhs) noexcept
{
moved_to = true;
moved_from = false;
rhs.moved_to = false;
rhs.moved_from = true;
return *this;
}
Moveable(const Moveable& other) = delete;
Moveable& operator =(const Moveable& rhs) = delete;
bool moved_from;
bool moved_to;
};
SUITE(test_variant)
{
TEST(test_alignment)
@ -176,20 +239,20 @@ namespace
static test_variant_c c(3);
static test_variant_d d(4.5);
CHECK((uintptr_t(&a.get<char>()) % uintptr_t(etl::alignment_of<char>::value)) == 0);
CHECK((uintptr_t(&b.get<short>()) % uintptr_t(etl::alignment_of<short>::value)) == 0);
CHECK((uintptr_t(&c.get<int>()) % uintptr_t(etl::alignment_of<int>::value)) == 0);
CHECK((uintptr_t(&d.get<double>()) % uintptr_t(etl::alignment_of<double>::value)) == 0);
CHECK((uintptr_t(&etl::get<char>(a)) % uintptr_t(etl::alignment_of<char>::value)) == 0);
CHECK((uintptr_t(&etl::get<short>(b)) % uintptr_t(etl::alignment_of<short>::value)) == 0);
CHECK((uintptr_t(&etl::get<int>(c)) % uintptr_t(etl::alignment_of<int>::value)) == 0);
CHECK((uintptr_t(&etl::get<double>(d)) % uintptr_t(etl::alignment_of<double>::value)) == 0);
}
//*************************************************************************
TEST(test_constructor_default)
{
CHECK_NO_THROW(test_variant_3 variant);
CHECK_NO_THROW(test_variant_etl_3 variant_etl);
test_variant_3 variant;
test_variant_etl_3 variant_etl;
CHECK(etl::holds_alternative<char>(variant));
CHECK(etl::holds_alternative<char>(variant_etl));
}
//*************************************************************************
@ -197,24 +260,24 @@ namespace
{
// Char.
char c = 'a';
test_variant_3 variant_char(c);
CHECK(etl::holds_alternative<char>(variant_char));
CHECK_EQUAL(c, etl::get<char>(variant_char));
test_variant_etl_3 variant_char_etl(c);
CHECK(c == 'a');
CHECK(etl::holds_alternative<char>(variant_char_etl));
CHECK_EQUAL(c, etl::get<char>(variant_char_etl));
// Int.
int i = 1;
test_variant_3 variant_int(i);
CHECK(etl::holds_alternative<int>(variant_int));
CHECK_EQUAL(i, etl::get<int>(variant_int));
test_variant_etl_3 variant_int_etl(i);
CHECK(i == 1);
CHECK(etl::holds_alternative<int>(variant_int_etl));
CHECK_EQUAL(i, etl::get<int>(variant_int_etl));
// String.
std::string text("Some Text");
test_variant_3 variant_text(text);
CHECK(etl::holds_alternative<std::string>(variant_text));
CHECK_EQUAL(text, etl::get<std::string>(variant_text));
test_variant_etl_3 variant_text_etl(text);
CHECK(text == "Some Text");
CHECK(etl::holds_alternative<std::string>(variant_text_etl));
CHECK_EQUAL(text, etl::get<std::string>(variant_text_etl));
}
//*************************************************************************
@ -222,72 +285,122 @@ namespace
{
// Char.
char c = 'a';
test_variant_3 variant_char(etl::move(c));
CHECK(etl::holds_alternative<char>(variant_char));
CHECK_EQUAL(c, etl::get<char>(variant_char));
test_variant_etl_3 variant_char_etl(etl::move(c));
CHECK(etl::holds_alternative<char>(variant_char_etl));
CHECK_EQUAL(c, etl::get<char>(variant_char_etl));
// Int.
int i = 1;
test_variant_3 variant_int(etl::move(i));
CHECK(etl::holds_alternative<int>(variant_int));
CHECK_EQUAL(i, etl::get<int>(variant_int));
test_variant_etl_3 variant_int_etl(etl::move(i));
CHECK(etl::holds_alternative<int>(variant_int_etl));
CHECK_EQUAL(i, etl::get<int>(variant_int_etl));
// String.
std::string text("Some Text");
test_variant_3 variant_text(etl::move(text));
test_variant_etl_3 variant_text_etl(etl::move(text));
CHECK(etl::holds_alternative<std::string>(variant_text_etl));
CHECK_EQUAL(std::string("Some Text"), etl::get<std::string>(variant_text_etl));
}
CHECK(etl::holds_alternative<std::string>(variant_text));
CHECK_EQUAL(text, etl::get<std::string>(variant_text));
//*************************************************************************
TEST(test_emplace_value)
{
// Char.
char c = 'a';
test_variant_etl_3 variant_char_etl;
variant_char_etl.emplace<char>(c);
CHECK(c == 'a');
CHECK(etl::holds_alternative<char>(variant_char_etl));
CHECK_EQUAL(c, etl::get<char>(variant_char_etl));
// Int.
int i = 1;
test_variant_etl_3 variant_int_etl;
variant_int_etl.emplace<int>(i);
CHECK(i == 1);
CHECK(etl::holds_alternative<int>(variant_int_etl));
CHECK_EQUAL(i, etl::get<int>(variant_int_etl));
// String.
std::string text("Some Text");
test_variant_etl_3 variant_text_etl;
variant_text_etl.emplace<std::string>(text);
CHECK(text == "Some Text");
CHECK(etl::holds_alternative<std::string>(variant_text_etl));
CHECK_EQUAL(text, etl::get<std::string>(variant_text_etl));
}
//*************************************************************************
TEST(test_copy_constructor)
{
std::string text("Some Text");
test_variant_3 variant_1(text);
test_variant_etl_3 variant_1_etl(text);
test_variant_3 variant_2(variant_1);
test_variant_etl_3 variant_2_etl(variant_1_etl);
CHECK_EQUAL(variant_1.index(), variant_2.index());
CHECK_EQUAL(variant_1.get<std::string>(), variant_2.get<std::string>());
CHECK_EQUAL(variant_1_etl.index(), variant_2_etl.index());
CHECK_EQUAL(etl::get<std::string>(variant_1_etl), etl::get<std::string>(variant_2_etl));
}
//*************************************************************************
TEST(test_copy_constructor_from_empty)
{
std::string text("Some Text");
test_variant_etl_3 variant_1_etl;
test_variant_etl_3 variant_2_etl(variant_1_etl);
CHECK_EQUAL(variant_1_etl.index(), variant_2_etl.index());
}
//*************************************************************************
TEST(test_move_constructor)
{
std::string text("Some Text");
test_variant_3 variant_1(text);
test_variant_etl_3 variant_1_etl(text);
test_variant_3 variant_2(etl::move(variant_1));
test_variant_etl_3 variant_2_etl(etl::move(variant_1_etl));
CHECK_EQUAL(variant_1.index(), variant_2.index());
CHECK_EQUAL(variant_1.get<std::string>(), variant_2.get<std::string>());
CHECK_EQUAL(variant_1_etl.index(), variant_2_etl.index());
CHECK_EQUAL(etl::get<std::string>(variant_1_etl), etl::get<std::string>(variant_2_etl));
}
//*************************************************************************
TEST(test_move_constructor_from_empty)
{
std::string text("Some Text");
test_variant_etl_3 variant_1_etl;
test_variant_etl_3 variant_2_etl(etl::move(variant_1_etl));
CHECK_EQUAL(variant_1_etl.index(), variant_2_etl.index());
}
//*************************************************************************
TEST(test_assign_from_value)
{
std::string text("Some Text");
test_variant_3 variant;
test_variant_etl_3 variant_etl;
variant = text;
variant_etl = text;
CHECK_EQUAL(text, variant.get<std::string>());
CHECK_EQUAL(text, etl::get<std::string>(variant_etl));
}
//*************************************************************************
TEST(test_assign_from_variant)
{
std::string text("Some Text");
test_variant_3 variant_1;
test_variant_3 variant_2;
test_variant_etl_3 variant_1_etl;
test_variant_etl_3 variant_2_etl;
variant_1 = text;
variant_2 = variant_1;
variant_1_etl = text;
variant_2_etl = variant_1_etl;
CHECK_EQUAL(text, variant_2.get<std::string>());
CHECK_EQUAL(text, etl::get<std::string>(variant_2_etl));
}
//*************************************************************************
@ -295,36 +408,36 @@ namespace
{
std::string text("Some Text");
int integer(99);
test_variant_3 variant_1;
test_variant_3 variant_2;
test_variant_etl_3 variant_1_etl;
test_variant_etl_3 variant_2_etl;
variant_1 = text;
variant_2 = integer;
variant_2 = variant_1;
variant_1_etl = text;
variant_2_etl = integer;
variant_2_etl = variant_1_etl;
CHECK_EQUAL(text, variant_2.get<std::string>());
CHECK_EQUAL(text, etl::get<std::string>(variant_2_etl));
}
//*************************************************************************
TEST(test_assignment_incorrect_type_exception)
{
std::string text("Some Text");
test_variant_3 variant(text);
test_variant_etl_3 variant_etl(text);
int i;
CHECK_THROW(etl::get<int>(variant), etl::variant_incorrect_type_exception);
CHECK_THROW(etl::get<int>(variant_etl), etl::variant_incorrect_type_exception);
(void)i;
}
//*************************************************************************
TEST(test_self_assignment)
{
test_variant_3 variant;
test_variant_etl_3 variant_etl;
variant = 1;
variant = variant;
variant_etl = 1;
variant_etl = variant_etl;
CHECK_EQUAL(1, etl::get<int>(variant));
CHECK_EQUAL(1, etl::get<int>(variant_etl));
}
//*************************************************************************
@ -332,16 +445,16 @@ namespace
{
std::string text("Some Text");
int integer(99);
test_variant_3 variant_1(text);
test_variant_3 variant_2(integer);
test_variant_etl_3 variant_1_etl(text);
test_variant_etl_3 variant_2_etl(integer);
variant_1.swap(variant_2);
variant_1_etl.swap(variant_2_etl);
CHECK(etl::holds_alternative<int>(variant_1));
CHECK_EQUAL(integer, etl::get<int>(variant_1));
CHECK(etl::holds_alternative<int>(variant_1_etl));
CHECK_EQUAL(integer, etl::get<int>(variant_1_etl));
CHECK(etl::holds_alternative<std::string>(variant_2));
CHECK_EQUAL(text, etl::get<std::string>(variant_2));
CHECK(etl::holds_alternative<std::string>(variant_2_etl));
CHECK_EQUAL(text, etl::get<std::string>(variant_2_etl));
}
//*************************************************************************
@ -349,38 +462,38 @@ namespace
{
std::string text("Some Text");
int integer(99);
test_variant_3 variant_1(text);
test_variant_3 variant_2(integer);
test_variant_etl_3 variant_1_etl(text);
test_variant_etl_3 variant_2_etl(integer);
etl::swap(variant_1, variant_2);
etl::swap(variant_1_etl, variant_2_etl);
CHECK(etl::holds_alternative<int>(variant_1));
CHECK_EQUAL(integer, etl::get<int>(variant_1));
CHECK(etl::holds_alternative<int>(variant_1_etl));
CHECK_EQUAL(integer, etl::get<int>(variant_1_etl));
CHECK(etl::holds_alternative<std::string>(variant_2));
CHECK_EQUAL(text, etl::get<std::string>(variant_2));
CHECK(etl::holds_alternative<std::string>(variant_2_etl));
CHECK_EQUAL(text, etl::get<std::string>(variant_2_etl));
}
//*************************************************************************
TEST(test_emplace)
{
test_variant_emplace variant;
test_variant_emplace variant_etl;
variant.emplace<D1>("1");
CHECK(etl::holds_alternative<D1>(variant));
CHECK_EQUAL(D1("1"), etl::get<D1>(variant));
variant_etl.emplace<D1>("1");
CHECK(etl::holds_alternative<D1>(variant_etl));
CHECK_EQUAL(D1("1"), etl::get<D1>(variant_etl));
variant.emplace<D2>("1", "2");
CHECK(etl::holds_alternative<D2>(variant));
CHECK_EQUAL(D2("1", "2"), etl::get<D2>(variant));
variant_etl.emplace<D2>("1", "2");
CHECK(etl::holds_alternative<D2>(variant_etl));
CHECK_EQUAL(D2("1", "2"), etl::get<D2>(variant_etl));
variant.emplace<D3>("1", "2", "3");
CHECK(etl::holds_alternative<D3>(variant));
CHECK_EQUAL(D3("1", "2", "3"), etl::get<D3>(variant));
variant_etl.emplace<D3>("1", "2", "3");
CHECK(etl::holds_alternative<D3>(variant_etl));
CHECK_EQUAL(D3("1", "2", "3"), etl::get<D3>(variant_etl));
variant.emplace<D4>("1", "2", "3", "4");
CHECK(etl::holds_alternative<D4>(variant));
CHECK_EQUAL(D4("1", "2", "3", "4"), etl::get<D4>(variant));
variant_etl.emplace<D4>("1", "2", "3", "4");
CHECK(etl::holds_alternative<D4>(variant_etl));
CHECK_EQUAL(D4("1", "2", "3", "4"), etl::get<D4>(variant_etl));
}
//*************************************************************************
@ -393,9 +506,9 @@ namespace
{
D1 da("1");
test_variant_emplace variant(etl::move(getD1()));
test_variant_emplace variant_etl(etl::move(getD1()));
D1 db = etl::move(etl::get<D1>(variant));
D1 db = etl::move(etl::get<D1>(variant_etl));
}
//*************************************************************************
@ -432,18 +545,18 @@ namespace
Visitor visitor;
test_variant_3 variant;
test_variant_etl_3 variant_etl;
variant = char(1);
variant.accept(visitor);
variant_etl = char(1);
variant_etl.accept(visitor);
CHECK_EQUAL(1, visitor.result_c);
variant = int(2);
variant.accept(visitor);
variant_etl = int(2);
variant_etl.accept(visitor);
CHECK_EQUAL(2, visitor.result_i);
variant = std::string("3");
variant.accept(visitor);
variant_etl = std::string("3");
variant_etl.accept(visitor);
CHECK_EQUAL("3", visitor.result_s);
}
@ -481,19 +594,137 @@ namespace
Visitor visitor;
test_variant_3 variant;
test_variant_etl_3 variant_etl;
variant = char(1);
variant(visitor);
variant_etl = char(1);
variant_etl(visitor);
CHECK_EQUAL(1, visitor.result_c);
variant = int(2);
variant(visitor);
variant_etl = int(2);
variant_etl(visitor);
CHECK_EQUAL(2, visitor.result_i);
variant = std::string("3");
variant(visitor);
variant_etl = std::string("3");
variant_etl(visitor);
CHECK_EQUAL("3", visitor.result_s);
}
//*************************************************************************
TEST(test_get_if_index)
{
test_variant_etl_3 variant_etl;
variant_etl = char(1);
CHECK(etl::get_if<0>(&variant_etl) != nullptr);
CHECK(etl::get_if<0>(variant_etl) != nullptr);
CHECK(etl::get_if<1>(&variant_etl) == nullptr);
CHECK(etl::get_if<1>(variant_etl) == nullptr);
CHECK(etl::get_if<2>(&variant_etl) == nullptr);
CHECK(etl::get_if<2>(variant_etl) == nullptr);
variant_etl = int(2);
CHECK(etl::get_if<0>(&variant_etl) == nullptr);
CHECK(etl::get_if<0>(variant_etl) == nullptr);
CHECK(etl::get_if<1>(&variant_etl) != nullptr);
CHECK(etl::get_if<1>(variant_etl) != nullptr);
CHECK(etl::get_if<2>(&variant_etl) == nullptr);
CHECK(etl::get_if<2>(variant_etl) == nullptr);
variant_etl = std::string("3");
CHECK(etl::get_if<0>(&variant_etl) == nullptr);
CHECK(etl::get_if<0>(variant_etl) == nullptr);
CHECK(etl::get_if<1>(&variant_etl) == nullptr);
CHECK(etl::get_if<1>(variant_etl) == nullptr);
CHECK(etl::get_if<2>(&variant_etl) != nullptr);
CHECK(etl::get_if<2>(variant_etl) != nullptr);
}
//*************************************************************************
TEST(test_get_if_type)
{
test_variant_etl_3 variant_etl;
variant_etl = char(1);
CHECK(etl::get_if<char>(&variant_etl) != nullptr);
CHECK(etl::get_if<char>(variant_etl) != nullptr);
CHECK(etl::get_if<int>(&variant_etl) == nullptr);
CHECK(etl::get_if<int>(variant_etl) == nullptr);
CHECK(etl::get_if<std::string>(&variant_etl) == nullptr);
CHECK(etl::get_if<std::string>(variant_etl) == nullptr);
variant_etl = int(2);
CHECK(etl::get_if<char>(&variant_etl) == nullptr);
CHECK(etl::get_if<char>(variant_etl) == nullptr);
CHECK(etl::get_if<int>(&variant_etl) != nullptr);
CHECK(etl::get_if<int>(variant_etl) != nullptr);
CHECK(etl::get_if<std::string>(&variant_etl) == nullptr);
CHECK(etl::get_if<std::string>(variant_etl) == nullptr);
variant_etl = std::string("3");
CHECK(etl::get_if<char>(&variant_etl) == nullptr);
CHECK(etl::get_if<char>(variant_etl) == nullptr);
CHECK(etl::get_if<int>(&variant_etl) == nullptr);
CHECK(etl::get_if<int>(variant_etl) == nullptr);
CHECK(etl::get_if<std::string>(&variant_etl) != nullptr);
CHECK(etl::get_if<std::string>(variant_etl) != nullptr);
}
//*************************************************************************
TEST(test_variant_size)
{
test_variant_etl_3 variant_etl;
CHECK_EQUAL(3U, etl::variant_size_v<test_variant_etl_3>);
}
//*************************************************************************
TEST(test_compare_etl_and_stl_variant_with_moveable_type)
{
Moveable from_etl;
Moveable to_etl;
Moveable from_std;
Moveable to_std;
etl::variant<Moveable> variant_etl;
std::variant<Moveable> variant_std;
variant_etl = etl::move(from_etl);
variant_std = etl::move(from_std);
CHECK_EQUAL(from_std.moved_from, from_etl.moved_from);
CHECK_EQUAL(from_std.moved_to, from_etl.moved_to);
to_etl = etl::move(etl::get<0>(variant_etl));
to_std = etl::move(std::get<0>(variant_std));
CHECK_EQUAL(to_std.moved_from, to_etl.moved_from);
CHECK_EQUAL(to_std.moved_to, to_etl.moved_to);
}
//*************************************************************************
TEST(test_compare_etl_and_stl_variant_with_copyable_type)
{
Copyable from_etl;
Copyable to_etl;
Copyable from_std;
Copyable to_std;
etl::variant<Copyable> variant_etl;
std::variant<Copyable> variant_std;
variant_etl = from_etl;
variant_std = from_std;
CHECK_EQUAL(from_std.copied_from, from_etl.copied_from);
CHECK_EQUAL(from_std.copied_to, from_etl.copied_to);
to_etl = etl::get<0>(variant_etl);
to_std = std::get<0>(variant_std);
CHECK_EQUAL(to_std.copied_from, to_etl.copied_from);
CHECK_EQUAL(to_std.copied_to, to_etl.copied_to);
}
};
}

View File

@ -3477,6 +3477,23 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugNoSTLForceNoAdvanced|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\sanity-check\overload.h.t.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugLLVMNoSTL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='MSVCDebugNoSTLAppveyor|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugMSVCSmallStrings|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug No Unit Tests|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugStringTruncationIsError|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='LLVM New|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug LLVM|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC No Checks|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugNoSTL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Clang|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='MSVCDebugAppveyor|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugNoSTLForceNoAdvanced|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\sanity-check\packet.h.t.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugNoSTL|Win32'">true</ExcludedFromBuild>
@ -4353,6 +4370,40 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugNoSTLForceNoAdvanced|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\sanity-check\variant_new.h.t.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugLLVMNoSTL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='MSVCDebugNoSTLAppveyor|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugMSVCSmallStrings|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug No Unit Tests|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugStringTruncationIsError|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='LLVM New|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug LLVM|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC No Checks|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugNoSTL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Clang|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='MSVCDebugAppveyor|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugNoSTLForceNoAdvanced|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\sanity-check\variant_legacy.h.t.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugLLVMNoSTL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='MSVCDebugNoSTLAppveyor|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugMSVCSmallStrings|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug No Unit Tests|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugStringTruncationIsError|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='LLVM New|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug LLVM|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC No Checks|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugNoSTL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Clang|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='MSVCDebugAppveyor|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugNoSTLForceNoAdvanced|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\sanity-check\variant_pool.h.t.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugNoSTL|Win32'">true</ExcludedFromBuild>
@ -4887,6 +4938,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug No Unit Tests|x64'">false</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\test_optional.cpp" />
<ClCompile Include="..\test_overload.cpp" />
<ClCompile Include="..\test_packet.cpp" />
<ClCompile Include="..\test_parameter_pack.cpp" />
<ClCompile Include="..\test_parameter_type.cpp" />

View File

@ -1137,6 +1137,9 @@
<ClInclude Include="..\..\include\etl\overload.h">
<Filter>ETL\Patterns</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\experimental\mem_cast.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\main.cpp">
@ -2576,6 +2579,18 @@
<ClCompile Include="..\sanity-check\mem_cast.h.t.cpp">
<Filter>Source Files\Sanity Checks</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\variant_new.h.t.cpp">
<Filter>Source Files\Sanity Checks</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\variant_legacy.h.t.cpp">
<Filter>Source Files\Sanity Checks</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\overload.h.t.cpp">
<Filter>Source Files\Sanity Checks</Filter>
</ClCompile>
<ClCompile Include="..\test_overload.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\library.properties">