mirror of
https://github.com/boostorg/utility.git
synced 2025-05-09 15:04:00 +00:00
Merged value_init doc + test from trunk, including doc and test for boost::initialized_value, that was added with changeset [46464]
[SVN r46465]
This commit is contained in:
parent
8849fbc52d
commit
8827b8ed8b
@ -28,11 +28,12 @@
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<dl class="page-index">
|
<dl class="page-index">
|
||||||
<dt><a href="#types">Types</a></dt>
|
<dt><a href="#types">Types and objects</a></dt>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#val_init"><code>value_initialized<T></code></a></li>
|
<li><a href="#val_init"><code>template class value_initialized<T></code></a></li>
|
||||||
|
<li><a href="#initialized_value"><code>initialized_value</code></a></li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
<a href="#acknowledgements">Acknowledgements</a><br>
|
<a href="#acknowledgements">Acknowledgements</a><br>
|
||||||
@ -52,6 +53,9 @@ union and class types.
|
|||||||
Moreover, <code>value_initialized</code> offers a workaround to various
|
Moreover, <code>value_initialized</code> offers a workaround to various
|
||||||
compiler issues regarding value-initialization.
|
compiler issues regarding value-initialization.
|
||||||
|
|
||||||
|
Furthermore, a <code>const</code> object, <code>initialized_value</code> is provided,
|
||||||
|
to avoid repeating the type name when retrieving the value from a
|
||||||
|
<code>value_initialized<T></code> object.
|
||||||
<br>
|
<br>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -117,6 +121,16 @@ constructed by the following declaration:
|
|||||||
<pre>
|
<pre>
|
||||||
value_initialized<T> var;
|
value_initialized<T> var;
|
||||||
</pre>
|
</pre>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The <code>const</code> object <a href="#initialized_value"><code>initialized_value</code></a>
|
||||||
|
allows value-initializing a variable as follows:
|
||||||
|
<pre>
|
||||||
|
T var = initialized_value ;
|
||||||
|
</pre>
|
||||||
|
This form of initialization is semantically equivalent to <code>T4 var4 = T4()</code>,
|
||||||
|
but robust against the aforementioned compiler issues.
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2><a name="details"></a>Details</h2>
|
<h2><a name="details"></a>Details</h2>
|
||||||
@ -235,7 +249,7 @@ offer a workaround to these issues: <code>value_initialized</code> will now clea
|
|||||||
its internal data, prior to constructing the object that it contains.
|
its internal data, prior to constructing the object that it contains.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2><a name="types"></a>Types</h2>
|
<h2><a name="types"></a>Types and objects</h2>
|
||||||
|
|
||||||
<h2><a name="val_init"><code>template class value_initialized<T></code></a></h2>
|
<h2><a name="val_init"><code>template class value_initialized<T></code></a></h2>
|
||||||
|
|
||||||
@ -298,6 +312,43 @@ the wrapped object is always performed with the <code>get()</code> idiom:</p>
|
|||||||
|
|
||||||
<pre>value_initialized<int> x ;<br>get(x) = 1 ; // OK<br><br>value_initialized<int const> cx ;<br>get(x) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized<int> const x_c ;<br>get(x_c) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized<int const> const cx_c ;<br>get(cx_c) = 1 ; // ERROR: Cannot modify a const object<br></pre>
|
<pre>value_initialized<int> x ;<br>get(x) = 1 ; // OK<br><br>value_initialized<int const> cx ;<br>get(x) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized<int> const x_c ;<br>get(x_c) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized<int const> const cx_c ;<br>get(cx_c) = 1 ; // ERROR: Cannot modify a const object<br></pre>
|
||||||
|
|
||||||
|
<h2><a name="initialized_value"><code>initialized_value</code></a></h2>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
namespace boost {
|
||||||
|
class initialized_value_t
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
template <class T> operator T() const ;
|
||||||
|
};
|
||||||
|
|
||||||
|
initialized_value_t const initialized_value = {} ;
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<code>initialized_value</code> provides a convenient way to get
|
||||||
|
an initialized value: its conversion operator provides an appropriate
|
||||||
|
<em>value-initialized</em> object for any CopyConstructible type.
|
||||||
|
|
||||||
|
Suppose you need to have an initialized variable of type <code>T</code>.
|
||||||
|
You could do it as follows:
|
||||||
|
<pre>
|
||||||
|
T var = T();
|
||||||
|
</pre>
|
||||||
|
But as mentioned before, this form suffers from various compiler issues.
|
||||||
|
The template <code>value_initialized</code> offers a workaround:
|
||||||
|
<pre>
|
||||||
|
T var = get( value_initialized<T>() );
|
||||||
|
</pre>
|
||||||
|
Unfortunately both forms repeat the type name, which
|
||||||
|
is rather short now (<code>T</code>), but could of course be
|
||||||
|
more like <code>Namespace::Template<Arg>::Type</code>.
|
||||||
|
Instead, one could use <code>initialized_value</code> as follows:
|
||||||
|
<pre>
|
||||||
|
T var = initialized_value ;
|
||||||
|
</pre>
|
||||||
|
|
||||||
<h3><a name="references">References</a></h3>
|
<h3><a name="references">References</a></h3>
|
||||||
[1] Bjarne Stroustrup, Gabriel Dos Reis, and J. Stephen Adamczyk wrote
|
[1] Bjarne Stroustrup, Gabriel Dos Reis, and J. Stephen Adamczyk wrote
|
||||||
various papers, proposing to extend the support for brace-enclosed <em>initializer lists</em>
|
various papers, proposing to extend the support for brace-enclosed <em>initializer lists</em>
|
||||||
@ -320,13 +371,15 @@ Special thanks to Björn Karlsson who carefully edited and completed this do
|
|||||||
<p>value_initialized was reimplemented by Fernando Cacciola and Niels Dekker
|
<p>value_initialized was reimplemented by Fernando Cacciola and Niels Dekker
|
||||||
for Boost release version 1.35 (2008), offering a workaround to various compiler issues.
|
for Boost release version 1.35 (2008), offering a workaround to various compiler issues.
|
||||||
</p>
|
</p>
|
||||||
|
<p>initialized_value was written by Niels Dekker, and added to Boost release version 1.36 (2008).
|
||||||
|
</p>
|
||||||
<p>Developed by <a href="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</a>,
|
<p>Developed by <a href="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</a>,
|
||||||
the latest version of this file can be found at <a
|
the latest version of this file can be found at <a
|
||||||
href="http://www.boost.org">www.boost.org</a>.
|
href="http://www.boost.org">www.boost.org</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<p>Revised 15 January 2008</p>
|
<p>Revised 23 May 2008</p>
|
||||||
|
|
||||||
<p>© Copyright Fernando Cacciola, 2002, 2008.</p>
|
<p>© Copyright Fernando Cacciola, 2002, 2008.</p>
|
||||||
|
|
||||||
@ -337,4 +390,4 @@ for Boost release version 1.35 (2008), offering a workaround to various compiler
|
|||||||
<br>
|
<br>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -6,8 +6,9 @@
|
|||||||
//
|
//
|
||||||
// Test program for "boost/utility/value_init.hpp"
|
// Test program for "boost/utility/value_init.hpp"
|
||||||
//
|
//
|
||||||
// 21 Agu 2002 (Created) Fernando Cacciola
|
// 21 Ago 2002 (Created) Fernando Cacciola
|
||||||
// 15 Jan 2008 (Added tests regarding compiler issues) Fernando Cacciola, Niels Dekker
|
// 15 Jan 2008 (Added tests regarding compiler issues) Fernando Cacciola, Niels Dekker
|
||||||
|
// 23 May 2008 (Added tests regarding initialized_value) Niels Dekker
|
||||||
|
|
||||||
#include <cstring> // For memcmp.
|
#include <cstring> // For memcmp.
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -52,7 +53,7 @@ struct NonPODBase
|
|||||||
struct NonPOD : NonPODBase
|
struct NonPOD : NonPODBase
|
||||||
{
|
{
|
||||||
NonPOD () : id() {}
|
NonPOD () : id() {}
|
||||||
NonPOD ( std::string const& id_) : id(id_) {}
|
explicit NonPOD ( std::string const& id_) : id(id_) {}
|
||||||
|
|
||||||
friend std::ostream& operator << ( std::ostream& os, NonPOD const& npod )
|
friend std::ostream& operator << ( std::ostream& os, NonPOD const& npod )
|
||||||
{ return os << '(' << npod.id << ')' ; }
|
{ return os << '(' << npod.id << ')' ; }
|
||||||
@ -180,6 +181,32 @@ struct CopyFunctionCallTester
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void check_initialized_value ( T const& y )
|
||||||
|
{
|
||||||
|
T initializedValue = boost::initialized_value ;
|
||||||
|
BOOST_CHECK ( y == initializedValue ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
#if __BORLANDC__ == 0x582
|
||||||
|
void check_initialized_value( NonPOD const& )
|
||||||
|
{
|
||||||
|
// The initialized_value check is skipped for Borland 5.82
|
||||||
|
// and this type (NonPOD), because the following statement
|
||||||
|
// won't compile on this particular compiler version:
|
||||||
|
// NonPOD initializedValue = boost::initialized_value() ;
|
||||||
|
//
|
||||||
|
// This is caused by a compiler bug, that is fixed with a newer version
|
||||||
|
// of the Borland compiler. The Release Notes for Delphi(R) 2007 for
|
||||||
|
// Win32(R) and C++Builder(R) 2007 (http://dn.codegear.com/article/36575)
|
||||||
|
// say about similar statements:
|
||||||
|
// both of these statements now compile but under 5.82 got the error:
|
||||||
|
// Error E2015: Ambiguity between 'V::V(const A &)' and 'V::V(const V &)'
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// This test function tests boost::value_initialized<T> for a specific type T.
|
// This test function tests boost::value_initialized<T> for a specific type T.
|
||||||
// The first argument (y) is assumed have the value of a value-initialized object.
|
// The first argument (y) is assumed have the value of a value-initialized object.
|
||||||
@ -189,9 +216,13 @@ template<class T>
|
|||||||
bool test ( T const& y, T const& z )
|
bool test ( T const& y, T const& z )
|
||||||
{
|
{
|
||||||
const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter();
|
const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter();
|
||||||
|
|
||||||
|
check_initialized_value(y);
|
||||||
|
|
||||||
boost::value_initialized<T> x ;
|
boost::value_initialized<T> x ;
|
||||||
BOOST_CHECK ( y == x ) ;
|
BOOST_CHECK ( y == x ) ;
|
||||||
BOOST_CHECK ( y == boost::get(x) ) ;
|
BOOST_CHECK ( y == boost::get(x) ) ;
|
||||||
|
|
||||||
static_cast<T&>(x) = z ;
|
static_cast<T&>(x) = z ;
|
||||||
boost::get(x) = z ;
|
boost::get(x) = z ;
|
||||||
BOOST_CHECK ( x == z ) ;
|
BOOST_CHECK ( x == z ) ;
|
||||||
@ -275,6 +306,10 @@ int test_main(int, char **)
|
|||||||
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes;
|
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes;
|
||||||
BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0);
|
BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0);
|
||||||
|
|
||||||
|
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes2;
|
||||||
|
valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes;
|
||||||
|
BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0);
|
||||||
|
|
||||||
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester1;
|
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester1;
|
||||||
BOOST_CHECK ( ! get(copyFunctionCallTester1).is_copy_constructed);
|
BOOST_CHECK ( ! get(copyFunctionCallTester1).is_copy_constructed);
|
||||||
BOOST_CHECK ( ! get(copyFunctionCallTester1).is_assignment_called);
|
BOOST_CHECK ( ! get(copyFunctionCallTester1).is_assignment_called);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user