頭檔案
c++/5/ext/new_allocator.h
c++/5/ext/allocator_traits.h
x86_64-linux-gnu/c++/5/bits/c++allocator.h
c++/5/bits/allocator.h
作用
為基本資料類及定義類 類型 構造記憶體空間。
源代碼解析
new_allocator.h
//new_allocator.h
template<typename _Tp>
class new_allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Tp* pointer;
typedef const _Tp* const_pointer;
typedef _Tp& reference;
typedef const _Tp& const_reference;
typedef _Tp value_type;
template<typename _Tp1>
struct rebind
{ typedef new_allocator<_Tp1> other; };
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2103. propagate_on_container_move_assignment
typedef std::true_type propagate_on_container_move_assignment;
#endif
//構造函數
new_allocator() _GLIBCXX_USE_NOEXCEPT { }
//拷貝構造函數
new_allocator(const new_allocator&) _GLIBCXX_USE_NOEXCEPT { }
template<typename _Tp1>
new_allocator(const new_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { }
//析構函數
~new_allocator() _GLIBCXX_USE_NOEXCEPT { }
//擷取 _Tp 類型 變量的位址
pointer
address(reference __x) const _GLIBCXX_NOEXCEPT
{ return std::__addressof(__x); }
//擷取 _Tp 類型 變量的位址
const_pointer
address(const_reference __x) const _GLIBCXX_NOEXCEPT
{ return std::__addressof(__x); }
// NB: __n is permitted to be 0. The C++ standard says nothing
// about what the return value is when __n == 0.
//申請類型為 _Tp ,數量為n, 的記憶體,即數組
pointer
allocate(size_type __n, const void* = 0)
{
if (__n > this->max_size())
std::__throw_bad_alloc();
return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
}
// __p is not permitted to be a null pointer.
// 釋放 _Tp* 記憶體
void
deallocate(pointer __p, size_type)
{ ::operator delete(__p); }
//擷取 最大的容量
size_type
max_size() const _GLIBCXX_USE_NOEXCEPT
{ return size_t(-1) / sizeof(_Tp); }
#if __cplusplus >= 201103L
template<typename _Up, typename... _Args>
void
construct(_Up* __p, _Args&&... __args)
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
template<typename _Up>
void
destroy(_Up* __p) { __p->~_Up(); }
#else
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 402. wrong new expression in [some_] allocator::construct
void
construct(pointer __p, const _Tp& __val)
{ ::new((void *)__p) _Tp(__val); }
//調用 _Tp* 的析構函數,并沒有釋放記憶體
void
destroy(pointer __p) { __p->~_Tp(); }
#endif
};
c++allocator.h
#if __cplusplus >= 201103L
namespace std
{
/**
* @brief An alias to the base class for std::allocator.
* @ingroup allocators
*
* Used to set the std::allocator base class to
* __gnu_cxx::new_allocator.
*
* @tparam _Tp Type of allocated object.
*/
template<typename _Tp>
using __allocator_base = __gnu_cxx::new_allocator<_Tp>;
}
#else
// Define new_allocator as the base class to std::allocator.
# define __allocator_base __gnu_cxx::new_allocator
#endif
allocator.h
template<typename _Tp>
class allocator: public __allocator_base<_Tp>
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Tp* pointer;
typedef const _Tp* const_pointer;
typedef _Tp& reference;
typedef const _Tp& const_reference;
typedef _Tp value_type;
template<typename _Tp1>
struct rebind
{ typedef allocator<_Tp1> other; };
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2103. std::allocator propagate_on_container_move_assignment
typedef true_type propagate_on_container_move_assignment;
#endif
allocator() throw() { }
allocator(const allocator& __a) throw()
: __allocator_base<_Tp>(__a) { }
template<typename _Tp1>
allocator(const allocator<_Tp1>&) throw() { }
~allocator() throw() { }
// Inherit everything else.
};
alloc_traits.h
template<typename _Alloc>
struct __alloc_traits
#if __cplusplus >= 201103L
: std::allocator_traits<_Alloc>
#endif
{
typedef _Alloc allocator_type;
#if __cplusplus >= 201103L
typedef std::allocator_traits<_Alloc> _Base_type;
typedef typename _Base_type::value_type value_type;
typedef typename _Base_type::pointer pointer;
typedef typename _Base_type::const_pointer const_pointer;
typedef typename _Base_type::size_type size_type;
typedef typename _Base_type::difference_type difference_type;
// C++11 allocators do not define reference or const_reference
typedef value_type& reference;
typedef const value_type& const_reference;
using _Base_type::allocate;
using _Base_type::deallocate;
using _Base_type::construct;
using _Base_type::destroy;
using _Base_type::max_size;
private:
template<typename _Ptr>
using __is_custom_pointer
= std::__and_<std::is_same<pointer, _Ptr>,
std::__not_<std::is_pointer<_Ptr>>>;
public:
// overload construct for non-standard pointer types
template<typename _Ptr, typename... _Args>
static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type
construct(_Alloc& __a, _Ptr __p, _Args&&... __args)
{
_Base_type::construct(__a, std::addressof(*__p),
std::forward<_Args>(__args)...);
}
// overload destroy for non-standard pointer types
template<typename _Ptr>
static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type
destroy(_Alloc& __a, _Ptr __p)
{ _Base_type::destroy(__a, std::addressof(*__p)); }
static _Alloc _S_select_on_copy(const _Alloc& __a)
{ return _Base_type::select_on_container_copy_construction(__a); }
static void _S_on_swap(_Alloc& __a, _Alloc& __b)
{ std::__alloc_on_swap(__a, __b); }
static constexpr bool _S_propagate_on_copy_assign()
{ return _Base_type::propagate_on_container_copy_assignment::value; }
static constexpr bool _S_propagate_on_move_assign()
{ return _Base_type::propagate_on_container_move_assignment::value; }
static constexpr bool _S_propagate_on_swap()
{ return _Base_type::propagate_on_container_swap::value; }
static constexpr bool _S_always_equal()
{ return __allocator_always_compares_equal<_Alloc>::value; }
static constexpr bool _S_nothrow_move()
{ return _S_propagate_on_move_assign() || _S_always_equal(); }
static constexpr bool _S_nothrow_swap()
{
using std::swap;
return !_S_propagate_on_swap()
|| noexcept(swap(std::declval<_Alloc&>(), std::declval<_Alloc&>()));
}
template<typename _Tp>
struct rebind
{ typedef typename _Base_type::template rebind_alloc<_Tp> other; };
#else
typedef typename _Alloc::pointer pointer;
typedef typename _Alloc::const_pointer const_pointer;
typedef typename _Alloc::value_type value_type;
typedef typename _Alloc::reference reference;
typedef typename _Alloc::const_reference const_reference;
typedef typename _Alloc::size_type size_type;
typedef typename _Alloc::difference_type difference_type;
static pointer
allocate(_Alloc& __a, size_type __n)
{ return __a.allocate(__n); }
static void deallocate(_Alloc& __a, pointer __p, size_type __n)
{ __a.deallocate(__p, __n); }
template<typename _Tp>
static void construct(_Alloc& __a, pointer __p, const _Tp& __arg)
{ __a.construct(__p, __arg); }
static void destroy(_Alloc& __a, pointer __p)
{ __a.destroy(__p); }
static size_type max_size(const _Alloc& __a)
{ return __a.max_size(); }
static const _Alloc& _S_select_on_copy(const _Alloc& __a) { return __a; }
static void _S_on_swap(_Alloc& __a, _Alloc& __b)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 431. Swapping containers with unequal allocators.
std::__alloc_swap<_Alloc>::_S_do_it(__a, __b);
}
template<typename _Tp>
struct rebind
{ typedef typename _Alloc::template rebind<_Tp>::other other; };
#endif
};