Implement P0032R3, Homogeneous interface for variant, any and optional,
for the parts concerning any and optional. * include/std/any (_Storage()): Make constexpr and have it initialize _M_ptr. (any()): Make constexpr. (any(const any&)): Adjust. (any(any&&)): Likewise. (__any_constructible_t): New. (any(_ValueType&&)): Constrain. (any(in_place_type_t<_Tp>, _Args&&...)): New. (any(in_place_type_t<_Tp>, initializer_list<_Up>, _Args&&...)): Likewise. (~any()): Adjust. (operator=(const any&)): Likewise. (operator=(any&&)): Likewise. (operator=(_ValueType&&)): Constrain. (emplace(_Args&&...)): New. (emplace(initializer_list<_Up>, _Args&&...)): Likewise. (clear()): Remove. (reset()): New. (swap(any&)): Adjust. (empty()): Remove. (has_value()): New. (type()): Adjust. (_Manager_internal::_S_create(_Storage&, _Args&&...)): New. (_Manager_external::_S_create(_Storage&, _Args&&...)): Likewise. (make_any(_Args&&...)): Likewise. (make_any(initializer_list<_Up>, _Args&&...)): Likewise. * include/std/optional (in_place_t, in_place): Remove. (bad_optional_access): Add a comment referring to LEWG 72. (emplace(_Args&&...)): Constrain. (has_value()): New. (reset()): Likewise. (make_optional(_Args&&...)): Likewise. (make_optional(initializer_list<_Up>, _Args&&...)): Likewise. * include/std/utility (in_place_tag): New. (__in_place, __in_place_type, __in_place_index): Likewise. (in_place_t, in_place_type_t, in_place_index_t): Likewise. (in_place(__in_place*)): Likewise. (in_place(__in_place_type<_Tp>*)): Likewise. (in_place(__in_place_index<_Idx>*)): Likewise. * testsuite/20_util/any/assign/1.cc: Adjust. * testsuite/20_util/any/assign/emplace.cc: New. * testsuite/20_util/any/assign/self.cc: Adjust. * testsuite/20_util/any/cons/1.cc: Likewise. * testsuite/20_util/any/cons/in_place.cc: New. * testsuite/20_util/any/make_any.cc: Likewise. * testsuite/20_util/any/misc/any_cast_neg.cc: Adjust. * testsuite/20_util/any/misc/swap.cc: Likewise. * testsuite/20_util/any/modifiers/1.cc: Likewise. * testsuite/20_util/any/requirements.cc: New. * testsuite/20_util/in_place/requirements.cc: Likewise. * testsuite/20_util/optional/constexpr/in_place.cc: Adjust. * testsuite/20_util/optional/in_place.cc: Likewise. * testsuite/20_util/optional/make_optional.cc: Add tests for the new overloads of make_optional. From-SVN: r238329
This commit is contained in:
parent
c0d31471ba
commit
25a69162c9
@ -1,3 +1,62 @@
|
||||
2016-07-14 Ville Voutilainen <ville.voutilainen@gmail.com>
|
||||
|
||||
Implement P0032R3, Homogeneous interface for variant, any and optional,
|
||||
for the parts concerning any and optional.
|
||||
* include/std/any (_Storage()): Make constexpr and have it
|
||||
initialize _M_ptr.
|
||||
(any()): Make constexpr.
|
||||
(any(const any&)): Adjust.
|
||||
(any(any&&)): Likewise.
|
||||
(__any_constructible_t): New.
|
||||
(any(_ValueType&&)): Constrain.
|
||||
(any(in_place_type_t<_Tp>, _Args&&...)): New.
|
||||
(any(in_place_type_t<_Tp>, initializer_list<_Up>, _Args&&...)):
|
||||
Likewise.
|
||||
(~any()): Adjust.
|
||||
(operator=(const any&)): Likewise.
|
||||
(operator=(any&&)): Likewise.
|
||||
(operator=(_ValueType&&)): Constrain.
|
||||
(emplace(_Args&&...)): New.
|
||||
(emplace(initializer_list<_Up>, _Args&&...)): Likewise.
|
||||
(clear()): Remove.
|
||||
(reset()): New.
|
||||
(swap(any&)): Adjust.
|
||||
(empty()): Remove.
|
||||
(has_value()): New.
|
||||
(type()): Adjust.
|
||||
(_Manager_internal::_S_create(_Storage&, _Args&&...)): New.
|
||||
(_Manager_external::_S_create(_Storage&, _Args&&...)): Likewise.
|
||||
(make_any(_Args&&...)): Likewise.
|
||||
(make_any(initializer_list<_Up>, _Args&&...)): Likewise.
|
||||
* include/std/optional (in_place_t, in_place): Remove.
|
||||
(bad_optional_access): Add a comment referring to LEWG 72.
|
||||
(emplace(_Args&&...)): Constrain.
|
||||
(has_value()): New.
|
||||
(reset()): Likewise.
|
||||
(make_optional(_Args&&...)): Likewise.
|
||||
(make_optional(initializer_list<_Up>, _Args&&...)): Likewise.
|
||||
* include/std/utility (in_place_tag): New.
|
||||
(__in_place, __in_place_type, __in_place_index): Likewise.
|
||||
(in_place_t, in_place_type_t, in_place_index_t): Likewise.
|
||||
(in_place(__in_place*)): Likewise.
|
||||
(in_place(__in_place_type<_Tp>*)): Likewise.
|
||||
(in_place(__in_place_index<_Idx>*)): Likewise.
|
||||
* testsuite/20_util/any/assign/1.cc: Adjust.
|
||||
* testsuite/20_util/any/assign/emplace.cc: New.
|
||||
* testsuite/20_util/any/assign/self.cc: Adjust.
|
||||
* testsuite/20_util/any/cons/1.cc: Likewise.
|
||||
* testsuite/20_util/any/cons/in_place.cc: New.
|
||||
* testsuite/20_util/any/make_any.cc: Likewise.
|
||||
* testsuite/20_util/any/misc/any_cast_neg.cc: Adjust.
|
||||
* testsuite/20_util/any/misc/swap.cc: Likewise.
|
||||
* testsuite/20_util/any/modifiers/1.cc: Likewise.
|
||||
* testsuite/20_util/any/requirements.cc: New.
|
||||
* testsuite/20_util/in_place/requirements.cc: Likewise.
|
||||
* testsuite/20_util/optional/constexpr/in_place.cc: Adjust.
|
||||
* testsuite/20_util/optional/in_place.cc: Likewise.
|
||||
* testsuite/20_util/optional/make_optional.cc: Add tests for
|
||||
the new overloads of make_optional.
|
||||
|
||||
2016-07-13 Ville Voutilainen <ville.voutilainen@gmail.com>
|
||||
|
||||
Implement P0307R2, Making Optional Greater Equal Again.
|
||||
|
@ -79,8 +79,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
// Holds either pointer to a heap object or the contained object itself.
|
||||
union _Storage
|
||||
{
|
||||
// This constructor intentionally doesn't initialize anything.
|
||||
_Storage() = default;
|
||||
constexpr _Storage() : _M_ptr{nullptr} {}
|
||||
|
||||
// Prevent trivial copies of this type, buffer might hold a non-POD.
|
||||
_Storage(const _Storage&) = delete;
|
||||
@ -113,12 +112,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
// construct/destruct
|
||||
|
||||
/// Default constructor, creates an empty object.
|
||||
any() noexcept : _M_manager(nullptr) { }
|
||||
constexpr any() noexcept : _M_manager(nullptr) { }
|
||||
|
||||
/// Copy constructor, copies the state of @p __other
|
||||
any(const any& __other)
|
||||
{
|
||||
if (__other.empty())
|
||||
if (!__other.has_value())
|
||||
_M_manager = nullptr;
|
||||
else
|
||||
{
|
||||
@ -131,11 +130,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
/**
|
||||
* @brief Move constructor, transfer the state from @p __other
|
||||
*
|
||||
* @post @c __other.empty() (this postcondition is a GNU extension)
|
||||
* @post @c !__other.has_value() (this postcondition is a GNU extension)
|
||||
*/
|
||||
any(any&& __other) noexcept
|
||||
{
|
||||
if (__other.empty())
|
||||
if (!__other.has_value())
|
||||
_M_manager = nullptr;
|
||||
else
|
||||
{
|
||||
@ -145,45 +144,71 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
}
|
||||
}
|
||||
|
||||
template <typename _Tp, typename... _Args>
|
||||
using __any_constructible_t =
|
||||
enable_if_t<__and_<is_copy_constructible<_Tp>,
|
||||
is_constructible<_Tp, _Args...>>::value,
|
||||
bool>;
|
||||
|
||||
/// Construct with a copy of @p __value as the contained object.
|
||||
template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
|
||||
typename _Mgr = _Manager<_Tp>,
|
||||
typename enable_if<is_constructible<_Tp, _ValueType&&>::value,
|
||||
bool>::type = true>
|
||||
__any_constructible_t<_Tp, _ValueType&&> = true>
|
||||
any(_ValueType&& __value)
|
||||
: _M_manager(&_Mgr::_S_manage)
|
||||
{
|
||||
_Mgr::_S_create(_M_storage, std::forward<_ValueType>(__value));
|
||||
static_assert(is_copy_constructible<_Tp>::value,
|
||||
"The contained object must be CopyConstructible");
|
||||
}
|
||||
|
||||
/// Construct with a copy of @p __value as the contained object.
|
||||
template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
|
||||
typename _Mgr = _Manager<_Tp>,
|
||||
typename enable_if<!is_constructible<_Tp, _ValueType&&>::value,
|
||||
bool>::type = false>
|
||||
enable_if_t<__and_<is_copy_constructible<_Tp>,
|
||||
__not_<
|
||||
is_constructible<_Tp,
|
||||
_ValueType&&>>>::value,
|
||||
bool> = false>
|
||||
any(_ValueType&& __value)
|
||||
: _M_manager(&_Mgr::_S_manage)
|
||||
{
|
||||
_Mgr::_S_create(_M_storage, __value);
|
||||
static_assert(is_copy_constructible<_Tp>::value,
|
||||
"The contained object must be CopyConstructible");
|
||||
}
|
||||
|
||||
/// Destructor, calls @c clear()
|
||||
~any() { clear(); }
|
||||
/// Construct with an object created from @p __args as the contained object.
|
||||
template <typename _Tp, typename... _Args,
|
||||
typename _Mgr = _Manager<_Tp>,
|
||||
__any_constructible_t<_Tp, _Args&&...> = false>
|
||||
any(in_place_type_t<_Tp>, _Args&&... __args)
|
||||
: _M_manager(&_Mgr::_S_manage)
|
||||
{
|
||||
_Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
/// Construct with an object created from @p __il and @p __args as
|
||||
/// the contained object.
|
||||
template <typename _Tp, typename _Up, typename... _Args,
|
||||
typename _Mgr = _Manager<_Tp>,
|
||||
__any_constructible_t<_Tp, initializer_list<_Up>,
|
||||
_Args&&...> = false>
|
||||
any(in_place_type_t<_Tp>, initializer_list<_Up> __il, _Args&&... __args)
|
||||
: _M_manager(&_Mgr::_S_manage)
|
||||
{
|
||||
_Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
/// Destructor, calls @c reset()
|
||||
~any() { reset(); }
|
||||
|
||||
// assignments
|
||||
|
||||
/// Copy the state of another object.
|
||||
any& operator=(const any& __rhs)
|
||||
{
|
||||
if (__rhs.empty())
|
||||
clear();
|
||||
if (!__rhs.has_value())
|
||||
reset();
|
||||
else if (this != &__rhs)
|
||||
{
|
||||
if (!empty())
|
||||
if (has_value())
|
||||
_M_manager(_Op_destroy, this, nullptr);
|
||||
_Arg __arg;
|
||||
__arg._M_any = this;
|
||||
@ -195,15 +220,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
/**
|
||||
* @brief Move assignment operator
|
||||
*
|
||||
* @post @c __rhs.empty() (not guaranteed for other implementations)
|
||||
* @post @c !__rhs.has_value() (not guaranteed for other implementations)
|
||||
*/
|
||||
any& operator=(any&& __rhs) noexcept
|
||||
{
|
||||
if (__rhs.empty())
|
||||
clear();
|
||||
if (!__rhs.has_value())
|
||||
reset();
|
||||
else if (this != &__rhs)
|
||||
{
|
||||
if (!empty())
|
||||
if (has_value())
|
||||
_M_manager(_Op_destroy, this, nullptr);
|
||||
_Arg __arg;
|
||||
__arg._M_any = this;
|
||||
@ -214,19 +239,44 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
/// Store a copy of @p __rhs as the contained object.
|
||||
template<typename _ValueType>
|
||||
enable_if_t<!is_same<any, decay_t<_ValueType>>::value, any&>
|
||||
enable_if_t<__and_<__not_<is_same<any, decay_t<_ValueType>>>,
|
||||
is_copy_constructible<_ValueType>>::value, any&>
|
||||
operator=(_ValueType&& __rhs)
|
||||
{
|
||||
*this = any(std::forward<_ValueType>(__rhs));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Emplace with an object created from @p __args as the contained object.
|
||||
template <typename _Tp, typename... _Args,
|
||||
typename _Mgr = _Manager<_Tp>,
|
||||
__any_constructible_t<_Tp, _Args&&...> = false>
|
||||
void emplace(_Args&&... __args)
|
||||
{
|
||||
reset();
|
||||
_M_manager = &_Mgr::_S_manage;
|
||||
_Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
/// Emplace with an object created from @p __il and @p __args as
|
||||
/// the contained object.
|
||||
template <typename _Tp, typename _Up, typename... _Args,
|
||||
typename _Mgr = _Manager<_Tp>,
|
||||
__any_constructible_t<_Tp, initializer_list<_Up>,
|
||||
_Args&&...> = false>
|
||||
void emplace(initializer_list<_Up> __il, _Args&&... __args)
|
||||
{
|
||||
reset();
|
||||
_M_manager = &_Mgr::_S_manage;
|
||||
_Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
// modifiers
|
||||
|
||||
/// If not empty, destroy the contained object.
|
||||
void clear() noexcept
|
||||
void reset() noexcept
|
||||
{
|
||||
if (!empty())
|
||||
if (has_value())
|
||||
{
|
||||
_M_manager(_Op_destroy, this, nullptr);
|
||||
_M_manager = nullptr;
|
||||
@ -236,10 +286,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
/// Exchange state with another object.
|
||||
void swap(any& __rhs) noexcept
|
||||
{
|
||||
if (empty() && __rhs.empty())
|
||||
if (!has_value() && !__rhs.has_value())
|
||||
return;
|
||||
|
||||
if (!empty() && !__rhs.empty())
|
||||
if (has_value() && __rhs.has_value())
|
||||
{
|
||||
if (this == &__rhs)
|
||||
return;
|
||||
@ -255,8 +305,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
}
|
||||
else
|
||||
{
|
||||
any* __empty = empty() ? this : &__rhs;
|
||||
any* __full = empty() ? &__rhs : this;
|
||||
any* __empty = !has_value() ? this : &__rhs;
|
||||
any* __full = !has_value() ? &__rhs : this;
|
||||
_Arg __arg;
|
||||
__arg._M_any = __empty;
|
||||
__full->_M_manager(_Op_xfer, __full, &__arg);
|
||||
@ -266,13 +316,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
// observers
|
||||
|
||||
/// Reports whether there is a contained object or not.
|
||||
bool empty() const noexcept { return _M_manager == nullptr; }
|
||||
bool has_value() const noexcept { return _M_manager != nullptr; }
|
||||
|
||||
#if __cpp_rtti
|
||||
/// The @c typeid of the contained object, or @c typeid(void) if empty.
|
||||
const type_info& type() const noexcept
|
||||
{
|
||||
if (empty())
|
||||
if (!has_value())
|
||||
return typeid(void);
|
||||
_Arg __arg;
|
||||
_M_manager(_Op_get_type_info, this, &__arg);
|
||||
@ -316,6 +366,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
void* __addr = &__storage._M_buffer;
|
||||
::new (__addr) _Tp(std::forward<_Up>(__value));
|
||||
}
|
||||
|
||||
template<typename... _Args>
|
||||
static void
|
||||
_S_create(_Storage& __storage, _Args&&... __args)
|
||||
{
|
||||
void* __addr = &__storage._M_buffer;
|
||||
::new (__addr) _Tp(std::forward<_Args>(__args)...);
|
||||
}
|
||||
};
|
||||
|
||||
// Manage external contained object.
|
||||
@ -331,12 +389,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
{
|
||||
__storage._M_ptr = new _Tp(std::forward<_Up>(__value));
|
||||
}
|
||||
template<typename... _Args>
|
||||
static void
|
||||
_S_create(_Storage& __storage, _Args&&... __args)
|
||||
{
|
||||
__storage._M_ptr = new _Tp(std::forward<_Args>(__args)...);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/// Exchange the states of two @c any objects.
|
||||
inline void swap(any& __x, any& __y) noexcept { __x.swap(__y); }
|
||||
|
||||
/// Create an any holding a @c _Tp constructed from @c __args.
|
||||
template <typename _Tp, typename... _Args>
|
||||
any make_any(_Args&&... __args)
|
||||
{
|
||||
return any(in_place<_Tp>, std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
/// Create an any holding a @c _Tp constructed from @c __il and @c __args.
|
||||
template <typename _Tp, typename _Up, typename... _Args>
|
||||
any make_any(initializer_list<_Up> __il, _Args&&... __args)
|
||||
{
|
||||
return any(in_place<_Tp>, __il, std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Access the contained object.
|
||||
*
|
||||
|
@ -57,13 +57,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
template<typename _Tp>
|
||||
class optional;
|
||||
|
||||
// [X.Y.5]
|
||||
/// Tag type for in-place construction.
|
||||
struct in_place_t { };
|
||||
|
||||
/// Tag for in-place construction.
|
||||
constexpr in_place_t in_place { };
|
||||
|
||||
// [X.Y.6]
|
||||
/// Tag type to disengage optional objects.
|
||||
struct nullopt_t
|
||||
@ -91,9 +84,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
*/
|
||||
class bad_optional_access : public logic_error
|
||||
{
|
||||
// XXX See LEWG 72, https://issues.isocpp.org/show_bug.cgi?id=72
|
||||
public:
|
||||
bad_optional_access() : logic_error("bad optional access") { }
|
||||
|
||||
// XXX This constructor is non-standard. Should not be inline
|
||||
explicit bad_optional_access(const char* __arg) : logic_error(__arg) { }
|
||||
|
||||
@ -641,18 +634,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
}
|
||||
|
||||
template<typename... _Args>
|
||||
void
|
||||
enable_if_t<is_constructible<_Tp, _Args&&...>::value>
|
||||
emplace(_Args&&... __args)
|
||||
{
|
||||
static_assert(is_constructible<_Tp, _Args&&...>(),
|
||||
"Cannot emplace value type from arguments");
|
||||
|
||||
this->_M_reset();
|
||||
this->_M_construct(std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
template<typename _Up, typename... _Args>
|
||||
enable_if_t<is_constructible<_Tp, initializer_list<_Up>&,
|
||||
enable_if_t<is_constructible<_Tp, initializer_list<_Up>&,
|
||||
_Args&&...>::value>
|
||||
emplace(initializer_list<_Up> __il, _Args&&... __args)
|
||||
{
|
||||
@ -712,6 +702,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
constexpr explicit operator bool() const noexcept
|
||||
{ return this->_M_is_engaged(); }
|
||||
|
||||
constexpr bool has_value() const noexcept
|
||||
{ return this->_M_is_engaged(); }
|
||||
|
||||
constexpr const _Tp&
|
||||
value() const&
|
||||
{
|
||||
@ -777,6 +770,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
? std::move(this->_M_get())
|
||||
: static_cast<_Tp>(std::forward<_Up>(__u));
|
||||
}
|
||||
void reset() { this->_M_reset(); }
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
@ -980,6 +974,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
make_optional(_Tp&& __t)
|
||||
{ return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
|
||||
|
||||
template<typename _Tp, typename ..._Args>
|
||||
constexpr optional<_Tp>
|
||||
make_optional(_Args&&... __args)
|
||||
{ return optional<_Tp> { in_place, std::forward<_Args>(__args)... }; }
|
||||
|
||||
template<typename _Tp, typename _Up, typename ..._Args>
|
||||
constexpr optional<_Tp>
|
||||
make_optional(initializer_list<_Up> __il, _Args&&... __args)
|
||||
{ return optional<_Tp> { in_place, __il, std::forward<_Args>(__args)... }; }
|
||||
|
||||
// [X.Y.12]
|
||||
template<typename _Tp>
|
||||
struct hash<optional<_Tp>>
|
||||
|
@ -75,6 +75,10 @@
|
||||
#include <bits/move.h>
|
||||
#include <initializer_list>
|
||||
|
||||
#if __cplusplus > 201402L
|
||||
#include <exception>
|
||||
#endif
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
@ -330,6 +334,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
using index_sequence_for = make_index_sequence<sizeof...(_Types)>;
|
||||
#endif
|
||||
|
||||
#if __cplusplus > 201402L
|
||||
|
||||
struct in_place_tag {
|
||||
in_place_tag() = delete;
|
||||
};
|
||||
|
||||
struct __in_place;
|
||||
template<typename _Tp> struct __in_place_type;
|
||||
template<size_t _Idx> struct __in_place_index;
|
||||
|
||||
using in_place_t = in_place_tag(&)(__in_place*);
|
||||
template <class _Tp>
|
||||
using in_place_type_t = in_place_tag(&)(__in_place_type<_Tp>*);
|
||||
template <int _Idx>
|
||||
using in_place_index_t = in_place_tag(&)(__in_place_index<_Idx>*);
|
||||
|
||||
inline in_place_tag in_place(__in_place*) {terminate();}
|
||||
template <class _Tp>
|
||||
in_place_tag in_place(__in_place_type<_Tp>*) {terminate();}
|
||||
template <size_t _Idx>
|
||||
in_place_tag in_place(__in_place_index<_Idx>*) {terminate();}
|
||||
|
||||
#endif
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace
|
||||
|
||||
|
@ -28,12 +28,12 @@ void test01()
|
||||
any x;
|
||||
any y;
|
||||
y = x;
|
||||
VERIFY( x.empty() );
|
||||
VERIFY( y.empty() );
|
||||
VERIFY( !x.has_value() );
|
||||
VERIFY( !y.has_value() );
|
||||
|
||||
y = std::move(x);
|
||||
VERIFY( x.empty() );
|
||||
VERIFY( y.empty() );
|
||||
VERIFY( !x.has_value() );
|
||||
VERIFY( !y.has_value() );
|
||||
}
|
||||
|
||||
void test02()
|
||||
@ -41,16 +41,16 @@ void test02()
|
||||
any x(1);
|
||||
any y;
|
||||
y = x;
|
||||
VERIFY( !x.empty() );
|
||||
VERIFY( !y.empty() );
|
||||
VERIFY( x.has_value() );
|
||||
VERIFY( y.has_value() );
|
||||
|
||||
x = std::move(y);
|
||||
VERIFY( !x.empty() );
|
||||
VERIFY( y.empty() );
|
||||
VERIFY( x.has_value() );
|
||||
VERIFY( !y.has_value() );
|
||||
|
||||
x = y;
|
||||
VERIFY( x.empty() );
|
||||
VERIFY( y.empty() );
|
||||
VERIFY( !x.has_value() );
|
||||
VERIFY( !y.has_value() );
|
||||
}
|
||||
|
||||
int main()
|
||||
|
62
libstdc++-v3/testsuite/20_util/any/assign/emplace.cc
Normal file
62
libstdc++-v3/testsuite/20_util/any/assign/emplace.cc
Normal file
@ -0,0 +1,62 @@
|
||||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do run }
|
||||
|
||||
// Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a moved_to of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <any>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
|
||||
struct combined {
|
||||
std::vector<int> v;
|
||||
std::tuple<int, int> t;
|
||||
template<class... Args>
|
||||
combined(std::initializer_list<int> il, Args&&... args)
|
||||
: v(il), t(std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
const int i = 42;
|
||||
std::any o;
|
||||
o.emplace<int>(i);
|
||||
int& i2 = std::any_cast<int&>(o);
|
||||
VERIFY( i2 == 42 );
|
||||
VERIFY( &i2 != &i );
|
||||
std::any o2;
|
||||
o2.emplace<std::tuple<int, int>>(1, 2);
|
||||
std::tuple<int, int>& t = std::any_cast<std::tuple<int, int>&>(o2);
|
||||
VERIFY( std::get<0>(t) == 1 && std::get<1>(t) == 2);
|
||||
std::any o3;
|
||||
o3.emplace<std::vector<int>>({42, 666});
|
||||
std::vector<int>& v = std::any_cast<std::vector<int>&>(o3);
|
||||
VERIFY(v[0] == 42 && v[1] == 666);
|
||||
std::any o4;
|
||||
o4.emplace<combined>({42, 666});
|
||||
combined& c = std::any_cast<combined&>(o4);
|
||||
VERIFY(c.v[0] == 42 && c.v[1] == 666
|
||||
&& std::get<0>(c.t) == 0 && std::get<1>(c.t) == 0 );
|
||||
std::any o5;
|
||||
o5.emplace<combined>({1, 2}, 3, 4);
|
||||
combined& c2 = std::any_cast<combined&>(o5);
|
||||
VERIFY(c2.v[0] == 1 && c2.v[1] == 2
|
||||
&& std::get<0>(c2.t) == 3 && std::get<1>(c2.t) == 4 );
|
||||
}
|
@ -36,13 +36,13 @@ test01()
|
||||
|
||||
any a;
|
||||
a = a;
|
||||
VERIFY( a.empty() );
|
||||
VERIFY( !a.has_value() );
|
||||
|
||||
a = A{};
|
||||
a = a;
|
||||
VERIFY( !a.empty() );
|
||||
VERIFY( a.has_value() );
|
||||
|
||||
a.clear();
|
||||
a.reset();
|
||||
VERIFY( live_objects.empty() );
|
||||
}
|
||||
|
||||
@ -57,13 +57,13 @@ test02()
|
||||
|
||||
X x;
|
||||
std::swap(x, x); // results in "self-move-assignment" of X::a
|
||||
VERIFY( x.a.empty() );
|
||||
VERIFY( !x.a.has_value() );
|
||||
|
||||
x.a = A{};
|
||||
std::swap(x, x); // results in "self-move-assignment" of X::a
|
||||
VERIFY( !x.a.empty() );
|
||||
VERIFY( x.a.has_value() );
|
||||
|
||||
x.a.clear();
|
||||
x.a.reset();
|
||||
VERIFY( live_objects.empty() );
|
||||
}
|
||||
|
||||
@ -74,13 +74,13 @@ test03()
|
||||
|
||||
any a;
|
||||
a.swap(a);
|
||||
VERIFY( a.empty() );
|
||||
VERIFY( !a.has_value() );
|
||||
|
||||
a = A{};
|
||||
a.swap(a);
|
||||
VERIFY( !a.empty() );
|
||||
VERIFY( a.has_value() );
|
||||
|
||||
a.clear();
|
||||
a.reset();
|
||||
VERIFY( live_objects.empty() );
|
||||
}
|
||||
|
||||
|
@ -26,29 +26,29 @@ using std::any;
|
||||
void test01()
|
||||
{
|
||||
any x;
|
||||
VERIFY( x.empty() );
|
||||
VERIFY( !x.has_value() );
|
||||
|
||||
any y(x);
|
||||
VERIFY( x.empty() );
|
||||
VERIFY( y.empty() );
|
||||
VERIFY( !x.has_value() );
|
||||
VERIFY( !y.has_value() );
|
||||
|
||||
any z(std::move(y));
|
||||
VERIFY( y.empty() );
|
||||
VERIFY( z.empty() );
|
||||
VERIFY( !y.has_value() );
|
||||
VERIFY( !z.has_value() );
|
||||
}
|
||||
|
||||
void test02()
|
||||
{
|
||||
any x(1);
|
||||
VERIFY( !x.empty() );
|
||||
VERIFY( x.has_value() );
|
||||
|
||||
any y(x);
|
||||
VERIFY( !x.empty() );
|
||||
VERIFY( !y.empty() );
|
||||
VERIFY( x.has_value() );
|
||||
VERIFY( y.has_value() );
|
||||
|
||||
any z(std::move(y));
|
||||
VERIFY( y.empty() );
|
||||
VERIFY( !z.empty() );
|
||||
VERIFY( !y.has_value() );
|
||||
VERIFY( z.has_value() );
|
||||
}
|
||||
|
||||
int main()
|
||||
|
57
libstdc++-v3/testsuite/20_util/any/cons/in_place.cc
Normal file
57
libstdc++-v3/testsuite/20_util/any/cons/in_place.cc
Normal file
@ -0,0 +1,57 @@
|
||||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do run }
|
||||
|
||||
// Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a moved_to of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <any>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
|
||||
struct combined {
|
||||
std::vector<int> v;
|
||||
std::tuple<int, int> t;
|
||||
template<class... Args>
|
||||
combined(std::initializer_list<int> il, Args&&... args)
|
||||
: v(il), t(std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
const int i = 42;
|
||||
std::any o(std::in_place<int>, i);
|
||||
int& i2 = std::any_cast<int&>(o);
|
||||
VERIFY( i2 == 42 );
|
||||
VERIFY( &i2 != &i );
|
||||
std::any o2(std::in_place<std::tuple<int, int>>, 1, 2);
|
||||
std::tuple<int, int>& t = std::any_cast<std::tuple<int, int>&>(o2);
|
||||
VERIFY( std::get<0>(t) == 1 && std::get<1>(t) == 2);
|
||||
std::any o3(std::in_place<std::vector<int>>, {42, 666});
|
||||
std::vector<int>& v = std::any_cast<std::vector<int>&>(o3);
|
||||
VERIFY(v[0] == 42 && v[1] == 666);
|
||||
std::any o4(std::in_place<combined>, {42, 666});
|
||||
combined& c = std::any_cast<combined&>(o4);
|
||||
VERIFY(c.v[0] == 42 && c.v[1] == 666
|
||||
&& std::get<0>(c.t) == 0 && std::get<1>(c.t) == 0 );
|
||||
std::any o5(std::in_place<combined>, {1, 2}, 3, 4);
|
||||
combined& c2 = std::any_cast<combined&>(o5);
|
||||
VERIFY(c2.v[0] == 1 && c2.v[1] == 2
|
||||
&& std::get<0>(c2.t) == 3 && std::get<1>(c2.t) == 4 );
|
||||
}
|
57
libstdc++-v3/testsuite/20_util/any/make_any.cc
Normal file
57
libstdc++-v3/testsuite/20_util/any/make_any.cc
Normal file
@ -0,0 +1,57 @@
|
||||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do run }
|
||||
|
||||
// Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a moved_to of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <any>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
|
||||
struct combined {
|
||||
std::vector<int> v;
|
||||
std::tuple<int, int> t;
|
||||
template<class... Args>
|
||||
combined(std::initializer_list<int> il, Args&&... args)
|
||||
: v(il), t(std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
const int i = 42;
|
||||
auto o = std::make_any<int>(i);
|
||||
int& i2 = std::any_cast<int&>(o);
|
||||
VERIFY( i2 == 42 );
|
||||
VERIFY( &i2 != &i );
|
||||
auto o2 = std::make_any<std::tuple<int, int>>(1, 2);
|
||||
std::tuple<int, int>& t = std::any_cast<std::tuple<int, int>&>(o2);
|
||||
VERIFY( std::get<0>(t) == 1 && std::get<1>(t) == 2);
|
||||
auto o3 = std::make_any<std::vector<int>>({42, 666});
|
||||
std::vector<int>& v = std::any_cast<std::vector<int>&>(o3);
|
||||
VERIFY(v[0] == 42 && v[1] == 666);
|
||||
auto o4 = std::make_any<combined>({42, 666});
|
||||
combined& c = std::any_cast<combined&>(o4);
|
||||
VERIFY(c.v[0] == 42 && c.v[1] == 666
|
||||
&& std::get<0>(c.t) == 0 && std::get<1>(c.t) == 0 );
|
||||
auto o5 = std::make_any<combined>({1, 2}, 3, 4);
|
||||
combined& c2 = std::any_cast<combined&>(o5);
|
||||
VERIFY(c2.v[0] == 1 && c2.v[1] == 2
|
||||
&& std::get<0>(c2.t) == 3 && std::get<1>(c2.t) == 4 );
|
||||
}
|
@ -26,5 +26,5 @@ void test01()
|
||||
using std::any_cast;
|
||||
|
||||
const any y(1);
|
||||
any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 357 }
|
||||
any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 435 }
|
||||
}
|
||||
|
@ -28,8 +28,8 @@ void test01()
|
||||
any x(1);
|
||||
any y;
|
||||
swap(x, y);
|
||||
VERIFY( x.empty() );
|
||||
VERIFY( !y.empty() );
|
||||
VERIFY( !x.has_value() );
|
||||
VERIFY( y.has_value() );
|
||||
}
|
||||
|
||||
int main()
|
||||
|
@ -28,14 +28,14 @@ void test01()
|
||||
any x(1);
|
||||
any y;
|
||||
x.swap(y);
|
||||
VERIFY( x.empty() );
|
||||
VERIFY( !y.empty() );
|
||||
VERIFY( !x.has_value() );
|
||||
VERIFY( y.has_value() );
|
||||
x.swap(y);
|
||||
VERIFY( !x.empty() );
|
||||
VERIFY( y.empty() );
|
||||
VERIFY( x.has_value() );
|
||||
VERIFY( !y.has_value() );
|
||||
|
||||
x.clear();
|
||||
VERIFY( x.empty() );
|
||||
x.reset();
|
||||
VERIFY( !x.has_value() );
|
||||
}
|
||||
|
||||
int main()
|
||||
|
33
libstdc++-v3/testsuite/20_util/any/requirements.cc
Normal file
33
libstdc++-v3/testsuite/20_util/any/requirements.cc
Normal file
@ -0,0 +1,33 @@
|
||||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do compile }
|
||||
|
||||
// Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a moved_to of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <any>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
using std::any;
|
||||
using std::unique_ptr;
|
||||
|
||||
static_assert(std::is_assignable<any&, int>::value);
|
||||
static_assert(!std::is_assignable<any&, unique_ptr<int>>::value);
|
||||
static_assert(std::is_constructible<any, int>::value);
|
||||
static_assert(!std::is_constructible<any, unique_ptr<int>>::value);
|
||||
|
47
libstdc++-v3/testsuite/20_util/in_place/requirements.cc
Normal file
47
libstdc++-v3/testsuite/20_util/in_place/requirements.cc
Normal file
@ -0,0 +1,47 @@
|
||||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do compile }
|
||||
|
||||
// Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a moved_to of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
using std::in_place_t;
|
||||
using std::in_place_type_t;
|
||||
using std::in_place_index_t;
|
||||
|
||||
float f(in_place_type_t<float>);
|
||||
double f(in_place_type_t<double>);
|
||||
char f(in_place_index_t<0>);
|
||||
unsigned int f(in_place_index_t<1>);
|
||||
int f(in_place_t);
|
||||
|
||||
static_assert(std::is_same<decltype(f(in_place_t(std::in_place))), int>::value);
|
||||
static_assert(std::is_same<decltype(f(std::in_place<float>)), float>::value);
|
||||
static_assert(std::is_same<decltype(f(std::in_place<double>)), double>::value);
|
||||
static_assert(std::is_same<decltype(f(std::in_place<0>)), char>::value);
|
||||
static_assert(std::is_same<decltype(f(std::in_place<1>)), unsigned int>::value);
|
||||
|
||||
template <class T, class... Args> float h(in_place_type_t<T>, Args&&...);
|
||||
template <size_t N, class... Args> int h(in_place_index_t<N>, Args&&...);
|
||||
template <class T> double h(in_place_t, T&&);
|
||||
|
||||
static_assert(std::is_same<decltype(h(std::in_place, 1)), double>::value);
|
||||
static_assert(std::is_same<decltype(h(std::in_place<float>, 1)), float>::value);
|
||||
static_assert(std::is_same<decltype(h(std::in_place<0>, 1)), int>::value);
|
@ -24,9 +24,6 @@
|
||||
int main()
|
||||
{
|
||||
// [20.5.5] In-place construction
|
||||
static_assert( std::is_same<decltype(std::in_place), const std::in_place_t>(), "" );
|
||||
static_assert( std::is_empty<std::in_place_t>(), "" );
|
||||
|
||||
{
|
||||
constexpr std::optional<int> o { std::in_place };
|
||||
static_assert( o, "" );
|
||||
|
@ -26,9 +26,6 @@
|
||||
int main()
|
||||
{
|
||||
// [20.5.5] In-place construction
|
||||
static_assert( std::is_same<decltype(std::in_place), const std::in_place_t>(), "" );
|
||||
static_assert( std::is_empty<std::in_place_t>(), "" );
|
||||
|
||||
{
|
||||
std::optional<int> o { std::in_place };
|
||||
VERIFY( o );
|
||||
|
@ -20,6 +20,18 @@
|
||||
|
||||
#include <optional>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
|
||||
struct combined {
|
||||
std::vector<int> v;
|
||||
std::tuple<int, int> t;
|
||||
template<class... Args>
|
||||
combined(std::initializer_list<int> il, Args&&... args)
|
||||
: v(il), t(std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -28,4 +40,22 @@ int main()
|
||||
static_assert( std::is_same<decltype(o), std::optional<int>>(), "" );
|
||||
VERIFY( o && *o == 42 );
|
||||
VERIFY( &*o != &i );
|
||||
auto o2 = std::make_optional<std::tuple<int, int>>(1, 2);
|
||||
static_assert( std::is_same<decltype(o2),
|
||||
std::optional<std::tuple<int, int>>>(), "" );
|
||||
VERIFY( o2 && std::get<0>(*o2) == 1 && std::get<1>(*o2) == 2);
|
||||
auto o3 = std::make_optional<std::vector<int>>({42, 666});
|
||||
static_assert( std::is_same<decltype(o3),
|
||||
std::optional<std::vector<int>>>(), "" );
|
||||
VERIFY(o3 && (*o3)[0] == 42 && (*o3)[1] == 666);
|
||||
auto o4 = std::make_optional<combined>({42, 666});
|
||||
static_assert( std::is_same<decltype(o4),
|
||||
std::optional<combined>>(), "" );
|
||||
VERIFY(o4 && (o4->v)[0] == 42 && (o4->v)[1] == 666
|
||||
&& std::get<0>(o4->t) == 0 && std::get<1>(o4->t) == 0 );
|
||||
auto o5 = std::make_optional<combined>({1, 2}, 3, 4);
|
||||
static_assert( std::is_same<decltype(o5),
|
||||
std::optional<combined>>(), "" );
|
||||
VERIFY(o4 && (o5->v)[0] == 1 && (o5->v)[1] == 2
|
||||
&& std::get<0>(o5->t) == 3 && std::get<1>(o5->t) == 4 );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user