alloc_construct.hpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*
  2. Copyright 2019 Glen Joseph Fernandes
  3. (glenjofe@gmail.com)
  4. Distributed under the Boost Software License, Version 1.0.
  5. (http://www.boost.org/LICENSE_1_0.txt)
  6. */
  7. #ifndef BOOST_CORE_ALLOC_CONSTRUCT_HPP
  8. #define BOOST_CORE_ALLOC_CONSTRUCT_HPP
  9. #include <boost/core/noinit_adaptor.hpp>
  10. namespace boost {
  11. #if !defined(BOOST_NO_CXX11_ALLOCATOR)
  12. template<class A, class T>
  13. inline void
  14. alloc_destroy(A& a, T* p)
  15. {
  16. std::allocator_traits<A>::destroy(a, p);
  17. }
  18. template<class A, class T>
  19. inline void
  20. alloc_destroy_n(A& a, T* p, std::size_t n)
  21. {
  22. while (n > 0) {
  23. std::allocator_traits<A>::destroy(a, p + --n);
  24. }
  25. }
  26. #else
  27. template<class A, class T>
  28. inline void
  29. alloc_destroy(A&, T* p)
  30. {
  31. p->~T();
  32. }
  33. template<class A, class T>
  34. inline void
  35. alloc_destroy_n(A&, T* p, std::size_t n)
  36. {
  37. while (n > 0) {
  38. p[--n].~T();
  39. }
  40. }
  41. #endif
  42. namespace detail {
  43. template<class A, class T>
  44. class alloc_destroyer {
  45. public:
  46. alloc_destroyer(A& a, T* p) BOOST_NOEXCEPT
  47. : a_(a),
  48. p_(p),
  49. n_(0) { }
  50. ~alloc_destroyer() {
  51. boost::alloc_destroy_n(a_, p_, n_);
  52. }
  53. std::size_t& size() BOOST_NOEXCEPT {
  54. return n_;
  55. }
  56. private:
  57. alloc_destroyer(const alloc_destroyer&);
  58. alloc_destroyer& operator=(const alloc_destroyer&);
  59. A& a_;
  60. T* p_;
  61. std::size_t n_;
  62. };
  63. } /* detail */
  64. #if !defined(BOOST_NO_CXX11_ALLOCATOR)
  65. template<class A, class T>
  66. inline void
  67. alloc_construct(A& a, T* p)
  68. {
  69. std::allocator_traits<A>::construct(a, p);
  70. }
  71. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  72. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  73. template<class A, class T, class U, class... V>
  74. inline void
  75. alloc_construct(A& a, T* p, U&& u, V&&... v)
  76. {
  77. std::allocator_traits<A>::construct(a, p, std::forward<U>(u),
  78. std::forward<V>(v)...);
  79. }
  80. #else
  81. template<class A, class T, class U>
  82. inline void
  83. alloc_construct(A& a, T* p, U&& u)
  84. {
  85. std::allocator_traits<A>::construct(a, p, std::forward<U>(u));
  86. }
  87. #endif
  88. #else
  89. template<class A, class T, class U>
  90. inline void
  91. alloc_construct(A& a, T* p, const U& u)
  92. {
  93. std::allocator_traits<A>::construct(a, p, u);
  94. }
  95. template<class A, class T, class U>
  96. inline void
  97. alloc_construct(A& a, T* p, U& u)
  98. {
  99. std::allocator_traits<A>::construct(a, p, u);
  100. }
  101. #endif
  102. template<class A, class T>
  103. inline void
  104. alloc_construct_n(A& a, T* p, std::size_t n)
  105. {
  106. detail::alloc_destroyer<A, T> hold(a, p);
  107. for (std::size_t& i = hold.size(); i < n; ++i) {
  108. std::allocator_traits<A>::construct(a, p + i);
  109. }
  110. hold.size() = 0;
  111. }
  112. template<class A, class T>
  113. inline void
  114. alloc_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m)
  115. {
  116. detail::alloc_destroyer<A, T> hold(a, p);
  117. for (std::size_t& i = hold.size(); i < n; ++i) {
  118. std::allocator_traits<A>::construct(a, p + i, l[i % m]);
  119. }
  120. hold.size() = 0;
  121. }
  122. template<class A, class T, class I>
  123. inline void
  124. alloc_construct_n(A& a, T* p, std::size_t n, I b)
  125. {
  126. detail::alloc_destroyer<A, T> hold(a, p);
  127. for (std::size_t& i = hold.size(); i < n; void(++i), void(++b)) {
  128. std::allocator_traits<A>::construct(a, p + i, *b);
  129. }
  130. hold.size() = 0;
  131. }
  132. #else
  133. template<class A, class T>
  134. inline void
  135. alloc_construct(A&, T* p)
  136. {
  137. ::new(static_cast<void*>(p)) T();
  138. }
  139. template<class A, class T>
  140. inline void
  141. alloc_construct(noinit_adaptor<A>&, T* p)
  142. {
  143. ::new(static_cast<void*>(p)) T;
  144. }
  145. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  146. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  147. template<class A, class T, class U, class... V>
  148. inline void
  149. alloc_construct(A&, T* p, U&& u, V&&... v)
  150. {
  151. ::new(static_cast<void*>(p)) T(std::forward<U>(u), std::forward<V>(v)...);
  152. }
  153. #else
  154. template<class A, class T, class U>
  155. inline void
  156. alloc_construct(A& a, T* p, U&& u)
  157. {
  158. ::new(static_cast<void*>(p)) T(std::forward<U>(u));
  159. }
  160. #endif
  161. #else
  162. template<class A, class T, class U>
  163. inline void
  164. alloc_construct(A&, T* p, const U& u)
  165. {
  166. ::new(static_cast<void*>(p)) T(u);
  167. }
  168. template<class A, class T, class U>
  169. inline void
  170. alloc_construct(A&, T* p, U& u)
  171. {
  172. ::new(static_cast<void*>(p)) T(u);
  173. }
  174. #endif
  175. template<class A, class T>
  176. inline void
  177. alloc_construct_n(A& a, T* p, std::size_t n)
  178. {
  179. detail::alloc_destroyer<A, T> hold(a, p);
  180. for (std::size_t& i = hold.size(); i < n; ++i) {
  181. ::new(static_cast<void*>(p + i)) T();
  182. }
  183. hold.size() = 0;
  184. }
  185. template<class A, class T>
  186. inline void
  187. alloc_construct_n(noinit_adaptor<A>& a, T* p, std::size_t n)
  188. {
  189. detail::alloc_destroyer<noinit_adaptor<A>, T> hold(a, p);
  190. for (std::size_t& i = hold.size(); i < n; ++i) {
  191. ::new(static_cast<void*>(p + i)) T;
  192. }
  193. hold.size() = 0;
  194. }
  195. template<class A, class T>
  196. inline void
  197. alloc_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m)
  198. {
  199. detail::alloc_destroyer<A, T> hold(a, p);
  200. for (std::size_t& i = hold.size(); i < n; ++i) {
  201. ::new(static_cast<void*>(p + i)) T(l[i % m]);
  202. }
  203. hold.size() = 0;
  204. }
  205. template<class A, class T, class I>
  206. inline void
  207. alloc_construct_n(A& a, T* p, std::size_t n, I b)
  208. {
  209. detail::alloc_destroyer<A, T> hold(a, p);
  210. for (std::size_t& i = hold.size(); i < n; void(++i), void(++b)) {
  211. ::new(static_cast<void*>(p + i)) T(*b);
  212. }
  213. hold.size() = 0;
  214. }
  215. #endif
  216. } /* boost */
  217. #endif