From 8827b8ed8b79a1ae9f93b1fcd745ae4b57349184 Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Tue, 17 Jun 2008 22:17:14 +0000 Subject: [PATCH] Merged value_init doc + test from trunk, including doc and test for boost::initialized_value, that was added with changeset [46464] [SVN r46465] --- value_init.htm | 63 +++++++++++++++++++++++++++++++++++++++++---- value_init_test.cpp | 39 ++++++++++++++++++++++++++-- 2 files changed, 95 insertions(+), 7 deletions(-) diff --git a/value_init.htm b/value_init.htm index 405f0b6..531814e 100644 --- a/value_init.htm +++ b/value_init.htm @@ -28,11 +28,12 @@
-
Types
+
Types and objects
Acknowledgements
@@ -52,6 +53,9 @@ union and class types. Moreover, value_initialized offers a workaround to various compiler issues regarding value-initialization. +Furthermore, a const object, initialized_value is provided, +to avoid repeating the type name when retrieving the value from a +value_initialized<T> object.

@@ -117,6 +121,16 @@ constructed by the following declaration:
   value_initialized<T> var;
 
+

+

+The const object initialized_value +allows value-initializing a variable as follows: +

+  T var = initialized_value ;
+
+This form of initialization is semantically equivalent to T4 var4 = T4(), +but robust against the aforementioned compiler issues. +

Details

@@ -235,7 +249,7 @@ offer a workaround to these issues: value_initialized will now clea its internal data, prior to constructing the object that it contains.

-

Types

+

Types and objects

template class value_initialized<T>

@@ -298,6 +312,43 @@ the wrapped object is always performed with the get() idiom:

value_initialized<int> x ;
get(x) = 1 ; // OK

value_initialized<int const> cx ;
get(x) = 1 ; // ERROR: Cannot modify a const object

value_initialized<int> const x_c ;
get(x_c) = 1 ; // ERROR: Cannot modify a const object

value_initialized<int const> const cx_c ;
get(cx_c) = 1 ; // ERROR: Cannot modify a const object
+

initialized_value

+ +
+namespace boost {
+class initialized_value_t
+{
+  public :
+    template <class T> operator T() const ;
+};
+
+initialized_value_t const initialized_value = {} ;
+
+} // namespace boost
+
+ +initialized_value provides a convenient way to get +an initialized value: its conversion operator provides an appropriate +value-initialized object for any CopyConstructible type. + +Suppose you need to have an initialized variable of type T. +You could do it as follows: +
+  T var = T();
+
+But as mentioned before, this form suffers from various compiler issues. +The template value_initialized offers a workaround: +
+  T var = get( value_initialized<T>() );
+
+Unfortunately both forms repeat the type name, which +is rather short now (T), but could of course be +more like Namespace::Template<Arg>::Type. +Instead, one could use initialized_value as follows: +
+  T var = initialized_value ;
+
+

References

[1] Bjarne Stroustrup, Gabriel Dos Reis, and J. Stephen Adamczyk wrote various papers, proposing to extend the support for brace-enclosed initializer lists @@ -320,13 +371,15 @@ Special thanks to Björn Karlsson who carefully edited and completed this do

value_initialized was reimplemented by Fernando Cacciola and Niels Dekker for Boost release version 1.35 (2008), offering a workaround to various compiler issues.

+

initialized_value was written by Niels Dekker, and added to Boost release version 1.36 (2008). +

Developed by Fernando Cacciola, the latest version of this file can be found at www.boost.org.


-

Revised 15 January 2008

+

Revised 23 May 2008

© Copyright Fernando Cacciola, 2002, 2008.

@@ -337,4 +390,4 @@ for Boost release version 1.35 (2008), offering a workaround to various compiler
- \ No newline at end of file + diff --git a/value_init_test.cpp b/value_init_test.cpp index 7b332d7..7191156 100644 --- a/value_init_test.cpp +++ b/value_init_test.cpp @@ -6,8 +6,9 @@ // // 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 +// 23 May 2008 (Added tests regarding initialized_value) Niels Dekker #include // For memcmp. #include @@ -52,7 +53,7 @@ struct NonPODBase struct NonPOD : NonPODBase { 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 ) { return os << '(' << npod.id << ')' ; } @@ -180,6 +181,32 @@ struct CopyFunctionCallTester }; +template +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 for a specific type T. // The first argument (y) is assumed have the value of a value-initialized object. @@ -189,9 +216,13 @@ template bool test ( T const& y, T const& z ) { const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter(); + + check_initialized_value(y); + boost::value_initialized x ; BOOST_CHECK ( y == x ) ; BOOST_CHECK ( y == boost::get(x) ) ; + static_cast(x) = z ; boost::get(x) = z ; BOOST_CHECK ( x == z ) ; @@ -275,6 +306,10 @@ int test_main(int, char **) boost::value_initialized valueInitializedArrayOfBytes; BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0); + boost::value_initialized valueInitializedArrayOfBytes2; + valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes; + BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0); + boost::value_initialized copyFunctionCallTester1; BOOST_CHECK ( ! get(copyFunctionCallTester1).is_copy_constructed); BOOST_CHECK ( ! get(copyFunctionCallTester1).is_assignment_called);