* [v3 PATCH] Implement LWG 2842, in_place_t check for optional::optional(U&&) should decay U.
@ 2016-12-19 14:13 Ville Voutilainen
2016-12-22 17:04 ` Jonathan Wakely
0 siblings, 1 reply; 2+ messages in thread
From: Ville Voutilainen @ 2016-12-19 14:13 UTC (permalink / raw)
To: libstdc++, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 1281 bytes --]
Tested on Linux-x64.
The perfect forwarder needs to sfinae out of the way of the in_place_t
signature,
and the in_place_t signature needs to check is_constructible. I also
did some housekeeping
to get rid of the int-pack constraints, because in case of empty packs
it's unclear
what a compiler is supposed to do for them.
2016-12-19 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.
[-- Attachment #2: lwg2842.diff --]
[-- Type: text/plain, Size: 4616 bytes --]
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 }
}
}
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [v3 PATCH] Implement LWG 2842, in_place_t check for optional::optional(U&&) should decay U.
2016-12-19 14:13 [v3 PATCH] Implement LWG 2842, in_place_t check for optional::optional(U&&) should decay U Ville Voutilainen
@ 2016-12-22 17:04 ` Jonathan Wakely
0 siblings, 0 replies; 2+ messages in thread
From: Jonathan Wakely @ 2016-12-22 17:04 UTC (permalink / raw)
To: Ville Voutilainen; +Cc: libstdc++, gcc-patches
On 19/12/16 16:07 +0200, Ville Voutilainen wrote:
>Tested on Linux-x64.
>
>The perfect forwarder needs to sfinae out of the way of the in_place_t
>signature,
>and the in_place_t signature needs to check is_constructible. I also
>did some housekeeping
>to get rid of the int-pack constraints, because in case of empty packs
>it's unclear
>what a compiler is supposed to do for them.
OK for trunk.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-12-22 16:52 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-19 14:13 [v3 PATCH] Implement LWG 2842, in_place_t check for optional::optional(U&&) should decay U Ville Voutilainen
2016-12-22 17:04 ` Jonathan Wakely
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).