SI  2.5.4
A header only c++ library that provides type safety and user defined literals for handling physical values defined in the International System of Units.
unit_cast.h
Go to the documentation of this file.
1 
12 #pragma once
13 
14 #include "detail.h"
15 #include <ratio>
16 #include <type_traits>
17 
18 namespace SI::detail {
19 
21 template <typename _target_type, typename _rhs_T>
22 constexpr auto unit_cast(const _rhs_T &rhs) {
23  // using static assert instead of std::enable if in order to be able to
24  // forward declare this function easier
25  static_assert(
26  is_unit_t_v<_rhs_T> ||
27  std::is_base_of<
28  unit_t<_rhs_T::symbol::value, typename _rhs_T::exponent,
29  typename _rhs_T::internal_type, typename _rhs_T::ratio>,
30  _rhs_T>::value,
31  "is of type unit_t or a derived class");
32 
33  using conversion_ratio =
34  std::ratio_divide<typename _rhs_T::ratio, typename _target_type::ratio>;
35  static_assert(std::is_convertible<decltype(conversion_ratio::den),
36  typename _rhs_T::internal_type>::value,
37  "conversion ratio denominator is convertible to internal type");
38 
39  // the static cast is needed because MSVC will print a warning without it
40  // because of a possible loss of precision when rhs is of type double
41  return _target_type(
42  ((rhs.value() * static_cast<typename _target_type::internal_type>(
43  conversion_ratio::num)) /
44  static_cast<typename _target_type::internal_type>(
45  conversion_ratio::den)));
46 }
47 
48 template <typename _unit_lhs, typename _unit_rhs>
50  static_assert(is_unit_t_v<_unit_lhs>, "only supported for SI::unit_t");
51  static_assert(is_unit_t_v<_unit_rhs>, "only supported for SI::unit_t");
52  static_assert(std::is_convertible<typename _unit_lhs::internal_type,
53  typename _unit_rhs::internal_type>::value);
54  static_assert(_unit_lhs::symbol::value == _unit_rhs::symbol::value);
55  using type =
56  unit_t<_unit_lhs::symbol::value, typename _unit_lhs::exponent,
57  typename _unit_lhs::internal_type,
58  typename detail::ratio_gcd<typename _unit_lhs::ratio,
59  typename _unit_rhs::ratio>::ratio>;
60 };
61 
62 } // namespace SI::detail
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
calculate gcd for rations
Definition: detail.h:32
base template class for holding values of type _type to be multiplied with a ratio _ratio
Definition: unit.h:51
Definition: unit_cast.h:49