Use constexpr addressof in optional, SFINAE housekeeping for any, optional and tuple.
authorVille Voutilainen <ville.voutilainen@gmail.com>
Mon, 14 Nov 2016 15:30:37 +0000 (17:30 +0200)
committerVille Voutilainen <ville@gcc.gnu.org>
Mon, 14 Nov 2016 15:30:37 +0000 (17:30 +0200)
Use constexpr addressof in optional, SFINAE housekeeping
for any, optional and tuple.
* include/std/any (__do_emplace(_Args&&...)): New.
(__do_emplace(initializer_list<_Up>, _Args&&...)): Likewise.
(__any_constructible): Likewise.
(__any_constructible_t): Use __any_constructible.
(operator=(_ValueType&&)): SFINAE in the return type.
(emplace(_Args&&...)): Likewise.
(emplace(initializer_list<_Up>, _Args&&...)): Likewise.
* include/std/optional (_Has_addressof_mem): Remove.
(_Has_addressof_free): Likewise.
(_Has_addressof): Likewise.
(__constexpr_addressof(_Tp&)): Likewise.
(operator->): Use std::__addressof.
* include/std/tuple (operator=(const tuple<_UElements...>&)):
SFINAE in return type.
(operator=(tuple<_UElements...>&&)): Likewise.
* testsuite/20_util/any/misc/any_cast_neg.cc: Adjust.

From-SVN: r242390

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/any
libstdc++-v3/include/std/optional
libstdc++-v3/include/std/tuple
libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc

index 57a7be64b846300a61e2d610e05956ee5b11c7a1..e984dfbadfb487fffe95d8e1881820fc1f4221e2 100644 (file)
@@ -1,3 +1,24 @@
+2016-11-14  Ville Voutilainen  <ville.voutilainen@gmail.com>
+
+       Use constexpr addressof in optional, SFINAE housekeeping
+       for any, optional and tuple.
+       * include/std/any (__do_emplace(_Args&&...)): New.
+       (__do_emplace(initializer_list<_Up>, _Args&&...)): Likewise.
+       (__any_constructible): Likewise.
+       (__any_constructible_t): Use __any_constructible.
+       (operator=(_ValueType&&)): SFINAE in the return type.
+       (emplace(_Args&&...)): Likewise.
+       (emplace(initializer_list<_Up>, _Args&&...)): Likewise.
+       * include/std/optional (_Has_addressof_mem): Remove.
+       (_Has_addressof_free): Likewise.
+       (_Has_addressof): Likewise.
+       (__constexpr_addressof(_Tp&)): Likewise.
+       (operator->): Use std::__addressof.
+       * include/std/tuple (operator=(const tuple<_UElements...>&)):
+       SFINAE in return type.
+       (operator=(tuple<_UElements...>&&)): Likewise.
+       * testsuite/20_util/any/misc/any_cast_neg.cc: Adjust.
+
 2016-11-14  Jonathan Wakely  <jwakely@redhat.com>
 
        * include/bits/move.h (addressof(const _Tp&&)): Add deleted overload,
index 45a2145179b21435ed300633b2ba99b4fea5eb2d..719e683f5ed278496751f0436bc6260323b3421c 100644 (file)
@@ -108,6 +108,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     template<typename _Tp, typename _Decayed = decay_t<_Tp>>
       using _Decay = enable_if_t<!is_same<_Decayed, any>::value, _Decayed>;
 
+    /// Emplace with an object created from @p __args as the contained object.
+    template <typename _Tp, typename... _Args,
+             typename _Mgr = _Manager<_Tp>>
+      void __do_emplace(_Args&&... __args)
+      {
+       reset();
+       _M_manager = &_Mgr::_S_manage;
+        _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
+      }
+
+    /// Emplace with an object created from @p __il and @p __args as
+    /// the contained object.
+    template <typename _Tp, typename _Up, typename... _Args,
+             typename _Mgr = _Manager<_Tp>>
+      void __do_emplace(initializer_list<_Up> __il, _Args&&... __args)
+      {
+       reset();
+       _M_manager = &_Mgr::_S_manage;
+        _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
+      }
+
   public:
     // construct/destruct
 
@@ -144,11 +165,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        }
     }
 
+    template <typename _Res, typename _Tp, typename... _Args>
+    using __any_constructible =
+      enable_if<__and_<is_copy_constructible<_Tp>,
+                        is_constructible<_Tp, _Args...>>::value,
+                 _Res>;
+
     template <typename _Tp, typename... _Args>
     using __any_constructible_t =
-      enable_if_t<__and_<is_copy_constructible<_Tp>,
-                        is_constructible<_Tp, _Args...>>::value,
-                 bool>;
+      typename __any_constructible<bool, _Tp, _Args...>::type;
 
     /// Construct with a copy of @p __value as the contained object.
     template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
@@ -233,9 +258,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
     /// Store a copy of @p __rhs as the contained object.
