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