41# pragma push_macro("pascal")
44# define _ALLOW_KEYWORD_MACROS
46# pragma warning(disable : 4520)
47# pragma push_macro("constexpr")
49# pragma push_macro("noexcept")
50# define noexcept throw()
54#if !defined(_MSC_VER) || _MSC_VER > 1800
55# define UNIT_HAS_LITERAL_SUPPORT
58#ifndef UNIT_LIB_DEFAULT_TYPE
59# define UNIT_LIB_DEFAULT_TYPE double
73#if defined(UNIT_LIB_ENABLE_IOSTREAM)
78#if __has_include(<fmt/format.h>) && !defined(UNIT_LIB_DISABLE_FMT)
94 template <
typename T> std::string
to_string(
const T& t)
96 std::string str{ std::to_string(t) };
102 char decimalPoint = *lc->decimal_point;
103 if (str.find_last_not_of(
'0') == str.find(decimalPoint)) { offset = 0; }
104 str.erase(str.find_last_not_of(
'0') + offset, std::string::npos);
112 template<
typename T>
constexpr const char*
name(
const T&);
136#define UNIT_ADD_UNIT_TAGS(namespaceName,nameSingular, namePlural, abbreviation, ...)\
137 namespace namespaceName\
139 typedef __VA_ARGS__ namePlural; \
140 typedef namePlural nameSingular; \
141 typedef namePlural abbreviation; \
151#define UNIT_ADD_UNIT_DEFINITION(namespaceName,nameSingular)\
152 namespace namespaceName\
154 typedef unit_t<nameSingular> nameSingular ## _t; \
165#define UNIT_ADD_CUSTOM_TYPE_UNIT_DEFINITION(namespaceName,nameSingular, underlyingType)\
166 namespace namespaceName\
168 typedef unit_t<nameSingular,underlyingType> nameSingular ## _t; \
180#if __has_include(<fmt/format.h>) && !defined(UNIT_LIB_DISABLE_FMT)
181 #define UNIT_ADD_IO(namespaceName, nameSingular, abbrev)\
184 struct fmt::formatter<units::namespaceName::nameSingular ## _t> \
185 : fmt::formatter<double> \
187 template <typename FmtContext>\
189 const units::namespaceName::nameSingular ## _t& obj,\
190 FmtContext& ctx) const\
192 auto out = ctx.out();\
193 out = fmt::formatter<double>::format(obj(), ctx);\
194 return fmt::format_to(out, " " #abbrev);\
199 namespace namespaceName\
201 inline std::string to_string(const nameSingular ## _t& obj)\
203 return units::detail::to_string(obj()) + std::string(" "#abbrev);\
206#elif defined(UNIT_LIB_ENABLE_IOSTREAM)
207 #define UNIT_ADD_IO(namespaceName, nameSingular, abbrev)\
208 namespace namespaceName\
210 inline std::ostream& operator<<(std::ostream& os, const nameSingular ## _t& obj) \
212 os << obj() << " "#abbrev; return os; \
214 inline std::string to_string(const nameSingular ## _t& obj)\
216 return units::detail::to_string(obj()) + std::string(" "#abbrev);\
220 #define UNIT_ADD_IO(namespaceName, nameSingular, abbrev)
233#define UNIT_ADD_NAME(namespaceName, nameSingular, abbrev)\
234template<> constexpr const char* name(const namespaceName::nameSingular ## _t&)\
236 return #nameSingular;\
238template<> constexpr const char* abbreviation(const namespaceName::nameSingular ## _t&)\
254#if defined(UNIT_HAS_LITERAL_SUPPORT)
255 #define UNIT_ADD_LITERALS(namespaceName, nameSingular, abbreviation)\
258 constexpr namespaceName::nameSingular ## _t operator""_ ## abbreviation(long double d)\
260 return namespaceName::nameSingular ## _t(static_cast<namespaceName::nameSingular ## _t::underlying_type>(d));\
262 constexpr namespaceName::nameSingular ## _t operator""_ ## abbreviation (unsigned long long d)\
264 return namespaceName::nameSingular ## _t(static_cast<namespaceName::nameSingular ## _t::underlying_type>(d));\
268 #define UNIT_ADD_LITERALS(namespaceName, nameSingular, abbreviation)
290#define UNIT_ADD(namespaceName, nameSingular, namePlural, abbreviation, ...)\
291 UNIT_ADD_UNIT_TAGS(namespaceName,nameSingular, namePlural, abbreviation, __VA_ARGS__)\
292 UNIT_ADD_UNIT_DEFINITION(namespaceName,nameSingular)\
293 UNIT_ADD_NAME(namespaceName,nameSingular, abbreviation)\
294 UNIT_ADD_IO(namespaceName,nameSingular, abbreviation)\
295 UNIT_ADD_LITERALS(namespaceName,nameSingular, abbreviation)
317#define UNIT_ADD_WITH_CUSTOM_TYPE(namespaceName, nameSingular, namePlural, abbreviation, underlyingType, ...)\
318 UNIT_ADD_UNIT_TAGS(namespaceName,nameSingular, namePlural, abbreviation, __VA_ARGS__)\
319 UNIT_ADD_CUSTOM_TYPE_UNIT_DEFINITION(namespaceName,nameSingular,underlyingType)\
320 UNIT_ADD_IO(namespaceName,nameSingular, abbreviation)\
321 UNIT_ADD_LITERALS(namespaceName,nameSingular, abbreviation)
332#define UNIT_ADD_DECIBEL(namespaceName, nameSingular, abbreviation)\
333 namespace namespaceName\
335 typedef unit_t<nameSingular, UNIT_LIB_DEFAULT_TYPE, units::decibel_scale> abbreviation ## _t; \
337 UNIT_ADD_IO(namespaceName, abbreviation, abbreviation)\
338 UNIT_ADD_LITERALS(namespaceName, abbreviation, abbreviation)
349#define UNIT_ADD_CATEGORY_TRAIT_DETAIL(unitCategory)\
355 template<typename T> struct is_ ## unitCategory ## _unit_impl : std::false_type {};\
356 template<typename C, typename U, typename P, typename T>\
357 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 {};\
358 template<typename U, typename S, template<typename> class N>\
359 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 {};\
364#define UNIT_ADD_IS_UNIT_CATEGORY_TRAIT(unitCategory)\
367 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> {};\
368 template<typename... T> constexpr bool is_ ## unitCategory ## _unit_v = is_ ## unitCategory ## _unit<T...>::value;\
370 template <typename T>\
371 concept unitCategory ## _unit = traits::is_ ## unitCategory ## _unit_v<T>;
373#define UNIT_ADD_CATEGORY_TRAIT(unitCategory)\
374 UNIT_ADD_CATEGORY_TRAIT_DETAIL(unitCategory)\
379 UNIT_ADD_IS_UNIT_CATEGORY_TRAIT(unitCategory)
399#define UNIT_ADD_WITH_METRIC_PREFIXES(namespaceName, nameSingular, namePlural, abbreviation, ...)\
400 UNIT_ADD(namespaceName, nameSingular, namePlural, abbreviation, __VA_ARGS__)\
401 UNIT_ADD(namespaceName, femto ## nameSingular, femto ## namePlural, f ## abbreviation, femto<namePlural>)\
402 UNIT_ADD(namespaceName, pico ## nameSingular, pico ## namePlural, p ## abbreviation, pico<namePlural>)\
403 UNIT_ADD(namespaceName, nano ## nameSingular, nano ## namePlural, n ## abbreviation, nano<namePlural>)\
404 UNIT_ADD(namespaceName, micro ## nameSingular, micro ## namePlural, u ## abbreviation, micro<namePlural>)\
405 UNIT_ADD(namespaceName, milli ## nameSingular, milli ## namePlural, m ## abbreviation, milli<namePlural>)\
406 UNIT_ADD(namespaceName, centi ## nameSingular, centi ## namePlural, c ## abbreviation, centi<namePlural>)\
407 UNIT_ADD(namespaceName, deci ## nameSingular, deci ## namePlural, d ## abbreviation, deci<namePlural>)\
408 UNIT_ADD(namespaceName, deca ## nameSingular, deca ## namePlural, da ## abbreviation, deca<namePlural>)\
409 UNIT_ADD(namespaceName, hecto ## nameSingular, hecto ## namePlural, h ## abbreviation, hecto<namePlural>)\
410 UNIT_ADD(namespaceName, kilo ## nameSingular, kilo ## namePlural, k ## abbreviation, kilo<namePlural>)\
411 UNIT_ADD(namespaceName, mega ## nameSingular, mega ## namePlural, M ## abbreviation, mega<namePlural>)\
412 UNIT_ADD(namespaceName, giga ## nameSingular, giga ## namePlural, G ## abbreviation, giga<namePlural>)\
413 UNIT_ADD(namespaceName, tera ## nameSingular, tera ## namePlural, T ## abbreviation, tera<namePlural>)\
414 UNIT_ADD(namespaceName, peta ## nameSingular, peta ## namePlural, P ## abbreviation, peta<namePlural>)\
434#define UNIT_ADD_WITH_METRIC_AND_BINARY_PREFIXES(namespaceName, nameSingular, namePlural, abbreviation, ...)\
435 UNIT_ADD_WITH_METRIC_PREFIXES(namespaceName, nameSingular, namePlural, abbreviation, __VA_ARGS__)\
436 UNIT_ADD(namespaceName, kibi ## nameSingular, kibi ## namePlural, Ki ## abbreviation, kibi<namePlural>)\
437 UNIT_ADD(namespaceName, mebi ## nameSingular, mebi ## namePlural, Mi ## abbreviation, mebi<namePlural>)\
438 UNIT_ADD(namespaceName, gibi ## nameSingular, gibi ## namePlural, Gi ## abbreviation, gibi<namePlural>)\
439 UNIT_ADD(namespaceName, tebi ## nameSingular, tebi ## namePlural, Ti ## abbreviation, tebi<namePlural>)\
440 UNIT_ADD(namespaceName, pebi ## nameSingular, pebi ## namePlural, Pi ## abbreviation, pebi<namePlural>)\
441 UNIT_ADD(namespaceName, exbi ## nameSingular, exbi ## namePlural, Ei ## abbreviation, exbi<namePlural>)
520 static constexpr const UNIT_LIB_DEFAULT_TYPE PI_VAL = 3.14159265358979323846264338327950288419716939937510;
542 static constexpr auto test(U*)->std::is_integral<
decltype(U::num)> {
return std::is_integral<
decltype(U::num)>{}; }
544 static constexpr std::false_type test(...) {
return std::false_type{}; }
546 using type =
decltype(test<T>(0));
556 struct has_num : units::detail::has_num_impl<T>::type {};
565 static constexpr auto test(U*)->std::is_integral<
decltype(U::den)> {
return std::is_integral<
decltype(U::den)>{}; }
567 static constexpr std::false_type test(...) {
return std::false_type{}; }
569 using type =
decltype(test<T>(0));
579 struct has_den : units::detail::has_den_impl<T>::type {};
609 struct void_t {
typedef void type; };
614 template<
bool...>
struct bool_pack {};
619 template<
bool... Args>
620 struct all_true : std::is_same<units::bool_pack<true, Args...>, units::bool_pack<Args..., true>> {};
621 template<
bool... Args>
622 constexpr bool all_true_t_v = all_true<Args...>::type::value;
630#ifdef FOR_DOXYGEN_PURPOSES_ONLY
641 typedef typename T::base_unit_type base_unit_type;
642 typedef typename T::conversion_ratio conversion_ratio;
643 typedef typename T::pi_exponent_ratio pi_exponent_ratio;
644 typedef typename T::translation_ratio translation_ratio;
651 template<
class T,
typename =
void>
654 typedef void base_unit_type;
655 typedef void conversion_ratio;
656 typedef void pi_exponent_ratio;
657 typedef void translation_ratio;
663 typename T::base_unit_type,
664 typename T::conversion_ratio,
665 typename T::pi_exponent_ratio,
666 typename T::translation_ratio>::type>
668 typedef typename T::base_unit_type base_unit_type;
669 typedef typename T::conversion_ratio conversion_ratio;
670 typedef typename T::pi_exponent_ratio pi_exponent_ratio;
671 typedef typename T::translation_ratio translation_ratio;
683 struct _base_unit_t {};
696 struct is_base_unit : std::is_base_of<units::detail::_base_unit_t, T> {};
708 template<std::
intmax_t Num, std::
intmax_t Den = 1>
709 using meter_ratio = std::ratio<Num, Den>;
722 struct is_unit : std::is_base_of<units::detail::_unit, T>::type {};
751 template<
class Meter = detail::meter_ratio<0>,
752 class Kilogram = std::ratio<0>,
753 class Second = std::ratio<0>,
754 class Radian = std::ratio<0>,
755 class Ampere = std::ratio<0>,
756 class Kelvin = std::ratio<0>,
757 class Mole = std::ratio<0>,
758 class Candela = std::ratio<0>,
759 class Byte = std::ratio<0>>
762 static_assert(
traits::is_ratio<Meter>::value,
"Template parameter `Meter` must be a `std::ratio` representing the exponent of meters the unit has");
764 static_assert(
traits::is_ratio<Second>::value,
"Template parameter `Second` must be a `std::ratio` representing the exponent of seconds the unit has");
765 static_assert(
traits::is_ratio<Ampere>::value,
"Template parameter `Ampere` must be a `std::ratio` representing the exponent of amperes the unit has");
768 static_assert(
traits::is_ratio<Mole>::value,
"Template parameter `Mole` must be a `std::ratio` representing the exponent of moles the unit has");
769 static_assert(
traits::is_ratio<Radian>::value,
"Template parameter `Radian` must be a `std::ratio` representing the exponent of radians the unit has");
770 static_assert(
traits::is_ratio<Byte>::value,
"Template parameter `Byte` must be a `std::ratio` representing the exponent of bytes the unit has");
830 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;
852 template <
class,
class,
class,
class>
struct unit;
853 template<
class Conversion,
class... Exponents,
class PiExponent,
class Translation>
854 struct unit<Conversion,
base_unit<Exponents...>, PiExponent, Translation> : units::detail::_unit
858 static_assert(
traits::is_ratio<Translation>::value,
"Template parameter `Translation` must be a `std::ratio` representing an additive translation required by the unit conversion.");
886 template<
class Conversion,
class BaseUnit,
class PiExponent = std::ratio<0>,
class Translation = std::ratio<0>>
887 struct unit : units::detail::_unit
893 typedef typename units::traits::unit_traits<BaseUnit>::base_unit_type
base_unit_type;
894 typedef typename std::ratio_multiply<typename BaseUnit::conversion_ratio, Conversion>
conversion_ratio;
895 typedef typename std::ratio_add<typename BaseUnit::pi_exponent_ratio, PiExponent>
pi_exponent_ratio;
896 typedef typename std::ratio_add<std::ratio_multiply<typename BaseUnit::conversion_ratio, Translation>,
typename BaseUnit::translation_ratio>
translation_ratio;
911 template<
class>
struct base_unit_of_impl;
912 template<
class Conversion,
class BaseUnit,
class PiExponent,
class Translation>
913 struct base_unit_of_impl<
unit<Conversion, BaseUnit, PiExponent, Translation>> : base_unit_of_impl<BaseUnit> {};
914 template<
class... Exponents>
915 struct base_unit_of_impl<base_unit<Exponents...>>
917 typedef base_unit<Exponents...> type;
920 struct base_unit_of_impl<void>
936 using base_unit_of =
typename units::detail::base_unit_of_impl<U>::type;
947 template<
class,
class>
struct base_unit_multiply_impl;
948 template<
class... Exponents1,
class... Exponents2>
956 template<
class U1,
class U2>
957 using base_unit_multiply =
typename base_unit_multiply_impl<U1, U2>::type;
964 template<
class,
class>
struct base_unit_divide_impl;
965 template<
class... Exponents1,
class... Exponents2>
966 struct base_unit_divide_impl<base_unit<Exponents1...>, base_unit<Exponents2...>> {
967 using type = base_unit<std::ratio_subtract<Exponents1, Exponents2>...>;
973 template<
class U1,
class U2>
974 using base_unit_divide =
typename base_unit_divide_impl<U1, U2>::type;
981 template<
class>
struct inverse_base_impl;
983 template<
class... Exponents>
984 struct inverse_base_impl<base_unit<Exponents...>> {
985 using type = base_unit<std::ratio_multiply<Exponents, std::ratio<-1>>...>;
992 template<
class U>
using inverse_base =
typename inverse_base_impl<U>::type;
999 template<
class U>
struct squared_base_impl;
1000 template<
class... Exponents>
1001 struct squared_base_impl<base_unit<Exponents...>> {
1002 using type = base_unit<std::ratio_multiply<Exponents, std::ratio<2>>...>;
1009 template<
class U>
using squared_base =
typename squared_base_impl<U>::type;
1016 template<
class U>
struct cubed_base_impl;
1017 template<
class... Exponents>
1018 struct cubed_base_impl<base_unit<Exponents...>> {
1019 using type = base_unit<std::ratio_multiply<Exponents, std::ratio<3>>...>;
1026 template<
class U>
using cubed_base =
typename cubed_base_impl<U>::type;
1033 template<
class U>
struct sqrt_base_impl;
1034 template<
class... Exponents>
1035 struct sqrt_base_impl<base_unit<Exponents...>> {
1036 using type = base_unit<std::ratio_divide<Exponents, std::ratio<2>>...>;
1043 template<
class U>
using sqrt_base =
typename sqrt_base_impl<U>::type;
1050 template<
class U>
struct cbrt_base_impl;
1051 template<
class... Exponents>
1052 struct cbrt_base_impl<base_unit<Exponents...>> {
1053 using type = base_unit<std::ratio_divide<Exponents, std::ratio<3>>...>;
1060 template<
class U>
using cbrt_base =
typename cbrt_base_impl<U>::type;
1077 template<
class Unit1,
class Unit2>
1078 struct unit_multiply_impl
1080 using type = unit < std::ratio_multiply<typename Unit1::conversion_ratio, typename Unit2::conversion_ratio>,
1081 base_unit_multiply <traits::base_unit_of<typename Unit1::base_unit_type>, traits::base_unit_of<typename Unit2::base_unit_type>>,
1082 std::ratio_add<typename Unit1::pi_exponent_ratio, typename Unit2::pi_exponent_ratio>,
1090 template<
class U1,
class U2>
1091 using unit_multiply =
typename unit_multiply_impl<U1, U2>::type;
1099 template<
class Unit1,
class Unit2>
1100 struct unit_divide_impl
1102 using type = unit < std::ratio_divide<typename Unit1::conversion_ratio, typename Unit2::conversion_ratio>,
1103 base_unit_divide<traits::base_unit_of<typename Unit1::base_unit_type>, traits::base_unit_of<typename Unit2::base_unit_type>>,
1104 std::ratio_subtract<typename Unit1::pi_exponent_ratio, typename Unit2::pi_exponent_ratio>,
1112 template<
class U1,
class U2>
1113 using unit_divide =
typename unit_divide_impl<U1, U2>::type;
1121 template<
class Unit>
1124 using type = unit < std::ratio<Unit::conversion_ratio::den, Unit::conversion_ratio::num>,
1125 inverse_base<traits::base_unit_of<typename units::traits::unit_traits<Unit>::base_unit_type>>,
1126 std::ratio_multiply<typename units::traits::unit_traits<Unit>::pi_exponent_ratio, std::ratio<-1>>,
1138 template<
class U>
using inverse =
typename units::detail::inverse_impl<U>::type;
1148 template<
class Unit>
1152 using Conversion =
typename Unit::conversion_ratio;
1153 using type = unit < std::ratio_multiply<Conversion, Conversion>,
1154 squared_base<traits::base_unit_of<typename Unit::base_unit_type>>,
1155 std::ratio_multiply<typename Unit::pi_exponent_ratio, std::ratio<2>>,
1156 typename Unit::translation_ratio
1169 using squared =
typename units::detail::squared_impl<U>::type;
1179 template<
class Unit>
1183 using Conversion =
typename Unit::conversion_ratio;
1184 using type = unit < std::ratio_multiply<Conversion, std::ratio_multiply<Conversion, Conversion>>,
1185 cubed_base<traits::base_unit_of<typename Unit::base_unit_type>>,
1186 std::ratio_multiply<typename Unit::pi_exponent_ratio, std::ratio<3>>,
1187 typename Unit::translation_ratio> ;
1199 using cubed =
typename units::detail::cubed_impl<U>::type;
1208 using Zero = std::ratio<0>;
1209 using One = std::ratio<1>;
1210 template <
typename R>
using Square = std::ratio_multiply<R, R>;
1213 template <
template <std::
intmax_t N>
class Predicate,
typename enabled =
void>
1214 struct BinarySearch {
1215 template <std::
intmax_t N>
1216 struct SafeDouble_ {
1217 static constexpr const std::intmax_t value = 2 * N;
1218 static_assert(value > 0,
"Overflows when computing 2 * N");
1221 template <
intmax_t Lower,
intmax_t Upper,
typename Condition1 =
void,
typename Condition2 =
void>
1222 struct DoubleSidedSearch_ : DoubleSidedSearch_<Lower, Upper,
1223 std::integral_constant<bool, (Upper - Lower == 1)>,
1224 std::integral_constant<bool, ((Upper - Lower>1 && Predicate<Lower + (Upper - Lower) / 2>::value))>> {};
1226 template <
intmax_t Lower,
intmax_t Upper>
1227 struct DoubleSidedSearch_<Lower, Upper,
std::false_type, std::false_type> : DoubleSidedSearch_<Lower, Lower + (Upper - Lower) / 2> {};
1229 template <
intmax_t Lower,
intmax_t Upper,
typename Condition2>
1230 struct DoubleSidedSearch_<Lower, Upper,
std::true_type, Condition2> : std::integral_constant<intmax_t, Lower>{};
1232 template <
intmax_t Lower,
intmax_t Upper,
typename Condition1>
1233 struct DoubleSidedSearch_<Lower, Upper, Condition1,
std::true_type> : DoubleSidedSearch_<Lower + (Upper - Lower) / 2, Upper>{};
1235 template <std::
intmax_t Lower,
class enabled1 =
void>
1236 struct SingleSidedSearch_ : SingleSidedSearch_<Lower, std::integral_constant<bool, Predicate<SafeDouble_<Lower>::value>::value>>{};
1238 template <std::
intmax_t Lower>
1239 struct SingleSidedSearch_<Lower,
std::false_type> : DoubleSidedSearch_<Lower, SafeDouble_<Lower>::value> {};
1241 template <std::
intmax_t Lower>
1242 struct SingleSidedSearch_<Lower,
std::true_type> : SingleSidedSearch_<SafeDouble_<Lower>::value>{};
1244 static constexpr const std::intmax_t value = SingleSidedSearch_<1>::value;
1247 template <
template <std::
intmax_t N>
class Predicate>
1248 struct BinarySearch<Predicate,
std::
enable_if_t<!Predicate<1>::value>> : std::integral_constant<std::intmax_t, 0>{};
1251 template <
typename R>
1253 template <std::
intmax_t N>
using Predicate_ = std::ratio_less_equal<std::ratio<N>, std::ratio_divide<R, std::ratio<N>>>;
1254 static constexpr const std::intmax_t value = BinarySearch<Predicate_>::value;
1257 template <
typename R>
1258 struct IsPerfectSquare {
1259 static constexpr const std::intmax_t DenSqrt_ = Integer<std::ratio<R::den>>::value;
1260 static constexpr const std::intmax_t NumSqrt_ = Integer<std::ratio<R::num>>::value;
1261 static constexpr const bool value =( DenSqrt_ * DenSqrt_ == R::den && NumSqrt_ * NumSqrt_ == R::num);
1262 using Sqrt = std::ratio<NumSqrt_, DenSqrt_>;
1266 template <
typename Tp,
typename Tq>
1273 template <
typename R>
1275 using P_ =
typename R::P;
1276 using Q_ =
typename R::Q;
1277 using Den_ = std::ratio_subtract<P_, Square<Q_>>;
1278 using A_ = std::ratio_divide<Q_, Den_>;
1279 using B_ = std::ratio_divide<P_, Square<Den_>>;
1280 static constexpr const std::intmax_t I_ = (A_::num + Integer<std::ratio_multiply<B_, Square<std::ratio<A_::den>>>>::value) / A_::den;
1281 using I = std::ratio<I_>;
1282 using Rem = Remainder<B_, std::ratio_subtract<I, A_>>;
1289 template <
typename Tr, std::
intmax_t N>
1290 struct ContinuedFraction {
1291 template <
typename T>
1292 using Abs_ = std::conditional_t<std::ratio_less<T, Zero>::value, std::ratio_subtract<Zero, T>, T>;
1295 using Last_ = ContinuedFraction<R, N - 1>;
1296 using Reciprocal_ = Reciprocal<typename Last_::Rem>;
1297 using Rem =
typename Reciprocal_::Rem;
1298 using I_ =
typename Reciprocal_::I;
1299 using Den_ = std::ratio_add<typename Last_::W, I_>;
1300 using U = std::ratio_divide<typename Last_::V, Den_>;
1301 using V = std::ratio_divide<std::ratio_add<typename Last_::U, std::ratio_multiply<typename Last_::V, I_>>, Den_>;
1302 using W = std::ratio_divide<One, Den_>;
1303 using Error = Abs_<std::ratio_divide<std::ratio_subtract<U, std::ratio_multiply<V, W>>,
typename Reciprocal<Rem>::I>>;
1306 template <
typename Tr>
1307 struct ContinuedFraction<Tr, 1> {
1310 using V = std::ratio<Integer<R>::value>;
1312 using Rem = Remainder<R, V>;
1313 using Error = std::ratio_divide<One, typename Reciprocal<Rem>::I>;
1316 template <
typename R,
typename Eps, std::
intmax_t N = 1,
typename enabled =
void>
1317 struct Sqrt_ : Sqrt_<R, Eps, N + 1> {};
1319 template <
typename R,
typename Eps, std::
intmax_t N>
1320 struct Sqrt_<R, Eps, N,
std::
enable_if_t<std::ratio_less_equal<typename ContinuedFraction<R, N>::Error, Eps>::value>> {
1321 using type =
typename ContinuedFraction<R, N>::V;
1324 template <
typename R,
typename Eps,
typename enabled =
void>
1326 static_assert(std::ratio_greater_equal<R, Zero>::value,
"R can't be negative");
1329 template <
typename R,
typename Eps>
1330 struct Sqrt<R, Eps,
std::
enable_if_t<std::ratio_greater_equal<R, Zero>::value && IsPerfectSquare<R>::value>> {
1331 using type =
typename IsPerfectSquare<R>::Sqrt;
1334 template <
typename R,
typename Eps>
1335 struct Sqrt<R, Eps,
std::
enable_if_t<(std::ratio_greater_equal<R, Zero>::value && !IsPerfectSquare<R>::value)>> : Sqrt_<R, Eps>{};
1359 template<
typename Ratio, std::
intmax_t Eps = 10000000000>
1360 using ratio_sqrt =
typename units::detail::Sqrt<Ratio, std::ratio<1, Eps>>::type;
1370 template<
class Unit, std::
intmax_t Eps>
1374 using Conversion =
typename Unit::conversion_ratio;
1375 using type = unit <ratio_sqrt<Conversion, Eps>,
1376 sqrt_base<traits::base_unit_of<typename Unit::base_unit_type>>,
1377 std::ratio_divide<typename Unit::pi_exponent_ratio, std::ratio<2>>,
1378 typename Unit::translation_ratio>;
1404 template<
class U, std::
intmax_t Eps = 10000000000>
1419 template<
class U,
class... Us>
struct compound_impl;
1420 template<
class U>
struct compound_impl<U> {
using type = U; };
1421 template<
class U1,
class U2,
class...Us>
1422 struct compound_impl<U1, U2, Us...>
1423 : compound_impl<unit_multiply<U1, U2>, Us...> {};
1437 template<
class U,
class... Us>
1451 template<
class Ratio,
class Unit>
1460 template <
int N,
class U>
1461 struct power_of_ratio
1463 typedef std::ratio_multiply<U,
typename power_of_ratio<N - 1, U>::type> type;
1468 struct power_of_ratio<1, U>
1481 template<
class U>
using atto =
typename units::detail::prefix<std::atto, U>::type;
1482 template<
class U>
using femto =
typename units::detail::prefix<std::femto,U>::type;
1483 template<
class U>
using pico =
typename units::detail::prefix<std::pico, U>::type;
1484 template<
class U>
using nano =
typename units::detail::prefix<std::nano, U>::type;
1485 template<
class U>
using micro =
typename units::detail::prefix<std::micro,U>::type;
1486 template<
class U>
using milli =
typename units::detail::prefix<std::milli,U>::type;
1487 template<
class U>
using centi =
typename units::detail::prefix<std::centi,U>::type;
1488 template<
class U>
using deci =
typename units::detail::prefix<std::deci, U>::type;
1489 template<
class U>
using deca =
typename units::detail::prefix<std::deca, U>::type;
1490 template<
class U>
using hecto =
typename units::detail::prefix<std::hecto,U>::type;
1491 template<
class U>
using kilo =
typename units::detail::prefix<std::kilo, U>::type;
1492 template<
class U>
using mega =
typename units::detail::prefix<std::mega, U>::type;
1493 template<
class U>
using giga =
typename units::detail::prefix<std::giga, U>::type;
1494 template<
class U>
using tera =
typename units::detail::prefix<std::tera, U>::type;
1495 template<
class U>
using peta =
typename units::detail::prefix<std::peta, U>::type;
1496 template<
class U>
using exa =
typename units::detail::prefix<std::exa, U>::type;
1505 template<
class U>
using kibi =
typename units::detail::prefix<std::ratio<1024>, U>::type;
1506 template<
class U>
using mebi =
typename units::detail::prefix<std::ratio<1048576>, U>::type;
1507 template<
class U>
using gibi =
typename units::detail::prefix<std::ratio<1073741824>, U>::type;
1508 template<
class U>
using tebi =
typename units::detail::prefix<std::ratio<1099511627776>, U>::type;
1509 template<
class U>
using pebi =
typename units::detail::prefix<std::ratio<1125899906842624>, U>::type;
1510 template<
class U>
using exbi =
typename units::detail::prefix<std::ratio<1152921504606846976>, U>::type;
1531 template<
class U1,
class U2>
1532 struct is_convertible_unit : std::is_same <traits::base_unit_of<typename units::traits::unit_traits<U1>::base_unit_type>,
1533 base_unit_of<typename units::traits::unit_traits<U2>::base_unit_type >> {};
1534 template<
class U1,
class U2>
1547 return y == 0 ? 1.0 : x * pow(x, y - 1);
1552 return x < 0 ? -x : x;
1556 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1557 static constexpr T
convert(
const T& value, std::true_type, std::false_type, std::false_type)
noexcept
1563 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1564 static constexpr T
convert(
const T& value, std::true_type, std::false_type, std::true_type)
noexcept
1570 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1571 static constexpr T
convert(
const T& value, std::true_type, std::true_type, std::false_type)
noexcept
1577 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1578 static constexpr T
convert(
const T& value, std::true_type, std::true_type, std::true_type)
noexcept
1584 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1585 static constexpr T
convert(
const T& value, std::false_type, std::false_type, std::false_type)
noexcept
1587 return ((value * Ratio::num) / Ratio::den);
1592 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1594 std::enable_if_t<(PiRatio::num / PiRatio::den >= 1 && PiRatio::num % PiRatio::den == 0), T>
1595 convert(
const T& value, std::false_type, std::true_type, std::false_type)
noexcept
1597 return ((value *
pow(constants::detail::PI_VAL, PiRatio::num / PiRatio::den) * Ratio::num) / Ratio::den);
1602 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1604 std::enable_if_t<(PiRatio::num / PiRatio::den <= -1 && PiRatio::num % PiRatio::den == 0), T>
1605 convert(
const T& value, std::false_type, std::true_type, std::false_type)
noexcept
1607 return (value * Ratio::num) / (Ratio::den *
pow(constants::detail::PI_VAL, -PiRatio::num / PiRatio::den));
1612 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1614 std::enable_if_t<(PiRatio::num / PiRatio::den < 1 && PiRatio::num / PiRatio::den > -1), T>
1615 convert(
const T& value, std::false_type, std::true_type, std::false_type)
noexcept
1617 return ((value * std::pow(constants::detail::PI_VAL, PiRatio::num / PiRatio::den) * Ratio::num) / Ratio::den);
1621 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1622 static constexpr T
convert(
const T& value, std::false_type, std::false_type, std::true_type)
noexcept
1624 return ((value * Ratio::num) / Ratio::den) + (
static_cast<UNIT_LIB_DEFAULT_TYPE>(Translation::num) / Translation::den);
1628 template<
class UnitFrom,
class UnitTo,
class Ratio,
class PiRatio,
class Translation,
typename T>
1629 static constexpr T
convert(
const T& value,
const std::false_type,
const std::true_type,
const std::true_type)
noexcept
1631 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);
1651 template<
class UnitFrom,
class UnitTo,
typename T = UNIT_LIB_DEFAULT_TYPE>
1652 static constexpr T
convert(
const T& value)
noexcept
1658 using Ratio = std::ratio_divide<typename UnitFrom::conversion_ratio, typename UnitTo::conversion_ratio>;
1659 using PiRatio = std::ratio_subtract<typename UnitFrom::pi_exponent_ratio, typename UnitTo::pi_exponent_ratio>;
1660 using Translation = std::ratio_divide<std::ratio_subtract<typename UnitFrom::translation_ratio, typename UnitTo::translation_ratio>,
typename UnitTo::conversion_ratio>;
1662 using isSame =
typename std::is_same<std::decay_t<UnitFrom>, std::decay_t<UnitTo>>::type;
1663 using piRequired = std::integral_constant<bool, !(std::is_same<std::ratio<0>, PiRatio>::value)>;
1664 using translationRequired = std::integral_constant<bool, !(std::is_same<std::ratio<0>, Translation>::value)>;
1666 return units::detail::convert<UnitFrom, UnitTo, Ratio, PiRatio, Translation, T>
1667 (value, isSame{}, piRequired{}, translationRequired{});
1683 template<
class T,
class Ret>
1684 struct has_operator_parenthesis_impl
1687 static constexpr auto test(U*) ->
decltype(std::declval<U>()()) {
return decltype(std::declval<U>()()){}; }
1689 static constexpr std::false_type test(...) {
return std::false_type{}; }
1691 using type =
typename std::is_same<Ret, decltype(test<T>(0))>::type;
1699 template<
class T,
class Ret>
1700 struct has_operator_parenthesis : traits::detail::has_operator_parenthesis_impl<T, Ret>::type {};
1711 template<
class T,
class Ret>
1712 struct has_value_member_impl
1715 static constexpr auto test(U* p) ->
decltype(p->m_value) {
return p->m_value; }
1717 static constexpr auto test(...)->std::false_type {
return std::false_type{}; }
1719 using type =
typename std::is_same<std::decay_t<Ret>, std::decay_t<decltype(test<T>(0))>>::type;
1727 template<
class T,
class Ret>
1728 struct has_value_member : traits::detail::has_value_member_impl<T, Ret>::type {};
1729 template<
class T,
class Ret>
1730 constexpr bool has_value_member_v = has_value_member<T, Ret>::value;
1747 template<
class T,
class Ret>
1749 std::is_default_constructible<T>::value &&
1750 has_operator_parenthesis<T, Ret>::value &&
1751 has_value_member<T, Ret>::value &&
1752 std::is_trivial<T>::value>
1762#ifdef FOR_DOXYGEN_PURPOSOES_ONLY
1769 template<
typename T>
1770 struct unit_t_traits
1772 typedef typename T::non_linear_scale_type non_linear_scale_type;
1773 typedef typename T::underlying_type underlying_type;
1774 typedef typename T::value_type value_type;
1775 typedef typename T::unit_type unit_type;
1784 template<
typename T,
typename =
void>
1785 struct unit_t_traits
1787 typedef void non_linear_scale_type;
1788 typedef void underlying_type;
1789 typedef void value_type;
1790 typedef void unit_type;
1798 template<
typename T>
1799 struct unit_t_traits <T, typename
void_t<
1800 typename T::non_linear_scale_type,
1801 typename T::underlying_type,
1802 typename T::value_type,
1803 typename T::unit_type>::type>
1805 typedef typename T::non_linear_scale_type non_linear_scale_type;
1806 typedef typename T::underlying_type underlying_type;
1807 typedef typename T::value_type value_type;
1808 typedef typename T::unit_type unit_type;
1827 template<
class U1,
class U2>
1829 is_convertible_unit<typename units::traits::unit_t_traits<U1>::unit_type, typename units::traits::unit_t_traits<U2>::unit_type>::value>
1855 #if !defined(_MSC_VER) || _MSC_VER > 1800
1868 struct is_unit_t : std::is_base_of<units::detail::_unit_t, T>::type {};
1928 template<
class Units,
typename T = UNIT_LIB_DEFAULT_TYPE,
template<
typename>
class NonLinearScale =
linear_scale>
1929 class unit_t :
public NonLinearScale<T>, units::detail::_unit_t
1931 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).");
1936 using nls = NonLinearScale<T>;
1960 template<
class... Args>
1971 template<class Ty, class = typename std::enable_if<traits::is_dimensionless_unit<Units>::value && std::is_arithmetic<Ty>::value>::type>
1983 constexpr unit_t(
const std::chrono::duration<Rep, Period>&
value) noexcept :
1994 template<
class UnitsRhs,
typename Ty,
template<
typename>
class NlsRhs>
2006 template<
class UnitsRhs,
typename Ty,
template<
typename>
class NlsRhs>
2018 template<class Ty, class = std::enable_if_t<traits::is_dimensionless_unit<Units>::value && std::is_arithmetic<Ty>::value>>
2031 template<
class UnitsRhs,
typename Ty,
template<
typename>
class NlsRhs>
2043 template<
class UnitsRhs,
typename Ty,
template<
typename>
class NlsRhs>
2055 template<
class UnitsRhs,
typename Ty,
template<
typename>
class NlsRhs>
2067 template<
class UnitsRhs,
typename Ty,
template<
typename>
class NlsRhs>
2080 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>
2088 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>
2101 template<
class UnitsRhs,
typename Ty,
template<
typename>
class NlsRhs>
2104 return !(*
this == rhs);
2120 template<typename Ty, class = std::enable_if_t<std::is_arithmetic<Ty>::value>>
2121 constexpr Ty
to() const noexcept
2123 return static_cast<Ty
>(*this);
2131 template<typename Ty, class = std::enable_if_t<std::is_arithmetic<Ty>::value>>
2134 return static_cast<Ty
>(
m_value);
2157 template<class Ty, std::enable_if_t<traits::is_dimensionless_unit<Units>::value && std::is_arithmetic<Ty>::value,
int> = 0>
2158 constexpr operator Ty() const noexcept
2168 template<class Ty, std::enable_if_t<!traits::is_dimensionless_unit<Units>::value && std::is_arithmetic<Ty>::value,
int> = 0>
2169 constexpr explicit operator Ty() const noexcept
2171 return static_cast<Ty
>((*this)());
2178 template<
typename U = Units, std::enable_if_t<units::traits::is_convertible_unit<U, unit<std::ratio<1>, category::time_unit>>::value,
int> = 0>
2179 constexpr operator std::chrono::nanoseconds() const noexcept
2181 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)())));
2187 constexpr const char*
name() const noexcept
2202 template<
class U,
typename Ty,
template<
typename>
class Nlt>
2220 template<class UnitType, typename T, class = std::enable_if_t<std::is_arithmetic<T>::value>>
2225 return UnitType(value);
2228#if defined(UNIT_LIB_ENABLE_IOSTREAM)
2229 template<
class Units,
typename T,
template<
typename>
class NonLinearScale>
2230 inline std::ostream& operator<<(std::ostream& os,
const unit_t<Units, T, NonLinearScale>& obj)
noexcept
2232 using BaseUnits = unit<std::ratio<1>,
typename traits::unit_traits<Units>::base_unit_type>;
2233 os << convert<Units, BaseUnits>(obj());
2235 if (traits::unit_traits<Units>::base_unit_type::meter_ratio::num != 0) { os <<
" m"; }
2236 if (traits::unit_traits<Units>::base_unit_type::meter_ratio::num != 0 &&
2237 traits::unit_traits<Units>::base_unit_type::meter_ratio::num != 1) { os <<
"^" << traits::unit_traits<Units>::base_unit_type::meter_ratio::num; }
2238 if (traits::unit_traits<Units>::base_unit_type::meter_ratio::den != 1) { os <<
"/" << traits::unit_traits<Units>::base_unit_type::meter_ratio::den; }
2240 if (traits::unit_traits<Units>::base_unit_type::kilogram_ratio::num != 0) { os <<
" kg"; }
2241 if (traits::unit_traits<Units>::base_unit_type::kilogram_ratio::num != 0 &&
2242 traits::unit_traits<Units>::base_unit_type::kilogram_ratio::num != 1) { os <<
"^" << traits::unit_traits<Units>::base_unit_type::kilogram_ratio::num; }
2243 if (traits::unit_traits<Units>::base_unit_type::kilogram_ratio::den != 1) { os <<
"/" << traits::unit_traits<Units>::base_unit_type::kilogram_ratio::den; }
2245 if (traits::unit_traits<Units>::base_unit_type::second_ratio::num != 0) { os <<
" s"; }
2246 if (traits::unit_traits<Units>::base_unit_type::second_ratio::num != 0 &&
2247 traits::unit_traits<Units>::base_unit_type::second_ratio::num != 1) { os <<
"^" << traits::unit_traits<Units>::base_unit_type::second_ratio::num; }
2248 if (traits::unit_traits<Units>::base_unit_type::second_ratio::den != 1) { os <<
"/" << traits::unit_traits<Units>::base_unit_type::second_ratio::den; }
2250 if (traits::unit_traits<Units>::base_unit_type::ampere_ratio::num != 0) { os <<
" A"; }
2251 if (traits::unit_traits<Units>::base_unit_type::ampere_ratio::num != 0 &&
2252 traits::unit_traits<Units>::base_unit_type::ampere_ratio::num != 1) { os <<
"^" << traits::unit_traits<Units>::base_unit_type::ampere_ratio::num; }
2253 if (traits::unit_traits<Units>::base_unit_type::ampere_ratio::den != 1) { os <<
"/" << traits::unit_traits<Units>::base_unit_type::ampere_ratio::den; }
2255 if (traits::unit_traits<Units>::base_unit_type::kelvin_ratio::num != 0) { os <<
" K"; }
2256 if (traits::unit_traits<Units>::base_unit_type::kelvin_ratio::num != 0 &&
2257 traits::unit_traits<Units>::base_unit_type::kelvin_ratio::num != 1) { os <<
"^" << traits::unit_traits<Units>::base_unit_type::kelvin_ratio::num; }
2258 if (traits::unit_traits<Units>::base_unit_type::kelvin_ratio::den != 1) { os <<
"/" << traits::unit_traits<Units>::base_unit_type::kelvin_ratio::den; }
2260 if (traits::unit_traits<Units>::base_unit_type::mole_ratio::num != 0) { os <<
" mol"; }
2261 if (traits::unit_traits<Units>::base_unit_type::mole_ratio::num != 0 &&
2262 traits::unit_traits<Units>::base_unit_type::mole_ratio::num != 1) { os <<
"^" << traits::unit_traits<Units>::base_unit_type::mole_ratio::num; }
2263 if (traits::unit_traits<Units>::base_unit_type::mole_ratio::den != 1) { os <<
"/" << traits::unit_traits<Units>::base_unit_type::mole_ratio::den; }
2265 if (traits::unit_traits<Units>::base_unit_type::candela_ratio::num != 0) { os <<
" cd"; }
2266 if (traits::unit_traits<Units>::base_unit_type::candela_ratio::num != 0 &&
2267 traits::unit_traits<Units>::base_unit_type::candela_ratio::num != 1) { os <<
"^" << traits::unit_traits<Units>::base_unit_type::candela_ratio::num; }
2268 if (traits::unit_traits<Units>::base_unit_type::candela_ratio::den != 1) { os <<
"/" << traits::unit_traits<Units>::base_unit_type::candela_ratio::den; }
2270 if (traits::unit_traits<Units>::base_unit_type::radian_ratio::num != 0) { os <<
" rad"; }
2271 if (traits::unit_traits<Units>::base_unit_type::radian_ratio::num != 0 &&
2272 traits::unit_traits<Units>::base_unit_type::radian_ratio::num != 1) { os <<
"^" << traits::unit_traits<Units>::base_unit_type::radian_ratio::num; }
2273 if (traits::unit_traits<Units>::base_unit_type::radian_ratio::den != 1) { os <<
"/" << traits::unit_traits<Units>::base_unit_type::radian_ratio::den; }
2275 if (traits::unit_traits<Units>::base_unit_type::byte_ratio::num != 0) { os <<
" b"; }
2276 if (traits::unit_traits<Units>::base_unit_type::byte_ratio::num != 0 &&
2277 traits::unit_traits<Units>::base_unit_type::byte_ratio::num != 1) { os <<
"^" << traits::unit_traits<Units>::base_unit_type::byte_ratio::num; }
2278 if (traits::unit_traits<Units>::base_unit_type::byte_ratio::den != 1) { os <<
"/" << traits::unit_traits<Units>::base_unit_type::byte_ratio::den; }
2284 template<
class Units,
typename T,
template<
typename>
class NonLinearScale,
typename RhsType>
2289 "parameters are not compatible units.");
2295 template<
class Units,
typename T,
template<
typename>
class NonLinearScale,
typename RhsType>
2300 "parameters are not compatible units.");
2306 template<
class Units,
typename T,
template<
typename>
class NonLinearScale,
typename RhsType>
2310 "right-hand side parameter must be dimensionless.");
2316 template<
class Units,
typename T,
template<
typename>
class NonLinearScale,
typename RhsType>
2320 "right-hand side parameter must be dimensionless.");
2331 template<
class Units,
typename T,
template<
typename>
class NonLinearScale>
2338 template<
class Units,
typename T,
template<
typename>
class NonLinearScale>
2346 template<
class Units,
typename T,
template<
typename>
class NonLinearScale>
2355 template<
class Units,
typename T,
template<
typename>
class NonLinearScale>
2362 template<
class Units,
typename T,
template<
typename>
class NonLinearScale>
2370 template<
class Units,
typename T,
template<
typename>
class NonLinearScale>
2395 template<typename T, typename Units, class = std::enable_if_t<std::is_arithmetic<T>::value && traits::is_unit_t<Units>::value>>
2398 return static_cast<T
>(value);
2406 template<
typename T>
struct decibel_scale;
2417#if !defined(_MSC_VER) || _MSC_VER > 1800
2418 template<
typename... T>
2419 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 > {};
2420 template<
typename... T>
2423 template<
typename T1,
typename T2 = T1,
typename T3 = T1>
2425 std::is_base_of<units::linear_scale<typename units::traits::unit_t_traits<T1>::underlying_type>, T1>::value &&
2426 std::is_base_of<units::linear_scale<typename units::traits::unit_t_traits<T2>::underlying_type>, T2>::value &&
2427 std::is_base_of<units::linear_scale<typename units::traits::unit_t_traits<T3>::underlying_type>, T3>::value> {};
2428 template<
typename T1,
typename T2 = T1,
typename T3 = T1>
2439#if !defined(_MSC_VER) || _MSC_VER > 1800
2440 template<
typename... T>
2441 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> {};
2442 template<
typename... T>
2445 template<
typename T1,
typename T2 = T1,
typename T3 = T1>
2447 std::is_base_of<units::decibel_scale<typename units::traits::unit_t_traits<T1>::underlying_type>, T1>::value &&
2448 std::is_base_of<units::decibel_scale<typename units::traits::unit_t_traits<T2>::underlying_type>, T2>::value &&
2449 std::is_base_of<units::decibel_scale<typename units::traits::unit_t_traits<T2>::underlying_type>, T3>::value> {};
2450 template<
typename T1,
typename T2 = T1,
typename T3 = T1>
2462 template<
typename T1,
typename T2>
2464 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>
2466 template<
typename T1,
typename T2>
2489 template<
typename T>
2496#if defined(_MSC_VER) && (_MSC_VER > 1800)
2500 template<
class... Args>
2522#if defined(_MSC_VER)
2523# pragma warning(push)
2524# pragma warning(disable : 4348)
2528#if defined(_MSC_VER)
2529# pragma warning(pop)
2536 template<class UnitTypeLhs, class UnitTypeRhs, std::enable_if_t<!traits::is_same_scale<UnitTypeLhs, UnitTypeRhs>::value,
int> = 0>
2537 constexpr inline int operator+(
const UnitTypeLhs& ,
const UnitTypeRhs& )
noexcept
2544 template<class UnitTypeLhs, class UnitTypeRhs, std::enable_if_t<traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value,
int> = 0>
2545 constexpr UnitTypeLhs
operator+(
const UnitTypeLhs& lhs,
const UnitTypeRhs& rhs)
noexcept
2547 using UnitsLhs =
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
2548 using UnitsRhs =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2553 template<typename T, std::enable_if_t<std::is_arithmetic<T>::value,
int> = 0>
2560 template<typename T, std::enable_if_t<std::is_arithmetic<T>::value,
int> = 0>
2567 template<class UnitTypeLhs, class UnitTypeRhs, std::enable_if_t<traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value,
int> = 0>
2568 constexpr UnitTypeLhs
operator-(
const UnitTypeLhs& lhs,
const UnitTypeRhs& rhs)
noexcept
2570 using UnitsLhs =
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
2571 using UnitsRhs =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2576 template<typename T, std::enable_if_t<std::is_arithmetic<T>::value,
int> = 0>
2583 template<typename T, std::enable_if_t<std::is_arithmetic<T>::value,
int> = 0>
2590 template<
class UnitTypeLhs,
class UnitTypeRhs,
2591 std::enable_if_t<traits::is_convertible_unit_t<UnitTypeLhs, UnitTypeRhs>::value && traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value,
int> = 0>
2594 using UnitsLhs =
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
2595 using UnitsRhs =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2601 template<
class UnitTypeLhs,
class UnitTypeRhs,
2602 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>
2603 constexpr auto operator*(
const UnitTypeLhs& lhs,
const UnitTypeRhs& rhs)
noexcept -> unit_t<compound_unit<typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type,
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type>>
2605 using UnitsLhs =
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
2606 using UnitsRhs =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2607 return unit_t<compound_unit<UnitsLhs, UnitsRhs>>
2612 template<
class UnitTypeLhs,
typename UnitTypeRhs,
2613 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>
2614 constexpr UnitTypeLhs
operator*(
const UnitTypeLhs& lhs,
const UnitTypeRhs& rhs)
noexcept
2621 template<
class UnitTypeLhs,
typename UnitTypeRhs,
2622 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>
2623 constexpr UnitTypeRhs
operator*(
const UnitTypeLhs& lhs,
const UnitTypeRhs& rhs)
noexcept
2630 template<
class UnitTypeLhs,
typename T,
2631 std::enable_if_t<std::is_arithmetic<T>::value && traits::has_linear_scale<UnitTypeLhs>::value,
int> = 0>
2632 constexpr UnitTypeLhs
operator*(
const UnitTypeLhs& lhs, T rhs)
noexcept
2634 return UnitTypeLhs(lhs() * rhs);
2638 template<
class UnitTypeRhs,
typename T,
2639 std::enable_if_t<std::is_arithmetic<T>::value && traits::has_linear_scale<UnitTypeRhs>::value,
int> = 0>
2640 constexpr UnitTypeRhs
operator*(T lhs,
const UnitTypeRhs& rhs)
noexcept
2642 return UnitTypeRhs(lhs * rhs());
2646 template<
class UnitTypeLhs,
class UnitTypeRhs,
2647 std::enable_if_t<traits::is_convertible_unit_t<UnitTypeLhs, UnitTypeRhs>::value && traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value,
int> = 0>
2650 using UnitsLhs =
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
2651 using UnitsRhs =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2656 template<
class UnitTypeLhs,
class UnitTypeRhs,
2657 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>
2660 using UnitsLhs =
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
2661 using UnitsRhs =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2667 template<
class UnitTypeLhs,
class UnitTypeRhs,
2668 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>
2669 constexpr UnitTypeLhs
operator/(
const UnitTypeLhs& lhs,
const UnitTypeRhs& rhs)
noexcept
2675 template<
class UnitTypeLhs,
class UnitTypeRhs,
2676 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>
2677 constexpr auto operator/(
const UnitTypeLhs& lhs,
const UnitTypeRhs& rhs)
noexcept -> unit_t<inverse<typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type>>
2679 return unit_t<inverse<typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type>>
2684 template<
class UnitTypeLhs,
typename T,
2685 std::enable_if_t<std::is_arithmetic<T>::value && traits::has_linear_scale<UnitTypeLhs>::value,
int> = 0>
2686 constexpr UnitTypeLhs
operator/(
const UnitTypeLhs& lhs, T rhs)
noexcept
2688 return UnitTypeLhs(lhs() / rhs);
2692 template<
class UnitTypeRhs,
typename T,
2693 std::enable_if_t<std::is_arithmetic<T>::value && traits::has_linear_scale<UnitTypeRhs>::value,
int> = 0>
2696 using UnitsRhs =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2705 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2709 detail::abs(lhs -
static_cast<UNIT_LIB_DEFAULT_TYPE>(rhs)) < (std::numeric_limits<UNIT_LIB_DEFAULT_TYPE>::min)();
2712 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2716 detail::abs(
static_cast<UNIT_LIB_DEFAULT_TYPE>(lhs) - rhs) < (std::numeric_limits<UNIT_LIB_DEFAULT_TYPE>::min)();
2719 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2725 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2731 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2737 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2743 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2749 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2755 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2761 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2767 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2770 return lhs < static_cast<UNIT_LIB_DEFAULT_TYPE>(rhs);
2773 template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
2787 template <
int N,
class U>
struct power_of_unit
2789 typedef typename units::detail::unit_multiply<U,
typename power_of_unit<N - 1, U>::type> type;
2793 template <
class U>
struct power_of_unit<1, U>
2809 template<int power, class UnitType, class = typename std::enable_if<traits::has_linear_scale<UnitType>::value,
int>>
2824 template<int power, class UnitType, class = typename std::enable_if<traits::has_linear_scale<UnitType>::value,
int>>
2827 static_assert(power >= 0,
"cpow cannot accept negative numbers. Try units::math::pow instead.");
2829 (detail::pow(value(), power));
2843 template<
typename T>
2850#if defined(_MSC_VER) && (_MSC_VER > 1800)
2855 template<
class... Args>
2870 namespace dimensionless
2875#if defined(UNIT_LIB_ENABLE_IOSTREAM)
2876 namespace dimensionless
2878 inline std::ostream& operator<<(std::ostream& os,
const dB_t& obj) { os << obj() <<
" dB";
return os; }
2882#if __has_include(<fmt/format.h>) && !defined(UNIT_LIB_DISABLE_FMT)
2884struct fmt::formatter<
units::dimensionless::dB_t> : fmt::formatter<double>
2886 template <
typename FmtContext>
2889 FmtContext& ctx)
const
2891 auto out = ctx.out();
2892 out = fmt::formatter<double>::format(obj(), ctx);
2893 return fmt::format_to(out,
" dB");
2904 template<
class UnitTypeLhs,
class UnitTypeRhs,
2905 std::enable_if_t<traits::has_decibel_scale<UnitTypeLhs, UnitTypeRhs>::value,
int> = 0>
2908 using LhsUnits =
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
2909 using RhsUnits =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2910 using underlying_type =
typename units::traits::unit_t_traits<UnitTypeLhs>::underlying_type;
2913 (lhs.template toLinearized<underlying_type>() *
convert<RhsUnits, LhsUnits>(rhs.template toLinearized<underlying_type>()), std::true_type());
2917 template<class UnitTypeLhs, std::enable_if_t<traits::has_decibel_scale<UnitTypeLhs>::value && !traits::is_dimensionless_unit<UnitTypeLhs>::value,
int> = 0>
2920 using underlying_type =
typename units::traits::unit_t_traits<UnitTypeLhs>::underlying_type;
2921 return UnitTypeLhs(lhs.template toLinearized<underlying_type>() * rhs.template toLinearized<underlying_type>(), std::true_type());
2925 template<class UnitTypeRhs, std::enable_if_t<traits::has_decibel_scale<UnitTypeRhs>::value && !traits::is_dimensionless_unit<UnitTypeRhs>::value,
int> = 0>
2928 using underlying_type =
typename units::traits::unit_t_traits<UnitTypeRhs>::underlying_type;
2929 return UnitTypeRhs(lhs.template toLinearized<underlying_type>() * rhs.template toLinearized<underlying_type>(), std::true_type());
2933 template<class UnitTypeLhs, class UnitTypeRhs, std::enable_if_t<traits::has_decibel_scale<UnitTypeLhs, UnitTypeRhs>::value,
int> = 0>
2936 using LhsUnits =
typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
2937 using RhsUnits =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2938 using underlying_type =
typename units::traits::unit_t_traits<UnitTypeLhs>::underlying_type;
2941 (lhs.template toLinearized<underlying_type>() /
convert<RhsUnits, LhsUnits>(rhs.template toLinearized<underlying_type>()), std::true_type());
2945 template<class UnitTypeLhs, std::enable_if_t<traits::has_decibel_scale<UnitTypeLhs>::value && !traits::is_dimensionless_unit<UnitTypeLhs>::value,
int> = 0>
2948 using underlying_type =
typename units::traits::unit_t_traits<UnitTypeLhs>::underlying_type;
2949 return UnitTypeLhs(lhs.template toLinearized<underlying_type>() / rhs.template toLinearized<underlying_type>(), std::true_type());
2953 template<class UnitTypeRhs, std::enable_if_t<traits::has_decibel_scale<UnitTypeRhs>::value && !traits::is_dimensionless_unit<UnitTypeRhs>::value,
int> = 0>
2956 using RhsUnits =
typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
2957 using underlying_type =
typename units::traits::unit_t_traits<RhsUnits>::underlying_type;
2960 (lhs.template toLinearized<underlying_type>() / rhs.template toLinearized<underlying_type>(), std::true_type());
2970 template<
class Units>
2971 struct _unit_value_t {};
2977#ifdef FOR_DOXYGEN_PURPOSES_ONLY
2985 template<
typename T>
2986 struct unit_value_t_traits
2988 typedef typename T::unit_type unit_type;
2989 typedef typename T::ratio ratio;
2998 template<
typename T,
typename =
void>
2999 struct unit_value_t_traits
3001 typedef void unit_type;
3010 template<
typename T>
3011 struct unit_value_t_traits <T, typename
void_t<
3012 typename T::unit_type,
3013 typename T::ratio>::type>
3015 typedef typename T::unit_type unit_type;
3016 typedef typename T::ratio ratio;
3038 template<
typename Units, std::u
intmax_t Num, std::u
intmax_t Denom = 1>
3058 template<typename T, typename Units = typename traits::unit_value_t_traits<T>::unit_type>
3060 std::is_base_of<units::detail::_unit_value_t<Units>, T>::value>
3062 template<typename T, typename Units = typename traits::unit_value_t_traits<T>::unit_type>
3070 template<
typename Category,
typename T>
3072 std::is_same<units::traits::base_unit_of<typename traits::unit_value_t_traits<T>::unit_type>, Category>::value>
3076 template<
typename Category,
typename T>
3084 template<
class U1,
class U2>
3085 struct unit_value_arithmetic
3090 using _UNIT1 =
typename traits::unit_value_t_traits<U1>::unit_type;
3091 using _UNIT2 =
typename traits::unit_value_t_traits<U2>::unit_type;
3092 using _CONV1 =
typename units::traits::unit_traits<_UNIT1>::conversion_ratio;
3093 using _CONV2 =
typename units::traits::unit_traits<_UNIT2>::conversion_ratio;
3094 using _RATIO1 =
typename traits::unit_value_t_traits<U1>::ratio;
3095 using _RATIO2 =
typename traits::unit_value_t_traits<U2>::ratio;
3096 using _RATIO2CONV =
typename std::ratio_divide<std::ratio_multiply<_RATIO2, _CONV2>, _CONV1>;
3097 using _PI_EXP = std::ratio_subtract<typename units::traits::unit_traits<_UNIT2>::pi_exponent_ratio,
typename units::traits::unit_traits<_UNIT1>::pi_exponent_ratio>;
3112 template<
class U1,
class U2>
3113 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>
3116 using Base = units::detail::unit_value_arithmetic<U1, U2>;
3117 typedef typename Base::_UNIT1 unit_type;
3118 using ratio = std::ratio_add<typename Base::_RATIO1, typename Base::_RATIO2CONV>;
3131 using UsePi = std::integral_constant<bool, Base::_PI_EXP::num != 0>;
3132 return value(UsePi());
3143 static constexpr const unit_t<unit_type>
value(std::true_type)
noexcept
3161 template<
class U1,
class U2>
3162 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>
3165 using Base = units::detail::unit_value_arithmetic<U1, U2>;
3167 typedef typename Base::_UNIT1 unit_type;
3168 using ratio = std::ratio_subtract<typename Base::_RATIO1, typename Base::_RATIO2CONV>;
3181 using UsePi = std::integral_constant<bool, Base::_PI_EXP::num != 0>;
3182 return value(UsePi());
3193 static constexpr const unit_t<unit_type>
value(std::true_type)
noexcept
3196 * std::pow(units::constants::detail::PI_VAL, ((
UNIT_LIB_DEFAULT_TYPE)Base::_PI_EXP::num / Base::_PI_EXP::den)));
3211 template<
class U1,
class U2>
3213 units::detail::_unit_value_t<typename std::conditional<traits::is_convertible_unit<typename traits::unit_value_t_traits<U1>::unit_type,
3214 typename traits::unit_value_t_traits<U2>::unit_type>::value, compound_unit<squared<typename traits::unit_value_t_traits<U1>::unit_type>>,
3215 compound_unit<typename traits::unit_value_t_traits<U1>::unit_type, typename traits::unit_value_t_traits<U2>::unit_type>>::type>
3218 using Base = units::detail::unit_value_arithmetic<U1, U2>;
3221 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>>;
3232 using UsePi = std::integral_constant<bool, Base::_PI_EXP::num != 0>;
3233 return value(UsePi());
3244 static constexpr const unit_t<unit_type>
value(std::true_type)
noexcept
3261 template<
class U1,
class U2>
3263 units::detail::_unit_value_t<typename std::conditional<traits::is_convertible_unit<typename traits::unit_value_t_traits<U1>::unit_type,
3264 typename traits::unit_value_t_traits<U2>::unit_type>::value, dimensionless::scalar, compound_unit<typename traits::unit_value_t_traits<U1>::unit_type,
3265 inverse<typename traits::unit_value_t_traits<U2>::unit_type>>>::type>
3268 using Base = units::detail::unit_value_arithmetic<U1, U2>;
3271 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>>;
3282 using UsePi = std::integral_constant<bool, Base::_PI_EXP::num != 0>;
3283 return value(UsePi());
3294 static constexpr const unit_t<unit_type>
value(std::true_type)
noexcept
3310 template<
class U1,
int power>
3311 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>
3314 using Base = units::detail::unit_value_arithmetic<U1, U1>;
3316 using unit_type =
typename units::detail::power_of_unit<power, typename Base::_UNIT1>::type;
3317 using ratio =
typename units::detail::power_of_ratio<power, typename Base::_RATIO1>::type;
3318 using pi_exponent = std::ratio_multiply<std::ratio<power>,
typename Base::_UNIT1::pi_exponent_ratio>;
3329 using UsePi = std::integral_constant<bool, Base::_PI_EXP::num != 0>;
3330 return value(UsePi());
3341 static constexpr const unit_t<unit_type>
value(std::true_type)
noexcept
3357 template<
class U1, std::
intmax_t Eps = 10000000000>
3358 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>>
3361 using Base = units::detail::unit_value_arithmetic<U1, U1>;
3376 using UsePi = std::integral_constant<bool, Base::_PI_EXP::num != 0>;
3377 return value(UsePi());
3388 static constexpr const unit_t<unit_type>
value(std::true_type)
noexcept
3413 template<
class UnitTypeLhs,
class UnitTypeRhs>
3414 constexpr UnitTypeLhs (
min)(
const UnitTypeLhs& lhs,
const UnitTypeRhs& rhs)
3418 return (lhs < r ? lhs : r);
3421 template<
class UnitTypeLhs,
class UnitTypeRhs>
3422 constexpr UnitTypeLhs (
max)(
const UnitTypeLhs& lhs,
const UnitTypeRhs& rhs)
3426 return (lhs > r ? lhs : r);
3432# if _MSC_VER <= 1800
3433# pragma warning(pop)
3435# pragma pop_macro("constexpr")
3437# pragma pop_macro("noexcept")
3438# undef _ALLOW_KEYWORD_MACROS
3440# pragma pop_macro("pascal")
3443#if defined(UNIT_HAS_LITERAL_SUPPORT)
3448#if __has_include(<fmt/format.h>) && !defined(UNIT_LIB_DISABLE_FMT)
Container for values which represent quantities of a given unit.
Definition base.h:1930
constexpr bool operator<(const unit_t< UnitsRhs, Ty, NlsRhs > &rhs) const noexcept
less-than
Definition base.h:2032
constexpr bool operator<=(const unit_t< UnitsRhs, Ty, NlsRhs > &rhs) const noexcept
less-than or equal
Definition base.h:2044
constexpr unit_t< U > convert() const noexcept
conversion
Definition base.h:2147
unit_t & operator=(const Ty &rhs) noexcept
assignment
Definition base.h:2019
T value_type
Synonym for underlying type. May be removed in future versions. Prefer underlying_type.
Definition base.h:1943
constexpr unit_t(const std::chrono::duration< Rep, Period > &value) noexcept
chrono constructor
Definition base.h:1983
Units unit_type
Type of unit the unit_t represents (e.g. meters)
Definition base.h:1944
constexpr underlying_type value() const noexcept
unit value
Definition base.h:2111
constexpr unit_t(const Ty value) noexcept
constructor
Definition base.h:1972
constexpr unit_t(const unit_t< UnitsRhs, Ty, NlsRhs > &rhs) noexcept
copy constructor (converting)
Definition base.h:1995
T underlying_type
Type of the underlying storage of the unit_t (e.g. double)
Definition base.h:1942
constexpr const char * name() const noexcept
returns the unit name
Definition base.h:2187
constexpr Ty toLinearized() const noexcept
linearized unit value
Definition base.h:2132
constexpr Ty to() const noexcept
unit value
Definition base.h:2121
constexpr bool operator!=(const unit_t< UnitsRhs, Ty, NlsRhs > &rhs) const noexcept
inequality
Definition base.h:2102
friend class unit_t
Definition base.h:2203
constexpr bool operator>(const unit_t< UnitsRhs, Ty, NlsRhs > &rhs) const noexcept
greater-than
Definition base.h:2056
constexpr bool operator==(const unit_t< UnitsRhs, Ty, NlsRhs > &rhs) const noexcept
equality
Definition base.h:2081
constexpr unit_t(const T value, const Args &... args) noexcept
constructor
Definition base.h:1961
constexpr const char * abbreviation() const noexcept
returns the unit abbreviation
Definition base.h:2195
NonLinearScale< T > nls
Definition base.h:1936
constexpr bool operator>=(const unit_t< UnitsRhs, Ty, NlsRhs > &rhs) const noexcept
greater-than or equal
Definition base.h:2068
constexpr unit_t()=default
default constructor.
unit_t & operator=(const unit_t< UnitsRhs, Ty, NlsRhs > &rhs) noexcept
assignment
Definition base.h:2007
NonLinearScale< T > non_linear_scale_type
Type of the non-linear scale of the unit_t (e.g. linear_scale)
Definition base.h:1941
constexpr T unit_cast(const Units &value) noexcept
Casts a unit container to an arithmetic type.
Definition base.h:2396
static constexpr T convert(const T &value) noexcept
converts a value from one type to another.
Definition base.h:1652
typename units::detail::Sqrt< Ratio, std::ratio< 1, Eps > >::type ratio_sqrt
Calculate square root of a ratio at compile-time.
Definition base.h:1360
constexpr UnitType make_unit(const T value) noexcept
Constructs a unit container from an arithmetic type.
Definition base.h:2221
typename units::detail::inverse_impl< U >::type inverse
represents the inverse unit type of class U.
Definition base.h:1138
typename units::detail::prefix< std::exa, U >::type exa
Represents the type of class U with the metric 'exa' prefix appended.
Definition base.h:1496
typename units::detail::prefix< std::deca, U >::type deca
Represents the type of class U with the metric 'deca' prefix appended.
Definition base.h:1489
typename units::detail::squared_impl< U >::type squared
represents the unit type of class U squared
Definition base.h:1169
typename units::detail::cubed_impl< U >::type cubed
represents the type of class U cubed.
Definition base.h:1199
typename units::detail::prefix< std::milli, U >::type milli
Represents the type of class U with the metric 'milli' prefix appended.
Definition base.h:1486
typename units::detail::prefix< std::peta, U >::type peta
Represents the type of class U with the metric 'peta' prefix appended.
Definition base.h:1495
typename units::detail::prefix< std::kilo, U >::type kilo
Represents the type of class U with the metric 'kilo' prefix appended.
Definition base.h:1491
typename units::detail::prefix< std::micro, U >::type micro
Represents the type of class U with the metric 'micro' prefix appended.
Definition base.h:1485
typename units::detail::prefix< std::deci, U >::type deci
Represents the type of class U with the metric 'deci' prefix appended.
Definition base.h:1488
typename units::detail::prefix< std::ratio< 1073741824 >, U >::type gibi
Represents the type of class U with the binary 'gibi' prefix appended.
Definition base.h:1507
typename units::detail::prefix< std::giga, U >::type giga
Represents the type of class U with the metric 'giga' prefix appended.
Definition base.h:1493
typename units::detail::prefix< std::ratio< 1048576 >, U >::type mebi
Represents the type of class U with the binary 'mibi' prefix appended.
Definition base.h:1506
typename units::detail::prefix< std::ratio< 1125899906842624 >, U >::type pebi
Represents the type of class U with the binary 'pebi' prefix appended.
Definition base.h:1509
typename units::detail::prefix< std::ratio< 1152921504606846976 >, U >::type exbi
Represents the type of class U with the binary 'exbi' prefix appended.
Definition base.h:1510
typename units::detail::prefix< std::pico, U >::type pico
Represents the type of class U with the metric 'pico' prefix appended.
Definition base.h:1483
typename units::detail::prefix< std::atto, U >::type atto
Definition base.h:1481
typename units::detail::prefix< std::tera, U >::type tera
Represents the type of class U with the metric 'tera' prefix appended.
Definition base.h:1494
typename units::detail::prefix< std::mega, U >::type mega
Represents the type of class U with the metric 'mega' prefix appended.
Definition base.h:1492
typename units::detail::prefix< std::hecto, U >::type hecto
Represents the type of class U with the metric 'hecto' prefix appended.
Definition base.h:1490
typename units::detail::prefix< std::nano, U >::type nano
Represents the type of class U with the metric 'nano' prefix appended.
Definition base.h:1484
typename units::detail::prefix< std::ratio< 1099511627776 >, U >::type tebi
Represents the type of class U with the binary 'tebi' prefix appended.
Definition base.h:1508
typename units::detail::prefix< std::centi, U >::type centi
Represents the type of class U with the metric 'centi' prefix appended.
Definition base.h:1487
typename units::detail::prefix< std::femto, U >::type femto
Represents the type of class U with the metric 'femto' prefix appended.
Definition base.h:1482
typename units::detail::prefix< std::ratio< 1024 >, U >::type kibi
Definition base.h:1505
typename units::detail::sqrt_impl< U, Eps >::type square_root
represents the square root of type class U.
Definition base.h:1405
typename units::detail::compound_impl< U, Us... >::type compound_unit
Represents a unit type made up from other units.
Definition base.h:1438
detail namespace with internal helper functions
Definition input_adapters.h:32
@ value
the parser finished reading a JSON value
constexpr common_t< T1, T2 > pow(const T1 base, const T2 exp_term) noexcept
Compile-time power function.
Definition pow.hpp:82
Implement std::hash so that hash_code can be used in STL containers.
Definition PointerIntPair.h:280
base_unit< detail::meter_ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > time_unit
Represents an SI base unit of time.
Definition base.h:801
base_unit< detail::meter_ratio< 0 >, std::ratio< 1 > > mass_unit
Represents an SI base unit of mass.
Definition base.h:800
base_unit< detail::meter_ratio<-3 >, std::ratio< 1 > > density_unit
Represents an SI derived unit of density.
Definition base.h:838
base_unit< detail::meter_ratio< 2 >, std::ratio< 1 >, std::ratio<-2 >, std::ratio< 0 >, std::ratio<-1 > > magnetic_flux_unit
Represents an SI derived unit of magnetic flux.
Definition base.h:826
base_unit< detail::meter_ratio< 0 >, std::ratio< 0 >, std::ratio<-1 >, std::ratio< 1 > > angular_velocity_unit
Represents an SI derived unit of angular velocity.
Definition base.h:813
base_unit< detail::meter_ratio< 2 >, std::ratio< 1 >, std::ratio<-3 >, std::ratio< 0 >, std::ratio<-2 > > impedance_unit
Represents an SI derived unit of impedance.
Definition base.h:824
base_unit< detail::meter_ratio< 1 > > length_unit
Represents an SI base unit of length.
Definition base.h:799
base_unit< detail::meter_ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > luminous_intensity_unit
Represents an SI base unit of luminous intensity.
Definition base.h:806
base_unit concentration_unit
Represents a unit of concentration.
Definition base.h:839
base_unit< detail::meter_ratio< 2 >, std::ratio< 1 >, std::ratio<-2 > > energy_unit
Represents an SI derived unit of energy.
Definition base.h:820
base_unit< detail::meter_ratio< 3 > > volume_unit
Represents an SI derived unit of volume.
Definition base.h:837
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
Represents an SI derived unit of illuminance.
Definition base.h:830
base_unit dimensionless_unit
Represents a quantity with no dimension.
Definition base.h:795
base_unit< detail::meter_ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > data_unit
Represents a unit of data size.
Definition base.h:840
base_unit< detail::meter_ratio<-1 >, std::ratio< 1 >, std::ratio<-2 > > pressure_unit
Represents an SI derived unit of pressure.
Definition base.h:818
base_unit< detail::meter_ratio< 1 >, std::ratio< 0 >, std::ratio<-2 > > acceleration_unit
Represents an SI derived unit of acceleration.
Definition base.h:814
base_unit scalar_unit
Represents a quantity with no dimension.
Definition base.h:794
base_unit< detail::meter_ratio< 2 >, std::ratio< 1 >, std::ratio<-3 > > power_unit
Represents an SI derived unit of power.
Definition base.h:821
base_unit< detail::meter_ratio< 0 >, std::ratio< 0 >, std::ratio<-1 > > frequency_unit
Represents an SI derived unit of frequency.
Definition base.h:811
base_unit< detail::meter_ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > angle_unit
Represents an SI base unit of angle.
Definition base.h:802
base_unit< detail::meter_ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > current_unit
Represents an SI base unit of current.
Definition base.h:803
base_unit< detail::meter_ratio< 0 >, std::ratio< 0 >, std::ratio< 1 >, std::ratio< 0 >, std::ratio< 1 > > charge_unit
Represents an SI derived unit of charge.
Definition base.h:819
base_unit< detail::meter_ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 2 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 > > solid_angle_unit
Represents an SI derived unit of solid angle.
Definition base.h:810
base_unit< detail::meter_ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > substance_unit
Represents an SI base unit of amount of substance.
Definition base.h:805
base_unit< detail::meter_ratio< 0 >, std::ratio< 0 >, std::ratio<-3 >, std::ratio< 1 > > angular_jerk_unit
Represents an SI derived unit of angular jerk.
Definition base.h:816
base_unit< detail::meter_ratio< 2 >, std::ratio< 1 >, std::ratio<-3 >, std::ratio< 0 >, std::ratio<-1 > > voltage_unit
Represents an SI derived unit of voltage.
Definition base.h:822
base_unit< detail::meter_ratio< 0 >, std::ratio< 0 >, std::ratio<-1 > > radioactivity_unit
Represents an SI derived unit of radioactivity.
Definition base.h:831
base_unit< detail::meter_ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 2 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > luminous_flux_unit
Represents an SI derived unit of luminous flux.
Definition base.h:829
base_unit< detail::meter_ratio< 2 >, std::ratio< 1 >, std::ratio<-2 > > torque_unit
Represents an SI derived unit of torque.
Definition base.h:835
base_unit< detail::meter_ratio< 2 >, std::ratio< 1 >, std::ratio<-2 >, std::ratio< 0 >, std::ratio<-2 > > inductance_unit
Represents an SI derived unit of inductance.
Definition base.h:828
base_unit< detail::meter_ratio< 1 >, std::ratio< 0 >, std::ratio<-1 > > velocity_unit
Represents an SI derived unit of velocity.
Definition base.h:812
base_unit< detail::meter_ratio< 1 >, std::ratio< 1 >, std::ratio<-2 > > force_unit
Represents an SI derived unit of force.
Definition base.h:817
base_unit< detail::meter_ratio< 0 >, std::ratio< 0 >, std::ratio<-2 >, std::ratio< 1 > > angular_acceleration_unit
Represents an SI derived unit of angular acceleration.
Definition base.h:815
base_unit< detail::meter_ratio< 0 >, std::ratio< 0 >, std::ratio<-1 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > data_transfer_rate_unit
Represents a unit of data transfer rate.
Definition base.h:841
base_unit< detail::meter_ratio<-2 >, std::ratio<-1 >, std::ratio< 4 >, std::ratio< 0 >, std::ratio< 2 > > capacitance_unit
Represents an SI derived unit of capacitance.
Definition base.h:823
base_unit< detail::meter_ratio<-2 >, std::ratio<-1 >, std::ratio< 3 >, std::ratio< 0 >, std::ratio< 2 > > conductance_unit
Represents an SI derived unit of conductance.
Definition base.h:825
base_unit< detail::meter_ratio< 0 >, std::ratio< 1 >, std::ratio<-2 >, std::ratio< 0 >, std::ratio<-1 > > magnetic_field_strength_unit
Represents an SI derived unit of magnetic field strength.
Definition base.h:827
base_unit< detail::meter_ratio< 2 > > area_unit
Represents an SI derived unit of area.
Definition base.h:836
base_unit< detail::meter_ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > temperature_unit
Represents an SI base unit of temperature.
Definition base.h:804
std::string to_string(const T &t)
Definition base.h:94
unit_t< scalar, UNIT_LIB_DEFAULT_TYPE, decibel_scale > dB_t
Definition base.h:2872
unit< std::ratio< 1 >, units::category::dimensionless_unit > dimensionless
Definition base.h:2515
dB_t dBi_t
Definition base.h:2873
scalar_t dimensionless_t
Definition base.h:2518
unit_t< scalar > scalar_t
Definition base.h:2517
unit< std::ratio< 1 >, units::category::scalar_unit > scalar
Definition base.h:2514
constexpr UnitTypeLhs max(const UnitTypeLhs &lhs, const UnitTypeRhs &rhs)
Definition base.h:3422
constexpr auto cpow(const UnitType &value) noexcept -> unit_t< typename units::detail::power_of_unit< power, typename units::traits::unit_t_traits< UnitType >::unit_type >::type, typename units::traits::unit_t_traits< UnitType >::underlying_type, linear_scale >
computes the value of value raised to the power as a constexpr
Definition base.h:2825
constexpr auto pow(const UnitType &value) noexcept -> unit_t< typename units::detail::power_of_unit< power, typename units::traits::unit_t_traits< UnitType >::unit_type >::type, typename units::traits::unit_t_traits< UnitType >::underlying_type, linear_scale >
computes the value of value raised to the power
Definition base.h:2810
constexpr UnitTypeLhs min(const UnitTypeLhs &lhs, const UnitTypeRhs &rhs)
Definition base.h:3414
constexpr bool has_decibel_scale_v
Definition base.h:2443
constexpr bool is_convertible_unit_v
Definition base.h:1535
constexpr bool has_linear_scale_v
Definition base.h:2421
constexpr bool is_unit_value_t_category_v
Definition base.h:3077
typename units::detail::base_unit_of_impl< U >::type base_unit_of
Trait which returns the base_unit type that a unit is originally derived from.
Definition base.h:936
constexpr bool is_same_scale_v
Definition base.h:2467
constexpr bool is_unit_v
Definition base.h:724
constexpr bool is_unit_t_v
Definition base.h:1870
constexpr bool is_ratio_v
Definition base.h:596
constexpr bool is_unit_value_t_v
Definition base.h:3063
Unit Conversion Library namespace.
Definition acceleration.h:33
constexpr unit_t< Units, T, NonLinearScale > & operator++(unit_t< Units, T, NonLinearScale > &u) noexcept
Definition base.h:2339
constexpr bool operator!=(const UNIT_LIB_DEFAULT_TYPE lhs, const Units &rhs) noexcept
Definition base.h:2720
constexpr unit_t< Units, T, NonLinearScale > & operator+=(unit_t< Units, T, NonLinearScale > &lhs, const RhsType &rhs) noexcept
Definition base.h:2285
constexpr const char * abbreviation(const T &)
constexpr unit_t< Units, T, NonLinearScale > & operator--(unit_t< Units, T, NonLinearScale > &u) noexcept
Definition base.h:2363
constexpr bool operator==(const UNIT_LIB_DEFAULT_TYPE lhs, const Units &rhs) noexcept
Definition base.h:2706
constexpr dimensionless::scalar_t operator/(const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
Division for convertible unit_t types with a linear scale.
Definition base.h:2648
constexpr const char * name(const T &)
constexpr unit_t< Units, T, NonLinearScale > & operator/=(unit_t< Units, T, NonLinearScale > &lhs, const RhsType &rhs) noexcept
Definition base.h:2317
constexpr bool operator<(const UNIT_LIB_DEFAULT_TYPE lhs, const Units &rhs) noexcept
Definition base.h:2768
constexpr unit_t< Units, T, NonLinearScale > & operator*=(unit_t< Units, T, NonLinearScale > &lhs, const RhsType &rhs) noexcept
Definition base.h:2307
constexpr bool operator<=(const UNIT_LIB_DEFAULT_TYPE lhs, const Units &rhs) noexcept
Definition base.h:2756
constexpr bool operator>=(const UNIT_LIB_DEFAULT_TYPE lhs, const Units &rhs) noexcept
Definition base.h:2732
constexpr bool operator>(const UNIT_LIB_DEFAULT_TYPE lhs, const Units &rhs) noexcept
Definition base.h:2744
constexpr unit_t< Units, T, NonLinearScale > operator-(const unit_t< Units, T, NonLinearScale > &u) noexcept
Definition base.h:2356
constexpr unit_t< Units, T, NonLinearScale > & operator-=(unit_t< Units, T, NonLinearScale > &lhs, const RhsType &rhs) noexcept
Definition base.h:2296
constexpr unit_t< Units, T, NonLinearScale > operator+(const unit_t< Units, T, NonLinearScale > &u) noexcept
Definition base.h:2332
constexpr auto operator*(const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept -> unit_t< compound_unit< squared< typename units::traits::unit_t_traits< UnitTypeLhs >::unit_type > > >
Multiplication type for convertible unit_t types with a linear scale.
Definition base.h:2592
Class representing SI base unit types.
Definition base.h:761
Meter meter_ratio
Definition base.h:772
Candela candela_ratio
Definition base.h:779
Byte byte_ratio
Definition base.h:780
Ampere ampere_ratio
Definition base.h:776
Mole mole_ratio
Definition base.h:778
Radian radian_ratio
Definition base.h:775
Kelvin kelvin_ratio
Definition base.h:777
Kilogram kilogram_ratio
Definition base.h:773
Second second_ratio
Definition base.h:774
unit_t scale for representing decibel values.
Definition base.h:2845
decibel_scale & operator=(const decibel_scale &)=default
constexpr decibel_scale(const T value) noexcept
Definition base.h:2854
constexpr decibel_scale(const T value, std::true_type, Args &&...) noexcept
Definition base.h:2856
constexpr decibel_scale()=default
T m_value
linearized value
Definition base.h:2859
constexpr T operator()() const noexcept
Definition base.h:2857
constexpr decibel_scale(const decibel_scale &)=default
unit_t scale which is linear
Definition base.h:2491
constexpr T operator()() const noexcept
returns value.
Definition base.h:2502
UNIT_LIB_DEFAULT_TYPE m_value
Definition base.h:2504
constexpr linear_scale(const linear_scale &)=default
linear_scale & operator=(const linear_scale &)=default
constexpr linear_scale()=default
default constructor.
constexpr linear_scale(const T &value, Args &&...) noexcept
constructor.
Definition base.h:2501
Trait which tests whether a type is inherited from a decibel scale.
Definition base.h:2441
Trait which tests whether a type is inherited from a linear scale.
Definition base.h:2419
Trait which tests if a class is a base_unit type.
Definition base.h:696
Trait which tests whether two container types derived from unit_t are convertible to each other.
Definition base.h:1830
Trait which checks whether two units can be converted to each other.
Definition base.h:1533
Trait which tests that class T meets the requirements for a non-linear scale.
Definition base.h:1753
Trait that tests whether a type represents a std::ratio.
Definition base.h:594
Trait which tests whether two types has the same non-linear scale.
Definition base.h:2465
Traits which tests if a class is a unit
Definition base.h:1868
Trait which tests whether type T is a unit_value_t with a unit type in the given category.
Definition base.h:3073
Trait which tests whether a type is a unit_value_t representing the given unit type.
Definition base.h:3061
Traits which tests if a class is a unit
Definition base.h:722
adds two unit_value_t types at compile-time
Definition base.h:3114
static constexpr const unit_t< unit_type > value() noexcept
Value of sum.
Definition base.h:3129
divides two unit_value_t types at compile-time
Definition base.h:3266
static constexpr const unit_t< unit_type > value() noexcept
Value of quotient.
Definition base.h:3280
multiplies two unit_value_t types at compile-time
Definition base.h:3216
static constexpr const unit_t< unit_type > value() noexcept
Value of product.
Definition base.h:3230
raises unit_value_to a power at compile-time
Definition base.h:3312
static constexpr const unit_t< unit_type > value() noexcept
Value of exponentiation.
Definition base.h:3327
calculates square root of unit_value_t at compile-time
Definition base.h:3359
static constexpr const unit_t< unit_type > value() noexcept
Value of square root.
Definition base.h:3374
subtracts two unit_value_t types at compile-time
Definition base.h:3163
static constexpr const unit_t< unit_type > value() noexcept
Value of difference.
Definition base.h:3179
Stores a rational unit value as a compile-time constant.
Definition base.h:3040
Units unit_type
Definition base.h:3041
static constexpr const unit_t< Units > value()
Definition base.h:3045
std::ratio< Num, Denom > ratio
Definition base.h:3042
Type representing an arbitrary unit.
Definition base.h:888
std::ratio_add< typename BaseUnit::pi_exponent_ratio, PiExponent > pi_exponent_ratio
Definition base.h:895
std::ratio_add< std::ratio_multiply< typename BaseUnit::conversion_ratio, Translation >, typename BaseUnit::translation_ratio > translation_ratio
Definition base.h:896
units::traits::unit_traits< BaseUnit >::base_unit_type base_unit_type
Definition base.h:893
std::ratio_multiply< typename BaseUnit::conversion_ratio, Conversion > conversion_ratio
Definition base.h:894
#define UNIT_LIB_DEFAULT_TYPE
Definition base.h:59
#define UNIT_ADD_CATEGORY_TRAIT(unitCategory)
Macro to create the is_category_unit type trait.
Definition base.h:373
typename std::enable_if< B, T >::type enable_if_t
Definition base.h:297
void void_t
Definition base.h:321