Implement LWG 2744 and LWG 2754.
authorVille Voutilainen <ville.voutilainen@gmail.com>
Mon, 15 Aug 2016 15:06:09 +0000 (18:06 +0300)
committerVille Voutilainen <ville@gcc.gnu.org>
Mon, 15 Aug 2016 15:06:09 +0000 (18:06 +0300)
* include/std/any (any(ValueType&&)): Constrain with __is_in_place_type.
(any(in_place_type_t<_ValueType>, _Args&&...)): Use _Decay.
(any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&...)):
Likewise.
(emplace(_Args&&...)): Likewise.
(emplace(initializer_list<_Up>, _Args&&...)): Likewise.
* include/std/utility: (__is_in_place_type_impl): New.
(__is_in_place_type): Likewise.
* testsuite/20_util/any/assign/emplace.cc: Add tests for decaying
emplace.
* testsuite/20_util/any/cons/in_place.cc: Add tests for decaying
in_place constructor.
* testsuite/20_util/any/misc/any_cast_neg.cc: Adjust.
* testsuite/20_util/any/requirements.cc: Add a test for
in_place-constructing a non-default-constructible type.

From-SVN: r239482

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/any
libstdc++-v3/include/std/utility
libstdc++-v3/testsuite/20_util/any/assign/emplace.cc
libstdc++-v3/testsuite/20_util/any/cons/in_place.cc
libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc
libstdc++-v3/testsuite/20_util/any/requirements.cc

index 05ee02a1398b27883c782a6f2c58d7e6f044170b..73ddaac385d54e34c96cf9c695c2c824171f4a1d 100644 (file)
@@ -1,3 +1,22 @@
+2016-08-15  Ville Voutilainen  <ville.voutilainen@gmail.com>
+
+       Implement LWG 2744 and LWG 2754.
+       * include/std/any (any(ValueType&&)): Constrain with __is_in_place_type.
+       (any(in_place_type_t<_ValueType>, _Args&&...)): Use _Decay.
+       (any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&...)):
+       Likewise.
+       (emplace(_Args&&...)): Likewise.
+       (emplace(initializer_list<_Up>, _Args&&...)): Likewise.
+       * include/std/utility: (__is_in_place_type_impl): New.
+       (__is_in_place_type): Likewise.
+       * testsuite/20_util/any/assign/emplace.cc: Add tests for decaying
+       emplace.
+       * testsuite/20_util/any/cons/in_place.cc: Add tests for decaying
+       in_place constructor.
+       * testsuite/20_util/any/misc/any_cast_neg.cc: Adjust.
+       * testsuite/20_util/any/requirements.cc: Add a test for
+       in_place-constructing a non-default-constructible type.
+
 2016-08-15  Ville Voutilainen  <ville.voutilainen@gmail.com>
 
        Add a feature macro for C++17 make_from_tuple.
index 4add1186923f8a87a911fcfb680d65841672d34b..9160035006e0f8019b7ef178e3528e88ac33453a 100644 (file)
@@ -153,7 +153,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     /// Construct with a copy of @p __value as the contained object.
     template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
              typename _Mgr = _Manager<_Tp>,
