1 // Allocator that wraps operator new -*- C++ -*- 2 3 // Copyright (C) 2001-2013 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file ext/new_allocator.h 26 * This file is a GNU extension to the Standard C++ Library. 27 */ 28 29 #ifndef _NEW_ALLOCATOR_H 30 #define _NEW_ALLOCATOR_H 1 31 32 #include <bits/c++config.h> 33 #include <new> 34 #include <bits/functexcept.h> 35 #include <bits/move.h> 36 #if __cplusplus >= 201103L 37 #include <type_traits> 38 #endif 39 40 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 41 { 42 _GLIBCXX_BEGIN_NAMESPACE_VERSION 43 44 using std::size_t; 45 using std::ptrdiff_t; 46 47 /** 48 * @brief An allocator that uses global new, as per [20.4]. 49 * @ingroup allocators 50 * 51 * This is precisely the allocator defined in the C++ Standard. 52 * - all allocation calls operator new 53 * - all deallocation calls operator delete 54 * 55 * @tparam _Tp Type of allocated object. 56 */ 57 template<typename _Tp> 58 class new_allocator 59 { 60 public: 61 typedef size_t size_type; 62 typedef ptrdiff_t difference_type; 63 typedef _Tp* pointer; 64 typedef const _Tp* const_pointer; 65 typedef _Tp& reference; 66 typedef const _Tp& const_reference; 67 typedef _Tp value_type; 68 69 template<typename _Tp1> 70 struct rebind 71 { typedef new_allocator<_Tp1> other; }; 72 73 #if __cplusplus >= 201103L 74 // _GLIBCXX_RESOLVE_LIB_DEFECTS 75 // 2103. propagate_on_container_move_assignment 76 typedef std::true_type propagate_on_container_move_assignment; 77 #endif 78 79 new_allocator() _GLIBCXX_USE_NOEXCEPT { } 80 81 new_allocator(const new_allocator&) _GLIBCXX_USE_NOEXCEPT { } 82 83 template<typename _Tp1> 84 new_allocator(const new_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { } 85 86 ~new_allocator() _GLIBCXX_USE_NOEXCEPT { } 87 88 pointer 89 address(reference __x) const _GLIBCXX_NOEXCEPT 90 { return std::__addressof(__x); } 91 92 const_pointer 93 address(const_reference __x) const _GLIBCXX_NOEXCEPT 94 { return std::__addressof(__x); } 95 96 // NB: __n is permitted to be 0. The C++ standard says nothing 97 // about what the return value is when __n == 0. 98 pointer 99 allocate(size_type __n, const void* = 0) 100 { 101 if (__n > this->max_size()) 102 std::__throw_bad_alloc(); 103 104 return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); 105 } 106 107 // __p is not permitted to be a null pointer. 108 void 109 deallocate(pointer __p, size_type) 110 { ::operator delete(__p); } 111 112 size_type 113 max_size() const _GLIBCXX_USE_NOEXCEPT 114 { return size_t(-1) / sizeof(_Tp); } 115 116 #if __cplusplus >= 201103L 117 template<typename _Up, typename... _Args> 118 void 119 construct(_Up* __p, _Args&&... __args) 120 { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } 121 122 template<typename _Up> 123 void 124 destroy(_Up* __p) { __p->~_Up(); } 125 #else 126 // _GLIBCXX_RESOLVE_LIB_DEFECTS 127 // 402. wrong new expression in [some_] allocator::construct 128 void 129 construct(pointer __p, const _Tp& __val) 130 { ::new((void *)__p) _Tp(__val); } 131 132 void 133 destroy(pointer __p) { __p->~_Tp(); } 134 #endif 135 }; 136 137 template<typename _Tp> 138 inline bool 139 operator==(const new_allocator<_Tp>&, const new_allocator<_Tp>&) 140 { return true; } 141 142 template<typename _Tp> 143 inline bool 144 operator!=(const new_allocator<_Tp>&, const new_allocator<_Tp>&) 145 { return false; } 146 147 _GLIBCXX_END_NAMESPACE_VERSION 148 } // namespace 149 150 #endif 151