qxLib
distance.inl
Go to the documentation of this file.
1 /**
2 
3  @file distance.inl
4  @author Khrapov
5  @date 24.09.2025
6  @copyright © Nick Khrapov, 2025. All right reserved.
7 
8 **/
9 
10 template<>
11 struct qx::units::traits<qx::units::distance>
12 {
13  template<arithmetic_c T>
14  static constexpr unit<T, distance> normalize(unit<T, distance> unit) noexcept;
15 
16  template<class char_t>
17  static constexpr auto get_suffixes() noexcept;
18 
19  static constexpr bool is_si(distance eDistance) noexcept;
20 };
21 
22 template<qx::arithmetic_c T>
23 class qx::convert<T, qx::units::distance> : public units::details::base_converter<T, units::distance>
24 {
25 public:
27 
28  constexpr unit<T, units::distance> to(units::distance eTo) const noexcept;
29 };
30 
31 namespace qx::units::details
32 {
33 
34 template<class T>
35 constexpr f64 to_meters(distance eFrom, T value) noexcept
36 {
37  const double fValue = static_cast<double>(value);
38  double fResult = 0.f;
39  if (traits<distance>::is_si(eFrom))
40  {
41  fResult = fValue * pow(10, static_cast<int>(eFrom));
42  }
43  else
44  {
45  switch (eFrom)
46  {
47  case distance::mils:
48  fResult = fValue * 0.0000254;
49  break;
50 
51  case distance::inches:
52  fResult = fValue * 0.0254;
53  break;
54 
55  case distance::hands:
56  fResult = fValue * 0.1016;
57  break;
58 
59  case distance::links:
60  fResult = fValue * 0.201168;
61  break;
62 
63  case distance::feet:
64  fResult = fValue * 0.3048;
65  break;
66 
67  case distance::yards:
68  fResult = fValue * 0.9144;
69  break;
70 
71  case distance::rods:
72  fResult = fValue * 5.0292;
73  break;
74 
75  case distance::chains:
76  fResult = fValue * 20.1168;
77  break;
78 
79  case distance::furlongs:
80  fResult = fValue * 201.168;
81  break;
82 
83  case distance::miles:
84  fResult = fValue * 1609.344;
85  break;
86 
87  case distance::leagues:
88  fResult = fValue * 4828.032;
89  break;
90 
91  case distance::fathoms:
92  fResult = fValue * 1.8288;
93  break;
94 
95  case distance::cables:
96  fResult = fValue * 185.2;
97  break;
98 
99  case distance::nautical_miles:
100  fResult = fValue * 1852.0;
101  break;
102 
103  case distance::astronomical_units:
104  fResult = fValue * 149597870700.0;
105  break;
106 
107  case distance::light_years:
108  fResult = fValue * 9460730472580800.0;
109  break;
110 
111  case distance::parsecs:
112  fResult = fValue * 30856775814913673.0;
113  break;
114  }
115  }
116 
117  return fResult;
118 }
119 
120 template<class T>
121 constexpr T from_meters(f64 fMeters, distance eTo) noexcept
122 {
123  double fResult = 0.f;
124  if (traits<distance>::is_si(eTo))
125  {
126  fResult = fMeters / pow(10, static_cast<int>(eTo));
127  }
128  else
129  {
130  switch (eTo)
131  {
132  case distance::mils:
133  fResult = fMeters / 0.0000254;
134  break;
135 
136  case distance::inches:
137  fResult = fMeters / 0.0254;
138  break;
139 
140  case distance::hands:
141  fResult = fMeters / 0.1016;
142  break;
143 
144  case distance::links:
145  fResult = fMeters / 0.201168;
146  break;
147 
148  case distance::feet:
149  fResult = fMeters / 0.3048;
150  break;
151 
152  case distance::yards:
153  fResult = fMeters / 0.9144;
154  break;
155 
156  case distance::rods:
157  fResult = fMeters / 5.0292;
158  break;
159 
160  case distance::chains:
161  fResult = fMeters / 20.1168;
162  break;
163 
164  case distance::furlongs:
165  fResult = fMeters / 201.168;
166  break;
167 
168  case distance::miles:
169  fResult = fMeters / 1609.344;
170  break;
171 
172  case distance::leagues:
173  fResult = fMeters / 4828.032;
174  break;
175 
176  case distance::fathoms:
177  fResult = fMeters / 1.8288;
178  break;
179 
180  case distance::cables:
181  fResult = fMeters / 185.2;
182  break;
183 
184  case distance::nautical_miles:
185  fResult = fMeters / 1852.0;
186  break;
187 
188  case distance::astronomical_units:
189  fResult = fMeters / 149597870700.0;
190  break;
191 
192  case distance::light_years:
193  fResult = fMeters / 9460730472580800.0;
194  break;
195 
196  case distance::parsecs:
197  fResult = fMeters / 30856775814913673.0;
198  break;
199  }
200  }
201 
202  return static_cast<T>(fResult);
203 }
204 
205 } // namespace qx::units::details
206 
207 template<qx::arithmetic_c T>
209  unit<T, distance> unit) noexcept
210 {
211  const f64 fMeters = details::to_meters(unit.type, unit.value);
212 
213  distance eTo = distance::petameters;
214  if (fMeters < pow(10, static_cast<int>(distance::micrometers)))
215  {
216  eTo = distance::nanometers;
217  }
218  else if (fMeters < pow(10, static_cast<int>(distance::millimeters)))
219  {
220  eTo = distance::micrometers;
221  }
222  else if (fMeters < pow(10, static_cast<int>(distance::centimeters)))
223  {
224  eTo = distance::millimeters;
225  }
226  // skip decimeters as rarely used
227  else if (fMeters < pow(10, static_cast<int>(distance::meters)))
228  {
229  eTo = distance::centimeters;
230  }
231  // skip decameters and hectometers as rarely used
232  else if (fMeters < pow(10, static_cast<int>(distance::kilometers)))
233  {
234  eTo = distance::meters;
235  }
236  else if (fMeters < pow(10, static_cast<int>(distance::megameters)))
237  {
238  eTo = distance::kilometers;
239  }
240  else if (fMeters < pow(10, static_cast<int>(distance::gigameters)))
241  {
242  eTo = distance::megameters;
243  }
244  else if (fMeters < pow(10, static_cast<int>(distance::terameters)))
245  {
246  eTo = distance::gigameters;
247  }
248  else if (fMeters < pow(10, static_cast<int>(distance::petameters)))
249  {
250  eTo = distance::terameters;
251  }
252 
253  return convert(unit).to(eTo);
254 }
255 
256 template<class char_t>
258 {
259  using pair_type = std::pair<distance, basic_string_view<char_t>>;
260  return std::array { pair_type { distance::nanometers, QX_STR_PREFIX(char_t, "nm") },
261  pair_type { distance::micrometers, QX_STR_PREFIX(char_t, "um") },
262  pair_type { distance::millimeters, QX_STR_PREFIX(char_t, "mm") },
263  pair_type { distance::centimeters, QX_STR_PREFIX(char_t, "cm") },
264  pair_type { distance::decimeters, QX_STR_PREFIX(char_t, "dm") },
265  pair_type { distance::meters, QX_STR_PREFIX(char_t, "m") },
266  pair_type { distance::decameters, QX_STR_PREFIX(char_t, "dam") },
267  pair_type { distance::hectometers, QX_STR_PREFIX(char_t, "hm") },
268  pair_type { distance::kilometers, QX_STR_PREFIX(char_t, "km") },
269  pair_type { distance::megameters, QX_STR_PREFIX(char_t, "Mm") },
270  pair_type { distance::gigameters, QX_STR_PREFIX(char_t, "Gm") },
271  pair_type { distance::terameters, QX_STR_PREFIX(char_t, "Tm") },
272  pair_type { distance::petameters, QX_STR_PREFIX(char_t, "Pm") },
273 
274  pair_type { distance::mils, QX_STR_PREFIX(char_t, "mil") },
275  pair_type { distance::inches, QX_STR_PREFIX(char_t, "in") },
276  pair_type { distance::hands, QX_STR_PREFIX(char_t, "hh") },
277  pair_type { distance::links, QX_STR_PREFIX(char_t, "li") },
278  pair_type { distance::feet, QX_STR_PREFIX(char_t, "ft") },
279  pair_type { distance::yards, QX_STR_PREFIX(char_t, "yd") },
280  pair_type { distance::rods, QX_STR_PREFIX(char_t, "rd") },
281  pair_type { distance::chains, QX_STR_PREFIX(char_t, "ch") },
282  pair_type { distance::furlongs, QX_STR_PREFIX(char_t, "fur") },
283  pair_type { distance::miles, QX_STR_PREFIX(char_t, "mi") },
284  pair_type { distance::leagues, QX_STR_PREFIX(char_t, "lea") },
285 
286  pair_type { distance::fathoms, QX_STR_PREFIX(char_t, "fm") },
287  pair_type { distance::cables, QX_STR_PREFIX(char_t, "cables") },
288  pair_type { distance::nautical_miles, QX_STR_PREFIX(char_t, "nmi") },
289 
290  pair_type { distance::astronomical_units, QX_STR_PREFIX(char_t, "AU") },
291  pair_type { distance::light_years, QX_STR_PREFIX(char_t, "ly") },
292  pair_type { distance::parsecs, QX_STR_PREFIX(char_t, "pc") } };
293 }
294 
295 constexpr bool qx::units::traits<qx::units::distance>::is_si(distance eDistance) noexcept
296 {
297  return eDistance < distance::_last_metric;
298 }
299 
300 template<qx::arithmetic_c T>
301 constexpr qx::unit<T, qx::units::distance> qx::convert<T, qx::units::distance>::to(units::distance eTo) const noexcept
302 {
303  if (this->m_From.type == eTo)
304  return { this->m_From.value, eTo };
305 
306  const f64 fMeters = units::details::to_meters(this->m_From.type, this->m_From.value);
307  return { units::details::from_meters<T>(fMeters, eTo), eTo };
308 }
309 
310 template<class char_t>
311 struct std::formatter<qx::units::distance, char_t> : qx::units::details::unit_formatter<qx::units::distance, char_t>
312 {
313 };
A conversion class.
Definition: base.h:77
constexpr double pow(T number, int nPower)
Power function for integer power.
Definition: common.inl:58
#define QX_STR_PREFIX(value_t, str)
Chose witch of prefixes add to string : L or none.
Definition: string_utils.h:253
Definition: base.h:52