mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Fix etl::optional for deleted copy constructors (#1362)
* Print test names at test time (#1343) * Fix etl::optional for deleted copy constructors --------- Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
This commit is contained in:
parent
0b5621e809
commit
bd15e42440
@ -169,21 +169,19 @@ namespace etl
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Constructor from value type.
|
||||
/// Converting constructor from value type.
|
||||
/// Constructs T in-place from U&&, without requiring T to be
|
||||
/// copy/move constructible.
|
||||
//***************************************************************************
|
||||
template <typename U,
|
||||
typename etl::enable_if<
|
||||
etl::is_constructible<T, U&&>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::in_place_t>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, optional_impl>::value, int>::type = 0>
|
||||
ETL_CONSTEXPR20_STL
|
||||
optional_impl(const T& value_)
|
||||
optional_impl(U&& value_)
|
||||
{
|
||||
storage.construct(value_);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Constructor from value type.
|
||||
//***************************************************************************
|
||||
ETL_CONSTEXPR20_STL
|
||||
optional_impl(T&& value_)
|
||||
{
|
||||
storage.construct(etl::move(value_));
|
||||
storage.construct(etl::forward<U>(value_));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -280,23 +278,24 @@ namespace etl
|
||||
//***************************************************************************
|
||||
/// Assignment operator from value type.
|
||||
//***************************************************************************
|
||||
#if ETL_USING_CPP11
|
||||
template <typename U,
|
||||
typename etl::enable_if<
|
||||
etl::is_constructible<T, U&&>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, optional_impl>::value, int>::type = 0>
|
||||
ETL_CONSTEXPR20_STL
|
||||
optional_impl& operator =(U&& value_)
|
||||
{
|
||||
storage.construct(etl::forward<U>(value_));
|
||||
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
ETL_CONSTEXPR20_STL
|
||||
optional_impl& operator =(const T& value_)
|
||||
{
|
||||
storage.construct(value_);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Assignment operator from value type.
|
||||
//***************************************************************************
|
||||
ETL_CONSTEXPR20_STL
|
||||
optional_impl& operator =(T&& value_)
|
||||
{
|
||||
storage.construct(etl::move(value_));
|
||||
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
@ -1442,22 +1441,36 @@ namespace etl
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Construct from value type.
|
||||
/// Converting constructor from value type.
|
||||
/// Constructs T in-place from U&&, without requiring T to be
|
||||
/// copy/move constructible.
|
||||
//***************************************************************************
|
||||
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
|
||||
template <typename U,
|
||||
typename etl::enable_if<
|
||||
etl::is_constructible<T, U&&>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::optional<T>>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::in_place_t>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::nullopt_t>::value &&
|
||||
etl::is_pod<typename etl::remove_cv<T>::type>::value, int>::type = 0>
|
||||
ETL_CONSTEXPR14
|
||||
optional(const T& value_)
|
||||
: impl_t(value_)
|
||||
optional(U&& value_)
|
||||
: impl_t(etl::forward<U>(value_))
|
||||
{
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Construct from value type.
|
||||
/// Converting constructor from value type.
|
||||
//***************************************************************************
|
||||
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
|
||||
template <typename U,
|
||||
typename etl::enable_if<
|
||||
etl::is_constructible<T, U&&>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::optional<T>>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::in_place_t>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::nullopt_t>::value &&
|
||||
!etl::is_pod<typename etl::remove_cv<T>::type>::value, int>::type = 0>
|
||||
ETL_CONSTEXPR20_STL
|
||||
optional(const T& value_)
|
||||
: impl_t(value_)
|
||||
optional(U&& value_)
|
||||
: impl_t(etl::forward<U>(value_))
|
||||
{
|
||||
}
|
||||
#else
|
||||
@ -1470,29 +1483,6 @@ namespace etl
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Move construct from value type.
|
||||
//***************************************************************************
|
||||
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
|
||||
ETL_CONSTEXPR14
|
||||
optional(T&& value_)
|
||||
: impl_t(etl::move(value_))
|
||||
{
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Move construct from value type.
|
||||
//***************************************************************************
|
||||
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
|
||||
ETL_CONSTEXPR20_STL
|
||||
optional(T&& value_)
|
||||
: impl_t(etl::move(value_))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Emplace construct from arguments.
|
||||
@ -1641,25 +1631,35 @@ namespace etl
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Assignment operator from value type.
|
||||
/// Converting assignment operator from value type.
|
||||
//***************************************************************************
|
||||
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
|
||||
template <typename U,
|
||||
typename etl::enable_if<
|
||||
etl::is_constructible<T, U&&>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::optional<T>>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::nullopt_t>::value &&
|
||||
etl::is_pod<typename etl::remove_cv<T>::type>::value, int>::type = 0>
|
||||
ETL_CONSTEXPR14
|
||||
optional& operator =(const T& value_)
|
||||
optional& operator =(U&& value_)
|
||||
{
|
||||
impl_t::operator=(value_);
|
||||
impl_t::operator=(etl::forward<U>(value_));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Assignment operator from value type.
|
||||
/// Converting assignment operator from value type.
|
||||
//***************************************************************************
|
||||
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
|
||||
template <typename U,
|
||||
typename etl::enable_if<
|
||||
etl::is_constructible<T, U&&>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::optional<T>>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::nullopt_t>::value &&
|
||||
!etl::is_pod<typename etl::remove_cv<T>::type>::value, int>::type = 0>
|
||||
ETL_CONSTEXPR20_STL
|
||||
optional& operator =(const T& value_)
|
||||
optional& operator =(U&& value_)
|
||||
{
|
||||
impl_t::operator=(value_);
|
||||
impl_t::operator=(etl::forward<U>(value_));
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -1675,32 +1675,6 @@ namespace etl
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Move assignment operator from value type.
|
||||
//***************************************************************************
|
||||
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
|
||||
ETL_CONSTEXPR14
|
||||
optional& operator =(T&& value_)
|
||||
{
|
||||
impl_t::operator=(etl::move(value_));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Move assignment operator from value type.
|
||||
//***************************************************************************
|
||||
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
|
||||
ETL_CONSTEXPR20_STL
|
||||
optional& operator =(T&& value_)
|
||||
{
|
||||
impl_t::operator=(etl::move(value_));
|
||||
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// Returns an iterator to the beginning of the optional.
|
||||
//***************************************************************************
|
||||
|
||||
@ -1118,5 +1118,46 @@ namespace
|
||||
|
||||
CHECK_EQUAL(42, *opt);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// GitHub issue #146: etl::optional doesn't compile with deleted copy constructor
|
||||
//*************************************************************************
|
||||
#if ETL_USING_CPP11
|
||||
struct Issue146_NonCopyable
|
||||
{
|
||||
Issue146_NonCopyable(int some) : _some(some) {}
|
||||
Issue146_NonCopyable(const Issue146_NonCopyable&) = delete;
|
||||
Issue146_NonCopyable(Issue146_NonCopyable&&) = delete;
|
||||
Issue146_NonCopyable& operator=(const Issue146_NonCopyable&) = delete;
|
||||
|
||||
int _some;
|
||||
};
|
||||
|
||||
struct Issue146_Container
|
||||
{
|
||||
Issue146_Container(int a_val) : a(a_val) {}
|
||||
Issue146_Container() : a(etl::nullopt) {}
|
||||
|
||||
etl::optional<Issue146_NonCopyable> a;
|
||||
};
|
||||
|
||||
TEST(test_optional_issue_146_deleted_copy_ctor)
|
||||
{
|
||||
// etl::optional<T> should compile when T has deleted copy/move constructors,
|
||||
// as long as T is constructible from the given arguments.
|
||||
Issue146_Container with_value(42);
|
||||
Issue146_Container without_value;
|
||||
|
||||
CHECK_TRUE(with_value.a.has_value());
|
||||
CHECK_EQUAL(42, with_value.a->_some);
|
||||
|
||||
CHECK_FALSE(without_value.a.has_value());
|
||||
|
||||
// in_place construction should also work
|
||||
etl::optional<Issue146_NonCopyable> opt(etl::in_place_t{}, 99);
|
||||
CHECK_TRUE(opt.has_value());
|
||||
CHECK_EQUAL(99, opt->_some);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user