blob: 8696365c49528f717b6b65cc9ca5de39708d7186 [file] [log] [blame]
Jeff Thompsonf7d49942013-08-01 16:47:40 -07001/*
2 * Copyright (c) 2012 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 */
Jeff Thompson3d613fd2013-10-15 15:39:04 -07009#ifndef NDNBOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP
10#define NDNBOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP
Jeff Thompsonf7d49942013-08-01 16:47:40 -070011
Jeff Thompson2277ce52013-08-01 17:34:11 -070012#include <ndnboost/config.hpp>
13#include <ndnboost/type_traits/has_trivial_constructor.hpp>
14#include <ndnboost/type_traits/has_trivial_destructor.hpp>
Jeff Thompsonf7d49942013-08-01 16:47:40 -070015
16namespace ndnboost {
17 namespace detail {
18 template<typename T>
19 inline void array_destroy(T*, std::size_t, ndnboost::true_type) {
20 }
21 template<typename T>
22 inline void array_destroy(T* memory, std::size_t size, ndnboost::false_type) {
23 for (std::size_t i = size; i > 0; ) {
24 memory[--i].~T();
25 }
26 }
27 template<typename T>
28 inline void array_destroy(T* memory, std::size_t size) {
29 ndnboost::has_trivial_destructor<T> type;
30 array_destroy(memory, size, type);
31 }
32 template<typename T>
33 inline void array_init(T* memory, std::size_t size, ndnboost::true_type) {
34 for (std::size_t i = 0; i < size; i++) {
35 memory[i] = T();
36 }
37 }
38 template<typename T>
39 inline void array_init(T* memory, std::size_t size, ndnboost::false_type) {
Jeff Thompson3d613fd2013-10-15 15:39:04 -070040#if !defined(NDNBOOST_NO_EXCEPTIONS)
Jeff Thompsonf7d49942013-08-01 16:47:40 -070041 std::size_t i = 0;
42 try {
43 for (; i < size; i++) {
44 void* p1 = memory + i;
45 ::new(p1) T();
46 }
47 } catch (...) {
48 array_destroy(memory, i);
49 throw;
50 }
51#else
52 for (std::size_t i = 0; i < size; i++) {
53 void* p1 = memory + i;
54 ::new(p1) T();
55 }
56#endif
57 }
58 template<typename T>
59 inline void array_init(T* memory, std::size_t size) {
60 ndnboost::has_trivial_default_constructor<T> type;
61 array_init(memory, size, type);
62 }
Jeff Thompson3d613fd2013-10-15 15:39:04 -070063#if !defined(NDNBOOST_NO_CXX11_RVALUE_REFERENCES)
Jeff Thompsonf7d49942013-08-01 16:47:40 -070064 template<typename T>
65 inline void array_init_value(T* memory, std::size_t size, T&& value) {
Jeff Thompson3d613fd2013-10-15 15:39:04 -070066#if !defined(NDNBOOST_NO_EXCEPTIONS)
Jeff Thompsonf7d49942013-08-01 16:47:40 -070067 std::size_t i = 0;
68 try {
69 for (; i < size; i++) {
70 void* p1 = memory + i;
71 ::new(p1) T(value);
72 }
73 } catch (...) {
74 array_destroy(memory, i);
75 throw;
76 }
77#else
78 for (std::size_t i = 0; i < size; i++) {
79 void* p1 = memory + i;
80 ::new(p1) T(value);
81 }
82#endif
83 }
Jeff Thompson3d613fd2013-10-15 15:39:04 -070084#if !defined(NDNBOOST_NO_CXX11_VARIADIC_TEMPLATES)
Jeff Thompsonf7d49942013-08-01 16:47:40 -070085 template<typename T, typename... Args>
86 inline void array_init_args(T* memory, std::size_t size, Args&&... args) {
Jeff Thompson3d613fd2013-10-15 15:39:04 -070087#if !defined(NDNBOOST_NO_EXCEPTIONS)
Jeff Thompsonf7d49942013-08-01 16:47:40 -070088 std::size_t i = 0;
89 try {
90 for (; i < size; i++) {
91 void* p1 = memory + i;
92 ::new(p1) T(args...);
93 }
94 } catch (...) {
95 array_destroy(memory, i);
96 throw;
97 }
98#else
99 for (std::size_t i = 0; i < size; i++) {
100 void* p1 = memory + i;
101 ::new(p1) T(args...);
102 }
103#endif
104 }
105#endif
106#endif
107 template<typename T>
108 inline void array_init_list(T* memory, std::size_t size, const T* list) {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700109#if !defined(NDNBOOST_NO_EXCEPTIONS)
Jeff Thompsonf7d49942013-08-01 16:47:40 -0700110 std::size_t i = 0;
111 try {
112 for (; i < size; i++) {
113 void* p1 = memory + i;
114 ::new(p1) T(list[i]);
115 }
116 } catch (...) {
117 array_destroy(memory, i);
118 throw;
119 }
120#else
121 for (std::size_t i = 0; i < size; i++) {
122 void* p1 = memory + i;
123 ::new(p1) T(list[i]);
124 }
125#endif
126 }
127 template<typename T, std::size_t N>
128 inline void array_init_list(T* memory, std::size_t size, const T* list) {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700129#if !defined(NDNBOOST_NO_EXCEPTIONS)
Jeff Thompsonf7d49942013-08-01 16:47:40 -0700130 std::size_t i = 0;
131 try {
132 for (; i < size; i++) {
133 void* p1 = memory + i;
134 ::new(p1) T(list[i % N]);
135 }
136 } catch (...) {
137 array_destroy(memory, i);
138 throw;
139 }
140#else
141 for (std::size_t i = 0; i < size; i++) {
142 void* p1 = memory + i;
143 ::new(p1) T(list[i % N]);
144 }
145#endif
146 }
147 template<typename T>
148 inline void array_noinit(T*, std::size_t, ndnboost::true_type) {
149 }
150 template<typename T>
151 inline void array_noinit(T* memory, std::size_t size, ndnboost::false_type) {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700152#if !defined(NDNBOOST_NO_EXCEPTIONS)
Jeff Thompsonf7d49942013-08-01 16:47:40 -0700153 std::size_t i = 0;
154 try {
155 for (; i < size; i++) {
156 void* p1 = memory + i;
157 ::new(p1) T;
158 }
159 } catch (...) {
160 array_destroy(memory, i);
161 throw;
162 }
163#else
164 for (std::size_t i = 0; i < size; i++) {
165 void* p1 = memory + i;
166 ::new(p1) T;
167 }
168#endif
169 }
170 template<typename T>
171 inline void array_noinit(T* memory, std::size_t size) {
172 ndnboost::has_trivial_default_constructor<T> type;
173 array_noinit(memory, size, type);
174 }
175 }
176}
177
178#endif