Photon microGUI widgets library 0.6.0
ratio.hpp
1#ifndef _STDEX_RATIO_H
2#define _STDEX_RATIO_H
3
4#if _MSC_VER > 1000
5#pragma once
6#endif // _MSC_VER > 1000
7
8// stdex includes
9#include "./cstdint.hpp" // stdex::intmax_t, STDEX_INTMAX_MAX, STDEX_INTMAX_MIN
10
11// POSIX includes
12/*none*/
13
14// std includes
15#include <climits> // CHAR_BIT
16
17namespace stdex
18{
19 namespace detail
20 {
21 template<stdex::intmax_t _Val>
22 struct _sign_of
23 { // computes sign of _Val
24 static const stdex::intmax_t value = _Val < 0 ? -1 : 1;
25 };
26
27 template<stdex::intmax_t _Val>
28 struct _abs
29 { // computes absolute value of _Val
30 static const stdex::intmax_t value = _Val * _sign_of<_Val>::value;
31 };
32
33 // [Greatest common divisor template]
34
35 template<stdex::intmax_t _Ax, stdex::intmax_t _Bx>
36 struct _gcdX
37 { // computes greatest common divisor of _Ax and _Bx
38 static const stdex::intmax_t value = _gcdX<_Bx, _Ax % _Bx>::value;
39 };
40
41 template<stdex::intmax_t _Ax>
42 struct _gcdX<_Ax, 0>
43 { // computes greatest common divisor of _Ax and 0
44 static const stdex::intmax_t value = _Ax;
45 };
46
47 template<stdex::intmax_t _Ax, stdex::intmax_t _Bx>
48 struct _gcd
49 { // computes greatest common divisor of abs(_Ax) and abs(_Bx)
50 static const stdex::intmax_t value =
51 _gcdX<_abs<_Ax>::value, _abs<_Bx>::value>::value;
52 };
53
54 template<>
55 struct _gcd<0, 0>
56 { // avoids division by 0 in ratio_less
57 static const stdex::intmax_t value = 1; // contrary to mathematical convention
58 };
59 }
60
61 namespace intern
62 {
63 // since we have no static_assert in pre-C++11 we just compile-time assert this way:
64 namespace ratio_asserts
65 {
66 template<bool>
67 struct overflow_in_multiplication_assert; // if you are there means overflow in safe template multiplication occurred
68
69 template<bool>
70 struct internal_library_error_assert; // if you are there means internal library error occurred
71
72 template<bool>
73 struct denominator_cant_be_zero_assert; // if you are there means you put the denominator to zero
74
75 template<bool>
76 struct out_of_range; // if you are there means that value is out of range
77
78 template<bool>
79 struct division_by_zero; // if you are there means that divider is zero
80
81 template<bool>
82 struct overflow_in_addition_assert; // if you are there means overflow in safe template addition occurred
83
84 template<>
85 struct overflow_in_multiplication_assert<true>
86 {
87 typedef bool overflow_in_multiplication_assert_failed;
88 };
89
90 template<>
91 struct internal_library_error_assert<true>
92 {
93 typedef bool internal_library_error_assert_failed;
94 };
95
96 template<>
97 struct denominator_cant_be_zero_assert<true>
98 {
99 typedef bool denominator_cant_be_zero_assert_failed;
100 };
101
102 template<>
103 struct out_of_range<true>
104 {
105 typedef bool out_of_range_failed;
106 };
107
108 template<>
109 struct division_by_zero<true>
110 {
111 typedef bool division_by_zero_failed;
112 };
113
114 template<>
115 struct overflow_in_addition_assert<true>
116 {
117 typedef bool overflow_in_addition_assert_failed;
118 };
119 } // namespace ratio_asserts
120 } // namespace intern
121
122 namespace detail
123 {
124 // [Safe add template]
125
126 template<stdex::intmax_t _Pn, stdex::intmax_t _Qn, bool>
127 struct _add_overflow_check_impl
128 {
129 static const stdex::intmax_t value = _Pn <= (STDEX_INTMAX_MAX - _Qn);
130 };
131
132 template<stdex::intmax_t _Pn, stdex::intmax_t _Qn>
133 struct _add_overflow_check_impl<_Pn, _Qn, false>
134 {
135 static const stdex::intmax_t value = _Pn >= (STDEX_INTMAX_MIN - _Qn);
136 };
137
138 template<stdex::intmax_t _Pn, stdex::intmax_t _Qn>
139 struct _add_overflow_check
140 : _add_overflow_check_impl<_Pn, _Qn, (_Qn >= 0)>
141 { };
142
143 template<stdex::intmax_t _Pn, stdex::intmax_t _Qn>
144 struct _safe_add
145 {
146 static const stdex::intmax_t value = _Pn + _Qn;
147
148 private:
149
150
151 typedef typename intern::ratio_asserts::overflow_in_addition_assert<bool(_add_overflow_check<_Pn, _Qn>::value != 0)>::
152 overflow_in_addition_assert_failed
153 check1; // if you are there means overflow in safe template addition occurred
154 };
155
156 struct _half_char_bit
157 {
158 static const stdex::uintmax_t value = (CHAR_BIT / 2);
159
160 private:
161
162 typedef intern::ratio_asserts::internal_library_error_assert< ( (CHAR_BIT % 2) == 0 ) >::
163 internal_library_error_assert_failed
164 check1; // if you are there means internal library error occurred (number of bits in char is not even on your platform)
165 };
166
167 // [Safe multiply template]
168
169 // Let c = 2^(half # of bits in an intmax_t)
170 // then we find a1, a0, b1, b0 s.t. N = a1*c + a0, M = b1*c + b0
171 // The multiplication of N and M becomes,
172 // N * M = (a1 * b1)c^2 + (a0 * b1 + b0 * a1)c + a0 * b0
173 // Multiplication is safe if each term and the sum of the terms
174 // is representable by intmax_t.
175 template<stdex::intmax_t _Pn, stdex::intmax_t _Qn>
176 struct _safe_multiply_helper
177 {
178 static const stdex::uintmax_t _c = stdex::uintmax_t(1) << (sizeof(stdex::intmax_t) * _half_char_bit::value);
179
180 static const stdex::uintmax_t _a0 = _abs<_Pn>::value % _c;
181 static const stdex::uintmax_t _a1 = _abs<_Pn>::value / _c;
182 static const stdex::uintmax_t _b0 = _abs<_Qn>::value % _c;
183 static const stdex::uintmax_t _b1 = _abs<_Qn>::value / _c;
184
185 static const stdex::uintmax_t _intmax_max = STDEX_UINTMAX_C(STDEX_INTMAX_MAX);
186 };
187
188 template<stdex::intmax_t _Pn, stdex::intmax_t _Qn>
189 struct _safe_multiply
190 {
191 private:
192 typedef _safe_multiply_helper<_Pn, _Qn> _helper_type;
193
194 typedef typename intern::ratio_asserts::overflow_in_multiplication_assert< bool(_helper_type::_a1 == 0 || _helper_type::_b1 == 0) >::
195 overflow_in_multiplication_assert_failed
196 check1; // if you are there means overflow in safe template multiplication occurred
197 typedef typename intern::ratio_asserts::overflow_in_multiplication_assert< bool(_helper_type::_a0 * _helper_type::_b1 + _helper_type::_b0 * _helper_type::_a1 < (_helper_type::_c / stdex::uintmax_t(2))) >::
198 overflow_in_multiplication_assert_failed
199 check2; // if you are there means overflow in safe template multiplication occurred
200 typedef typename intern::ratio_asserts::overflow_in_multiplication_assert< bool( _helper_type::_b0 * _helper_type::_a0 <= _helper_type::_intmax_max ) >::
201 overflow_in_multiplication_assert_failed
202 check3; // if you are there means overflow in safe template multiplication occurred
203 typedef typename intern::ratio_asserts::overflow_in_multiplication_assert< bool((_helper_type::_a0 * _helper_type::_b1 + _helper_type::_b0 * _helper_type::_a1) * _helper_type::_c <= _helper_type::_intmax_max - _helper_type::_b0 * _helper_type::_a0) >::
204 overflow_in_multiplication_assert_failed
205 check4; // if you are there means overflow in safe template multiplication occurred
206
207 public:
208 static const stdex::intmax_t value = _Pn * _Qn;
209 };
210
211 // [Less template]
212
213 // Some double-precision utilities, where numbers are represented as
214 // _hi*2^(8*sizeof(uintmax_t)) + _lo.
215 template<stdex::uintmax_t _hi1, stdex::uintmax_t _lo1, stdex::uintmax_t _hi2, stdex::uintmax_t _lo2>
216 struct _big_less
217 {
218 static const bool value = (_hi1 < _hi2 || (_hi1 == _hi2 && _lo1 < _lo2));
219 };
220
221 template<stdex::uintmax_t _lo1, stdex::uintmax_t _lo2>
222 struct _big_add_lo
223 {
224 static const stdex::uintmax_t value = (_lo1 + _lo2);
225 };
226
227 template<stdex::uintmax_t _hi1, stdex::uintmax_t _lo1, stdex::uintmax_t _hi2, stdex::uintmax_t _lo2>
228 struct _big_add
229 {
230 typedef _big_add_lo<_lo1, _lo2> _lo_type;// overflow is ok
231 static const stdex::uintmax_t _lo = _lo_type::value;
232 static const stdex::uintmax_t _hi = (_hi1 + _hi2 +
233 stdex::uintmax_t(_lo_type::value < _lo1) ); // carry
234 };
235
236 // [Subtract template]
237
238 template<stdex::uintmax_t _hi1, stdex::uintmax_t _lo1, stdex::uintmax_t _hi2, stdex::uintmax_t _lo2>
239 struct _big_sub_helper
240 {
241 static const stdex::uintmax_t _lo = _lo1 - _lo2;
242 static const stdex::uintmax_t _hi = (_hi1 - _hi2 - (_lo1 < _lo2));
243 };
244
245 // Subtract a number from a bigger one.
246 template<stdex::uintmax_t _hi1, stdex::uintmax_t _lo1, stdex::uintmax_t _hi2, stdex::uintmax_t _lo2>
247 struct _big_sub
248 {
249 typedef _big_sub_helper<_hi1, _lo1, _hi2, _lo2> _helper_type;
250 static const stdex::uintmax_t _lo = _helper_type::_lo;
251 static const stdex::uintmax_t _hi = _helper_type::_hi;
252
253 private:
254
255 typedef typename intern::ratio_asserts::internal_library_error_assert< bool(!(_big_less<_hi1, _lo1, _hi2, _lo2>::value != 0)) >::
256 internal_library_error_assert_failed
257 check1; // if you are there means internal library error occurred
258 };
259
260 // [Safe multiply for bigger numbers template]
261 template<stdex::uintmax_t _x, stdex::uintmax_t _y>
262 struct _big_multiply_helper1
263 {
264 static const stdex::uintmax_t _c = stdex::uintmax_t(1) << (sizeof(stdex::intmax_t) * _half_char_bit::value);
265 static const stdex::uintmax_t _x0 = _x % _c;
266 static const stdex::uintmax_t _x1 = _x / _c;
267 static const stdex::uintmax_t _y0 = _y % _c;
268 static const stdex::uintmax_t _y1 = _y / _c;
269 };
270
271 template<stdex::uintmax_t _x, stdex::uintmax_t _y>
272 struct _big_multiply_helper2
273 {
274 typedef _big_multiply_helper1<_x, _y> _helper_type;
275
276 static const stdex::uintmax_t _x0y0 = _helper_type::_x0 * _helper_type::_y0;
277 static const stdex::uintmax_t _x0y1 = _helper_type::_x0 * _helper_type::_y1;
278 static const stdex::uintmax_t _x1y0 = _helper_type::_x1 * _helper_type::_y0;
279 static const stdex::uintmax_t _x1y1 = _helper_type::_x1 * _helper_type::_y1;
280 };
281
282 template<stdex::uintmax_t _x, stdex::uintmax_t _y>
283 struct _big_multiply_helper3
284 {
285 typedef _big_multiply_helper2<_x, _y> _helper_type;
286
287 static const stdex::uintmax_t _mix = _helper_type::_x0y1 + _helper_type::_x1y0; // possible carry...
288 };
289
290 template<stdex::uintmax_t _x, stdex::uintmax_t _y>
291 struct _big_multiply_helper
292 {
293 typedef _big_multiply_helper1<_x, _y> _helper_type1;
294 typedef _big_multiply_helper2<_x, _y> _helper_type2;
295 typedef _big_multiply_helper3<_x, _y> _helper_type3;
296
297 static const stdex::uintmax_t _mix_lo = static_cast<const stdex::uintmax_t>(_helper_type3::_mix) * _helper_type1::_c; // overflow is ok
298 static const stdex::uintmax_t _mix_hi
299 = _helper_type3::_mix / _helper_type1::_c + ((_helper_type3::_mix < _helper_type2::_x0y1) ? _helper_type1::_c : 0); // ... added here
300 };
301
302 // Same principle as _safe_multiply.
303 template<stdex::uintmax_t _x, stdex::uintmax_t _y>
304 struct _big_multiply
305 {
306 private:
307 typedef _big_multiply_helper<_x, _y> _helper_type;
308 typedef _big_multiply_helper2<_x, _y> _helper_type2;
309 typedef _big_add<_helper_type::_mix_hi, _helper_type::_mix_lo, _helper_type2::_x1y1, _helper_type2::_x0y0> _Res;
310 public:
311 static const stdex::uintmax_t _hi = _Res::_hi;
312 static const stdex::uintmax_t _lo = _Res::_lo;
313 };
314 }
315
316 namespace detail
317 {
318 template<stdex::intmax_t _Num, stdex::intmax_t _Den = 1>
319 struct _ratio
320 {
321 static const stdex::intmax_t num =
322 _Num * _sign_of<_Den>::value / _gcd<_Num, _Den>::value;
323
324 static const stdex::intmax_t den =
325 _abs<_Den>::value / _gcd<_Num, _Den>::value;
326 };
327
328 } // namespace detail
329
330 template<stdex::intmax_t _Num, stdex::intmax_t _Den = 1>
331 struct ratio
332 {
333 // Note: sign(N) * abs(N) == N
334 static const stdex::intmax_t num =
335 detail::_ratio<_Num, _Den>::num;
336
337 static const stdex::intmax_t den =
338 detail::_ratio<_Num, _Den>::den;
339
340 typedef
341 ratio<
342 detail::_ratio<_Num, _Den>::num,
343 detail::_ratio<_Num, _Den>::den
344 > type;
345
346 private:
347
348 typedef typename intern::ratio_asserts::denominator_cant_be_zero_assert< bool(_Den != 0) >::
349 denominator_cant_be_zero_assert_failed
350 check1; // if you are there means you put the denominator to zero
351 typedef typename intern::ratio_asserts::out_of_range<bool( (_Num >= -STDEX_INTMAX_MAX) && (_Den >= -STDEX_INTMAX_MAX) )>::
352 out_of_range_failed
353 check2; // if you are there means that value is out of range
354 };
355
356 namespace detail
357 {
358 template<class _R1, class _R2>
359 struct _ratio_multiply_gcd
360 {
361 static const stdex::intmax_t _gcd1 =
362 _gcd<_R1::num, _R2::den>::value;
363 static const stdex::intmax_t _gcd2 =
364 _gcd<_R2::num, _R1::den>::value;
365 };
366
367 template<class _R1, class _R2>
368 struct _ratio_multiply
369 {
370 private:
371 typedef _ratio_multiply_gcd<_R1, _R2> _gcd_type;
372
373 public:
374 typedef ratio<
375 _safe_multiply<stdex::intmax_t(_R1::num / _gcd_type::_gcd1),
376 stdex::intmax_t(_R2::num / _gcd_type::_gcd2)>::value,
377 _safe_multiply<stdex::intmax_t(_R1::den / _gcd_type::_gcd2),
378 stdex::intmax_t(_R2::den / _gcd_type::_gcd1)>::value> type;
379
380 static const stdex::intmax_t num = type::num;
381 static const stdex::intmax_t den = type::den;
382 };
383
384 template<class _R1, class _R2>
385 struct _ratio_multiply_den
386 {
387 private:
388 typedef _ratio_multiply_gcd<_R1, _R2> _gcd_type;
389
390 public:
391
392 static const stdex::intmax_t value =
393 _safe_multiply<
394 stdex::intmax_t(_R1::den / _gcd_type::_gcd2),
395 stdex::intmax_t(_R2::den / _gcd_type::_gcd1)
396 >::value;
397 };
398
399 template<class _R1, class _R2>
400 struct _ratio_multiply_num
401 {
402 private:
403 typedef _ratio_multiply_gcd<_R1, _R2> _gcd_type;
404
405 public:
406
407 static const stdex::intmax_t value =
408 _safe_multiply<
409 stdex::intmax_t(_R1::num / _gcd_type::_gcd1),
410 stdex::intmax_t(_R2::num / _gcd_type::_gcd2)
411 >::value;
412 };
413 }
414
415 template<class _R1, class _R2>
416 struct ratio_multiply :
417 detail::_ratio_multiply<_R1, _R2>::type
418 {};
419
420 namespace detail
421 {
422
423 template<class _R1, class _R2>
424 struct _ratio_divide
425 {
426 typedef typename ratio_multiply<
427 _R1,
428 ratio<_R2::den, _R2::num> >::type type;
429
430 static const stdex::intmax_t num = type::num;
431 static const stdex::intmax_t den = type::den;
432
433 private:
434
435
436 typedef typename intern::ratio_asserts::out_of_range< bool(_R2::num != 0) >::
437 out_of_range_failed
438 check1;// if you are there means that divider is zero
439 };
440
441 template<class _R1, class _R2>
442 struct _ratio_divide_den
443 {
444 typedef _ratio_multiply_den<
445 _R1,
446 ratio<_R2::den, _R2::num> > type;
447
448 static const stdex::intmax_t value = type::value;
449 private:
450
451
452 typedef typename intern::ratio_asserts::out_of_range< bool(_R2::num != 0) >::
453 out_of_range_failed
454 check1;// if you are there means that divider is zero
455 };
456
457 template<class _R1, class _R2>
458 struct _ratio_divide_num
459 {
460 typedef _ratio_multiply_num<
461 _R1,
462 ratio<_R2::den, _R2::num> > type;
463
464 static const stdex::intmax_t value = type::value;
465 private:
466
467
468 typedef typename intern::ratio_asserts::out_of_range< bool(_R2::num != 0) >::
469 out_of_range_failed
470 check1;// if you are there means that divider is zero
471 };
472 }
473
474 template<class _R1, class _R2>
475 struct ratio_divide :
476 detail::_ratio_divide<_R1, _R2>::type
477 {};
478
479 // ratio_equal
480 template<class _R1, class _R2>
481 struct ratio_equal
482 {
483 static const bool value = _R1::num == _R2::num && _R1::den == _R2::den;
484 };
485
486 // ratio_not_equal
487 template<class _R1, class _R2>
488 struct ratio_not_equal
489 {
490 static const bool value = !ratio_equal<_R1, _R2>::value;
491 };
492
493 namespace detail
494 {
495 // Both numbers are positive.
496 template<class _R1, class _R2,
497 class _Left = _big_multiply<_R1::num, _R2::den>,
498 class _Right = _big_multiply<_R2::num, _R1::den> >
499 struct _ratio_less_impl_1
500 {
501 static const bool value = _big_less<_Left::_hi, _Left::_lo, _Right::_hi, _Right::_lo>::value;
502 };
503
504 template<class _R1, class _R2,
505 bool = (_R1::num == 0 || _R2::num == 0
506 || (_sign_of<_R1::num>::value
507 != _sign_of<_R2::num>::value)),
508 bool = (_sign_of<_R1::num>::value == -1
509 && _sign_of<_R2::num>::value == -1)>
510 struct _ratio_less_impl :
511 _ratio_less_impl_1<_R1, _R2>
512 { };
513
514 template<class _R1, class _R2>
515 struct _ratio_less_impl<_R1, _R2, true, false>
516 {
517 static const bool value = _R1::num < _R2::num;
518 };
519
520 template<class _R1, class _R2>
521 struct _ratio_less_impl<_R1, _R2, false, true> :
522 _ratio_less_impl_1< ratio<-_R2::num, _R2::den>, ratio<-_R1::num, _R1::den> >
523 { };
524 }
525
526 // ratio_less
527 template<class _R1, class _R2>
528 struct ratio_less:
529 detail::_ratio_less_impl<_R1, _R2>
530 { };
531
532 // ratio_less_equal
533 template<class _R1, class _R2>
534 struct ratio_less_equal
535 {
536 static const bool value = ratio_less<_R2, _R1>::value == bool(false);
537 };
538
539 // ratio_greater
540 template<class _R1, class _R2>
541 struct ratio_greater
542 {
543 static const bool value = ratio_less<_R2, _R1>::value;
544 };
545
546 // ratio_greater_equal
547 template<class _R1, class _R2>
548 struct ratio_greater_equal
549 {
550 static const bool value = !ratio_less<_R1, _R2>::value;
551 };
552
553 namespace detail
554 {
555 // ratio_add
556 template<class _R1, class _R2>
557 struct _ratio_add
558 { // add two ratios
559 private:
560 static const stdex::intmax_t _n1 = _R1::num;
561 static const stdex::intmax_t _d1 = _R1::den;
562 static const stdex::intmax_t _n2 = _R2::num;
563 static const stdex::intmax_t _d2 = _R2::den;
564
565 static const stdex::intmax_t _gx = _gcd<_d1, _d2>::value;
566
567 static const stdex::intmax_t _n = _safe_add<
568 _safe_multiply<_R1::num, stdex::intmax_t(_R2::den / _ratio_add::_gx)>::value,
569 _safe_multiply<_R2::num, stdex::intmax_t(_R1::den / _ratio_add::_gx)>::value>::value;
570
571 // The new numerator may have common factors with the denominator,
572 // but they have to also be factors of __gcd.
573 static const stdex::intmax_t _gx2 = _gcd<_ratio_add::_n, _ratio_add::_gx>::value;
574
575 public:
576 // typename ratio<>::type is necessary here
577 typedef
578 typename
579 ratio<
580 stdex::intmax_t(_ratio_add::_n / _ratio_add::_gx2),
581 _safe_multiply<
582 stdex::intmax_t(_R1::den / _ratio_add::_gx2), stdex::intmax_t(_R2::den / _ratio_add::_gx)
583 >::value
584 >::type type;
585 };
586 }
587
588 template<class _R1, class _R2>
589 struct ratio_add :
590 detail::_ratio_add<_R1, _R2>::type
591 {};
592
593 namespace detail
594 {
595 template<class _R1, class _R2>
596 struct _ratio_subtract
597 {
598 typedef
599 typename
600 _ratio_add<
601 _R1,
602 ratio<
603 stdex::intmax_t(-_R2::num),
604 _R2::den
605 >
606 >::type type;
607
608 static const stdex::intmax_t num = type::num;
609 static const stdex::intmax_t den = type::den;
610 };
611 }
612
613 template<class _R1, class _R2>
614 struct ratio_subtract :
615 detail::_ratio_subtract<_R1, _R2>::type
616 {};
617
618 namespace detail
619 {
620 template<int _MaxBitsN>
621 struct _ratio_predefined_impl:
622 _ratio_predefined_impl<_MaxBitsN - 1>
623 { };
624
625 template<bool>
626 struct _10_pow_01
627 {
628 static const stdex::uintmax_t value = STDEX_UINTMAX_C(10);
629 };
630
631 template<>
632 struct _10_pow_01<true>
633 {
634 static const stdex::uintmax_t value = STDEX_UINTMAX_C(1);
635 };
636
637 enum {
638 _10_pow_01_bit_n = 4,
639 _10_pow_02_bit_n = 7,
640 _10_pow_03_bit_n = 10,
641 _10_pow_06_bit_n = 20,
642 _10_pow_09_bit_n = 30,
643 _10_pow_12_bit_n = 40,
644 _10_pow_15_bit_n = 50,
645 _10_pow_18_bit_n = 60,
646 _10_pow_21_bit_n = 70,
647 _10_pow_24_bit_n = 80
648 };
649
650 #define _STDEX_10_POW(cond) _10_pow_01<(cond)>::value
651 #define _STDEX_INTMAX_BIT_COUNT (sizeof(stdex::intmax_t) * CHAR_BIT)
652 #define _STDEX_10_POW_IMPL(pow_n) _STDEX_10_POW(_10_pow_##pow_n##_bit_n > _STDEX_INTMAX_BIT_COUNT)
653 #define _STDEX_10_POW_01_IMPL(pow_n) (_STDEX_10_POW_IMPL(pow_n))
654 #define _STDEX_10_POW_02_IMPL(pow_n) (_STDEX_10_POW_01_IMPL(pow_n) * _STDEX_10_POW_01_IMPL(pow_n))
655 #define _STDEX_10_POW_03_IMPL(pow_n) (_STDEX_10_POW_01_IMPL(pow_n) * _STDEX_10_POW_02_IMPL(pow_n))
656 #define _STDEX_10_POW_06_IMPL(pow_n) (_STDEX_10_POW_03_IMPL(pow_n) * _STDEX_10_POW_03_IMPL(pow_n))
657 #define _STDEX_10_POW_09_IMPL(pow_n) (_STDEX_10_POW_03_IMPL(pow_n) * _STDEX_10_POW_06_IMPL(pow_n))
658 #define _STDEX_10_POW_12_IMPL(pow_n) (_STDEX_10_POW_06_IMPL(pow_n) * _STDEX_10_POW_06_IMPL(pow_n))
659 #define _STDEX_10_POW_15_IMPL(pow_n) (_STDEX_10_POW_06_IMPL(pow_n) * _STDEX_10_POW_09_IMPL(pow_n))
660 #define _STDEX_10_POW_18_IMPL(pow_n) (_STDEX_10_POW_09_IMPL(pow_n) * _STDEX_10_POW_09_IMPL(pow_n))
661 #define _STDEX_10_POW_21_IMPL(pow_n) (_STDEX_10_POW_09_IMPL(pow_n) * _STDEX_10_POW_12_IMPL(pow_n))
662 #define _STDEX_10_POW_24_IMPL(pow_n) (_STDEX_10_POW_12_IMPL(pow_n) * _STDEX_10_POW_12_IMPL(pow_n))
663
664 #define _STDEX_10_POW_01 _STDEX_10_POW_01_IMPL(01)
665 #define _STDEX_10_POW_02 _STDEX_10_POW_02_IMPL(02)
666 #define _STDEX_10_POW_03 _STDEX_10_POW_03_IMPL(03)
667 #define _STDEX_10_POW_06 _STDEX_10_POW_06_IMPL(06)
668 #define _STDEX_10_POW_09 _STDEX_10_POW_09_IMPL(09)
669 #define _STDEX_10_POW_12 _STDEX_10_POW_12_IMPL(12)
670 #define _STDEX_10_POW_15 _STDEX_10_POW_15_IMPL(15)
671 #define _STDEX_10_POW_18 _STDEX_10_POW_18_IMPL(18)
672 #define _STDEX_10_POW_21 _STDEX_10_POW_21_IMPL(21)
673 #define _STDEX_10_POW_24 _STDEX_10_POW_24_IMPL(24)
674
675
676
677 template<>
678 struct _ratio_predefined_impl<0>;
679
680 template<>
681 struct _ratio_predefined_impl<_10_pow_01_bit_n>;
682
683 template<>
684 struct _ratio_predefined_impl<_10_pow_02_bit_n>
685 {
686 struct type_cannot_be_implemented;
687
688 typedef type_cannot_be_implemented yocto;
689 typedef type_cannot_be_implemented zepto;
690 typedef type_cannot_be_implemented atto;
691 typedef type_cannot_be_implemented femto;
692 typedef type_cannot_be_implemented pico;
693 typedef type_cannot_be_implemented nano;
694 typedef type_cannot_be_implemented micro;
695 typedef type_cannot_be_implemented milli;
696 typedef ratio<STDEX_INTMAX_C(1), static_cast<stdex::intmax_t>(_STDEX_10_POW_02)> centi;
697 typedef ratio<STDEX_INTMAX_C(1), static_cast<stdex::intmax_t>(_STDEX_10_POW_01)> deci;
698 typedef ratio<static_cast<stdex::intmax_t>(_STDEX_10_POW_01), STDEX_INTMAX_C(1)> deca;
699 typedef ratio<static_cast<stdex::intmax_t>(_STDEX_10_POW_02), STDEX_INTMAX_C(1)> hecto;
700 typedef type_cannot_be_implemented kilo;
701 typedef type_cannot_be_implemented mega;
702 typedef type_cannot_be_implemented giga;
703 typedef type_cannot_be_implemented tera;
704 typedef type_cannot_be_implemented peta;
705 typedef type_cannot_be_implemented exa;
706 typedef type_cannot_be_implemented zetta;
707 typedef type_cannot_be_implemented yotta;
708 };
709
710 template<>
711 struct _ratio_predefined_impl<_10_pow_03_bit_n>:
712 _ratio_predefined_impl<_10_pow_02_bit_n>
713 {
714 typedef ratio<STDEX_INTMAX_C(1), static_cast<stdex::intmax_t>(_STDEX_10_POW_03)> milli;
715 typedef ratio<static_cast<stdex::intmax_t>(_STDEX_10_POW_03), STDEX_INTMAX_C(1)> kilo;
716 };
717
718 template<>
719 struct _ratio_predefined_impl<_10_pow_06_bit_n>:
720 _ratio_predefined_impl<_10_pow_03_bit_n>
721 {
722 typedef ratio<STDEX_INTMAX_C(1), static_cast<stdex::intmax_t>(_STDEX_10_POW_06)> micro;
723 typedef ratio<static_cast<stdex::intmax_t>(_STDEX_10_POW_06), STDEX_INTMAX_C(1)> mega;
724 };
725
726 template<>
727 struct _ratio_predefined_impl<_10_pow_09_bit_n>:
728 _ratio_predefined_impl<_10_pow_06_bit_n>
729 {
730 typedef ratio<STDEX_INTMAX_C(1), static_cast<stdex::intmax_t>(_STDEX_10_POW_09)> nano;
731 typedef ratio<static_cast<stdex::intmax_t>(_STDEX_10_POW_09), STDEX_INTMAX_C(1)> giga;
732 };
733
734 template<>
735 struct _ratio_predefined_impl<_10_pow_12_bit_n>:
736 _ratio_predefined_impl<_10_pow_09_bit_n>
737 {
738 typedef ratio<STDEX_INTMAX_C(1), static_cast<stdex::intmax_t>(_STDEX_10_POW_12)> pico;
739 typedef ratio<static_cast<stdex::intmax_t>(_STDEX_10_POW_12), STDEX_INTMAX_C(1)> tera;
740 };
741
742 template<>
743 struct _ratio_predefined_impl<_10_pow_15_bit_n>:
744 _ratio_predefined_impl<_10_pow_12_bit_n>
745 {
746 typedef ratio<STDEX_INTMAX_C(1), static_cast<stdex::intmax_t>(_STDEX_10_POW_15)> femto;
747 typedef ratio<static_cast<stdex::intmax_t>(_STDEX_10_POW_15), STDEX_INTMAX_C(1)> peta;
748 };
749
750 template<>
751 struct _ratio_predefined_impl<_10_pow_18_bit_n>:
752 _ratio_predefined_impl<_10_pow_15_bit_n>
753 {
754 typedef ratio<STDEX_INTMAX_C(1), static_cast<stdex::intmax_t>(_STDEX_10_POW_18)> atto;
755 typedef ratio<static_cast<stdex::intmax_t>(_STDEX_10_POW_18), STDEX_INTMAX_C(1)> exa;
756 };
757
758 template<>
759 struct _ratio_predefined_impl<_10_pow_21_bit_n>:
760 _ratio_predefined_impl<_10_pow_18_bit_n>
761 {
762 typedef ratio<STDEX_INTMAX_C(1), static_cast<stdex::intmax_t>(_STDEX_10_POW_21)> zepto;
763 typedef ratio<static_cast<stdex::intmax_t>(_STDEX_10_POW_21), STDEX_INTMAX_C(1)> zetta;
764 };
765
766 template<>
767 struct _ratio_predefined_impl<_10_pow_24_bit_n>:
768 _ratio_predefined_impl<_10_pow_21_bit_n>
769 {
770 typedef ratio<STDEX_INTMAX_C(1), static_cast<stdex::intmax_t>(_STDEX_10_POW_24)> yocto;
771 typedef ratio<static_cast<stdex::intmax_t>(_STDEX_10_POW_24), STDEX_INTMAX_C(1)> yotta;
772 };
773
774 #undef _STDEX_10_POW
775 #undef _STDEX_INTMAX_BIT_COUNT
776 #undef _STDEX_10_POW_IMPL
777
778 #undef _STDEX_10_POW_01_IMPL
779 #undef _STDEX_10_POW_02_IMPL
780 #undef _STDEX_10_POW_03_IMPL
781 #undef _STDEX_10_POW_06_IMPL
782 #undef _STDEX_10_POW_09_IMPL
783 #undef _STDEX_10_POW_12_IMPL
784 #undef _STDEX_10_POW_15_IMPL
785 #undef _STDEX_10_POW_18_IMPL
786 #undef _STDEX_10_POW_21_IMPL
787 #undef _STDEX_10_POW_24_IMPL
788
789 #undef _STDEX_10_POW_01
790 #undef _STDEX_10_POW_02
791 #undef _STDEX_10_POW_03
792 #undef _STDEX_10_POW_06
793 #undef _STDEX_10_POW_09
794 #undef _STDEX_10_POW_12
795 #undef _STDEX_10_POW_15
796 #undef _STDEX_10_POW_18
797 #undef _STDEX_10_POW_21
798 #undef _STDEX_10_POW_24
799
800 struct _ratio_predefined:
801 _ratio_predefined_impl<(sizeof(stdex::intmax_t) * CHAR_BIT)>
802 { };
803 } // namespace detail
804
805 typedef detail::_ratio_predefined::yocto yocto;
806 typedef detail::_ratio_predefined::zepto zepto;
807 typedef detail::_ratio_predefined::atto atto;
808 typedef detail::_ratio_predefined::femto femto;
809 typedef detail::_ratio_predefined::pico pico;
810 typedef detail::_ratio_predefined::nano nano;
811 typedef detail::_ratio_predefined::micro micro;
812 typedef detail::_ratio_predefined::milli milli;
813 typedef detail::_ratio_predefined::centi centi;
814 typedef detail::_ratio_predefined::deci deci;
815 typedef detail::_ratio_predefined::deca deca;
816 typedef detail::_ratio_predefined::hecto hecto;
817 typedef detail::_ratio_predefined::kilo kilo;
818 typedef detail::_ratio_predefined::mega mega;
819 typedef detail::_ratio_predefined::giga giga;
820 typedef detail::_ratio_predefined::tera tera;
821 typedef detail::_ratio_predefined::peta peta;
822 typedef detail::_ratio_predefined::exa exa;
823 typedef detail::_ratio_predefined::zetta zetta;
824 typedef detail::_ratio_predefined::yotta yotta;
825
826} // namespace stdex
827
828#endif // _STDEX_RATIO_H