diff options
author | Ville Voutilainen <ville.voutilainen@gmail.com> | 2016-10-24 15:46:44 +0300 |
---|---|---|
committer | Ville Voutilainen <ville@gcc.gnu.org> | 2016-10-24 15:46:44 +0300 |
commit | f11cc05023b90e1d24521cc09a065497732a8f6f (patch) | |
tree | 3a1b63e17adc7ada6334846b6f90783e87546b43 /libstdc++-v3 | |
parent | 405def8d4667163a262f6c9fcb4a8f675dae4193 (diff) | |
download | gcc-f11cc05023b90e1d24521cc09a065497732a8f6f.zip gcc-f11cc05023b90e1d24521cc09a065497732a8f6f.tar.gz gcc-f11cc05023b90e1d24521cc09a065497732a8f6f.tar.bz2 |
Cross-port the latest resolution of LWG2756 and some bug-fixes to experimental::optional.
Cross-port the latest resolution of LWG2756 and some
bug-fixes to experimental::optional.
PR libstdc++/77288
PR libstdc++/77727
* include/experimental/optional (_Optional_base):
Remove constructors that take a _Tp.
(__is_optional_impl, __is_optional): Remove.
(__converts_from_optional): New.
(optional(_Up&&)): Fix constraints, call base with in_place.
(optional(const optional<_Up>&)): Fix constraints, use emplace.
(optional(optional<_Up>&&)): Likewise.
(operator=(_Up&&)): Fix constraints.
(operator=(const optional<_Up>&)): Likewise.
(operator=(optional<_Up>&&)): Likewise.
(emplace(_Args&&...)): Constrain.
(emplace(initializer_list<_Up>, _Args&&...)): Likewise.
* testsuite/experimental/optional/77288.cc: New.
* testsuite/experimental/optional/assignment/5.cc: Adjust.
* testsuite/experimental/optional/cons/77727.cc: New.
* testsuite/experimental/optional/cons/value.cc: Adjust.
From-SVN: r241476
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 23 | ||||
-rw-r--r-- | libstdc++-v3/include/experimental/optional | 169 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/experimental/optional/77288.cc | 405 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/experimental/optional/assignment/5.cc | 11 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/experimental/optional/cons/77727.cc | 50 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/experimental/optional/cons/value.cc | 27 |
6 files changed, 594 insertions, 91 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 7d0a002..1a18ede 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,26 @@ +2016-10-24 Ville Voutilainen <ville.voutilainen@gmail.com> + + Cross-port the latest resolution of LWG2756 and some + bug-fixes to experimental::optional. + PR libstdc++/77288 + PR libstdc++/77727 + * include/experimental/optional (_Optional_base): + Remove constructors that take a _Tp. + (__is_optional_impl, __is_optional): Remove. + (__converts_from_optional): New. + (optional(_Up&&)): Fix constraints, call base with in_place. + (optional(const optional<_Up>&)): Fix constraints, use emplace. + (optional(optional<_Up>&&)): Likewise. + (operator=(_Up&&)): Fix constraints. + (operator=(const optional<_Up>&)): Likewise. + (operator=(optional<_Up>&&)): Likewise. + (emplace(_Args&&...)): Constrain. + (emplace(initializer_list<_Up>, _Args&&...)): Likewise. + * testsuite/experimental/optional/77288.cc: New. + * testsuite/experimental/optional/assignment/5.cc: Adjust. + * testsuite/experimental/optional/cons/77727.cc: New. + * testsuite/experimental/optional/cons/value.cc: Adjust. + 2016-10-24 Jonathan Wakely <jwakely@redhat.com> * include/bits/stl_vector.h (vector::_M_data_ptr, vector::data): diff --git a/libstdc++-v3/include/experimental/optional b/libstdc++-v3/include/experimental/optional index 7191eca..a631158 100644 --- a/libstdc++-v3/include/experimental/optional +++ b/libstdc++-v3/include/experimental/optional @@ -214,12 +214,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _Optional_base{} { } // Constructors for engaged optionals. - constexpr _Optional_base(const _Tp& __t) - : _M_payload(__t), _M_engaged(true) { } - - constexpr _Optional_base(_Tp&& __t) - : _M_payload(std::move(__t)), _M_engaged(true) { } - template<typename... _Args> constexpr explicit _Optional_base(in_place_t, _Args&&... __args) : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } @@ -356,12 +350,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _Optional_base(nullopt_t) noexcept : _Optional_base{} { } - constexpr _Optional_base(const _Tp& __t) - : _M_payload(__t), _M_engaged(true) { } - - constexpr _Optional_base(_Tp&& __t) - : _M_payload(std::move(__t)), _M_engaged(true) { } - template<typename... _Args> constexpr explicit _Optional_base(in_place_t, _Args&&... __args) : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } @@ -474,19 +462,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> class optional; - template<typename> - struct __is_optional_impl : false_type - { }; - - template<typename _Tp> - struct __is_optional_impl<optional<_Tp>> : true_type - { }; - - template<typename _Tp> - struct __is_optional - : public __is_optional_impl<std::remove_cv_t<std::remove_reference_t<_Tp>>> - { }; - + template<typename _Tp, typename _Up> + using __converts_from_optional = + __or_<is_constructible<_Tp, const optional<_Up>&>, + is_constructible<_Tp, optional<_Up>&>, + is_constructible<_Tp, const optional<_Up>&&>, + is_constructible<_Tp, optional<_Up>&&>, + is_convertible<const optional<_Up>&, _Tp>, + is_convertible<optional<_Up>&, _Tp>, + is_convertible<const optional<_Up>&&, _Tp>, + is_convertible<optional<_Up>&&, _Tp>>; + + template<typename _Tp, typename _Up> + using __assigns_from_optional = + __or_<is_assignable<_Tp&, const optional<_Up>&>, + is_assignable<_Tp&, optional<_Up>&>, + is_assignable<_Tp&, const optional<_Up>&&>, + is_assignable<_Tp&, optional<_Up>&&>>; /** * @brief Class template for optional values. @@ -522,75 +514,75 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr optional() = default; // Converting constructors for engaged optionals. - template <typename _Up, + template <typename _Up = _Tp, enable_if_t<__and_< - __not_<is_same<_Tp, _Up>>, + __not_<is_same<optional<_Tp>, decay_t<_Up>>>, is_constructible<_Tp, _Up&&>, is_convertible<_Up&&, _Tp> >::value, bool> = true> constexpr optional(_Up&& __t) - : _Base(_Tp(std::forward<_Up>(__t))) { } + : _Base(in_place, std::forward<_Up>(__t)) { } - template <typename _Up, + template <typename _Up = _Tp, enable_if_t<__and_< - __not_<is_same<_Tp, _Up>>, - is_constructible<_Tp, _Up&&>, - __not_<is_convertible<_Up&&, _Tp>> - >::value, bool> = false> + __not_<is_same<optional<_Tp>, decay_t<_Up>>>, + is_constructible<_Tp, _Up&&>, + __not_<is_convertible<_Up&&, _Tp>> + >::value, bool> = false> explicit constexpr optional(_Up&& __t) - : _Base(_Tp(std::forward<_Up>(__t))) { } + : _Base(in_place, std::forward<_Up>(__t)) { } template <typename _Up, enable_if_t<__and_< __not_<is_same<_Tp, _Up>>, - __not_<is_constructible< - _Tp, const optional<_Up>&>>, - __not_<is_convertible< - const optional<_Up>&, _Tp>>, is_constructible<_Tp, const _Up&>, - is_convertible<const _Up&, _Tp> + is_convertible<const _Up&, _Tp>, + __not_<__converts_from_optional<_Tp, _Up>> >::value, bool> = true> constexpr optional(const optional<_Up>& __t) - : _Base(__t ? optional<_Tp>(*__t) : optional<_Tp>()) { } + { + if (__t) + emplace(*__t); + } template <typename _Up, enable_if_t<__and_< __not_<is_same<_Tp, _Up>>, - __not_<is_constructible< - _Tp, const optional<_Up>&>>, - __not_<is_convertible< - const optional<_Up>&, _Tp>>, is_constructible<_Tp, const _Up&>, - __not_<is_convertible<const _Up&, _Tp>> + __not_<is_convertible<const _Up&, _Tp>>, + __not_<__converts_from_optional<_Tp, _Up>> >::value, bool> = false> explicit constexpr optional(const optional<_Up>& __t) - : _Base(__t ? optional<_Tp>(*__t) : optional<_Tp>()) { } + { + if (__t) + emplace(*__t); + } template <typename _Up, enable_if_t<__and_< __not_<is_same<_Tp, _Up>>, - __not_<is_constructible< - _Tp, optional<_Up>&&>>, - __not_<is_convertible< - optional<_Up>&&, _Tp>>, is_constructible<_Tp, _Up&&>, - is_convertible<_Up&&, _Tp> + is_convertible<_Up&&, _Tp>, + __not_<__converts_from_optional<_Tp, _Up>> >::value, bool> = true> constexpr optional(optional<_Up>&& __t) - : _Base(__t ? optional<_Tp>(std::move(*__t)) : optional<_Tp>()) { } + { + if (__t) + emplace(std::move(*__t)); + } template <typename _Up, enable_if_t<__and_< __not_<is_same<_Tp, _Up>>, - __not_<is_constructible< - _Tp, optional<_Up>&&>>, - __not_<is_convertible< - optional<_Up>&&, _Tp>>, is_constructible<_Tp, _Up&&>, - __not_<is_convertible<_Up&&, _Tp>> + __not_<is_convertible<_Up&&, _Tp>>, + __not_<__converts_from_optional<_Tp, _Up>> >::value, bool> = false> explicit constexpr optional(optional<_Up>&& __t) - : _Base(__t ? optional<_Tp>(std::move(*__t)) : optional<_Tp>()) { } + { + if (__t) + emplace(std::move(*__t)); + } // [X.Y.4.3] (partly) Assignment. optional& @@ -600,18 +592,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } - template<typename _Up, - enable_if_t<__and_< - __not_<is_same<_Up, nullopt_t>>, - __not_<__is_optional<_Up>>>::value, - bool> = true> - optional& + template<typename _Up = _Tp> + enable_if_t<__and_< + __not_<is_same<optional<_Tp>, decay_t<_Up>>>, + is_constructible<_Tp, _Up>, + __not_<__and_<is_scalar<_Tp>, + is_same<_Tp, decay_t<_Up>>>>, + is_assignable<_Tp&, _Up>>::value, + optional&> operator=(_Up&& __u) { - static_assert(__and_<is_constructible<_Tp, _Up>, - is_assignable<_Tp&, _Up>>(), - "Cannot assign to value type from argument"); - if (this->_M_is_engaged()) this->_M_get() = std::forward<_Up>(__u); else @@ -620,17 +610,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } - template<typename _Up, - enable_if_t<__and_< - __not_<is_same<_Tp, _Up>>>::value, - bool> = true> - optional& + template<typename _Up> + enable_if_t<__and_< + __not_<is_same<_Tp, _Up>>, + is_constructible<_Tp, const _Up&>, + is_assignable<_Tp&, _Up>, + __not_<__converts_from_optional<_Tp, _Up>>, + __not_<__assigns_from_optional<_Tp, _Up>> + >::value, + optional&> operator=(const optional<_Up>& __u) { - static_assert(__and_<is_constructible<_Tp, _Up>, - is_assignable<_Tp&, _Up>>(), - "Cannot assign to value type from argument"); - if (__u) { if (this->_M_is_engaged()) @@ -645,17 +635,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } - template<typename _Up, - enable_if_t<__and_< - __not_<is_same<_Tp, _Up>>>::value, - bool> = true> - optional& + template<typename _Up> + enable_if_t<__and_< + __not_<is_same<_Tp, _Up>>, + is_constructible<_Tp, _Up>, + is_assignable<_Tp&, _Up>, + __not_<__converts_from_optional<_Tp, _Up>>, + __not_<__assigns_from_optional<_Tp, _Up>> + >::value, + optional&> operator=(optional<_Up>&& __u) { - static_assert(__and_<is_constructible<_Tp, _Up>, - is_assignable<_Tp&, _Up>>(), - "Cannot assign to value type from argument"); - if (__u) { if (this->_M_is_engaged()) @@ -672,18 +662,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) { diff --git a/libstdc++-v3/testsuite/experimental/optional/77288.cc b/libstdc++-v3/testsuite/experimental/optional/77288.cc new file mode 100644 index 0000000..38b1e85 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/77288.cc @@ -0,0 +1,405 @@ +// { dg-do run { target c++14 } } + +// 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 <experimental/optional> +#include <experimental/any> + +using std::experimental::optional; + +#include <testsuite_hooks.h> + +void test01() +{ + optional<optional<int>> nested_element; + optional<int> element = {}; + nested_element = element; + VERIFY(nested_element); +} + +template <class T> +struct service_result +{ + static optional<T> get_result() + { + T sr; + return sr; + } + + static optional<T> get_result_with_cond(bool cond) + { + if (cond) + return T{}; + return {}; + } +}; + +void test02() +{ + VERIFY(service_result<int>::get_result()); + VERIFY(service_result<optional<int>>::get_result()); + VERIFY(service_result<int>::get_result_with_cond(true)); + VERIFY(service_result<optional<int>>::get_result_with_cond(true)); + VERIFY(!service_result<int>::get_result_with_cond(false)); + VERIFY(!service_result<optional<int>>::get_result_with_cond(false)); +} + +struct Widget +{ + Widget(int) {} + Widget(optional<int>) {} +}; + + +void test03() +{ + optional<Widget> w; + w = optional<int>(); + VERIFY(w); + static_assert(!std::is_assignable<optional<Widget>&, + optional<short>>::value); + w = optional<optional<int>>(); + VERIFY(!w); + static_assert(!std::is_assignable<optional<Widget>&, + optional<optional<short>>>::value); + + optional<Widget> w2{optional<int>()}; + VERIFY(w2); + optional<Widget> w3 = optional<int>(); + VERIFY(w3); + optional<Widget> w4{optional<short>()}; + VERIFY(w4); + static_assert(!std::is_convertible<optional<short>&&, + optional<Widget>>::value); + + optional<Widget> w6{optional<optional<int>>()}; + VERIFY(!w6); + optional<Widget> w7 = optional<optional<int>>(); + VERIFY(!w7); + optional<Widget> w8{optional<optional<short>>()}; + VERIFY(!w8); + static_assert(!std::is_convertible<optional<optional<short>>&&, + optional<Widget>>::value); + optional<Widget> w10{optional<optional<short>>(10)}; + VERIFY(w10); + optional<Widget> w11 = std::experimental::nullopt; + VERIFY(!w11); + optional<Widget> w12 = {}; + VERIFY(!w12); + optional<Widget> w13{std::experimental::nullopt}; + VERIFY(!w13); + optional<Widget> w14; + w14 = {}; + VERIFY(!w14); +} + +struct Widget2 +{ + Widget2(int) {} + Widget2(optional<int>) {} + Widget2& operator=(int) {return *this;} + Widget2& operator=(optional<int>) {return *this;} +}; + +void test04() +{ + optional<Widget2> w; + w = optional<int>(); + VERIFY(w); + w = optional<short>(); + VERIFY(w); + w = optional<optional<int>>(); + VERIFY(!w); + w = optional<optional<short>>(); + VERIFY(!w); + w = optional<optional<short>>(10); + optional<Widget2> w2 = std::experimental::nullopt; + VERIFY(!w2); + optional<Widget2> w3 = {}; + VERIFY(!w3); + optional<Widget2> w4{std::experimental::nullopt}; + VERIFY(!w4); + optional<Widget2> w5; + w5 = {}; + VERIFY(!w5); +} + +struct Thingy +{ + Thingy(int) {} + Thingy(Widget) {} +}; + +void test05() +{ + optional<Thingy> ot; + + static_assert(!std::is_assignable<optional<Thingy>&, + optional<int>>::value); + static_assert(std::is_assignable<optional<Thingy>&, + optional<short>>::value); + static_assert(!std::is_assignable<optional<Thingy>&, + optional<optional<int>>>::value); + ot = optional<Widget>(); + VERIFY(!ot); + optional<Thingy> ot2{optional<int>()}; + VERIFY(ot2); + static_assert(!std::is_convertible<optional<int>&&, + optional<Thingy>>::value); + optional<Thingy> ot3{optional<short>()}; + VERIFY(!ot3); + optional<Thingy> ot4 = optional<short>(); + VERIFY(!ot4); + + optional<Thingy> ot5{optional<optional<int>>()}; + VERIFY(!ot5); + static_assert(!std::is_convertible<optional<optional<int>>&&, + optional<Thingy>>::value); + + optional<Thingy> ot7{optional<Widget>()}; + VERIFY(!ot7); + optional<Thingy> ot8 = optional<Widget>(); + VERIFY(!ot8); + static_assert(!std::is_constructible<optional<Thingy>, + optional<optional<short>>>::value); + static_assert(!std::is_convertible<optional<optional<short>>, + optional<Thingy>>::value); + static_assert(!std::is_assignable<optional<Thingy>&, + optional<optional<short>>>::value); + optional<Thingy> ot9 = std::experimental::nullopt; + VERIFY(!ot9); + optional<Thingy> ot10 = {}; + VERIFY(!ot10); + optional<Thingy> ot11{std::experimental::nullopt}; + VERIFY(!ot11); + optional<Thingy> ot12; + ot12 = {}; + VERIFY(!ot12); +} + +struct RvalueConstructible +{ + RvalueConstructible(int) {} + RvalueConstructible(optional<int>&&) {} +}; + +void test06() +{ + optional<int> oi; + optional<RvalueConstructible> ori; + static_assert(!std::is_assignable<optional<RvalueConstructible>&, + optional<int>&>::value); + ori = std::move(oi); + VERIFY(ori); + + optional<optional<int>> ooi; + static_assert(!std::is_assignable<optional<RvalueConstructible>&, + optional<optional<int>>&>::value); + ori = std::move(ooi); + VERIFY(!ori); + + static_assert(!std::is_constructible<optional<RvalueConstructible>, + optional<int>&>::value); + static_assert(!std::is_convertible<optional<int>&, + optional<RvalueConstructible>>::value); + + optional<RvalueConstructible> ori2(std::move(oi)); + VERIFY(ori2); + optional<RvalueConstructible> ori3 = std::move(oi); + VERIFY(ori3); + + static_assert(!std::is_constructible<optional<RvalueConstructible>, + optional<optional<int>>&>::value); + static_assert(!std::is_convertible<optional<optional<int>>&, + optional<RvalueConstructible>>::value); + optional<RvalueConstructible> ori6(std::move(ooi)); + VERIFY(!ori6); + optional<RvalueConstructible> ori7 = std::move(ooi); + VERIFY(!ori7); + optional<RvalueConstructible> ori8 = std::experimental::nullopt; + VERIFY(!ori8); + optional<RvalueConstructible> ori9 = {}; + VERIFY(!ori9); + optional<RvalueConstructible> ori10{std::experimental::nullopt}; + VERIFY(!ori10); + optional<RvalueConstructible> ori11; + ori11 = {}; + VERIFY(!ori11); +} + +struct Thingy2 +{ + Thingy2(int) {} + explicit Thingy2(optional<int>) {} + Thingy2(Widget) {} +}; + +void test07() +{ + optional<Thingy2> ot{optional<int>{}}; + VERIFY(ot); + static_assert(!std::is_convertible<optional<int>, + optional<Thingy2>>::value); + optional<Thingy2> ot2{optional<short>{}}; + VERIFY(ot2); + static_assert(!std::is_convertible<optional<short>, + optional<Thingy2>>::value); + optional<Thingy2> ot3{optional<optional<int>>{}}; + VERIFY(!ot3); + static_assert(!std::is_convertible<optional<optional<int>>, + optional<Thingy2>>::value); + optional<Thingy2> ot4{optional<optional<short>>{}}; + VERIFY(!ot4); + static_assert(!std::is_convertible<optional<optional<short>>, + optional<Thingy2>>::value); + + optional<Thingy2> ot5{optional<Widget>{}}; + VERIFY(!ot5); + optional<Thingy2> ot6 = optional<Widget>(); + VERIFY(!ot6); + + static_assert(!std::is_assignable<optional<Thingy2>&, + optional<int>>::value); + static_assert(!std::is_assignable<optional<Thingy2>&, + optional<short>>::value); + static_assert(!std::is_assignable<optional<Thingy2>&, + optional<optional<int>>>::value); + static_assert(!std::is_assignable<optional<Thingy2>&, + optional<optional<short>>>::value); + optional<Thingy2> ot7; + ot = optional<Widget>(); + VERIFY(!ot7); + optional<Thingy2> ot8 = std::experimental::nullopt; + VERIFY(!ot8); + optional<Thingy2> ot9 = {}; + VERIFY(!ot9); + optional<Thingy2> ot10{std::experimental::nullopt}; + VERIFY(!ot10); + optional<Thingy2> ot11; + ot11 = {}; + VERIFY(!ot11); +} + +struct Thingy3 +{ + Thingy3(int) {} + template<class... Args, + std::enable_if_t<std::is_constructible<Widget, Args&&...>::value, + bool> = true> + explicit Thingy3(Args&&... args) {} + Thingy3(Widget) {} +}; + +void test08() +{ + optional<Thingy3> ot{optional<int>{}}; + VERIFY(ot); + static_assert(!std::is_convertible<optional<int>, + optional<Thingy3>>::value); + optional<Thingy3> ot2{optional<short>{}}; + VERIFY(ot2); + static_assert(!std::is_convertible<optional<short>, + optional<Thingy3>>::value); + optional<Thingy3> ot3{optional<optional<int>>{}}; + VERIFY(!ot3); + static_assert(!std::is_convertible<optional<optional<int>>, + optional<Thingy3>>::value); + optional<Thingy3> ot4{optional<optional<short>>{}}; + VERIFY(!ot4); + static_assert(!std::is_convertible<optional<optional<short>>, + optional<Thingy3>>::value); + + optional<Thingy3> ot5{optional<Widget>{}}; + VERIFY(!ot5); + optional<Thingy3> ot6 = optional<Widget>(); + VERIFY(!ot6); + + static_assert(!std::is_assignable<optional<Thingy3>&, + optional<int>>::value); + static_assert(!std::is_assignable<optional<Thingy3>&, + optional<short>>::value); + static_assert(!std::is_assignable<optional<Thingy3>&, + optional<optional<int>>>::value); + static_assert(!std::is_assignable<optional<Thingy3>&, + optional<optional<short>>>::value); + optional<Thingy3> ot7; + ot = optional<Widget>(); + VERIFY(!ot7); + optional<Thingy3> ot8 = std::experimental::nullopt; + VERIFY(!ot8); + optional<Thingy3> ot9 = {}; + VERIFY(!ot9); + optional<Thingy3> ot10{std::experimental::nullopt}; + VERIFY(!ot10); + optional<Thingy3> ot11; + ot11 = {}; + VERIFY(!ot11); +} + +void test09() +{ + std::experimental::any a = 42; + optional<std::experimental::any> oa2 = a; + VERIFY(oa2); + VERIFY(std::experimental::any_cast<int>(*oa2) == 42); + optional<std::experimental::any> oa3 = oa2; + VERIFY(oa3); + VERIFY(std::experimental::any_cast<int>(*oa3) == 42); + optional<std::experimental::any> oa4{oa2}; + VERIFY(oa4); + VERIFY(std::experimental::any_cast<int>(*oa4) == 42); + optional<std::experimental::any> oa5(oa2); + VERIFY(oa5); + VERIFY(std::experimental::any_cast<int>(*oa5) == 42); + optional<std::experimental::any> oa6; + VERIFY(!oa6); + optional<std::experimental::any> oa7 = oa6; + VERIFY(!oa7); + optional<std::experimental::any> oa8{oa6}; + VERIFY(!oa8); + optional<std::experimental::any> oa9(oa6); + VERIFY(!oa9); +} + +void test10() +{ + struct X {}; + optional<int> oi(std::experimental::in_place); + oi = {}; + VERIFY(bool(oi) == false); + optional<X> ot(std::experimental::in_place); + ot = {}; + VERIFY(bool(ot) == false); + optional<int> oi2(std::experimental::in_place); + short int si = 6; + oi2 = si; +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); + test05(); + test06(); + test07(); + test08(); + test09(); + test10(); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/assignment/5.cc b/libstdc++-v3/testsuite/experimental/optional/assignment/5.cc index a3d7e85..8ee6201 100644 --- a/libstdc++-v3/testsuite/experimental/optional/assignment/5.cc +++ b/libstdc++-v3/testsuite/experimental/optional/assignment/5.cc @@ -18,6 +18,7 @@ // <http://www.gnu.org/licenses/>. #include <experimental/optional> +#include <vector> #include <testsuite_hooks.h> int counter = 0; @@ -61,5 +62,15 @@ int main() VERIFY( !o ); } + { + std::experimental::optional<std::vector<int>> ovi{{1, 2, 3}}; + VERIFY(ovi->size() == 3); + VERIFY((*ovi)[0] == 1 && (*ovi)[1] == 2 && (*ovi)[2] == 3); + ovi = {4, 5, 6, 7}; + VERIFY(ovi->size() == 4); + VERIFY((*ovi)[0] == 4 && (*ovi)[1] == 5 && + (*ovi)[2] == 6 && (*ovi)[3] == 7); + } + VERIFY( counter == 0 ); } diff --git a/libstdc++-v3/testsuite/experimental/optional/cons/77727.cc b/libstdc++-v3/testsuite/experimental/optional/cons/77727.cc new file mode 100644 index 0000000..e3abedb --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/optional/cons/77727.cc @@ -0,0 +1,50 @@ +// { dg-do run { target c++14 } } + +// 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 <experimental/optional> +#include <testsuite_hooks.h> + + +struct NonTransferable +{ + int x; + NonTransferable(int x) : x(x) {} + NonTransferable(NonTransferable&&) = delete; + NonTransferable& operator=(NonTransferable&&) = delete; + operator int() {return x;} +}; + +int main() +{ + std::experimental::optional<int> oi; + std::experimental::optional<NonTransferable> ot(std::move(oi)); + VERIFY(!ot); + + std::experimental::optional<int> oi2; + std::experimental::optional<NonTransferable> ot2(oi2); + VERIFY(!ot); + + std::experimental::optional<int> oi3{42}; + std::experimental::optional<NonTransferable> ot3(std::move(oi3)); + VERIFY(ot3 && *ot3 == 42); + + std::experimental::optional<int> oi4{666}; + std::experimental::optional<NonTransferable> ot4(oi4); + VERIFY(ot4 && *ot4 == 666); +} diff --git a/libstdc++-v3/testsuite/experimental/optional/cons/value.cc b/libstdc++-v3/testsuite/experimental/optional/cons/value.cc index 920b796..81b2cb8 100644 --- a/libstdc++-v3/testsuite/experimental/optional/cons/value.cc +++ b/libstdc++-v3/testsuite/experimental/optional/cons/value.cc @@ -254,4 +254,31 @@ int main() std::experimental::optional<X> ox4; ox4 = oi; } + + { + std::experimental::optional<std::experimental::optional<int>> ooi = + std::experimental::optional<int>(); + VERIFY(bool(ooi)); + ooi = std::experimental::optional<int>(); + VERIFY(bool(ooi)); + ooi = std::experimental::optional<int>(42); + VERIFY(bool(ooi)); + VERIFY(bool(*ooi)); + std::experimental::optional<std::experimental::optional<int>> ooi2 = + std::experimental::optional<short>(); + VERIFY(bool(ooi2)); + ooi2 = std::experimental::optional<short>(); + VERIFY(bool(ooi2)); + ooi2 = std::experimental::optional<short>(6); + VERIFY(bool(ooi2)); + VERIFY(bool(*ooi2)); + std::experimental::optional<std::experimental::optional<int>> ooi3 = + std::experimental::optional<int>(42); + VERIFY(bool(ooi3)); + VERIFY(bool(*ooi3)); + std::experimental::optional<std::experimental::optional<int>> ooi4 = + std::experimental::optional<short>(6); + VERIFY(bool(ooi4)); + VERIFY(bool(*ooi4)); + } } |