13 template<arithmetic_c T>
16 template<
class char_t>
17 static constexpr
auto get_suffixes() noexcept;
19 static constexpr
bool is_si(distance eDistance) noexcept;
22 template<qx::arithmetic_c T>
31 namespace qx::units::details
35 constexpr f64 to_meters(distance eFrom, T value) noexcept
37 const double fValue =
static_cast<double>(value);
39 if (traits<distance>::is_si(eFrom))
41 fResult = fValue *
pow(10,
static_cast<int>(eFrom));
48 fResult = fValue * 0.0000254;
51 case distance::inches:
52 fResult = fValue * 0.0254;
56 fResult = fValue * 0.1016;
60 fResult = fValue * 0.201168;
64 fResult = fValue * 0.3048;
68 fResult = fValue * 0.9144;
72 fResult = fValue * 5.0292;
75 case distance::chains:
76 fResult = fValue * 20.1168;
79 case distance::furlongs:
80 fResult = fValue * 201.168;
84 fResult = fValue * 1609.344;
87 case distance::leagues:
88 fResult = fValue * 4828.032;
91 case distance::fathoms:
92 fResult = fValue * 1.8288;
95 case distance::cables:
96 fResult = fValue * 185.2;
99 case distance::nautical_miles:
100 fResult = fValue * 1852.0;
103 case distance::astronomical_units:
104 fResult = fValue * 149597870700.0;
107 case distance::light_years:
108 fResult = fValue * 9460730472580800.0;
111 case distance::parsecs:
112 fResult = fValue * 30856775814913673.0;
121 constexpr T from_meters(f64 fMeters, distance eTo) noexcept
123 double fResult = 0.f;
124 if (traits<distance>::is_si(eTo))
126 fResult = fMeters /
pow(10,
static_cast<int>(eTo));
133 fResult = fMeters / 0.0000254;
136 case distance::inches:
137 fResult = fMeters / 0.0254;
140 case distance::hands:
141 fResult = fMeters / 0.1016;
144 case distance::links:
145 fResult = fMeters / 0.201168;
149 fResult = fMeters / 0.3048;
152 case distance::yards:
153 fResult = fMeters / 0.9144;
157 fResult = fMeters / 5.0292;
160 case distance::chains:
161 fResult = fMeters / 20.1168;
164 case distance::furlongs:
165 fResult = fMeters / 201.168;
168 case distance::miles:
169 fResult = fMeters / 1609.344;
172 case distance::leagues:
173 fResult = fMeters / 4828.032;
176 case distance::fathoms:
177 fResult = fMeters / 1.8288;
180 case distance::cables:
181 fResult = fMeters / 185.2;
184 case distance::nautical_miles:
185 fResult = fMeters / 1852.0;
188 case distance::astronomical_units:
189 fResult = fMeters / 149597870700.0;
192 case distance::light_years:
193 fResult = fMeters / 9460730472580800.0;
196 case distance::parsecs:
197 fResult = fMeters / 30856775814913673.0;
202 return static_cast<T
>(fResult);
207 template<qx::arithmetic_c T>
209 unit<T, distance> unit) noexcept
211 const f64 fMeters = details::to_meters(unit.type, unit.value);
213 distance eTo = distance::petameters;
214 if (fMeters <
pow(10,
static_cast<int>(distance::micrometers)))
216 eTo = distance::nanometers;
218 else if (fMeters <
pow(10,
static_cast<int>(distance::millimeters)))
220 eTo = distance::micrometers;
222 else if (fMeters <
pow(10,
static_cast<int>(distance::centimeters)))
224 eTo = distance::millimeters;
227 else if (fMeters <
pow(10,
static_cast<int>(distance::meters)))
229 eTo = distance::centimeters;
232 else if (fMeters <
pow(10,
static_cast<int>(distance::kilometers)))
234 eTo = distance::meters;
236 else if (fMeters <
pow(10,
static_cast<int>(distance::megameters)))
238 eTo = distance::kilometers;
240 else if (fMeters <
pow(10,
static_cast<int>(distance::gigameters)))
242 eTo = distance::megameters;
244 else if (fMeters <
pow(10,
static_cast<int>(distance::terameters)))
246 eTo = distance::gigameters;
248 else if (fMeters <
pow(10,
static_cast<int>(distance::petameters)))
250 eTo = distance::terameters;
253 return convert(unit).to(eTo);
256 template<
class char_t>
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") },
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") },
282 pair_type { distance::furlongs,
QX_STR_PREFIX(char_t,
"fur") },
284 pair_type { distance::leagues,
QX_STR_PREFIX(char_t,
"lea") },
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") },
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") } };
297 return eDistance < distance::_last_metric;
300 template<qx::arithmetic_c T>
303 if (this->m_From.type == eTo)
304 return { this->m_From.value, eTo };
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 };
310 template<
class char_t>
constexpr double pow(T number, int nPower)
Power function for integer power.
#define QX_STR_PREFIX(value_t, str)
Chose witch of prefixes add to string : L or none.