14#ifdef SI_DISABLE_IMPLICIT_RATIO_CONVERSION
15#define SI_ENABLE_IMPLICIT_RATIO_CONVERSION false
17#define SI_ENABLE_IMPLICIT_RATIO_CONVERSION true
30template <
typename _unit_lhs,
typename _unit_rhs>
struct unit_with_common_ratio;
49template <
char _symbol,
typename _exponent,
typename _type,
50 typename _ratio = std::ratio<1>>
52 static_assert(std::is_arithmetic_v<_type>,
"Type is an arithmetic value");
53 static_assert(detail::is_ratio_v<_exponent>,
"_exponent is a ratio type");
54 static_assert(detail::is_ratio_v<_ratio>,
"_ratio is a std::ratio");
58 using symbol = std::integral_constant<char, _symbol>;
67 template <
typename _type_rhs>
70 static_assert(std::is_convertible<_type_rhs, _type>::value,
71 "Internal representation is convertible");
76 template <
typename _rhs_type,
typename _rhs_ratio>
80 static_assert(detail::is_ratio_v<_rhs_ratio>,
"_rhs_ratio is a std::ratio");
83 std::ratio_equal_v<ratio, _rhs_ratio>,
84 "Implicit ratio conversion disabled, convert before assigning");
87 template <
typename _rhs_ratio>
92 static_assert(detail::is_ratio_v<_rhs_ratio>,
"_rhs_ratio is a std::ratio");
95 std::ratio_equal_v<ratio, _rhs_ratio>,
96 "Implicit ratio conversion disabled, convert before assigning");
106 static_assert(std::ratio_equal_v<typename _unit_rhs::exponent, _exponent>,
107 "Exponents must match");
108 static_assert(_unit_rhs::symbol::value ==
_symbol,
109 "target unit must be of the same type must match");
116 template <
template <
typename _type_rhs>
typename _unit_rhs>
119 "only supported for SI::unit_t");
121 std::ratio_equal_v<typename _unit_rhs<_type>::exponent,
_exponent>,
122 "Exponents must match");
124 "target unit must be of the same type must match");
141 std::enable_if_t<!std::ratio_equal_v<_rhs_ratio, _ratio>> * =
nullptr>
145 static_assert(detail::is_ratio_v<_rhs_ratio>,
"_rhs_ratio is a std::ratio");
148 std::ratio_equal_v<ratio, _rhs_ratio>,
149 "Implicit ratio conversion disabled, convert before assigning");
158 std::enable_if_t<!std::ratio_equal_v<_rhs_ratio, _ratio>> * =
nullptr>
162 static_assert(detail::is_ratio_v<_rhs_ratio>,
"_rhs_ratio is a std::ratio");
165 std::ratio_equal_v<ratio, _rhs_ratio>,
166 "Implicit ratio conversion disabled, convert before assigning");
175 template <
typename _rhs_type,
typename _rhs_ratio>
181 std::ratio_equal_v<ratio, _rhs_ratio>,
182 "Implicit ratio conversion disabled, convert before comparing");
184 static_assert(detail::is_ratio_v<_rhs_ratio>,
"_rhs_ratio is a std::ratio");
185 static_assert(std::is_integral_v<_type> || std::is_floating_point_v<_type>,
186 "Is integral or floating point");
188 typename std::remove_reference<
decltype(
rhs)>::type,
189 typename std::remove_reference<
decltype(*
this)>::type>::type;
191 if constexpr (std::is_integral_v<_type>) {
202 template <
typename _rhs_type,
typename _rhs_ratio>
205 static_assert(detail::is_ratio_v<_rhs_ratio>,
"_rhs_ratio is a std::ratio");
206 return !(*
this ==
rhs);
209 template <
typename _rhs_type,
typename _rhs_ratio>
212 static_assert(detail::is_ratio_v<_rhs_ratio>,
"_rhs_ratio is a std::ratio");
215 std::ratio_equal_v<ratio, _rhs_ratio>,
216 "Implicit ratio conversion disabled, convert before comparing");
219 typename std::remove_reference<
decltype(
rhs)>::type,
220 typename std::remove_reference<
decltype(*
this)>::type>::type;
225 template <
typename _rhs_type,
typename _rhs_ratio>
228 return !(*
this >
rhs);
231 template <
typename _rhs_type,
typename _rhs_ratio>
234 static_assert(detail::is_ratio_v<_rhs_ratio>,
"_rhs_ratio is a std::ratio");
237 std::ratio_equal_v<ratio, _rhs_ratio>,
238 "Implicit ratio conversion disabled, convert before comparing");
241 typename std::remove_reference<
decltype(
rhs)>::type,
242 typename std::remove_reference<
decltype(*
this)>::type>::type;
248 template <
typename _rhs_type,
typename _rhs_ratio>
251 return !(*
this <
rhs);
258 template <
typename _rhs_exponent,
typename _rhs_type>
262 static_assert(detail::is_ratio_v<_rhs_exponent>,
263 "rhs exponent is a ratio type");
265 std::ratio_multiply<ratio, _ratio>>{
value() *
rhs.value()};
272 template <
typename _rhs_exponent,
typename _rhs_ratio,
typename _rhs_type>
275 static_assert(detail::is_ratio_v<_rhs_exponent>,
276 "rhs exponent is a ratio type");
277 static_assert(detail::is_ratio_v<_rhs_ratio>,
"_rhs_ratio is a std::ratio");
281 std::ratio_equal_v<ratio, _rhs_ratio>,
282 "Implicit ratio conversion disabled, convert before comparing");
285 std::ratio_multiply<ratio, _rhs_ratio>>{value_ *
rhs.value()};
300 std::enable_if_t<std::ratio_not_equal_v<_rhs_exponent, _exponent>>
304 static_assert(detail::is_ratio_v<_rhs_exponent>,
305 "rhs exponent is a ratio type");
306 using rhs_t =
typename std::remove_reference<
decltype(
rhs)>::type;
309 std::ratio_subtract<_exponent, typename rhs_t::exponent>,
310 _type, std::ratio_divide<ratio, _ratio>>{value_ /
318 std::enable_if_t<std::ratio_not_equal_v<_rhs_exponent, _exponent>>
322 static_assert(detail::is_ratio_v<_rhs_ratio>,
"_rhs_ratio is a std::ratio");
323 static_assert(detail::is_ratio_v<_rhs_exponent>,
324 "rhs exponent is a ratio type");
327 std::ratio_equal_v<ratio, _rhs_ratio>,
328 "Implicit ratio conversion disabled, convert before dividing");
331 std::ratio_divide<ratio, _rhs_ratio>>{value_ /
rhs.value()};
335 template <
typename _rhs_type>
345 std::enable_if_t<std::ratio_equal_v<_rhs_exponent, exponent>> * =
nullptr>
349 std::ratio_equal_v<_rhs_ratio, _ratio>,
350 "Implicit ratio conversion disabled, convert to same ratio "
353 static_assert(detail::is_ratio_v<_rhs_ratio>,
"_rhs_ratio is a std::ratio");
355 static_assert(detail::is_ratio_v<_rhs_exponent>,
356 "rhs exponent is a ratio type");
359 typename std::remove_reference<
decltype(*this)>::type,
360 typename std::remove_reference<
decltype(
rhs)>::type>::type;
372 template <
typename _rhs_type,
typename _rhs_ratio>
376 static_assert(detail::is_ratio_v<_rhs_ratio>,
"_rhs_ratio is a std::ratio");
379 std::ratio_equal_v<ratio, _rhs_ratio>,
380 "Implicit ratio conversion disabled, convert before adding values");
389 value_ +=
rhs.value();
396 std::enable_if_t<!std::ratio_equal_v<_rhs_ratio, _ratio>> * =
nullptr>
400 static_assert(detail::is_ratio_v<_rhs_ratio>,
"_rhs_ratio is a std::ratio");
403 std::ratio_equal_v<ratio, _rhs_ratio>,
404 "Implicit ratio conversion disabled, convert before adding values");
412 template <
typename _rhs_type,
typename _rhs_ratio>
416 static_assert(detail::is_ratio_v<_rhs_ratio>,
"_rhs_ratio is a std::ratio");
419 std::ratio_equal_v<ratio, _rhs_ratio>,
420 "Implicit ratio conversion disabled, convert before subtracting");
429 value_ -=
rhs.value();
435 std::enable_if<!std::ratio_equal_v<_rhs_ratio, _ratio>> * =
nullptr>
439 static_assert(detail::is_ratio_v<_rhs_ratio>,
"_rhs_ratio is a std::ratio");
442 std::ratio_equal_v<ratio, _rhs_ratio>,
443 "Implicit ratio conversion disabled, convert before adding values");
487template <
typename _type,
char _symbol,
typename _exponent,
typename _rhs_type,
489 std::enable_if_t<std::is_integral_v<_type>> * =
nullptr>
494 std::ratio_equal<std::ratio<1>, _ratio>::value,
495 "Implicit ratio conversion disabled, convert to ratio<1> "
497 static_assert(detail::is_ratio_v<_exponent>,
"Exponent is a ratio type");
498 return unit_t<_symbol, std::ratio_multiply<std::ratio<-1>, _exponent>, _type,
499 _ratio>{lhs / rhs.
value()};
506template <
typename _type,
char _symbol,
typename _exponent,
typename _rhs_type,
508 std::enable_if_t<std::is_floating_point_v<_type>> * =
nullptr>
511 const unit_t<_symbol, _exponent, _rhs_type, _ratio> &rhs) {
513 std::ratio_equal_v<_ratio, std::ratio<1>>,
514 "Implicit ratio conversion disabled, convert to ratio<1> "
516 static_assert(detail::is_ratio_v<_exponent>,
"Exponent is a ratio type");
517 return unit_t<_symbol, std::ratio_multiply<std::ratio<-1>, _exponent>, _type,
518 _ratio>{lhs / rhs.value()};
Namespace containing implementation details for SI.
Definition acceleration.h:34
constexpr auto unit_cast(const _rhs_T &rhs)
function to cast between two units of the same type
Definition unit_cast.h:22
constexpr bool eps_equals(const T &lhs, const T &rhs)
Definition eps_equal.h:22
constexpr auto operator/(const _type &lhs, const unit_t< _symbol, _exponent, _rhs_type, _ratio > &rhs)
Definition unit.h:491
base template class for holding values of type _type to be multiplied with a ratio _ratio
Definition unit.h:51
constexpr unit_t & operator-=(const unit_t &rhs)
Subtract-assign value of the same unit.
Definition unit.h:428
constexpr bool operator>(const unit_t< _symbol, _exponent, _rhs_type, _rhs_ratio > &rhs) const
Definition unit.h:232
_ratio ratio
Definition unit.h:55
constexpr unit_t & operator*=(const _type scalar)
multiply with a non-unit scalar
Definition unit.h:289
constexpr unit_t()=default
constexpr unit_t operator*(const _type f) const
multiply with a non-unit scalar
Definition unit.h:255
constexpr bool operator>=(const unit_t< _symbol, _exponent, _rhs_type, _rhs_ratio > &rhs) const
Definition unit.h:249
void setValue(_type v)
Definition unit.h:130
constexpr auto operator/(const unit_t< _symbol, _rhs_exponent, _rhs_type, _ratio > &rhs) const
Definition unit.h:302
constexpr bool operator<=(const unit_t< _symbol, _exponent, _rhs_type, _rhs_ratio > &rhs) const
Definition unit.h:226
unit_t operator++(int)
increment by postfix ++
Definition unit.h:459
constexpr _type operator/(const unit_t< _symbol, _exponent, _rhs_type, _ratio > &rhs)
divide whit same unit result is a scalar
Definition unit.h:337
unit_t & operator--()
decrement by prefix –
Definition unit.h:467
constexpr _unit_rhs< _type > as() const
Definition unit.h:117
constexpr unit_t & operator+=(const unit_t< _symbol, _exponent, _rhs_type, _rhs_ratio > &rhs)
add value of the same type but possibly different ratio
Definition unit.h:398
_type internal_type
Definition unit.h:56
constexpr _type operator/(const unit_t< _symbol, _rhs_exponent, _rhs_type, _rhs_ratio > &rhs) const
Definition unit.h:346
constexpr unit_t & operator=(unit_t< _symbol, _exponent, _type, _rhs_ratio > &&rhs)
Move assignment of same unit but different ratio.
Definition unit.h:160
constexpr unit_t(const unit_t< _symbol, _exponent, _type_rhs, _ratio > &rhs)
construct from other unit with implicitly convertible type
Definition unit.h:68
constexpr auto operator*(const unit_t< _symbol, _rhs_exponent, _rhs_type, _rhs_ratio > &rhs) const
Definition unit.h:273
constexpr unit_t(unit_t &&)=default
_exponent exponent
Definition unit.h:57
constexpr unit_t operator-(const unit_t< _symbol, _exponent, _rhs_type, _rhs_ratio > &rhs) const
subtracts two values, returning type is type of lhs
Definition unit.h:413
constexpr bool operator<(const unit_t< _symbol, _exponent, _rhs_type, _rhs_ratio > &rhs) const
Definition unit.h:210
constexpr unit_t & operator=(const unit_t &rhs)=default
Assignment for same ratio.
constexpr unit_t operator+(const unit_t< _symbol, _exponent, _rhs_type, _rhs_ratio > &rhs) const
adds two values, returning type is type of lhs
Definition unit.h:373
constexpr unit_t(const unit_t &)=default
constexpr unit_t operator-() const
negate operation
Definition unit.h:451
constexpr bool operator!=(const unit_t< _symbol, _exponent, _rhs_type, _rhs_ratio > &rhs) const
compares two values, considers different ratios.
Definition unit.h:203
unit_t operator--(int)
decrement by postfix –
Definition unit.h:473
constexpr bool operator==(const unit_t< _symbol, _exponent, _rhs_type, _rhs_ratio > &rhs) const
Definition unit.h:176
constexpr auto operator/(const unit_t< _symbol, _rhs_exponent, _rhs_type, _rhs_ratio > &rhs) const
Definition unit.h:320
constexpr _unit_rhs as() const
Definition unit.h:104
constexpr unit_t operator/(const _type f) const
divide by a non-unit scalar
Definition unit.h:295
std::integral_constant< char, _symbol > symbol
Definition unit.h:58
constexpr unit_t(_type v)
Construct with value v.
Definition unit.h:61
constexpr unit_t & operator+=(const unit_t &rhs)
add-assign value of the same unit
Definition unit.h:388
constexpr unit_t(unit_t< _symbol, _exponent, _type, _rhs_ratio > &&rhs)
Definition unit.h:88
constexpr unit_t & operator=(unit_t &&rhs)=default
Move assignment for same ratio.
constexpr _type value() const
returns the stored value as raw type
Definition unit.h:100
constexpr unit_t & operator/=(const _type scalar)
divide with a non-unit scalar
Definition unit.h:366
unit_t & operator++()
increment by prefix ++
Definition unit.h:454
constexpr unit_t & operator=(const unit_t< _symbol, _exponent, _type, _rhs_ratio > &rhs)
Assignment of same unit but different ratio.
Definition unit.h:143
constexpr unit_t(const unit_t< _symbol, _exponent, _rhs_type, _rhs_ratio > &rhs)
Definition unit.h:77
constexpr auto operator*(const unit_t< _symbol, _rhs_exponent, _rhs_type, _ratio > &rhs) const
multiply with an unit of the same ratio
Definition unit.h:259
constexpr unit_t & operator-=(const unit_t< _symbol, _exponent, _type, _rhs_ratio > &rhs)
subtract value of the same type but possibly different ratio
Definition unit.h:437
Definition unit_cast.h:49
#define SI_ENABLE_IMPLICIT_RATIO_CONVERSION
Definition unit.h:17