source: mainline/uspace/lib/cpp/include/impl/ratio.hpp@ 88e2c82

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 88e2c82 was 88e2c82, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: uncommented static_assert after fixing the s_a macro

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/*
2 * Copyright (c) 2017 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_RATIO
30#define LIBCPP_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 struct ratio_not_equal: integral_constant<bool, !ratio_equal<R1, R2>::value>
141 { /* DUMMY BODY */ };
142
143 template<class R1, class R2>
144 struct ratio_less: integral_constant<
145 bool, R1::num * R2::den < R2::num * R1::den
146 >
147 { /* DUMMY BODY */ };
148
149 template<class R1, class R2>
150 struct ratio_less_equal: integral_constant<bool, !ratio_less<R2, R1>::value>
151 { /* DUMMY BODY */ };
152
153 template<class R1, class R2>
154 struct ratio_greater: integral_constant<bool, ratio_less<R2, R1>::value>
155 { /* DUMMY BODY */ };
156
157 template<class R1, class R2>
158 struct ratio_greater_equal: integral_constant<bool, !ratio_less<R1, R2>::value>
159 { /* DUMMY BODY */ };
160
161 /**
162 * 20.11.6, convenience SI typedefs:
163 */
164
165 // TODO: yocto/zepto and yotta/zetta should not be defined if intmax_t is too small
166
167 /* using yocto = ratio<1, 1'000'000'000'000'000'000'000'000>; */
168 /* using zepto = ratio<1, 1'000'000'000'000'000'000'000>; */
169 using atto = ratio<1, 1'000'000'000'000'000'000>;
170 using femto = ratio<1, 1'000'000'000'000'000>;
171 using pico = ratio<1, 1'000'000'000'000>;
172 using nano = ratio<1, 1'000'000'000>;
173 using micro = ratio<1, 1'000'000>;
174 using milli = ratio<1, 1'000>;
175 using centi = ratio<1, 100>;
176 using deci = ratio<1, 10>;
177 using deca = ratio< 10, 1>;
178 using hecto = ratio< 100, 1>;
179 using kilo = ratio< 1'000, 1>;
180 using mega = ratio< 1'000'000, 1>;
181 using giga = ratio< 1'000'000'000, 1>;
182 using tera = ratio< 1'000'000'000'000, 1>;
183 using peta = ratio< 1'000'000'000'000'000, 1>;
184 using exa = ratio< 1'000'000'000'000'000'000, 1>;
185 /* using zetta = ratio< 1'000'000'000'000'000'000'000, 1>; */
186 /* using yotta = ratio<1'000'000'000'000'000'000'000'000, 1>; */
187}
188
189#endif
Note: See TracBrowser for help on using the repository browser.