mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
#1171 optional of a const arary can't be emplaced with gcc-15
This commit is contained in:
parent
ea61ff7770
commit
d27adeb510
@ -42,6 +42,12 @@ SOFTWARE.
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//*****************************************************************************
|
||||
// Forward declaration of etl::optional
|
||||
//*****************************************************************************
|
||||
template <typename T>
|
||||
class optional;
|
||||
|
||||
//*****************************************************************************
|
||||
/// A null option type.
|
||||
///\ingroup utilities
|
||||
@ -102,7 +108,7 @@ namespace etl
|
||||
//*****************************************************************************
|
||||
namespace private_optional
|
||||
{
|
||||
template <typename T, bool IsDefaultConstructible = etl::is_fundamental<T>::value>
|
||||
template <typename T, bool UseFundamentalPath = etl::is_fundamental<T>::value && !etl::is_const<T>::value>
|
||||
class optional_impl;
|
||||
|
||||
//*****************************************************************************
|
||||
@ -114,6 +120,7 @@ namespace etl
|
||||
protected:
|
||||
|
||||
typedef T value_type;
|
||||
typedef optional_impl<T, false> this_type;
|
||||
|
||||
//***************************************************************************
|
||||
/// Constructor.
|
||||
@ -299,7 +306,7 @@ namespace etl
|
||||
ETL_CONSTEXPR20_STL
|
||||
T* operator ->()
|
||||
{
|
||||
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
|
||||
#if ETL_IS_DEBUG_BUILD
|
||||
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
|
||||
#endif
|
||||
|
||||
@ -312,7 +319,7 @@ namespace etl
|
||||
ETL_CONSTEXPR20_STL
|
||||
const T* operator ->() const
|
||||
{
|
||||
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
|
||||
#if ETL_IS_DEBUG_BUILD
|
||||
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
|
||||
#endif
|
||||
|
||||
@ -325,7 +332,7 @@ namespace etl
|
||||
ETL_CONSTEXPR20_STL
|
||||
T& operator *() ETL_LVALUE_REF_QUALIFIER
|
||||
{
|
||||
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
|
||||
#if ETL_IS_DEBUG_BUILD
|
||||
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
|
||||
#endif
|
||||
|
||||
@ -338,7 +345,7 @@ namespace etl
|
||||
ETL_CONSTEXPR20_STL
|
||||
const T& operator *() const ETL_LVALUE_REF_QUALIFIER
|
||||
{
|
||||
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
|
||||
#if ETL_IS_DEBUG_BUILD
|
||||
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
|
||||
#endif
|
||||
|
||||
@ -352,7 +359,7 @@ namespace etl
|
||||
ETL_CONSTEXPR20_STL
|
||||
T&& operator *()&&
|
||||
{
|
||||
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
|
||||
#if ETL_IS_DEBUG_BUILD
|
||||
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
|
||||
#endif
|
||||
|
||||
@ -365,7 +372,7 @@ namespace etl
|
||||
ETL_CONSTEXPR20_STL
|
||||
const T&& operator *() const&&
|
||||
{
|
||||
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
|
||||
#if ETL_IS_DEBUG_BUILD
|
||||
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
|
||||
#endif
|
||||
|
||||
@ -496,16 +503,36 @@ namespace etl
|
||||
storage.destroy();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
///
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR20_STL
|
||||
T& emplace(const optional_impl<T>& other)
|
||||
{
|
||||
#if ETL_IS_DEBUG_BUILD
|
||||
ETL_ASSERT(other.has_value(), ETL_ERROR(optional_invalid));
|
||||
#endif
|
||||
|
||||
storage.construct(other.value());
|
||||
|
||||
return storage.u.value;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_OPTIONAL_FORCE_CPP03_IMPLEMENTATION)
|
||||
//*************************************************************************
|
||||
/// Emplaces a value.
|
||||
///\param args The arguments to construct with.
|
||||
/// Emplaces a value from arbitrary constructor arguments.
|
||||
/// Disabled (via SFINAE) if the first argument is an optional_impl (or a
|
||||
/// derived type such as etl::optional<T>) so that the dedicated
|
||||
/// emplace(const optional_impl&) overload is selected instead.
|
||||
//*************************************************************************
|
||||
template <typename... TArgs>
|
||||
template <typename U,
|
||||
typename... URest,
|
||||
typename etl::enable_if<!etl::is_base_of<optional_impl,
|
||||
typename etl::remove_cv<typename etl::remove_reference<U>::type>::type>::value, int>::type = 0>
|
||||
ETL_CONSTEXPR20_STL
|
||||
T& emplace(TArgs&& ... args)
|
||||
T& emplace(U&& first, URest&&... rest)
|
||||
{
|
||||
storage.construct(etl::forward<TArgs>(args)...);
|
||||
storage.construct(etl::forward<U>(first), etl::forward<URest>(rest)...);
|
||||
|
||||
return storage.u.value;
|
||||
}
|
||||
@ -533,7 +560,9 @@ namespace etl
|
||||
/// 1 parameter.
|
||||
//*************************************************************************
|
||||
template <typename T1>
|
||||
T& emplace(const T1& value1)
|
||||
typename etl::enable_if<!etl::is_base_of<this_type, typename etl::remove_cv<typename etl::remove_reference<T1>::type>::type>::value &&
|
||||
!etl::is_same<etl::optional<T>, typename etl::remove_cv<typename etl::remove_reference<T1>::type>::type>::value, T&>::type
|
||||
emplace(const T1& value1)
|
||||
{
|
||||
if (has_value())
|
||||
{
|
||||
@ -614,6 +643,8 @@ namespace etl
|
||||
//*************************************
|
||||
struct storage_type
|
||||
{
|
||||
typedef typename etl::remove_const<T>::type* pointer_type;
|
||||
|
||||
//*******************************
|
||||
ETL_CONSTEXPR20_STL
|
||||
storage_type()
|
||||
@ -626,12 +657,9 @@ namespace etl
|
||||
ETL_CONSTEXPR20_STL
|
||||
void construct(const T& value_)
|
||||
{
|
||||
if (valid)
|
||||
{
|
||||
etl::destroy_at(&u.value);
|
||||
}
|
||||
destroy();
|
||||
|
||||
etl::construct_at(&u.value, value_);
|
||||
etl::construct_at(const_cast<pointer_type>(&u.value), value_);
|
||||
valid = true;
|
||||
}
|
||||
|
||||
@ -640,12 +668,9 @@ namespace etl
|
||||
ETL_CONSTEXPR20_STL
|
||||
void construct(T&& value_)
|
||||
{
|
||||
if (valid)
|
||||
{
|
||||
etl::destroy_at(&u.value);
|
||||
}
|
||||
destroy();
|
||||
|
||||
etl::construct_at(&u.value, etl::move(value_));
|
||||
etl::construct_at(const_cast<pointer_type>(&u.value), etl::move(value_));
|
||||
valid = true;
|
||||
}
|
||||
|
||||
@ -654,12 +679,9 @@ namespace etl
|
||||
ETL_CONSTEXPR20_STL
|
||||
void construct(TArgs&&... args)
|
||||
{
|
||||
if (valid)
|
||||
{
|
||||
etl::destroy_at(&u.value);
|
||||
}
|
||||
destroy();
|
||||
|
||||
etl::construct_at(&u.value, etl::forward<TArgs>(args)...);
|
||||
etl::construct_at(const_cast<pointer_type>(&u.value), etl::forward<TArgs>(args)...);
|
||||
valid = true;
|
||||
}
|
||||
#endif
|
||||
@ -670,7 +692,7 @@ namespace etl
|
||||
{
|
||||
if (valid)
|
||||
{
|
||||
etl::destroy_at(&u.value);
|
||||
etl::destroy_at(const_cast<pointer_type>(&u.value));
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
@ -708,6 +730,7 @@ namespace etl
|
||||
protected:
|
||||
|
||||
typedef T value_type;
|
||||
typedef optional_impl<T, true> this_type;
|
||||
|
||||
//***************************************************************************
|
||||
/// Constructor.
|
||||
@ -884,7 +907,7 @@ namespace etl
|
||||
ETL_CONSTEXPR14
|
||||
T* operator ->()
|
||||
{
|
||||
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
|
||||
#if ETL_IS_DEBUG_BUILD
|
||||
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
|
||||
#endif
|
||||
|
||||
@ -897,7 +920,7 @@ namespace etl
|
||||
ETL_CONSTEXPR14
|
||||
const T* operator ->() const
|
||||
{
|
||||
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
|
||||
#if ETL_IS_DEBUG_BUILD
|
||||
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
|
||||
#endif
|
||||
|
||||
@ -910,7 +933,7 @@ namespace etl
|
||||
ETL_CONSTEXPR14
|
||||
T& operator *() ETL_LVALUE_REF_QUALIFIER
|
||||
{
|
||||
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
|
||||
#if ETL_IS_DEBUG_BUILD
|
||||
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
|
||||
#endif
|
||||
|
||||
@ -923,7 +946,7 @@ namespace etl
|
||||
ETL_CONSTEXPR14
|
||||
const T& operator *() const ETL_LVALUE_REF_QUALIFIER
|
||||
{
|
||||
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
|
||||
#if ETL_IS_DEBUG_BUILD
|
||||
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
|
||||
#endif
|
||||
|
||||
@ -937,7 +960,7 @@ namespace etl
|
||||
ETL_CONSTEXPR14
|
||||
T&& operator *()&&
|
||||
{
|
||||
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
|
||||
#if ETL_IS_DEBUG_BUILD
|
||||
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
|
||||
#endif
|
||||
|
||||
@ -950,7 +973,7 @@ namespace etl
|
||||
ETL_CONSTEXPR14
|
||||
const T&& operator *() const&&
|
||||
{
|
||||
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
|
||||
#if ETL_IS_DEBUG_BUILD
|
||||
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
|
||||
#endif
|
||||
|
||||
@ -1081,6 +1104,21 @@ namespace etl
|
||||
storage.destroy();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
///
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR20_STL
|
||||
T& emplace(const optional_impl<T>& other)
|
||||
{
|
||||
#if ETL_IS_DEBUG_BUILD
|
||||
ETL_ASSERT(other.has_value(), ETL_ERROR(optional_invalid));
|
||||
#endif
|
||||
|
||||
storage.construct(other.value());
|
||||
|
||||
return storage.u.value;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_OPTIONAL_FORCE_CPP03_IMPLEMENTATION)
|
||||
//*************************************************************************
|
||||
/// Emplaces a value.
|
||||
@ -1118,7 +1156,9 @@ namespace etl
|
||||
/// 1 parameter.
|
||||
//*************************************************************************
|
||||
template <typename T1>
|
||||
T& emplace(const T1& value1)
|
||||
typename etl::enable_if<!etl::is_base_of<this_type, typename etl::remove_cv<typename etl::remove_reference<T1>::type>::type>::value &&
|
||||
!etl::is_same<etl::optional<T>, typename etl::remove_cv<typename etl::remove_reference<T1>::type>::type>::value, T&>::type
|
||||
emplace(const T1& value1)
|
||||
{
|
||||
if (has_value())
|
||||
{
|
||||
@ -1247,11 +1287,11 @@ namespace etl
|
||||
};
|
||||
}
|
||||
|
||||
#define ETL_OPTIONAL_ENABLE_CPP14 typename etl::enable_if< etl::is_pod<U>::value, int>::type = 0
|
||||
#define ETL_OPTIONAL_ENABLE_CPP20_STL typename etl::enable_if<!etl::is_pod<U>::value, int>::type = 0
|
||||
#define ETL_OPTIONAL_ENABLE_CPP14 typename etl::enable_if< etl::is_pod<typename etl::remove_cv<U>::type>::value, int>::type = 0
|
||||
#define ETL_OPTIONAL_ENABLE_CPP20_STL typename etl::enable_if<!etl::is_pod<typename etl::remove_cv<U>::type>::value, int>::type = 0
|
||||
|
||||
#define ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 ETL_CONSTEXPR14 typename etl::enable_if< etl::is_pod<T>::value, bool>::type
|
||||
#define ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL ETL_CONSTEXPR20_STL typename etl::enable_if<!etl::is_pod<T>::value, bool>::type
|
||||
#define ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 ETL_CONSTEXPR14 typename etl::enable_if< etl::is_pod<typename etl::remove_cv<T>::type>::value, bool>::type
|
||||
#define ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL ETL_CONSTEXPR20_STL typename etl::enable_if<!etl::is_pod<typename etl::remove_cv<T>::type>::value, bool>::type
|
||||
|
||||
//*****************************************************************************
|
||||
/// An optional type.
|
||||
|
||||
@ -976,5 +976,36 @@ namespace
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
using ItemType = etl::array<uint8_t, 2>;
|
||||
|
||||
etl::optional<const ItemType> create_optional_issue_1171()
|
||||
{
|
||||
ItemType t;
|
||||
t[0] = 1;
|
||||
t[1] = 20;
|
||||
|
||||
return etl::optional<const ItemType>(t);
|
||||
}
|
||||
|
||||
TEST(test_optional_issue_1171)
|
||||
{
|
||||
etl::optional<const ItemType> opt1 = create_optional_issue_1171();
|
||||
CHECK_TRUE(opt1.has_value());
|
||||
CHECK_EQUAL(1, (*opt1)[0]);
|
||||
CHECK_EQUAL(20, (*opt1)[1]);
|
||||
|
||||
etl::optional<const ItemType> opt2(create_optional_issue_1171());
|
||||
CHECK_TRUE(opt2.has_value());
|
||||
CHECK_EQUAL(1, (*opt2)[0]);
|
||||
CHECK_EQUAL(20, (*opt2)[1]);
|
||||
|
||||
etl::optional<const ItemType> opt3;
|
||||
opt3.emplace(create_optional_issue_1171());
|
||||
CHECK_TRUE(opt3.has_value());
|
||||
CHECK_EQUAL(1, (*opt3)[0]);
|
||||
CHECK_EQUAL(20, (*opt3)[1]);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user