-              __any_constructible_t<_Tp, _ValueType&&> = true>
+              __any_constructible_t<_Tp, _ValueType&&> = true,
+             enable_if_t<!__is_in_place_type<_ValueType>::value, bool> = true>
       any(_ValueType&& __value)
       : _M_manager(&_Mgr::_S_manage)
       {
@@ -164,9 +165,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
              typename _Mgr = _Manager<_Tp>,
               enable_if_t<__and_<is_copy_constructible<_Tp>,
-                                __not_<
-                                  is_constructible<_Tp,
-                                                   _ValueType&&>>>::value,
+                                __not_<is_constructible<_Tp, _ValueType&&>>,
+                                __not_<__is_in_place_type<_ValueType>>>::value,
                          bool> = false>
       any(_ValueType&& __value)
       : _M_manager(&_Mgr::_S_manage)
@@ -175,10 +175,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
     /// Construct with an object created from @p __args as the contained object.
-    template <typename _Tp, typename... _Args,
+    template <typename _ValueType, typename... _Args,
+             typename _Tp = _Decay<_ValueType>,
              typename _Mgr = _Manager<_Tp>,
               __any_constructible_t<_Tp, _Args&&...> = false>
-      any(in_place_type_t<_Tp>, _Args&&... __args)
+      any(in_place_type_t<_ValueType>, _Args&&... __args)
       : _M_manager(&_Mgr::_S_manage)
       {
         _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
@@ -186,11 +187,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     /// Construct with an object created from @p __il and @p __args as
     /// the contained object.
-    template <typename _Tp, typename _Up, typename... _Args,
+    template <typename _ValueType, typename _Up, typename... _Args,
+             typename _Tp = _Decay<_ValueType>,
              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)
+      any(in_place_type_t<_ValueType>,
+         initializer_list<_Up> __il, _Args&&... __args)
       : _M_manager(&_Mgr::_S_manage)
       {
         _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
@@ -248,7 +251,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
     /// Emplace with an object created from @p __args as the contained object.
-    template <typename _Tp, typename... _Args,
+    template <typename _ValueType, typename... _Args,
+             typename _Tp = _Decay<_ValueType>,
              typename _Mgr = _Manager<_Tp>,
               __any_constructible_t<_Tp, _Args&&...> = false>
       void emplace(_Args&&... __args)
@@ -260,7 +264,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     /// Emplace with an object created from @p __il and @p __args as
     /// the contained object.
-    template <typename _Tp, typename _Up, typename... _Args,
+    template <typename _ValueType, typename _Up, typename... _Args,
+             typename _Tp = _Decay<_ValueType>,
              typename _Mgr = _Manager<_Tp>,
               __any_constructible_t<_Tp, initializer_list<_Up>,
                                    _Args&&...> = false>
index 0c0364430b6adbbb5a576a16c94fb1c2c4d42161..6a6659b54958d9a7b183cb157dcc4e92d1308541 100644 (file)
@@ -356,6 +356,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template <size_t _Idx>
     in_place_tag in_place(__in_place_index<_Idx>*) {terminate();}
 
+  template<typename>
+    struct __is_in_place_type_impl : false_type
+    { };
+
+  template<typename _Tp>
+    struct __is_in_place_type_impl<in_place_type_t<_Tp>> : true_type
+    { };
+
+  template<typename _Tp>
+    struct __is_in_place_type
+      : public __is_in_place_type_impl<_Tp>
+    { };
+
 #define  __cpp_lib_as_const 201510
   template<typename _Tp>
     constexpr add_const_t<_Tp>& as_const(_Tp& __t) noexcept { return __t; }
@@ -363,7 +376,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     void as_const(const _Tp&&) = delete;
 
-#endif
+#endif // C++17
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
index 663bae27f38eefe678e87be33ebd38db027d20c9..799c5edf4a41c353271cb15865ab9d4d21c8c048 100644 (file)
@@ -59,4 +59,17 @@ int main()
   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 );
+  std::any o6;
+  o6.emplace<const int&>(i);
+  VERIFY(o6.type() == o.type());
+  std::any o7;
+  o7.emplace<void()>(nullptr);
+  std::any o8;
+  o8.emplace<void(*)()>(nullptr);
+  VERIFY(o7.type() == o8.type());
+  std::any o9;
+  o9.emplace<char(&)[42]>(nullptr);
+  std::any o10;
+  o10.emplace<char*>(nullptr);
+  VERIFY(o9.type() == o10.type());
 }
index 2368b83d250a3aaad027913118a115a516811ca8..52f2b38d5fc1bb3f62019e7b6a2cc260af922e2c 100644 (file)
@@ -54,4 +54,12 @@ int main()
   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 );
+  std::any o6(std::in_place<int&>, i);
+  VERIFY(o6.type() == o.type());
+  std::any o7(std::in_place<void()>, nullptr);
+  std::any o8(std::in_place<void(*)()>, nullptr);
+  VERIFY(o7.type() == o8.type());
+  std::any o9(std::in_place<char(&)[42]>, nullptr);
+  std::any o10(std::in_place<char*>, nullptr);
+  VERIFY(o9.type() == o10.type());
 }
index 32b4e767fd2a7e3250509a88ec59dba95e9e5f83..05fdeb7198da6b99707725f010df4e6547bc7e7d 100644 (file)
@@ -26,5 +26,5 @@ void test01()
   using std::any_cast;
 
   const any y(1);
-  any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 435 }
+  any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 440 }
 }
index f33cd67ffe6391e3a5127c51d24e07a741ddb12f..7b084bec64ac87d12222ddf0b1b9afa0342196e9 100644 (file)
@@ -34,3 +34,11 @@ static_assert(!std::is_assignable<any&, const unique_ptr<int>&>::value);
 static_assert(!std::is_constructible<any&, const unique_ptr<int>&>::value);
 static_assert(!std::is_assignable<any&, unique_ptr<int>&>::value);
 static_assert(!std::is_constructible<any&, unique_ptr<int>&>::value);
+
+struct NoDefaultCtor
+{
+  NoDefaultCtor() = delete;
+};
+
+static_assert(!std::is_constructible<any,
+             std::in_place_type_t<NoDefaultCtor>>::value);