30 #include <type_traits>
35 #ifndef UNIT_DISABLE_IOSTREAM
41 template <
typename Rep,
typename Ratio,
typename UnitType>
49 template <
typename Rep,
typename Ratio,
typename UnitType>
56 template <
intmax_t Numerator>
57 struct integer_sign : std::integral_constant<intmax_t, (Numerator < 0) ? -1 : 1>
61 template <intmax_t Numerator>
62 struct integer_abs : std::integral_constant<intmax_t, Numerator * integer_sign<Numerator>::value>
66 template <intmax_t Numerator, intmax_t Quotient>
67 struct greatest_common_divisor;
69 template <intmax_t Numerator, intmax_t Quotient>
70 struct greatest_common_divisor : greatest_common_divisor<Quotient, (Numerator % Quotient)>
74 template <intmax_t Numerator>
75 struct greatest_common_divisor<Numerator, 0> : std::integral_constant<intmax_t, integer_abs<Numerator>::value>
79 template <intmax_t Quotient>
80 struct greatest_common_divisor<0, Quotient> : std::integral_constant<intmax_t, integer_abs<Quotient>::value>
85 auto fmod(T x, T y) -> typename std::enable_if<std::is_floating_point<T>::value, long long int>::type
87 return y != 0 ? x - std::trunc(x / y) * y :
throw std::domain_error{
"Dividing by zero!"};
90 template <
class CommonRep,
94 bool = std::is_convertible<Rep2, CommonRep>::value>
95 struct unit_div_mod_base
100 template <
class CommonRep,
class Ratio,
class UnitType,
class Rep2>
101 struct unit_div_mod_base<CommonRep, Ratio, UnitType, Rep2, false>
105 template <class Rep1, class Ratio1, class UnitType1, class Rep2, bool = is_unit<Rep2>::value>
110 template <
class Rep1,
class Ratio1,
class UnitType1,
class Rep2>
111 struct unit_div_mod<Rep1, Ratio1, UnitType1, Rep2, false>
112 : unit_div_mod_base<typename std::common_type<Rep1, Rep2>::type, Ratio1, UnitType1, Rep2>
120 template <
typename CommonRep,
typename Ratio1,
typename Ratio2,
typename UnitType>
124 using gcd_num = units::detail::greatest_common_divisor<Ratio1::num, Ratio2::num>;
125 using gcd_den = units::detail::greatest_common_divisor<Ratio1::den, Ratio2::den>;
126 using common_rep =
typename CommonRep::type;
127 using ratio = std::ratio<gcd_num::value, (Ratio1::den / gcd_den::value) * Ratio2::den>;
128 using unit_type = UnitType;
134 template <
typename Rep1,
typename Ratio1,
typename UnitType1,
typename Rep2,
typename Ratio2,
typename UnitType2>
135 struct common_type<units::unit<Rep1, Ratio1, UnitType1>,
units::unit<Rep2, Ratio2, UnitType2>>
137 static_assert(std::is_same<UnitType1, UnitType2>::value,
"Incompatible unit types");
152 template <
typename ToUnit,
typename Rep,
typename Ratio,
typename UnitType>
154 typename std::enable_if<is_unit<ToUnit>::value, ToUnit>::type;
156 template <
typename Rep,
typename Ratio,
typename UnitType>
161 using unit_type = UnitType;
163 constexpr
explicit unit(rep value)
168 template <
typename Rep2,
typename Ratio2,
typename UnitType2>
169 constexpr unit(unit<Rep2, Ratio2, UnitType2> dist)
170 : value{unit_cast<unit<rep, ratio, unit_type>>(dist).count()}
172 static_assert(std::is_same<unit_type, UnitType2>::value,
"Unit types are not compatible");
175 constexpr rep count()
const;
177 constexpr std::common_type_t<unit> operator+()
const;
178 constexpr std::common_type_t<unit> operator-()
const;
181 unit operator++(
int);
183 unit operator--(
int);
185 unit& operator+=(unit
const other);
186 unit& operator-=(unit
const other);
187 unit& operator*=(rep
const scalar);
188 unit& operator/=(rep
const scalar);
189 unit& operator%=(rep
const scalar);
190 unit& operator%=(unit
const other);
196 template <
typename Rep,
typename Ratio = std::ratio<1>>
197 using distance = unit<Rep, Ratio, unit_type::distance>;
200 using nanometres = distance<double, std::nano>;
201 using micrometres = distance<double, std::micro>;
202 using millimetres = distance<double, std::milli>;
203 using centimetres = distance<double, std::centi>;
204 using decimetres = distance<double, std::deci>;
205 using metres = distance<double>;
206 using kilometres = distance<double, std::kilo>;
209 using nanometers = nanometres;
210 using micrometers = micrometres;
211 using millimeters = millimetres;
212 using centimeters = centimetres;
213 using decimeters = decimetres;
214 using meters = metres;
215 using kilometers = kilometres;
218 using feet = distance<double, std::ratio_multiply<std::ratio<381, 1250>, metres::ratio>>;
219 using thous = distance<double, std::ratio_divide<feet::ratio, std::ratio<12000>>>;
220 using inches = distance<double, std::ratio_divide<feet::ratio, std::ratio<12>>>;
221 using links = distance<double, std::ratio_multiply<std::ratio<33, 50>, feet::ratio>>;
222 using yards = distance<double, std::ratio_multiply<std::ratio<3>, feet::ratio>>;
223 using rods = distance<double, std::ratio_multiply<std::ratio<25>, links::ratio>>;
224 using chains = distance<double, std::ratio_multiply<std::ratio<4>, rods::ratio>>;
225 using furlongs = distance<double, std::ratio_multiply<std::ratio<10>, chains::ratio>>;
226 using miles = distance<double, std::ratio_multiply<std::ratio<5280>, feet::ratio>>;
227 using leagues = distance<double, std::ratio_multiply<std::ratio<15840>, feet::ratio>>;
230 using fathoms = distance<double, std::ratio_multiply<std::ratio<608, 100>, feet::ratio>>;
231 using cables = distance<double, std::ratio_multiply<std::ratio<608>, feet::ratio>>;
232 using nautical_miles = distance<double, std::ratio_multiply<std::ratio<6080>, feet::ratio>>;
239 using earth_radii = distance<long double, std::ratio_multiply<std::ratio<6371>, kilometres::ratio>>;
240 using lunar_distances = distance<long double, std::ratio_multiply<std::ratio<384402>, kilometres::ratio>>;
241 using astronimical_units = distance<long double, std::ratio<149597870700>>;
242 using light_years = distance<long double, std::ratio_multiply<std::ratio<94607304725808, 10>, kilometres::ratio>>;
243 using parsecs = distance<long double, std::ratio_multiply<std::ratio<308567758146719, 10>, kilometres::ratio>>;
245 template <
typename Rep,
typename Ratio = std::ratio<1>>
246 using mass = unit<Rep, Ratio, unit_type::mass>;
249 using picograms = mass<double, std::pico>;
250 using nanograms = mass<double, std::nano>;
251 using micrograms = mass<double, std::micro>;
252 using milligrams = mass<double, std::milli>;
253 using grams = mass<double>;
254 using kilograms = mass<double, std::kilo>;
255 using tons = mass<double, std::ratio_multiply<std::ratio<1000>, kilograms::ratio>>;
258 using pounds = mass<double, std::ratio_multiply<std::ratio<45359237, 100000000>, kilograms::ratio>>;
259 using grains = mass<double, std::ratio_divide<pounds::ratio, std::ratio<7000>>>;
260 using drams = mass<double, std::ratio_multiply<std::ratio<2734375, 100000>, grains::ratio>>;
261 using ounces = mass<double, std::ratio_multiply<std::ratio<16>, drams::ratio>>;
262 using us_hundredweight = mass<double, std::ratio_multiply<std::ratio<100>, pounds::ratio>>;
263 using long_hundredweight = mass<double, std::ratio_multiply<std::ratio<112>, pounds::ratio>>;
264 using short_ton = mass<double, std::ratio_multiply<std::ratio<2000>, pounds::ratio>>;
265 using long_ton = mass<double, std::ratio_multiply<std::ratio<2240>, pounds::ratio>>;
268 template <
typename Rep1,
typename Ratio1,
typename UnitType1,
typename Rep2,
typename Ratio2,
typename UnitType2>
269 constexpr
auto operator+(unit<Rep1, Ratio1, UnitType1> lhs, unit<Rep2, Ratio2, UnitType2> rhs) ->
270 typename std::common_type<unit<Rep1, Ratio1, UnitType1>, unit<Rep2, Ratio2, UnitType2>>::type;
272 template <
typename Rep1,
typename Ratio1,
typename UnitType1,
typename Rep2,
typename Ratio2,
typename UnitType2>
273 constexpr
auto operator-(unit<Rep1, Ratio1, UnitType1> lhs, unit<Rep2, Ratio2, UnitType2> rhs) ->
274 typename std::common_type<unit<Rep1, Ratio1, UnitType1>, unit<Rep2, Ratio2, UnitType2>>::type;
276 template <
typename Rep1,
typename Ratio,
typename UnitType,
typename Rep2>
277 constexpr
auto operator*(unit<Rep1, Ratio, UnitType> lhs, Rep2
const scalar)
278 -> unit<typename std::common_type<Rep1, Rep2>::type, Ratio, UnitType>;
280 template <
typename Rep1,
typename Rep2,
typename Ratio,
typename UnitType>
281 constexpr
auto operator*(Rep1
const scalar, unit<Rep2, Ratio, UnitType> rhs)
282 -> unit<typename std::common_type<Rep1, Rep2>::type, Ratio, UnitType>;
284 template <
typename Rep1,
typename Ratio,
typename UnitType,
typename Rep2>
285 constexpr
auto operator/(unit<Rep1, Ratio, UnitType> lhs, Rep2
const scalar)
286 -> unit<typename std::common_type<Rep1, Rep2>::type, Ratio, UnitType>;
288 template <
typename Rep1,
typename Ratio1,
typename UnitType1,
typename Rep2,
typename Ratio2,
typename UnitType2>
289 constexpr
auto operator%(unit<Rep1, Ratio1, UnitType1> lhs, unit<Rep2, Ratio2, UnitType2> rhs) ->
290 typename std::common_type<unit<Rep1, Ratio1, UnitType1>, unit<Rep2, Ratio2, UnitType2>>::type;
292 template <
typename Rep1,
typename Ratio,
typename UnitType,
typename Rep2>
293 constexpr
auto operator%(unit<Rep1, Ratio, UnitType> lhs, Rep2
const scalar) ->
294 typename detail::unit_div_mod<Rep1, Ratio, UnitType, Rep2>::type;
297 template <
typename Rep1,
typename Ratio1,
typename UnitType1,
typename Rep2,
typename Ratio2,
typename UnitType2>
298 constexpr
bool operator==(unit<Rep1, Ratio1, UnitType1> lhs, unit<Rep2, Ratio2, UnitType2> rhs);
300 template <
typename Rep1,
typename Ratio1,
typename UnitType1,
typename Rep2,
typename Ratio2,
typename UnitType2>
301 constexpr
bool operator!=(unit<Rep1, Ratio1, UnitType1> lhs, unit<Rep2, Ratio2, UnitType2> rhs);
303 template <
typename Rep1,
typename Ratio1,
typename UnitType1,
typename Rep2,
typename Ratio2,
typename UnitType2>
304 constexpr
bool operator<(unit<Rep1, Ratio1, UnitType1> lhs, unit<Rep2, Ratio2, UnitType2> rhs);
306 template <
typename Rep1,
typename Ratio1,
typename UnitType1,
typename Rep2,
typename Ratio2,
typename UnitType2>
307 constexpr
bool operator<=(unit<Rep1, Ratio1, UnitType1> lhs, unit<Rep2, Ratio2, UnitType2> rhs);
309 template <
typename Rep1,
typename Ratio1,
typename UnitType1,
typename Rep2,
typename Ratio2,
typename UnitType2>
310 constexpr
bool operator>(unit<Rep1, Ratio1, UnitType1> lhs, unit<Rep2, Ratio2, UnitType2> rhs);
312 template <
typename Rep1,
typename Ratio1,
typename UnitType1,
typename Rep2,
typename Ratio2,
typename UnitType2>
313 constexpr
bool operator>=(unit<Rep1, Ratio1, UnitType1> lhs, unit<Rep2, Ratio2, UnitType2> rhs);
315 #ifndef UNITS_DISABLE_IOSTREAM
316 template <
typename CharT,
typename Traits,
typename Rep,
typename Ratio,
typename UnitType>
317 std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os,
318 unit<Rep, Ratio, UnitType>
const& u);
322 inline namespace literals
324 namespace distance_literals
332 constexpr
units::metres operator"" _m(
unsigned long long int dist);
336 constexpr
units::thous operator"" _th(
unsigned long long int dist);
337 constexpr
units::inches operator"" _in(
unsigned long long int dist);
338 constexpr
units::links operator"" _li(
unsigned long long int dist);
339 constexpr
units::feet operator"" _ft(
unsigned long long int dist);
340 constexpr
units::yards operator"" _yd(
unsigned long long int dist);
341 constexpr
units::rods operator"" _rd(
unsigned long long int dist);
342 constexpr
units::chains operator"" _ch(
unsigned long long int dist);
343 constexpr
units::furlongs operator"" _fur(
unsigned long long int dist);
344 constexpr
units::miles operator"" _mi(
unsigned long long int dist);
345 constexpr
units::leagues operator"" _lea(
unsigned long long int dist);
348 constexpr
units::fathoms operator"" _ftm(
unsigned long long int dist);
349 constexpr
units::cables operator"" _cb(
unsigned long long int dist);
358 constexpr
units::parsecs operator"" _pc(
unsigned long long int dist);
361 namespace mass_literals
368 constexpr
units::grams operator"" _g(
unsigned long long int mass);
372 constexpr
units::grains operator"" _gr(
unsigned long long int mass);
373 constexpr
units::drams operator"" _dr(
unsigned long long int mass);
374 constexpr
units::ounces operator"" _oz(
unsigned long long int mass);
375 constexpr
units::pounds operator"" _lb(
unsigned long long int mass);
383 template <
typename Rep,
typename Ratio,
typename UnitType>
384 constexpr
typename unit<Rep, Ratio, UnitType>::rep unit<Rep, Ratio, UnitType>::count()
const
389 template <
typename Rep,
typename Ratio,
typename UnitType>
390 constexpr std::common_type_t<unit<Rep, Ratio, UnitType>> unit<Rep, Ratio, UnitType>::operator+()
const
395 template <
typename Rep,
typename Ratio,
typename UnitType>
396 constexpr std::common_type_t<unit<Rep, Ratio, UnitType>> unit<Rep, Ratio, UnitType>::operator-()
const
398 return unit<Rep, Ratio, UnitType>{0 - value};
401 template <
typename Rep,
typename Ratio,
typename UnitType>
402 unit<Rep, Ratio, UnitType>& unit<Rep, Ratio, UnitType>::operator++()
408 template <
typename Rep,
typename Ratio,
typename UnitType>
409 unit<Rep, Ratio, UnitType> unit<Rep, Ratio, UnitType>::operator++(
int)
411 auto const temp = value;
413 return unit<Rep, Ratio, UnitType>{temp};
416 template <
typename Rep,
typename Ratio,
typename UnitType>
417 unit<Rep, Ratio, UnitType>& unit<Rep, Ratio, UnitType>::operator--()
423 template <
typename Rep,
typename Ratio,
typename UnitType>
424 unit<Rep, Ratio, UnitType> unit<Rep, Ratio, UnitType>::operator--(
int)
426 auto const temp = value;
428 return unit<Rep, Ratio, UnitType>{temp};
431 template <
typename Rep,
typename Ratio,
typename UnitType>
432 unit<Rep, Ratio, UnitType>& unit<Rep, Ratio, UnitType>::operator+=(unit
const other)
434 value += other.count();
438 template <
typename Rep,
typename Ratio,
typename UnitType>
439 unit<Rep, Ratio, UnitType>& unit<Rep, Ratio, UnitType>::operator-=(unit
const other)
441 value -= other.count();
445 template <
typename Rep,
typename Ratio,
typename UnitType>
446 unit<Rep, Ratio, UnitType>& unit<Rep, Ratio, UnitType>::operator*=(rep
const scalar)
452 template <
typename Rep,
typename Ratio,
typename UnitType>
453 unit<Rep, Ratio, UnitType>& unit<Rep, Ratio, UnitType>::operator/=(rep
const scalar)
459 template <
typename Rep,
typename Ratio,
typename UnitType>
460 unit<Rep, Ratio, UnitType>& unit<Rep, Ratio, UnitType>::operator%=(rep
const scalar)
462 value = detail::fmod(value, scalar);
466 template <
typename Rep,
typename Ratio,
typename UnitType>
467 unit<Rep, Ratio, UnitType>& unit<Rep, Ratio, UnitType>::operator%=(unit
const other)
469 value = detail::fmod(value, other.count());
474 template <
typename Rep1,
typename Ratio1,
typename UnitType1,
typename Rep2,
typename Ratio2,
typename UnitType2>
475 constexpr
auto operator+(unit<Rep1, Ratio1, UnitType1> lhs, unit<Rep2, Ratio2, UnitType2> rhs) ->
476 typename std::common_type<unit<Rep1, Ratio1, UnitType1>, unit<Rep2, Ratio2, UnitType2>>::type
478 using unit1 = unit<Rep1, Ratio1, UnitType1>;
479 using unit2 = unit<Rep2, Ratio2, UnitType2>;
480 using common_type =
typename std::common_type<unit1, unit2>::type;
482 return static_cast<common_type
>(
static_cast<common_type
>(lhs).count() +
static_cast<common_type
>(rhs).count());
485 template <
typename Rep1,
typename Ratio1,
typename UnitType1,
typename Rep2,
typename Ratio2,
typename UnitType2>
486 constexpr
auto operator-(unit<Rep1, Ratio1, UnitType1> lhs, unit<Rep2, Ratio2, UnitType2> rhs) ->
487 typename std::common_type<unit<Rep1, Ratio1, UnitType1>, unit<Rep2, Ratio2, UnitType2>>::type
489 using unit1 = unit<Rep1, Ratio1, UnitType1>;
490 using unit2 = unit<Rep2, Ratio2, UnitType2>;
491 using common_type =
typename std::common_type<unit1, unit2>::type;
493 return static_cast<common_type
>(
static_cast<common_type
>(lhs).count() -
static_cast<common_type
>(rhs).count());
496 template <
typename Rep1,
typename Ratio,
typename UnitType,
typename Rep2>
497 constexpr
auto operator*(unit<Rep1, Ratio, UnitType> lhs, Rep2
const scalar)
498 -> unit<typename std::common_type<Rep1, Rep2>::type, Ratio, UnitType>
500 using result_type = unit<typename std::common_type<Rep1, Rep2>::type, Ratio, UnitType>;
501 return static_cast<result_type
>(
static_cast<result_type
>(lhs).count() * scalar);
504 template <
typename Rep1,
typename Rep2,
typename Ratio,
typename UnitType>
505 constexpr
auto operator*(Rep1
const scalar, unit<Rep2, Ratio, UnitType> rhs)
506 -> unit<typename std::common_type<Rep1, Rep2>::type, Ratio, UnitType>
508 using result_type = unit<typename std::common_type<Rep1, Rep2>::type, Ratio, UnitType>;
512 template <
typename Rep1,
typename Ratio,
typename UnitType,
typename Rep2>
513 constexpr
auto operator/(unit<Rep1, Ratio, UnitType> lhs, Rep2
const scalar)
514 -> unit<typename std::common_type<Rep1, Rep2>::type, Ratio, UnitType>
516 using result_type = unit<typename std::common_type<Rep1, Rep2>::type, Ratio, UnitType>;
517 return static_cast<result_type
>(
static_cast<result_type
>(lhs).count() / scalar);
520 template <
typename Rep1,
typename Ratio1,
typename UnitType1,
typename Rep2,
typename Ratio2,
typename UnitType2>
521 constexpr
auto operator%(unit<Rep1, Ratio1, UnitType1> lhs, unit<Rep2, Ratio2, UnitType2> rhs) ->
522 typename std::common_type<unit<Rep1, Ratio1, UnitType1>, unit<Rep2, Ratio2, UnitType2>>::type
524 using unit1 = unit<Rep1, Ratio1, UnitType1>;
525 using unit2 = unit<Rep2, Ratio2, UnitType2>;
526 using common_type =
typename std::common_type<unit1, unit2>::type;
528 return common_type{common_type{lhs}.count() % common_type{rhs}.count()};
531 template <
typename Rep1,
typename Ratio,
typename UnitType,
typename Rep2>
532 constexpr
auto operator%(unit<Rep1, Ratio, UnitType> lhs, Rep2
const scalar) ->
533 typename detail::unit_div_mod<Rep1, Ratio, UnitType, Rep2>::type
535 using result_type = unit<typename std::common_type<Rep1, Rep2>::type, Ratio, UnitType>;
536 return result_type{result_type{lhs}.count()
537 % result_type{
static_cast<typename result_type::rep
>(scalar)}.count()};
542 template <
typename T>
543 constexpr
auto abs(
const T& value)
545 return (T{} > value) ? -value : value;
548 constexpr
bool unit_compare(
double lhs,
550 double max_diff = 0.000000001,
551 double max_relative_diff = std::numeric_limits<double>::epsilon())
553 return (abs(lhs - rhs) <= (((abs(rhs) > abs(lhs)) ? abs(rhs) : abs(lhs)) * max_relative_diff)) || (abs(lhs - rhs) <= max_diff);
558 template <
typename Rep1,
typename Ratio1,
typename UnitType1,
typename Rep2,
typename Ratio2,
typename UnitType2>
559 constexpr
bool operator==(unit<Rep1, Ratio1, UnitType1> lhs, unit<Rep2, Ratio2, UnitType2> rhs)
561 using unit1 = unit<Rep1, Ratio1, UnitType1>;
562 using unit2 = unit<Rep2, Ratio2, UnitType2>;
563 using common_type =
typename std::common_type<unit1, unit2>::type;
564 using common_rep =
typename common_type::rep;
566 return detail::unit_compare(unit_cast<common_type>(lhs).count(), unit_cast<common_type>(rhs).count());
569 template <
typename Rep1,
typename Ratio1,
typename UnitType1,
typename Rep2,
typename Ratio2,
typename UnitType2>
570 constexpr
bool operator!=(unit<Rep1, Ratio1, UnitType1> lhs, unit<Rep2, Ratio2, UnitType2> rhs)
572 using unit1 = unit<Rep1, Ratio1, UnitType1>;
573 using unit2 = unit<Rep2, Ratio2, UnitType2>;
574 using common_type =
typename std::common_type<unit1, unit2>::type;
576 return !(lhs == rhs);
579 template <
typename Rep1,
typename Ratio1,
typename UnitType1,
typename Rep2,
typename Ratio2,
typename UnitType2>
580 constexpr
bool operator<(unit<Rep1, Ratio1, UnitType1> lhs, unit<Rep2, Ratio2, UnitType2> rhs)
582 using unit1 = unit<Rep1, Ratio1, UnitType1>;
583 using unit2 = unit<Rep2, Ratio2, UnitType2>;
584 using common_type =
typename std::common_type<unit1, unit2>::type;
586 return std::isless(unit_cast<common_type>(lhs).count(), unit_cast<common_type>(rhs).count());
589 template <
typename Rep1,
typename Ratio1,
typename UnitType1,
typename Rep2,
typename Ratio2,
typename UnitType2>
590 constexpr
bool operator<=(unit<Rep1, Ratio1, UnitType1> lhs, unit<Rep2, Ratio2, UnitType2> rhs)
592 using unit1 = unit<Rep1, Ratio1, UnitType1>;
593 using unit2 = unit<Rep2, Ratio2, UnitType2>;
594 using common_type =
typename std::common_type<unit1, unit2>::type;
596 return std::islessequal(unit_cast<common_type>(lhs).count(), unit_cast<common_type>(rhs).count());
599 template <
typename Rep1,
typename Ratio1,
typename UnitType1,
typename Rep2,
typename Ratio2,
typename UnitType2>
600 constexpr
bool operator>(unit<Rep1, Ratio1, UnitType1> lhs, unit<Rep2, Ratio2, UnitType2> rhs)
602 using unit1 = unit<Rep1, Ratio1, UnitType1>;
603 using unit2 = unit<Rep2, Ratio2, UnitType2>;
604 using common_type =
typename std::common_type<unit1, unit2>::type;
606 return std::isgreater(unit_cast<common_type>(lhs).count(), unit_cast<common_type>(rhs).count());
609 template <
typename Rep1,
typename Ratio1,
typename UnitType1,
typename Rep2,
typename Ratio2,
typename UnitType2>
610 constexpr
bool operator>=(unit<Rep1, Ratio1, UnitType1> lhs, unit<Rep2, Ratio2, UnitType2> rhs)
612 using unit1 = unit<Rep1, Ratio1, UnitType1>;
613 using unit2 = unit<Rep2, Ratio2, UnitType2>;
614 using common_type =
typename std::common_type<unit1, unit2>::type;
616 return std::isgreaterequal(unit_cast<common_type>(lhs).count(), unit_cast<common_type>(rhs).count());
621 template <
typename ToUnit,
624 bool RatioNumIsOne =
false,
625 bool RatioDenIsOne =
false>
628 template <
typename Rep,
typename Length,
typename UnitType>
629 static constexpr ToUnit cast(unit<Rep, Length, UnitType> from)
631 using ToRep =
typename ToUnit::rep;
632 return ToUnit{
static_cast<ToRep
>(
static_cast<CommonType
>(from.count())
633 / static_cast<CommonType>(Ratio::num)
634 *
static_cast<CommonType
>(Ratio::den))};
638 template <
typename ToUnit,
typename Ratio,
typename CommonType>
639 struct unit_cast<ToUnit, Ratio, CommonType, true, true>
641 template <
typename Rep,
typename Length,
typename UnitType>
642 static constexpr ToUnit cast(unit<Rep, Length, UnitType> from)
644 using ToRep =
typename ToUnit::rep;
645 return ToUnit{
static_cast<ToRep
>(
static_cast<CommonType
>(from.count()))};
649 template <
typename ToUnit,
typename Ratio,
typename CommonType>
650 struct unit_cast<ToUnit, Ratio, CommonType, true, false>
652 template <
typename Rep,
typename Length,
typename UnitType>
653 static constexpr ToUnit cast(unit<Rep, Length, UnitType> from)
655 using ToRep =
typename ToUnit::rep;
657 static_cast<ToRep
>(
static_cast<CommonType
>(from.count()) * static_cast<CommonType>(Ratio::den))};
661 template <
typename ToUnit,
typename Ratio,
typename CommonType>
662 struct unit_cast<ToUnit, Ratio, CommonType, false, true>
664 template <
typename Rep,
typename Length,
typename UnitType>
665 static constexpr ToUnit cast(unit<Rep, Length, UnitType> from)
667 using ToRep =
typename ToUnit::rep;
669 static_cast<ToRep
>(
static_cast<CommonType
>(from.count()) / static_cast<CommonType>(Ratio::num))};
674 template <
typename ToUnit,
typename Rep,
typename Ratio,
typename UnitType>
675 constexpr
auto unit_cast(unit<Rep, Ratio, UnitType> from) ->
676 typename std::enable_if<is_unit<ToUnit>::value, ToUnit>::type
678 static_assert(std::is_same<typename ToUnit::unit_type, UnitType>::value,
"Incompatible types");
680 using ToRatio =
typename ToUnit::ratio;
681 using ToRep =
typename ToUnit::rep;
682 using CommonType =
typename std::common_type<ToRep, Rep, intmax_t>::type;
683 using CommonRatio = std::ratio_divide<ToRatio, Ratio>;
685 return detail::unit_cast<ToUnit, CommonRatio, CommonType, CommonRatio::num == 1, CommonRatio::den == 1>::cast(
690 inline namespace literals
692 namespace distance_literals
720 constexpr
units::metres operator"" _m(
unsigned long long int dist)
731 constexpr
units::thous operator"" _th(
unsigned long long int dist)
733 return units::thous{
static_cast<units::thous::rep
>(dist)};
736 constexpr
units::inches operator"" _in(
unsigned long long int dist)
741 constexpr
units::links operator"" _li(
unsigned long long int dist)
743 return units::links{
static_cast<units::links::rep
>(dist)};
746 constexpr
units::feet operator"" _ft(
unsigned long long int dist)
748 return units::feet{
static_cast<units::feet::rep
>(dist)};
751 constexpr
units::yards operator"" _yd(
unsigned long long int dist)
753 return units::yards{
static_cast<units::yards::rep
>(dist)};
756 constexpr
units::rods operator"" _rd(
unsigned long long int dist)
758 return units::rods{
static_cast<units::rods::rep
>(dist)};
761 constexpr
units::chains operator"" _ch(
unsigned long long int dist)
771 constexpr
units::miles operator"" _mi(
unsigned long long int dist)
773 return units::miles{
static_cast<units::miles::rep
>(dist)};
776 constexpr
units::leagues operator"" _lea(
unsigned long long int dist)
782 constexpr
units::fathoms operator"" _ftm(
unsigned long long int dist)
787 constexpr
units::cables operator"" _cb(
unsigned long long int dist)
823 constexpr
units::parsecs operator"" _pc(
unsigned long long int dist)
829 namespace mass_literals
852 constexpr
units::grams operator"" _g(
unsigned long long int mass)
854 return units::grams{
static_cast<units::grams::rep
>(mass)};
863 constexpr
units::grains operator"" _gr(
unsigned long long int mass)
868 constexpr
units::drams operator"" _dr(
unsigned long long int mass)
870 return units::drams{
static_cast<units::drams::rep
>(mass)};
873 constexpr
units::ounces operator"" _oz(
unsigned long long int mass)
878 constexpr
units::pounds operator"" _lb(
unsigned long long int mass)
892 #ifndef UNITS_DISABLE_IOSTREAM
895 template <
typename Ratio>
896 inline std::string get_prefix();
899 inline std::string get_prefix<std::ratio<1>>()
905 inline std::string get_prefix<std::pico>()
911 inline std::string get_prefix<std::nano>()
917 inline std::string get_prefix<std::micro>()
923 inline std::string get_prefix<std::milli>()
929 inline std::string get_prefix<std::centi>()
935 inline std::string get_prefix<std::deci>()
941 inline std::string get_prefix<std::kilo>()
946 template <
typename UnitType>
947 inline std::string get_unit();
950 inline std::string get_unit<unit_type::distance>()
956 inline std::string get_unit<unit_type::mass>()
961 template <
typename Ratio,
typename UnitType>
962 inline std::string get_unit()
964 return get_prefix<Ratio>() + get_unit<UnitType>();
968 inline std::string get_unit<thous::ratio, unit_type::distance>()
974 inline std::string get_unit<inches::ratio, unit_type::distance>()
980 inline std::string get_unit<links::ratio, unit_type::distance>()
986 inline std::string get_unit<feet::ratio, unit_type::distance>()
992 inline std::string get_unit<yards::ratio, unit_type::distance>()
998 inline std::string get_unit<rods::ratio, unit_type::distance>()
1004 inline std::string get_unit<chains::ratio, unit_type::distance>()
1010 inline std::string get_unit<furlongs::ratio, unit_type::distance>()
1016 inline std::string get_unit<miles::ratio, unit_type::distance>()
1022 inline std::string get_unit<leagues::ratio, unit_type::distance>()
1028 inline std::string get_unit<fathoms::ratio, unit_type::distance>()
1034 inline std::string get_unit<cables::ratio, unit_type::distance>()
1040 inline std::string get_unit<nautical_miles::ratio, unit_type::distance>()
1046 inline std::string get_unit<earth_radii::ratio, unit_type::distance>()
1052 inline std::string get_unit<lunar_distances::ratio, unit_type::distance>()
1058 inline std::string get_unit<astronimical_units::ratio, unit_type::distance>()
1064 inline std::string get_unit<light_years::ratio, unit_type::distance>()
1070 inline std::string get_unit<parsecs::ratio, unit_type::distance>()
1076 inline std::string get_unit<grains::ratio, unit_type::mass>()
1082 inline std::string get_unit<drams::ratio, unit_type::mass>()
1088 inline std::string get_unit<ounces::ratio, unit_type::mass>()
1094 inline std::string get_unit<pounds::ratio, unit_type::mass>()
1100 inline std::string get_unit<us_hundredweight::ratio, unit_type::mass>()
1106 template <
typename CharT,
typename Traits,
typename Rep,
typename Ratio,
typename UnitType>
1107 inline std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os,
1108 unit<Rep, Ratio, UnitType>
const& u)
1110 return os << u.count() << detail::get_unit<Ratio, UnitType>();