1 ///////////////////////////////////////////////////////////////////////////// 2 // 3 // (C) Copyright Ion Gaztanaga 2014-2014 4 // 5 // Distributed under the Boost Software License, Version 1.0. 6 // (See accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 // 9 // See http://www.boost.org/libs/intrusive for documentation. 10 // 11 ///////////////////////////////////////////////////////////////////////////// 12 13 #ifndef BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP 14 #define BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP 15 16 #ifndef BOOST_CONFIG_HPP 17 # include <boost/config.hpp> 18 #endif 19 20 #if defined(BOOST_HAS_PRAGMA_ONCE) 21 # pragma once 22 #endif 23 24 #include <boost/config.hpp> 25 #include <boost/core/no_exceptions_support.hpp> 26 #include <boost/move/detail/placement_new.hpp> 27 28 namespace boost { 29 namespace intrusive { 30 namespace detail { 31 32 //This is not standard, but should work with all compilers 33 union max_align 34 { 35 char char_; 36 short short_; 37 int int_; 38 long long_; 39 #ifdef BOOST_HAS_LONG_LONG 40 ::boost::long_long_type long_long_; 41 #endif 42 float float_; 43 double double_; 44 long double long_double_; 45 void * void_ptr_; 46 }; 47 48 template<class T, std::size_t N> 49 class array_initializer 50 { 51 public: 52 template<class CommonInitializer> array_initializer(const CommonInitializer & init)53 array_initializer(const CommonInitializer &init) 54 { 55 char *init_buf = (char*)rawbuf; 56 std::size_t i = 0; 57 BOOST_TRY{ 58 for(; i != N; ++i){ 59 ::new(init_buf, boost_move_new_t()) T(init); 60 init_buf += sizeof(T); 61 } 62 } 63 BOOST_CATCH(...){ 64 while(i--){ 65 init_buf -= sizeof(T); 66 ((T*)init_buf)->~T(); 67 } 68 BOOST_RETHROW; 69 } 70 BOOST_CATCH_END 71 } 72 operator T*()73 operator T* () 74 { return (T*)(rawbuf); } 75 operator const T*() const76 operator const T*() const 77 { return (const T*)(rawbuf); } 78 ~array_initializer()79 ~array_initializer() 80 { 81 char *init_buf = (char*)rawbuf + N*sizeof(T); 82 for(std::size_t i = 0; i != N; ++i){ 83 init_buf -= sizeof(T); 84 ((T*)init_buf)->~T(); 85 } 86 } 87 88 private: 89 detail::max_align rawbuf[(N*sizeof(T)-1)/sizeof(detail::max_align)+1]; 90 }; 91 92 } //namespace detail{ 93 } //namespace intrusive{ 94 } //namespace boost{ 95 96 #endif //BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP 97