$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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