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 
27 namespace boost {
28 namespace intrusive {
29 namespace detail {
30 
31 //This is not standard, but should work with all compilers
32 union 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 
47 template<class T, std::size_t N>
48 class array_initializer
49 {
50    public:
51    template<class CommonInitializer>
array_initializer(const CommonInitializer & init)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 
operator T*()72    operator T* ()
73    {  return (T*)(rawbuf);  }
74 
operator const T*() const75    operator const T*() const
76    {  return (const T*)(rawbuf);  }
77 
~array_initializer()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