diff options
author | Ville Voutilainen <ville.voutilainen@gmail.com> | 2016-07-14 12:10:05 +0300 |
---|---|---|
committer | Ville Voutilainen <ville@gcc.gnu.org> | 2016-07-14 12:10:05 +0300 |
commit | 25a69162c99e78e9a23066f6c4465176ee4b6213 (patch) | |
tree | 55dbc3ec38b350b3bd5207f535070577e1812ae0 /libstdc++-v3 | |
parent | c0d31471bade3deb8f1d7e3110e0d40c1555f849 (diff) | |
download | gcc-25a69162c99e78e9a23066f6c4465176ee4b6213.zip gcc-25a69162c99e78e9a23066f6c4465176ee4b6213.tar.gz gcc-25a69162c99e78e9a23066f6c4465176ee4b6213.tar.bz2 |
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
Diffstat (limited to 'libstdc++-v3')
18 files changed, 538 insertions, 89 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 70ad53a..a34ca21 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -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. diff --git a/libstdc++-v3/include/std/any b/libstdc++-v3/include/std/any index 2e8baa6..54882d7 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 <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. * diff --git a/libstdc++-v3/include/std/optional b/libstdc++-v3/include/std/optional index f1bb17c..2ea4fdd 100644 --- a/libstdc++-v3/include/std/optional +++ b/libstdc++-v3/include/std/optional @@ -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>> diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility index 1451a91..106ba4d 100644 --- a/libstdc++-v3/include/std/utility +++ b/libstdc++-v3/include/std/utility @@ -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 diff --git a/libstdc++-v3/testsuite/20_util/any/assign/1.cc b/libstdc++-v3/testsuite/20_util/any/assign/1.cc index 582a92d..5e3ffa7 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 0000000..663bae2 --- /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 +// <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 ); +} diff --git a/libstdc++-v3/testsuite/20_util/any/assign/self.cc b/libstdc++-v3/testsuite/20_util/any/assign/self.cc index e773efa..f0bf128 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 d663204..59af878 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 0000000..2368b83 --- /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 +// <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 ); +} 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 0000000..4ec245b --- /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 +// <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 ); +} 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 43c6c6b..32b4e76 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<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 357 } + any_cast<int&>(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 0b3e1eb..26a86dd 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 36b9c24..39cbe96 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 0000000..67e4253 --- /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 +// <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); + 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 0000000..fc141d8 --- /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 +// <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); 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 cd75275..6db03ea 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<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, "" ); diff --git a/libstdc++-v3/testsuite/20_util/optional/in_place.cc b/libstdc++-v3/testsuite/20_util/optional/in_place.cc index ef8c744..53059db 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<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 ); diff --git a/libstdc++-v3/testsuite/20_util/optional/make_optional.cc b/libstdc++-v3/testsuite/20_util/optional/make_optional.cc index 6f245c7..b288a25 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 <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 ); } |