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