50 # pragma push_macro("pascal")
53 # define _ALLOW_KEYWORD_MACROS
54 # pragma warning(push)
55 # pragma warning(disable : 4520)
56 # pragma push_macro("constexpr")
58 # pragma push_macro("noexcept")
59 # define noexcept throw()
60 # endif // _MSC_VER < 1800
63 #if !defined(_MSC_VER) || _MSC_VER > 1800
64 # define UNIT_HAS_LITERAL_SUPPORT
65 # define UNIT_HAS_VARIADIC_TEMPLATE_SUPPORT
68 #ifndef UNIT_LIB_DEFAULT_TYPE
69 # define UNIT_LIB_DEFAULT_TYPE double
78 #include <type_traits>
83 #if !defined(UNIT_LIB_DISABLE_IOSTREAM)
96 template <
typename T> std::string to_string(
const T& t)
98 std::string str{ std::to_string(t) };
104 char decimalPoint = *lc->decimal_point;
105 if (str.find_last_not_of(
'0') == str.find(decimalPoint)) { offset = 0; }
106 str.erase(str.find_last_not_of(
'0') + offset, std::string::npos);
115 template<
typename T>
inline constexpr
const char* name(
const T&);
116 template<
typename T>
inline constexpr
const char* abbreviation(
const T&);
139 #define UNIT_ADD_UNIT_TAGS(namespaceName,nameSingular, namePlural, abbreviation, ...)\
140 namespace namespaceName\
142 typedef __VA_ARGS__ namePlural; \
143 typedef namePlural nameSingular; \
144 typedef namePlural abbreviation; \
154 #define UNIT_ADD_UNIT_DEFINITION(namespaceName,nameSingular)\
155 namespace namespaceName\
157 typedef unit_t<nameSingular> nameSingular ## _t; \
168 #define UNIT_ADD_CUSTOM_TYPE_UNIT_DEFINITION(namespaceName,nameSingular, underlyingType)\
169 namespace namespaceName\
171 typedef unit_t<nameSingular,underlyingType> nameSingular ## _t; \
183 #if defined(UNIT_LIB_DISABLE_IOSTREAM)
184 #define UNIT_ADD_IO(namespaceName, nameSingular, abbrev)
186 #define UNIT_ADD_IO(namespaceName, nameSingular, abbrev)\
187 namespace namespaceName\
189 inline std::ostream& operator<<(std::ostream& os, const nameSingular ## _t& obj) \
191 os << obj() << " "#abbrev; return os; \
193 inline std::string to_string(const nameSingular ## _t& obj)\
195 return units::detail::to_string(obj()) + std::string(" "#abbrev);\
210 #define UNIT_ADD_NAME(namespaceName, nameSingular, abbrev)\
211 template<> inline constexpr const char* name(const namespaceName::nameSingular ## _t&)\
213 return #nameSingular;\
215 template<> inline constexpr const char* abbreviation(const namespaceName::nameSingular ## _t&)\
231 #if defined(UNIT_HAS_LITERAL_SUPPORT)
232 #define UNIT_ADD_LITERALS(namespaceName, nameSingular, abbreviation)\
235 inline constexpr namespaceName::nameSingular ## _t operator""_ ## abbreviation(long double d)\
237 return namespaceName::nameSingular ## _t(static_cast<namespaceName::nameSingular ## _t::underlying_type>(d));\
239 inline constexpr namespaceName::nameSingular ## _t operator""_ ## abbreviation (unsigned long long d)\
241 return namespaceName::nameSingular ## _t(static_cast<namespaceName::nameSingular ## _t::underlying_type>(d));\
245 #define UNIT_ADD_LITERALS(namespaceName, nameSingular, abbreviation)
267 #define UNIT_ADD(namespaceName, nameSingular, namePlural, abbreviation, ...)\
268 UNIT_ADD_UNIT_TAGS(namespaceName,nameSingular, namePlural, abbreviation, __VA_ARGS__)\
269 UNIT_ADD_UNIT_DEFINITION(namespaceName,nameSingular)\
270 UNIT_ADD_NAME(namespaceName,nameSingular, abbreviation)\
271 UNIT_ADD_IO(namespaceName,nameSingular, abbreviation)\
272 UNIT_ADD_LITERALS(namespaceName,nameSingular, abbreviation)
294 #define UNIT_ADD_WITH_CUSTOM_TYPE(namespaceName, nameSingular, namePlural, abbreviation, underlyingType, ...)\
295 UNIT_ADD_UNIT_TAGS(namespaceName,nameSingular, namePlural, abbreviation, __VA_ARGS__)\
296 UNIT_ADD_CUSTOM_TYPE_UNIT_DEFINITION(namespaceName,nameSingular,underlyingType)\
297 UNIT_ADD_IO(namespaceName,nameSingular, abbreviation)\
298 UNIT_ADD_LITERALS(namespaceName,nameSingular, abbreviation)
309 #define UNIT_ADD_DECIBEL(namespaceName, nameSingular, abbreviation)\
310 namespace namespaceName\
312 typedef unit_t<nameSingular, UNIT_LIB_DEFAULT_TYPE, units::decibel_scale> abbreviation ## _t; \
314 UNIT_ADD_IO(namespaceName, abbreviation, abbreviation)\
315 UNIT_ADD_LITERALS(namespaceName, abbreviation, abbreviation)
326 #define UNIT_ADD_CATEGORY_TRAIT_DETAIL(unitCategory)\
332 template<typename T> struct is_ ## unitCategory ## _unit_impl : std::false_type {};\
333 template<typename C, typename U, typename P, typename T>\
334 struct is_ ## unitCategory ## _unit_impl<units::unit<C, U, P, T>> : std::is_same<units::traits::base_unit_of<typename units::traits::unit_traits<units::unit<C, U, P, T>>::base_unit_type>, units::category::unitCategory ## _unit>::type {};\
335 template<typename U, typename S, template<typename> class N>\
336 struct is_ ## unitCategory ## _unit_impl<units::unit_t<U, S, N>> : std::is_same<units::traits::base_unit_of<typename units::traits::unit_t_traits<units::unit_t<U, S, N>>::unit_type>, units::category::unitCategory ## _unit>::type {};\
341 #if defined(UNIT_HAS_VARIADIC_TEMPLATE_SUPPORT)
342 #define UNIT_ADD_IS_UNIT_CATEGORY_TRAIT(unitCategory)\
345 template<typename... T> struct is_ ## unitCategory ## _unit : std::integral_constant<bool, units::all_true<units::traits::detail::is_ ## unitCategory ## _unit_impl<std::decay_t<T>>::value...>::value> {};\
348 #define UNIT_ADD_IS_UNIT_CATEGORY_TRAIT(unitCategory)\
351 template<typename T1, typename T2 = T1, typename T3 = T1>\
352 struct is_ ## unitCategory ## _unit : std::integral_constant<bool, units::traits::detail::is_ ## unitCategory ## _unit_impl<typename std::decay<T1>::type>::value &&\
353 units::traits::detail::is_ ## unitCategory ## _unit_impl<typename std::decay<T2>::type>::value &&\
354 units::traits::detail::is_ ## unitCategory ## _unit_impl<typename std::decay<T3>::type>::value>{};\
358 #define UNIT_ADD_CATEGORY_TRAIT(unitCategory)\
359 UNIT_ADD_CATEGORY_TRAIT_DETAIL(unitCategory)\
364 UNIT_ADD_IS_UNIT_CATEGORY_TRAIT(unitCategory)
384 #define UNIT_ADD_WITH_METRIC_PREFIXES(namespaceName, nameSingular, namePlural, abbreviation, ...)\
385 UNIT_ADD(namespaceName, nameSingular, namePlural, abbreviation, __VA_ARGS__)\
386 UNIT_ADD(namespaceName, femto ## nameSingular, femto ## namePlural, f ## abbreviation, femto<namePlural>)\
387 UNIT_ADD(namespaceName, pico ## nameSingular, pico ## namePlural, p ## abbreviation, pico<namePlural>)\
388 UNIT_ADD(namespaceName, nano ## nameSingular, nano ## namePlural, n ## abbreviation, nano<namePlural>)\
389 UNIT_ADD(namespaceName, micro ## nameSingular, micro ## namePlural, u ## abbreviation, micro<namePlural>)\
390 UNIT_ADD(namespaceName, milli ## nameSingular, milli ## namePlural, m ## abbreviation, milli<namePlural>)\
391 UNIT_ADD(namespaceName, centi ## nameSingular, centi ## namePlural, c ## abbreviation, centi<namePlural>)\
392 UNIT_ADD(namespaceName, deci ## nameSingular, deci ## namePlural, d ## abbreviation, deci<namePlural>)\
393 UNIT_ADD(namespaceName, deca ## nameSingular, deca ## namePlural, da ## abbreviation, deca<namePlural>)\
394 UNIT_ADD(namespaceName, hecto ## nameSingular, hecto ## namePlural, h ## abbreviation, hecto<namePlural>)\
395 UNIT_ADD(namespaceName, kilo ## nameSingular, kilo ## namePlural, k ## abbreviation, kilo<namePlural>)\
396 UNIT_ADD(namespaceName, mega ## nameSingular, mega ## namePlural, M ## abbreviation, mega<namePlural>)\
397 UNIT_ADD(namespaceName, giga ## nameSingular, giga ## namePlural, G ## abbreviation, giga<namePlural>)\
398 UNIT_ADD(namespaceName, tera ## nameSingular, tera ## namePlural, T ## abbreviation, tera<namePlural>)\
399 UNIT_ADD(namespaceName, peta ## nameSingular, peta ## namePlural, P ## abbreviation, peta<namePlural>)\
419 #define UNIT_ADD_WITH_METRIC_AND_BINARY_PREFIXES(namespaceName, nameSingular, namePlural, abbreviation, ...)\
420 UNIT_ADD_WITH_METRIC_PREFIXES(namespaceName, nameSingular, namePlural, abbreviation, __VA_ARGS__)\
421 UNIT_ADD(namespaceName, kibi ## nameSingular, kibi ## namePlural, Ki ## abbreviation, kibi<namePlural>)\
422 UNIT_ADD(namespaceName, mebi ## nameSingular, mebi ## namePlural, Mi ## abbreviation, mebi<namePlural>)\
423 UNIT_ADD(namespaceName, gibi ## nameSingular, gibi ## namePlural, Gi ## abbreviation, gibi<namePlural>)\
424 UNIT_ADD(namespaceName, tebi ## nameSingular, tebi ## namePlural, Ti ## abbreviation, tebi<namePlural>)\
425 UNIT_ADD(namespaceName, pebi ## nameSingular, pebi ## namePlural, Pi ## abbreviation, pebi<namePlural>)\
426 UNIT_ADD(namespaceName, exbi ## nameSingular, exbi ## namePlural, Ei ## abbreviation, exbi<namePlural>)
494 static constexpr
const UNIT_LIB_DEFAULT_TYPE PI_VAL = 3.14159265358979323846264338327950288419716939937510;
516 static constexpr
auto test(U*)->std::is_integral<decltype(U::num)> {
return std::is_integral<decltype(U::num)>{}; }
518 static constexpr std::false_type test(...) {
return std::false_type{}; }
520 using type = decltype(test<T>(0));
530 struct has_num : units::detail::has_num_impl<T>::type {};
539 static constexpr
auto test(U*)->std::is_integral<decltype(U::den)> {
return std::is_integral<decltype(U::den)>{}; }
541 static constexpr std::false_type test(...) {
return std::false_type{}; }
543 using type = decltype(test<T>(0));
553 struct has_den : units::detail::has_den_impl<T>::type {};
581 struct void_t {
typedef void type; };
586 template<
bool...>
struct bool_pack {};
591 template<
bool... Args>
592 struct all_true : std::is_same<units::bool_pack<true, Args...>, units::bool_pack<Args..., true>> {};
600 #ifdef FOR_DOXYGEN_PURPOSES_ONLY
611 typedef typename T::base_unit_type base_unit_type;
612 typedef typename T::conversion_ratio conversion_ratio;
613 typedef typename T::pi_exponent_ratio pi_exponent_ratio;
614 typedef typename T::translation_ratio translation_ratio;
621 template<
class T,
typename =
void>
624 typedef void base_unit_type;
625 typedef void conversion_ratio;
626 typedef void pi_exponent_ratio;
627 typedef void translation_ratio;
633 typename T::base_unit_type,
634 typename T::conversion_ratio,
635 typename T::pi_exponent_ratio,
636 typename T::translation_ratio>::type>
638 typedef typename T::base_unit_type base_unit_type;
639 typedef typename T::conversion_ratio conversion_ratio;
640 typedef typename T::pi_exponent_ratio pi_exponent_ratio;
641 typedef typename T::translation_ratio translation_ratio;
653 struct _base_unit_t {};
666 struct is_base_unit : std::is_base_of<units::detail::_base_unit_t, T> {};
678 template<std::
intmax_t Num, std::
intmax_t Den = 1>
679 using meter_ratio = std::ratio<Num, Den>;
692 struct is_unit : std::is_base_of<units::detail::_unit, T>::type {};
719 template<
class Meter = detail::meter_ratio<0>,
720 class Kilogram = std::ratio<0>,
721 class Second = std::ratio<0>,
722 class Radian = std::ratio<0>,
723 class Ampere = std::ratio<0>,
724 class Kelvin = std::ratio<0>,
725 class Mole = std::ratio<0>,
726 class Candela = std::ratio<0>,
727 class Byte = std::ratio<0>>
730 static_assert(
traits::is_ratio<Meter>::value,
"Template parameter `Meter` must be a `std::ratio` representing the exponent of meters the unit has");
732 static_assert(
traits::is_ratio<Second>::value,
"Template parameter `Second` must be a `std::ratio` representing the exponent of seconds the unit has");
733 static_assert(
traits::is_ratio<Ampere>::value,
"Template parameter `Ampere` must be a `std::ratio` representing the exponent of amperes the unit has");
736 static_assert(
traits::is_ratio<Mole>::value,
"Template parameter `Mole` must be a `std::ratio` representing the exponent of moles the unit has");
737 static_assert(
traits::is_ratio<Radian>::value,
"Template parameter `Radian` must be a `std::ratio` representing the exponent of radians the unit has");
738 static_assert(
traits::is_ratio<Byte>::value,
"Template parameter `Byte` must be a `std::ratio` representing the exponent of bytes the unit has");
740 typedef Meter meter_ratio;
741 typedef Kilogram kilogram_ratio;
742 typedef Second second_ratio;
743 typedef Radian radian_ratio;
744 typedef Ampere ampere_ratio;
745 typedef Kelvin kelvin_ratio;
746 typedef Mole mole_ratio;
747 typedef Candela candela_ratio;
748 typedef Byte byte_ratio;
796 typedef base_unit<detail::meter_ratio<-2>, std::ratio<0>, std::ratio<0>, std::ratio<2>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>>
illuminance_unit;
818 template <
class,
class,
class,
class>
struct unit;
819 template<
class Conversion,
class... Exponents,
class PiExponent,
class Translation>
820 struct unit<Conversion,
base_unit<Exponents...>, PiExponent, Translation> : units::detail::_unit
824 static_assert(
traits::is_ratio<Translation>::value,
"Template parameter `Translation` must be a `std::ratio` representing an additive translation required by the unit conversion.");
827 typedef Conversion conversion_ratio;
828 typedef Translation translation_ratio;
829 typedef PiExponent pi_exponent_ratio;
852 template<
class Conversion,
class BaseUnit,
class PiExponent = std::ratio<0>,
class Translation = std::ratio<0>>
853 struct unit : units::detail::_unit
859 typedef typename units::traits::unit_traits<BaseUnit>::base_unit_type base_unit_type;
860 typedef typename std::ratio_multiply<typename BaseUnit::conversion_ratio, Conversion> conversion_ratio;
861 typedef typename std::ratio_add<typename BaseUnit::pi_exponent_ratio, PiExponent> pi_exponent_ratio;
862 typedef typename std::ratio_add<std::ratio_multiply<typename BaseUnit::conversion_ratio, Translation>,
typename BaseUnit::translation_ratio> translation_ratio;
877 template<
class>
struct base_unit_of_impl;
878 template<
class Conversion,
class BaseUnit,
class PiExponent,
class Translation>
879 struct base_unit_of_impl<
unit<Conversion, BaseUnit, PiExponent, Translation>> : base_unit_of_impl<BaseUnit> {};
880 template<
class... Exponents>
881 struct base_unit_of_impl<base_unit<Exponents...>>
883 typedef base_unit<Exponents...> type;
886 struct base_unit_of_impl<void>
902 using base_unit_of =
typename units::detail::base_unit_of_impl<U>::type;
913 template<
class,
class>
struct base_unit_multiply_impl;
914 template<
class... Exponents1,
class... Exponents2>
922 template<
class U1,
class U2>
923 using base_unit_multiply =
typename base_unit_multiply_impl<U1, U2>::type;
930 template<
class,
class>
struct base_unit_divide_impl;
931 template<
class... Exponents1,
class... Exponents2>
932 struct base_unit_divide_impl<base_unit<Exponents1...>, base_unit<Exponents2...>> {
933 using type = base_unit<std::ratio_subtract<Exponents1, Exponents2>...>;
939 template<
class U1,
class U2>
940 using base_unit_divide =
typename base_unit_divide_impl<U1, U2>::type;
947 template<
class>
struct inverse_base_impl;
949 template<
class... Exponents>
950 struct inverse_base_impl<base_unit<Exponents...>> {
951 using type = base_unit<std::ratio_multiply<Exponents, std::ratio<-1>>...>;
958 template<
class U>
using inverse_base =
typename inverse_base_impl<U>::type;
965 template<
class U>
struct squared_base_impl;
966 template<
class... Exponents>
967 struct squared_base_impl<base_unit<Exponents...>> {
968 using type = base_unit<std::ratio_multiply<Exponents, std::ratio<2>>...>;
975 template<
class U>
using squared_base =
typename squared_base_impl<U>::type;
982 template<
class U>
struct cubed_base_impl;
983 template<
class... Exponents>
984 struct cubed_base_impl<base_unit<Exponents...>> {
985 using type = base_unit<std::ratio_multiply<Exponents, std::ratio<3>>...>;
992 template<
class U>
using cubed_base =
typename cubed_base_impl<U>::type;
999 template<
class U>
struct sqrt_base_impl;
1000 template<
class... Exponents>
1001 struct sqrt_base_impl<base_unit<Exponents...>> {
1002 using type = base_unit<std::ratio_divide<Exponents, std::ratio<2>>...>;
1009 template<
class U>
using sqrt_base =
typename sqrt_base_impl<U>::type;
1016 template<
class U>
struct cbrt_base_impl;
1017 template<
class... Exponents>
1018 struct cbrt_base_impl<base_unit<Exponents...>> {
1019 using type = base_unit<std::ratio_divide<Exponents, std::ratio<3>>...>;
1026 template<
class U>
using cbrt_base =
typename cbrt_base_impl<U>::type;
1043 template<
class Unit1,
class Unit2>
1044 struct unit_multiply_impl
1046 using type = unit < std::ratio_multiply<typename Unit1::conversion_ratio, typename Unit2::conversion_ratio>,
1047 base_unit_multiply <traits::base_unit_of<typename Unit1::base_unit_type>, traits::base_unit_of<typename Unit2::base_unit_type>>,
1048 std::ratio_add<typename Unit1::pi_exponent_ratio, typename Unit2::pi_exponent_ratio>,
1056 template<
class U1,
class U2>
1057 using unit_multiply =
typename unit_multiply_impl<U1, U2>::type;
1065 template<
class Unit1,
class Unit2>
1066 struct unit_divide_impl
1068 using type = unit < std::ratio_divide<typename Unit1::conversion_ratio, typename Unit2::conversion_ratio>,
1069 base_unit_divide<traits::base_unit_of<typename Unit1::base_unit_type>, traits::base_unit_of<typename Unit2::base_unit_type>>,
1070 std::ratio_subtract<typename Unit1::pi_exponent_ratio, typename Unit2::pi_exponent_ratio>,
1078 template<
class U1,
class U2>
1079 using unit_divide =
typename unit_divide_impl<U1, U2>::type;
1087 template<
class Unit>
1090 using type = unit < std::ratio<Unit::conversion_ratio::den, Unit::conversion_ratio::num>,
1091 inverse_base<traits::base_unit_of<typename units::traits::unit_traits<Unit>::base_unit_type>>,
1092 std::ratio_multiply<typename units::traits::unit_traits<Unit>::pi_exponent_ratio, std::ratio<-1>>,
1104 template<
class U>
using inverse =
typename units::detail::inverse_impl<U>::type;
1114 template<
class Unit>
1118 using Conversion =
typename Unit::conversion_ratio;
1120 squared_base<traits::base_unit_of<typename Unit::base_unit_type>>,
1121 std::ratio_multiply<typename Unit::pi_exponent_ratio, std::ratio<2>>,
1122 typename Unit::translation_ratio
1135 using squared =
typename units::detail::squared_impl<U>::type;
1145 template<
class Unit>
1149 using Conversion =
typename Unit::conversion_ratio;
1151 cubed_base<traits::base_unit_of<typename Unit::base_unit_type>>,
1152 std::ratio_multiply<typename Unit::pi_exponent_ratio, std::ratio<3>>,
1153 typename Unit::translation_ratio> ;
1165 using cubed =
typename units::detail::cubed_impl<U>::type;
1174 using Zero = std::ratio<0>;
1175 using One = std::ratio<1>;
1176 template <
typename R>
using Square = std::ratio_multiply<R, R>;
1179 template <
template <std::
intmax_t N>
class Predicate,
typename enabled =
void>
1180 struct BinarySearch {
1181 template <std::
intmax_t N>
1182 struct SafeDouble_ {
1183 static constexpr
const std::intmax_t value = 2 * N;
1184 static_assert(value > 0,
"Overflows when computing 2 * N");
1187 template <
intmax_t Lower,
intmax_t Upper,
typename Condition1 =
void,
typename Condition2 =
void>
1188 struct DoubleSidedSearch_ : DoubleSidedSearch_<Lower, Upper,
1189 std::integral_constant<bool, (Upper - Lower == 1)>,
1190 std::integral_constant<bool, ((Upper - Lower>1 && Predicate<Lower + (Upper - Lower) / 2>::value))>> {};
1192 template <
intmax_t Lower,
intmax_t Upper>
1193 struct DoubleSidedSearch_<Lower, Upper, std::false_type, std::false_type> : DoubleSidedSearch_<Lower, Lower + (Upper - Lower) / 2> {};
1195 template <
intmax_t Lower,
intmax_t Upper,
typename Condition2>
1196 struct DoubleSidedSearch_<Lower, Upper, std::true_type, Condition2> : std::integral_constant<intmax_t, Lower>{};
1198 template <
intmax_t Lower,
intmax_t Upper,
typename Condition1>
1199 struct DoubleSidedSearch_<Lower, Upper, Condition1, std::true_type> : DoubleSidedSearch_<Lower + (Upper - Lower) / 2, Upper>{};
1201 template <std::
intmax_t Lower,
class enabled1 =
void>
1202 struct SingleSidedSearch_ : SingleSidedSearch_<Lower, std::integral_constant<bool, Predicate<SafeDouble_<Lower>::value>::value>>{};
1204 template <std::
intmax_t Lower>
1205 struct SingleSidedSearch_<Lower, std::false_type> : DoubleSidedSearch_<Lower, SafeDouble_<Lower>::value> {};
1207 template <std::
intmax_t Lower>
1208 struct SingleSidedSearch_<Lower, std::true_type> : SingleSidedSearch_<SafeDouble_<Lower>::value>{};
1210 static constexpr
const std::intmax_t value = SingleSidedSearch_<1>::value;
1213 template <
template <std::
intmax_t N>
class Predicate>
1214 struct BinarySearch<Predicate, std::enable_if_t<!Predicate<1>::value>> : std::integral_constant<std::intmax_t, 0>{};
1217 template <
typename R>
1219 template <std::
intmax_t N>
using Predicate_ = std::ratio_less_equal<std::ratio<N>, std::ratio_divide<R, std::ratio<N>>>;
1220 static constexpr
const std::intmax_t value = BinarySearch<Predicate_>::value;
1223 template <
typename R>
1224 struct IsPerfectSquare {
1225 static constexpr
const std::intmax_t DenSqrt_ = Integer<std::ratio<R::den>>::value;
1226 static constexpr
const std::intmax_t NumSqrt_ = Integer<std::ratio<R::num>>::value;
1227 static constexpr
const bool value =( DenSqrt_ * DenSqrt_ == R::den && NumSqrt_ * NumSqrt_ == R::num);
1228 using Sqrt = std::ratio<NumSqrt_, DenSqrt_>;
1232 template <
typename Tp,
typename Tq>
1239 template <
typename R>
1241 using P_ =
typename R::P;
1242 using Q_ =
typename R::Q;
1243 using Den_ = std::ratio_subtract<P_, Square<Q_>>;
1244 using A_ = std::ratio_divide<Q_, Den_>;
1245 using B_ = std::ratio_divide<P_, Square<Den_>>;
1246 static constexpr
const std::intmax_t I_ = (A_::num + Integer<std::ratio_multiply<B_, Square<std::ratio<A_::den>>>>::value) / A_::den;
1247 using I = std::ratio<I_>;
1248 using Rem = Remainder<B_, std::ratio_subtract<I, A_>>;
1255 template <
typename Tr, std::
intmax_t N>
1256 struct ContinuedFraction {
1257 template <
typename T>
1258 using Abs_ = std::conditional_t<std::ratio_less<T, Zero>::value, std::ratio_subtract<Zero, T>, T>;
1261 using Last_ = ContinuedFraction<
R, N - 1>;
1262 using Reciprocal_ = Reciprocal<typename Last_::Rem>;
1263 using Rem =
typename Reciprocal_::Rem;
1264 using I_ =
typename Reciprocal_::I;
1265 using Den_ = std::ratio_add<typename Last_::W, I_>;
1266 using U = std::ratio_divide<typename Last_::V, Den_>;
1267 using V = std::ratio_divide<std::ratio_add<typename Last_::U, std::ratio_multiply<typename Last_::V, I_>>, Den_>;
1268 using W = std::ratio_divide<One, Den_>;
1269 using Error = Abs_<std::ratio_divide<std::ratio_subtract<U, std::ratio_multiply<V, W>>,
typename Reciprocal<Rem>::I>>;
1272 template <
typename Tr>
1273 struct ContinuedFraction<Tr, 1> {
1276 using V = std::ratio<Integer<R>::value>;
1278 using Rem = Remainder<R, V>;
1279 using Error = std::ratio_divide<One, typename Reciprocal<Rem>::I>;
1282 template <
typename R,
typename Eps, std::
intmax_t N = 1,
typename enabled =
void>
1283 struct Sqrt_ : Sqrt_<R, Eps, N + 1> {};
1285 template <
typename R,
typename Eps, std::
intmax_t N>
1286 struct Sqrt_<
R, Eps, N, std::enable_if_t<std::ratio_less_equal<typename ContinuedFraction<R, N>::Error, Eps>::value>> {
1287 using type =
typename ContinuedFraction<R, N>::V;
1290 template <
typename R,
typename Eps,
typename enabled =
void>
1292 static_assert(std::ratio_greater_equal<R, Zero>::value,
"R can't be negative");
1295 template <
typename R,
typename Eps>
1296 struct Sqrt<
R, Eps, std::enable_if_t<std::ratio_greater_equal<R, Zero>::value && IsPerfectSquare<R>::value>> {
1297 using type =
typename IsPerfectSquare<R>::Sqrt;
1300 template <
typename R,
typename Eps>
1301 struct Sqrt<
R, Eps, std::enable_if_t<(std::ratio_greater_equal<R, Zero>::value && !IsPerfectSquare<R>::value)>> : Sqrt_<R, Eps>{};
1325 template<
typename Ratio, std::
intmax_t Eps = 10000000000>
1326 using ratio_sqrt =
typename units::detail::Sqrt<Ratio, std::ratio<1, Eps>>::type;
1336 template<
class Unit, std::
intmax_t Eps>
1340 using Conversion =
typename Unit::conversion_ratio;
1342 sqrt_base<traits::base_unit_of<typename Unit::base_unit_type>>,
1343 std::ratio_divide<typename Unit::pi_exponent_ratio, std::ratio<2>>,
1344 typename Unit::translation_ratio>;
1370 template<
class U, std::
intmax_t Eps = 10000000000>
1385 template<
class U,
class... Us>
struct compound_impl;
1386 template<
class U>
struct compound_impl<U> {
using type = U; };
1387 template<
class U1,
class U2,
class...Us>
1388 struct compound_impl<U1, U2, Us...>
1389 : compound_impl<unit_multiply<U1, U2>, Us...> {};
1403 template<
class U,
class... Us>
1417 template<
class Ratio,
class Unit>
1426 template <
int N,
class U>
1427 struct power_of_ratio
1429 typedef std::ratio_multiply<U,
typename power_of_ratio<N - 1, U>::type> type;
1434 struct power_of_ratio<1, U>
1447 template<
class U>
using atto =
typename units::detail::prefix<std::atto, U>::type;
1448 template<
class U>
using femto =
typename units::detail::prefix<std::femto,U>::type;
1449 template<
class U>
using pico =
typename units::detail::prefix<std::pico, U>::type;
1450 template<
class U>
using nano =
typename units::detail::prefix<std::nano, U>::type;
1451 template<
class U>
using micro =
typename units::detail::prefix<std::micro,U>::type;
1452 template<
class U>
using milli =
typename units::detail::prefix<std::milli,U>::type;
1453 template<
class U>
using centi =
typename units::detail::prefix<std::centi,U>::type;
1454 template<
class U>
using deci =
typename units::detail::prefix<std::deci, U>::type;
1455 template<
class U>
using deca =
typename units::detail::prefix<std::deca, U>::type;
1456 template<
class U>
using hecto =
typename units::detail::prefix<std::hecto,U>::type;
1457 template<
class U>
using kilo =
typename units::detail::prefix<std::kilo, U>::type;
1458 template<
class U>
using mega =
typename units::detail::prefix<std::mega, U>::type;
1459 template<
class U>
using giga =
typename units::detail::prefix<std::giga, U>::type;
1460 template<
class U>
using tera =
typename units::detail::prefix<std::tera, U>::type;
1461 template<
class U>
using peta =
typename units::detail::prefix<std::peta, U>::type;
1462 template<
class U>
using exa =
typename units::detail::prefix<std::exa, U>::type;
1471 template<
class U>
using kibi =
typename units::detail::prefix<std::ratio<1024>, U>::type;
1472 template<
class U>
using mebi =
typename units::detail::prefix<std::ratio<1048576>, U>::type;
1473 template<
class U>
using gibi =
typename units::detail::prefix<std::ratio<1073741824>, U>::type;
1474 template<
class U>
using tebi =
typename units::detail::prefix<std::ratio<1099511627776>, U>::type;
1475 template<
class U>
using pebi =
typename units::detail::prefix<std::ratio<1125899906842624>, U>::type;
1476 template<
class U>
using exbi =
typename units::detail::prefix<std::ratio<1152921504606846976>, U>::type;
1497 template<
class U1,
class U2>
1498 struct is_convertible_unit : std::is_same <traits::base_unit_of<typename units::traits::unit_traits<U1>::base_unit_type>,
1499 base_unit_of<typename units::traits::unit_traits<U2>::base_unit_type >> {};
1509 constexpr
inline UNIT_LIB_DEFAULT_TYPE
pow(UNIT_LIB_DEFAULT_TYPE x,
unsigned long long y)
1511 return y == 0 ? 1.0 : x *
pow(x, y - 1);
1514 constexpr
inline UNIT_LIB_DEFAULT_TYPE
abs(UNIT_LIB_DEFAULT_TYPE x)
1516 return x < 0 ? -x : x;
1520 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1521 static inline constexpr T
convert(
const T& value, std::true_type, std::false_type, std::false_type) noexcept
1527 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1528 static inline constexpr T
convert(
const T& value, std::true_type, std::false_type, std::true_type) noexcept
1534 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1535 static inline constexpr T
convert(
const T& value, std::true_type, std::true_type, std::false_type) noexcept
1541 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1542 static inline constexpr T
convert(
const T& value, std::true_type, std::true_type, std::true_type) noexcept
1548 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1549 static inline constexpr T
convert(
const T& value, std::false_type, std::false_type, std::false_type) noexcept
1551 return ((value * Ratio::num) / Ratio::den);
1556 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1557 static inline constexpr
1558 std::enable_if_t<(PiRatio::num / PiRatio::den >= 1 && PiRatio::num % PiRatio::den == 0), T>
1559 convert(
const T& value, std::false_type, std::true_type, std::false_type) noexcept
1561 return ((value *
pow(constants::detail::PI_VAL, PiRatio::num / PiRatio::den) * Ratio::num) / Ratio::den);
1566 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1567 static inline constexpr
1568 std::enable_if_t<(PiRatio::num / PiRatio::den <= -1 && PiRatio::num % PiRatio::den == 0), T>
1569 convert(
const T& value, std::false_type, std::true_type, std::false_type) noexcept
1571 return (value * Ratio::num) / (Ratio::den *
pow(constants::detail::PI_VAL, -PiRatio::num / PiRatio::den));
1576 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1578 std::enable_if_t<(PiRatio::num / PiRatio::den < 1 && PiRatio::num / PiRatio::den > -1), T>
1579 convert(
const T& value, std::false_type, std::true_type, std::false_type) noexcept
1581 return ((value *
std::pow(constants::detail::PI_VAL, PiRatio::num / PiRatio::den) * Ratio::num) / Ratio::den);
1585 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1586 static inline constexpr T
convert(
const T& value, std::false_type, std::false_type, std::true_type) noexcept
1588 return ((value * Ratio::num) / Ratio::den) + (
static_cast<UNIT_LIB_DEFAULT_TYPE
>(Translation::num) / Translation::den);
1592 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1593 static inline constexpr T
convert(
const T& value,
const std::false_type,
const std::true_type,
const std::true_type) noexcept
1595 return ((value *
std::pow(constants::detail::PI_VAL, PiRatio::num / PiRatio::den) * Ratio::num) / Ratio::den) + (
static_cast<UNIT_LIB_DEFAULT_TYPE
>(Translation::num) / Translation::den);
1615 template<
class UnitFrom,
class UnitTo,
typename T = UNIT_LIB_DEFAULT_TYPE>
1616 static inline constexpr T
convert(
const T& value) noexcept
1622 using Ratio = std::ratio_divide<typename UnitFrom::conversion_ratio, typename UnitTo::conversion_ratio>;
1623 using PiRatio = std::ratio_subtract<typename UnitFrom::pi_exponent_ratio, typename UnitTo::pi_exponent_ratio>;
1624 using Translation = std::ratio_divide<std::ratio_subtract<typename UnitFrom::translation_ratio, typename UnitTo::translation_ratio>,
typename UnitTo::conversion_ratio>;
1626 using isSame =
typename std::is_same<std::decay_t<UnitFrom>, std::decay_t<UnitTo>>::type;
1627 using piRequired = std::integral_constant<bool, !(std::is_same<std::ratio<0>, PiRatio>::value)>;
1628 using translationRequired = std::integral_constant<bool, !(std::is_same<std::ratio<0>, Translation>::value)>;
1630 return units::detail::convert<UnitFrom, UnitTo, Ratio, PiRatio, Translation, T>
1631 (value, isSame{}, piRequired{}, translationRequired{});
1647 template<
class T,
class Ret>
1648 struct has_operator_parenthesis_impl
1651 static constexpr
auto test(U*) -> decltype(std::declval<U>()()) {
return decltype(std::declval<U>()()){}; }
1653 static constexpr std::false_type test(...) {
return std::false_type{}; }
1655 using type =
typename std::is_same<Ret, decltype(test<T>(0))>::type;
1663 template<
class T,
class Ret>
1664 struct has_operator_parenthesis : traits::detail::has_operator_parenthesis_impl<T, Ret>::type {};
1675 template<
class T,
class Ret>
1676 struct has_value_member_impl
1679 static constexpr
auto test(U* p) -> decltype(p->m_value) {
return p->m_value; }
1681 static constexpr
auto test(...)->std::false_type {
return std::false_type{}; }
1683 using type =
typename std::is_same<std::decay_t<Ret>, std::decay_t<decltype(test<T>(0))>>::type;
1691 template<
class T,
class Ret>
1692 struct has_value_member : traits::detail::has_value_member_impl<T, Ret>::type {};
1709 template<
class T,
class Ret>
1711 std::is_default_constructible<T>::value &&
1712 has_operator_parenthesis<T, Ret>::value &&
1713 has_value_member<T, Ret>::value &&
1714 std::is_trivial<T>::value>
1724 #ifdef FOR_DOXYGEN_PURPOSOES_ONLY
1731 template<
typename T>
1732 struct unit_t_traits
1734 typedef typename T::non_linear_scale_type non_linear_scale_type;
1735 typedef typename T::underlying_type underlying_type;
1736 typedef typename T::value_type value_type;
1737 typedef typename T::unit_type unit_type;
1746 template<
typename T,
typename =
void>
1747 struct unit_t_traits
1749 typedef void non_linear_scale_type;
1750 typedef void underlying_type;
1751 typedef void value_type;
1752 typedef void unit_type;
1760 template<
typename T>
1761 struct unit_t_traits <T, typename void_t<
1762 typename T::non_linear_scale_type,
1763 typename T::underlying_type,
1764 typename T::value_type,
1765 typename T::unit_type>::type>
1767 typedef typename T::non_linear_scale_type non_linear_scale_type;
1768 typedef typename T::underlying_type underlying_type;
1769 typedef typename T::value_type value_type;
1770 typedef typename T::unit_type unit_type;
1789 template<
class U1,
class U2>
1791 is_convertible_unit<typename units::traits::unit_t_traits<U1>::unit_type, typename units::traits::unit_t_traits<U2>::unit_type>::value>
1817 #if !defined(_MSC_VER) || _MSC_VER > 1800 // bug in VS2013 prevents this from working
1830 struct is_unit_t : std::is_base_of<units::detail::_unit_t, T>::type {};
1888 template<
class Units,
typename T = UNIT_LIB_DEFAULT_TYPE,
template<
typename>
class NonLinearScale =
linear_scale>
1889 class unit_t :
public NonLinearScale<T>, units::detail::_unit_t
1891 static_assert(
traits::is_unit<Units>::value,
"Template parameter `Units` must be a unit tag. Check that you aren't using a unit type (_t).");
1892 static_assert(
traits::is_nonlinear_scale<NonLinearScale<T>, T>::
value,
"Template parameter `NonLinearScale` does not conform to the `is_nonlinear_scale` concept.");
1896 using nls = NonLinearScale<T>;
1910 constexpr
unit_t() =
default;
1920 template<
class... Args>
1921 inline explicit constexpr
unit_t(
const T
value,
const Args&... args) noexcept : nls(
value, args...)
1931 template<class Ty, class = typename std::enable_if<traits::is_dimensionless_unit<Units>::value && std::is_arithmetic<Ty>::value>::type>
1943 inline constexpr
unit_t(
const std::chrono::duration<Rep, Period>&
value) noexcept :
1954 template<
class UnitsRhs,
typename Ty,
template<
typename>
class NlsRhs>
1956 nls(units::convert<UnitsRhs, Units, T>(rhs.m_value), std::true_type() )
1966 template<
class UnitsRhs,
typename Ty,
template<
typename>
class NlsRhs>
1969 nls::m_value = units::convert<UnitsRhs, Units, T>(rhs.m_value);
1978 template<class Ty, class = std::enable_if_t<traits::is_dimensionless_unit<Units>::value && std::is_arithmetic<Ty>::value>>
1991 template<
class UnitsRhs,
typename Ty,
template<
typename>
class NlsRhs>
1994 return (nls::m_value < units::convert<UnitsRhs, Units>(rhs.m_value));
2003 template<
class UnitsRhs,
typename Ty,
template<
typename>
class NlsRhs>
2006 return (nls::m_value <= units::convert<UnitsRhs, Units>(rhs.m_value));
2015 template<
class UnitsRhs,
typename Ty,
template<
typename>
class NlsRhs>
2018 return (nls::m_value > units::convert<UnitsRhs, Units>(rhs.m_value));
2027 template<
class UnitsRhs,
typename Ty,
template<
typename>
class NlsRhs>
2030 return (nls::m_value >= units::convert<UnitsRhs, Units>(rhs.m_value));
2040 template<
class UnitsRhs,
typename Ty,
template<
typename>
class NlsRhs, std::enable_if_t<std::is_floating_point<T>::value || std::is_floating_point<Ty>::value,
int> = 0>
2043 return detail::abs(nls::m_value - units::convert<UnitsRhs, Units>(rhs.m_value)) < std::numeric_limits<T>::epsilon() *
2044 detail::abs(nls::m_value + units::convert<UnitsRhs, Units>(rhs.m_value)) ||
2045 detail::abs(nls::m_value - units::convert<UnitsRhs, Units>(rhs.m_value)) < std::numeric_limits<T>::min();
2048 template<
class UnitsRhs,
typename Ty,
template<
typename>
class NlsRhs, std::enable_if_t<std::is_integral<T>::value && std::is_integral<Ty>::value,
int> = 0>
2051 return nls::m_value == units::convert<UnitsRhs, Units>(rhs.m_value);
2061 template<
class UnitsRhs,
typename Ty,
template<
typename>
class NlsRhs>
2064 return !(*
this == rhs);
2080 template<typename Ty, class = std::enable_if_t<std::is_arithmetic<Ty>::value>>
2081 inline constexpr Ty
to() const noexcept
2083 return static_cast<Ty
>(*this);
2091 template<typename Ty, class = std::enable_if_t<std::is_arithmetic<Ty>::value>>
2094 return static_cast<Ty
>(
m_value);
2117 template<class Ty, std::enable_if_t<traits::is_dimensionless_unit<Units>::value && std::is_arithmetic<Ty>::value,
int> = 0>
2118 inline constexpr
operator Ty() const noexcept
2128 template<class Ty, std::enable_if_t<!traits::is_dimensionless_unit<Units>::value && std::is_arithmetic<Ty>::value,
int> = 0>
2129 inline constexpr
explicit operator Ty() const noexcept
2131 return static_cast<Ty
>((*this)());
2138 template<
typename U = Units, std::enable_if_t<units::traits::is_convertible_unit<U, unit<std::ratio<1>, category::time_unit>>::value,
int> = 0>
2139 inline constexpr
operator std::chrono::nanoseconds() const noexcept
2141 return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::duration<double, std::nano>(
units::convert<Units,
unit<std::ratio<1,1000000000>,
category::time_unit>>((*
this)())));
2147 inline constexpr
const char*
name() const noexcept
2149 return units::name(*
this);
2157 return units::abbreviation(*
this);
2162 template<
class U,
typename Ty,
template<
typename>
class Nlt>
2180 template<class UnitType, typename T, class = std::enable_if_t<std::is_arithmetic<T>::value>>
2185 return UnitType(value);
2188 #if !defined(UNIT_LIB_DISABLE_IOSTREAM)
2189 template<
class Units,
typename T,
template<
typename>
class NonLinearScale>
2190 inline std::ostream& operator<<(std::ostream& os,
const unit_t<Units, T, NonLinearScale>& obj) noexcept
2192 using BaseUnits = unit<std::ratio<1>,
typename traits::unit_traits<Units>::base_unit_type>;
2193 os << convert<Units, BaseUnits>(obj());
2195 if (traits::unit_traits<Units>::base_unit_type::meter_ratio::num != 0) { os <<
" m"; }
2196 if (traits::unit_traits<Units>::base_unit_type::meter_ratio::num != 0 &&
2197 traits::unit_traits<Units>::base_unit_type::meter_ratio::num != 1) { os <<
"^" << traits::unit_traits<Units>::base_unit_type::meter_ratio::num; }
2198 if (traits::unit_traits<Units>::base_unit_type::meter_ratio::den != 1) { os <<
"/" << traits::unit_traits<Units>::base_unit_type::meter_ratio::den; }
2200 if (traits::unit_traits<Units>::base_unit_type::kilogram_ratio::num != 0) { os <<
" kg"; }
2201 if (traits::unit_traits<Units>::base_unit_type::kilogram_ratio::num != 0 &&
2202 traits::unit_traits<Units>::base_unit_type::kilogram_ratio::num != 1) { os <<
"^" << traits::unit_traits<Units>::base_unit_type::kilogram_ratio::num; }
2203 if (traits::unit_traits<Units>::base_unit_type::kilogram_ratio::den != 1) { os <<
"/" << traits::unit_traits<Units>::base_unit_type::kilogram_ratio::den; }
2205 if (traits::unit_traits<Units>::base_unit_type::second_ratio::num != 0) { os <<
" s"; }
2206 if (traits::unit_traits<Units>::base_unit_type::second_ratio::num != 0 &&
2207 traits::unit_traits<Units>::base_unit_type::second_ratio::num != 1) { os <<
"^" << traits::unit_traits<Units>::base_unit_type::second_ratio::num; }
2208 if (traits::unit_traits<Units>::base_unit_type::second_ratio::den != 1) { os <<
"/" << traits::unit_traits<Units>::base_unit_type::second_ratio::den; }
2210 if (traits::unit_traits<Units>::base_unit_type::ampere_ratio::num != 0) { os <<
" A"; }
2211 if (traits::unit_traits<Units>::base_unit_type::ampere_ratio::num != 0 &&
2212 traits::unit_traits<Units>::base_unit_type::ampere_ratio::num != 1) { os <<
"^" << traits::unit_traits<Units>::base_unit_type::ampere_ratio::num; }
2213 if (traits::unit_traits<Units>::base_unit_type::ampere_ratio::den != 1) { os <<
"/" << traits::unit_traits<Units>::base_unit_type::ampere_ratio::den; }
2215 if (traits::unit_traits<Units>::base_unit_type::kelvin_ratio::num != 0) { os <<
" K"; }
2216 if (traits::unit_traits<Units>::base_unit_type::kelvin_ratio::num != 0 &&
2217 traits::unit_traits<Units>::base_unit_type::kelvin_ratio::num != 1) { os <<
"^" << traits::unit_traits<Units>::base_unit_type::kelvin_ratio::num; }
2218 if (traits::unit_traits<Units>::base_unit_type::kelvin_ratio::den != 1) { os <<
"/" << traits::unit_traits<Units>::base_unit_type::kelvin_ratio::den; }
2220 if (traits::unit_traits<Units>::base_unit_type::mole_ratio::num != 0) { os <<
" mol"; }
2221 if (traits::unit_traits<Units>::base_unit_type::mole_ratio::num != 0 &&
2222 traits::unit_traits<Units>::base_unit_type::mole_ratio::num != 1) { os <<
"^" << traits::unit_traits<Units>::base_unit_type::mole_ratio::num; }
2223 if (traits::unit_traits<Units>::base_unit_type::mole_ratio::den != 1) { os <<
"/" << traits::unit_traits<Units>::base_unit_type::mole_ratio::den; }
2225 if (traits::unit_traits<Units>::base_unit_type::candela_ratio::num != 0) { os <<
" cd"; }
2226 if (traits::unit_traits<Units>::base_unit_type::candela_ratio::num != 0 &&
2227 traits::unit_traits<Units>::base_unit_type::candela_ratio::num != 1) { os <<
"^" << traits::unit_traits<Units>::base_unit_type::candela_ratio::num; }
2228 if (traits::unit_traits<Units>::base_unit_type::candela_ratio::den != 1) { os <<
"/" << traits::unit_traits<Units>::base_unit_type::candela_ratio::den; }
2230 if (traits::unit_traits<Units>::base_unit_type::radian_ratio::num != 0) { os <<
" rad"; }
2231 if (traits::unit_traits<Units>::base_unit_type::radian_ratio::num != 0 &&
2232 traits::unit_traits<Units>::base_unit_type::radian_ratio::num != 1) { os <<
"^" << traits::unit_traits<Units>::base_unit_type::radian_ratio::num; }
2233 if (traits::unit_traits<Units>::base_unit_type::radian_ratio::den != 1) { os <<
"/" << traits::unit_traits<Units>::base_unit_type::radian_ratio::den; }
2235 if (traits::unit_traits<Units>::base_unit_type::byte_ratio::num != 0) { os <<
" b"; }
2236 if (traits::unit_traits<Units>::base_unit_type::byte_ratio::num != 0 &&
2237 traits::unit_traits<Units>::base_unit_type::byte_ratio::num != 1) { os <<
"^" << traits::unit_traits<Units>::base_unit_type::byte_ratio::num; }
2238 if (traits::unit_traits<Units>::base_unit_type::byte_ratio::den != 1) { os <<
"/" << traits::unit_traits<Units>::base_unit_type::byte_ratio::den; }
2244 template<
class Units,
typename T,
template<
typename>
class NonLinearScale,
typename RhsType>
2245 inline unit_t<Units, T, NonLinearScale>& operator+=(unit_t<Units, T, NonLinearScale>& lhs,
const RhsType& rhs) noexcept
2247 static_assert(traits::is_convertible_unit_t<unit_t<Units, T, NonLinearScale>, RhsType>::value ||
2248 (traits::is_dimensionless_unit<decltype(lhs)>::value && std::is_arithmetic<RhsType>::value),
2249 "parameters are not compatible units.");
2255 template<
class Units,
typename T,
template<
typename>
class NonLinearScale,
typename RhsType>
2256 inline unit_t<Units, T, NonLinearScale>& operator-=(unit_t<Units, T, NonLinearScale>& lhs,
const RhsType& rhs) noexcept
2258 static_assert(traits::is_convertible_unit_t<unit_t<Units, T, NonLinearScale>, RhsType>::value ||
2259 (traits::is_dimensionless_unit<decltype(lhs)>::value && std::is_arithmetic<RhsType>::value),
2260 "parameters are not compatible units.");
2266 template<
class Units,
typename T,
template<
typename>
class NonLinearScale,
typename RhsType>
2267 inline unit_t<Units, T, NonLinearScale>& operator*=(unit_t<Units, T, NonLinearScale>& lhs,
const RhsType& rhs) noexcept
2269 static_assert((traits::is_dimensionless_unit<RhsType>::value || std::is_arithmetic<RhsType>::value),
2270 "right-hand side parameter must be dimensionless.");
2276 template<
class Units,
typename T,
template<
typename>
class NonLinearScale,
typename RhsType>
2277 inline unit_t<Units, T, NonLinearScale>& operator/=(unit_t<Units, T, NonLinearScale>& lhs,
const RhsType& rhs) noexcept
2279 static_assert((traits::is_dimensionless_unit<RhsType>::value || std::is_arithmetic<RhsType>::value),
2280 "right-hand side parameter must be dimensionless.");
2291 template<
class Units,
typename T,
template<
typename>
class NonLinearScale>
2292 inline unit_t<Units, T, NonLinearScale>
operator+(
const unit_t<Units, T, NonLinearScale>& u) noexcept
2298 template<
class Units,
typename T,
template<
typename>
class NonLinearScale>
2299 inline unit_t<Units, T, NonLinearScale>& operator++(unit_t<Units, T, NonLinearScale>& u) noexcept
2301 u = unit_t<Units, T, NonLinearScale>(u() + 1);
2306 template<
class Units,
typename T,
template<
typename>
class NonLinearScale>
2307 inline unit_t<Units, T, NonLinearScale> operator++(unit_t<Units, T, NonLinearScale>& u,
int) noexcept
2310 u = unit_t<Units, T, NonLinearScale>(u() + 1);
2315 template<
class Units,
typename T,
template<
typename>
class NonLinearScale>
2316 inline unit_t<Units, T, NonLinearScale>
operator-(
const unit_t<Units, T, NonLinearScale>& u) noexcept
2318 return unit_t<Units, T, NonLinearScale>(-u());
2322 template<
class Units,
typename T,
template<
typename>
class NonLinearScale>
2323 inline unit_t<Units, T, NonLinearScale>& operator--(unit_t<Units, T, NonLinearScale>& u) noexcept
2325 u = unit_t<Units, T, NonLinearScale>(u() - 1);
2330 template<
class Units,
typename T,
template<
typename>
class NonLinearScale>
2331 inline unit_t<Units, T, NonLinearScale> operator--(unit_t<Units, T, NonLinearScale>& u,
int) noexcept
2334 u = unit_t<Units, T, NonLinearScale>(u() - 1);
2355 template<typename T, typename Units, class = std::enable_if_t<std::is_arithmetic<T>::value && traits::is_unit_t<Units>::value>>
2358 return static_cast<T
>(value);
2377 #if !defined(_MSC_VER) || _MSC_VER > 1800 // bug in VS2013 prevents this from working
2378 template<
typename... T>
2379 struct has_linear_scale : std::integral_constant<bool, units::all_true<std::is_base_of<units::linear_scale<typename units::traits::unit_t_traits<T>::underlying_type>, T>::value...>::value > {};
2381 template<
typename T1,
typename T2 = T1,
typename T3 = T1>
2383 std::is_base_of<units::linear_scale<typename units::traits::unit_t_traits<T1>::underlying_type>, T1>::value &&
2384 std::is_base_of<units::linear_scale<typename units::traits::unit_t_traits<T2>::underlying_type>, T2>::value &&
2385 std::is_base_of<units::linear_scale<typename units::traits::unit_t_traits<T3>::underlying_type>, T3>::value> {};
2395 #if !defined(_MSC_VER) || _MSC_VER > 1800 // bug in VS2013 prevents this from working
2396 template<
typename... T>
2397 struct has_decibel_scale : std::integral_constant<bool, units::all_true<std::is_base_of<units::decibel_scale<typename units::traits::unit_t_traits<T>::underlying_type>, T>::value...>::value> {};
2399 template<
typename T1,
typename T2 = T1,
typename T3 = T1>
2401 std::is_base_of<units::decibel_scale<typename units::traits::unit_t_traits<T1>::underlying_type>, T1>::value &&
2402 std::is_base_of<units::decibel_scale<typename units::traits::unit_t_traits<T2>::underlying_type>, T2>::value &&
2403 std::is_base_of<units::decibel_scale<typename units::traits::unit_t_traits<T2>::underlying_type>, T3>::value> {};
2414 template<
typename T1,
typename T2>
2416 std::is_same<typename units::traits::unit_t_traits<T1>::non_linear_scale_type, typename units::traits::unit_t_traits<T2>::non_linear_scale_type>::value>
2439 template<
typename T>
2446 #if defined(_MSC_VER) && (_MSC_VER > 1800)
2450 template<
class... Args>
2452 inline constexpr T operator()()
const noexcept {
return m_value; }
2472 #if defined(_MSC_VER)
2473 # pragma warning(push)
2474 # pragma warning(disable : 4348)
2478 #if defined(_MSC_VER)
2479 # pragma warning(pop)
2486 template<class UnitTypeLhs, class UnitTypeRhs, std::enable_if_t<!traits::is_same_scale<UnitTypeLhs, UnitTypeRhs>::value,
int> = 0>
2487 constexpr
inline int operator+(
const UnitTypeLhs& ,
const UnitTypeRhs& ) noexcept
2494 template<class UnitTypeLhs, class UnitTypeRhs, std::enable_if_t<traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value,
int> = 0>
2495 inline constexpr UnitTypeLhs operator+(
const UnitTypeLhs& lhs,
const UnitTypeRhs& rhs) noexcept
2497 using UnitsLhs =
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
2498 using UnitsRhs =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2499 return UnitTypeLhs(lhs() + convert<UnitsRhs, UnitsLhs>(rhs()));
2503 template<typename T, std::enable_if_t<std::is_arithmetic<T>::value,
int> = 0>
2510 template<typename T, std::enable_if_t<std::is_arithmetic<T>::value,
int> = 0>
2517 template<class UnitTypeLhs, class UnitTypeRhs, std::enable_if_t<traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value,
int> = 0>
2518 inline constexpr UnitTypeLhs operator-(
const UnitTypeLhs& lhs,
const UnitTypeRhs& rhs) noexcept
2520 using UnitsLhs =
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
2521 using UnitsRhs =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2522 return UnitTypeLhs(lhs() - convert<UnitsRhs, UnitsLhs>(rhs()));
2526 template<typename T, std::enable_if_t<std::is_arithmetic<T>::value,
int> = 0>
2533 template<typename T, std::enable_if_t<std::is_arithmetic<T>::value,
int> = 0>
2540 template<
class UnitTypeLhs,
class UnitTypeRhs,
2541 std::enable_if_t<traits::is_convertible_unit_t<UnitTypeLhs, UnitTypeRhs>::value && traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value,
int> = 0>
2544 using UnitsLhs =
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
2545 using UnitsRhs =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2547 (lhs() * convert<UnitsRhs, UnitsLhs>(rhs()));
2551 template<
class UnitTypeLhs,
class UnitTypeRhs,
2552 std::enable_if_t<!traits::is_convertible_unit_t<UnitTypeLhs, UnitTypeRhs>::value && traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value && !traits::is_dimensionless_unit<UnitTypeLhs>::value && !traits::is_dimensionless_unit<UnitTypeRhs>::value,
int> = 0>
2555 using UnitsLhs =
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
2556 using UnitsRhs =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2557 return unit_t<compound_unit<UnitsLhs, UnitsRhs>>
2562 template<
class UnitTypeLhs,
typename UnitTypeRhs,
2563 std::enable_if_t<traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value && !traits::is_dimensionless_unit<UnitTypeLhs>::value && traits::is_dimensionless_unit<UnitTypeRhs>::value,
int> = 0>
2564 inline constexpr UnitTypeLhs
operator*(
const UnitTypeLhs& lhs,
const UnitTypeRhs& rhs) noexcept
2567 return UnitTypeLhs(lhs() *
static_cast<UNIT_LIB_DEFAULT_TYPE
>(rhs));
2571 template<
class UnitTypeLhs,
typename UnitTypeRhs,
2572 std::enable_if_t<traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value && traits::is_dimensionless_unit<UnitTypeLhs>::value && !traits::is_dimensionless_unit<UnitTypeRhs>::value,
int> = 0>
2573 inline constexpr UnitTypeRhs
operator*(
const UnitTypeLhs& lhs,
const UnitTypeRhs& rhs) noexcept
2576 return UnitTypeRhs(
static_cast<UNIT_LIB_DEFAULT_TYPE
>(lhs) * rhs());
2580 template<
class UnitTypeLhs,
typename T,
2581 std::enable_if_t<std::is_arithmetic<T>::value && traits::has_linear_scale<UnitTypeLhs>::value,
int> = 0>
2582 inline constexpr UnitTypeLhs
operator*(
const UnitTypeLhs& lhs, T rhs) noexcept
2584 return UnitTypeLhs(lhs() * rhs);
2588 template<
class UnitTypeRhs,
typename T,
2589 std::enable_if_t<std::is_arithmetic<T>::value && traits::has_linear_scale<UnitTypeRhs>::value,
int> = 0>
2590 inline constexpr UnitTypeRhs
operator*(T lhs,
const UnitTypeRhs& rhs) noexcept
2592 return UnitTypeRhs(lhs * rhs());
2596 template<
class UnitTypeLhs,
class UnitTypeRhs,
2597 std::enable_if_t<traits::is_convertible_unit_t<UnitTypeLhs, UnitTypeRhs>::value && traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value,
int> = 0>
2600 using UnitsLhs =
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
2601 using UnitsRhs =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2606 template<
class UnitTypeLhs,
class UnitTypeRhs,
2607 std::enable_if_t<!traits::is_convertible_unit_t<UnitTypeLhs, UnitTypeRhs>::value && traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value && !traits::is_dimensionless_unit<UnitTypeLhs>::value && !traits::is_dimensionless_unit<UnitTypeRhs>::value,
int> = 0>
2610 using UnitsLhs =
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
2611 using UnitsRhs =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2617 template<
class UnitTypeLhs,
class UnitTypeRhs,
2618 std::enable_if_t<traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value && !traits::is_dimensionless_unit<UnitTypeLhs>::value && traits::is_dimensionless_unit<UnitTypeRhs>::value,
int> = 0>
2619 inline constexpr UnitTypeLhs
operator/(
const UnitTypeLhs& lhs,
const UnitTypeRhs& rhs) noexcept
2621 return UnitTypeLhs(lhs() /
static_cast<UNIT_LIB_DEFAULT_TYPE
>(rhs));
2625 template<
class UnitTypeLhs,
class UnitTypeRhs,
2626 std::enable_if_t<traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value && traits::is_dimensionless_unit<UnitTypeLhs>::value && !traits::is_dimensionless_unit<UnitTypeRhs>::value,
int> = 0>
2630 (
static_cast<UNIT_LIB_DEFAULT_TYPE
>(lhs) / rhs());
2634 template<
class UnitTypeLhs,
typename T,
2635 std::enable_if_t<std::is_arithmetic<T>::value && traits::has_linear_scale<UnitTypeLhs>::value,
int> = 0>
2636 inline constexpr UnitTypeLhs
operator/(
const UnitTypeLhs& lhs, T rhs) noexcept
2638 return UnitTypeLhs(lhs() / rhs);
2642 template<
class UnitTypeRhs,
typename T,
2643 std::enable_if_t<std::is_arithmetic<T>::value && traits::has_linear_scale<UnitTypeRhs>::value,
int> = 0>
2646 using UnitsRhs =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2655 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2656 constexpr
bool operator==(
const UNIT_LIB_DEFAULT_TYPE lhs,
const Units& rhs) noexcept
2658 return detail::abs(lhs -
static_cast<UNIT_LIB_DEFAULT_TYPE
>(rhs)) < std::numeric_limits<UNIT_LIB_DEFAULT_TYPE>::epsilon() *
detail::abs(lhs +
static_cast<UNIT_LIB_DEFAULT_TYPE
>(rhs)) ||
2659 detail::abs(lhs -
static_cast<UNIT_LIB_DEFAULT_TYPE
>(rhs)) < std::numeric_limits<UNIT_LIB_DEFAULT_TYPE>::min();
2662 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2663 constexpr
bool operator==(
const Units& lhs,
const UNIT_LIB_DEFAULT_TYPE rhs) noexcept
2665 return detail::abs(
static_cast<UNIT_LIB_DEFAULT_TYPE
>(lhs) - rhs) < std::numeric_limits<UNIT_LIB_DEFAULT_TYPE>::epsilon() *
detail::abs(
static_cast<UNIT_LIB_DEFAULT_TYPE
>(lhs) + rhs) ||
2666 detail::abs(
static_cast<UNIT_LIB_DEFAULT_TYPE
>(lhs) - rhs) < std::numeric_limits<UNIT_LIB_DEFAULT_TYPE>::min();
2669 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2670 constexpr
bool operator!=(
const UNIT_LIB_DEFAULT_TYPE lhs,
const Units& rhs) noexcept
2672 return!(lhs ==
static_cast<UNIT_LIB_DEFAULT_TYPE
>(rhs));
2675 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2676 constexpr
bool operator!=(
const Units& lhs,
const UNIT_LIB_DEFAULT_TYPE rhs) noexcept
2678 return !(
static_cast<UNIT_LIB_DEFAULT_TYPE
>(lhs) == rhs);
2681 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2682 constexpr
bool operator>=(
const UNIT_LIB_DEFAULT_TYPE lhs,
const Units& rhs) noexcept
2684 return std::isgreaterequal(lhs,
static_cast<UNIT_LIB_DEFAULT_TYPE
>(rhs));
2687 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2688 constexpr
bool operator>=(
const Units& lhs,
const UNIT_LIB_DEFAULT_TYPE rhs) noexcept
2690 return std::isgreaterequal(
static_cast<UNIT_LIB_DEFAULT_TYPE
>(lhs), rhs);
2693 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2694 constexpr
bool operator>(
const UNIT_LIB_DEFAULT_TYPE lhs,
const Units& rhs) noexcept
2696 return lhs >
static_cast<UNIT_LIB_DEFAULT_TYPE
>(rhs);
2699 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2700 constexpr
bool operator>(
const Units& lhs,
const UNIT_LIB_DEFAULT_TYPE rhs) noexcept
2702 return static_cast<UNIT_LIB_DEFAULT_TYPE
>(lhs) > rhs;
2705 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2706 constexpr
bool operator<=(
const UNIT_LIB_DEFAULT_TYPE lhs,
const Units& rhs) noexcept
2708 return std::islessequal(lhs,
static_cast<UNIT_LIB_DEFAULT_TYPE
>(rhs));
2711 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2712 constexpr
bool operator<=(
const Units& lhs,
const UNIT_LIB_DEFAULT_TYPE rhs) noexcept
2714 return std::islessequal(
static_cast<UNIT_LIB_DEFAULT_TYPE
>(lhs), rhs);
2717 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2718 constexpr
bool operator<(
const UNIT_LIB_DEFAULT_TYPE lhs,
const Units& rhs) noexcept
2720 return lhs < static_cast<UNIT_LIB_DEFAULT_TYPE>(rhs);
2723 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2724 constexpr
bool operator<(
const Units& lhs,
const UNIT_LIB_DEFAULT_TYPE rhs) noexcept
2726 return static_cast<UNIT_LIB_DEFAULT_TYPE
>(lhs) < rhs;
2737 template <
int N,
class U>
struct power_of_unit
2739 typedef typename units::detail::unit_multiply<U,
typename power_of_unit<N - 1, U>::type> type;
2743 template <
class U>
struct power_of_unit<1, U>
2759 template<int power, class UnitType, class = typename std::enable_if<traits::has_linear_scale<UnitType>::value,
int>>
2774 template<int power, class UnitType, class = typename std::enable_if<traits::has_linear_scale<UnitType>::value,
int>>
2777 static_assert(power >= 0,
"cpow cannot accept negative numbers. Try units::math::pow instead.");
2793 template<
typename T>
2794 struct decibel_scale
2796 inline constexpr decibel_scale() =
default;
2797 inline constexpr decibel_scale(
const decibel_scale&) =
default;
2798 inline ~decibel_scale() =
default;
2799 inline decibel_scale& operator=(
const decibel_scale&) =
default;
2800 #if defined(_MSC_VER) && (_MSC_VER > 1800)
2801 inline constexpr decibel_scale(decibel_scale&&) =
default;
2802 inline decibel_scale& operator=(decibel_scale&&) =
default;
2804 inline constexpr decibel_scale(
const T value) noexcept :
m_value(
std::pow(10, value / 10)) {}
2805 template<
class... Args>
2806 inline constexpr decibel_scale(
const T value, std::true_type, Args&&...) noexcept :
m_value(value) {}
2807 inline constexpr T operator()() const noexcept {
return 10 *
std::log10(
m_value); }
2820 namespace dimensionless
2823 #if !defined(UNIT_LIB_DISABLE_IOSTREAM)
2824 inline std::ostream& operator<<(std::ostream& os,
const dB_t& obj) { os << obj() <<
" dB";
return os; }
2834 template<
class UnitTypeLhs,
class UnitTypeRhs,
2835 std::enable_if_t<traits::has_decibel_scale<UnitTypeLhs, UnitTypeRhs>::value,
int> = 0>
2838 using LhsUnits =
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
2839 using RhsUnits =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2840 using underlying_type =
typename units::traits::unit_t_traits<UnitTypeLhs>::underlying_type;
2843 (lhs.template toLinearized<underlying_type>() * convert<RhsUnits, LhsUnits>(rhs.template toLinearized<underlying_type>()), std::true_type());
2847 template<class UnitTypeLhs, std::enable_if_t<traits::has_decibel_scale<UnitTypeLhs>::value && !traits::is_dimensionless_unit<UnitTypeLhs>::value,
int> = 0>
2850 using underlying_type =
typename units::traits::unit_t_traits<UnitTypeLhs>::underlying_type;
2851 return UnitTypeLhs(lhs.template toLinearized<underlying_type>() * rhs.template toLinearized<underlying_type>(), std::true_type());
2855 template<class UnitTypeRhs, std::enable_if_t<traits::has_decibel_scale<UnitTypeRhs>::value && !traits::is_dimensionless_unit<UnitTypeRhs>::value,
int> = 0>
2858 using underlying_type =
typename units::traits::unit_t_traits<UnitTypeRhs>::underlying_type;
2859 return UnitTypeRhs(lhs.template toLinearized<underlying_type>() * rhs.template toLinearized<underlying_type>(), std::true_type());
2863 template<class UnitTypeLhs, class UnitTypeRhs, std::enable_if_t<traits::has_decibel_scale<UnitTypeLhs, UnitTypeRhs>::value,
int> = 0>
2866 using LhsUnits =
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
2867 using RhsUnits =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2868 using underlying_type =
typename units::traits::unit_t_traits<UnitTypeLhs>::underlying_type;
2871 (lhs.template toLinearized<underlying_type>() / convert<RhsUnits, LhsUnits>(rhs.template toLinearized<underlying_type>()), std::true_type());
2875 template<class UnitTypeLhs, std::enable_if_t<traits::has_decibel_scale<UnitTypeLhs>::value && !traits::is_dimensionless_unit<UnitTypeLhs>::value,
int> = 0>
2878 using underlying_type =
typename units::traits::unit_t_traits<UnitTypeLhs>::underlying_type;
2879 return UnitTypeLhs(lhs.template toLinearized<underlying_type>() / rhs.template toLinearized<underlying_type>(), std::true_type());
2883 template<class UnitTypeRhs, std::enable_if_t<traits::has_decibel_scale<UnitTypeRhs>::value && !traits::is_dimensionless_unit<UnitTypeRhs>::value,
int> = 0>
2886 using RhsUnits =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2887 using underlying_type =
typename units::traits::unit_t_traits<RhsUnits>::underlying_type;
2890 (lhs.template toLinearized<underlying_type>() / rhs.template toLinearized<underlying_type>(), std::true_type());
2900 template<
class Units>
2901 struct _unit_value_t {};
2907 #ifdef FOR_DOXYGEN_PURPOSES_ONLY
2915 template<
typename T>
2916 struct unit_value_t_traits
2918 typedef typename T::unit_type unit_type;
2919 typedef typename T::ratio ratio;
2928 template<
typename T,
typename =
void>
2929 struct unit_value_t_traits
2931 typedef void unit_type;
2940 template<
typename T>
2941 struct unit_value_t_traits <T, typename void_t<
2942 typename T::unit_type,
2943 typename T::ratio>::type>
2945 typedef typename T::unit_type unit_type;
2946 typedef typename T::ratio ratio;
2968 template<
typename Units, std::u
intmax_t Num, std::u
intmax_t Denom = 1>
2971 typedef Units unit_type;
2972 typedef std::ratio<Num, Denom> ratio;
2988 template<typename T, typename Units = typename traits::unit_value_t_traits<T>::unit_type>
2990 std::is_base_of<units::detail::_unit_value_t<Units>, T>::value>
2998 template<
typename Category,
typename T>
3000 std::is_same<units::traits::base_unit_of<typename traits::unit_value_t_traits<T>::unit_type>, Category>::value>
3010 template<
class U1,
class U2>
3011 struct unit_value_arithmetic
3016 using _UNIT1 =
typename traits::unit_value_t_traits<U1>::unit_type;
3017 using _UNIT2 =
typename traits::unit_value_t_traits<U2>::unit_type;
3018 using _CONV1 =
typename units::traits::unit_traits<_UNIT1>::conversion_ratio;
3019 using _CONV2 =
typename units::traits::unit_traits<_UNIT2>::conversion_ratio;
3020 using _RATIO1 =
typename traits::unit_value_t_traits<U1>::ratio;
3021 using _RATIO2 =
typename traits::unit_value_t_traits<U2>::ratio;
3022 using _RATIO2CONV =
typename std::ratio_divide<std::ratio_multiply<_RATIO2, _CONV2>, _CONV1>;
3023 using _PI_EXP = std::ratio_subtract<typename units::traits::unit_traits<_UNIT2>::pi_exponent_ratio,
typename units::traits::unit_traits<_UNIT1>::pi_exponent_ratio>;
3038 template<
class U1,
class U2>
3039 struct unit_value_add : units::detail::unit_value_arithmetic<U1, U2>, units::detail::_unit_value_t<typename traits::unit_value_t_traits<U1>::unit_type>
3042 using Base = units::detail::unit_value_arithmetic<U1, U2>;
3043 typedef typename Base::_UNIT1 unit_type;
3044 using ratio = std::ratio_add<typename Base::_RATIO1, typename Base::_RATIO2CONV>;
3057 using UsePi = std::integral_constant<bool, Base::_PI_EXP::num != 0>;
3058 return value(UsePi());
3069 static constexpr
const unit_t<unit_type>
value(std::true_type) noexcept
3071 return unit_t<unit_type>(((UNIT_LIB_DEFAULT_TYPE)Base::_RATIO1::num / Base::_RATIO1::den) +
3072 ((UNIT_LIB_DEFAULT_TYPE)Base::_RATIO2CONV::num / Base::_RATIO2CONV::den) *
std::pow(units::constants::detail::PI_VAL, ((UNIT_LIB_DEFAULT_TYPE)Base::_PI_EXP::num / Base::_PI_EXP::den)));
3087 template<
class U1,
class U2>
3088 struct unit_value_subtract : units::detail::unit_value_arithmetic<U1, U2>, units::detail::_unit_value_t<typename traits::unit_value_t_traits<U1>::unit_type>
3091 using Base = units::detail::unit_value_arithmetic<U1, U2>;
3093 typedef typename Base::_UNIT1 unit_type;
3094 using ratio = std::ratio_subtract<typename Base::_RATIO1, typename Base::_RATIO2CONV>;
3107 using UsePi = std::integral_constant<bool, Base::_PI_EXP::num != 0>;
3108 return value(UsePi());
3119 static constexpr
const unit_t<unit_type>
value(std::true_type) noexcept
3121 return unit_t<unit_type>(((UNIT_LIB_DEFAULT_TYPE)Base::_RATIO1::num / Base::_RATIO1::den) - ((UNIT_LIB_DEFAULT_TYPE)Base::_RATIO2CONV::num / Base::_RATIO2CONV::den)
3122 *
std::pow(units::constants::detail::PI_VAL, ((UNIT_LIB_DEFAULT_TYPE)Base::_PI_EXP::num / Base::_PI_EXP::den)));
3137 template<
class U1,
class U2>
3139 units::detail::_unit_value_t<typename std::conditional<traits::is_convertible_unit<typename traits::unit_value_t_traits<U1>::unit_type,
3140 typename traits::unit_value_t_traits<U2>::unit_type>::value, compound_unit<squared<typename traits::unit_value_t_traits<U1>::unit_type>>,
3141 compound_unit<typename traits::unit_value_t_traits<U1>::unit_type, typename traits::unit_value_t_traits<U2>::unit_type>>::type>
3144 using Base = units::detail::unit_value_arithmetic<U1, U2>;
3147 using ratio = std::conditional_t<traits::is_convertible_unit<typename Base::_UNIT1, typename Base::_UNIT2>::value, std::ratio_multiply<typename Base::_RATIO1, typename Base::_RATIO2CONV>, std::ratio_multiply<typename Base::_RATIO1, typename Base::_RATIO2>>;
3158 using UsePi = std::integral_constant<bool, Base::_PI_EXP::num != 0>;
3159 return value(UsePi());
3170 static constexpr
const unit_t<unit_type>
value(std::true_type) noexcept
3172 return unit_t<unit_type>(((UNIT_LIB_DEFAULT_TYPE)ratio::num / ratio::den) *
std::pow(units::constants::detail::PI_VAL, ((UNIT_LIB_DEFAULT_TYPE)Base::_PI_EXP::num / Base::_PI_EXP::den)));
3187 template<
class U1,
class U2>
3189 units::detail::_unit_value_t<typename std::conditional<traits::is_convertible_unit<typename traits::unit_value_t_traits<U1>::unit_type,
3190 typename traits::unit_value_t_traits<U2>::unit_type>::value, dimensionless::scalar, compound_unit<typename traits::unit_value_t_traits<U1>::unit_type,
3191 inverse<typename traits::unit_value_t_traits<U2>::unit_type>>>::type>
3194 using Base = units::detail::unit_value_arithmetic<U1, U2>;
3197 using ratio = std::conditional_t<traits::is_convertible_unit<typename Base::_UNIT1, typename Base::_UNIT2>::value, std::ratio_divide<typename Base::_RATIO1, typename Base::_RATIO2CONV>, std::ratio_divide<typename Base::_RATIO1, typename Base::_RATIO2>>;
3208 using UsePi = std::integral_constant<bool, Base::_PI_EXP::num != 0>;
3209 return value(UsePi());
3220 static constexpr
const unit_t<unit_type>
value(std::true_type) noexcept
3222 return unit_t<unit_type>(((UNIT_LIB_DEFAULT_TYPE)ratio::num / ratio::den) *
std::pow(units::constants::detail::PI_VAL, ((UNIT_LIB_DEFAULT_TYPE)Base::_PI_EXP::num / Base::_PI_EXP::den)));
3236 template<
class U1,
int power>
3237 struct unit_value_power : units::detail::unit_value_arithmetic<U1, U1>, units::detail::_unit_value_t<typename units::detail::power_of_unit<power, typename traits::unit_value_t_traits<U1>::unit_type>::type>
3240 using Base = units::detail::unit_value_arithmetic<U1, U1>;
3242 using unit_type =
typename units::detail::power_of_unit<power, typename Base::_UNIT1>::type;
3243 using ratio =
typename units::detail::power_of_ratio<power, typename Base::_RATIO1>::type;
3244 using pi_exponent = std::ratio_multiply<std::ratio<power>,
typename Base::_UNIT1::pi_exponent_ratio>;
3255 using UsePi = std::integral_constant<bool, Base::_PI_EXP::num != 0>;
3256 return value(UsePi());
3267 static constexpr
const unit_t<unit_type>
value(std::true_type) noexcept
3269 return unit_t<unit_type>(((UNIT_LIB_DEFAULT_TYPE)ratio::num / ratio::den) *
std::pow(units::constants::detail::PI_VAL, ((UNIT_LIB_DEFAULT_TYPE)pi_exponent::num / pi_exponent::den)));
3283 template<
class U1, std::
intmax_t Eps = 10000000000>
3284 struct unit_value_sqrt : units::detail::unit_value_arithmetic<U1, U1>, units::detail::_unit_value_t<square_root<typename traits::unit_value_t_traits<U1>::unit_type, Eps>>
3287 using Base = units::detail::unit_value_arithmetic<U1, U1>;
3302 using UsePi = std::integral_constant<bool, Base::_PI_EXP::num != 0>;
3303 return value(UsePi());
3314 static constexpr
const unit_t<unit_type>
value(std::true_type) noexcept
3316 return unit_t<unit_type>(((UNIT_LIB_DEFAULT_TYPE)ratio::num / ratio::den) *
std::pow(units::constants::detail::PI_VAL, ((UNIT_LIB_DEFAULT_TYPE)pi_exponent::num / pi_exponent::den)));
3348 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_LENGTH_UNITS)
3350 UNIT_ADD(length, foot, feet, ft, unit<std::ratio<381, 1250>, meters>)
3351 UNIT_ADD(length, mil, mils, mil, unit<std::ratio<1000>, feet>)
3352 UNIT_ADD(length, inch, inches, in, unit<std::ratio<1, 12>, feet>)
3353 UNIT_ADD(length, mile, miles, mi, unit<std::ratio<5280>, feet>)
3354 UNIT_ADD(length, nauticalMile, nauticalMiles, nmi, unit<std::ratio<1852>, meters>)
3355 UNIT_ADD(length, astronicalUnit, astronicalUnits, au, unit<std::ratio<149597870700>, meters>)
3356 UNIT_ADD(length, lightyear, lightyears, ly, unit<std::ratio<9460730472580800>, meters>)
3357 UNIT_ADD(length, parsec, parsecs, pc, unit<std::ratio<648000>, astronicalUnits, std::ratio<-1>>)
3358 UNIT_ADD(length, angstrom, angstroms, angstrom, unit<std::ratio<1, 10>, nanometers>)
3359 UNIT_ADD(length, cubit, cubits, cbt, unit<std::ratio<18>, inches>)
3360 UNIT_ADD(length, fathom, fathoms, ftm, unit<std::ratio<6>, feet>)
3361 UNIT_ADD(length, chain, chains, ch, unit<std::ratio<66>, feet>)
3362 UNIT_ADD(length, furlong, furlongs, fur, unit<std::ratio<10>, chains>)
3363 UNIT_ADD(length, hand, hands, hand, unit<std::ratio<4>, inches>)
3364 UNIT_ADD(length, league, leagues, lea, unit<std::ratio<3>, miles>)
3365 UNIT_ADD(length, nauticalLeague, nauticalLeagues, nl, unit<std::ratio<3>, nauticalMiles>)
3366 UNIT_ADD(length, yard, yards, yd, unit<std::ratio<3>, feet>)
3383 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_MASS_UNITS)
3385 UNIT_ADD(mass, metric_ton, metric_tons, t,
unit<std::ratio<1000>, kilograms>)
3386 UNIT_ADD(mass, pound, pounds, lb,
unit<std::ratio<45359237, 100000000>, kilograms>)
3387 UNIT_ADD(mass, long_ton, long_tons, ln_t,
unit<std::ratio<2240>, pounds>)
3388 UNIT_ADD(mass, short_ton, short_tons, sh_t,
unit<std::ratio<2000>, pounds>)
3389 UNIT_ADD(mass, stone, stone, st,
unit<std::ratio<14>, pounds>)
3390 UNIT_ADD(mass, ounce, ounces, oz,
unit<std::ratio<1, 16>, pounds>)
3391 UNIT_ADD(mass, carat, carats, ct,
unit<std::ratio<200>, milligrams>)
3392 UNIT_ADD(mass, slug, slugs, slug,
unit<std::ratio<145939029, 10000000>, kilograms>)
3409 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_TIME_UNITS)
3411 UNIT_ADD(time, minute, minutes, min,
unit<std::ratio<60>, seconds>)
3412 UNIT_ADD(time, hour, hours, hr,
unit<std::ratio<60>, minutes>)
3413 UNIT_ADD(time, day, days, d,
unit<std::ratio<24>, hours>)
3414 UNIT_ADD(time, week, weeks, wk,
unit<std::ratio<7>, days>)
3415 UNIT_ADD(time, year, years, yr,
unit<std::ratio<365>, days>)
3416 UNIT_ADD(time, julian_year, julian_years, a_j,
unit<std::ratio<31557600>, seconds>)
3417 UNIT_ADD(time, gregorian_year, gregorian_years, a_g,
unit<std::ratio<31556952>, seconds>)
3434 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
3436 UNIT_ADD(angle, degree, degrees, deg,
unit<std::ratio<1, 180>, radians, std::ratio<1>>)
3437 UNIT_ADD(angle, arcminute, arcminutes, arcmin,
unit<std::ratio<1, 60>, degrees>)
3438 UNIT_ADD(angle, arcsecond, arcseconds, arcsec,
unit<std::ratio<1, 60>, arcminutes>)
3439 UNIT_ADD(angle, milliarcsecond, milliarcseconds, mas,
milli<arcseconds>)
3440 UNIT_ADD(angle, turn, turns, tr,
unit<std::ratio<2>, radians, std::ratio<1>>)
3441 UNIT_ADD(angle, gradian, gradians, gon,
unit<std::ratio<1, 400>, turns>)
3457 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_CURRENT_UNITS)
3478 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_TEMPERATURE_UNITS)
3480 UNIT_ADD(temperature, celsius, celsius, degC,
unit<std::ratio<1>, kelvin, std::ratio<0>, std::ratio<27315, 100>>)
3481 UNIT_ADD(temperature, fahrenheit, fahrenheit, degF,
unit<std::ratio<5, 9>, celsius, std::ratio<0>, std::ratio<-160, 9>>)
3482 UNIT_ADD(temperature, reaumur, reaumur, Re,
unit<std::ratio<10, 8>, celsius>)
3483 UNIT_ADD(temperature, rankine, rankine, Ra,
unit<std::ratio<5, 9>, kelvin>)
3500 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_SUBSTANCE_UNITS)
3518 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_LUMINOUS_INTENSITY_UNITS)
3536 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_SOLID_ANGLE_UNITS)
3538 UNIT_ADD(solid_angle, degree_squared, degrees_squared, sq_deg,
squared<angle::degrees>)
3539 UNIT_ADD(solid_angle, spat, spats, sp,
unit<std::ratio<4>, steradians, std::ratio<1>>)
3556 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_FREQUENCY_UNITS)
3574 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_VELOCITY_UNITS)
3576 UNIT_ADD(velocity, feet_per_second, feet_per_second, fps,
compound_unit<length::feet,
inverse<time::seconds>>)
3577 UNIT_ADD(velocity, miles_per_hour, miles_per_hour, mph,
compound_unit<length::miles,
inverse<time::hour>>)
3578 UNIT_ADD(velocity, kilometers_per_hour, kilometers_per_hour, kph,
compound_unit<length::kilometers,
inverse<time::hour>>)
3579 UNIT_ADD(velocity, knot, knots, kts,
compound_unit<length::nauticalMiles,
inverse<time::hour>>)
3596 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGULAR_VELOCITY_UNITS)
3598 UNIT_ADD(angular_velocity, degrees_per_second, degrees_per_second, deg_per_s,
compound_unit<angle::degrees,
inverse<time::seconds>>)
3599 UNIT_ADD(angular_velocity, revolutions_per_minute, revolutions_per_minute, rpm,
unit<std::ratio<2, 60>, radians_per_second, std::ratio<1>>)
3600 UNIT_ADD(angular_velocity, milliarcseconds_per_year, milliarcseconds_per_year, mas_per_yr,
compound_unit<angle::milliarcseconds,
inverse<time::year>>)
3617 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ACCELERATION_UNITS)
3619 UNIT_ADD(acceleration, feet_per_second_squared, feet_per_second_squared, fps_sq,
compound_unit<length::feet,
inverse<
squared<time::seconds>>>)
3620 UNIT_ADD(acceleration, standard_gravity, standard_gravity, SG,
unit<std::ratio<980665, 100000>, meters_per_second_squared>)
3637 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_FORCE_UNITS)
3640 UNIT_ADD(force, dyne, dynes, dyn,
unit<std::ratio<1, 100000>, newtons>)
3641 UNIT_ADD(force, kilopond, kiloponds, kp,
compound_unit<acceleration::standard_gravity, mass::kilograms>)
3659 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_PRESSURE_UNITS)
3661 UNIT_ADD(pressure, bar, bars, bar,
unit<std::ratio<100>,
kilo<pascals>>)
3662 UNIT_ADD(pressure, mbar, mbars, mbar,
unit<std::ratio<1>,
milli<bar>>)
3663 UNIT_ADD(pressure, atmosphere, atmospheres, atm,
unit<std::ratio<101325>, pascals>)
3664 UNIT_ADD(pressure, pounds_per_square_inch, pounds_per_square_inch, psi,
compound_unit<force::pounds,
inverse<
squared<length::inch>>>)
3665 UNIT_ADD(pressure, torr, torrs, torr,
unit<std::ratio<1, 760>, atmospheres>)
3682 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_CHARGE_UNITS)
3701 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ENERGY_UNITS)
3704 UNIT_ADD(energy, kilowatt_hour, kilowatt_hours, kWh,
unit<std::ratio<36, 10>, megajoules>)
3705 UNIT_ADD(energy, watt_hour, watt_hours, Wh,
unit<std::ratio<1, 1000>, kilowatt_hours>)
3706 UNIT_ADD(energy, british_thermal_unit, british_thermal_units, BTU,
unit<std::ratio<105505585262, 100000000>, joules>)
3707 UNIT_ADD(energy, british_thermal_unit_iso, british_thermal_units_iso, BTU_iso,
unit<std::ratio<1055056, 1000>, joules>)
3708 UNIT_ADD(energy, british_thermal_unit_59, british_thermal_units_59, BTU59,
unit<std::ratio<1054804, 1000>, joules>)
3709 UNIT_ADD(energy, therm, therms, thm,
unit<std::ratio<100000>, british_thermal_units_59>)
3710 UNIT_ADD(energy, foot_pound, foot_pounds, ftlbf,
unit<std::ratio<13558179483314004, 10000000000000000>, joules>)
3727 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_POWER_UNITS)
3729 UNIT_ADD(power, horsepower, horsepower, hp,
unit<std::ratio<7457, 10>, watts>)
3748 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_VOLTAGE_UNITS)
3750 UNIT_ADD(voltage, statvolt, statvolts, statV,
unit<std::ratio<1000000, 299792458>, volts>)
3751 UNIT_ADD(voltage, abvolt, abvolts, abV,
unit<std::ratio<1, 100000000>, volts>)
3768 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_CAPACITANCE_UNITS)
3786 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_IMPEDANCE_UNITS)
3804 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_CONDUCTANCE_UNITS)
3822 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_MAGNETIC_FLUX_UNITS)
3824 UNIT_ADD(magnetic_flux, maxwell, maxwells, Mx,
unit<std::ratio<1, 100000000>, webers>)
3842 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_MAGNETIC_FIELD_STRENGTH_UNITS)
3861 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_INDUCTANCE_UNITS)
3879 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_LUMINOUS_FLUX_UNITS)
3897 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ILLUMINANCE_UNITS)
3900 UNIT_ADD(illuminance, lumens_per_square_inch, lumens_per_square_inch, lm_per_in_sq,
compound_unit<luminous_flux::lumen,
inverse<
squared<length::inch>>>)
3920 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_RADIATION_UNITS)
3924 UNIT_ADD(radiation, curie, curies, Ci,
unit<std::ratio<37>, gigabecquerels>)
3925 UNIT_ADD(radiation, rutherford, rutherfords, rd,
unit<std::ratio<1>, megabecquerels>)
3926 UNIT_ADD(radiation, rad, rads, rads,
unit<std::ratio<1>, centigrays>)
3943 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_TORQUE_UNITS)
3945 UNIT_ADD(torque, foot_pound, foot_pounds, ftlb,
compound_unit<length::foot, force::pounds>)
3946 UNIT_ADD(torque, foot_poundal, foot_poundals, ftpdl,
compound_unit<length::foot, force::poundal>)
3947 UNIT_ADD(torque, inch_pound, inch_pounds, inlb,
compound_unit<length::inch, force::pounds>)
3948 UNIT_ADD(torque, meter_kilogram, meter_kilograms, mkgf,
compound_unit<length::meter, force::kiloponds>)
3965 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_AREA_UNITS)
3967 UNIT_ADD(area, square_foot, square_feet, sq_ft,
squared<length::feet>)
3968 UNIT_ADD(area, square_inch, square_inches, sq_in,
squared<length::inch>)
3969 UNIT_ADD(area, square_mile, square_miles, sq_mi,
squared<length::miles>)
3970 UNIT_ADD(area, square_kilometer, square_kilometers, sq_km,
squared<length::kilometers>)
3971 UNIT_ADD(area, hectare, hectares, ha,
unit<std::ratio<10000>, square_meters>)
3972 UNIT_ADD(area, acre, acres, acre,
unit<std::ratio<43560>, square_feet>)
3989 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_VOLUME_UNITS)
3991 UNIT_ADD(volume, cubic_millimeter, cubic_millimeters, cu_mm,
cubed<length::millimeter>)
3992 UNIT_ADD(volume, cubic_kilometer, cubic_kilometers, cu_km,
cubed<length::kilometer>)
3994 UNIT_ADD(volume, cubic_inch, cubic_inches, cu_in,
cubed<length::inches>)
3995 UNIT_ADD(volume, cubic_foot, cubic_feet, cu_ft,
cubed<length::feet>)
3996 UNIT_ADD(volume, cubic_yard, cubic_yards, cu_yd,
cubed<length::yards>)
3997 UNIT_ADD(volume, cubic_mile, cubic_miles, cu_mi,
cubed<length::miles>)
3998 UNIT_ADD(volume, gallon, gallons, gal,
unit<std::ratio<231>, cubic_inches>)
3999 UNIT_ADD(volume, quart, quarts, qt,
unit<std::ratio<1, 4>, gallons>)
4000 UNIT_ADD(volume, pint, pints, pt,
unit<std::ratio<1, 2>, quarts>)
4001 UNIT_ADD(volume, cup, cups,
c,
unit<std::ratio<1, 2>, pints>)
4002 UNIT_ADD(volume, fluid_ounce, fluid_ounces, fl_oz,
unit<std::ratio<1, 8>, cups>)
4003 UNIT_ADD(volume, barrel, barrels, bl,
unit<std::ratio<42>, gallons>)
4004 UNIT_ADD(volume, bushel, bushels, bu,
unit<std::ratio<215042, 100>, cubic_inches>)
4005 UNIT_ADD(volume, cord, cords, cord,
unit<std::ratio<128>, cubic_feet>)
4006 UNIT_ADD(volume, cubic_fathom, cubic_fathoms, cu_fm,
cubed<length::fathom>)
4007 UNIT_ADD(volume, tablespoon, tablespoons, tbsp,
unit<std::ratio<1, 2>, fluid_ounces>)
4008 UNIT_ADD(volume, teaspoon, teaspoons, tsp,
unit<std::ratio<1, 6>, fluid_ounces>)
4009 UNIT_ADD(volume, pinch, pinches, pinch,
unit<std::ratio<1, 8>, teaspoons>)
4010 UNIT_ADD(volume, dash, dashes, dash,
unit<std::ratio<1, 2>, pinches>)
4011 UNIT_ADD(volume, drop, drops, drop,
unit<std::ratio<1, 360>, fluid_ounces>)
4012 UNIT_ADD(volume, fifth, fifths, fifth,
unit<std::ratio<1, 5>, gallons>)
4013 UNIT_ADD(volume, dram, drams, dr,
unit<std::ratio<1, 8>, fluid_ounces>)
4014 UNIT_ADD(volume, gill, gills, gi,
unit<std::ratio<4>, fluid_ounces>)
4015 UNIT_ADD(volume, peck, pecks, pk,
unit<std::ratio<1, 4>, bushels>)
4016 UNIT_ADD(volume, sack, sacks, sacks,
unit<std::ratio<3>, bushels>)
4017 UNIT_ADD(volume, shot, shots, shots,
unit<std::ratio<3, 2>, fluid_ounces>)
4018 UNIT_ADD(volume, strike, strikes, strikes,
unit<std::ratio<2>, bushels>)
4035 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_DENSITY_UNITS)
4037 UNIT_ADD(density, grams_per_milliliter, grams_per_milliliter, g_per_mL,
compound_unit<mass::grams,
inverse<volume::milliliter>>)
4038 UNIT_ADD(density, kilograms_per_liter, kilograms_per_liter, kg_per_L,
unit<std::ratio<1>,
compound_unit<mass::grams,
inverse<volume::milliliter>>>)
4039 UNIT_ADD(density, ounces_per_cubic_foot, ounces_per_cubic_foot, oz_per_cu_ft,
compound_unit<mass::ounces,
inverse<volume::cubic_foot>>)
4040 UNIT_ADD(density, ounces_per_cubic_inch, ounces_per_cubic_inch, oz_per_cu_in,
compound_unit<mass::ounces,
inverse<volume::cubic_inch>>)
4041 UNIT_ADD(density, ounces_per_gallon, ounces_per_gallon, oz_per_gal,
compound_unit<mass::ounces,
inverse<volume::gallon>>)
4042 UNIT_ADD(density, pounds_per_cubic_foot, pounds_per_cubic_foot, lb_per_cu_ft,
compound_unit<mass::pounds,
inverse<volume::cubic_foot>>)
4043 UNIT_ADD(density, pounds_per_cubic_inch, pounds_per_cubic_inch, lb_per_cu_in,
compound_unit<mass::pounds,
inverse<volume::cubic_inch>>)
4044 UNIT_ADD(density, pounds_per_gallon, pounds_per_gallon, lb_per_gal,
compound_unit<mass::pounds,
inverse<volume::gallon>>)
4045 UNIT_ADD(density, slugs_per_cubic_foot, slugs_per_cubic_foot, slug_per_cu_ft,
compound_unit<mass::slugs,
inverse<volume::cubic_foot>>)
4062 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_CONCENTRATION_UNITS)
4064 UNIT_ADD(concentration, ppb, parts_per_billion, ppb,
unit<std::ratio<1, 1000>, parts_per_million>)
4065 UNIT_ADD(concentration, ppt, parts_per_trillion, ppt,
unit<std::ratio<1, 1000>, parts_per_billion>)
4066 UNIT_ADD(concentration, percent, percent, pct,
unit<std::ratio<1, 100>,
units::category::
scalar_unit>)
4083 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_DATA_UNITS)
4085 UNIT_ADD(data, exabyte, exabytes, EB,
unit<std::ratio<1000>, petabytes>)
4087 UNIT_ADD(data, exabit, exabits, Eb,
unit<std::ratio<1000>, petabits>)
4104 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_DATA_TRANSFER_RATE_UNITS)
4106 UNIT_ADD(data_transfer_rate, exabytes_per_second, exabytes_per_second, EBps,
unit<std::ratio<1000>, petabytes_per_second>)
4108 UNIT_ADD(data_transfer_rate, exabits_per_second, exabits_per_second, Ebps,
unit<std::ratio<1000>, petabits_per_second>)
4121 #if !defined(DISABLE_PREDEFINED_UNITS)
4140 static constexpr
const mass::kilogram_t
m_e(9.10938356
e-31);
4141 static constexpr
const mass::kilogram_t
m_p(1.672621898
e-27);
4168 template<
class UnitTypeLhs,
class UnitTypeRhs>
4169 UnitTypeLhs min(
const UnitTypeLhs& lhs,
const UnitTypeRhs& rhs)
4173 return (lhs < r ? lhs : r);
4176 template<
class UnitTypeLhs,
class UnitTypeRhs>
4177 UnitTypeLhs max(
const UnitTypeLhs& lhs,
const UnitTypeRhs& rhs)
4179 static_assert(traits::is_convertible_unit_t<UnitTypeLhs, UnitTypeRhs>::value,
"Unit types are not compatible.");
4181 return (lhs > r ? lhs : r);
4196 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
4197 template<
class AngleUnit>
4213 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
4214 template<
class AngleUnit>
4229 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
4230 template<
class AngleUnit>
4245 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
4246 template<
class ScalarUnit>
4261 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
4262 template<
class ScalarUnit>
4281 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
4282 template<
class ScalarUnit>
4298 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
4299 template<
class Y,
class X>
4321 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
4322 template<
class AngleUnit>
4338 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
4339 template<
class AngleUnit>
4355 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
4356 template<
class AngleUnit>
4372 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
4373 template<
class ScalarUnit>
4388 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
4389 template<
class ScalarUnit>
4406 #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
4407 template<
class ScalarUnit>
4431 template<
class ScalarUnit>
4447 template<
class ScalarUnit>
4462 template<
class ScalarUnit>
4480 template<
class ScalarUnit>
4485 UNIT_LIB_DEFAULT_TYPE intp;
4498 template<
class ScalarUnit>
4513 template<
class ScalarUnit>
4529 template<
class ScalarUnit>
4544 template<
class ScalarUnit>
4569 template<class UnitType, std::enable_if_t<units::traits::has_linear_scale<UnitType>::value,
int> = 0>
4585 template<class UnitTypeLhs, class UnitTypeRhs, std::enable_if_t<units::traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value,
int> = 0>
4586 inline UnitTypeLhs
hypot(
const UnitTypeLhs& x,
const UnitTypeRhs& y)
4589 return UnitTypeLhs(
std::hypot(x(), y.template
convert<
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type>()()));
4603 template<class UnitType, class = std::enable_if_t<traits::is_unit_t<UnitType>::value>>
4604 UnitType
ceil(
const UnitType x) noexcept
4616 template<class UnitType, class = std::enable_if_t<traits::is_unit_t<UnitType>::value>>
4617 UnitType
floor(
const UnitType x) noexcept
4631 UnitTypeLhs
fmod(
const UnitTypeLhs numer,
const UnitTypeRhs denom) noexcept
4634 return UnitTypeLhs(
std::fmod(numer(), denom.template
convert<
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type>()()));
4645 template<class UnitType, class = std::enable_if_t<traits::is_unit_t<UnitType>::value>>
4646 UnitType
trunc(
const UnitType x) noexcept
4660 template<class UnitType, class = std::enable_if_t<traits::is_unit_t<UnitType>::value>>
4661 UnitType
round(
const UnitType x) noexcept
4680 UnitTypeLhs
copysign(
const UnitTypeLhs x,
const UnitTypeRhs y) noexcept
4686 template<class UnitTypeLhs, class = std::enable_if_t<traits::is_unit_t<UnitTypeLhs>::value>>
4687 UnitTypeLhs
copysign(
const UnitTypeLhs x,
const UNIT_LIB_DEFAULT_TYPE y) noexcept
4707 UnitTypeLhs
fdim(
const UnitTypeLhs x,
const UnitTypeRhs y) noexcept
4710 return UnitTypeLhs(
std::fdim(x(), y.template
convert<
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type>()()));
4724 UnitTypeLhs
fmax(
const UnitTypeLhs x,
const UnitTypeRhs y) noexcept
4727 return UnitTypeLhs(
std::fmax(x(), y.template
convert<
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type>()()));
4742 UnitTypeLhs
fmin(
const UnitTypeLhs x,
const UnitTypeRhs y) noexcept
4745 return UnitTypeLhs(
std::fmin(x(), y.template
convert<
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type>()()));
4759 template<class UnitType, class = std::enable_if_t<traits::is_unit_t<UnitType>::value>>
4760 UnitType
fabs(
const UnitType x) noexcept
4772 template<class UnitType, class = std::enable_if_t<traits::is_unit_t<UnitType>::value>>
4773 UnitType
abs(
const UnitType x) noexcept
4789 auto fma(
const UnitTypeLhs x,
const UnitMultiply y,
const UnitAdd z) noexcept -> decltype(x * y)
4791 using resultType = decltype(x * y);
4792 static_assert(
traits::is_convertible_unit_t<
compound_unit<
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type,
typename units::traits::unit_t_traits<UnitMultiply>::unit_type>,
typename units::traits::unit_t_traits<UnitAdd>::unit_type>::value,
"Unit types are not compatible.");
4793 return resultType(
std::fma(x(), y(), resultType(z)()));
4805 template<
class Units,
typename T,
template<
typename>
class NonLinearScale>
4806 class numeric_limits<
units::unit_t<Units, T, NonLinearScale>>
4825 # if _MSC_VER <= 1800
4826 # pragma warning(pop)
4828 # pragma pop_macro("constexpr")
4830 # pragma pop_macro("noexcept")
4831 # undef _ALLOW_KEYWORD_MACROS
4832 # endif // _MSC_VER < 1800
4833 # pragma pop_macro("pascal")