value_init.hpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. // (C) Copyright 2002-2008, Fernando Luis Cacciola Carballal.
  2. // Copyright 2020 Peter Dimov
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // 21 Ago 2002 (Created) Fernando Cacciola
  9. // 24 Dec 2007 (Refactored and worked around various compiler bugs) Fernando Cacciola, Niels Dekker
  10. // 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola
  11. // 21 Ago 2008 (Added swap) Niels Dekker, Fernando Cacciola
  12. // 20 Feb 2009 (Fixed logical const-ness issues) Niels Dekker, Fernando Cacciola
  13. // 03 Apr 2010 (Added initialized<T>, suggested by Jeffrey Hellrung, fixing #3472) Niels Dekker
  14. // 30 May 2010 (Made memset call conditional, fixing #3869) Niels Dekker
  15. //
  16. #ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
  17. #define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
  18. // Note: The implementation of boost::value_initialized had to deal with the
  19. // fact that various compilers haven't fully implemented value-initialization.
  20. // The constructor of boost::value_initialized<T> works around these compiler
  21. // issues, by clearing the bytes of T, before constructing the T object it
  22. // contains. More details on these issues are at libs/utility/value_init.htm
  23. #include <boost/config.hpp> // For BOOST_NO_COMPLETE_VALUE_INITIALIZATION.
  24. #include <boost/core/invoke_swap.hpp>
  25. #include <cstring>
  26. #include <cstddef>
  27. #ifdef BOOST_MSVC
  28. #pragma warning(push)
  29. // It is safe to ignore the following warning from MSVC 7.1 or higher:
  30. // "warning C4351: new behavior: elements of array will be default initialized"
  31. #pragma warning(disable: 4351)
  32. // It is safe to ignore the following MSVC warning, which may pop up when T is
  33. // a const type: "warning C4512: assignment operator could not be generated".
  34. #pragma warning(disable: 4512)
  35. #endif
  36. #ifndef BOOST_UTILITY_DOCS
  37. #ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION
  38. // Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
  39. // suggests that a workaround should be applied, because of compiler issues
  40. // regarding value-initialization.
  41. #define BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
  42. #endif
  43. // Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND
  44. // switches the value-initialization workaround either on or off.
  45. #ifndef BOOST_DETAIL_VALUE_INIT_WORKAROUND
  46. #ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
  47. #define BOOST_DETAIL_VALUE_INIT_WORKAROUND 1
  48. #else
  49. #define BOOST_DETAIL_VALUE_INIT_WORKAROUND 0
  50. #endif
  51. #endif
  52. #endif // BOOST_UTILITY_DOCS
  53. namespace boost {
  54. namespace detail {
  55. struct zero_init
  56. {
  57. zero_init()
  58. {
  59. }
  60. zero_init( void * p, std::size_t n )
  61. {
  62. std::memset( p, 0, n );
  63. }
  64. };
  65. } // namespace detail
  66. template<class T>
  67. class initialized
  68. #if BOOST_DETAIL_VALUE_INIT_WORKAROUND
  69. : detail::zero_init
  70. #endif
  71. {
  72. private:
  73. T data_;
  74. public :
  75. BOOST_GPU_ENABLED
  76. initialized():
  77. #if BOOST_DETAIL_VALUE_INIT_WORKAROUND
  78. zero_init( &const_cast< char& >( reinterpret_cast<char const volatile&>( data_ ) ), sizeof( data_ ) ),
  79. #endif
  80. data_()
  81. {
  82. }
  83. BOOST_GPU_ENABLED
  84. explicit initialized(T const & arg): data_( arg )
  85. {
  86. }
  87. BOOST_GPU_ENABLED
  88. T const & data() const
  89. {
  90. return data_;
  91. }
  92. BOOST_GPU_ENABLED
  93. T& data()
  94. {
  95. return data_;
  96. }
  97. BOOST_GPU_ENABLED
  98. void swap(initialized & arg)
  99. {
  100. ::boost::core::invoke_swap( this->data(), arg.data() );
  101. }
  102. BOOST_GPU_ENABLED
  103. operator T const &() const
  104. {
  105. return data_;
  106. }
  107. BOOST_GPU_ENABLED
  108. operator T&()
  109. {
  110. return data_;
  111. }
  112. } ;
  113. template<class T>
  114. BOOST_GPU_ENABLED
  115. T const& get ( initialized<T> const& x )
  116. {
  117. return x.data() ;
  118. }
  119. template<class T>
  120. BOOST_GPU_ENABLED
  121. T& get ( initialized<T>& x )
  122. {
  123. return x.data() ;
  124. }
  125. template<class T>
  126. BOOST_GPU_ENABLED
  127. void swap ( initialized<T> & lhs, initialized<T> & rhs )
  128. {
  129. lhs.swap(rhs) ;
  130. }
  131. template<class T>
  132. class value_initialized
  133. {
  134. private :
  135. // initialized<T> does value-initialization by default.
  136. initialized<T> m_data;
  137. public :
  138. BOOST_GPU_ENABLED
  139. value_initialized()
  140. :
  141. m_data()
  142. { }
  143. BOOST_GPU_ENABLED
  144. T const & data() const
  145. {
  146. return m_data.data();
  147. }
  148. BOOST_GPU_ENABLED
  149. T& data()
  150. {
  151. return m_data.data();
  152. }
  153. BOOST_GPU_ENABLED
  154. void swap(value_initialized & arg)
  155. {
  156. m_data.swap(arg.m_data);
  157. }
  158. BOOST_GPU_ENABLED
  159. operator T const &() const
  160. {
  161. return m_data;
  162. }
  163. BOOST_GPU_ENABLED
  164. operator T&()
  165. {
  166. return m_data;
  167. }
  168. } ;
  169. template<class T>
  170. BOOST_GPU_ENABLED
  171. T const& get ( value_initialized<T> const& x )
  172. {
  173. return x.data() ;
  174. }
  175. template<class T>
  176. BOOST_GPU_ENABLED
  177. T& get ( value_initialized<T>& x )
  178. {
  179. return x.data() ;
  180. }
  181. template<class T>
  182. BOOST_GPU_ENABLED
  183. void swap ( value_initialized<T> & lhs, value_initialized<T> & rhs )
  184. {
  185. lhs.swap(rhs) ;
  186. }
  187. class initialized_value_t
  188. {
  189. public :
  190. template <class T> BOOST_GPU_ENABLED operator T() const
  191. {
  192. return initialized<T>().data();
  193. }
  194. };
  195. initialized_value_t const initialized_value = {} ;
  196. } // namespace boost
  197. #ifdef BOOST_MSVC
  198. #pragma warning(pop)
  199. #endif
  200. #endif