array_initializer.hpp 2.4 KB

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