destroy.hpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copyright David Abrahams 2002.
  2. // Distributed under the Boost Software License, Version 1.0. (See
  3. // accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef DESTROY_DWA2002221_HPP
  6. # define DESTROY_DWA2002221_HPP
  7. # include <boost/type_traits/is_array.hpp>
  8. # include <boost/detail/workaround.hpp>
  9. # if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
  10. # include <boost/type_traits/is_enum.hpp>
  11. # endif
  12. namespace boost { namespace python { namespace detail {
  13. template <
  14. bool array
  15. # if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
  16. , bool enum_ // vc7 has a problem destroying enums
  17. # endif
  18. > struct value_destroyer;
  19. template <>
  20. struct value_destroyer<
  21. false
  22. # if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
  23. , false
  24. # endif
  25. >
  26. {
  27. template <class T>
  28. static void execute(T const volatile* p)
  29. {
  30. p->~T();
  31. }
  32. };
  33. template <>
  34. struct value_destroyer<
  35. true
  36. # if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
  37. , false
  38. # endif
  39. >
  40. {
  41. template <class A, class T>
  42. static void execute(A*, T const volatile* const first)
  43. {
  44. for (T const volatile* p = first; p != first + sizeof(A)/sizeof(T); ++p)
  45. {
  46. value_destroyer<
  47. boost::is_array<T>::value
  48. # if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
  49. , boost::is_enum<T>::value
  50. # endif
  51. >::execute(p);
  52. }
  53. }
  54. template <class T>
  55. static void execute(T const volatile* p)
  56. {
  57. execute(p, *p);
  58. }
  59. };
  60. # if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
  61. template <>
  62. struct value_destroyer<true,true>
  63. {
  64. template <class T>
  65. static void execute(T const volatile*)
  66. {
  67. }
  68. };
  69. template <>
  70. struct value_destroyer<false,true>
  71. {
  72. template <class T>
  73. static void execute(T const volatile*)
  74. {
  75. }
  76. };
  77. # endif
  78. template <class T>
  79. inline void destroy_referent_impl(void* p, T& (*)())
  80. {
  81. // note: cv-qualification needed for MSVC6
  82. // must come *before* T for metrowerks
  83. value_destroyer<
  84. (boost::is_array<T>::value)
  85. # if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
  86. , (boost::is_enum<T>::value)
  87. # endif
  88. >::execute((const volatile T*)p);
  89. }
  90. template <class T>
  91. inline void destroy_referent(void* p, T(*)() = 0)
  92. {
  93. destroy_referent_impl(p, (T(*)())0);
  94. }
  95. }}} // namespace boost::python::detail
  96. #endif // DESTROY_DWA2002221_HPP