Chris@16
|
1 /*
|
Chris@101
|
2 * Copyright (c) 2012-2014 Glen Joseph Fernandes
|
Chris@16
|
3 * glenfe at live dot com
|
Chris@16
|
4 *
|
Chris@101
|
5 * Distributed under the Boost Software License,
|
Chris@101
|
6 * Version 1.0. (See accompanying file LICENSE_1_0.txt
|
Chris@16
|
7 * or copy at http://boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 */
|
Chris@16
|
9 #ifndef BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP
|
Chris@16
|
10 #define BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP
|
Chris@16
|
11
|
Chris@16
|
12 #include <boost/config.hpp>
|
Chris@16
|
13 #include <boost/type_traits/has_trivial_constructor.hpp>
|
Chris@16
|
14 #include <boost/type_traits/has_trivial_destructor.hpp>
|
Chris@101
|
15 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
Chris@101
|
16 #include <memory>
|
Chris@101
|
17 #endif
|
Chris@16
|
18
|
Chris@16
|
19 namespace boost {
|
Chris@16
|
20 namespace detail {
|
Chris@101
|
21 typedef boost::true_type ms_is_trivial;
|
Chris@101
|
22 typedef boost::false_type ms_no_trivial;
|
Chris@101
|
23
|
Chris@101
|
24 template<class T>
|
Chris@101
|
25 inline void ms_destroy(T*, std::size_t, ms_is_trivial) {
|
Chris@16
|
26 }
|
Chris@101
|
27
|
Chris@101
|
28 template<class T>
|
Chris@101
|
29 inline void ms_destroy(T* memory, std::size_t size, ms_no_trivial) {
|
Chris@101
|
30 for (std::size_t i = size; i > 0;) {
|
Chris@16
|
31 memory[--i].~T();
|
Chris@16
|
32 }
|
Chris@16
|
33 }
|
Chris@101
|
34
|
Chris@101
|
35 template<class T>
|
Chris@101
|
36 inline void ms_destroy(T* memory, std::size_t size) {
|
Chris@101
|
37 boost::has_trivial_destructor<T> trivial;
|
Chris@101
|
38 ms_destroy(memory, size, trivial);
|
Chris@16
|
39 }
|
Chris@101
|
40
|
Chris@101
|
41 template<class T>
|
Chris@101
|
42 inline void ms_init(T* memory, std::size_t size, ms_is_trivial) {
|
Chris@16
|
43 for (std::size_t i = 0; i < size; i++) {
|
Chris@101
|
44 void* p1 = memory + i;
|
Chris@101
|
45 ::new(p1) T();
|
Chris@16
|
46 }
|
Chris@16
|
47 }
|
Chris@101
|
48
|
Chris@101
|
49 template<class T>
|
Chris@101
|
50 inline void ms_init(T* memory, std::size_t size, ms_no_trivial) {
|
Chris@16
|
51 #if !defined(BOOST_NO_EXCEPTIONS)
|
Chris@16
|
52 std::size_t i = 0;
|
Chris@16
|
53 try {
|
Chris@16
|
54 for (; i < size; i++) {
|
Chris@16
|
55 void* p1 = memory + i;
|
Chris@16
|
56 ::new(p1) T();
|
Chris@16
|
57 }
|
Chris@16
|
58 } catch (...) {
|
Chris@101
|
59 ms_destroy(memory, i);
|
Chris@16
|
60 throw;
|
Chris@16
|
61 }
|
Chris@16
|
62 #else
|
Chris@16
|
63 for (std::size_t i = 0; i < size; i++) {
|
Chris@16
|
64 void* p1 = memory + i;
|
Chris@16
|
65 ::new(p1) T();
|
Chris@16
|
66 }
|
Chris@16
|
67 #endif
|
Chris@16
|
68 }
|
Chris@101
|
69
|
Chris@101
|
70 template<class T>
|
Chris@101
|
71 inline void ms_init(T* memory, std::size_t size) {
|
Chris@101
|
72 boost::has_trivial_default_constructor<T> trivial;
|
Chris@101
|
73 ms_init(memory, size, trivial);
|
Chris@16
|
74 }
|
Chris@101
|
75
|
Chris@101
|
76 template<class T, std::size_t N>
|
Chris@101
|
77 inline void ms_init(T* memory, std::size_t size, const T* list) {
|
Chris@16
|
78 #if !defined(BOOST_NO_EXCEPTIONS)
|
Chris@16
|
79 std::size_t i = 0;
|
Chris@16
|
80 try {
|
Chris@16
|
81 for (; i < size; i++) {
|
Chris@16
|
82 void* p1 = memory + i;
|
Chris@16
|
83 ::new(p1) T(list[i % N]);
|
Chris@16
|
84 }
|
Chris@16
|
85 } catch (...) {
|
Chris@101
|
86 ms_destroy(memory, i);
|
Chris@16
|
87 throw;
|
Chris@16
|
88 }
|
Chris@16
|
89 #else
|
Chris@16
|
90 for (std::size_t i = 0; i < size; i++) {
|
Chris@16
|
91 void* p1 = memory + i;
|
Chris@16
|
92 ::new(p1) T(list[i % N]);
|
Chris@16
|
93 }
|
Chris@16
|
94 #endif
|
Chris@16
|
95 }
|
Chris@101
|
96
|
Chris@101
|
97 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
Chris@101
|
98 template<class T, class A>
|
Chris@101
|
99 inline void as_destroy(const A& allocator, T* memory,
|
Chris@101
|
100 std::size_t size) {
|
Chris@101
|
101 typedef typename std::allocator_traits<A>::
|
Chris@101
|
102 template rebind_alloc<T> TA;
|
Chris@101
|
103 typedef typename std::allocator_traits<A>::
|
Chris@101
|
104 template rebind_traits<T> TT;
|
Chris@101
|
105 TA a2(allocator);
|
Chris@101
|
106 for (std::size_t i = size; i > 0;) {
|
Chris@101
|
107 TT::destroy(a2, &memory[--i]);
|
Chris@101
|
108 }
|
Chris@16
|
109 }
|
Chris@101
|
110
|
Chris@101
|
111 template<class T, class A>
|
Chris@101
|
112 inline void as_init(const A& allocator, T* memory, std::size_t size,
|
Chris@101
|
113 ms_is_trivial) {
|
Chris@101
|
114 typedef typename std::allocator_traits<A>::
|
Chris@101
|
115 template rebind_alloc<T> TA;
|
Chris@101
|
116 typedef typename std::allocator_traits<A>::
|
Chris@101
|
117 template rebind_traits<T> TT;
|
Chris@101
|
118 TA a2(allocator);
|
Chris@101
|
119 for (std::size_t i = 0; i < size; i++) {
|
Chris@101
|
120 TT::construct(a2, memory + i);
|
Chris@101
|
121 }
|
Chris@101
|
122 }
|
Chris@101
|
123
|
Chris@101
|
124 template<class T, class A>
|
Chris@101
|
125 inline void as_init(const A& allocator, T* memory, std::size_t size,
|
Chris@101
|
126 ms_no_trivial) {
|
Chris@101
|
127 typedef typename std::allocator_traits<A>::
|
Chris@101
|
128 template rebind_alloc<T> TA;
|
Chris@101
|
129 typedef typename std::allocator_traits<A>::
|
Chris@101
|
130 template rebind_traits<T> TT;
|
Chris@101
|
131 TA a2(allocator);
|
Chris@101
|
132 #if !defined(BOOST_NO_EXCEPTIONS)
|
Chris@101
|
133 std::size_t i = 0;
|
Chris@101
|
134 try {
|
Chris@101
|
135 for (; i < size; i++) {
|
Chris@101
|
136 TT::construct(a2, memory + i);
|
Chris@101
|
137 }
|
Chris@101
|
138 } catch (...) {
|
Chris@101
|
139 as_destroy(a2, memory, i);
|
Chris@101
|
140 throw;
|
Chris@101
|
141 }
|
Chris@101
|
142 #else
|
Chris@101
|
143 for (std::size_t i = 0; i < size; i++) {
|
Chris@101
|
144 TT::construct(a2, memory + i);
|
Chris@101
|
145 }
|
Chris@101
|
146 #endif
|
Chris@101
|
147 }
|
Chris@101
|
148
|
Chris@101
|
149 template<class T, class A>
|
Chris@101
|
150 inline void as_init(const A& allocator, T* memory, std::size_t size) {
|
Chris@101
|
151 boost::has_trivial_default_constructor<T> trivial;
|
Chris@101
|
152 as_init(allocator, memory, size, trivial);
|
Chris@101
|
153 }
|
Chris@101
|
154
|
Chris@101
|
155 template<class T, class A, std::size_t N>
|
Chris@101
|
156 inline void as_init(const A& allocator, T* memory, std::size_t size,
|
Chris@101
|
157 const T* list) {
|
Chris@101
|
158 typedef typename std::allocator_traits<A>::
|
Chris@101
|
159 template rebind_alloc<T> TA;
|
Chris@101
|
160 typedef typename std::allocator_traits<A>::
|
Chris@101
|
161 template rebind_traits<T> TT;
|
Chris@101
|
162 TA a2(allocator);
|
Chris@101
|
163 #if !defined(BOOST_NO_EXCEPTIONS)
|
Chris@101
|
164 std::size_t i = 0;
|
Chris@101
|
165 try {
|
Chris@101
|
166 for (; i < size; i++) {
|
Chris@101
|
167 TT::construct(a2, memory + i, list[i % N]);
|
Chris@101
|
168 }
|
Chris@101
|
169 } catch (...) {
|
Chris@101
|
170 as_destroy(a2, memory, i);
|
Chris@101
|
171 throw;
|
Chris@101
|
172 }
|
Chris@101
|
173 #else
|
Chris@101
|
174 for (std::size_t i = 0; i < size; i++) {
|
Chris@101
|
175 TT::construct(a2, memory + i, list[i % N]);
|
Chris@101
|
176 }
|
Chris@101
|
177 #endif
|
Chris@101
|
178 }
|
Chris@101
|
179 #endif
|
Chris@101
|
180
|
Chris@101
|
181 template<class T>
|
Chris@101
|
182 inline void ms_noinit(T*, std::size_t, ms_is_trivial) {
|
Chris@101
|
183 }
|
Chris@101
|
184
|
Chris@101
|
185 template<class T>
|
Chris@101
|
186 inline void ms_noinit(T* memory, std::size_t size, ms_no_trivial) {
|
Chris@16
|
187 #if !defined(BOOST_NO_EXCEPTIONS)
|
Chris@16
|
188 std::size_t i = 0;
|
Chris@16
|
189 try {
|
Chris@16
|
190 for (; i < size; i++) {
|
Chris@16
|
191 void* p1 = memory + i;
|
Chris@16
|
192 ::new(p1) T;
|
Chris@16
|
193 }
|
Chris@16
|
194 } catch (...) {
|
Chris@101
|
195 ms_destroy(memory, i);
|
Chris@16
|
196 throw;
|
Chris@16
|
197 }
|
Chris@16
|
198 #else
|
Chris@16
|
199 for (std::size_t i = 0; i < size; i++) {
|
Chris@16
|
200 void* p1 = memory + i;
|
Chris@16
|
201 ::new(p1) T;
|
Chris@16
|
202 }
|
Chris@16
|
203 #endif
|
Chris@16
|
204 }
|
Chris@101
|
205
|
Chris@101
|
206 template<class T>
|
Chris@101
|
207 inline void ms_noinit(T* memory, std::size_t size) {
|
Chris@101
|
208 boost::has_trivial_default_constructor<T> trivial;
|
Chris@101
|
209 ms_noinit(memory, size, trivial);
|
Chris@16
|
210 }
|
Chris@16
|
211 }
|
Chris@16
|
212 }
|
Chris@16
|
213
|
Chris@16
|
214 #endif
|