]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 |