-    template<typename _ValueType,
-            typename _Tp = _Decay<_ValueType>>
-      enable_if_t<is_copy_constructible<_Tp>::value, any&>
+    template<typename _ValueType>
+      enable_if_t<is_copy_constructible<_Decay<_ValueType>>::value, any&>
       operator=(_ValueType&& __rhs)
       {
        *this = any(std::forward<_ValueType>(__rhs));
@@ -243,29 +267,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
     /// Emplace with an object created from @p __args as the contained object.
-    template <typename _ValueType, typename... _Args,
-             typename _Tp = _Decay<_ValueType>,
-             typename _Mgr = _Manager<_Tp>,
-              __any_constructible_t<_Tp, _Args&&...> = false>
-      void emplace(_Args&&... __args)
+    template <typename _ValueType, typename... _Args>
+      typename __any_constructible<void,
+                                  _Decay<_ValueType>, _Args&&...>::type
+      emplace(_Args&&... __args)
       {
-       reset();
-       _M_manager = &_Mgr::_S_manage;
-        _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
+       __do_emplace<_Decay<_ValueType>>
+         (std::forward<_Args>(__args)...);
       }
 
     /// Emplace with an object created from @p __il and @p __args as
     /// the contained object.
-    template <typename _ValueType, typename _Up, typename... _Args,
-             typename _Tp = _Decay<_ValueType>,
-             typename _Mgr = _Manager<_Tp>,
-              __any_constructible_t<_Tp, initializer_list<_Up>,
-                                   _Args&&...> = false>
-      void emplace(initializer_list<_Up> __il, _Args&&... __args)
+    template <typename _ValueType, typename _Up, typename... _Args>
+      typename __any_constructible<void,
+                                  _Decay<_ValueType>,
+                                  initializer_list<_Up>,
+                                  _Args&&...>::type
+      emplace(initializer_list<_Up> __il, _Args&&... __args)
       {
-       reset();
-       _M_manager = &_Mgr::_S_manage;
-        _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
+       __do_emplace<_Decay<_ValueType>, _Up>
+         (__il, std::forward<_Args>(__args)...);
       }
 
     // modifiers
index f272876fd8b3b9908472ddf7392a9f87b1244ec9..35b6932fc984451f94a82bd7426a5843701ab2ef 100644 (file)
@@ -96,53 +96,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __throw_bad_optional_access(const char* __s)
   { _GLIBCXX_THROW_OR_ABORT(bad_optional_access(__s)); }
 
-  template<typename _Tp, typename = void>
-    struct _Has_addressof_mem : std::false_type { };
-
-  template<typename _Tp>
-    struct _Has_addressof_mem<_Tp,
-         __void_t<decltype( std::declval<const _Tp&>().operator&() )>
-      >
-    : std::true_type { };
-
-  template<typename _Tp, typename = void>
-    struct _Has_addressof_free : std::false_type { };
-
-  template<typename _Tp>
-    struct _Has_addressof_free<_Tp,
-         __void_t<decltype( operator&(std::declval<const _Tp&>()) )>
-      >
-    : std::true_type { };
-
-  /**
-    * @brief Trait that detects the presence of an overloaded unary operator&.
-    *
-    * Practically speaking this detects the presence of such an operator when
-    * called on a const-qualified lvalue (e.g.
-    * declval<const _Tp&>().operator&()).
-    */
-  template<typename _Tp>
-    struct _Has_addressof
-    : std::__or_<_Has_addressof_mem<_Tp>, _Has_addressof_free<_Tp>>::type
-    { };
-
-  /**
-    * @brief An overload that attempts to take the address of an lvalue as a
-    * constant expression. Falls back to __addressof in the presence of an
-    * overloaded addressof operator (unary operator&), in which case the call
-    * will not be a constant expression.
-    */
-  template<typename _Tp, enable_if_t<!_Has_addressof<_Tp>::value, int>...>
-    constexpr _Tp* __constexpr_addressof(_Tp& __t)
-    { return &__t; }
-
-  /**
-    * @brief Fallback overload that defers to __addressof.
-    */
-  template<typename _Tp, enable_if_t<_Has_addressof<_Tp>::value, int>...>
-    inline _Tp* __constexpr_addressof(_Tp& __t)
-    { return std::__addressof(__t); }
-
   /**
     * @brief Class template that holds the necessary state for @ref optional
     * and that has the responsibility for construction and the special members.
@@ -681,7 +634,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // Observers.
       constexpr const _Tp*
       operator->() const
-      { return __constexpr_addressof(this->_M_get()); }
+      { return std::__addressof(this->_M_get()); }
 
       _Tp*
       operator->()
index c06a040a960995d18da4531a46757460c7ffc55f..63cacd4935c987ace8d93f517bfa124dea2ceff7 100644 (file)
@@ -846,20 +846,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        return *this;
       }
 
-      template<typename... _UElements, typename = typename
+      template<typename... _UElements>
+       typename
               enable_if<sizeof...(_UElements)
-                        == sizeof...(_Elements)>::type>
-        tuple&
+                        == sizeof...(_Elements), tuple&>::type
         operator=(const tuple<_UElements...>& __in)
         {
          static_cast<_Inherited&>(*this) = __in;
          return *this;
        }
 
-      template<typename... _UElements, typename = typename
+      template<typename... _UElements>
+       typename
               enable_if<sizeof...(_UElements)
-                        == sizeof...(_Elements)>::type>
-        tuple&
+                        == sizeof...(_Elements), tuple&>::type
         operator=(tuple<_UElements...>&& __in)
         {
          static_cast<_Inherited&>(*this) = std::move(__in);
index 8b306665f391c5755ee7f206f09603fa3fb16e45..4de400d717ef62735dd7cc0a9a5b016206b43143 100644 (file)
@@ -26,5 +26,5 @@ void test01()
   using std::any_cast;
 
   const any y(1);
-  any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 432 }
+  any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 453 }
 }