diff --git a/include/boost/utility/value_init.hpp b/include/boost/utility/value_init.hpp index 7bd7943..2490b48 100644 --- a/include/boost/utility/value_init.hpp +++ b/include/boost/utility/value_init.hpp @@ -1,4 +1,5 @@ // (C) Copyright 2002-2008, Fernando Luis Cacciola Carballal. +// Copyright 2020 Peter Dimov // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -21,15 +22,10 @@ // issues, by clearing the bytes of T, before constructing the T object it // contains. More details on these issues are at libs/utility/value_init.htm -#include #include // For BOOST_NO_COMPLETE_VALUE_INITIALIZATION. -#include -#include -#include -#include #include #include -#include +#include #ifdef BOOST_MSVC #pragma warning(push) @@ -39,6 +35,8 @@ // 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) +// C4355: 'this' : used in base member initializer list +#pragma warning(disable: 4355) #endif #ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION @@ -60,92 +58,58 @@ namespace boost { +namespace detail { + + struct zero_init + { + zero_init() + { + } + + zero_init( void * p, std::size_t n ) + { + std::memset( p, 0, n ); + } + }; + +} // namespace detail + template class initialized +#if BOOST_DETAIL_VALUE_INIT_WORKAROUND + : detail::zero_init +#endif { - private : - struct wrapper - { -#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x592)) - typename -#endif - remove_const::type data; + private: - BOOST_GPU_ENABLED - wrapper() - : - data() - { - } - - BOOST_GPU_ENABLED - wrapper(T const & arg) - : - data(arg) - { - } - }; - - mutable -#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x592)) - typename -#endif - aligned_storage::value>::type x; - - BOOST_GPU_ENABLED - wrapper * wrapper_address() const - { - return static_cast( static_cast(&x)); - } + T data_; public : BOOST_GPU_ENABLED - initialized() - { + initialized(): #if BOOST_DETAIL_VALUE_INIT_WORKAROUND - std::memset(&x, 0, sizeof(x)); + zero_init( this, sizeof(*this) ), #endif - new (wrapper_address()) wrapper(); + data_() + { } BOOST_GPU_ENABLED - initialized(initialized const & arg) + explicit initialized(T const & arg): data_( arg ) { - new (wrapper_address()) wrapper( static_cast(*(arg.wrapper_address()))); - } - - BOOST_GPU_ENABLED - explicit initialized(T const & arg) - { - new (wrapper_address()) wrapper(arg); - } - - BOOST_GPU_ENABLED - initialized & operator=(initialized const & arg) - { - // Assignment is only allowed when T is non-const. - BOOST_STATIC_ASSERT( ! is_const::value ); - *wrapper_address() = static_cast(*(arg.wrapper_address())); - return *this; - } - - BOOST_GPU_ENABLED - ~initialized() - { - wrapper_address()->wrapper::~wrapper(); } BOOST_GPU_ENABLED T const & data() const { - return wrapper_address()->data; + return data_; } BOOST_GPU_ENABLED T& data() { - return wrapper_address()->data; + return data_; } BOOST_GPU_ENABLED @@ -157,13 +121,13 @@ class initialized BOOST_GPU_ENABLED operator T const &() const { - return wrapper_address()->data; + return data_; } BOOST_GPU_ENABLED operator T&() { - return wrapper_address()->data; + return data_; } } ; diff --git a/test/value_init_test.cpp b/test/value_init_test.cpp index c4ed281..8cfb72e 100644 --- a/test/value_init_test.cpp +++ b/test/value_init_test.cpp @@ -22,6 +22,7 @@ #endif #include +#include // // Sample POD type