1 主要变量与函数
存储
// Holds either pointer to a heap object or the contained object itself.
union _Storage {
constexpr _Storage() : _M_ptr{
nullptr} {
}
// Prevent trivial copies of this type, buffer might hold a non-POD.
_Storage(const _Storage &) = delete;
_Storage &operator=(const _Storage &) = delete;
void *_M_ptr;
aligned_storage<sizeof(_M_ptr), alignof(void *)>::type _M_buffer;
};
这个共用体_Storage
是any类的存储实体,它可以使用_M_buffer
作为实际的存储,或者使用_M_ptr
指向在heap上存储的实际对象。
那么如何判定是存储在哪儿的呢?
template <typename _Tp, typename _Safe = is_nothrow_move_constructible<_Tp>,
bool _Fits = (sizeof(_Tp) <= sizeof(_Storage)) &&
(alignof(_Tp) <= alignof(_Storage))>
using _Internal = std::integral_constant<bool, _Safe::value && _Fits>;
所以,如果一个类型是不抛异常的可移动构造,且能放入进_Storage
的,则是internal的。
对于是否internal,对应有不同的manager:
template <typename _Tp>
using _Manager =
conditional_t<_Internal<_Tp>::value, _Manager_internal<_Tp>,
_Manager_external<_Tp>>;
主要数据成员
private:
enum _Op {
_Op_access,
_Op_get_type_info,
_Op_clone,
_Op_destroy,
_Op_xfer
};
union _Arg {
void *_M_obj;
const std::type_info *_M_typeinfo;
any *_M_any;
};
void (*_M_manager)(_Op, const any *, _Arg *);
_Storage _M_storage;
_M_manager
就是负责管理具体数据的函数指针,具体见下。
从具体代码可以看出,共用体_Arg
的两个主要成员变量:_M_obj
指向实际的数据位置,如_M_buffer
或_M_ptr
;_M_any
指向一个any对象。
_Op
、_Arg
一般都是在_M_manager
内使用的。
内部、外部存储manager
// Manage in-place contained object.
template <typename _Tp> struct _Manager_internal {
static void _S_manage(_Op __which, const any *__any, _Arg *__arg) {
// The contained object is in _M_storage._M_buffer
auto __ptr = reinterpret_cast<const _Tp *>(&__any->_M_storage._M_buffer);
switch (__which) {
case _Op_access:
__arg->_M_obj = const_cast<_Tp *>(__ptr);
break;
case _Op_get_type_info:
#if __cpp_rtti
__arg->_M_typeinfo = &typeid(_Tp);
#endif
break;
case _Op_clone:
::new (&__arg->_M_any->_M_storage._M_buffer) _Tp(*__ptr);
__arg->_M_any->_M_manager = __any->_M_manager;
break;
case _Op_destroy:
__ptr->~_Tp();
break;
case _Op_xfer:
::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;
break;
}
}
template <typename _Up>
static void _S_create(_Storage &__storage, _Up &&__value) {
void *__addr = &__storage._M_buffer;
::new (__addr) _Tp(std::forward<_Up>(__value));
}
template <typename... _Args>
static void _S_create(_Storage &__storage, _Args &&...__args) {
void *__addr = &__storage._M_buffer;
::new (__addr) _Tp(std::forward<_Args>(__args)...);
}
};
// Manage external contained object.
te