// (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
// 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 <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>
-#include <boost/type_traits/alignment_of.hpp>
#include <boost/swap.hpp>
#include <cstring>
-#include <new>
+#include <cstddef>
#ifdef BOOST_MSVC
#pragma warning(push)
namespace boost {
-template<class T>
-class initialized
-{
- private :
- struct wrapper
+namespace detail {
+
+ struct zero_init
+ {
+ zero_init()
{
-#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
- typename
-#endif
- remove_const<T>::type data;
-
- BOOST_GPU_ENABLED
- wrapper()
- :
- data()
- {
- }
-
- BOOST_GPU_ENABLED
- wrapper(T const & arg)
- :
- data(arg)
- {
- }
- };
-
- mutable
-#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
- typename
-#endif
- aligned_storage<sizeof(wrapper), alignment_of<wrapper>::value>::type x;
+ }
- BOOST_GPU_ENABLED
- wrapper * wrapper_address() const
+ zero_init( void * p, std::size_t n )
{
- return static_cast<wrapper *>( static_cast<void*>(&x));
+ std::memset( p, 0, n );
}
+ };
- public :
+} // namespace detail
- BOOST_GPU_ENABLED
- initialized()
- {
+template<class T>
+class initialized
#if BOOST_DETAIL_VALUE_INIT_WORKAROUND
- std::memset(&x, 0, sizeof(x));
+ : detail::zero_init
#endif
- new (wrapper_address()) wrapper();
- }
+{
+ private:
- BOOST_GPU_ENABLED
- initialized(initialized const & arg)
- {
- new (wrapper_address()) wrapper( static_cast<wrapper const &>(*(arg.wrapper_address())));
- }
+ T data_;
- BOOST_GPU_ENABLED
- explicit initialized(T const & arg)
- {
- new (wrapper_address()) wrapper(arg);
- }
+ public :
BOOST_GPU_ENABLED
- initialized & operator=(initialized const & arg)
+ initialized():
+#if BOOST_DETAIL_VALUE_INIT_WORKAROUND
+ zero_init( &const_cast< char& >( reinterpret_cast<char const volatile&>( data_ ) ), sizeof( data_ ) ),
+#endif
+ data_()
{
- // Assignment is only allowed when T is non-const.
- BOOST_STATIC_ASSERT( ! is_const<T>::value );
- *wrapper_address() = static_cast<wrapper const &>(*(arg.wrapper_address()));
- return *this;
}
BOOST_GPU_ENABLED
- ~initialized()
+ explicit initialized(T const & arg): data_( arg )
{
- 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
BOOST_GPU_ENABLED
operator T const &() const
{
- return wrapper_address()->data;
+ return data_;
}
BOOST_GPU_ENABLED
operator T&()
{
- return wrapper_address()->data;
+ return data_;
}
} ;