///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2014-2014 // // 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) // // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// #ifndef BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP #define BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP #ifndef BOOST_CONFIG_HPP # include #endif #if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif #include #include #include namespace boost { namespace intrusive { namespace detail { //This is not standard, but should work with all compilers union max_align { char char_; short short_; int int_; long long_; #ifdef BOOST_HAS_LONG_LONG ::boost::long_long_type long_long_; #endif float float_; double double_; long double long_double_; void * void_ptr_; }; template class array_initializer { public: template array_initializer(const CommonInitializer &init) { char *init_buf = (char*)rawbuf; std::size_t i = 0; BOOST_TRY{ for(; i != N; ++i){ ::new(init_buf, boost_move_new_t()) T(init); init_buf += sizeof(T); } } BOOST_CATCH(...){ while(i--){ init_buf -= sizeof(T); ((T*)init_buf)->~T(); } BOOST_RETHROW; } BOOST_CATCH_END } operator T* () { return (T*)(rawbuf); } operator const T*() const { return (const T*)(rawbuf); } ~array_initializer() { char *init_buf = (char*)rawbuf + N*sizeof(T); for(std::size_t i = 0; i != N; ++i){ init_buf -= sizeof(T); ((T*)init_buf)->~T(); } } private: detail::max_align rawbuf[(N*sizeof(T)-1)/sizeof(detail::max_align)+1]; }; } //namespace detail{ } //namespace intrusive{ } //namespace boost{ #endif //BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP