Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/units/detail/dimension_impl.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // Boost.Units - A C++ library for zero-overhead dimensional analysis and | |
2 // unit/quantity manipulation and conversion | |
3 // | |
4 // Copyright (C) 2003-2008 Matthias Christian Schabel | |
5 // Copyright (C) 2008 Steven Watanabe | |
6 // | |
7 // Distributed under the Boost Software License, Version 1.0. (See | |
8 // accompanying file LICENSE_1_0.txt or copy at | |
9 // http://www.boost.org/LICENSE_1_0.txt) | |
10 | |
11 #ifndef BOOST_UNITS_DIMENSION_IMPL_HPP | |
12 #define BOOST_UNITS_DIMENSION_IMPL_HPP | |
13 | |
14 #include <boost/mpl/begin_end.hpp> | |
15 #include <boost/mpl/deref.hpp> | |
16 #include <boost/mpl/if.hpp> | |
17 #include <boost/mpl/list.hpp> | |
18 #include <boost/mpl/next.hpp> | |
19 #include <boost/mpl/size.hpp> | |
20 #include <boost/mpl/less.hpp> | |
21 | |
22 #include <boost/units/config.hpp> | |
23 #include <boost/units/dimensionless_type.hpp> | |
24 #include <boost/units/static_rational.hpp> | |
25 #include <boost/units/units_fwd.hpp> | |
26 #include <boost/units/detail/dimension_list.hpp> | |
27 #include <boost/units/detail/push_front_if.hpp> | |
28 #include <boost/units/detail/push_front_or_add.hpp> | |
29 | |
30 /// \file | |
31 /// \brief Core class and metaprogramming utilities for compile-time dimensional analysis. | |
32 | |
33 namespace boost { | |
34 | |
35 namespace units { | |
36 | |
37 namespace detail { | |
38 | |
39 template<int N> | |
40 struct insertion_sort_dims_insert; | |
41 | |
42 template<bool is_greater> | |
43 struct insertion_sort_dims_comparison_impl; | |
44 | |
45 // have to recursively add the element to the next sequence. | |
46 template<> | |
47 struct insertion_sort_dims_comparison_impl<true> { | |
48 template<class Begin, int N, class T> | |
49 struct apply { | |
50 typedef list< | |
51 typename Begin::item, | |
52 typename insertion_sort_dims_insert<N - 1>::template apply< | |
53 typename Begin::next, | |
54 T | |
55 >::type | |
56 > type; | |
57 }; | |
58 }; | |
59 | |
60 // either prepend the current element or join it to | |
61 // the first remaining element of the sequence. | |
62 template<> | |
63 struct insertion_sort_dims_comparison_impl<false> { | |
64 template<class Begin, int N, class T> | |
65 struct apply { | |
66 typedef typename push_front_or_add<Begin, T>::type type; | |
67 }; | |
68 }; | |
69 | |
70 template<int N> | |
71 struct insertion_sort_dims_insert { | |
72 template<class Begin, class T> | |
73 struct apply { | |
74 typedef typename insertion_sort_dims_comparison_impl<mpl::less<typename Begin::item, T>::value>::template apply< | |
75 Begin, | |
76 N, | |
77 T | |
78 >::type type; | |
79 }; | |
80 }; | |
81 | |
82 template<> | |
83 struct insertion_sort_dims_insert<0> { | |
84 template<class Begin, class T> | |
85 struct apply { | |
86 typedef list<T, dimensionless_type> type; | |
87 }; | |
88 }; | |
89 | |
90 template<int N> | |
91 struct insertion_sort_dims_mpl_sequence { | |
92 template<class Begin> | |
93 struct apply { | |
94 typedef typename insertion_sort_dims_mpl_sequence<N - 1>::template apply<typename mpl::next<Begin>::type>::type next; | |
95 typedef typename insertion_sort_dims_insert<(next::size::value)>::template apply<next, typename mpl::deref<Begin>::type>::type type; | |
96 }; | |
97 }; | |
98 | |
99 template<> | |
100 struct insertion_sort_dims_mpl_sequence<0> { | |
101 template<class Begin> | |
102 struct apply { | |
103 typedef dimensionless_type type; | |
104 }; | |
105 }; | |
106 | |
107 template<int N> | |
108 struct insertion_sort_dims_impl { | |
109 template<class Begin> | |
110 struct apply { | |
111 typedef typename insertion_sort_dims_impl<N - 1>::template apply<typename Begin::next>::type next; | |
112 typedef typename insertion_sort_dims_insert<(next::size::value)>::template apply<next, typename Begin::item>::type type; | |
113 }; | |
114 }; | |
115 | |
116 template<> | |
117 struct insertion_sort_dims_impl<0> { | |
118 template<class Begin> | |
119 struct apply { | |
120 typedef dimensionless_type type; | |
121 }; | |
122 }; | |
123 | |
124 template<class T> | |
125 struct sort_dims | |
126 { | |
127 typedef typename insertion_sort_dims_mpl_sequence<mpl::size<T>::value>::template apply<typename mpl::begin<T>::type>::type type; | |
128 }; | |
129 | |
130 | |
131 template<class T, class Next> | |
132 struct sort_dims<list<T, Next> > | |
133 { | |
134 typedef typename insertion_sort_dims_impl<list<T, Next>::size::value>::template apply<list<T, Next> >::type type; | |
135 }; | |
136 | |
137 /// sorted sequences can be merged in linear time | |
138 template<bool less, bool greater> | |
139 struct merge_dimensions_func; | |
140 | |
141 template<int N1, int N2> | |
142 struct merge_dimensions_impl; | |
143 | |
144 template<> | |
145 struct merge_dimensions_func<true, false> | |
146 { | |
147 template<typename Begin1, typename Begin2, int N1, int N2> | |
148 struct apply | |
149 { | |
150 typedef list< | |
151 typename Begin1::item, | |
152 typename merge_dimensions_impl<N1 - 1, N2>::template apply< | |
153 typename Begin1::next, | |
154 Begin2 | |
155 >::type | |
156 > type; | |
157 }; | |
158 }; | |
159 | |
160 template<> | |
161 struct merge_dimensions_func<false, true> { | |
162 template<typename Begin1, typename Begin2, int N1, int N2> | |
163 struct apply | |
164 { | |
165 typedef list< | |
166 typename Begin2::item, | |
167 typename merge_dimensions_impl<N2 - 1, N1>::template apply< | |
168 typename Begin2::next, | |
169 Begin1 | |
170 >::type | |
171 > type; | |
172 }; | |
173 }; | |
174 | |
175 template<> | |
176 struct merge_dimensions_func<false, false> { | |
177 template<typename Begin1, typename Begin2, int N1, int N2> | |
178 struct apply | |
179 { | |
180 typedef typename mpl::plus<typename Begin1::item, typename Begin2::item>::type combined; | |
181 typedef typename push_front_if<!is_empty_dim<combined>::value>::template apply< | |
182 typename merge_dimensions_impl<N1 - 1, N2 - 1>::template apply< | |
183 typename Begin1::next, | |
184 typename Begin2::next | |
185 >::type, | |
186 combined | |
187 >::type type; | |
188 }; | |
189 }; | |
190 | |
191 template<int N1, int N2> | |
192 struct merge_dimensions_impl { | |
193 template<typename Begin1, typename Begin2> | |
194 struct apply | |
195 { | |
196 typedef typename Begin1::item dim1; | |
197 typedef typename Begin2::item dim2; | |
198 | |
199 typedef typename merge_dimensions_func<(mpl::less<dim1,dim2>::value == true), | |
200 (mpl::less<dim2,dim1>::value == true)>::template apply< | |
201 Begin1, | |
202 Begin2, | |
203 N1, | |
204 N2 | |
205 >::type type; | |
206 }; | |
207 }; | |
208 | |
209 template<typename Sequence1, typename Sequence2> | |
210 struct merge_dimensions | |
211 { | |
212 typedef typename detail::merge_dimensions_impl<Sequence1::size::value, | |
213 Sequence2::size::value>::template | |
214 apply< | |
215 Sequence1, | |
216 Sequence2 | |
217 >::type type; | |
218 }; | |
219 | |
220 template<int N> | |
221 struct iterator_to_list | |
222 { | |
223 template<typename Begin> | |
224 struct apply | |
225 { | |
226 typedef list< | |
227 typename Begin::item, | |
228 typename iterator_to_list<N - 1>::template apply< | |
229 typename Begin::next | |
230 >::type | |
231 > type; | |
232 }; | |
233 }; | |
234 | |
235 template<> | |
236 struct iterator_to_list<0> | |
237 { | |
238 template<typename Begin> | |
239 struct apply { | |
240 typedef dimensionless_type type; | |
241 }; | |
242 }; | |
243 | |
244 template<int N> | |
245 struct merge_dimensions_impl<N, 0> | |
246 { | |
247 template<typename Begin1, typename Begin2> | |
248 struct apply | |
249 { | |
250 typedef typename iterator_to_list<N>::template apply<Begin1>::type type; | |
251 }; | |
252 }; | |
253 | |
254 template<int N> | |
255 struct merge_dimensions_impl<0, N> | |
256 { | |
257 template<typename Begin1, typename Begin2> | |
258 struct apply | |
259 { | |
260 typedef typename iterator_to_list<N>::template apply<Begin2>::type type; | |
261 }; | |
262 }; | |
263 | |
264 template<> | |
265 struct merge_dimensions_impl<0, 0> | |
266 { | |
267 template<typename Begin1, typename Begin2> | |
268 struct apply | |
269 { | |
270 typedef dimensionless_type type; | |
271 }; | |
272 }; | |
273 | |
274 template<int N> | |
275 struct static_inverse_impl | |
276 { | |
277 template<typename Begin> | |
278 struct apply { | |
279 typedef list< | |
280 typename mpl::negate<typename Begin::item>::type, | |
281 typename static_inverse_impl<N - 1>::template apply< | |
282 typename Begin::next | |
283 >::type | |
284 > type; | |
285 }; | |
286 }; | |
287 | |
288 template<> | |
289 struct static_inverse_impl<0> | |
290 { | |
291 template<typename Begin> | |
292 struct apply | |
293 { | |
294 typedef dimensionless_type type; | |
295 }; | |
296 }; | |
297 | |
298 template<int N> | |
299 struct static_power_impl | |
300 { | |
301 template<typename Begin, typename Ex> | |
302 struct apply | |
303 { | |
304 typedef list< | |
305 typename mpl::times<typename Begin::item, Ex>::type, | |
306 typename detail::static_power_impl<N - 1>::template apply<typename Begin::next, Ex>::type | |
307 > type; | |
308 }; | |
309 }; | |
310 | |
311 template<> | |
312 struct static_power_impl<0> | |
313 { | |
314 template<typename Begin, typename Ex> | |
315 struct apply | |
316 { | |
317 typedef dimensionless_type type; | |
318 }; | |
319 }; | |
320 | |
321 template<int N> | |
322 struct static_root_impl { | |
323 template<class Begin, class Ex> | |
324 struct apply { | |
325 typedef list< | |
326 typename mpl::divides<typename Begin::item, Ex>::type, | |
327 typename detail::static_root_impl<N - 1>::template apply<typename Begin::next, Ex>::type | |
328 > type; | |
329 }; | |
330 }; | |
331 | |
332 template<> | |
333 struct static_root_impl<0> { | |
334 template<class Begin, class Ex> | |
335 struct apply | |
336 { | |
337 typedef dimensionless_type type; | |
338 }; | |
339 }; | |
340 | |
341 } // namespace detail | |
342 | |
343 } // namespace units | |
344 | |
345 } // namespace boost | |
346 | |
347 #endif // BOOST_UNITS_DIMENSION_IMPL_HPP |