• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
19 // Note: The implementation of boost::value_initialized had to deal with the
20 // fact that various compilers haven't fully implemented value-initialization.
21 // The constructor of boost::value_initialized<T> works around these compiler
22 // issues, by clearing the bytes of T, before constructing the T object it
23 // contains. More details on these issues are at libs/utility/value_init.htm
24 
25 #include <boost/config.hpp> // For BOOST_NO_COMPLETE_VALUE_INITIALIZATION.
26 #include <boost/swap.hpp>
27 #include <cstring>
28 #include <cstddef>
29 
30 #ifdef BOOST_MSVC
31 #pragma warning(push)
32 // It is safe to ignore the following warning from MSVC 7.1 or higher:
33 // "warning C4351: new behavior: elements of array will be default initialized"
34 #pragma warning(disable: 4351)
35 // It is safe to ignore the following MSVC warning, which may pop up when T is
36 // a const type: "warning C4512: assignment operator could not be generated".
37 #pragma warning(disable: 4512)
38 #endif
39 
40 #ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION
41   // Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
42   // suggests that a workaround should be applied, because of compiler issues
43   // regarding value-initialization.
44   #define BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
45 #endif
46 
47 // Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND
48 // switches the value-initialization workaround either on or off.
49 #ifndef BOOST_DETAIL_VALUE_INIT_WORKAROUND
50   #ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
51   #define BOOST_DETAIL_VALUE_INIT_WORKAROUND 1
52   #else
53   #define BOOST_DETAIL_VALUE_INIT_WORKAROUND 0
54   #endif
55 #endif
56 
57 namespace boost {
58 
59 namespace detail {
60 
61   struct zero_init
62   {
zero_initboost::detail::zero_init63     zero_init()
64     {
65     }
66 
zero_initboost::detail::zero_init67     zero_init( void * p, std::size_t n )
68     {
69       std::memset( p, 0, n );
70     }
71   };
72 
73 } // namespace detail
74 
75 template<class T>
76 class initialized
77 #if BOOST_DETAIL_VALUE_INIT_WORKAROUND
78   : detail::zero_init
79 #endif
80 {
81   private:
82 
83     T data_;
84 
85   public :
86 
87     BOOST_GPU_ENABLED
initialized()88     initialized():
89 #if BOOST_DETAIL_VALUE_INIT_WORKAROUND
90       zero_init( &const_cast< char& >( reinterpret_cast<char const volatile&>( data_ ) ), sizeof( data_ ) ),
91 #endif
92       data_()
93     {
94     }
95 
96     BOOST_GPU_ENABLED
initialized(T const & arg)97     explicit initialized(T const & arg): data_( arg )
98     {
99     }
100 
101     BOOST_GPU_ENABLED
data() const102     T const & data() const
103     {
104       return data_;
105     }
106 
107     BOOST_GPU_ENABLED
data()108     T& data()
109     {
110       return data_;
111     }
112 
113     BOOST_GPU_ENABLED
swap(initialized & arg)114     void swap(initialized & arg)
115     {
116       ::boost::swap( this->data(), arg.data() );
117     }
118 
119     BOOST_GPU_ENABLED
operator T const&() const120     operator T const &() const
121     {
122       return data_;
123     }
124 
125     BOOST_GPU_ENABLED
operator T&()126     operator T&()
127     {
128       return data_;
129     }
130 
131 } ;
132 
133 template<class T>
134 BOOST_GPU_ENABLED
get(initialized<T> const & x)135 T const& get ( initialized<T> const& x )
136 {
137   return x.data() ;
138 }
139 
140 template<class T>
141 BOOST_GPU_ENABLED
get(initialized<T> & x)142 T& get ( initialized<T>& x )
143 {
144   return x.data() ;
145 }
146 
147 template<class T>
148 BOOST_GPU_ENABLED
swap(initialized<T> & lhs,initialized<T> & rhs)149 void swap ( initialized<T> & lhs, initialized<T> & rhs )
150 {
151   lhs.swap(rhs) ;
152 }
153 
154 template<class T>
155 class value_initialized
156 {
157   private :
158 
159     // initialized<T> does value-initialization by default.
160     initialized<T> m_data;
161 
162   public :
163 
164     BOOST_GPU_ENABLED
value_initialized()165     value_initialized()
166     :
167     m_data()
168     { }
169 
170     BOOST_GPU_ENABLED
data() const171     T const & data() const
172     {
173       return m_data.data();
174     }
175 
176     BOOST_GPU_ENABLED
data()177     T& data()
178     {
179       return m_data.data();
180     }
181 
182     BOOST_GPU_ENABLED
swap(value_initialized & arg)183     void swap(value_initialized & arg)
184     {
185       m_data.swap(arg.m_data);
186     }
187 
188     BOOST_GPU_ENABLED
operator T const&() const189     operator T const &() const
190     {
191       return m_data;
192     }
193 
194     BOOST_GPU_ENABLED
operator T&()195     operator T&()
196     {
197       return m_data;
198     }
199 } ;
200 
201 
202 template<class T>
203 BOOST_GPU_ENABLED
get(value_initialized<T> const & x)204 T const& get ( value_initialized<T> const& x )
205 {
206   return x.data() ;
207 }
208 
209 template<class T>
210 BOOST_GPU_ENABLED
get(value_initialized<T> & x)211 T& get ( value_initialized<T>& x )
212 {
213   return x.data() ;
214 }
215 
216 template<class T>
217 BOOST_GPU_ENABLED
swap(value_initialized<T> & lhs,value_initialized<T> & rhs)218 void swap ( value_initialized<T> & lhs, value_initialized<T> & rhs )
219 {
220   lhs.swap(rhs) ;
221 }
222 
223 
224 class initialized_value_t
225 {
226   public :
227 
operator T() const228     template <class T> BOOST_GPU_ENABLED operator T() const
229     {
230       return initialized<T>().data();
231     }
232 };
233 
234 initialized_value_t const initialized_value = {} ;
235 
236 
237 } // namespace boost
238 
239 #ifdef BOOST_MSVC
240 #pragma warning(pop)
241 #endif
242 
243 #endif
244