source: mainline/uspace/lib/cpp/include/__bits/ratio.hpp@ 34b2f54d

Last change on this file since 34b2f54d was b57ba05, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 3 years ago

Update headers in C++ files

  • Property mode set to 100644
File size: 5.5 KB
Line 
1/*
2 * SPDX-FileCopyrightText: 2018 Jaroslav Jindrak
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef LIBCPP_BITS_RATIO
8#define LIBCPP_BITS_RATIO
9
10#include <cstdint>
11#include <type_traits>
12
13namespace std
14{
15 namespace aux
16 {
17 template<intmax_t A, intmax_t B>
18 struct gcd
19 {
20 static constexpr intmax_t value = gcd<B, A % B>::value;
21 };
22
23 template<intmax_t A>
24 struct gcd<A, 0>
25 {
26 static constexpr intmax_t value = A;
27 };
28
29 template<intmax_t A, intmax_t B>
30 inline constexpr intmax_t gcd_v = gcd<A, B>::value;
31
32 template<intmax_t A>
33 struct abs
34 {
35 static constexpr intmax_t value = (A > 0 ? A : -A);
36 };
37
38 template<intmax_t A>
39 inline constexpr intmax_t abs_v = abs<A>::value;
40
41 template<intmax_t A>
42 struct sign
43 {
44 static constexpr intmax_t value = (A == 0 ? 0: (A > 0 ? 1 : -1));
45 };
46
47 template<intmax_t A>
48 inline constexpr intmax_t sign_v = sign<A>::value;
49
50 // Not used here, but in <chrono>, better to keep them together.
51 template<intmax_t A, intmax_t B>
52 struct lcm
53 {
54 static constexpr intmax_t value = abs_v<A * B> / gcd_v<A, B>;
55 };
56
57 template<intmax_t A, intmax_t B>
58 inline constexpr intmax_t lcm_v = lcm<A, B>::value;
59 }
60
61 /**
62 * 20.11.3, class template ratio:
63 */
64
65 template<intmax_t N, intmax_t D = 1>
66 class ratio
67 {
68 public:
69 static_assert(D != 0, "ratio with denominator == 0");
70
71 static constexpr intmax_t num = aux::sign_v<N> * aux::sign_v<D>
72 * aux::abs_v<N> / aux::gcd_v<N, D>;
73
74 static constexpr intmax_t den = aux::abs_v<D> / aux::gcd_v<N, D>;
75
76 using type = ratio<num, den>;
77 };
78
79 /**
80 * 20.11.4, ratio arithmetic:
81 */
82
83 template<class R1, class R2>
84 using ratio_add = typename ratio<
85 R1::num * R2::den + R2::num * R1::den,
86 R1::den * R2::den
87 >::type;
88
89 template<class R1, class R2>
90 using ratio_subtract = typename ratio<
91 R1::num * R2::den - R2::num * R1::den,
92 R1::den * R2::den
93 >::type;
94
95 template<class R1, class R2>
96 using ratio_multiply = typename ratio<
97 R1::num * R2::num,
98 R1::den * R2::den
99 >::type;
100
101 template<class R1, class R2>
102 using ratio_divide = typename ratio<
103 R1::num * R2::den,
104 R1::den * R2::num
105 >::type;
106
107 /**
108 * 20.11.5, ratio comparison:
109 */
110
111 template<class R1, class R2>
112 struct ratio_equal: integral_constant<
113 bool, (R1::num == R2::num) && (R1::den == R2::den)
114 >
115 { /* DUMMY BODY */ };
116
117 template<class R1, class R2>
118 inline constexpr bool ratio_equal_v = ratio_equal<R1, R2>::value;
119
120 template<class R1, class R2>
121 struct ratio_not_equal: integral_constant<bool, !ratio_equal<R1, R2>::value>
122 { /* DUMMY BODY */ };
123
124 template<class R1, class R2>
125 inline constexpr bool ratio_not_equal_v = ratio_not_equal<R1, R2>::value;
126
127 template<class R1, class R2>
128 struct ratio_less: integral_constant<
129 bool, R1::num * R2::den < R2::num * R1::den
130 >
131 { /* DUMMY BODY */ };
132
133 template<class R1, class R2>
134 inline constexpr bool ratio_less_v = ratio_less<R1, R2>::value;
135
136 template<class R1, class R2>
137 struct ratio_less_equal: integral_constant<bool, !ratio_less<R2, R1>::value>
138 { /* DUMMY BODY */ };
139
140 template<class R1, class R2>
141 inline constexpr bool ratio_less_equal_v = ratio_less_equal<R1, R2>::value;
142
143 template<class R1, class R2>
144 struct ratio_greater: integral_constant<bool, ratio_less<R2, R1>::value>
145 { /* DUMMY BODY */ };
146
147 template<class R1, class R2>
148 inline constexpr bool ratio_greater_v = ratio_greater<R1, R2>::value;
149
150 template<class R1, class R2>
151 struct ratio_greater_equal: integral_constant<bool, !ratio_less<R1, R2>::value>
152 { /* DUMMY BODY */ };
153
154 template<class R1, class R2>
155 inline constexpr bool ratio_greater_equal_v = ratio_greater_equal<R1, R2>::value;
156
157 /**
158 * 20.11.6, convenience SI typedefs:
159 */
160
161 // TODO: yocto/zepto and yotta/zetta should not be defined if intmax_t is too small
162
163 /* using yocto = ratio<1, 1'000'000'000'000'000'000'000'000>; */
164 /* using zepto = ratio<1, 1'000'000'000'000'000'000'000>; */
165 using atto = ratio<1, 1'000'000'000'000'000'000>;
166 using femto = ratio<1, 1'000'000'000'000'000>;
167 using pico = ratio<1, 1'000'000'000'000>;
168 using nano = ratio<1, 1'000'000'000>;
169 using micro = ratio<1, 1'000'000>;
170 using milli = ratio<1, 1'000>;
171 using centi = ratio<1, 100>;
172 using deci = ratio<1, 10>;
173 using deca = ratio< 10, 1>;
174 using hecto = ratio< 100, 1>;
175 using kilo = ratio< 1'000, 1>;
176 using mega = ratio< 1'000'000, 1>;
177 using giga = ratio< 1'000'000'000, 1>;
178 using tera = ratio< 1'000'000'000'000, 1>;
179 using peta = ratio< 1'000'000'000'000'000, 1>;
180 using exa = ratio< 1'000'000'000'000'000'000, 1>;
181 /* using zetta = ratio< 1'000'000'000'000'000'000'000, 1>; */
182 /* using yotta = ratio<1'000'000'000'000'000'000'000'000, 1>; */
183}
184
185#endif
Note: See TracBrowser for help on using the repository browser.