array_utility.hpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*
  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. */
  9. #ifndef BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP
  10. #define BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP
  11. #include <boost/config.hpp>
  12. #include <boost/type_traits/has_trivial_constructor.hpp>
  13. #include <boost/type_traits/has_trivial_destructor.hpp>
  14. namespace boost {
  15. namespace detail {
  16. template<typename T>
  17. inline void array_destroy(T*, std::size_t, boost::true_type) {
  18. }
  19. template<typename T>
  20. inline void array_destroy(T* memory, std::size_t size, boost::false_type) {
  21. for (std::size_t i = size; i > 0; ) {
  22. memory[--i].~T();
  23. }
  24. }
  25. template<typename T>
  26. inline void array_destroy(T* memory, std::size_t size) {
  27. boost::has_trivial_destructor<T> type;
  28. array_destroy(memory, size, type);
  29. }
  30. template<typename T>
  31. inline void array_init(T* memory, std::size_t size, boost::true_type) {
  32. for (std::size_t i = 0; i < size; i++) {
  33. memory[i] = T();
  34. }
  35. }
  36. template<typename T>
  37. inline void array_init(T* memory, std::size_t size, boost::false_type) {
  38. #if !defined(BOOST_NO_EXCEPTIONS)
  39. std::size_t i = 0;
  40. try {
  41. for (; i < size; i++) {
  42. void* p1 = memory + i;
  43. ::new(p1) T();
  44. }
  45. } catch (...) {
  46. array_destroy(memory, i);
  47. throw;
  48. }
  49. #else
  50. for (std::size_t i = 0; i < size; i++) {
  51. void* p1 = memory + i;
  52. ::new(p1) T();
  53. }
  54. #endif
  55. }
  56. template<typename T>
  57. inline void array_init(T* memory, std::size_t size) {
  58. boost::has_trivial_default_constructor<T> type;
  59. array_init(memory, size, type);
  60. }
  61. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  62. template<typename T>
  63. inline void array_init_value(T* memory, std::size_t size, T&& value) {
  64. #if !defined(BOOST_NO_EXCEPTIONS)
  65. std::size_t i = 0;
  66. try {
  67. for (; i < size; i++) {
  68. void* p1 = memory + i;
  69. ::new(p1) T(value);
  70. }
  71. } catch (...) {
  72. array_destroy(memory, i);
  73. throw;
  74. }
  75. #else
  76. for (std::size_t i = 0; i < size; i++) {
  77. void* p1 = memory + i;
  78. ::new(p1) T(value);
  79. }
  80. #endif
  81. }
  82. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  83. template<typename T, typename... Args>
  84. inline void array_init_args(T* memory, std::size_t size, Args&&... args) {
  85. #if !defined(BOOST_NO_EXCEPTIONS)
  86. std::size_t i = 0;
  87. try {
  88. for (; i < size; i++) {
  89. void* p1 = memory + i;
  90. ::new(p1) T(args...);
  91. }
  92. } catch (...) {
  93. array_destroy(memory, i);
  94. throw;
  95. }
  96. #else
  97. for (std::size_t i = 0; i < size; i++) {
  98. void* p1 = memory + i;
  99. ::new(p1) T(args...);
  100. }
  101. #endif
  102. }
  103. #endif
  104. #endif
  105. template<typename T>
  106. inline void array_init_list(T* memory, std::size_t size, const T* list) {
  107. #if !defined(BOOST_NO_EXCEPTIONS)
  108. std::size_t i = 0;
  109. try {
  110. for (; i < size; i++) {
  111. void* p1 = memory + i;
  112. ::new(p1) T(list[i]);
  113. }
  114. } catch (...) {
  115. array_destroy(memory, i);
  116. throw;
  117. }
  118. #else
  119. for (std::size_t i = 0; i < size; i++) {
  120. void* p1 = memory + i;
  121. ::new(p1) T(list[i]);
  122. }
  123. #endif
  124. }
  125. template<typename T, std::size_t N>
  126. inline void array_init_list(T* memory, std::size_t size, const T* list) {
  127. #if !defined(BOOST_NO_EXCEPTIONS)
  128. std::size_t i = 0;
  129. try {
  130. for (; i < size; i++) {
  131. void* p1 = memory + i;
  132. ::new(p1) T(list[i % N]);
  133. }
  134. } catch (...) {
  135. array_destroy(memory, i);
  136. throw;
  137. }
  138. #else
  139. for (std::size_t i = 0; i < size; i++) {
  140. void* p1 = memory + i;
  141. ::new(p1) T(list[i % N]);
  142. }
  143. #endif
  144. }
  145. template<typename T>
  146. inline void array_noinit(T*, std::size_t, boost::true_type) {
  147. }
  148. template<typename T>
  149. inline void array_noinit(T* memory, std::size_t size, boost::false_type) {
  150. #if !defined(BOOST_NO_EXCEPTIONS)
  151. std::size_t i = 0;
  152. try {
  153. for (; i < size; i++) {
  154. void* p1 = memory + i;
  155. ::new(p1) T;
  156. }
  157. } catch (...) {
  158. array_destroy(memory, i);
  159. throw;
  160. }
  161. #else
  162. for (std::size_t i = 0; i < size; i++) {
  163. void* p1 = memory + i;
  164. ::new(p1) T;
  165. }
  166. #endif
  167. }
  168. template<typename T>
  169. inline void array_noinit(T* memory, std::size_t size) {
  170. boost::has_trivial_default_constructor<T> type;
  171. array_noinit(memory, size, type);
  172. }
  173. }
  174. }
  175. #endif