Chris@16: // (C) Copyright 2002-2008, Fernando Luis Cacciola Carballal. Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // 21 Ago 2002 (Created) Fernando Cacciola Chris@16: // 24 Dec 2007 (Refactored and worked around various compiler bugs) Fernando Cacciola, Niels Dekker Chris@16: // 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola Chris@16: // 21 Ago 2008 (Added swap) Niels Dekker, Fernando Cacciola Chris@16: // 20 Feb 2009 (Fixed logical const-ness issues) Niels Dekker, Fernando Cacciola Chris@16: // 03 Apr 2010 (Added initialized, suggested by Jeffrey Hellrung, fixing #3472) Niels Dekker Chris@16: // 30 May 2010 (Made memset call conditional, fixing #3869) Niels Dekker Chris@16: // Chris@16: #ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP Chris@16: #define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP Chris@16: Chris@16: // Note: The implementation of boost::value_initialized had to deal with the Chris@16: // fact that various compilers haven't fully implemented value-initialization. Chris@16: // The constructor of boost::value_initialized works around these compiler Chris@16: // issues, by clearing the bytes of T, before constructing the T object it Chris@16: // contains. More details on these issues are at libs/utility/value_init.htm Chris@16: Chris@16: #include Chris@16: #include // For BOOST_NO_COMPLETE_VALUE_INITIALIZATION. Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #ifdef BOOST_MSVC Chris@16: #pragma warning(push) Chris@16: // It is safe to ignore the following warning from MSVC 7.1 or higher: Chris@16: // "warning C4351: new behavior: elements of array will be default initialized" Chris@16: #pragma warning(disable: 4351) Chris@16: // It is safe to ignore the following MSVC warning, which may pop up when T is Chris@16: // a const type: "warning C4512: assignment operator could not be generated". Chris@16: #pragma warning(disable: 4512) Chris@16: #endif Chris@16: Chris@16: #ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION Chris@16: // Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED Chris@16: // suggests that a workaround should be applied, because of compiler issues Chris@16: // regarding value-initialization. Chris@16: #define BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED Chris@16: #endif Chris@16: Chris@16: // Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND Chris@16: // switches the value-initialization workaround either on or off. Chris@16: #ifndef BOOST_DETAIL_VALUE_INIT_WORKAROUND Chris@16: #ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED Chris@16: #define BOOST_DETAIL_VALUE_INIT_WORKAROUND 1 Chris@16: #else Chris@16: #define BOOST_DETAIL_VALUE_INIT_WORKAROUND 0 Chris@16: #endif Chris@16: #endif Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: template Chris@16: class initialized Chris@16: { Chris@16: private : Chris@16: struct wrapper Chris@16: { Chris@16: #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) Chris@16: typename Chris@16: #endif Chris@16: remove_const::type data; Chris@16: Chris@101: BOOST_GPU_ENABLED Chris@16: wrapper() Chris@16: : Chris@16: data() Chris@16: { Chris@16: } Chris@16: Chris@101: BOOST_GPU_ENABLED Chris@16: wrapper(T const & arg) Chris@16: : Chris@16: data(arg) Chris@16: { Chris@16: } Chris@16: }; Chris@16: Chris@16: mutable Chris@16: #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) Chris@16: typename Chris@16: #endif Chris@16: aligned_storage::value>::type x; Chris@16: Chris@101: BOOST_GPU_ENABLED Chris@16: wrapper * wrapper_address() const Chris@16: { Chris@16: return static_cast( static_cast(&x)); Chris@16: } Chris@16: Chris@16: public : Chris@16: Chris@101: BOOST_GPU_ENABLED Chris@16: initialized() Chris@16: { Chris@16: #if BOOST_DETAIL_VALUE_INIT_WORKAROUND Chris@16: std::memset(&x, 0, sizeof(x)); Chris@16: #endif Chris@16: new (wrapper_address()) wrapper(); Chris@16: } Chris@16: Chris@101: BOOST_GPU_ENABLED Chris@16: initialized(initialized const & arg) Chris@16: { Chris@16: new (wrapper_address()) wrapper( static_cast(*(arg.wrapper_address()))); Chris@16: } Chris@16: Chris@101: BOOST_GPU_ENABLED Chris@16: explicit initialized(T const & arg) Chris@16: { Chris@16: new (wrapper_address()) wrapper(arg); Chris@16: } Chris@16: Chris@101: BOOST_GPU_ENABLED Chris@16: initialized & operator=(initialized const & arg) Chris@16: { Chris@16: // Assignment is only allowed when T is non-const. Chris@16: BOOST_STATIC_ASSERT( ! is_const::value ); Chris@16: *wrapper_address() = static_cast(*(arg.wrapper_address())); Chris@16: return *this; Chris@16: } Chris@16: Chris@101: BOOST_GPU_ENABLED Chris@16: ~initialized() Chris@16: { Chris@16: wrapper_address()->wrapper::~wrapper(); Chris@16: } Chris@16: Chris@101: BOOST_GPU_ENABLED Chris@16: T const & data() const Chris@16: { Chris@16: return wrapper_address()->data; Chris@16: } Chris@16: Chris@101: BOOST_GPU_ENABLED Chris@16: T& data() Chris@16: { Chris@16: return wrapper_address()->data; Chris@16: } Chris@16: Chris@101: BOOST_GPU_ENABLED Chris@16: void swap(initialized & arg) Chris@16: { Chris@16: ::boost::swap( this->data(), arg.data() ); Chris@16: } Chris@16: Chris@101: BOOST_GPU_ENABLED Chris@16: operator T const &() const Chris@16: { Chris@16: return wrapper_address()->data; Chris@16: } Chris@16: Chris@101: BOOST_GPU_ENABLED Chris@16: operator T&() Chris@16: { Chris@16: return wrapper_address()->data; Chris@16: } Chris@16: Chris@16: } ; Chris@16: Chris@16: template Chris@101: BOOST_GPU_ENABLED Chris@16: T const& get ( initialized const& x ) Chris@16: { Chris@16: return x.data() ; Chris@16: } Chris@16: Chris@16: template Chris@101: BOOST_GPU_ENABLED Chris@16: T& get ( initialized& x ) Chris@16: { Chris@16: return x.data() ; Chris@16: } Chris@16: Chris@16: template Chris@101: BOOST_GPU_ENABLED Chris@16: void swap ( initialized & lhs, initialized & rhs ) Chris@16: { Chris@16: lhs.swap(rhs) ; Chris@16: } Chris@16: Chris@16: template Chris@16: class value_initialized Chris@16: { Chris@16: private : Chris@16: Chris@16: // initialized does value-initialization by default. Chris@16: initialized m_data; Chris@16: Chris@16: public : Chris@16: Chris@101: BOOST_GPU_ENABLED Chris@16: value_initialized() Chris@16: : Chris@16: m_data() Chris@16: { } Chris@16: Chris@101: BOOST_GPU_ENABLED Chris@16: T const & data() const Chris@16: { Chris@16: return m_data.data(); Chris@16: } Chris@16: Chris@101: BOOST_GPU_ENABLED Chris@16: T& data() Chris@16: { Chris@16: return m_data.data(); Chris@16: } Chris@16: Chris@101: BOOST_GPU_ENABLED Chris@16: void swap(value_initialized & arg) Chris@16: { Chris@16: m_data.swap(arg.m_data); Chris@16: } Chris@16: Chris@101: BOOST_GPU_ENABLED Chris@16: operator T const &() const Chris@16: { Chris@16: return m_data; Chris@16: } Chris@16: Chris@101: BOOST_GPU_ENABLED Chris@16: operator T&() Chris@16: { Chris@16: return m_data; Chris@16: } Chris@16: } ; Chris@16: Chris@16: Chris@16: template Chris@101: BOOST_GPU_ENABLED Chris@16: T const& get ( value_initialized const& x ) Chris@16: { Chris@16: return x.data() ; Chris@16: } Chris@16: Chris@16: template Chris@101: BOOST_GPU_ENABLED Chris@16: T& get ( value_initialized& x ) Chris@16: { Chris@16: return x.data() ; Chris@16: } Chris@16: Chris@16: template Chris@101: BOOST_GPU_ENABLED Chris@16: void swap ( value_initialized & lhs, value_initialized & rhs ) Chris@16: { Chris@16: lhs.swap(rhs) ; Chris@16: } Chris@16: Chris@16: Chris@16: class initialized_value_t Chris@16: { Chris@16: public : Chris@16: Chris@101: template BOOST_GPU_ENABLED operator T() const Chris@16: { Chris@16: return initialized().data(); Chris@16: } Chris@16: }; Chris@16: Chris@16: initialized_value_t const initialized_value = {} ; Chris@16: Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #ifdef BOOST_MSVC Chris@16: #pragma warning(pop) Chris@16: #endif Chris@16: Chris@16: #endif