qxLib
base.inl
Go to the documentation of this file.
1 /**
2 
3  @file base.inl
4  @author Khrapov
5  @date 13.08.2025
6  @copyright © Nick Khrapov, 2025. All right reserved.
7 
8 **/
9 
10 namespace qx::units::details
11 {
12 
13 template<arithmetic_c T, enumeration_c unit_t>
15 {
16 public:
17  constexpr base_converter(unit<T, unit_t> from) noexcept;
18  constexpr base_converter(T value, unit_t eFrom) noexcept;
19 
20 protected:
21  unit<T, unit_t> m_From;
22 };
23 
24 template<arithmetic_c T, enumeration_c unit_t>
26 
27 template<enumeration_c unit_t, class char_t>
29 
30 } // namespace qx::units::details
31 
32 template<qx::arithmetic_c T, qx::enumeration_c unit_t>
33 qx::unit<T, unit_t>::operator T() const noexcept
34 {
35  return value;
36 }
37 
38 template<qx::arithmetic_c T, qx::enumeration_c unit_t>
40 {
41 }
42 
43 template<qx::arithmetic_c T, qx::enumeration_c unit_t>
44 constexpr qx::units::details::base_converter<T, unit_t>::base_converter(T value, unit_t eFrom) noexcept
45  : m_From({ value, eFrom })
46 {
47 }
48 
49 template<qx::arithmetic_c T, qx::enumeration_c unit_t>
50 qx::unit<T, unit_t> qx::normalize_unit(unit<T, unit_t> unit) noexcept
51 {
52  return units::details::unit_normalizer<T, unit_t>::normalize(unit);
53 }
54 
55 template<qx::arithmetic_c T, qx::enumeration_c unit_t>
56 qx::unit<T, unit_t> qx::normalize_unit(T value, unit_t eInitialType) noexcept
57 {
58  return qx::normalize_unit(unit { value, eInitialType });
59 }
60 
61 template<qx::arithmetic_c T, qx::enumeration_c unit_t, class char_t>
62 std::optional<qx::unit<T, unit_t>> qx::unit_from_string(basic_string_view<char_t> svValue) noexcept
63 {
64  auto remove_suffix = [](basic_string_view<char_t> svValue,
65  auto predicate) -> std::optional<basic_string_view<char_t>>
66  {
67  size_t nToErase = predicate(svValue);
68  if (nToErase == 0)
69  return std::nullopt;
70 
71  svValue.remove_suffix(nToErase);
72  return svValue;
73  };
74 
75  auto trim_right = [&remove_suffix](basic_string_view<char_t> svValue)
76  {
77  while (std::optional<basic_string_view<char_t>> svErased = remove_suffix(
78  svValue,
79  [](basic_string_view<char_t> svValue)
80  {
81  size_t nToErase = 0;
82  while (string_traits::traits<char_t>::is_space(svValue[nToErase]))
83  {
84  ++nToErase;
85  }
86 
87  return nToErase;
88  }))
89  {
90  svValue = *svErased;
91  }
92 
93  return svValue;
94  };
95 
96  svValue = trim_right(svValue);
97 
98  std::optional<unit_t> optUnitType;
99  auto optNewValue = remove_suffix(
100  svValue,
101  [&optUnitType](basic_string_view<char_t> svValue) -> size_t
102  {
103  const auto& suffixes = units::details::unit_suffixes<unit_t, char_t>::get();
104  const auto it = std::ranges::find_if(
105  suffixes,
106  [svValue](const std::pair<unit_t, basic_string_view<char_t>>& suffix)
107  {
108  return svValue.ends_with(suffix.second);
109  });
110 
111  if (it != suffixes.end())
112  {
113  optUnitType = it->first;
114  return it->second.size();
115  }
116  else
117  {
118  return 0;
119  }
120  });
121  if (!optUnitType)
122  return std::nullopt;
123  if (!optNewValue)
124  return std::nullopt;
125  svValue = *optNewValue;
126 
127  svValue = trim_right(svValue);
128 
129  // todo we can make it constexpr and get rid of a possible allocation
130  basic_string<char_t> sValue = svValue;
131  std::optional<T> optValue = sValue.template to<T>();
132  if (!optValue)
133  return std::nullopt;
134 
135  return unit(*optValue, *optUnitType);
136 }
137 
138 
139 template<qx::arithmetic_c T, qx::enumeration_c unit_t>
140 template<class format_parse_context_t>
141 constexpr auto std::formatter<qx::unit<T, unit_t>, qx::char_type>::parse(format_parse_context_t& context) noexcept
142 {
143  return valueFormatter.parse(context);
144 }
145 
146 
147 template<qx::arithmetic_c T, qx::enumeration_c unit_t>
148 template<class format_context_type_t>
149 constexpr auto std::formatter<qx::unit<T, unit_t>, qx::char_type>::format(
150  const qx::unit<T, unit_t>& unit,
151  format_context_type_t& ctx) const noexcept
152 {
153  auto outIt = valueFormatter.format(unit.value, ctx);
154  return std::format_to(outIt, QX_TEXT("{}"), unit.type);
155 }
std::optional< unit< T, unit_t > > unit_from_string(basic_string_view< char_t > svValue) noexcept
Creates a unit from a string.
unit< T, unit_t > normalize_unit(unit< T, unit_t > unit) noexcept
The function returns the closest value greater than one from the SI for the unit of measurement.
Definition: base.h:38