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
57namespace boost {
58
59namespace 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
75template<class T>
76class 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
133template<class T>
134BOOST_GPU_ENABLED
135T const& get ( initialized<T> const& x )
136{
137 return x.data() ;
138}
139
140template<class T>
141BOOST_GPU_ENABLED
142T& get ( initialized<T>& x )
143{
144 return x.data() ;
145}
146
147template<class T>
148BOOST_GPU_ENABLED
149void swap ( initialized<T> & lhs, initialized<T> & rhs )
150{
151 lhs.swap(rhs) ;
152}
153
154template<class T>
155class 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
202template<class T>
203BOOST_GPU_ENABLED
204T const& get ( value_initialized<T> const& x )
205{
206 return x.data() ;
207}
208
209template<class T>
210BOOST_GPU_ENABLED
211T& get ( value_initialized<T>& x )
212{
213 return x.data() ;
214}
215
216template<class T>
217BOOST_GPU_ENABLED
218void swap ( value_initialized<T> & lhs, value_initialized<T> & rhs )
219{
220 lhs.swap(rhs) ;
221}
222
223
224class 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
234initialized_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

source code of include/boost/utility/value_init.hpp