referent_storage.hpp 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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 REFERENT_STORAGE_DWA200278_HPP
  6. # define REFERENT_STORAGE_DWA200278_HPP
  7. # include <boost/mpl/if.hpp>
  8. # include <cstddef>
  9. namespace boost { namespace python { namespace detail {
  10. struct alignment_dummy;
  11. typedef void (*function_ptr)();
  12. typedef int (alignment_dummy::*member_ptr);
  13. typedef int (alignment_dummy::*member_function_ptr)();
  14. # define BOOST_PYTHON_ALIGNER(T, n) \
  15. typename mpl::if_c< \
  16. sizeof(T) <= size, T, char>::type t##n
  17. // Storage for size bytes, aligned to all fundamental types no larger than size
  18. template <std::size_t size>
  19. union aligned_storage
  20. {
  21. BOOST_PYTHON_ALIGNER(char, 0);
  22. BOOST_PYTHON_ALIGNER(short, 1);
  23. BOOST_PYTHON_ALIGNER(int, 2);
  24. BOOST_PYTHON_ALIGNER(long, 3);
  25. BOOST_PYTHON_ALIGNER(float, 4);
  26. BOOST_PYTHON_ALIGNER(double, 5);
  27. BOOST_PYTHON_ALIGNER(long double, 6);
  28. BOOST_PYTHON_ALIGNER(void*, 7);
  29. BOOST_PYTHON_ALIGNER(function_ptr, 8);
  30. BOOST_PYTHON_ALIGNER(member_ptr, 9);
  31. BOOST_PYTHON_ALIGNER(member_function_ptr, 10);
  32. char bytes[size];
  33. };
  34. # undef BOOST_PYTHON_ALIGNER
  35. // Compute the size of T's referent. We wouldn't need this at all,
  36. // but sizeof() is broken in CodeWarriors <= 8.0
  37. template <class T> struct referent_size;
  38. # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  39. template <class T>
  40. struct referent_size<T&>
  41. {
  42. BOOST_STATIC_CONSTANT(
  43. std::size_t, value = sizeof(T));
  44. };
  45. # else
  46. template <class T> struct referent_size
  47. {
  48. static T f();
  49. BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(f()));
  50. };
  51. # endif
  52. // A metafunction returning a POD type which can store U, where T ==
  53. // U&. If T is not a reference type, returns a POD which can store T.
  54. template <class T>
  55. struct referent_storage
  56. {
  57. typedef aligned_storage<
  58. ::boost::python::detail::referent_size<T>::value
  59. > type;
  60. };
  61. }}} // namespace boost::python::detail
  62. #endif // REFERENT_STORAGE_DWA200278_HPP