From 55f3c351a388a1bc2c38cb06d4e6a324faaaa66e Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Fri, 7 Sep 2007 17:17:09 +0000 Subject: [PATCH] Added MSVC workaround to value_initialized, as described by ticket #1217, proposed at the Boost Developers mailing list, and discussed with Fernando Cacciola. [SVN r39157] --- include/boost/utility/value_init.hpp | 84 ++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 4 deletions(-) diff --git a/include/boost/utility/value_init.hpp b/include/boost/utility/value_init.hpp index 65600e5..a564658 100644 --- a/include/boost/utility/value_init.hpp +++ b/include/boost/utility/value_init.hpp @@ -1,10 +1,11 @@ -// (C) 2002, Fernando Luis Cacciola Carballal. +// (C) Copyright 2002-2007, Fernando Luis Cacciola Carballal. // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // 21 Ago 2002 (Created) Fernando Cacciola +// 07 Set 2007 (Worked around MSVC++ bug) Fernando Cacciola, Niels Dekker // #ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP #define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP @@ -13,6 +14,75 @@ #include #include +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) ) +// Microsoft Visual C++ does not correctly support value initialization, as reported by +// Pavel Kuznetsov (MetaCommunications Engineering), 7/28/2005, Feedback ID 100744, +// Feedback Title: Value-initialization in new-expression +// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744 +// The report was closed at 11/14/2006, and its status was set to "Closed (Won't Fix)". +// Luckily, even in the presence of this compiler bug, boost::value_initialized will still +// do its job correctly, when using the following workaround: +#define BOOST_UTILITY_VALUE_INIT_WORKAROUND +#endif + +#ifdef BOOST_UTILITY_VALUE_INIT_WORKAROUND +#include +#include +#include +#include + +namespace boost { + +namespace vinit_detail { + +template +class const_T_base +{ + protected : + + const_T_base() + { + std::memset(&x, 0, sizeof(x)); + new (&x) T(); + } + + ~const_T_base() { get().T::~T(); } + + T & get() const + { + void const * ptr = &x; + return *static_cast(ptr); + } + + private : + typename ::boost::aligned_storage::value>::type x; +} ; + +template +class non_const_T_base +{ + protected : + + non_const_T_base() + { + std::memset(&x, 0, sizeof(x)); + new (&x) T(); + } + + ~non_const_T_base() { get().T::~T(); } + + T & get() const + { + void * ptr = &x; + return *static_cast(ptr); + } + + private : + mutable typename ::boost::aligned_storage::value>::type x; +} ; + +#else + namespace boost { namespace vinit_detail { @@ -23,20 +93,26 @@ class const_T_base protected : const_T_base() : x() {} + T & get() const { return x; } + private : T x ; } ; template -struct non_const_T_base +class non_const_T_base { protected : non_const_T_base() : x() {} + T & get() const { return x; } + private : mutable T x ; } ; +#endif + template struct select_base { @@ -57,9 +133,9 @@ class value_initialized : private vinit_detail::select_base::type value_initialized() {} - operator T&() const { return this->x ; } + operator T&() const { return this->get(); } - T& data() const { return this->x ; } + T& data() const { return this->get(); } } ;