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