TypeSI
Units of 'Système international' Blended for C++
Loading...
Searching...
No Matches
si_internal.hpp
Go to the documentation of this file.
1#pragma once
4#include <ratio>
5#include <utility>
6namespace Si {
8namespace Internal {
9#ifdef TYPE_SI_DISABLE_CHECKS
15template <typename T, typename... Powers> using Unit = T;
16#else
22template <typename T, typename... Powers> class Unit {
23 T _value;
24
25public:
27 explicit Unit(const T &value = T()) : _value(value) {}
30 template <typename AnotherT>
32 : _value(static_cast<AnotherT>(unit)) {}
35 template <typename AnotherT> explicit operator AnotherT() const {
36 return static_cast<AnotherT>(_value);
37 }
39 T operator+() const { return _value; }
41 template <typename AnotherT>
42 decltype(std::declval<T>() == std::declval<AnotherT>())
43 operator==(const Unit<AnotherT, Powers...> &unit) const {
44 return _value == static_cast<AnotherT>(unit);
45 }
47 template <typename AnotherT>
48 decltype(std::declval<T>() != std::declval<AnotherT>())
49 operator!=(const Unit<AnotherT, Powers...> &unit) const {
50 return _value != static_cast<AnotherT>(unit);
51 }
53 template <typename AnotherT>
54 decltype(std::declval<T>() < std::declval<AnotherT>())
55 operator<(const Unit<AnotherT, Powers...> &unit) const {
56 return _value < static_cast<AnotherT>(unit);
57 }
59 template <typename AnotherT>
60 decltype(std::declval<T>() <= std::declval<AnotherT>())
61 operator<=(const Unit<AnotherT, Powers...> &unit) const {
62 return _value <= static_cast<AnotherT>(unit);
63 }
65 template <typename AnotherT>
66 decltype(std::declval<T>() > std::declval<AnotherT>())
67 operator>(const Unit<AnotherT, Powers...> &unit) const {
68 return _value > static_cast<AnotherT>(unit);
69 }
71 template <typename AnotherT>
72 decltype(std::declval<T>() >= std::declval<AnotherT>())
73 operator>=(const Unit<AnotherT, Powers...> &unit) const {
74 return _value >= static_cast<AnotherT>(unit);
75 }
77 template <typename AnotherT>
78 Unit<decltype(std::declval<T>() + std::declval<AnotherT>()), Powers...>
79 operator+(const Unit<AnotherT, Powers...> &unit) const {
80 return Unit<decltype(std::declval<T>() + std::declval<AnotherT>()),
81 Powers...>(_value + static_cast<AnotherT>(unit));
82 }
85 ++_value;
86 return *this;
87 }
89 Unit operator++(int) { return Unit(_value++); }
91 template <typename AnotherT>
93 _value += static_cast<AnotherT>(unit);
94 return *this;
95 }
97 template <typename AnotherT>
98 Unit<decltype(std::declval<T>() - std::declval<AnotherT>()), Powers...>
99 operator-(const Unit<AnotherT, Powers...> &unit) const {
100 return Unit<decltype(std::declval<T>() - std::declval<AnotherT>()),
101 Powers...>(_value - static_cast<AnotherT>(unit));
102 }
104 template <typename AnotherT>
106 _value -= static_cast<AnotherT>(unit);
107 return *this;
108 }
111 --_value;
112 return *this;
113 }
115 Unit operator--(int) { return Unit(_value--); }
117 Unit<decltype(std::declval<T>() * std::declval<T>()), Powers...>
118 operator*(const T &value) const {
119 return Unit<decltype(std::declval<T>() * std::declval<T>()), Powers...>(
120 _value * value);
121 }
123 Unit<decltype(std::declval<T>() / std::declval<T>()), Powers...>
124 operator/(const T &value) const {
125 return Unit<decltype(std::declval<T>() / std::declval<T>()), Powers...>(
126 _value / value);
127 }
129 Unit &operator*=(const T &value) {
130 _value *= value;
131 return *this;
132 }
134 Unit &operator/=(const T &value) {
135 _value /= value;
136 return *this;
137 }
139 template <typename AnotherT, typename... OtherPowers>
140 Unit<decltype(std::declval<T>() * std::declval<AnotherT>()),
141 std::ratio_add<Powers, OtherPowers>...>
142 operator*(const Unit<AnotherT, OtherPowers...> &unit) const {
143 return Unit<decltype(std::declval<T>() * std::declval<AnotherT>()),
144 std::ratio_add<Powers, OtherPowers>...>(
145 _value * static_cast<AnotherT>(unit));
146 }
148 template <typename AnotherT, typename... OtherPowers>
149 Unit<decltype(std::declval<T>() / std::declval<AnotherT>()),
150 std::ratio_subtract<Powers, OtherPowers>...>
151 operator/(const Unit<AnotherT, OtherPowers...> &unit) const {
152 return Unit<decltype(std::declval<T>() / std::declval<AnotherT>()),
153 std::ratio_subtract<Powers, OtherPowers>...>(
154 _value / static_cast<AnotherT>(unit));
155 }
156};
157#endif
159template <typename... Elements> struct Tuple {};
161template <typename T, typename... Powers>
165template <typename U> using Powers = decltype(getPowers(std::declval<U>()));
170template <typename T>
172 Unit<T, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
173 std::ratio<0>, std::ratio<0>, std::ratio<0>>;
174} // namespace Internal
175} // namespace Si
Generic unit type.
Definition: si_internal.hpp:22
Unit & operator/=(const T &value)
Operator '/=' for dimensionless operand of container type.
Definition: si_internal.hpp:134
Unit operator--(int)
Postfix decrement.
Definition: si_internal.hpp:115
Unit & operator-=(const Unit< AnotherT, Powers... > &unit)
Operator '-=' for units with same power values.
Definition: si_internal.hpp:105
T operator+() const
Conversion to container type via unary '+'.
Definition: si_internal.hpp:39
Unit(const Unit< AnotherT, Powers... > &unit)
Implicit constructor from units with same power values but different container type.
Definition: si_internal.hpp:31
Unit operator++(int)
Postfix increment.
Definition: si_internal.hpp:89
Unit & operator*=(const T &value)
Operator '*=' for dimensionless operand of container type.
Definition: si_internal.hpp:129
Unit(const T &value=T())
Explicit constructor from container type.
Definition: si_internal.hpp:27
Unit & operator--()
Prefix decrement.
Definition: si_internal.hpp:110
Unit & operator++()
Prefix increment.
Definition: si_internal.hpp:84
Unit & operator+=(const Unit< AnotherT, Powers... > &unit)
Operator '+=' for units with same power values.
Definition: si_internal.hpp:92
decltype(getPowers(std::declval< U >())) Powers
Tool to get tuple of powers from unit.
Definition: si_internal.hpp:165
Tuple< Powers... > getPowers(Unit< T, Powers... >)
Helper to get tuple of powers from unit.
Definition: si_internal.hpp:162
Metastructure to identify and compare typename sets.
Definition: si_internal.hpp:159