]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libstdc++-v3/include/std/any
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / include / std / any
index 54882d797e20414655ce3c1c299db73921bbcd9a..6b7e68f0e63a7a3664fae24faadceeba657570db 100644 (file)
@@ -1,6 +1,6 @@
 // <any> -*- C++ -*-
 
-// Copyright (C) 2014-2016 Free Software Foundation, Inc.
+// Copyright (C) 2014-2020 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -31,9 +31,7 @@
 
 #pragma GCC system_header
 
-#if __cplusplus <= 201402L
-# include <bits/c++17_warning.h>
-#else
+#if __cplusplus >= 201703L
 
 #include <typeinfo>
 #include <new>
@@ -68,9 +66,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
   }
 
+#define __cpp_lib_any 201606L
+
   /**
    *  @brief A type-safe container of any type.
-   * 
+   *
    *  An @c any object's state is either empty or it stores a contained object
    *  of CopyConstructible type.
    */
@@ -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();
+        _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
+       _M_manager = &_Mgr::_S_manage;
+      }
+
+    /// 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();
+        _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
+       _M_manager = &_Mgr::_S_manage;
+      }
+
   public:
     // construct/destruct
 
@@ -144,16 +165,21 @@ _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>,
              typename _Mgr = _Manager<_Tp>,
-              __any_constructible_t<_Tp, _ValueType&&> = true>
+              __any_constructible_t<_Tp, _ValueType&&> = true,
+             enable_if_t<!__is_in_place_type<_Tp>::value, bool> = true>
       any(_ValueType&& __value)
       : _M_manager(&_Mgr::_S_manage)
       {
@@ -163,10 +189,9 @@ _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>,
-              enable_if_t<__and_<is_copy_constructible<_Tp>,
-                                __not_<
-                                  is_constructible<_Tp,
-                                                   _ValueType&&>>>::value,
+              enable_if_t<__and_v<is_copy_constructible<_Tp>,
+                                 __not_<is_constructible<_Tp, _ValueType&&>>,
+                                 __not_<__is_in_place_type<_Tp>>>,
                          bool> = false>
       any(_ValueType&& __value)
       : _M_manager(&_Mgr::_S_manage)
@@ -175,10 +200,12 @@ _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)
+      explicit
+      any(in_place_type_t<_ValueType>, _Args&&... __args)
       : _M_manager(&_Mgr::_S_manage)
       {
         _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
@@ -186,11 +213,14 @@ _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)
+      explicit
+      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)...);
@@ -204,16 +234,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     /// Copy the state of another object.
     any& operator=(const any& __rhs)
     {
-      if (!__rhs.has_value())
-       reset();
-      else if (this != &__rhs)
-       {
-         if (has_value())
-           _M_manager(_Op_destroy, this, nullptr);
-         _Arg __arg;
-         __arg._M_any = this;
-         __rhs._M_manager(_Op_clone, &__rhs, &__arg);
-       }
+      *this = any(__rhs);
       return *this;
     }
 
@@ -228,8 +249,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        reset();
       else if (this != &__rhs)
        {
-         if (has_value())
-           _M_manager(_Op_destroy, this, nullptr);
+         reset();
          _Arg __arg;
          __arg._M_any = this;
          __rhs._M_manager(_Op_xfer, &__rhs, &__arg);
@@ -239,8 +259,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     /// Store a copy of @p __rhs as the contained object.
     template<typename _ValueType>
-    enable_if_t<__and_<__not_<is_same<any, decay_t<_ValueType>>>,
-                      is_copy_constructible<_ValueType>>::value, any&>
+      enable_if_t<is_copy_constructible<_Decay<_ValueType>>::value, any&>
       operator=(_ValueType&& __rhs)
       {
        *this = any(std::forward<_ValueType>(__rhs));
@@ -248,27 +267,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
     /// Emplace with an object created from @p __args as the contained object.
-    template <typename _Tp, typename... _Args,
-             typename _Mgr = _Manager<_Tp>,
-              __any_constructible_t<_Tp, _Args&&...> = false>
-      void emplace(_Args&&... __args)
+    template <typename _ValueType, typename... _Args>
+      typename __any_constructible<_Decay<_ValueType>&,
+                                  _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)...);
+       any::_Arg __arg;
+       this->_M_manager(any::_Op_access, this, &__arg);
+       return *static_cast<_Decay<_ValueType>*>(__arg._M_obj);
       }
 
     /// 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>,
-              __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<_Decay<_ValueType>&,
+                                  _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)...);
+       any::_Arg __arg;
+       this->_M_manager(any::_Op_access, this, &__arg);
+       return *static_cast<_Decay<_ValueType>*>(__arg._M_obj);
       }
 
     // modifiers
