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