]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/units/include/boost/units/detail/dimension_impl.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / units / include / boost / units / detail / dimension_impl.hpp
CommitLineData
7c673cae
FG
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
33namespace boost {
34
35namespace units {
36
37namespace detail {
38
39template<int N>
40struct insertion_sort_dims_insert;
41
42template<bool is_greater>
43struct insertion_sort_dims_comparison_impl;
44
45// have to recursively add the element to the next sequence.
46template<>
47struct 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.
62template<>
63struct 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
70template<int N>
71struct 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
82template<>
83struct insertion_sort_dims_insert<0> {
84 template<class Begin, class T>
85 struct apply {
86 typedef list<T, dimensionless_type> type;
87 };
88};
89
90template<int N>
91struct 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
99template<>
100struct insertion_sort_dims_mpl_sequence<0> {
101 template<class Begin>
102 struct apply {
103 typedef dimensionless_type type;
104 };
105};
106
107template<int N>
108struct 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
116template<>
117struct insertion_sort_dims_impl<0> {
118 template<class Begin>
119 struct apply {
120 typedef dimensionless_type type;
121 };
122};
123
124template<class T>
125struct 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
131template<class T, class Next>
132struct 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
138template<bool less, bool greater>
139struct merge_dimensions_func;
140
141template<int N1, int N2>
142struct merge_dimensions_impl;
143
144template<>
145struct 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
160template<>
161struct 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
175template<>
176struct 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
191template<int N1, int N2>
192struct 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
209template<typename Sequence1, typename Sequence2>
210struct 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
220template<int N>
221struct 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
235template<>
236struct iterator_to_list<0>
237{
238 template<typename Begin>
239 struct apply {
240 typedef dimensionless_type type;
241 };
242};
243
244template<int N>
245struct 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
254template<int N>
255struct 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
264template<>
265struct merge_dimensions_impl<0, 0>
266{
267 template<typename Begin1, typename Begin2>
268 struct apply
269 {
270 typedef dimensionless_type type;
271 };
272};
273
274template<int N>
275struct 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
288template<>
289struct static_inverse_impl<0>
290{
291 template<typename Begin>
292 struct apply
293 {
294 typedef dimensionless_type type;
295 };
296};
297
298template<int N>
299struct 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
311template<>
312struct static_power_impl<0>
313{
314 template<typename Begin, typename Ex>
315 struct apply
316 {
317 typedef dimensionless_type type;
318 };
319};
320
321template<int N>
322struct 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
332template<>
333struct 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