]> git.lyx.org Git - lyx.git/blob - boost/boost/type_traits/type_with_alignment.hpp
update to boost 1.30.1
[lyx.git] / boost / boost / type_traits / type_with_alignment.hpp
1
2 // (C) Copyright John Maddock 2000.
3 // Permission to copy, use, modify, sell and distribute this software is 
4 // granted provided this copyright notice appears in all copies. This 
5 // software is provided "as is" without express or implied warranty, 
6 // and with no claim as to its suitability for any purpose.
7
8 #ifndef BOOST_TT_TYPE_WITH_ALIGNMENT_INCLUDED
9 #define BOOST_TT_TYPE_WITH_ALIGNMENT_INCLUDED
10
11 #include "boost/mpl/if.hpp"
12 #include "boost/preprocessor/list/for_each_i.hpp"
13 #include "boost/preprocessor/tuple/to_list.hpp"
14 #include "boost/preprocessor/cat.hpp"
15 #include "boost/type_traits/alignment_of.hpp"
16 #include "boost/type_traits/is_pod.hpp"
17 #include "boost/static_assert.hpp"
18 #include "boost/config.hpp"
19
20 // should be the last #include
21 #include "boost/type_traits/detail/bool_trait_def.hpp"
22
23 #include <cstddef>
24
25 #ifdef BOOST_MSVC
26 #   pragma warning(push)
27 #   pragma warning(disable: 4121) // alignment is sensitive to packing
28 #endif
29
30 namespace boost {
31
32 #ifndef __BORLANDC__
33
34 namespace detail {
35
36 class alignment_dummy;
37 typedef void (*function_ptr)();
38 typedef int (alignment_dummy::*member_ptr);
39 typedef int (alignment_dummy::*member_function_ptr)();
40
41 #define BOOST_TT_ALIGNMENT_TYPES BOOST_PP_TUPLE_TO_LIST( \
42         11, ( \
43         char, short, int, long, float, double, long double \
44         , void*, function_ptr, member_ptr, member_function_ptr))
45
46 #define BOOST_TT_CHOOSE_MIN_ALIGNMENT(R,P,I,T) \
47         typename mpl::if_c< \
48            alignment_of<T>::value <= target, T, char>::type BOOST_PP_CAT(t,I);
49
50 #define BOOST_TT_CHOOSE_T(R,P,I,T) T BOOST_PP_CAT(t,I);
51            
52 template <std::size_t target>
53 union lower_alignment
54 {
55     BOOST_PP_LIST_FOR_EACH_I(
56           BOOST_TT_CHOOSE_MIN_ALIGNMENT
57         , ignored
58         , BOOST_TT_ALIGNMENT_TYPES
59         )
60 };
61
62 union max_align
63 {
64     BOOST_PP_LIST_FOR_EACH_I(
65           BOOST_TT_CHOOSE_T
66         , ignored
67         , BOOST_TT_ALIGNMENT_TYPES
68         )
69 };
70
71 #undef BOOST_TT_ALIGNMENT_TYPES
72 #undef BOOST_TT_CHOOSE_MIN_ALIGNMENT
73 #undef BOOST_TT_CHOOSE_T
74
75 template<int TAlign, int Align>
76 struct is_aligned
77 {
78     BOOST_STATIC_CONSTANT(bool,
79         value = (TAlign >= Align) & (TAlign % Align == 0)
80         );
81 };
82
83 BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_pod,::boost::detail::max_align,true)
84 BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_pod,::boost::detail::lower_alignment<1> ,true)
85 BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_pod,::boost::detail::lower_alignment<2> ,true)
86 BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_pod,::boost::detail::lower_alignment<4> ,true)
87 BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_pod,::boost::detail::lower_alignment<8> ,true)
88 BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_pod,::boost::detail::lower_alignment<10> ,true)
89 BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_pod,::boost::detail::lower_alignment<16> ,true)
90 BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_pod,::boost::detail::lower_alignment<32> ,true)
91
92 } // namespace detail
93
94 // This alignment method originally due to Brian Parker, implemented by David
95 // Abrahams, and then ported here by Doug Gregor. 
96 template <int Align>
97 class type_with_alignment
98 {
99     typedef detail::lower_alignment<Align> t1;
100     typedef typename mpl::if_c<
101           ::boost::detail::is_aligned< ::boost::alignment_of<t1>::value,Align >::value
102         , t1
103         , detail::max_align
104         >::type align_t;
105
106     BOOST_STATIC_CONSTANT(std::size_t, found = alignment_of<align_t>::value);
107
108 #ifndef __BORLANDC__
109     BOOST_STATIC_ASSERT(found >= Align);
110     BOOST_STATIC_ASSERT(found % Align == 0);
111 #else
112     BOOST_STATIC_ASSERT(::boost::type_with_alignment<Align>::found >= Align);
113     BOOST_STATIC_ASSERT(::boost::type_with_alignment<Align>::found % Align == 0);
114 #endif
115
116  public:
117     typedef align_t type;
118 };
119
120 #else
121
122 //
123 // Borland specific version, we have this for two reasons:
124 // 1) The version above doesn't always compile (with the new test cases for example)
125 // 2) Because of Borlands #pragma option we can create types with alignments that are
126 //    greater that the largest aligned builtin type.
127
128 namespace align{
129 #pragma option push -a16
130 struct a2{ short s; };
131 struct a4{ int s; };
132 struct a8{ double s; };
133 struct a16{ long double s; };
134 #pragma option pop
135 }
136
137 namespace detail {
138 BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_pod,::boost::align::a2,true)
139 BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_pod,::boost::align::a4,true)
140 BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_pod,::boost::align::a8,true)
141 BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_pod,::boost::align::a16,true)
142 }
143
144 template <std::size_t N> struct type_with_alignment
145 {
146    // We should never get to here, but if we do use the maximally
147    // aligned type:
148    // BOOST_STATIC_ASSERT(0);
149    typedef align::a16 type;
150 };
151 template <> struct type_with_alignment<1>{ typedef char type; };
152 template <> struct type_with_alignment<2>{ typedef align::a2 type; };
153 template <> struct type_with_alignment<4>{ typedef align::a4 type; };
154 template <> struct type_with_alignment<8>{ typedef align::a8 type; };
155 template <> struct type_with_alignment<16>{ typedef align::a16 type; };
156
157 #endif
158
159 } // namespace boost
160
161 #ifdef BOOST_MSVC
162 #   pragma warning(pop)
163 #endif
164
165 #include "boost/type_traits/detail/bool_trait_undef.hpp"
166
167 #endif // BOOST_TT_TYPE_WITH_ALIGNMENT_INCLUDED
168
169