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 | { |
63 | zero_init() |
64 | { |
65 | } |
66 | |
67 | zero_init( void * p, std::size_t n ) |
68 | { |
69 | std::memset( s: p, c: 0, n: 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 |
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 |
97 | explicit initialized(T const & arg): data_( arg ) |
98 | { |
99 | } |
100 | |
101 | BOOST_GPU_ENABLED |
102 | T const & data() const |
103 | { |
104 | return data_; |
105 | } |
106 | |
107 | BOOST_GPU_ENABLED |
108 | T& data() |
109 | { |
110 | return data_; |
111 | } |
112 | |
113 | BOOST_GPU_ENABLED |
114 | void swap(initialized & arg) |
115 | { |
116 | ::boost::swap( this->data(), arg.data() ); |
117 | } |
118 | |
119 | BOOST_GPU_ENABLED |
120 | operator T const &() const |
121 | { |
122 | return data_; |
123 | } |
124 | |
125 | BOOST_GPU_ENABLED |
126 | operator T&() |
127 | { |
128 | return data_; |
129 | } |
130 | |
131 | } ; |
132 | |
133 | template<class T> |
134 | BOOST_GPU_ENABLED |
135 | T const& get ( initialized<T> const& x ) |
136 | { |
137 | return x.data() ; |
138 | } |
139 | |
140 | template<class T> |
141 | BOOST_GPU_ENABLED |
142 | T& get ( initialized<T>& x ) |
143 | { |
144 | return x.data() ; |
145 | } |
146 | |
147 | template<class T> |
148 | BOOST_GPU_ENABLED |
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 |
165 | value_initialized() |
166 | : |
167 | m_data() |
168 | { } |
169 | |
170 | BOOST_GPU_ENABLED |
171 | T const & data() const |
172 | { |
173 | return m_data.data(); |
174 | } |
175 | |
176 | BOOST_GPU_ENABLED |
177 | T& data() |
178 | { |
179 | return m_data.data(); |
180 | } |
181 | |
182 | BOOST_GPU_ENABLED |
183 | void swap(value_initialized & arg) |
184 | { |
185 | m_data.swap(arg.m_data); |
186 | } |
187 | |
188 | BOOST_GPU_ENABLED |
189 | operator T const &() const |
190 | { |
191 | return m_data; |
192 | } |
193 | |
194 | BOOST_GPU_ENABLED |
195 | operator T&() |
196 | { |
197 | return m_data; |
198 | } |
199 | } ; |
200 | |
201 | |
202 | template<class T> |
203 | BOOST_GPU_ENABLED |
204 | T const& get ( value_initialized<T> const& x ) |
205 | { |
206 | return x.data() ; |
207 | } |
208 | |
209 | template<class T> |
210 | BOOST_GPU_ENABLED |
211 | T& get ( value_initialized<T>& x ) |
212 | { |
213 | return x.data() ; |
214 | } |
215 | |
216 | template<class T> |
217 | BOOST_GPU_ENABLED |
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 | |
228 | 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 | |