@@ -405,14 +428,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template <typename _Tp, typename... _Args>
     any make_any(_Args&&... __args)
     {
-      return any(in_place<_Tp>, std::forward<_Args>(__args)...);
+      return any(in_place_type<_Tp>, std::forward<_Args>(__args)...);
     }
 
   /// Create an any holding a @c _Tp constructed from @c __il and @c __args.
   template <typename _Tp, typename _Up, typename... _Args>
     any make_any(initializer_list<_Up> __il, _Args&&... __args)
     {
-      return any(in_place<_Tp>, __il, std::forward<_Args>(__args)...);
+      return any(in_place_type<_Tp>, __il, std::forward<_Args>(__args)...);
     }
 
   /**
@@ -428,11 +451,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _ValueType>
     inline _ValueType any_cast(const any& __any)
     {
+      using _Up = __remove_cvref_t<_ValueType>;
       static_assert(any::__is_valid_cast<_ValueType>(),
          "Template argument must be a reference or CopyConstructible type");
-      auto __p = any_cast<add_const_t<remove_reference_t<_ValueType>>>(&__any);
+      static_assert(is_constructible_v<_ValueType, const _Up&>,
+         "Template argument must be constructible from a const value.");
+      auto __p = any_cast<_Up>(&__any);
       if (__p)
-       return *__p;
+       return static_cast<_ValueType>(*__p);
       __throw_bad_any_cast();
     }
 
@@ -451,52 +477,60 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _ValueType>
     inline _ValueType any_cast(any& __any)
     {
+      using _Up = __remove_cvref_t<_ValueType>;
       static_assert(any::__is_valid_cast<_ValueType>(),
          "Template argument must be a reference or CopyConstructible type");
-      auto __p = any_cast<remove_reference_t<_ValueType>>(&__any);
+      static_assert(is_constructible_v<_ValueType, _Up&>,
+         "Template argument must be constructible from an lvalue.");
+      auto __p = any_cast<_Up>(&__any);
       if (__p)
-       return *__p;
+       return static_cast<_ValueType>(*__p);
       __throw_bad_any_cast();
     }
 
-  template<typename _ValueType,
-           typename enable_if<!is_move_constructible<_ValueType>::value
-                              || is_lvalue_reference<_ValueType>::value,
-                              bool>::type = true>
-    inline _ValueType any_cast(any&& __any)
-    {
-      static_assert(any::__is_valid_cast<_ValueType>(),
-         "Template argument must be a reference or CopyConstructible type");
-      auto __p = any_cast<remove_reference_t<_ValueType>>(&__any);
-      if (__p)
-       return *__p;
-      __throw_bad_any_cast();
-    }
-
-  template<typename _ValueType,
-           typename enable_if<is_move_constructible<_ValueType>::value
-                              && !is_lvalue_reference<_ValueType>::value,
-                              bool>::type = false>
+  template<typename _ValueType>
     inline _ValueType any_cast(any&& __any)
     {
+      using _Up = __remove_cvref_t<_ValueType>;
       static_assert(any::__is_valid_cast<_ValueType>(),
          "Template argument must be a reference or CopyConstructible type");
-      auto __p = any_cast<remove_reference_t<_ValueType>>(&__any);
+      static_assert(is_constructible_v<_ValueType, _Up>,
+         "Template argument must be constructible from an rvalue.");
+      auto __p = any_cast<_Up>(&__any);
       if (__p)
-       return std::move(*__p);
+       return static_cast<_ValueType>(std::move(*__p));
       __throw_bad_any_cast();
     }
   // @}
 
+  /// @cond undocumented
   template<typename _Tp>
     void* __any_caster(const any* __any)
     {
-      if (__any->_M_manager != &any::_Manager<decay_t<_Tp>>::_S_manage)
+      // any_cast<T> returns non-null if __any->type() == typeid(T) and
+      // typeid(T) ignores cv-qualifiers so remove them:
+      using _Up = remove_cv_t<_Tp>;
+      // The contained value has a decayed type, so if decay_t<U> is not U,
+      // then it's not possible to have a contained value of type U:
+      if constexpr (!is_same_v<decay_t<_Up>, _Up>)
        return nullptr;
-      any::_Arg __arg;
-      __any->_M_manager(any::_Op_access, __any, &__arg);
-      return __arg._M_obj;
+      // Only copy constructible types can be used for contained values:
+      else if constexpr (!is_copy_constructible_v<_Up>)
+       return nullptr;
+      // First try comparing function addresses, which works without RTTI
+      else if (__any->_M_manager == &any::_Manager<_Up>::_S_manage
+#if __cpp_rtti
+         || __any->type() == typeid(_Tp)
+#endif
+         )
+       {
+         any::_Arg __arg;
+         __any->_M_manager(any::_Op_access, __any, &__arg);
+         return __arg._M_obj;
+       }
+      return nullptr;
     }
+  /// @endcond
 
   /**
    * @brief Access the contained object.
@@ -512,16 +546,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _ValueType>
     inline const _ValueType* any_cast(const any* __any) noexcept
     {
-      if (__any)
-       return static_cast<_ValueType*>(__any_caster<_ValueType>(__any));
+      if constexpr (is_object_v<_ValueType>)
+       if (__any)
+         return static_cast<_ValueType*>(__any_caster<_ValueType>(__any));
       return nullptr;
     }
 
   template<typename _ValueType>
     inline _ValueType* any_cast(any* __any) noexcept
     {
-      if (__any)
-       return static_cast<_ValueType*>(__any_caster<_ValueType>(__any));
+      if constexpr (is_object_v<_ValueType>)
+       if (__any)
+         return static_cast<_ValueType*>(__any_caster<_ValueType>(__any));
       return nullptr;
     }
   // @}
@@ -551,7 +587,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        __ptr->~_Tp();
        break;
       case _Op_xfer:
-       ::new(&__arg->_M_any->_M_storage._M_buffer) _Tp(*__ptr);
+       ::new(&__arg->_M_any->_M_storage._M_buffer) _Tp
+         (std::move(*const_cast<_Tp*>(__ptr)));
        __ptr->~_Tp();
        __arg->_M_any->_M_manager = __any->_M_manager;
        const_cast<any*>(__any)->_M_manager = nullptr;
@@ -592,10 +629,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
   /// @}
-  
+
+  namespace __detail::__variant
+  {
+    template<typename> struct _Never_valueless_alt; // see <variant>
+
+    // Provide the strong exception-safety guarantee when emplacing an
+    // any into a variant.
+    template<>
+      struct _Never_valueless_alt<std::any>
+      : std::true_type
+      { };
+  }  // namespace __detail::__variant
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
 
-#endif // C++14
-
+#endif // C++17
 #endif // _GLIBCXX_ANY