Skip to content

Commit 952a02a

Browse files
authored
Merge pull request #21 from ion098/ostream-support
feat: ✨ Allow printing unnamed unit types
2 parents 0018b63 + 34a7f15 commit 952a02a

File tree

3 files changed

+78
-6
lines changed

3 files changed

+78
-6
lines changed

include/units/Angle.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,16 @@ class Angle : public Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::
1616
std::ratio<0>, std::ratio<0>>(value) {};
1717
};
1818

19+
template <> struct LookupName<Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>,
20+
std::ratio<0>, std::ratio<0>, std::ratio<0>>> {
21+
using Named = Angle;
22+
};
23+
24+
inline std::ostream& operator<<(std::ostream& os, const Angle& quantity) {
25+
os << quantity.internal() << " rad";
26+
return os;
27+
}
28+
1929
constexpr Angle rad = Angle(1.0);
2030
constexpr Angle deg = Angle(M_PI / 180);
2131
constexpr Angle rot = Angle(M_TWOPI);

include/units/Temperature.hpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,29 @@
22

33
#include "units/units.hpp"
44

5-
using Temperature = Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>,
6-
std::ratio<0>, std::ratio<0>>;
5+
class Temperature : public Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
6+
std::ratio<1>, std::ratio<0>, std::ratio<0>> {
7+
public:
8+
explicit constexpr Temperature(double value)
9+
: Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>,
10+
std::ratio<0>, std::ratio<0>>(value) {}
11+
12+
constexpr Temperature(Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
13+
std::ratio<1>, std::ratio<0>, std::ratio<0>>
14+
value)
15+
: Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>,
16+
std::ratio<0>, std::ratio<0>>(value) {};
17+
};
18+
19+
template <> struct LookupName<Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
20+
std::ratio<1>, std::ratio<0>, std::ratio<0>>> {
21+
using Named = Temperature;
22+
};
23+
24+
inline std::ostream& operator<<(std::ostream& os, const Temperature& quantity) {
25+
os << quantity.internal() << " k";
26+
return os;
27+
}
728

829
constexpr Temperature kelvin = Temperature(1.0);
930

include/units/units.hpp

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ template <typename Q> using Named = typename LookupName<Q>::Named;
121121
template <typename Mass = std::ratio<0>, typename Length = std::ratio<0>, typename Time = std::ratio<0>,
122122
typename Current = std::ratio<0>, typename Angle = std::ratio<0>, typename Temperature = std::ratio<0>,
123123
typename Luminosity = std::ratio<0>, typename Moles = std::ratio<0>>
124-
void quantityChecker(Quantity<Mass, Length, Time, Current, Angle, Temperature, Luminosity, Moles> q) {}
124+
void quantityChecker(Quantity<Mass, Length, Time, Current, Angle, Temperature, Luminosity, Moles>) {}
125125

126126
// isQuantity concept
127127
template <typename Q>
@@ -164,6 +164,47 @@ template <isQuantity Q, typename quotient> using Rooted = Named<
164164
std::ratio_divide<typename Q::angle, quotient>, std::ratio_divide<typename Q::temperature, quotient>,
165165
std::ratio_divide<typename Q::luminosity, quotient>, std::ratio_divide<typename Q::moles, quotient>>>;
166166

167+
template <isQuantity Q> inline std::ostream& operator<<(std::ostream& os, const Q& quantity) {
168+
if constexpr (!std::is_same_v<Named<Q>, Q>) {
169+
os << Named<Q>(quantity);
170+
} else {
171+
os << quantity.internal();
172+
if constexpr (Q::mass::num != 0) {
173+
os << " kg^" << Q::mass::num;
174+
if constexpr (Q::mass::den != 1) os << "/" << Q::mass::den;
175+
}
176+
if constexpr (Q::length::num != 0) {
177+
os << "*m^" << Q::length::num;
178+
if constexpr (Q::length::den != 1) os << "/" << Q::length::den;
179+
}
180+
if constexpr (Q::time::num != 0) {
181+
os << "*s^" << Q::time::num;
182+
if constexpr (Q::time::den != 1) os << "/" << Q::time::den;
183+
}
184+
if constexpr (Q::current::num != 0) {
185+
os << "*A^" << Q::current::num;
186+
if constexpr (Q::current::den != 1) os << "/" << Q::current::den;
187+
}
188+
if constexpr (Q::angle::num != 0) {
189+
os << "*rad^" << Q::angle::num;
190+
if constexpr (Q::angle::den != 1) os << "/" << Q::angle::den;
191+
}
192+
if constexpr (Q::temperature::num != 0) {
193+
os << "*K^" << Q::temperature::num;
194+
if constexpr (Q::temperature::den != 1) os << "/" << Q::temperature::den;
195+
}
196+
if constexpr (Q::luminosity::num != 0) {
197+
os << "*cd^" << Q::luminosity::num;
198+
if constexpr (Q::luminosity::den != 1) os << "/" << Q::luminosity::den;
199+
}
200+
if constexpr (Q::moles::num != 0) {
201+
os << "*mol^" << Q::moles::num;
202+
if constexpr (Q::moles::den != 1) os << "/" << Q::moles::den;
203+
}
204+
}
205+
return os;
206+
}
207+
167208
template <isQuantity Q, isQuantity R> constexpr Q operator+(Q lhs, R rhs)
168209
requires Isomorphic<Q, R>
169210
{
@@ -243,7 +284,7 @@ template <isQuantity Q, isQuantity R> constexpr bool operator>(const Q& lhs, con
243284
std::ratio<o>, std::ratio<j>, std::ratio<n>>> { \
244285
using Named = Name; \
245286
}; \
246-
constexpr Name suffix = Name(1.0); \
287+
[[maybe_unused]] constexpr Name suffix = Name(1.0); \
247288
constexpr Name operator""_##suffix(long double value) { \
248289
return Name(Quantity<std::ratio<m>, std::ratio<l>, std::ratio<t>, std::ratio<i>, std::ratio<a>, std::ratio<o>, \
249290
std::ratio<j>, std::ratio<n>>(static_cast<double>(value))); \
@@ -253,14 +294,14 @@ template <isQuantity Q, isQuantity R> constexpr bool operator>(const Q& lhs, con
253294
std::ratio<j>, std::ratio<n>>(static_cast<double>(value))); \
254295
} \
255296
inline std::ostream& operator<<(std::ostream& os, const Name& quantity) { \
256-
os << quantity.internal() << "_" << #suffix; \
297+
os << quantity.internal() << " " << #suffix; \
257298
return os; \
258299
} \
259300
constexpr inline Name from_##suffix(double value) { return Name(value); } \
260301
constexpr inline double to_##suffix(Name quantity) { return quantity.internal(); }
261302

262303
#define NEW_UNIT_LITERAL(Name, suffix, multiple) \
263-
constexpr Name suffix = multiple; \
304+
[[maybe_unused]] constexpr Name suffix = multiple; \
264305
constexpr Name operator""_##suffix(long double value) { return static_cast<double>(value) * multiple; } \
265306
constexpr Name operator""_##suffix(unsigned long long value) { return static_cast<double>(value) * multiple; } \
266307
constexpr inline Name from_##suffix(double value) { return value * multiple; } \

0 commit comments

Comments
 (0)