]> git.lyx.org Git - lyx.git/blob - boost/boost/type_traits/alignment_traits.hpp
update boost
[lyx.git] / boost / boost / type_traits / alignment_traits.hpp
1
2 //  (C) Copyright John Maddock 2000.
3 //  Permission to copy, use, modify, sell and
4 //  distribute this software is granted provided this copyright notice appears
5 //  in all copies. This software is provided "as is" without express or implied
6 //  warranty, and with no claim as to its suitability for any purpose.
7
8 //
9 // defines alignment_of:
10
11 #ifndef ALIGNMENT_TYPE_TRAITS_HPP
12 #define ALIGNMENT_TYPE_TRAITS_HPP
13
14 #include <cstdlib>
15 #include <cstddef>
16 #ifndef BOOST_ICE_TYPE_TRAITS_HPP
17 #include <boost/type_traits/ice.hpp>
18 #endif
19 #include <boost/preprocessor/list/for_each_i.hpp>
20 #include <boost/preprocessor/tuple/to_list.hpp>
21 #include <boost/preprocessor/cat.hpp>
22 #include <boost/type_traits/transform_traits.hpp>
23 #include <boost/static_assert.hpp>
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 template <class T> struct alignment_of;
32
33 //
34 // get the alignment of some arbitrary type:
35 namespace detail{
36
37 template <class T>
38 struct alignment_of_hack
39 {
40    char c;
41    T t;
42    alignment_of_hack();
43 };
44
45
46 template <unsigned A, unsigned S>
47 struct alignment_logic
48 {
49    BOOST_STATIC_CONSTANT(std::size_t, value = A < S ? A : S);
50 };
51
52 } // namespace detail
53
54 template <class T>
55 struct alignment_of
56 {
57    BOOST_STATIC_CONSTANT(std::size_t, value =
58       (::boost::detail::alignment_logic<
59          sizeof(detail::alignment_of_hack<T>) - sizeof(T),
60          sizeof(T)
61       >::value));
62 };
63
64 //
65 // references have to be treated specially, assume
66 // that a reference is just a special pointer:
67 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
68 template <class T>
69 struct alignment_of<T&>
70 {
71 public:
72    BOOST_STATIC_CONSTANT(std::size_t, value = ::boost::alignment_of<T*>::value);
73 };
74 #endif
75 //
76 // void has to be treated specially:
77 template <>
78 struct alignment_of<void>
79 { BOOST_STATIC_CONSTANT(std::size_t, value = 0); };
80 #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
81 template <>
82 struct alignment_of<const void>
83 { BOOST_STATIC_CONSTANT(std::size_t, value = 0); };
84 template <>
85 struct alignment_of<volatile void>
86 { BOOST_STATIC_CONSTANT(std::size_t, value = 0); };
87 template <>
88 struct alignment_of<const volatile void>
89 { BOOST_STATIC_CONSTANT(std::size_t, value = 0); };
90 #endif
91
92 namespace detail {
93 class alignment_dummy;
94 typedef void (*function_ptr)();
95 typedef int (alignment_dummy::*member_ptr);
96 typedef int (alignment_dummy::*member_function_ptr)();
97
98 /*
99  * The ct_if implementation is temporary code. It will be replaced with MPL
100  * in the future...
101  */
102 struct select_then
103 {
104   template<typename Then, typename Else>
105   struct result
106   {
107     typedef Then type;
108   };
109 };
110  
111 struct select_else
112 {
113   template<typename Then, typename Else>
114   struct result
115   { 
116     typedef Else type;
117   };
118 };
119  
120 template<bool Condition>
121 struct ct_if_selector
122 {
123   typedef select_then type;
124 };
125  
126 template<>
127 struct ct_if_selector<false>
128 {
129   typedef select_else type;
130 };
131  
132 template<bool Condition, typename Then, typename Else>
133 struct ct_if
134 {
135   typedef typename ct_if_selector<Condition>::type select;
136   typedef typename select::template result<Then,Else>::type type;
137 };
138
139 #define BOOST_TT_ALIGNMENT_TYPES BOOST_PP_TUPLE_TO_LIST( \
140         11, ( \
141         char, short, int, long, float, double, long double \
142         , void*, function_ptr, member_ptr, member_function_ptr))
143
144 #define BOOST_TT_CHOOSE_LOWER_ALIGNMENT(R,P,I,T) \
145         typename ct_if< \
146            alignment_of<T>::value <= target, T, char>::type BOOST_PP_CAT(t,I);
147
148 #define BOOST_TT_CHOOSE_T(R,P,I,T) T BOOST_PP_CAT(t,I);
149            
150 template <std::size_t target>
151 union lower_alignment
152 {
153   BOOST_PP_LIST_FOR_EACH_I(
154       BOOST_TT_CHOOSE_LOWER_ALIGNMENT
155       , ignored, BOOST_TT_ALIGNMENT_TYPES)
156 };
157
158 union max_align
159 {
160   BOOST_PP_LIST_FOR_EACH_I(
161       BOOST_TT_CHOOSE_T
162       , ignored, BOOST_TT_ALIGNMENT_TYPES)
163 };
164
165 #undef BOOST_TT_ALIGNMENT_TYPES
166 #undef BOOST_TT_CHOOSE_LOWER_ALIGNMENT
167 #undef BOOST_TT_CHOOSE_T
168
169 template<int TAlign, int Align>
170 struct is_aligned 
171 {
172   BOOST_STATIC_CONSTANT(bool, 
173                         value = (TAlign >= Align) & (TAlign % Align == 0));
174 };
175
176 }
177
178 // This alignment method originally due to Brian Parker, implemented by David
179 // Abrahams, and then ported here by Doug Gregor. 
180 template <int Align>
181 class type_with_alignment
182 {
183   typedef detail::lower_alignment<Align> t1;
184
185   typedef type_with_alignment<Align> this_type;
186
187   typedef typename detail::ct_if<
188               (detail::is_aligned<(alignment_of<t1>::value), Align>::value)
189             , t1
190             , detail::max_align
191           >::type align_t;
192
193   BOOST_STATIC_CONSTANT(std::size_t, found = alignment_of<align_t>::value);
194   
195   BOOST_STATIC_ASSERT(found >= Align);
196   BOOST_STATIC_ASSERT(found % Align == 0);
197   
198 public:
199   typedef align_t type;
200 };
201
202 } // namespace boost
203
204 #ifdef BOOST_MSVC
205 # pragma warning(pop)
206 #endif
207
208 #endif // ALIGNMENT_TYPE_TRAITS_HPP