value_init.hpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  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/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. #ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION
  37. // Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
  38. // suggests that a workaround should be applied, because of compiler issues
  39. // regarding value-initialization.
  40. #define BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
  41. #endif
  42. // Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND
  43. // switches the value-initialization workaround either on or off.
  44. #ifndef BOOST_DETAIL_VALUE_INIT_WORKAROUND
  45. #ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
  46. #define BOOST_DETAIL_VALUE_INIT_WORKAROUND 1
  47. #else
  48. #define BOOST_DETAIL_VALUE_INIT_WORKAROUND 0
  49. #endif
  50. #endif
  51. namespace boost {
  52. namespace detail {
  53. struct zero_init
  54. {
  55. zero_init()
  56. {
  57. }
  58. zero_init( void * p, std::size_t n )
  59. {
  60. std::memset( p, 0, n );
  61. }
  62. };
  63. } // namespace detail
  64. template<class T>
  65. class initialized
  66. #if BOOST_DETAIL_VALUE_INIT_WORKAROUND
  67. : detail::zero_init
  68. #endif
  69. {
  70. private:
  71. T data_;
  72. public :
  73. BOOST_GPU_ENABLED
  74. initialized():
  75. #if BOOST_DETAIL_VALUE_INIT_WORKAROUND
  76. zero_init( &const_cast< char& >( reinterpret_cast<char const volatile&>( data_ ) ), sizeof( data_ ) ),
  77. #endif
  78. data_()
  79. {
  80. }
  81. BOOST_GPU_ENABLED
  82. explicit initialized(T const & arg): data_( arg )
  83. {
  84. }
  85. BOOST_GPU_ENABLED
  86. T const & data() const
  87. {
  88. return data_;
  89. }
  90. BOOST_GPU_ENABLED
  91. T& data()
  92. {
  93. return data_;
  94. }
  95. BOOST_GPU_ENABLED
  96. void swap(initialized & arg)
  97. {
  98. ::boost::swap( this->data(), arg.data() );
  99. }
  100. BOOST_GPU_ENABLED
  101. operator T const &() const
  102. {
  103. return data_;
  104. }
  105. BOOST_GPU_ENABLED
  106. operator T&()
  107. {
  108. return data_;
  109. }
  110. } ;
  111. template<class T>
  112. BOOST_GPU_ENABLED
  113. T const& get ( initialized<T> const& x )
  114. {
  115. return x.data() ;
  116. }
  117. template<class T>
  118. BOOST_GPU_ENABLED
  119. T& get ( initialized<T>& x )
  120. {
  121. return x.data() ;
  122. }
  123. template<class T>
  124. BOOST_GPU_ENABLED
  125. void swap ( initialized<T> & lhs, initialized<T> & rhs )
  126. {
  127. lhs.swap(rhs) ;
  128. }
  129. template<class T>
  130. class value_initialized
  131. {
  132. private :
  133. // initialized<T> does value-initialization by default.
  134. initialized<T> m_data;
  135. public :
  136. BOOST_GPU_ENABLED
  137. value_initialized()
  138. :
  139. m_data()
  140. { }
  141. BOOST_GPU_ENABLED
  142. T const & data() const
  143. {
  144. return m_data.data();
  145. }
  146. BOOST_GPU_ENABLED
  147. T& data()
  148. {
  149. return m_data.data();
  150. }
  151. BOOST_GPU_ENABLED
  152. void swap(value_initialized & arg)
  153. {
  154. m_data.swap(arg.m_data);
  155. }
  156. BOOST_GPU_ENABLED
  157. operator T const &() const
  158. {
  159. return m_data;
  160. }
  161. BOOST_GPU_ENABLED
  162. operator T&()
  163. {
  164. return m_data;
  165. }
  166. } ;
  167. template<class T>
  168. BOOST_GPU_ENABLED
  169. T const& get ( value_initialized<T> const& x )
  170. {
  171. return x.data() ;
  172. }
  173. template<class T>
  174. BOOST_GPU_ENABLED
  175. T& get ( value_initialized<T>& x )
  176. {
  177. return x.data() ;
  178. }
  179. template<class T>
  180. BOOST_GPU_ENABLED
  181. void swap ( value_initialized<T> & lhs, value_initialized<T> & rhs )
  182. {
  183. lhs.swap(rhs) ;
  184. }
  185. class initialized_value_t
  186. {
  187. public :
  188. template <class T> BOOST_GPU_ENABLED operator T() const
  189. {
  190. return initialized<T>().data();
  191. }
  192. };
  193. initialized_value_t const initialized_value = {} ;
  194. } // namespace boost
  195. #ifdef BOOST_MSVC
  196. #pragma warning(pop)
  197. #endif
  198. #endif