]> 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 ded2bb275222f27d2e3cad25456e044db15f466d..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.
    */
@@ -114,8 +114,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       void __do_emplace(_Args&&... __args)
       {
        reset();
-       _M_manager = &_Mgr::_S_manage;
         _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
@@ -125,8 +125,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       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)...);
+       _M_manager = &_Mgr::_S_manage;
       }
 
   public:
@@ -189,9 +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&&>>,
-                                __not_<__is_in_place_type<_Tp>>>::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)
@@ -268,25 +268,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     /// Emplace with an object created from @p __args as the contained object.
     template <typename _ValueType, typename... _Args>
-      typename __any_constructible<void,
+      typename __any_constructible<_Decay<_ValueType>&,
                                   _Decay<_ValueType>, _Args&&...>::type
       emplace(_Args&&... __args)
       {
-       __do_emplace<_Decay<_ValueType>>
-         (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 _ValueType, typename _Up, typename... _Args>
-      typename __any_constructible<void,
+      typename __any_constructible<_Decay<_ValueType>&,
                                   _Decay<_ValueType>,
                                   initializer_list<_Up>,
                                   _Args&&...>::type
       emplace(initializer_list<_Up> __il, _Args&&... __args)
       {
-       __do_emplace<_Decay<_ValueType>, _Up>
-         (__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
@@ -446,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();
     }
 
@@ -469,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.
@@ -530,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;
     }
   // @}
@@ -611,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