mirror of
https://github.com/ETLCPP/etl.git
synced 2026-10-28 18:07:10 +08:00
Exclude in-place tags from variant's converting constructor
Like std::variant, etl::variant should exclude in_place_type_t and in_place_index_t specializations from its converting constructor. This prevents implicit conversions from treating an in-place tag as an ordinary value while preserving dedicated in-place construction.
This commit is contained in:
parent
cba156b44f
commit
cff9da11bd
@ -312,6 +312,24 @@ namespace etl
|
||||
template <typename T, typename... TTypes>
|
||||
using select_alternative_index = decltype(conversion_overloads<T, TTypes...>::select(etl::declval<T>()));
|
||||
|
||||
//*************************************************************************
|
||||
/// Helpers for identifying in-place tags.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
struct is_in_place_tag : etl::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_in_place_tag<etl::in_place_type_t<T> > : etl::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <size_t Index>
|
||||
struct is_in_place_tag<etl::in_place_index_t<Index> > : etl::true_type
|
||||
{
|
||||
};
|
||||
|
||||
//*******************************************
|
||||
/// Constexpr get by index from variadic_union.
|
||||
//*******************************************
|
||||
@ -1075,7 +1093,9 @@ namespace etl
|
||||
//***************************************************************************
|
||||
#include "diagnostic_uninitialized_push.h"
|
||||
template < typename T, bool Trivial_ = Is_Trivially_Destructible_Suite,
|
||||
etl::enable_if_t<!etl::is_same<etl::remove_cvref_t<T>, variant>::value && !Trivial_, int> = 0,
|
||||
etl::enable_if_t< !etl::is_same<etl::remove_cvref_t<T>, variant>::value && !Trivial_
|
||||
&& !private_variant::is_in_place_tag<etl::remove_cvref_t<T> >::value,
|
||||
int> = 0,
|
||||
size_t AlternativeIndex = private_variant::select_alternative_index<T, TTypes...>::value,
|
||||
typename TAlternative = type_from_index<AlternativeIndex>, etl::enable_if_t<etl::is_constructible<TAlternative, T>::value, int> = 0>
|
||||
ETL_CONSTEXPR14 variant(T&& value)
|
||||
@ -1085,7 +1105,9 @@ namespace etl
|
||||
}
|
||||
|
||||
template < typename T, bool Trivial_ = Is_Trivially_Destructible_Suite,
|
||||
etl::enable_if_t<!etl::is_same<etl::remove_cvref_t<T>, variant>::value && Trivial_, int> = 0,
|
||||
etl::enable_if_t<!etl::is_same<etl::remove_cvref_t<T>, variant>::value && Trivial_
|
||||
&& !private_variant::is_in_place_tag<etl::remove_cvref_t<T> >::value,
|
||||
int> = 0,
|
||||
size_t AlternativeIndex = private_variant::select_alternative_index<T, TTypes...>::value,
|
||||
typename TAlternative = type_from_index<AlternativeIndex>, etl::enable_if_t<etl::is_constructible<TAlternative, T>::value, int> = 0 >
|
||||
constexpr variant(T&& value)
|
||||
|
||||
@ -918,6 +918,12 @@ namespace
|
||||
|
||||
CHECK(!(std::is_constructible<etl::variant<int, long>, AmbiguousIntLong>::value));
|
||||
CHECK(!(std::is_constructible<etl::variant<std::string, int, long>, AmbiguousIntLong>::value));
|
||||
|
||||
// The converting constructor should not accept in-place type or index tags.
|
||||
CHECK((!std::is_constructible<etl::variant<etl::in_place_type_t<int>>, etl::in_place_type_t<int>>::value));
|
||||
CHECK((!std::is_constructible<etl::variant<std::string, etl::in_place_type_t<int>>, etl::in_place_type_t<int>>::value));
|
||||
CHECK((!std::is_constructible<etl::variant<etl::in_place_index_t<1U>>, etl::in_place_index_t<1U>>::value));
|
||||
CHECK((!std::is_constructible<etl::variant<std::string, etl::in_place_index_t<2U>>, etl::in_place_index_t<2U>>::value));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user