diff options
author | Ville Voutilainen <ville.voutilainen@gmail.com> | 2016-12-29 21:19:59 +0200 |
---|---|---|
committer | Ville Voutilainen <ville@gcc.gnu.org> | 2016-12-29 21:19:59 +0200 |
commit | 2ae2d394c1f9928fcb4bb7efdf9874edb787936a (patch) | |
tree | 5f999260165757bb14be4c311ec15e229091ee47 | |
parent | f3d17b5e71df5bae6d5fe34319058473aa6678d4 (diff) | |
download | gcc-2ae2d394c1f9928fcb4bb7efdf9874edb787936a.zip gcc-2ae2d394c1f9928fcb4bb7efdf9874edb787936a.tar.gz gcc-2ae2d394c1f9928fcb4bb7efdf9874edb787936a.tar.bz2 |
Implement LWG 2842, in_place_t check for optional::optional(U&&) should decay U.
Implement LWG 2842, in_place_t check for optional::optional(U&&)
should decay U.
* include/std/optional (_Optional_base(in_place_t, _Args&&...)):
Constrain.
(_Optional_base(in_place_t, initializer_list<_Up>, _Args&&...)):
Turn the int-pack constraint hack into a saner bool.
(_Optional_base<_Tp, false>::_Optional_base(in_place_t, _Args&&...)):
Constrain.
(_Optional_base<_Tp, false>::_Optional_base(in_place_t,
initializer_list<_Up>, _Args&&...)):
Turn the int-pack constraint hack into a saner bool.
(optional(_Up&&)): Constrain against in_place_t.
(optional(in_place_t, _Args&&...)): Constrain.
(constexpr optional(in_place_t, initializer_list<_Up>, _Args&&...)):
Turn the int-pack constraint hack into a saner bool.
* testsuite/20_util/optional/cons/value_neg.cc: Add a test for
a type that is constructible from in_place.
From-SVN: r243966
-rw-r--r-- | libstdc++-v3/ChangeLog | 20 | ||||
-rw-r--r-- | libstdc++-v3/include/std/optional | 32 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/optional/cons/value_neg.cc | 5 |
3 files changed, 42 insertions, 15 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 32b81e8..34ca95a 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,23 @@ +2016-12-29 Ville Voutilainen <ville.voutilainen@gmail.com> + + Implement LWG 2842, in_place_t check for optional::optional(U&&) + should decay U. + * include/std/optional (_Optional_base(in_place_t, _Args&&...)): + Constrain. + (_Optional_base(in_place_t, initializer_list<_Up>, _Args&&...)): + Turn the int-pack constraint hack into a saner bool. + (_Optional_base<_Tp, false>::_Optional_base(in_place_t, _Args&&...)): + Constrain. + (_Optional_base<_Tp, false>::_Optional_base(in_place_t, + initializer_list<_Up>, _Args&&...)): + Turn the int-pack constraint hack into a saner bool. + (optional(_Up&&)): Constrain against in_place_t. + (optional(in_place_t, _Args&&...)): Constrain. + (constexpr optional(in_place_t, initializer_list<_Up>, _Args&&...)): + Turn the int-pack constraint hack into a saner bool. + * testsuite/20_util/optional/cons/value_neg.cc: Add a test for + a type that is constructible from in_place. + 2016-12-24 François Dumont <fdumont@gcc.gnu.org> * include/ext/random.tcc: Fix usage of _OutputIteratorConcept. diff --git a/libstdc++-v3/include/std/optional b/libstdc++-v3/include/std/optional index 3d69e10..73bc2b4 100644 --- a/libstdc++-v3/include/std/optional +++ b/libstdc++-v3/include/std/optional @@ -128,15 +128,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _Optional_base{} { } // Constructors for engaged optionals. - template<typename... _Args> + template<typename... _Args, + enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false> constexpr explicit _Optional_base(in_place_t, _Args&&... __args) : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } template<typename _Up, typename... _Args, - enable_if_t<is_constructible<_Tp, - initializer_list<_Up>&, - _Args&&...>::value, - int>...> + enable_if_t<is_constructible_v<_Tp, + initializer_list<_Up>&, + _Args&&...>, bool> = false> constexpr explicit _Optional_base(in_place_t, initializer_list<_Up> __il, _Args&&... __args) @@ -264,15 +264,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _Optional_base(nullopt_t) noexcept : _Optional_base{} { } - template<typename... _Args> + template<typename... _Args, + enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false> constexpr explicit _Optional_base(in_place_t, _Args&&... __args) : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } template<typename _Up, typename... _Args, - enable_if_t<is_constructible<_Tp, - initializer_list<_Up>&, - _Args&&...>::value, - int>...> + enable_if_t<is_constructible_v<_Tp, + initializer_list<_Up>&, + _Args&&...>, bool> = false> constexpr explicit _Optional_base(in_place_t, initializer_list<_Up> __il, _Args&&... __args) @@ -432,6 +432,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template <typename _Up = _Tp, enable_if_t<__and_< __not_<is_same<optional<_Tp>, decay_t<_Up>>>, + __not_<is_same<in_place_t, decay_t<_Up>>>, is_constructible<_Tp, _Up&&>, is_convertible<_Up&&, _Tp> >::value, bool> = true> @@ -441,6 +442,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template <typename _Up = _Tp, enable_if_t<__and_< __not_<is_same<optional<_Tp>, decay_t<_Up>>>, + __not_<is_same<in_place_t, decay_t<_Up>>>, is_constructible<_Tp, _Up&&>, __not_<is_convertible<_Up&&, _Tp>> >::value, bool> = false> @@ -499,15 +501,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION emplace(std::move(*__t)); } - template<typename... _Args> + template<typename... _Args, + enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false> explicit constexpr optional(in_place_t, _Args&&... __args) : _Base(std::in_place, std::forward<_Args>(__args)...) { } template<typename _Up, typename... _Args, - enable_if_t<is_constructible<_Tp, - initializer_list<_Up>&, - _Args&&...>::value, - int>...> + enable_if_t<is_constructible_v<_Tp, + initializer_list<_Up>&, + _Args&&...>, bool> = false> explicit constexpr optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) diff --git a/libstdc++-v3/testsuite/20_util/optional/cons/value_neg.cc b/libstdc++-v3/testsuite/20_util/optional/cons/value_neg.cc index 21e86c5..6a2827e 100644 --- a/libstdc++-v3/testsuite/20_util/optional/cons/value_neg.cc +++ b/libstdc++-v3/testsuite/20_util/optional/cons/value_neg.cc @@ -35,5 +35,10 @@ int main() std::optional<X> ox2 = 42; // { dg-error "conversion" } std::optional<std::unique_ptr<int>> oup{new int}; std::optional<std::unique_ptr<int>> oup2 = new int; // { dg-error "conversion" } + struct U { explicit U(std::in_place_t); }; + std::optional<U> ou(std::in_place); // { dg-error "no matching" } + // { dg-error "no type" "" { target { *-*-* } } 438 } + // { dg-error "no type" "" { target { *-*-* } } 448 } + // { dg-error "no type" "" { target { *-*-* } } 505 } } } |