Quantify
An extensible C++ units library
Loading...
Searching...
No Matches
preface.cppm
Go to the documentation of this file.
1// Copyright (c) 2024-2025, Víctor Castillo Agüero.
2// SPDX-License-Identifier: Apache-2.0
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16module;
18
19export module quantify.core:preface;
20import std;
21import packtl;
22export import :ratio;
23
24namespace quantify {
25 export struct no_scale {};
26 export struct no_unit {
27 using scale = no_scale;
28 using reduce = no_unit;
29
30 template <typename T>
32
33 UNIT_SYMBOL("(no unit)")
34 };
35
36 export template <typename U_FROM, typename U_TO, typename T>
38
39 export template <typename S_FROM, typename S_TO>
41
42 export {
43 template <typename Expr>
44 struct reduce_impl {
45 using type = Expr;
46 };
47
48 template <typename Expr>
50
51 template <typename Scale>
52 struct reduce_scale {
53 using type = Scale;
54 };
55
56 template <typename Scale>
57 requires requires {
59 }
60 struct reduce_scale<Scale> {
62 };
63
64 }
65
66 export {
67 template <typename...>
68 struct mul;
69
70 template <typename N, typename D>
71 struct frac;
72
73 template <typename...>
74 struct is_mul: std::false_type {};
75
76 template <typename... Args>
77 struct is_mul<mul<Args...>>: std::true_type {};
78
79 template <typename M>
80 constexpr bool is_mul_v = is_mul<M>::value;
81
82 template <typename...>
83 struct is_frac: std::false_type {};
84
85 template <typename... Args>
86 struct is_frac<frac<Args...>>: std::true_type {};
87
88 template <typename F>
89 constexpr bool is_frac_v = is_frac<F>::value;
90
98 template <typename S>
99 concept has_scale = requires { typename S::scale; };
100
102 template <typename S>
103 constexpr bool has_scale_v = has_scale<S>;
104
106 template <typename Mul, typename CancelProduct>
107 using cancel_out = typename packtl::take_one_out<CancelProduct, Mul>::type;
108
109 template <typename...>
110 struct cancel_out_many {};
111
112 template <typename Mul, typename CP>
113 struct cancel_out_many<Mul, CP> {
114 using type = cancel_out<Mul, CP>;
115 };
116
117 template <typename Mul, typename CP1, typename... CancelProducts>
118 struct cancel_out_many<Mul, CP1, CancelProducts...> {
119 private:
120 using cancelled = typename packtl::take_one_out<CP1, Mul>::type;
121 using cancelled_many = std::conditional_t<
122 (sizeof...(CancelProducts) > 1),
123 cancel_out_many<cancelled, CancelProducts...>,
124 packtl::take_one_out<typename packtl::get_first<CancelProducts...>::type, cancelled>>;
125
126 using result = std::
127 conditional_t<sizeof...(CancelProducts) == 0, cancelled, typename cancelled_many::type>;
128
129 public:
130 using type = result;
131 };
132
133 template <typename Mul, template <typename...> typename Pack, typename... CancelProducts>
134 struct cancel_out_many<Mul, Pack<CancelProducts...>> {
135 using type = typename cancel_out_many<Mul, CancelProducts...>::type;
136 };
137
138 template <typename M>
139 struct normalize {
140 using type = M;
141 };
142
143 template <typename M>
144 using normalize_t = typename normalize<M>::type;
145
146
147 template <typename M, typename...>
148 struct normalize_impl {
149 using type = M;
150 };
151
152 template <typename M>
153 using normalize_impl_t = typename normalize_impl<M>::type;
154
155 template <typename Num, typename Den, typename... Ps>
156 struct normalize_impl<mul<frac<Num, Den>, Ps...>> {
157 using type = frac<normalize_t<mul<Ps..., Num>>, Den>;
158 };
159
160 template <typename P1, typename... Ps>
161 requires(!is_frac_v<P1> && (is_frac_v<Ps> || ...))
162 struct normalize_impl<mul<P1, Ps...>> {
163 using type = normalize_impl_t<mul<Ps..., P1>>;
164 };
165
166
167 template <typename... Ps>
168 struct normalize<mul<Ps...>> {
169 using type = normalize_impl_t<typename packtl::flatten<mul<Ps...>>::type>;
170 };
172 }
173} // namespace quantify
Predicate that checks if a type defines a scale for itself.
Definition preface.cppm:99
#define UNIT_SYMBOL(...)
Definition unit_macros.h:18
Core components of the Quantify library.
constexpr bool is_mul_v
Definition preface.cppm:80
constexpr bool is_frac_v
Definition preface.cppm:89
typename reduce_impl< Expr >::type reduce
Definition preface.cppm:49
constexpr bool has_scale_v
See has_scale.
Definition preface.cppm:103
ratio< T, 1, 1 > factor
Definition preface.cppm:31
Static representation of a numerical ratio in the form of a fraction.
Definition ratio.cppm:26