//////////////////////////////////////////////////////////////////////// // Adapted version of http://svn.boost.org/trac/boost/log/trunk/boost/boost/utility/value_init.hpp?rev=35084 //////////////////////////////////////////////////////////////////////// // (C) Copyright 2002, 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 // 27 Ago 2007 (Worked around MSVC++ bug) Fernando Cacciola, Niels Dekker // #ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP #define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP #include #include #include #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) ) // Microsoft Visual C++ does not correctly support value initialization, as reported by // Pavel, 7/28/2005, Feedback ID 100744, 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 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 { template class const_T_base { protected : const_T_base() : x() {} T & get() const { return x; } private : T x ; } ; template 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 { typedef #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) typename #endif ::boost::detail::if_true< ::boost::is_const::value > ::template then< const_T_base, non_const_T_base >::type type ; } ; } // namespace vinit_detail template class value_initialized : private vinit_detail::select_base::type { public : value_initialized() {} operator T&() const { return this->get(); } T& data() const { return this->get(); } } ; template T const& get ( value_initialized const& x ) { return x.data() ; } template T& get ( value_initialized& x ) { return x.data() ; } } // namespace boost #endif