Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r63637 - branches/release/boost/utility
From: nielsdekker_at_[hidden]
Date: 2010-07-04 17:50:40


Author: niels_dekker
Date: 2010-07-04 17:50:38 EDT (Sun, 04 Jul 2010)
New Revision: 63637
URL: http://svn.boost.org/trac/boost/changeset/63637

Log:
Merged value_init fixes from trunk, ref #3472, #3869.
Properties modified:
   branches/release/boost/utility/value_init.hpp (contents, props changed)
Text files modified:
   branches/release/boost/utility/value_init.hpp | 147 ++++++++++++++++++++++++++++++++++-----
   1 files changed, 127 insertions(+), 20 deletions(-)

Modified: branches/release/boost/utility/value_init.hpp
==============================================================================
--- branches/release/boost/utility/value_init.hpp (original)
+++ branches/release/boost/utility/value_init.hpp 2010-07-04 17:50:38 EDT (Sun, 04 Jul 2010)
@@ -9,6 +9,8 @@
 // 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola
 // 21 Ago 2008 (Added swap) Niels Dekker, Fernando Cacciola
 // 20 Feb 2009 (Fixed logical const-ness issues) Niels Dekker, Fernando Cacciola
+// 03 Apr 2010 (Added initialized<T>, suggested by Jeffrey Hellrung, fixing #3472) Niels Dekker
+// 30 May 2010 (Made memset call conditional, fixing #3869) Niels Dekker
 //
 #ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
 #define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
@@ -20,6 +22,7 @@
 // contains. More details on these issues are at libs/utility/value_init.htm
 
 #include <boost/aligned_storage.hpp>
+#include <boost/config.hpp> // For BOOST_NO_COMPLETE_VALUE_INITIALIZATION.
 #include <boost/detail/workaround.hpp>
 #include <boost/static_assert.hpp>
 #include <boost/type_traits/cv_traits.hpp>
@@ -28,10 +31,39 @@
 #include <cstring>
 #include <new>
 
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#if _MSC_VER >= 1310
+// It is safe to ignore the following warning from MSVC 7.1 or higher:
+// "warning C4351: new behavior: elements of array will be default initialized"
+#pragma warning(disable: 4351)
+// It is safe to ignore the following MSVC warning, which may pop up when T is
+// a const type: "warning C4512: assignment operator could not be generated".
+#pragma warning(disable: 4512)
+#endif
+#endif
+
+#ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION
+ // Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
+ // suggests that a workaround should be applied, because of compiler issues
+ // regarding value-initialization.
+ #define BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
+#endif
+
+// Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND
+// switches the value-initialization workaround either on or off.
+#ifndef BOOST_DETAIL_VALUE_INIT_WORKAROUND
+ #ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
+ #define BOOST_DETAIL_VALUE_INIT_WORKAROUND 1
+ #else
+ #define BOOST_DETAIL_VALUE_INIT_WORKAROUND 0
+ #endif
+#endif
+
 namespace boost {
 
 template<class T>
-class value_initialized
+class initialized
 {
   private :
     struct wrapper
@@ -40,6 +72,18 @@
       typename
 #endif
       remove_const<T>::type data;
+
+ wrapper()
+ :
+ data()
+ {
+ }
+
+ wrapper(T const & arg)
+ :
+ data(arg)
+ {
+ }
     };
 
     mutable
@@ -55,30 +99,25 @@
 
   public :
 
- value_initialized()
+ initialized()
     {
+#if BOOST_DETAIL_VALUE_INIT_WORKAROUND
       std::memset(&x, 0, sizeof(x));
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#if _MSC_VER >= 1310
-// When using MSVC 7.1 or higher, the following placement new expression may trigger warning C4345:
-// "behavior change: an object of POD type constructed with an initializer of the form ()
-// will be default-initialized". It is safe to ignore this warning when using value_initialized.
-#pragma warning(disable: 4345)
-#endif
 #endif
       new (wrapper_address()) wrapper();
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
     }
 
- value_initialized(value_initialized const & arg)
+ initialized(initialized const & arg)
     {
       new (wrapper_address()) wrapper( static_cast<wrapper const &>(*(arg.wrapper_address())));
     }
 
- value_initialized & operator=(value_initialized const & arg)
+ explicit initialized(T const & arg)
+ {
+ new (wrapper_address()) wrapper(arg);
+ }
+
+ initialized & operator=(initialized const & arg)
     {
       // Assignment is only allowed when T is non-const.
       BOOST_STATIC_ASSERT( ! is_const<T>::value );
@@ -86,7 +125,7 @@
       return *this;
     }
 
- ~value_initialized()
+ ~initialized()
     {
       wrapper_address()->wrapper::~wrapper();
     }
@@ -101,17 +140,81 @@
       return wrapper_address()->data;
     }
 
- void swap(value_initialized & arg)
+ void swap(initialized & arg)
     {
       ::boost::swap( this->data(), arg.data() );
     }
 
- operator T const &() const { return this->data(); }
+ operator T const &() const
+ {
+ return wrapper_address()->data;
+ }
 
- operator T&() { return this->data(); }
+ operator T&()
+ {
+ return wrapper_address()->data;
+ }
 
 } ;
 
+template<class T>
+T const& get ( initialized<T> const& x )
+{
+ return x.data() ;
+}
+
+template<class T>
+T& get ( initialized<T>& x )
+{
+ return x.data() ;
+}
+
+template<class T>
+void swap ( initialized<T> & lhs, initialized<T> & rhs )
+{
+ lhs.swap(rhs) ;
+}
+
+template<class T>
+class value_initialized
+{
+ private :
+
+ // initialized<T> does value-initialization by default.
+ initialized<T> m_data;
+
+ public :
+
+ value_initialized()
+ :
+ m_data()
+ { }
+
+ T const & data() const
+ {
+ return m_data.data();
+ }
+
+ T& data()
+ {
+ return m_data.data();
+ }
+
+ void swap(value_initialized & arg)
+ {
+ m_data.swap(arg.m_data);
+ }
+
+ operator T const &() const
+ {
+ return m_data;
+ }
+
+ operator T&()
+ {
+ return m_data;
+ }
+} ;
 
 
 template<class T>
@@ -119,6 +222,7 @@
 {
   return x.data() ;
 }
+
 template<class T>
 T& get ( value_initialized<T>& x )
 {
@@ -138,7 +242,7 @@
     
     template <class T> operator T() const
     {
- return get( value_initialized<T>() );
+ return initialized<T>().data();
     }
 };
 
@@ -147,5 +251,8 @@
 
 } // namespace boost
 
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
 
 #endif


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk