Implement LWG 2842, in_place_t check for optional::optional(U&&) should decay U.
authorVille Voutilainen <ville.voutilainen@gmail.com>
Thu, 29 Dec 2016 19:19:59 +0000 (21:19 +0200)
committerVille Voutilainen <ville@gcc.gnu.org>
Thu, 29 Dec 2016 19:19:59 +0000 (21:19 +0200)
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

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/optional
libstdc++-v3/testsuite/20_util/optional/cons/value_neg.cc

index 32b81e8bbb7ddaf2924ff0d16539abeac1a26d71..34ca95a846eac5f56bcebc4e5a2e5efa23d4a1d5 100644 (file)
@@ -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.
index 3d69e104199d0f6d47bfc5fa5baabcec66968ead..73bc2b42bf3d7eac603d4142923f9ba6185ef415 100644 (file)
@@ -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)
index 21e86c5a5b4243f535629a35a42b9ef2095070c4..6a2827ec46133fd16ae7739eb8ca415cd70dc4b4 100644 (file)
@@ -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 }
   }
 }