Quantify
An extensible C++ units library
Loading...
Searching...
No Matches
unit_macros.h
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
18
#define UNIT_SYMBOL(...) \
19
static constexpr inline std::string symbol() noexcept { \
20
return (__VA_ARGS__); \
21
}
22
23
#define SCALE(NAME) \
24
namespace NAME { \
25
struct scale { \
26
UNIT_SYMBOL(#NAME) \
27
}; \
28
template <typename Q> \
29
concept quantity = quantify::Quantity<Q, scale>; \
30
} \
31
namespace NAME
32
33
#define DERIVED_SCALE(NAME, ...) \
34
namespace NAME { \
35
using scale = typename reduce_scale<__VA_ARGS__>::type; \
36
template <typename Q> \
37
concept quantity = quantify::Quantity<Q, scale>; \
38
} \
39
namespace NAME
40
41
#define UNIT(NAME, SYMBOL, FACTOR_NUM, FACTOR_DEN) \
42
struct NAME { \
43
using scale = scale; \
44
template <typename T> \
45
using factor = quantify::ratio<T, FACTOR_NUM, FACTOR_DEN>; \
46
using reduce = NAME; \
47
UNIT_SYMBOL(SYMBOL) \
48
}
49
50
#define UNIT_IN_SCALE(SCALE, NAME, SYMBOL, FACTOR_NUM, FACTOR_DEN) \
51
struct NAME { \
52
using scale = SCALE; \
53
template <typename T> \
54
using factor = quantify::ratio<T, FACTOR_NUM, FACTOR_DEN>; \
55
using reduce = NAME; \
56
UNIT_SYMBOL(SYMBOL) \
57
}
58
59
#define METRIC_UNIT(UNIT_NAME, SYMBOL, FACTOR_NUM, FACTOR_DEN) \
60
UNIT(nano##UNIT_NAME, "n" SYMBOL, 1UL * (FACTOR_NUM), 1000000000UL * (FACTOR_DEN)); \
61
UNIT(micro##UNIT_NAME, "u" SYMBOL, 1UL * (FACTOR_NUM), 1000000UL * (FACTOR_DEN)); \
62
UNIT(milli##UNIT_NAME, "m" SYMBOL, 1UL * (FACTOR_NUM), 1000UL * (FACTOR_DEN)); \
63
UNIT(centi##UNIT_NAME, "c" SYMBOL, 1UL * (FACTOR_NUM), 100UL * (FACTOR_DEN)); \
64
UNIT(deci##UNIT_NAME, "d" SYMBOL, 1UL * (FACTOR_NUM), 10UL * (FACTOR_DEN)); \
65
UNIT(UNIT_NAME, SYMBOL, 1UL * (FACTOR_NUM), 1UL * (FACTOR_DEN)); \
66
UNIT(deca##UNIT_NAME, "D" SYMBOL, 10UL * (FACTOR_NUM), 1UL * (FACTOR_DEN)); \
67
UNIT(hecto##UNIT_NAME, "h" SYMBOL, 100UL * (FACTOR_NUM), 1UL * (FACTOR_DEN)); \
68
UNIT(kilo##UNIT_NAME, "k" SYMBOL, 1000UL * (FACTOR_NUM), 1UL * (FACTOR_DEN)); \
69
UNIT(mega##UNIT_NAME, "M" SYMBOL, 1000000UL * (FACTOR_NUM), 1UL * (FACTOR_DEN))
70
71
72
#define SCALE_CONVERSION(FROM, TO) \
73
template <> \
74
struct quantify::scale_conversion_t<FROM, TO> { \
75
using from_scale = FROM; \
76
using to_scale = TO;
77
78
#define SCALE_FORWARD_CONVERSION(...) \
79
template <typename U_FROM, typename U_TO, typename T> \
80
requires quantify::CompareScales<from_scale, typename U_FROM::scale> && \
81
quantify::CompareScales<to_scale, typename U_TO::scale> \
82
static quantity<U_TO, T> forward(const quantity<U_FROM, T>& _quantity) { \
83
quantity<U_TO, T> result{ \
84
_quantity.value * U_FROM::template factor<T>::numerator / \
85
U_FROM::template factor<T>::denominator \
86
}; \
87
auto it = result.value; \
88
result.value = __VA_ARGS__; \
89
result.value = \
90
result.value * U_TO::template factor<T>::denominator / U_TO::template factor<T>::numerator; \
91
return result; \
92
}
93
94
#define SCALE_BACKWARD_CONVERSION(...) \
95
template <typename U_FROM, typename U_TO, typename T> \
96
requires quantify::CompareScales<to_scale, typename U_FROM::scale> && \
97
quantify::CompareScales<from_scale, typename U_TO::scale> \
98
static quantity<U_TO, T> backward(const quantity<U_FROM, T>& _quantity) { \
99
quantity<U_TO, T> result{ \
100
_quantity.value * U_FROM::template factor<T>::numerator / \
101
U_FROM::template factor<T>::denominator \
102
}; \
103
auto it = result.value; \
104
result.value = __VA_ARGS__; \
105
result.value = \
106
result.value * U_TO::template factor<T>::denominator / U_TO::template factor<T>::numerator; \
107
return result; \
108
} \
109
} \
110
;
111
include
quantify
unit_macros.h
Generated by
1.13.2