array_initializer.hpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. #ifndef BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP
  13. #define BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP
  14. #ifndef BOOST_CONFIG_HPP
  15. # include <boost/config.hpp>
  16. #endif
  17. #if defined(BOOST_HAS_PRAGMA_ONCE)
  18. # pragma once
  19. #endif
  20. #include <boost/config.hpp>
  21. #include <boost/core/no_exceptions_support.hpp>
  22. namespace boost {
  23. namespace intrusive {
  24. namespace detail {
  25. //This is not standard, but should work with all compilers
  26. union max_align
  27. {
  28. char char_;
  29. short short_;
  30. int int_;
  31. long long_;
  32. #ifdef BOOST_HAS_LONG_LONG
  33. ::boost::long_long_type long_long_;
  34. #endif
  35. float float_;
  36. double double_;
  37. long double long_double_;
  38. void * void_ptr_;
  39. };
  40. template<class T, std::size_t N>
  41. class array_initializer
  42. {
  43. public:
  44. template<class CommonInitializer>
  45. array_initializer(const CommonInitializer &init)
  46. {
  47. char *init_buf = (char*)rawbuf;
  48. std::size_t i = 0;
  49. BOOST_TRY{
  50. for(; i != N; ++i){
  51. new(init_buf)T(init);
  52. init_buf += sizeof(T);
  53. }
  54. }
  55. BOOST_CATCH(...){
  56. while(i--){
  57. init_buf -= sizeof(T);
  58. ((T*)init_buf)->~T();
  59. }
  60. BOOST_RETHROW;
  61. }
  62. BOOST_CATCH_END
  63. }
  64. operator T* ()
  65. { return (T*)(rawbuf); }
  66. operator const T*() const
  67. { return (const T*)(rawbuf); }
  68. ~array_initializer()
  69. {
  70. char *init_buf = (char*)rawbuf + N*sizeof(T);
  71. for(std::size_t i = 0; i != N; ++i){
  72. init_buf -= sizeof(T);
  73. ((T*)init_buf)->~T();
  74. }
  75. }
  76. private:
  77. detail::max_align rawbuf[(N*sizeof(T)-1)/sizeof(detail::max_align)+1];
  78. };
  79. } //namespace detail{
  80. } //namespace intrusive{
  81. } //namespace boost{
  82. #endif //BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP