// <any> -*- C++ -*-
-// Copyright (C) 2014-2021 Free Software Foundation, Inc.
+// Copyright (C) 2014-2022 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
#if __cplusplus >= 201703L
+#include <initializer_list>
#include <typeinfo>
#include <new>
-#include <utility>
#include <type_traits>
+#include <bits/utility.h> // in_place_type_t
namespace std _GLIBCXX_VISIBILITY(default)
{
/**
* @brief A type-safe container of any type.
*
- * An @c any object's state is either empty or it stores a contained object
+ * An `any` object's state is either empty or it stores a contained object
* of CopyConstructible type.
+ *
+ * @since C++17
*/
class any
{
struct _Manager_external; // creates contained object on the heap
template<typename _Tp>
- using _Manager = conditional_t<_Internal<_Tp>::value,
- _Manager_internal<_Tp>,
- _Manager_external<_Tp>>;
+ using _Manager = __conditional_t<_Internal<_Tp>::value,
+ _Manager_internal<_Tp>,
+ _Manager_external<_Tp>>;
template<typename _Tp, typename _VTp = decay_t<_Tp>>
using _Decay_if_not_any = enable_if_t<!is_same_v<_VTp, any>, _VTp>;
/// Construct with a copy of @p __value as the contained object.
template <typename _Tp, typename _VTp = _Decay_if_not_any<_Tp>,
typename _Mgr = _Manager<_VTp>,
- enable_if_t<is_copy_constructible<_VTp>::value
- && !__is_in_place_type<_VTp>::value, bool> = true>
+ typename = _Require<__not_<__is_in_place_type<_VTp>>,
+ is_copy_constructible<_VTp>>>
any(_Tp&& __value)
: _M_manager(&_Mgr::_S_manage)
{
/// the contained object.
template <typename _Tp, typename _Up, typename... _Args,
typename _VTp = decay_t<_Tp>, typename _Mgr = _Manager<_VTp>,
- __any_constructible_t<_VTp, initializer_list<_Up>,
+ __any_constructible_t<_VTp, initializer_list<_Up>&,
_Args&&...> = false>
explicit
any(in_place_type_t<_Tp>, initializer_list<_Up> __il, _Args&&... __args)
{
using _VTp = decay_t<_Tp>;
__do_emplace<_VTp>(std::forward<_Args>(__args)...);
- any::_Arg __arg;
- this->_M_manager(any::_Op_access, this, &__arg);
- return *static_cast<_VTp*>(__arg._M_obj);
+ return *any::_Manager<_VTp>::_S_access(_M_storage);
}
/// Emplace with an object created from @p __il and @p __args as
/// the contained object.
template <typename _Tp, typename _Up, typename... _Args>
- __emplace_t<decay_t<_Tp>, initializer_list<_Up>, _Args&&...>
+ __emplace_t<decay_t<_Tp>, initializer_list<_Up>&, _Args&&...>
emplace(initializer_list<_Up> __il, _Args&&... __args)
{
using _VTp = decay_t<_Tp>;
__do_emplace<_VTp, _Up>(__il, std::forward<_Args>(__args)...);
- any::_Arg __arg;
- this->_M_manager(any::_Op_access, this, &__arg);
- return *static_cast<_VTp*>(__arg._M_obj);
+ return *any::_Manager<_VTp>::_S_access(_M_storage);
}
// modifiers
}
#endif
+ /// @cond undocumented
template<typename _Tp>
static constexpr bool __is_valid_cast()
{ return __or_<is_reference<_Tp>, is_copy_constructible<_Tp>>::value; }
+ /// @endcond
private:
enum _Op {
void (*_M_manager)(_Op, const any*, _Arg*);
_Storage _M_storage;
+ /// @cond undocumented
template<typename _Tp>
friend void* __any_caster(const any* __any);
+ /// @endcond
// Manage in-place contained object.
template<typename _Tp>
void* __addr = &__storage._M_buffer;
::new (__addr) _Tp(std::forward<_Args>(__args)...);
}
+
+ static _Tp*
+ _S_access(const _Storage& __storage)
+ {
+ // The contained object is in __storage._M_buffer
+ const void* __addr = &__storage._M_buffer;
+ return static_cast<_Tp*>(const_cast<void*>(__addr));
+ }
};
// Manage external contained object.
{
__storage._M_ptr = new _Tp(std::forward<_Args>(__args)...);
}
+ static _Tp*
+ _S_access(const _Storage& __storage)
+ {
+ // The contained object is in *__storage._M_ptr
+ return static_cast<_Tp*>(__storage._M_ptr);
+ }
};
};
/// Exchange the states of two @c any objects.
inline void swap(any& __x, any& __y) noexcept { __x.swap(__y); }
- /// Create an any holding a @c _Tp constructed from @c __args.
+ /// Create an `any` holding a `_Tp` constructed from `__args...`.
template <typename _Tp, typename... _Args>
- any make_any(_Args&&... __args)
+ inline
+ enable_if_t<is_constructible_v<any, in_place_type_t<_Tp>, _Args...>, any>
+ make_any(_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.
+ /// Create an `any` holding a `_Tp` constructed from `__il` and `__args...`.
template <typename _Tp, typename _Up, typename... _Args>
- any make_any(initializer_list<_Up> __il, _Args&&... __args)
+ inline
+ enable_if_t<is_constructible_v<any, in_place_type_t<_Tp>,
+ initializer_list<_Up>&, _Args...>, any>
+ make_any(initializer_list<_Up> __il, _Args&&... __args)
{
return any(in_place_type<_Tp>, __il, std::forward<_Args>(__args)...);
}
return static_cast<_ValueType>(std::move(*__p));
__throw_bad_any_cast();
}
- // @}
+ /// @}
/// @cond undocumented
template<typename _Tp>
#endif
)
{
- any::_Arg __arg;
- __any->_M_manager(any::_Op_access, __any, &__arg);
- return __arg._M_obj;
+ return any::_Manager<_Up>::_S_access(__any->_M_storage);
}
return nullptr;
}
return static_cast<_ValueType*>(__any_caster<_ValueType>(__any));
return nullptr;
}
- // @}
+ /// @}
template<typename _Tp>
void