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
27namespace boost {
28namespace intrusive {
29namespace detail {
30
31//This is not standard, but should work with all compilers
32union max_align
33{
34 char char_;
35 short short_;
36 int int_;
37 long long_;
38 #ifdef BOOST_HAS_LONG_LONG
39 ::boost::long_long_type long_long_;
40 #endif
41 float float_;
42 double double_;
43 long double long_double_;
44 void * void_ptr_;
45};
46
47template<class T, std::size_t N>
48class array_initializer
49{
50 public:
51 template<class CommonInitializer>
52 array_initializer(const CommonInitializer &init)
53 {
54 char *init_buf = (char*)rawbuf;
55 std::size_t i = 0;
56 BOOST_TRY{
57 for(; i != N; ++i){
58 new(init_buf)T(init);
59 init_buf += sizeof(T);
60 }
61 }
62 BOOST_CATCH(...){
63 while(i--){
64 init_buf -= sizeof(T);
65 ((T*)init_buf)->~T();
66 }
67 BOOST_RETHROW;
68 }
69 BOOST_CATCH_END
70 }
71
72 operator T* ()
73 { return (T*)(rawbuf); }
74
75 operator const T*() const
76 { return (const T*)(rawbuf); }
77
78 ~array_initializer()
79 {
80 char *init_buf = (char*)rawbuf + N*sizeof(T);
81 for(std::size_t i = 0; i != N; ++i){
82 init_buf -= sizeof(T);
83 ((T*)init_buf)->~T();
84 }
85 }
86
87 private:
88 detail::max_align rawbuf[(N*sizeof(T)-1)/sizeof(detail::max_align)+1];
89};
90
91} //namespace detail{
92} //namespace intrusive{
93} //namespace boost{
94
95#endif //BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP
96