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
19namespace 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
215

source code of boost/boost/smart_ptr/detail/array_utility.hpp