source: mainline/uspace/lib/cpp/include/__bits/ratio.hpp@ 205f1add

Last change on this file since 205f1add was b57a3ee, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: refactored the library layout, everything from the impl directory was moved to the bits directory for the sake of consistency, updated copyright notices and include guards

  • Property mode set to 100644
File size: 6.8 KB
Line 
1/*
2 * Copyright (c) 2018 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef LIBCPP_BITS_RATIO
30#define LIBCPP_BITS_RATIO
31
32#include <cstdint>
33#include <type_traits>
34
35namespace std
36{
37 namespace aux
38 {
39 template<intmax_t A, intmax_t B>
40 struct gcd
41 {
42 static constexpr intmax_t value = gcd<B, A % B>::value;
43 };
44
45 template<intmax_t A>
46 struct gcd<A, 0>
47 {
48 static constexpr intmax_t value = A;
49 };
50
51 template<intmax_t A, intmax_t B>
52 inline constexpr intmax_t gcd_v = gcd<A, B>::value;
53
54 template<intmax_t A>
55 struct abs
56 {
57 static constexpr intmax_t value = (A > 0 ? A : -A);
58 };
59
60 template<intmax_t A>
61 inline constexpr intmax_t abs_v = abs<A>::value;
62
63 template<intmax_t A>
64 struct sign
65 {
66 static constexpr intmax_t value = (A == 0 ? 0: (A > 0 ? 1 : -1));
67 };
68
69 template<intmax_t A>
70 inline constexpr intmax_t sign_v = sign<A>::value;
71
72 // Not used here, but in <chrono>, better to keep them together.
73 template<intmax_t A, intmax_t B>
74 struct lcm
75 {
76 static constexpr intmax_t value = abs_v<A * B> / gcd_v<A, B>;
77 };
78
79 template<intmax_t A, intmax_t B>
80 inline constexpr intmax_t lcm_v = lcm<A, B>::value;
81 }
82
83 /**
84 * 20.11.3, class template ratio:
85 */
86
87 template<intmax_t N, intmax_t D = 1>
88 class ratio
89 {
90 public:
91 static_assert(D != 0, "ratio with denominator == 0");
92
93 static constexpr intmax_t num = aux::sign_v<N> * aux::sign_v<D>
94 * aux::abs_v<N> / aux::gcd_v<N, D>;
95
96 static constexpr intmax_t den = aux::abs_v<D> / aux::gcd_v<N, D>;
97
98 using type = ratio<num, den>;
99 };
100
101 /**
102 * 20.11.4, ratio arithmetic:
103 */
104
105 template<class R1, class R2>
106 using ratio_add = typename ratio<
107 R1::num * R2::den + R2::num * R1::den,
108 R1::den * R2::den
109 >::type;
110
111 template<class R1, class R2>
112 using ratio_subtract = typename ratio<
113 R1::num * R2::den - R2::num * R1::den,
114 R1::den * R2::den
115 >::type;
116
117 template<class R1, class R2>
118 using ratio_multiply = typename ratio<
119 R1::num * R2::num,
120 R1::den * R2::den
121 >::type;
122
123 template<class R1, class R2>
124 using ratio_divide = typename ratio<
125 R1::num * R2::den,
126 R1::den * R2::num
127 >::type;
128
129 /**
130 * 20.11.5, ratio comparison:
131 */
132
133 template<class R1, class R2>
134 struct ratio_equal: integral_constant<
135 bool, (R1::num == R2::num) && (R1::den == R2::den)
136 >
137 { /* DUMMY BODY */ };
138
139 template<class R1, class R2>
140 inline constexpr bool ratio_equal_v = ratio_equal<R1, R2>::value;
141
142 template<class R1, class R2>
143 struct ratio_not_equal: integral_constant<bool, !ratio_equal<R1, R2>::value>
144 { /* DUMMY BODY */ };
145
146 template<class R1, class R2>
147 inline constexpr bool ratio_not_equal_v = ratio_not_equal<R1, R2>::value;
148
149 template<class R1, class R2>
150 struct ratio_less: integral_constant<
151 bool, R1::num * R2::den < R2::num * R1::den
152 >
153 { /* DUMMY BODY */ };
154
155 template<class R1, class R2>
156 inline constexpr bool ratio_less_v = ratio_less<R1, R2>::value;
157
158 template<class R1, class R2>
159 struct ratio_less_equal: integral_constant<bool, !ratio_less<R2, R1>::value>
160 { /* DUMMY BODY */ };
161
162 template<class R1, class R2>
163 inline constexpr bool ratio_less_equal_v = ratio_less_equal<R1, R2>::value;
164
165 template<class R1, class R2>
166 struct ratio_greater: integral_constant<bool, ratio_less<R2, R1>::value>
167 { /* DUMMY BODY */ };
168
169 template<class R1, class R2>
170 inline constexpr bool ratio_greater_v = ratio_greater<R1, R2>::value;
171
172 template<class R1, class R2>
173 struct ratio_greater_equal: integral_constant<bool, !ratio_less<R1, R2>::value>
174 { /* DUMMY BODY */ };
175
176 template<class R1, class R2>
177 inline constexpr bool ratio_greater_equal_v = ratio_greater_equal<R1, R2>::value;
178
179 /**
180 * 20.11.6, convenience SI typedefs:
181 */
182
183 // TODO: yocto/zepto and yotta/zetta should not be defined if intmax_t is too small
184
185 /* using yocto = ratio<1, 1'000'000'000'000'000'000'000'000>; */
186 /* using zepto = ratio<1, 1'000'000'000'000'000'000'000>; */
187 using atto = ratio<1, 1'000'000'000'000'000'000>;
188 using femto = ratio<1, 1'000'000'000'000'000>;
189 using pico = ratio<1, 1'000'000'000'000>;
190 using nano = ratio<1, 1'000'000'000>;
191 using micro = ratio<1, 1'000'000>;
192 using milli = ratio<1, 1'000>;
193 using centi = ratio<1, 100>;
194 using deci = ratio<1, 10>;
195 using deca = ratio< 10, 1>;
196 using hecto = ratio< 100, 1>;
197 using kilo = ratio< 1'000, 1>;
198 using mega = ratio< 1'000'000, 1>;
199 using giga = ratio< 1'000'000'000, 1>;
200 using tera = ratio< 1'000'000'000'000, 1>;
201 using peta = ratio< 1'000'000'000'000'000, 1>;
202 using exa = ratio< 1'000'000'000'000'000'000, 1>;
203 /* using zetta = ratio< 1'000'000'000'000'000'000'000, 1>; */
204 /* using yotta = ratio<1'000'000'000'000'000'000'000'000, 1>; */
205}
206
207#endif
Note: See TracBrowser for help on using the repository browser.