]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/units/detail/dimension_impl.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / units / detail / dimension_impl.hpp
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