From 25a69162c99e78e9a23066f6c4465176ee4b6213 Mon Sep 17 00:00:00 2001 From: Ville Voutilainen Date: Thu, 14 Jul 2016 12:10:05 +0300 Subject: [PATCH] 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 --- libstdc++-v3/ChangeLog | 59 ++++++++ libstdc++-v3/include/std/any | 142 ++++++++++++++---- libstdc++-v3/include/std/optional | 30 ++-- libstdc++-v3/include/std/utility | 28 ++++ .../testsuite/20_util/any/assign/1.cc | 20 +-- .../testsuite/20_util/any/assign/emplace.cc | 62 ++++++++ .../testsuite/20_util/any/assign/self.cc | 18 +-- libstdc++-v3/testsuite/20_util/any/cons/1.cc | 20 +-- .../testsuite/20_util/any/cons/in_place.cc | 57 +++++++ .../testsuite/20_util/any/make_any.cc | 57 +++++++ .../20_util/any/misc/any_cast_neg.cc | 2 +- .../testsuite/20_util/any/misc/swap.cc | 4 +- .../testsuite/20_util/any/modifiers/1.cc | 12 +- .../testsuite/20_util/any/requirements.cc | 33 ++++ .../20_util/in_place/requirements.cc | 47 ++++++ .../20_util/optional/constexpr/in_place.cc | 3 - .../testsuite/20_util/optional/in_place.cc | 3 - .../20_util/optional/make_optional.cc | 30 ++++ 18 files changed, 538 insertions(+), 89 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/any/assign/emplace.cc create mode 100644 libstdc++-v3/testsuite/20_util/any/cons/in_place.cc create mode 100644 libstdc++-v3/testsuite/20_util/any/make_any.cc create mode 100644 libstdc++-v3/testsuite/20_util/any/requirements.cc create mode 100644 libstdc++-v3/testsuite/20_util/in_place/requirements.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 70ad53a0531..a34ca218797 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,62 @@ +2016-07-14 Ville Voutilainen + + 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 Implement P0307R2, Making Optional Greater Equal Again. diff --git a/libstdc++-v3/include/std/any b/libstdc++-v3/include/std/any index 2e8baa6f8dd..54882d797e2 100644 --- a/libstdc++-v3/include/std/any +++ b/libstdc++-v3/include/std/any @@ -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 + using __any_constructible_t = + enable_if_t<__and_, + is_constructible<_Tp, _Args...>>::value, + bool>; + /// Construct with a copy of @p __value as the contained object. template , typename _Mgr = _Manager<_Tp>, - typename enable_if::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 _Mgr = _Manager<_Tp>, - typename enable_if::value, - bool>::type = false> + enable_if_t<__and_, + __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 , + __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 , + __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 - enable_if_t>::value, any&> + enable_if_t<__and_<__not_>>, + 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 , + __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 , + __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 + 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 + 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 + 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 + any make_any(initializer_list<_Up> __il, _Args&&... __args) + { + return any(in_place<_Tp>, __il, std::forward<_Args>(__args)...); + } + /** * @brief Access the contained object. * diff --git a/libstdc++-v3/include/std/optional b/libstdc++-v3/include/std/optional index f1bb17c75dc..2ea4fddb31d 100644 --- a/libstdc++-v3/include/std/optional +++ b/libstdc++-v3/include/std/optional @@ -57,13 +57,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template 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 - void + enable_if_t::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 - enable_if_t&, + enable_if_t&, _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 @@ -980,6 +974,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION make_optional(_Tp&& __t) { return optional> { std::forward<_Tp>(__t) }; } + template + constexpr optional<_Tp> + make_optional(_Args&&... __args) + { return optional<_Tp> { in_place, std::forward<_Args>(__args)... }; } + + template + 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 struct hash> diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility index 1451a91d42a..106ba4dfcf3 100644 --- a/libstdc++-v3/include/std/utility +++ b/libstdc++-v3/include/std/utility @@ -75,6 +75,10 @@ #include #include +#if __cplusplus > 201402L +#include +#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; #endif +#if __cplusplus > 201402L + + struct in_place_tag { + in_place_tag() = delete; + }; + + struct __in_place; + template struct __in_place_type; + template struct __in_place_index; + + using in_place_t = in_place_tag(&)(__in_place*); + template + using in_place_type_t = in_place_tag(&)(__in_place_type<_Tp>*); + template + using in_place_index_t = in_place_tag(&)(__in_place_index<_Idx>*); + + inline in_place_tag in_place(__in_place*) {terminate();} + template + in_place_tag in_place(__in_place_type<_Tp>*) {terminate();} + template + in_place_tag in_place(__in_place_index<_Idx>*) {terminate();} + +#endif + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/testsuite/20_util/any/assign/1.cc b/libstdc++-v3/testsuite/20_util/any/assign/1.cc index 582a92d2f07..5e3ffa70ce6 100644 --- a/libstdc++-v3/testsuite/20_util/any/assign/1.cc +++ b/libstdc++-v3/testsuite/20_util/any/assign/1.cc @@ -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() diff --git a/libstdc++-v3/testsuite/20_util/any/assign/emplace.cc b/libstdc++-v3/testsuite/20_util/any/assign/emplace.cc new file mode 100644 index 00000000000..663bae27f38 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/any/assign/emplace.cc @@ -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 +// . + +#include +#include +#include +#include + +struct combined { + std::vector v; + std::tuple t; + template + combined(std::initializer_list il, Args&&... args) + : v(il), t(std::forward(args)...) + { + } +}; + +int main() +{ + const int i = 42; + std::any o; + o.emplace(i); + int& i2 = std::any_cast(o); + VERIFY( i2 == 42 ); + VERIFY( &i2 != &i ); + std::any o2; + o2.emplace>(1, 2); + std::tuple& t = std::any_cast&>(o2); + VERIFY( std::get<0>(t) == 1 && std::get<1>(t) == 2); + std::any o3; + o3.emplace>({42, 666}); + std::vector& v = std::any_cast&>(o3); + VERIFY(v[0] == 42 && v[1] == 666); + std::any o4; + o4.emplace({42, 666}); + combined& c = std::any_cast(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({1, 2}, 3, 4); + combined& c2 = std::any_cast(o5); + VERIFY(c2.v[0] == 1 && c2.v[1] == 2 + && std::get<0>(c2.t) == 3 && std::get<1>(c2.t) == 4 ); +} diff --git a/libstdc++-v3/testsuite/20_util/any/assign/self.cc b/libstdc++-v3/testsuite/20_util/any/assign/self.cc index e773efad11c..f0bf12838c7 100644 --- a/libstdc++-v3/testsuite/20_util/any/assign/self.cc +++ b/libstdc++-v3/testsuite/20_util/any/assign/self.cc @@ -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() ); } diff --git a/libstdc++-v3/testsuite/20_util/any/cons/1.cc b/libstdc++-v3/testsuite/20_util/any/cons/1.cc index d66320413d4..59af878a60c 100644 --- a/libstdc++-v3/testsuite/20_util/any/cons/1.cc +++ b/libstdc++-v3/testsuite/20_util/any/cons/1.cc @@ -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() diff --git a/libstdc++-v3/testsuite/20_util/any/cons/in_place.cc b/libstdc++-v3/testsuite/20_util/any/cons/in_place.cc new file mode 100644 index 00000000000..2368b83d250 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/any/cons/in_place.cc @@ -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 +// . + +#include +#include +#include +#include + +struct combined { + std::vector v; + std::tuple t; + template + combined(std::initializer_list il, Args&&... args) + : v(il), t(std::forward(args)...) + { + } +}; + +int main() +{ + const int i = 42; + std::any o(std::in_place, i); + int& i2 = std::any_cast(o); + VERIFY( i2 == 42 ); + VERIFY( &i2 != &i ); + std::any o2(std::in_place>, 1, 2); + std::tuple& t = std::any_cast&>(o2); + VERIFY( std::get<0>(t) == 1 && std::get<1>(t) == 2); + std::any o3(std::in_place>, {42, 666}); + std::vector& v = std::any_cast&>(o3); + VERIFY(v[0] == 42 && v[1] == 666); + std::any o4(std::in_place, {42, 666}); + combined& c = std::any_cast(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, {1, 2}, 3, 4); + combined& c2 = std::any_cast(o5); + VERIFY(c2.v[0] == 1 && c2.v[1] == 2 + && std::get<0>(c2.t) == 3 && std::get<1>(c2.t) == 4 ); +} diff --git a/libstdc++-v3/testsuite/20_util/any/make_any.cc b/libstdc++-v3/testsuite/20_util/any/make_any.cc new file mode 100644 index 00000000000..4ec245bfdae --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/any/make_any.cc @@ -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 +// . + +#include +#include +#include +#include + +struct combined { + std::vector v; + std::tuple t; + template + combined(std::initializer_list il, Args&&... args) + : v(il), t(std::forward(args)...) + { + } +}; + +int main() +{ + const int i = 42; + auto o = std::make_any(i); + int& i2 = std::any_cast(o); + VERIFY( i2 == 42 ); + VERIFY( &i2 != &i ); + auto o2 = std::make_any>(1, 2); + std::tuple& t = std::any_cast&>(o2); + VERIFY( std::get<0>(t) == 1 && std::get<1>(t) == 2); + auto o3 = std::make_any>({42, 666}); + std::vector& v = std::any_cast&>(o3); + VERIFY(v[0] == 42 && v[1] == 666); + auto o4 = std::make_any({42, 666}); + combined& c = std::any_cast(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({1, 2}, 3, 4); + combined& c2 = std::any_cast(o5); + VERIFY(c2.v[0] == 1 && c2.v[1] == 2 + && std::get<0>(c2.t) == 3 && std::get<1>(c2.t) == 4 ); +} diff --git a/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc b/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc index 43c6c6b4a26..32b4e767fd2 100644 --- a/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc +++ b/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc @@ -26,5 +26,5 @@ void test01() using std::any_cast; const any y(1); - any_cast(y); // { dg-error "qualifiers" "" { target { *-*-* } } 357 } + any_cast(y); // { dg-error "qualifiers" "" { target { *-*-* } } 435 } } diff --git a/libstdc++-v3/testsuite/20_util/any/misc/swap.cc b/libstdc++-v3/testsuite/20_util/any/misc/swap.cc index 0b3e1eb26de..26a86dd5cfc 100644 --- a/libstdc++-v3/testsuite/20_util/any/misc/swap.cc +++ b/libstdc++-v3/testsuite/20_util/any/misc/swap.cc @@ -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() diff --git a/libstdc++-v3/testsuite/20_util/any/modifiers/1.cc b/libstdc++-v3/testsuite/20_util/any/modifiers/1.cc index 36b9c247843..39cbe96fd8d 100644 --- a/libstdc++-v3/testsuite/20_util/any/modifiers/1.cc +++ b/libstdc++-v3/testsuite/20_util/any/modifiers/1.cc @@ -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() diff --git a/libstdc++-v3/testsuite/20_util/any/requirements.cc b/libstdc++-v3/testsuite/20_util/any/requirements.cc new file mode 100644 index 00000000000..67e4253c557 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/any/requirements.cc @@ -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 +// . + +#include +#include + +#include + +using std::any; +using std::unique_ptr; + +static_assert(std::is_assignable::value); +static_assert(!std::is_assignable>::value); +static_assert(std::is_constructible::value); +static_assert(!std::is_constructible>::value); + diff --git a/libstdc++-v3/testsuite/20_util/in_place/requirements.cc b/libstdc++-v3/testsuite/20_util/in_place/requirements.cc new file mode 100644 index 00000000000..fc141d862fd --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/in_place/requirements.cc @@ -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 +// . + +#include +#include +#include + +using std::in_place_t; +using std::in_place_type_t; +using std::in_place_index_t; + +float f(in_place_type_t); +double f(in_place_type_t); +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::value); +static_assert(std::is_same)), float>::value); +static_assert(std::is_same)), double>::value); +static_assert(std::is_same)), char>::value); +static_assert(std::is_same)), unsigned int>::value); + +template float h(in_place_type_t, Args&&...); +template int h(in_place_index_t, Args&&...); +template double h(in_place_t, T&&); + +static_assert(std::is_same::value); +static_assert(std::is_same, 1)), float>::value); +static_assert(std::is_same, 1)), int>::value); diff --git a/libstdc++-v3/testsuite/20_util/optional/constexpr/in_place.cc b/libstdc++-v3/testsuite/20_util/optional/constexpr/in_place.cc index cd75275aaff..6db03ea5138 100644 --- a/libstdc++-v3/testsuite/20_util/optional/constexpr/in_place.cc +++ b/libstdc++-v3/testsuite/20_util/optional/constexpr/in_place.cc @@ -24,9 +24,6 @@ int main() { // [20.5.5] In-place construction - static_assert( std::is_same(), "" ); - static_assert( std::is_empty(), "" ); - { constexpr std::optional o { std::in_place }; static_assert( o, "" ); diff --git a/libstdc++-v3/testsuite/20_util/optional/in_place.cc b/libstdc++-v3/testsuite/20_util/optional/in_place.cc index ef8c744f1dc..53059dbba7f 100644 --- a/libstdc++-v3/testsuite/20_util/optional/in_place.cc +++ b/libstdc++-v3/testsuite/20_util/optional/in_place.cc @@ -26,9 +26,6 @@ int main() { // [20.5.5] In-place construction - static_assert( std::is_same(), "" ); - static_assert( std::is_empty(), "" ); - { std::optional o { std::in_place }; VERIFY( o ); diff --git a/libstdc++-v3/testsuite/20_util/optional/make_optional.cc b/libstdc++-v3/testsuite/20_util/optional/make_optional.cc index 6f245c716ad..b288a250bd5 100644 --- a/libstdc++-v3/testsuite/20_util/optional/make_optional.cc +++ b/libstdc++-v3/testsuite/20_util/optional/make_optional.cc @@ -20,6 +20,18 @@ #include #include +#include +#include + +struct combined { + std::vector v; + std::tuple t; + template + combined(std::initializer_list il, Args&&... args) + : v(il), t(std::forward(args)...) + { + } +}; int main() { @@ -28,4 +40,22 @@ int main() static_assert( std::is_same>(), "" ); VERIFY( o && *o == 42 ); VERIFY( &*o != &i ); + auto o2 = std::make_optional>(1, 2); + static_assert( std::is_same>>(), "" ); + VERIFY( o2 && std::get<0>(*o2) == 1 && std::get<1>(*o2) == 2); + auto o3 = std::make_optional>({42, 666}); + static_assert( std::is_same>>(), "" ); + VERIFY(o3 && (*o3)[0] == 42 && (*o3)[1] == 666); + auto o4 = std::make_optional({42, 666}); + static_assert( std::is_same>(), "" ); + 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({1, 2}, 3, 4); + static_assert( std::is_same>(), "" ); + VERIFY(o4 && (o5->v)[0] == 1 && (o5->v)[1] == 2 + && std::get<0>(o5->t) == 3 && std::get<1>(o5->t) == 4 ); } -- 2.30.2