]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/utility/value_init.htm
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / utility / value_init.htm
1 <html>
2 <head>
3
4 <meta http-equiv="Content-Type"
5 content="text/html; charset=iso-8859-1">
6 <title>value_initialized</title>
7
8 </head>
9 <body vlink="#800080" link="#0000ff" text="#000000" bgcolor="#ffffff">
10
11 <h2><img src="../../boost.png" width="276" height="86">
12 Header &lt;<a href="../../boost/utility/value_init.hpp">boost/utility/value_init.hpp</a>&gt;
13 </h2>
14
15 <h2>Contents</h2>
16
17 <dl>
18 <dt><a href="#rationale">Rationale</a></dt>
19 <dt><a href="#intro">Introduction</a></dt>
20 <dt><a href="#details">Details</a></dt>
21 </dl>
22
23 <ul>
24 <li><a href="#valueinit">value-initialization</a></li>
25 <li><a href="#valueinitsyn">value-initialization syntax</a></li>
26 <li><a href="#compiler_issues">compiler issues</a></li>
27
28 </ul>
29
30 <dl class="page-index">
31 <dt><a href="#types">Types and objects</a></dt>
32 </dl>
33
34 <ul>
35 <li><a href="#val_init"><code>template class value_initialized&lt;T&gt;</code></a></li>
36 <li><a href="#initialized"><code>template class initialized&lt;T&gt;</code></a></li>
37 <li><a href="#initialized_value"><code>initialized_value</code></a></li>
38
39 </ul>
40 <a href="#acknowledgements">Acknowledgements</a><br>
41 <br>
42
43 <hr>
44 <h2><a name="rationale"></a>Rationale</h2>
45
46 <p>Constructing and initializing objects in a generic way is difficult in
47 C++. The problem is that there are several different rules that apply
48 for initialization. Depending on the type, the value of a newly constructed
49 object can be zero-initialized (logically 0), default-constructed (using
50 the default constructor), or indeterminate. When writing generic code,
51 this problem must be addressed. The template <code>value_initialized</code> provides
52 a solution with consistent syntax for value initialization of scalar,
53 union and class types.
54 Moreover, <code>value_initialized</code> offers a workaround to various
55 compiler issues regarding value-initialization.
56
57 Furthermore, a <code>const</code> object, <code>initialized_value</code> is provided,
58 to avoid repeating the type name when retrieving the value from a
59 <code>value_initialized&lt;T&gt;</code> object.
60 <br>
61 </p>
62
63 <h2><a name="intro"></a>Introduction</h2>
64
65 <p>
66 There are various ways to initialize a variable, in C++. The following
67 declarations all <em>may</em> have a local variable initialized to its default
68 value:
69 <pre>
70 T1 var1;
71 T2 var2 = 0;
72 T3 var3 = {};
73 T4 var4 = T4();
74 </pre>
75 Unfortunately, whether or not any of those declarations correctly
76 initialize the variable very much depends on its type. The first
77 declaration is valid for any <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
78 DefaultConstructible</a> type (by definition).
79 However, it does not always do an initialization!
80 It correctly initializes the variable when it's an instance of a
81 class, and the author of the class has provided a proper default
82 constructor. On the other hand, the value of <code>var1</code> is <em>indeterminate</em> when
83 its type is an arithmetic type, like <code>int</code>, <code>float</code>, or <code>char</code>.
84 An arithmetic variable
85 is of course initialized properly by the second declaration, <code>T2
86 var2 = 0</code>. But this initialization form usually won't work for a
87 class type (unless the class was especially written to support being
88 initialized that way). The third form, <code>T3 var3 = {}</code>
89 initializes an aggregate, typically a "C-style" <code>struct</code> or a "C-style" array.
90 However, the syntax is not allowed for a class that has an explicitly declared
91 constructor. (But watch out for an upcoming C++ language change,
92 by Bjarne Stroustrup et al [<a href="#references">1</a>]!)
93 The fourth form is the most generic form of them, as it
94 can be used to initialize arithmetic types, class types, aggregates, pointers, and
95 other types. The declaration, <code>T4 var4 = T4()</code>, should be read
96 as follows: First a temporary object is created, by <code>T4()</code>.
97 This object is <a href="#valueinit">value-initialized</a>. Next the temporary
98 object is copied to the named variable, <code>var4</code>. Afterwards, the temporary
99 is destroyed. While the copying and the destruction are likely to
100 be optimized away, C++ still requires the type <code>T4</code> to be
101 <a href="CopyConstructible.html">CopyConstructible</a>.
102 (So <code>T4</code> needs to be <em>both</em> DefaultConstructible <em>and</em> CopyConstructible.)
103 A class may not be CopyConstructible, for example because it may have a
104 private and undefined copy constructor,
105 or because it may be derived from <a href="utility.htm#Class_noncopyable">boost::noncopyable</a>.
106 Scott Meyers [<a href="#references">2</a>] explains why a class would be defined like that.
107 </p>
108 <p>
109 There is another, less obvious disadvantage to the fourth form, <code>T4 var4 = T4()</code>:
110 It suffers from various <a href="#compiler_issues">compiler issues</a>, causing
111 a variable to be left uninitialized in some compiler specific cases.
112 </p>
113 <p>
114 The template <a href="#val_init"><code>value_initialized</code></a>
115 offers a generic way to initialize
116 an object, like <code>T4 var4 = T4()</code>, but without requiring its type
117 to be CopyConstructible. And it offers a workaround to those compiler issues
118 regarding value-initialization as well! It allows getting an initialized
119 variable of any type; it <em>only</em> requires the type to be DefaultConstructible.
120 A properly <em>value-initialized</em> object of type <code>T</code> is
121 constructed by the following declaration:
122 <pre>
123 value_initialized&lt;T&gt; var;
124 </pre>
125 </p>
126 <p>
127 The template <a href="#initialized"><code>initialized</code></a>
128 offers both value-initialization and direct-initialization.
129 It is especially useful as a data member type, allowing the very same object
130 to be either direct-initialized or value-initialized.
131 </p>
132 <p>
133 The <code>const</code> object <a href="#initialized_value"><code>initialized_value</code></a>
134 allows value-initializing a variable as follows:
135 <pre>
136 T var = initialized_value ;
137 </pre>
138 This form of initialization is semantically equivalent to <code>T4 var4 = T4()</code>,
139 but robust against the aforementioned compiler issues.
140
141 </p>
142
143 <h2><a name="details"></a>Details</h2>
144 <p>The C++ standard [<a href="#references">3</a>] contains the definitions
145 of <code>zero-initialization</code> and <code>default-initialization</code>.
146 Informally, zero-initialization means that the object is given the initial
147 value 0 (converted to the type) and default-initialization means that
148 POD [<a href="#references">4</a>] types are zero-initialized, while non-POD class
149 types are initialized with their corresponding default constructors. A
150 <i>declaration</i> can contain an <i>initializer</i>, which specifies the
151 object's initial value. The initializer can be just '()', which states that
152 the object shall be value-initialized (but see below). However, if a <i>declaration</i>
153 has no <i>initializer</i> and it is of a non-<code>const</code>, non-<code>static</code>
154 POD type, the initial value is indeterminate: <cite>(see &sect;8.5, [dcl.init], for the
155 accurate definitions).</cite></p>
156
157 <pre>int x ; // no initializer. x value is indeterminate.<br>std::string s ; // no initializer, s is default-constructed.<br><br>int y = int() ; <br>// y is initialized using copy-initialization<br>// but the temporary uses an empty set of parentheses as the initializer,<br>// so it is default-constructed.<br>// A default constructed POD type is zero-initialized,<br>// therefore, y == 0.<br><br>void foo ( std::string ) ;<br>foo ( std::string() ) ; <br>// the temporary string is default constructed <br>// as indicated by the initializer () </pre>
158
159 <h3><a name="valueinit">value-initialization</a></h3>
160
161 <p>The first <a
162 href="http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html">Technical
163 Corrigendum for the C++ Standard</a> (TC1), whose draft was released to
164 the public in November 2001, introduced <a
165 href="http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#178">Core
166 Issue 178</a> (among many other issues, of course).</p>
167
168 <p> That issue introduced the new concept of <code>value-initialization</code>
169 (it also fixed the wording for zero-initialization). Informally, value-initialization
170 is similar to default-initialization with the exception that in some cases
171 non-static data members and base class sub-objects are also value-initialized.
172 The difference is that an object that is value-initialized won't have
173 (or at least is less likely to have) indeterminate values for data members
174 and base class sub-objects; unlike the case of an object default constructed.
175 (see Core Issue 178 for a normative description).</p>
176
177 <p>In order to specify value-initialization of an object we need to use the
178 empty-set initializer: (). </p>
179
180 <p>As before, a declaration with no intializer specifies default-initialization,
181 and a declaration with a non-empty initializer specifies copy (=xxx) or
182 direct (xxx) initialization. </p>
183
184 <pre>template&lt;class T&gt; void eat(T);<br>int x ; // indeterminate initial value.<br>std::string s; // default-initialized.<br>eat ( int() ) ; // value-initialized<br>eat ( std::string() ) ; // value-initialized</pre>
185
186 <h4><a name="valueinitsyn">value-initialization</a> syntax</h4>
187
188 <p>Value initialization is specified using (). However, the empty set of
189 parentheses is not permitted by the syntax of initializers because it is
190 parsed as the declaration of a function taking no arguments: </p>
191
192 <pre>int x() ; // declares function int(*)()</pre>
193
194 <p>Thus, the empty () must be put in some other initialization context.</p>
195
196 <p>One alternative is to use copy-initialization syntax:</p>
197
198 <pre>int x = int() ;</pre>
199
200 <p>This works perfectly fine for POD types. But for non-POD class types,
201 copy-initialization searches for a suitable constructor, which could be,
202 for instance, the copy-constructor (it also searches for a suitable conversion
203 sequence but this doesn't apply in this context). For an arbitrary unknown
204 type, using this syntax may not have the value-initialization effect intended
205 because we don't know if a copy from a default constructed object is exactly
206 the same as a default constructed object, and the compiler is allowed (in
207 some cases), but never required to, optimize the copy away.</p>
208
209 <p>One possible generic solution is to use value-initialization of a non static
210 data member:</p>
211
212 <pre>template&lt;class T&gt; <br>struct W <br>{<br> // value-initialization of 'data' here.<br> W() : data() {}<br> T data ;<br>} ;<br>W&lt;int&gt; w ;<br>// w.data is value-initialized for any type. </pre>
213
214 <p>This is the solution as it was supplied by earlier versions of the
215 <code>value_initialized&lt;T&gt;</code> template
216 class. Unfortunately this approach suffered from various compiler issues.</p>
217
218 <h4><a name="compiler_issues">compiler issues</a> </h4>
219
220 Various compilers haven't yet fully implemented value-initialization.
221 So when an object should be <em>value-initialized</em> (according to the C++ Standard),
222 it <em>may</em> in practice still be left uninitialized, because of those
223 compiler issues! It's hard to make a general statement on what those issues
224 are like, because they depend on the compiler you are using, its version number,
225 and the type of object you would like to have value-initialized.
226 All compilers we have tested so far support value-initialization for arithmetic types properly.
227 However, various compilers may leave some types of <em>aggregates</em> uninitialized, when they
228 should be value-initialized. Value-initialization of objects of a pointer-to-member type may also
229 go wrong on various compilers.
230 </p>
231 <p>
232 At the moment of writing, May 2010, the following reported issues regarding
233 value-initialization are still there in current compiler releases:
234 <ul>
235 <li>
236 <a href="https://connect.microsoft.com/VisualStudio/feedback/details/100744">
237 Microsoft Visual Studio Feedback ID 100744, Value-initialization in new-expression</a>
238 <br>Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005
239 </li><li>
240 <a href="http://connect.microsoft.com/VisualStudio/feedback/details/484295">
241 Microsoft Visual Studio Feedback ID 484295, VC++ does not value-initialize members of derived classes without user-declared constructor</a>
242 <br>Reported by Sylvester Hesp, 2009
243 </li><li>
244 <a href="https://connect.microsoft.com/VisualStudio/feedback/details/499606">
245 Microsoft Visual Studio Feedback ID 499606, Presence of copy constructor breaks member class initialization</a>
246 <br>Reported by Alex Vakulenko, 2009
247 </li><li>
248 <a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=83751">
249 Embarcadero/C++Builder Report 83751, Value-initialization: arrays should have each element value-initialized</a>
250 <br>Reported by Niels Dekker (LKEB), 2010
251 </li><li>
252 <a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=83851">
253 Embarcadero/C++Builder Report 83851, Value-initialized temporary triggers internal backend error C1798</a>
254 <br>Reported by Niels Dekker, 2010
255 </li><li>
256 <a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=84279">
257 Embarcadero/C++Builder Report 84279, Internal compiler error (F1004), value-initializing member function pointer by "new T()"</a>
258 <br>Reported by Niels Dekker, 2010
259 </li><li>
260 Sun CR 6947016, Sun 5.10 may fail to value-initialize an object of a non-POD aggregate.
261 <br>Reported to Steve Clamage by Niels Dekker, 2010
262 </li><li>
263 IBM's XL V10.1 and V11.1 may fail to value-initialize a temporary of a non-POD aggregate.
264 <br>Reported to Michael Wong by Niels Dekker, 2010
265 </li><li>
266 Intel support issue 589832, Attempt to value-initialize pointer-to-member triggers internal error
267 on Intel 11.1.
268 <br>Reported by John Maddock, 2010
269 </li>
270 </ul>
271 Note that all known GCC issues regarding value-initialization are
272 fixed with GCC version 4.4, including
273 <a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111">GCC Bug 30111</a>.
274 Clang also has completely implemented value-initialization, as far as we know,
275 now that <a href="http://llvm.org/bugs/show_bug.cgi?id=7139">Clang Bug 7139</a> is fixed.
276 </p><p>
277
278 New versions of <code>value_initialized</code>
279 (Boost release version 1.35 or higher)
280 offer a workaround to these issues: <code>value_initialized</code> may now clear
281 its internal data, prior to constructing the object that it contains. It will do
282 so for those compilers that need to have such a workaround, based on the
283 <a href="../config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_defects"
284 >compiler defect macro</a> BOOST_NO_COMPLETE_VALUE_INITIALIZATION.
285 </p>
286
287 <h2><a name="types"></a>Types and objects</h2>
288
289 <h2><a name="val_init"><code>template class value_initialized&lt;T&gt;</code></a></h2>
290
291 <pre>namespace boost {<br><br>template&lt;class T&gt;<br>class value_initialized<br>{
292 <br> public :
293 <br> value_initialized() : x() {}
294 <br> operator T const &amp;() const { return x ; }
295 <br> operator T&amp;() { return x ; }
296 <br> T const &amp;data() const { return x ; }
297 <br> T&amp; data() { return x ; }
298 <br> void swap( value_initialized&amp; );
299 <br>
300 <br> private :
301 <br> <i>unspecified</i> x ;
302 <br>} ;
303 <br>
304 <br>template&lt;class T&gt;
305 <br>T const&amp; get ( value_initialized&lt;T&gt; const&amp; x )
306 <br>{
307 <br> return x.data() ;
308 <br>}
309 <br>
310 <br>template&lt;class T&gt;
311 <br>T&amp; get ( value_initialized&lt;T&gt;&amp; x )
312 <br>{
313 <br> return x.data() ;
314 <br>}
315 <br>
316 <br>template&lt;class T&gt;
317 <br>void swap ( value_initialized&lt;T&gt;&amp; lhs, value_initialized&lt;T&gt;&amp; rhs )
318 <br>{
319 <br> lhs.swap(rhs) ;
320 <br>}
321 <br>
322 <br>} // namespace boost
323 <br></pre>
324
325 <p>An object of this template class is a <code>T</code>-wrapper convertible
326 to <code>'T&amp;'</code> whose wrapped object (data member of type <code>T</code>)
327 is <a href="#valueinit">value-initialized</a> upon default-initialization
328 of this wrapper class: </p>
329
330 <pre>int zero = 0 ;<br>value_initialized&lt;int&gt; x ;<br>assert ( x == zero ) ;<br><br>std::string def ;<br>value_initialized&lt; std::string &gt; y ;<br>assert ( y == def ) ;<br></pre>
331
332 <p>The purpose of this wrapper is to provide a consistent syntax for value
333 initialization of scalar, union and class types (POD and non-POD) since
334 the correct syntax for value initialization varies (see <a
335 href="#valueinitsyn">value-initialization syntax</a>)</p>
336
337 <p>The wrapped object can be accessed either through the conversion operator
338 <code>T&amp;</code>, the member function <code>data()</code>, or the
339 non-member function <code>get()</code>: </p>
340
341 <pre>void watch(int);<br>value_initialized&lt;int&gt; x;
342 <br><br>watch(x) ; // operator T&amp; used.<br>watch(x.data());<br>watch( get(x) ) // function get() used</pre>
343
344 <p>Both <code>const</code> and non-<code>const</code> objects can be wrapped.
345 Mutable objects can be modified directly from within the wrapper but constant
346 objects cannot:</p>
347
348 <p>When <code>T</code> is a <em>Swappable</em> type, <code>value_initialized&lt;T&gt;</code>
349 is swappable as well, by calling its <code>swap</code> member function
350 as well as by calling <code>boost::swap</code>.</p>
351
352 <pre>value_initialized&lt;int&gt; x ; <br>static_cast&lt;int&amp;&gt;(x) = 1 ; // OK<br>get(x) = 1 ; // OK
353 <br><br>value_initialized&lt;int const&gt; y ; <br>static_cast&lt;int&amp;&gt;(y) = 1 ; // ERROR: cannot cast to int&amp;<br>static_cast&lt;int const&amp;&gt;(y) = 1 ; // ERROR: cannot modify a const value<br>get(y) = 1 ; // ERROR: cannot modify a const value</pre>
354
355 <h3>Warning:</h3>
356
357 <p>The <code>value_initialized</code> implementation of Boost version 1.40.0 and older
358 allowed <i>non-const</i> access to the wrapped object, from a constant wrapper,
359 both by its conversion operator and its <code>data()</code> member function. For example:</p>
360
361 <pre>value_initialized&lt;int&gt; const x_c ;<br>int&amp; xr = x_c ; // OK, conversion to int&amp; available even though x_c is itself const.
362 <br>xr = 2 ; </pre>
363
364 <p>The reason for this obscure behavior was that some compilers
365 didn't accept the following valid code:</p>
366
367 <pre>struct X<br>{<br> operator int&amp;() ;<br> operator int const&amp;() const ; <br>};<br>X x ;<br>(x == 1 ) ; // ERROR HERE!</pre>
368
369 <p>The current version of <code>value_initialized</code> no longer has this obscure behavior.
370 As compilers nowadays widely support overloading the conversion operator by having a <code>const</code> and a <code>non-const</code> version, we have decided to fix the issue accordingly. So the current version supports the idea of logical constness.
371 <br>
372 </p>
373
374 <h3>Recommended practice: The non-member get() idiom</h3>
375
376 <p>The obscure behavior of being able to modify a non-<code>const</code>
377 wrapped object from within a constant wrapper (as was supported by previous
378 versions of <code>value_initialized</code>)
379 can be avoided if access to
380 the wrapped object is always performed with the <code>get()</code> idiom:</p>
381
382 <pre>value_initialized&lt;int&gt; x ;<br>get(x) = 1 ; // OK<br><br>value_initialized&lt;int const&gt; cx ;<br>get(x) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized&lt;int&gt; const x_c ;<br>get(x_c) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized&lt;int const&gt; const cx_c ;<br>get(cx_c) = 1 ; // ERROR: Cannot modify a const object<br></pre>
383
384 <h2><a name="initialized"><code>template class initialized&lt;T&gt;</code></a></h2>
385
386 <pre>namespace boost {<br><br>template&lt;class T&gt;<br>class initialized<br>{
387 <br> public :
388 <br> initialized() : x() {}
389 <br> explicit initialized(T const &amp; arg) : x(arg) {}
390 <br> operator T const &amp;() const;
391 <br> operator T&amp;();
392 <br> T const &amp;data() const;
393 <br> T&amp; data();
394 <br> void swap( initialized&amp; );
395 <br>
396 <br> private :
397 <br> <i>unspecified</i> x ;
398 <br>} ;
399 <br>
400 <br>template&lt;class T&gt;
401 <br>T const&amp; get ( initialized&lt;T&gt; const&amp; x );
402 <br>
403 <br>template&lt;class T&gt;
404 <br>T&amp; get ( initialized&lt;T&gt;&amp; x );
405 <br>
406 <br>template&lt;class T&gt;
407 <br>void swap ( initialized&lt;T&gt;&amp; lhs, initialized&lt;T&gt;&amp; rhs );
408 <br>
409 <br>} // namespace boost
410 <br></pre>
411
412 The template class <code>boost::initialized&lt;T&gt;</code> supports both value-initialization
413 and direct-initialization, so its interface is a superset of the interface
414 of <code>value_initialized&lt;T&gt;</code>: Its default-constructor
415 value-initializes the wrapped object just like the default-constructor of
416 <code>value_initialized&lt;T&gt;</code>, but <code>boost::initialized&lt;T&gt;</code>
417 also offers an extra <code>explicit</code>
418 constructor, which direct-initializes the wrapped object by the specified value.
419 <p>
420
421 <code>initialized&lt;T&gt;</code> is especially useful when the wrapped
422 object must be either value-initialized or direct-initialized, depending on
423 runtime conditions. For example, <code>initialized&lt;T&gt;</code> could
424 hold the value of a data member that may be value-initialized by some
425 constructors, and direct-initialized by others.
426 On the other hand, if it is known beforehand that the
427 object must <i>always</i> be value-initialized, <code>value_initialized&lt;T&gt;</code>
428 may be preferable. And if the object must always be
429 direct-initialized, none of the two wrappers really needs to be used.
430 </p>
431
432
433 <h2><a name="initialized_value"><code>initialized_value</code></a></h2>
434
435 <pre>
436 namespace boost {
437 class initialized_value_t
438 {
439 public :
440 template &lt;class T&gt; operator T() const ;
441 };
442
443 initialized_value_t const initialized_value = {} ;
444
445 } // namespace boost
446 </pre>
447
448 <code>initialized_value</code> provides a convenient way to get
449 an initialized value: its conversion operator provides an appropriate
450 <em>value-initialized</em> object for any CopyConstructible type.
451
452 Suppose you need to have an initialized variable of type <code>T</code>.
453 You could do it as follows:
454 <pre>
455 T var = T();
456 </pre>
457 But as mentioned before, this form suffers from various compiler issues.
458 The template <code>value_initialized</code> offers a workaround:
459 <pre>
460 T var = get( value_initialized&lt;T&gt;() );
461 </pre>
462 Unfortunately both forms repeat the type name, which
463 is rather short now (<code>T</code>), but could of course be
464 more like <code>Namespace::Template&lt;Arg&gt;::Type</code>.
465 Instead, one could use <code>initialized_value</code> as follows:
466 <pre>
467 T var = initialized_value ;
468 </pre>
469
470 <h3><a name="references">References</a></h3>
471 [1] Bjarne Stroustrup, Gabriel Dos Reis, and J. Stephen Adamczyk wrote
472 various papers, proposing to extend the support for brace-enclosed <em>initializer lists</em>
473 in the next version of C++.
474 This would allow a variable <code>var</code> of any DefaultConstructible type
475 <code>T</code> to be <em>value-initialized</em> by doing <code>T var = {}</code>.
476 The papers are listed at Bjarne's web page,
477 <a href="http://www.research.att.com/~bs/WG21.html">My C++ Standards committee papers</a> <br>
478 [2] Scott Meyers, Effective C++, Third Edition, item 6,
479 <em>Explicitly disallow the use of compiler-generated functions you do not want</em>,
480 <a href="http://www.aristeia.com/books.html">Scott Meyers: Books and CDs</a> <br>
481 [3] The C++ Standard, Second edition (2003), ISO/IEC 14882:2003 <br>
482 [4] POD stands for "Plain Old Data"
483
484 <h3><a name="acknowledgements"></a>Acknowledgements</h3>
485 value_initialized was developed by Fernando Cacciola, with help and
486 suggestions from David Abrahams and Darin Adler.<br>
487 Special thanks to Bj&ouml;rn Karlsson who carefully edited and completed this documentation.
488
489 <p>value_initialized was reimplemented by Fernando Cacciola and Niels Dekker
490 for Boost release version 1.35 (2008), offering a workaround to various compiler issues.
491 </p>
492 <p><code>boost::initialized</code> was very much inspired by feedback from Edward Diener and
493 Jeffrey Hellrung.
494 </p>
495 <p>initialized_value was written by Niels Dekker, and added to Boost release version 1.36 (2008).
496 </p>
497 <p>Developed by <a href="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</a>,
498 the latest version of this file can be found at <a
499 href="http://www.boost.org">www.boost.org</a>.
500 </p>
501
502 <hr>
503 <p>Revised 30 May 2010</p>
504
505 <p>&copy; Copyright Fernando Cacciola, 2002 - 2010.</p>
506
507 <p>Distributed under the Boost Software License, Version 1.0. See
508 <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
509
510 <br>
511 <br>
512
513 </body>
514 </html>