From fc8bd7de464045c1a172ee7d27a07e67aeb993b5 Mon Sep 17 00:00:00 2001 From: Nic Holthaus Date: Sat, 21 Dec 2024 20:35:55 -0500 Subject: [PATCH] fix: cleaned up clang warnings fix: stopped using reserved identifiers for include guards feat: added various units of radiometry & unit tests --- include/units.h | 14 +- include/units/acceleration.h | 6 +- include/units/angle.h | 6 +- include/units/angular_velocity.h | 8 +- include/units/area.h | 6 +- include/units/capacitance.h | 4 +- include/units/charge.h | 6 +- include/units/concentration.h | 6 +- include/units/conductance.h | 6 +- include/units/core.h | 790 ++++++------ include/units/current.h | 6 +- include/units/data.h | 6 +- include/units/data_transfer_rate.h | 6 +- include/units/density.h | 6 +- include/units/energy.h | 6 +- include/units/energy_density.h | 67 + include/units/force.h | 6 +- include/units/frequency.h | 6 +- include/units/illuminance.h | 6 +- include/units/impedance.h | 6 +- include/units/inductance.h | 6 +- include/units/irradiance.h | 64 + include/units/jerk.h | 6 +- include/units/length.h | 6 +- include/units/luminance.h | 2 +- include/units/luminous_flux.h | 6 +- include/units/luminous_intensity.h | 6 +- include/units/magnetic_field_strength.h | 6 +- include/units/magnetic_flux.h | 6 +- include/units/mass.h | 6 +- include/units/power.h | 6 +- include/units/pressure.h | 8 +- include/units/radiance.h | 64 + include/units/radiant_intensity.h | 64 + include/units/radiation.h | 6 +- include/units/solid_angle.h | 4 +- include/units/spectral_flux.h | 64 + .../{radiometry.h => spectral_intensity.h} | 36 +- include/units/spectral_irradiance.h | 64 + include/units/spectral_radiance.h | 65 + include/units/substance.h | 6 +- include/units/substance_concentration.h | 6 +- include/units/substance_mass.h | 6 +- include/units/temperature.h | 6 +- include/units/time.h | 6 +- include/units/torque.h | 6 +- include/units/velocity.h | 6 +- include/units/voltage.h | 6 +- include/units/volume.h | 6 +- unitTests/main.cpp | 1097 +++++++++-------- 50 files changed, 1546 insertions(+), 1073 deletions(-) create mode 100644 include/units/energy_density.h create mode 100644 include/units/irradiance.h create mode 100644 include/units/radiance.h create mode 100644 include/units/radiant_intensity.h create mode 100644 include/units/spectral_flux.h rename include/units/{radiometry.h => spectral_intensity.h} (69%) create mode 100644 include/units/spectral_irradiance.h create mode 100644 include/units/spectral_radiance.h diff --git a/include/units.h b/include/units.h index d2f49582..17cb1724 100644 --- a/include/units.h +++ b/include/units.h @@ -45,8 +45,8 @@ #pragma once -#ifndef units_h__ -#define units_h__ +#ifndef units_h_ +#define units_h_ #include #include @@ -61,11 +61,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -76,8 +78,14 @@ #include #include #include +#include +#include #include #include +#include +#include +#include +#include #include #include #include @@ -138,4 +146,4 @@ namespace units } // namespace constants } // end namespace units -#endif // units_h__ \ No newline at end of file +#endif // units_h_ \ No newline at end of file diff --git a/include/units/acceleration.h b/include/units/acceleration.h index 8ff4a1af..efe3640f 100644 --- a/include/units/acceleration.h +++ b/include/units/acceleration.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_acceleration_h__ -#define units_acceleration_h__ +#ifndef units_acceleration_h_ +#define units_acceleration_h_ #include #include @@ -67,4 +67,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(acceleration) } // namespace units -#endif // units_acceleration_h__ \ No newline at end of file +#endif // units_acceleration_h_ \ No newline at end of file diff --git a/include/units/angle.h b/include/units/angle.h index 1290e918..77bcd931 100644 --- a/include/units/angle.h +++ b/include/units/angle.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_angle_h__ -#define units_angle_h__ +#ifndef units_angle_h_ +#define units_angle_h_ #include @@ -273,4 +273,4 @@ namespace units } } // namespace units -#endif // units_angle_h__ +#endif // units_angle_h_ \ No newline at end of file diff --git a/include/units/angular_velocity.h b/include/units/angular_velocity.h index e7ec5d8c..904527ce 100644 --- a/include/units/angular_velocity.h +++ b/include/units/angular_velocity.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_angular_velocity_h__ -#define units_angular_velocity_h__ +#ifndef units_angular_velocity_h_ +#define units_angular_velocity_h_ #include #include @@ -55,7 +55,7 @@ namespace units * @namespace units::angular_velocity * @brief namespace for unit types and containers representing angular velocity values * @details The SI unit for angular velocity is `radians_per_second`, and the corresponding `dimension` - *dimension is `angular_velocity_unit`. + * dimension is `angular_velocity_unit`. * @anchor angularVelocityContainers * @sa See unit for more information on unit type containers. */ @@ -68,4 +68,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(angular_velocity) } // namespace units -#endif // units_angular_velocity_h__ +#endif // units_angular_velocity_h_ \ No newline at end of file diff --git a/include/units/area.h b/include/units/area.h index 8d69919c..df317faf 100644 --- a/include/units/area.h +++ b/include/units/area.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_area_h__ -#define units_area_h__ +#ifndef units_area_h_ +#define units_area_h_ #include @@ -69,4 +69,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(area) } // namespace units -#endif // units_area_h__ +#endif // units_area_h_ \ No newline at end of file diff --git a/include/units/capacitance.h b/include/units/capacitance.h index d346f8d7..aab88e2c 100644 --- a/include/units/capacitance.h +++ b/include/units/capacitance.h @@ -43,7 +43,7 @@ #pragma once -#ifndef units_capacitance_h__ +#ifndef units_capacitance_h_ #define units_capacitance_h__ #include @@ -63,4 +63,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(capacitance) } // namespace units -#endif // units_capacitance_h__ +#endif // units_capacitance_h__ \ No newline at end of file diff --git a/include/units/charge.h b/include/units/charge.h index db6ee4e8..39a2ab3f 100644 --- a/include/units/charge.h +++ b/include/units/charge.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_charge_h__ -#define units_charge_h__ +#ifndef units_charge_h_ +#define units_charge_h_ #include #include @@ -65,4 +65,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(charge) } // namespace units -#endif // units_charge_h__ +#endif // units_charge_h_ \ No newline at end of file diff --git a/include/units/concentration.h b/include/units/concentration.h index 5903505f..1c1f3e20 100644 --- a/include/units/concentration.h +++ b/include/units/concentration.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_concentration_h__ -#define units_concentration_h__ +#ifndef units_concentration_h_ +#define units_concentration_h_ #include @@ -66,4 +66,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(concentration) } // namespace units -#endif // units_concentration_h__ +#endif // units_concentration_h_ \ No newline at end of file diff --git a/include/units/conductance.h b/include/units/conductance.h index 1c08e62a..e299cef1 100644 --- a/include/units/conductance.h +++ b/include/units/conductance.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_conductance_h__ -#define units_conductance_h__ +#ifndef units_conductance_h_ +#define units_conductance_h_ #include @@ -67,4 +67,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(conductance) } // namespace units -#endif // units_conductance_h__ +#endif // units_conductance_h_ \ No newline at end of file diff --git a/include/units/core.h b/include/units/core.h index ba808e17..062b26d4 100644 --- a/include/units/core.h +++ b/include/units/core.h @@ -37,7 +37,7 @@ //-------------------------------------------------------------------------------------------------- // /// @file units/core.h -/// @brief `unit`, dimensional analisys, generic cmath functions, traits (not dimension-specific), +/// @brief `unit`, dimensional analysis, generic cmath functions, traits (not dimension-specific), /// and what they're implemented with (`conversion_factor`, unit manipulators, etc.) // //-------------------------------------------------------------------------------------------------- @@ -153,29 +153,29 @@ namespace units * unit tag. * @param namespaceName namespace in which the new units will be encapsulated. * @param namePlural - plural version of the unit name, e.g. 'meters' - * @param __VA_ARGS__ - the conversion factor definition for the unit type. Taken as variadiac + * @param __VA_ARGS__ - the conversion factor definition for the unit type. Taken as variadic * arguments because they contain commas in the macro definition. The complete __VA_ARGS__ * represents the full conversion factor type. e.g. `meters<>`. * @note the purpose of this trait is primarily to improve the readability of * conversion error messages. */ -#define UNIT_ADD_STRONG_CONVERSION_FACTOR(namespaceName, namePlural, /*conversion factor*/...) \ - inline namespace namespaceName \ - { \ - /** @name ConversionFactor (full names plural) */ /** @{ */ struct namePlural##_ : __VA_ARGS__ \ - { \ - }; /** @} */ \ - } \ - namespace traits \ - { \ - template<> \ - struct strong<__VA_ARGS__> \ - { \ - using type = ::units::namespaceName::namePlural##_; \ - }; \ - \ - template \ - using strong_t = typename strong::type; \ +#define UNIT_ADD_STRONG_CONVERSION_FACTOR(namespaceName, namePlural, /*conversion factor*/...) \ + inline namespace namespaceName \ + { \ + /** @name ConversionFactor (full names plural) */ /** @{ */ struct namePlural##_ : __VA_ARGS__ \ + { \ + }; /** @} */ \ + } \ + namespace traits \ + { \ + template<> \ + struct strong<__VA_ARGS__> \ + { \ + using type = ::units::namespaceName::namePlural##_; \ + }; \ + \ + template \ + using strong_t = typename strong::type; \ } /** @@ -184,14 +184,14 @@ namespace units * @details The macro generates the definition of the unit container types, e.g. `meter` * @param namespaceName namespace in which the new units will be encapsulated. * @param namePlural - plural version of the unit name, e.g. 'meters' - * @param __VA_ARGS__ - the conversion factor definition for the unit type. Taken as variadiac + * @param __VA_ARGS__ - the conversion factor definition for the unit type. Taken as variadic * arguments because they contain commas in the macro definition. The complete __VA_ARGS__ * represents the full conversion factor type. e.g. `meters<>`. */ -#define UNIT_ADD_UNIT_DEFINITION(namespaceName, namePlural, /*conversionFactor*/...) \ - inline namespace namespaceName \ - { \ - /** @name Unit Containers */ /** @{ */ UNIT_ADD_SCALED_UNIT_DEFINITION(namePlural, ::units::linear_scale, __VA_ARGS__) /** @} */ \ +#define UNIT_ADD_UNIT_DEFINITION(namespaceName, namePlural, /*conversionFactor*/...) \ + inline namespace namespaceName \ + { \ + /** @name Unit Containers */ /** @{ */ UNIT_ADD_SCALED_UNIT_DEFINITION(namePlural, ::units::linear_scale, __VA_ARGS__) /** @} */ \ } /** @@ -203,15 +203,15 @@ namespace units * @param scale the non-linear scale template argument of the unit's base * @param definition - the variadic parameter is used for the definition of the unit * (e.g. `conversion_factor, units::dimension::length>`) - * @param __VA_ARGS__ - the conversion factor definition for the unit type. Taken as variadiac + * @param __VA_ARGS__ - the conversion factor definition for the unit type. Taken as variadic * arguments because they contain commas in the macro definition. The complete __VA_ARGS__ * represents the full conversion factor type. e.g. `meters<>`. * @note a variadic template is used for the definition to allow templates with * commas to be easily expanded. All the variadic 'arguments' should together * comprise the unit definition. */ -#define UNIT_ADD_SCALED_UNIT_DEFINITION(unitName, scale, /*conversionFactor*/...) \ - template \ +#define UNIT_ADD_SCALED_UNIT_DEFINITION(unitName, scale, /*conversionFactor*/...) \ + template \ using unitName = ::units::unit, Underlying, scale>; /** * @def UNIT_ADD_NAME(namespaceName,namePlural,abbreviation) @@ -223,17 +223,17 @@ namespace units * @param namePlural - plural version of the unit name, e.g. 'meters' * @param abbreviation - abbreviated unit name, e.g. 'm' */ -#define UNIT_ADD_NAME(namespaceName, namePlural, abbrev) \ - template \ - struct unit_name> \ - { \ - static constexpr const char* value = #namePlural; \ - }; \ - \ - template \ - struct unit_abbreviation> \ - { \ - static constexpr const char* value = #abbrev; \ +#define UNIT_ADD_NAME(namespaceName, namePlural, abbrev) \ + template \ + struct unit_name> \ + { \ + static constexpr const char* value = #namePlural; \ + }; \ + \ + template \ + struct unit_abbreviation> \ + { \ + static constexpr const char* value = #abbrev; \ }; /** @@ -250,17 +250,17 @@ namespace units #ifdef UNIT_NO_LITERAL_SUPPORT #define UNIT_ADD_LITERALS(namespaceName, namePlural, abbreviation) #else -#define UNIT_ADD_LITERALS(namespaceName, namePlural, abbreviation) \ - namespace literals \ - { \ - constexpr namespaceName::namePlural operator""_##abbreviation(long double d) noexcept \ - { \ - return namespaceName::namePlural(static_cast(d)); \ - } \ - constexpr namespaceName::namePlural operator""_##abbreviation(unsigned long long d) noexcept \ - { \ - return namespaceName::namePlural(static_cast(d)); \ - } \ +#define UNIT_ADD_LITERALS(namespaceName, namePlural, abbreviation) \ + namespace literals \ + { \ + constexpr namespaceName::namePlural operator""_##abbreviation(long double d) noexcept \ + { \ + return namespaceName::namePlural(static_cast(d)); \ + } \ + constexpr namespaceName::namePlural operator""_##abbreviation(unsigned long long d) noexcept \ + { \ + return namespaceName::namePlural(static_cast(d)); \ + } \ } #endif @@ -278,18 +278,18 @@ namespace units * are placed in the `units::literals` namespace. * @param namePlural - plural version of the unit name, e.g. 'meters' * @param abbreviation - abbreviated unit name, e.g. 'm' - * @param __VA_ARGS__ - the conversion factor definition for the unit type. Taken as variadiac + * @param __VA_ARGS__ - the conversion factor definition for the unit type. Taken as variadic * arguments because they contain commas in the macro definition. The complete __VA_ARGS__ * represents the full conversion factor type. e.g. `meters<>`. * @note a variadic template is used for the definition to allow templates with * commas to be easily expanded. All the variadic 'arguments' should together * comprise the unit definition. */ -#define UNIT_ADD(namespaceName, namePlural, abbreviation, /*conversionFactor*/...) \ - UNIT_ADD_STRONG_CONVERSION_FACTOR(namespaceName, namePlural, __VA_ARGS__) \ - UNIT_ADD_UNIT_DEFINITION(namespaceName, namePlural, __VA_ARGS__) \ - UNIT_ADD_NAME(namespaceName, namePlural, abbreviation) \ - UNIT_ADD_LITERALS(namespaceName, namePlural, abbreviation) \ +#define UNIT_ADD(namespaceName, namePlural, abbreviation, /*conversionFactor*/...) \ + UNIT_ADD_STRONG_CONVERSION_FACTOR(namespaceName, namePlural, __VA_ARGS__) \ + UNIT_ADD_UNIT_DEFINITION(namespaceName, namePlural, __VA_ARGS__) \ + UNIT_ADD_NAME(namespaceName, namePlural, abbreviation) \ + UNIT_ADD_LITERALS(namespaceName, namePlural, abbreviation) \ UNIT_ADD_CONSTANT(namespaceName, namePlural, abbreviation) /** @@ -301,13 +301,12 @@ namespace units * @param namePlural plural version of the dimension name, e.g. 'watts' * @param abbreviation - abbreviated decibel unit name, e.g. 'dBW' */ -#define UNIT_ADD_DECIBEL(namespaceName, namePlural, abbreviation) \ - inline namespace namespaceName \ - { \ - /** @name Unit Containers */ /** @{ */ UNIT_ADD_SCALED_UNIT_DEFINITION( \ - abbreviation, ::units::decibel_scale, typename ::units::namespaceName::namePlural<>::conversion_factor) /** @} */ \ - } \ - UNIT_ADD_NAME(namespaceName, abbreviation, abbreviation) \ +#define UNIT_ADD_DECIBEL(namespaceName, namePlural, abbreviation) \ + inline namespace namespaceName \ + { \ + /** @name Unit Containers */ /** @{ */ UNIT_ADD_SCALED_UNIT_DEFINITION(abbreviation, ::units::decibel_scale, typename ::units::namespaceName::namePlural<>::conversion_factor) /** @} */ \ + } \ + UNIT_ADD_NAME(namespaceName, abbreviation, abbreviation) \ UNIT_ADD_LITERALS(namespaceName, abbreviation, abbreviation) /** @@ -319,20 +318,20 @@ namespace units * @param unitdimension The name of the dimension of unit, e.g. length or mass. */ -#define UNIT_ADD_DIMENSION_TRAIT(unitdimension) \ - /** @ingroup TypeTraits*/ \ - /** @brief `UnaryTypeTrait` for querying whether `T` represents a unit of unitdimension*/ \ - /** @details The base characteristic is a specialization of the template `std::bool_constant`.*/ \ - /** Use `is_ ## unitdimension ## _unit_v` to test the unit represents a unitdimension quantity.*/ \ - /** @tparam T type to test*/ \ - namespace traits \ - { \ - template \ - struct is_##unitdimension##_unit : ::units::detail::has_dimension_of, units::dimension::unitdimension> \ - { \ - }; \ - template \ - inline constexpr bool is_##unitdimension##_unit_v = is_##unitdimension##_unit::value; \ +#define UNIT_ADD_DIMENSION_TRAIT(unitdimension) \ + /** @ingroup TypeTraits*/ \ + /** @brief `UnaryTypeTrait` for querying whether `T` represents a unit of unitdimension*/ \ + /** @details The base characteristic is a specialization of the template `std::bool_constant`.*/ \ + /** Use `is_ ## unitdimension ## _unit_v` to test the unit represents a unitdimension quantity.*/ \ + /** @tparam T type to test*/ \ + namespace traits \ + { \ + template \ + struct is_##unitdimension##_unit : ::units::detail::has_dimension_of, units::dimension::unitdimension> \ + { \ + }; \ + template \ + inline constexpr bool is_##unitdimension##_unit_v = is_##unitdimension##_unit::value; \ } /** @@ -346,28 +345,28 @@ namespace units * are placed in the `units::literals` namespace. * @param namePlural - plural version of the unit name, e.g. 'meters' * @param abbreviation - abbreviated unit name, e.g. 'm' - * @param __VA_ARGS__ - the conversion factor definition for the unit type. Taken as variadiac + * @param __VA_ARGS__ - the conversion factor definition for the unit type. Taken as variadic * arguments because they contain commas in the macro definition. The complete __VA_ARGS__ * represents the full conversion factor type. e.g. `meters<>`. * @note a variadic template is used for the definition to allow templates with * commas to be easily expanded. All the variadic 'arguments' should together * comprise the unit definition. */ -#define UNIT_ADD_WITH_METRIC_PREFIXES(namespaceName, namePlural, abbreviation, /*conversionFactor*/...) \ - UNIT_ADD(namespaceName, namePlural, abbreviation, __VA_ARGS__) \ - UNIT_ADD(namespaceName, femto##namePlural, f##abbreviation, femto>) \ - UNIT_ADD(namespaceName, pico##namePlural, p##abbreviation, pico>) \ - UNIT_ADD(namespaceName, nano##namePlural, n##abbreviation, nano>) \ - UNIT_ADD(namespaceName, micro##namePlural, u##abbreviation, micro>) \ - UNIT_ADD(namespaceName, milli##namePlural, m##abbreviation, milli>) \ - UNIT_ADD(namespaceName, centi##namePlural, c##abbreviation, centi>) \ - UNIT_ADD(namespaceName, deci##namePlural, d##abbreviation, deci>) \ - UNIT_ADD(namespaceName, deca##namePlural, da##abbreviation, deca>) \ - UNIT_ADD(namespaceName, hecto##namePlural, h##abbreviation, hecto>) \ - UNIT_ADD(namespaceName, kilo##namePlural, k##abbreviation, kilo>) \ - UNIT_ADD(namespaceName, mega##namePlural, M##abbreviation, mega>) \ - UNIT_ADD(namespaceName, giga##namePlural, G##abbreviation, giga>) \ - UNIT_ADD(namespaceName, tera##namePlural, T##abbreviation, tera>) \ +#define UNIT_ADD_WITH_METRIC_PREFIXES(namespaceName, namePlural, abbreviation, /*conversionFactor*/...) \ + UNIT_ADD(namespaceName, namePlural, abbreviation, __VA_ARGS__) \ + UNIT_ADD(namespaceName, femto##namePlural, f##abbreviation, femto>) \ + UNIT_ADD(namespaceName, pico##namePlural, p##abbreviation, pico>) \ + UNIT_ADD(namespaceName, nano##namePlural, n##abbreviation, nano>) \ + UNIT_ADD(namespaceName, micro##namePlural, u##abbreviation, micro>) \ + UNIT_ADD(namespaceName, milli##namePlural, m##abbreviation, milli>) \ + UNIT_ADD(namespaceName, centi##namePlural, c##abbreviation, centi>) \ + UNIT_ADD(namespaceName, deci##namePlural, d##abbreviation, deci>) \ + UNIT_ADD(namespaceName, deca##namePlural, da##abbreviation, deca>) \ + UNIT_ADD(namespaceName, hecto##namePlural, h##abbreviation, hecto>) \ + UNIT_ADD(namespaceName, kilo##namePlural, k##abbreviation, kilo>) \ + UNIT_ADD(namespaceName, mega##namePlural, M##abbreviation, mega>) \ + UNIT_ADD(namespaceName, giga##namePlural, G##abbreviation, giga>) \ + UNIT_ADD(namespaceName, tera##namePlural, T##abbreviation, tera>) \ UNIT_ADD(namespaceName, peta##namePlural, P##abbreviation, peta>) /** @@ -381,20 +380,20 @@ namespace units * are placed in the `units::literals` namespace. * @param namePlural - plural version of the unit name, e.g. 'bytes' * @param abbreviation - abbreviated unit name, e.g. 'B' - * @param __VA_ARGS__ - the conversion factor definition for the unit type. Taken as variadiac + * @param __VA_ARGS__ - the conversion factor definition for the unit type. Taken as variadic * arguments because they contain commas in the macro definition. The complete __VA_ARGS__ * represents the full conversion factor type. e.g. `meters<>`. * @note a variadic template is used for the definition to allow templates with * commas to be easily expanded. All the variadic 'arguments' should together * comprise the unit definition. */ -#define UNIT_ADD_WITH_METRIC_AND_BINARY_PREFIXES(namespaceName, namePlural, abbreviation, /*conversionFactor*/...) \ - UNIT_ADD_WITH_METRIC_PREFIXES(namespaceName, namePlural, abbreviation, __VA_ARGS__) \ - UNIT_ADD(namespaceName, kibi##namePlural, Ki##abbreviation, kibi>) \ - UNIT_ADD(namespaceName, mebi##namePlural, Mi##abbreviation, mebi>) \ - UNIT_ADD(namespaceName, gibi##namePlural, Gi##abbreviation, gibi>) \ - UNIT_ADD(namespaceName, tebi##namePlural, Ti##abbreviation, tebi>) \ - UNIT_ADD(namespaceName, pebi##namePlural, Pi##abbreviation, pebi>) \ +#define UNIT_ADD_WITH_METRIC_AND_BINARY_PREFIXES(namespaceName, namePlural, abbreviation, /*conversionFactor*/...) \ + UNIT_ADD_WITH_METRIC_PREFIXES(namespaceName, namePlural, abbreviation, __VA_ARGS__) \ + UNIT_ADD(namespaceName, kibi##namePlural, Ki##abbreviation, kibi>) \ + UNIT_ADD(namespaceName, mebi##namePlural, Mi##abbreviation, mebi>) \ + UNIT_ADD(namespaceName, gibi##namePlural, Gi##abbreviation, gibi>) \ + UNIT_ADD(namespaceName, tebi##namePlural, Ti##abbreviation, tebi>) \ + UNIT_ADD(namespaceName, pebi##namePlural, Pi##abbreviation, pebi>) \ UNIT_ADD(namespaceName, exbi##namePlural, Ei##abbreviation, exbi>) //-------------------- @@ -556,7 +555,6 @@ namespace units template inline constexpr bool is_ratio_v = is_ratio::value; - } // namespace traits //------------------------------ @@ -604,8 +602,7 @@ namespace units }; template - struct conversion_factor_traits> + struct conversion_factor_traits> { using dimension_type = typename T::dimension_type; ///< Unit type that the unit was derived from. May be a `dimension` or ///< another `conversion_factor`. Use the `dimension_of_t` trait to find the @@ -618,6 +615,7 @@ namespace units ///< degrees C to degrees F conversion). This will be `void` if type `T` ///< is not a unit. }; + /** @endcond */ // END DOXYGEN IGNORE } // namespace traits @@ -691,7 +689,10 @@ namespace units { template requires std::is_same_v - decltype(NumericalScale::scale(T{})) operator()(T); + decltype(NumericalScale::scale(T{})) operator()(T) + { + return scale(T{}); + }; }; } // namespace detail /** @endcond */ // END DOXYGEN IGNORE @@ -932,9 +933,8 @@ namespace units struct merge_dimensions_impl<0> { template - using apply = typename merge_dimensions_combine_impl::num == - 0>::template apply>, R...>; + using apply = typename merge_dimensions_combine_impl::num == 0>::template apply>, R...>; }; template @@ -1062,40 +1062,47 @@ namespace units using angle = make_dimension; ///< Represents a quantity of angle // SI DERIVED UNIT TYPES - using solid_angle = dimension_pow>; ///< Represents an SI derived unit of solid angle - using frequency = make_dimension>; ///< Represents an SI derived unit of frequency - using velocity = dimension_divide; ///< Represents an SI derived unit of velocity - using angular_velocity = dimension_divide; ///< Represents an SI derived unit of angular velocity - using acceleration = dimension_divide; ///< Represents an SI derived unit of acceleration - using force = dimension_multiply; ///< Represents an SI derived unit of force - using area = dimension_pow>; ///< Represents an SI derived unit of area - using pressure = dimension_divide; ///< Represents an SI derived unit of pressure - using charge = dimension_multiply; ///< Represents an SI derived unit of charge - using energy = dimension_multiply; ///< Represents an SI derived unit of energy - using power = dimension_divide; ///< Represents an SI derived unit of power - using voltage = dimension_divide; ///< Represents an SI derived unit of voltage - using capacitance = dimension_divide; ///< Represents an SI derived unit of capacitance - using impedance = dimension_divide; ///< Represents an SI derived unit of impedance - using conductance = dimension_divide; ///< Represents an SI derived unit of conductance - using magnetic_flux = dimension_divide; ///< Represents an SI derived unit of magnetic flux - using inductance = dimension_multiply; ///< Represents an SI derived unit of inductance - using luminous_flux = dimension_multiply; ///< Represents an SI derived unit of luminous flux - using illuminance = make_dimension, length, std::ratio<-2>>; ///< Represents an SI derived unit of illuminance - using luminance = make_dimension, length, std::ratio<-2>>; ///< Represents an SI derived unit of luminance - using radioactivity = make_dimension, time, std::ratio<-2>>; ///< Represents an SI derived unit of radioactivity - using substance_mass = dimension_divide; - using substance_concentration = dimension_divide; - using magnetic_field_strength = - make_dimension, time, std::ratio<-2>, current, std::ratio<-1>>; ///< Represents an SI derived unit of magnetic field strength + using solid_angle = dimension_pow>; ///< Represents an SI derived unit of solid angle + using frequency = make_dimension>; ///< Represents an SI derived unit of frequency + using velocity = dimension_divide; ///< Represents an SI derived unit of velocity + using angular_velocity = dimension_divide; ///< Represents an SI derived unit of angular velocity + using acceleration = dimension_divide; ///< Represents an SI derived unit of acceleration + using force = dimension_multiply; ///< Represents an SI derived unit of force + using area = dimension_pow>; ///< Represents an SI derived unit of area + using volume = dimension_pow>; ///< Represents an SI derived unit of volume + using pressure = dimension_divide; ///< Represents an SI derived unit of pressure + using charge = dimension_multiply; ///< Represents an SI derived unit of charge + using energy = dimension_multiply; ///< Represents an SI derived unit of energy + using power = dimension_divide; ///< Represents an SI derived unit of power + using voltage = dimension_divide; ///< Represents an SI derived unit of voltage + using capacitance = dimension_divide; ///< Represents an SI derived unit of capacitance + using impedance = dimension_divide; ///< Represents an SI derived unit of impedance + using conductance = dimension_divide; ///< Represents an SI derived unit of conductance + using magnetic_flux = dimension_divide; ///< Represents an SI derived unit of magnetic flux + using inductance = dimension_multiply; ///< Represents an SI derived unit of inductance + using luminous_flux = dimension_multiply; ///< Represents an SI derived unit of luminous flux + using illuminance = make_dimension, length, std::ratio<-2>>; ///< Represents an SI derived unit of illuminance + using luminance = make_dimension, length, std::ratio<-2>>; ///< Represents an SI derived unit of luminance + using radioactivity = make_dimension, time, std::ratio<-2>>; ///< Represents an SI derived unit of radioactivity + using substance_mass = dimension_divide; ///< Represents an SI derived unit of substance mass + using substance_concentration = dimension_divide; ///< Represents an SI derived unit of substance concentration + using magnetic_field_strength = make_dimension, time, std::ratio<-2>, current, std::ratio<-1>>; ///< Represents an SI derived unit of magnetic field strength + using radiant_intensity = make_dimension, solid_angle, std::ratio<-1>>; ///< Represents an SI derived unit of radiant intensity + using radiance = make_dimension, area, std::ratio<-1>>; ///< Represents an SI derived unit of radiance + using irradiance = make_dimension, area, std::ratio<-1>>; ///< Represents an SI derived unit of irradiance + using spectral_intensity = make_dimension, length, std::ratio<-1>>; ///< Represents an SI derived unit of spectral intensity + using spectral_flux = make_dimension, length, std::ratio<-1>>; ///< Represents an SI derived unit of spectral flux + using spectral_radiance = make_dimension, volume, std::ratio<-1>>; ///< Represents an SI derived unit of spectral intensity + using spectral_irradiance = make_dimension, volume, std::ratio<-1>>; ///< Represents an SI derived unit of spectral irradiance // OTHER UNIT TYPES - using jerk = make_dimension, time, std::ratio<-3>>; ///< Represents an SI derived unit of jerk - using torque = dimension_multiply; ///< Represents an SI derived unit of torque - using volume = dimension_pow>; ///< Represents an SI derived unit of volume - using density = dimension_divide; ///< Represents an SI derived unit of density - using concentration = make_dimension>; ///< Represents a unit of concentration - using data = make_dimension; ///< Represents a unit of data size - using data_transfer_rate = dimension_divide; ///< Represents a unit of data transfer rate + using jerk = make_dimension, time, std::ratio<-3>>; ///< Represents an SI derived unit of jerk + using torque = dimension_multiply; ///< Represents an SI derived unit of torque + using density = dimension_divide; ///< Represents an SI derived unit of density + using energy_density = make_dimension, volume, std::ratio<-1>>; ///< Represents an SI derived unit of energy density + using concentration = make_dimension>; ///< Represents a unit of concentration + using data = make_dimension; ///< Represents a unit of data size + using data_transfer_rate = dimension_divide; ///< Represents a unit of data transfer rate } // namespace dimension //------------------------------ @@ -1112,26 +1119,22 @@ namespace units template struct conversion_factor, PiExponent, Translation> : detail::_conversion_factor { - static_assert(traits::is_ratio_v, - "Template parameter `Conversion` must be a `std::ratio` representing the conversion factor to " - "`Dimension`."); - static_assert(traits::is_ratio_v, "Template parameter `PiExponent` must be a `std::ratio` representing the exponents of Pi the unit has."); - static_assert(traits::is_ratio_v, - "Template parameter `Translation` must be a `std::ratio` representing an additive translation required by " - "the unit conversion."); - using dimension_type = dimension_t; using conversion_ratio = Conversion; using translation_ratio = Translation; using pi_exponent_ratio = PiExponent; }; + /** @endcond */ // END DOXYGEN IGNORE - /** @cond */ // DOXYGEN IGNORE + /** @cond */ // DOXYGEN IGNORE namespace detail { template - conversion_factor conversion_factor_base_t_impl(conversion_factor*); + conversion_factor conversion_factor_base_t_impl(conversion_factor* cf) + { + return *cf; + }; template using conversion_factor_base_t = decltype(conversion_factor_base_t_impl(std::declval())); @@ -1196,8 +1199,7 @@ namespace units }; template - struct has_dimension_of_impl, Dim, true> - : std::is_same::dimension_type, Dim>::type + struct has_dimension_of_impl, Dim, true> : std::is_same::dimension_type, Dim>::type { }; @@ -1246,7 +1248,7 @@ namespace units * - An exponent representing factors of PI required by the conversion. (e.g. `std::ratio<-1>` for a * radians to degrees conversion) * - a ratio representing a datum translation required for the conversion (e.g. `std::ratio<32>` for a - * farenheit to celsius conversion) + * Fahrenheit to Celsius conversion) * * Typically, a specific conversion factor, like `meters`, * would be implemented as a strong type alias of `conversion_factor`, i.e. @@ -1325,9 +1327,8 @@ namespace units template struct inverse_impl { - using type = - conversion_factor, dimension_pow>, - std::ratio_multiply>>; // inverses are rates or changes, so translation factor is removed. + using type = conversion_factor, dimension_pow>, + std::ratio_multiply>>; // inverses are rates or changes, so translation factor is removed. }; } // namespace detail /** @endcond */ // END DOXYGEN IGNORE @@ -1353,8 +1354,7 @@ namespace units struct squared_impl { using Conversion = typename Cf::conversion_ratio; - using type = conversion_factor, - dimension_pow, std::ratio<2>>, + using type = conversion_factor, dimension_pow, std::ratio<2>>, std::ratio_multiply>, typename Cf::translation_ratio>; }; } // namespace detail @@ -1382,8 +1382,7 @@ namespace units { using Conversion = typename Cf::conversion_ratio; using type = conversion_factor>, - dimension_pow, std::ratio<3>>, - std::ratio_multiply>, typename Cf::translation_ratio>; + dimension_pow, std::ratio<3>>, std::ratio_multiply>, typename Cf::translation_ratio>; }; } // namespace detail /** @endcond */ // END DOXYGEN IGNORE @@ -1583,8 +1582,8 @@ namespace units struct sqrt_impl { using Conversion = typename Unit::conversion_ratio; - using type = conversion_factor, dimension_root, std::ratio<2>>, - std::ratio_divide>, typename Unit::translation_ratio>; + using type = conversion_factor, dimension_root, std::ratio<2>>, + std::ratio_divide>, typename Unit::translation_ratio>; }; } // namespace detail /** @endcond */ // END DOXYGEN IGNORE @@ -1607,7 +1606,7 @@ namespace units * error. This value should be chosen to be as high as possible before * integer overflow errors occur in the compiler. * @note USE WITH CAUTION. The is an approximate value. In general, square> != meter, - * i.e. the operation is not reversible, and it will result in propogated approximations. + * i.e. the operation is not reversible, and it will result in propagated approximations. * Use only when absolutely necessary. */ template @@ -1746,8 +1745,8 @@ namespace units * @sa is_same_dimension_unit */ template - struct is_same_dimension_conversion_factor : std::conjunction::dimension_type>, - dimension_of_t::dimension_type>>> + struct is_same_dimension_conversion_factor + : std::conjunction::dimension_type>, dimension_of_t::dimension_type>>> { }; @@ -1800,8 +1799,7 @@ namespace units const FloatingPoint x(x_); - return x >= 0 && x < std::numeric_limits::infinity() ? Detail::sqrtNewtonRaphson(x, x, FloatingPoint(0)) - : std::numeric_limits::quiet_NaN(); + return x >= 0 && x < std::numeric_limits::infinity() ? Detail::sqrtNewtonRaphson(x, x, FloatingPoint(0)) : std::numeric_limits::quiet_NaN(); } /** @cond */ // DOXYGEN IGNORE @@ -1889,12 +1887,13 @@ namespace units /** * @brief Tag for `unit` constructors - * @details Tag to disambiguates the `unit` constructor whose value argument is already linearized. + * @details Tag to disambiguate the `unit` constructor whose value argument is already linearized. */ struct linearized_value_t { explicit linearized_value_t() = default; }; + inline constexpr linearized_value_t linearized_value{}; /** @@ -1913,8 +1912,8 @@ namespace units * @param[in] value Arithmetic value to convert. * The value should represent a quantity in units of `ConversionFactorFrom`. * @tparam To type of the converted unit value. Shall be an arithmetic type. - * @returns value, converted from units of `ConverionFactorFrom` to `ConverionFactorTo`. - * The value represents a quantity in units of `ConverionFactorTo`. + * @returns value, converted from units of `ConversionFactorFrom` to `ConversionFactorTo`. + * The value represents a quantity in units of `ConversionFactorTo`. */ template requires(traits::is_same_dimension_conversion_factor_v) @@ -1923,8 +1922,7 @@ namespace units using Ratio = std::ratio_divide; using PiRatio = std::ratio_subtract; using Translation = - std::ratio_divide, - typename ConversionFactorTo::conversion_ratio>; + std::ratio_divide, typename ConversionFactorTo::conversion_ratio>; [[maybe_unused]] constexpr auto normal_convert = [](const T0& val) { @@ -1935,10 +1933,9 @@ namespace units [[maybe_unused]] constexpr auto pi_convert = [](const T0& val) { - using ResolvedUnitFrom = conversion_factor; - using ResolvedUnitTo = conversion_factor; + using ResolvedUnitFrom = + conversion_factor; + using ResolvedUnitTo = conversion_factor; return convert>(val); }; @@ -1961,14 +1958,12 @@ namespace units // constexpr pi in denominator else if constexpr (PiRatioValue <= -1 && PiRatio::num % PiRatio::den == 0) { - return static_cast( - normal_convert(static_cast(value) / static_cast(pow(detail::PI_VAL, -PiRatioValue)))); + return static_cast(normal_convert(static_cast(value) / static_cast(pow(detail::PI_VAL, -PiRatioValue)))); } // non-constexpr pi in numerator. This case (only) isn't actually constexpr. else if constexpr (PiRatioValue < 1 && PiRatio::num / PiRatioValue > -1) { - return static_cast( - normal_convert(static_cast(value) * static_cast(std::pow(detail::PI_VAL, PiRatioValue)))); + return static_cast(normal_convert(static_cast(value) * static_cast(std::pow(detail::PI_VAL, PiRatioValue)))); } } // Translation required, no pi variable @@ -1976,16 +1971,14 @@ namespace units { using CommonUnderlying = std::common_type_t; - return static_cast(normal_convert(static_cast(value)) + - (static_cast(Translation::num) / static_cast(Translation::den))); + return static_cast(normal_convert(static_cast(value)) + (static_cast(Translation::num) / static_cast(Translation::den))); } // pi and translation needed else if constexpr (!std::same_as, PiRatio> && !std::same_as, Translation>) { using CommonUnderlying = std::common_type_t; - return static_cast(pi_convert(static_cast(value)) + - (static_cast(Translation::num) / static_cast(Translation::den))); + return static_cast(pi_convert(static_cast(value)) + (static_cast(Translation::num) / static_cast(Translation::den))); } // normal conversion between two different units else @@ -1999,8 +1992,7 @@ namespace units if constexpr (Ratio::num == 1 && Ratio::den != 1) return static_cast(static_cast(value) / static_cast(Ratio::den)); if constexpr (Ratio::num != 1 && Ratio::den != 1) - return static_cast( - (static_cast(value) * static_cast(Ratio::num)) / static_cast(Ratio::den)); + return static_cast((static_cast(value) * static_cast(Ratio::num)) / static_cast(Ratio::den)); } } @@ -2015,8 +2007,7 @@ namespace units template struct delayed_is_same_dimension_conversion_factor : std::false_type { - static constexpr bool value = - traits::is_same_dimension_conversion_factor_v; + static constexpr bool value = traits::is_same_dimension_conversion_factor_v; }; } // namespace detail /** @endcond */ // END DOXYGEN IGNORE @@ -2037,8 +2028,7 @@ namespace units requires same_dimension constexpr UnitTo convert(const UnitFrom& from) noexcept { - return UnitTo(convert(from.to_linearized()), - linearized_value); + return UnitTo(convert(from.to_linearized()), linearized_value); } //------------------------------ @@ -2050,7 +2040,7 @@ namespace units #ifdef FOR_DOXYGEN_PURPOSOES_ONLY /** * @ingroup TypeTraits - * @brief Trait for accessing the publically defined types of `units::unit` + * @brief Trait for accessing the publicly defined types of `units::unit` * @details The units library determines certain properties of the unit types passed to them * and what they represent by using the members of the corresponding unit_traits instantiation. */ @@ -2061,8 +2051,8 @@ namespace units ///< This property is used to enable the proper linear or logarithmic ///< arithmetic functions. typedef typename T::underlying_type underlying_type; ///< Underlying storage type of the `unit`, e.g. `double`. - typedef typename T::value_type value_type; ///< Synonym for underlying type. May be removed in future versions. Prefer underlying_type. - typedef typename T::conversion_factor conversion_factor; ///< Type of unit the `unit` represents, e.g. `meters` + typedef typename T::value_type value_type; ///< Synonym for underlying type. May be removed in future versions. Prefer underlying_type. + typedef typename T::conversion_factor conversion_factor; ///< Type of unit the `unit` represents, e.g. `meters` }; #endif @@ -2102,6 +2092,7 @@ namespace units using value_type = typename T::value_type; using conversion_factor = typename T::conversion_factor; }; + /** @endcond */ // END DOXYGEN IGNORE } // namespace traits @@ -2119,14 +2110,12 @@ namespace units */ template struct is_same_dimension_unit - : std::conjunction, is_unit, - is_same_dimension_conversion_factor::conversion_factor, typename unit_traits::conversion_factor>> + : std::conjunction, is_unit, is_same_dimension_conversion_factor::conversion_factor, typename unit_traits::conversion_factor>> { }; template inline constexpr bool is_same_dimension_unit_v = is_same_dimension_unit::value; - } // namespace traits //---------------------------------- @@ -2150,8 +2139,7 @@ namespace units template struct is_non_truncated_convertible_unit : std::false_type { - static constexpr bool value = - std::ratio_divide::den == 1; + static constexpr bool value = std::ratio_divide::den == 1; }; /** @@ -2170,70 +2158,68 @@ namespace units * @brief SFINAE helper to test if a `conversion_factor` is of the time dimension. */ template - inline constexpr bool is_time_conversion_factor = - traits::is_same_dimension_conversion_factor_v>>; - + inline constexpr bool is_time_conversion_factor = traits::is_same_dimension_conversion_factor_v>>; } // namespace detail /** @endcond */ // END DOXYGEN IGNORE - /** - * @ingroup UnitTypes - * @brief Describes objects that represent quantities of a given unit. - * @details Stores a value which represents a quantity in the given units. Units - * (except dimensionless units) are *not* convertible to arithmetic types, in order to - * provide type safety in dimensional analysis. Units *are* implicitly - * convertible to other units types of the same dimension, if such conversion is lossless. - * Units support various types of arithmetic operations, depending on their scale type. - * - * The value of an `unit` can only be set on construction, or changed by assignment - * from another `unit` type. If necessary, the underlying value can be accessed - * using `operator()`: @code - * meter_t m(5.0); - * double val = m(); // val == 5.0 @endcode. - * @tparam ConversionFactor `conversion_factor` of the represented unit (e.g. meters) - * @tparam T underlying type of the storage. Defaults to `UNIT_LIB_DEFAULT_TYPE`. - * @tparam NumericalScale optional scale class for the units. Defaults to linear (i.e. does - * not scale the unit value). Examples of non-linear scales could be logarithmic, - * decibel, or richter scales. Numerical scales must adhere to the numerical-scale - * concept, i.e. `is_numerical_scale_v<...>` must be `true`. - * @sa - * - \ref lengthUnits "length units" - * - \ref massUnits "mass units" - * - \ref timeUnits "time units" - * - \ref angleUnits "angle units" - * - \ref currentUnits "current units" - * - \ref temperatureUnits "temperature units" - * - \ref substanceUnits "substance units" - * - \ref luminousIntensityUnits "luminous intensity units" - * - \ref solidAngleUnits "solid angle units" - * - \ref frequencyUnits "frequency units" - * - \ref velocityUnits "velocity units" - * - \ref angularVelocityUnits "angular velocity units" - * - \ref accelerationUnits "acceleration units" - * - \ref forceUnits "force units" - * - \ref pressureUnits "pressure units" - * - \ref chargeUnits "charge units" - * - \ref energyUnits "energy units" - * - \ref powerUnits "power units" - * - \ref voltageUnits "voltage units" - * - \ref capacitanceUnits "capacitance units" - * - \ref impedanceUnits "impedance units" - * - \ref magneticFluxUnits "magnetic flux units" - * - \ref magneticFieldStrengthUnits "magnetic field strength units" - * - \ref inductanceUnits "inductance units" - * - \ref luminousFluxUnits "luminous flux units" - * - \ref illuminanceUnits "illuminance units" - * - \ref radiationUnits "radiation units" - * - \ref torqueUnits "torque units" - * - \ref areaUnits "area units" - * - \ref volumeUnits "volume units" - * - \ref densityUnits "density units" - * - \ref concentrationUnits "concentration units" - * - \ref constantUnits "constant units" - */ + /** + * @ingroup UnitTypes + * @brief Describes objects that represent quantities of a given unit. + * @details Stores a value which represents a quantity in the given units. Units + * (except dimensionless units) are *not* convertible to arithmetic types, in order to + * provide type safety in dimensional analysis. Units *are* implicitly + * convertible to other units types of the same dimension, if such conversion is lossless. + * Units support various types of arithmetic operations, depending on their scale type. + * + * The value of an `unit` can only be set on construction, or changed by assignment + * from another `unit` type. If necessary, the underlying value can be accessed + * using `operator()`: @code + * meter_t m(5.0); + * double val = m(); // val == 5.0 @endcode. + * @tparam ConversionFactor `conversion_factor` of the represented unit (e.g. meters) + * @tparam T underlying type of the storage. Defaults to `UNIT_LIB_DEFAULT_TYPE`. + * @tparam NumericalScale optional scale class for the units. Defaults to linear (i.e. does + * not scale the unit value). Examples of non-linear scales could be logarithmic, + * decibel, or richter scales. Numerical scales must adhere to the numerical-scale + * concept, i.e. `is_numerical_scale_v<...>` must be `true`. + * @sa + * - \ref lengthUnits "length units" + * - \ref massUnits "mass units" + * - \ref timeUnits "time units" + * - \ref angleUnits "angle units" + * - \ref currentUnits "current units" + * - \ref temperatureUnits "temperature units" + * - \ref substanceUnits "substance units" + * - \ref luminousIntensityUnits "luminous intensity units" + * - \ref solidAngleUnits "solid angle units" + * - \ref frequencyUnits "frequency units" + * - \ref velocityUnits "velocity units" + * - \ref angularVelocityUnits "angular velocity units" + * - \ref accelerationUnits "acceleration units" + * - \ref forceUnits "force units" + * - \ref pressureUnits "pressure units" + * - \ref chargeUnits "charge units" + * - \ref energyUnits "energy units" + * - \ref powerUnits "power units" + * - \ref voltageUnits "voltage units" + * - \ref capacitanceUnits "capacitance units" + * - \ref impedanceUnits "impedance units" + * - \ref magneticFluxUnits "magnetic flux units" + * - \ref magneticFieldStrengthUnits "magnetic field strength units" + * - \ref inductanceUnits "inductance units" + * - \ref luminousFluxUnits "luminous flux units" + * - \ref illuminanceUnits "illuminance units" + * - \ref radiationUnits "radiation units" + * - \ref torqueUnits "torque units" + * - \ref areaUnits "area units" + * - \ref volumeUnits "volume units" + * - \ref densityUnits "density units" + * - \ref concentrationUnits "concentration units" + * - \ref constantUnits "constant units" + */ #ifdef _WIN32 -// Microsoft compiler requires explicit activation of empty base class optimization -// so that sizeof(unit<..., double, ...>) == sizeof(double) + // Microsoft compiler requires explicit activation of empty base class optimization + // so that sizeof(unit<..., double, ...>) == sizeof(double) #define MSVC_EBO __declspec(empty_bases) #else #define MSVC_EBO @@ -2259,6 +2245,18 @@ namespace units */ constexpr unit(const unit&) = default; + /** + * @brief converting constructor + * @details performs implicit unit conversions if required. + * @param[in] rhs unit to copy. + */ + template NsRhs> + requires traits::is_same_dimension_unit_v, unit> && detail::is_losslessly_convertible_unit, unit> + constexpr unit(const unit& rhs) noexcept + : linearized_value(units::convert(rhs).linearized_value) + { + } + /** * @brief constructor * @details constructs a new unit with `value`. @@ -2266,7 +2264,8 @@ namespace units */ template requires(!traits::is_dimensionless_unit::value && detail::is_losslessly_convertible) - explicit constexpr unit(Ty value) noexcept : linearized_value(NumericalScale::linearize(static_cast(value))) + explicit constexpr unit(Ty value) noexcept + : linearized_value(NumericalScale::linearize(static_cast(value))) { } @@ -2277,7 +2276,8 @@ namespace units */ template requires detail::is_losslessly_convertible - explicit constexpr unit(Ty value, linearized_value_t) noexcept : linearized_value(value) + explicit constexpr unit(Ty value, linearized_value_t) noexcept + : linearized_value(value) { } @@ -2286,9 +2286,10 @@ namespace units * @details enable implicit conversions from T types ONLY for linear dimensionless units * @param[in] value value of the unit */ - template - requires traits::is_dimensionless_unit::value && detail::is_losslessly_convertible - constexpr unit(Ty value) noexcept : linearized_value(NumericalScale::linearize(static_cast(value))) + template + requires traits::is_dimensionless_unit::value && detail::is_losslessly_convertible + constexpr unit(Ty value) noexcept + : linearized_value(NumericalScale::linearize(static_cast(value))) { } @@ -2297,24 +2298,13 @@ namespace units * @details enable implicit conversions from std::chrono::duration types ONLY for time units * @param[in] value value of the unit */ - template - requires detail::is_time_conversion_factor && detail::is_losslessly_convertible + template + requires detail::is_time_conversion_factor && detail::is_losslessly_convertible constexpr unit(const std::chrono::duration& value) noexcept : linearized_value(units::convert(units::unit, Rep>(value.count())).linearized_value) { } - /** - * @brief converting constructor - * @details performs implicit unit conversions if required. - * @param[in] rhs unit to copy. - */ - template NsRhs> - requires detail::is_losslessly_convertible_unit, unit> - constexpr unit(const unit& rhs) noexcept : linearized_value(units::convert(rhs).linearized_value) - { - } - /** * @brief default assignment * @details performs implicit unit conversions if required. @@ -2433,7 +2423,7 @@ namespace units /** * @brief scaled unit value * @details does NOT normalize dimensionless values. - * @returns value of the unit in it's underlying, non-safe type after appliyng the scale. + * @returns value of the unit in it's underlying, non-safe type after applying the scale. * */ constexpr underlying_type raw() const noexcept @@ -2451,9 +2441,9 @@ namespace units constexpr underlying_type value() const noexcept { if constexpr (traits::is_dimensionless_unit::value) - return NumericalScale::scale(units::convert, dimension::dimensionless, - typename traits::conversion_factor_traits::pi_exponent_ratio, - typename traits::conversion_factor_traits::translation_ratio>, + return NumericalScale::scale( + units::convert, dimension::dimensionless, typename traits::conversion_factor_traits::pi_exponent_ratio, + typename traits::conversion_factor_traits::translation_ratio>, T, NumericalScale>>(*this) .to_linearized()); else @@ -2521,8 +2511,7 @@ namespace units { // this conversion also resolves any PI exponents, by converting from a non-zero PI ratio to a zero-pi // ratio. - return NumericalScale::scale( - units::convert, dimension::dimensionless>, Ty, NumericalScale>>(*this).to_linearized()); + return NumericalScale::scale(units::convert, dimension::dimensionless>, Ty, NumericalScale>>(*this).to_linearized()); } /** @@ -2673,8 +2662,7 @@ namespace units } else { - std::string s = detail::to_string( - std::conditional_t, BaseUnit>, BaseUnit, PromotedBaseUnit>(obj).raw()); + std::string s = detail::to_string(std::conditional_t, BaseUnit>, BaseUnit, PromotedBaseUnit>(obj).raw()); using DimType = traits::dimension_of_t; if constexpr (!DimType::empty) @@ -2719,11 +2707,10 @@ namespace std template struct common_type, units::unit> : std::enable_if, - units::unit, - units::traits::dimension_of_t, - units::detail::ratio_gcd, - units::detail::ratio_gcd>>, + units::unit< + units::traits::strong_t, + units::traits::dimension_of_t, units::detail::ratio_gcd, + units::detail::ratio_gcd>>, common_type_t, NumericalScale>> { }; @@ -2776,6 +2763,7 @@ namespace std : common_type, units::unit> { }; + /** @endcond */ // END DOXYGEN IGNORE } // namespace std @@ -2841,7 +2829,6 @@ namespace units template inline constexpr bool has_decibel_scale_v = has_decibel_scale::value; - } // namespace traits //---------------------------------- @@ -2859,7 +2846,7 @@ namespace units /** * @brief numerical scale which is linear * @details Represents a linear numerical scale. This is the appropriate unit scale for almost - * all units almost all of the time. + * all units almost all the time. * @sa unit */ struct linear_scale @@ -2878,7 +2865,7 @@ namespace units /** * @brief scales `value` - * @tparam T underlying type of an unit + * @tparam T underlying type of unit * @tparam[in] value value to scale * @returns `value` */ @@ -3060,8 +3047,7 @@ namespace units /// converted to built-in types. template requires(traits::has_linear_scale_v) - constexpr traits::replace_underlying_t> operator+( - const UnitTypeLhs& lhs, T rhs) noexcept + constexpr traits::replace_underlying_t> operator+(const UnitTypeLhs& lhs, T rhs) noexcept { // Apply any necessary scale factor to T using multiplication for lossless conversion // for non-scaled dimensionless units it's a no-op @@ -3074,8 +3060,7 @@ namespace units /// converted to built-in types. template requires(traits::has_linear_scale_v) - constexpr traits::replace_underlying_t> operator+( - T lhs, const UnitTypeRhs& rhs) noexcept + constexpr traits::replace_underlying_t> operator+(T lhs, const UnitTypeRhs& rhs) noexcept { // Apply any necessary scale factor to T using multiplication for lossless conversion // for non-scaled dimensionless units it's a no-op @@ -3097,8 +3082,7 @@ namespace units /// converted to built-in types. template requires(traits::has_linear_scale_v) - constexpr traits::replace_underlying_t> operator-( - const UnitTypeLhs& lhs, T rhs) noexcept + constexpr traits::replace_underlying_t> operator-(const UnitTypeLhs& lhs, T rhs) noexcept { // Apply any necessary scale factor to T using multiplication for lossless conversion // for non-scaled dimensionless units it's a no-op @@ -3111,8 +3095,7 @@ namespace units /// converted to built-in types. template requires(traits::has_linear_scale_v) - constexpr traits::replace_underlying_t> operator-( - T lhs, const UnitTypeRhs& rhs) noexcept + constexpr traits::replace_underlying_t> operator-(T lhs, const UnitTypeRhs& rhs) noexcept { // Apply any necessary scale factor to T using multiplication for lossless conversion // for non-scaled dimensionless units it's a no-op @@ -3139,8 +3122,7 @@ namespace units template requires(!same_dimension && traits::has_linear_scale_v) constexpr auto operator*(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept - -> unit::conversion_factor, - typename traits::unit_traits::conversion_factor>>, + -> unit::conversion_factor, typename traits::unit_traits::conversion_factor>>, std::common_type_t> { using CompoundUnit = decltype(lhs * rhs); @@ -3151,8 +3133,8 @@ namespace units /// Multiplication by a dimensionless unit for unit types with a linear scale. template requires(traits::has_linear_scale_v) - constexpr traits::replace_underlying_t> - operator*(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept + constexpr traits::replace_underlying_t> operator*( + const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept { using CommonUnit = decltype(lhs * rhs); // the cast makes sure factors of PI are handled as expected @@ -3162,8 +3144,8 @@ namespace units /// Multiplication by a dimensionless unit for unit types with a linear scale. template requires(traits::has_linear_scale_v) - constexpr traits::replace_underlying_t> - operator*(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept + constexpr traits::replace_underlying_t> operator*( + const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept { using CommonUnit = decltype(lhs * rhs); // the cast makes sure factors of PI are handled as expected @@ -3173,8 +3155,7 @@ namespace units /// Multiplication by an arithmetic type for dimensioned unit types with a linear scale. template requires(traits::has_linear_scale_v) - constexpr traits::replace_underlying_t> operator*( - const UnitTypeLhs& lhs, T rhs) noexcept + constexpr traits::replace_underlying_t> operator*(const UnitTypeLhs& lhs, T rhs) noexcept { using CommonUnit = decltype(lhs * rhs); return CommonUnit(CommonUnit(lhs).raw() * rhs); @@ -3183,8 +3164,7 @@ namespace units /// Multiplication by an arithmetic type for dimensioned unit types with a linear scale. template requires(traits::has_linear_scale_v) - constexpr traits::replace_underlying_t> operator*( - T lhs, const UnitTypeRhs& rhs) noexcept + constexpr traits::replace_underlying_t> operator*(T lhs, const UnitTypeRhs& rhs) noexcept { using CommonUnit = decltype(lhs * rhs); return CommonUnit(lhs * CommonUnit(rhs).raw()); @@ -3193,8 +3173,7 @@ namespace units /// Multiplication by an arithmetic type for dimensionless unit types with a linear scale. template requires(traits::has_linear_scale_v) - constexpr traits::replace_underlying_t> operator*( - const UnitTypeLhs& lhs, T rhs) noexcept + constexpr traits::replace_underlying_t> operator*(const UnitTypeLhs& lhs, T rhs) noexcept { using CommonUnit = decltype(lhs * rhs); return CommonUnit(lhs.raw() * rhs); @@ -3203,8 +3182,7 @@ namespace units /// Multiplication by an arithmetic type for dimensionless unit types with a linear scale. template requires(traits::has_linear_scale_v) - constexpr traits::replace_underlying_t> operator*( - T lhs, const UnitTypeRhs& rhs) noexcept + constexpr traits::replace_underlying_t> operator*(T lhs, const UnitTypeRhs& rhs) noexcept { using CommonUnit = decltype(lhs * rhs); return CommonUnit(lhs * rhs.raw()); @@ -3214,8 +3192,7 @@ namespace units /// dimensionless template requires(same_dimension && traits::has_linear_scale_v) - constexpr dimensionless> operator/( - const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept + constexpr dimensionless> operator/(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept { using CommonUnit = std::common_type_t; return CommonUnit(lhs).raw() / CommonUnit(rhs).raw(); @@ -3226,8 +3203,7 @@ namespace units template requires(!same_dimension && traits::has_linear_scale_v) constexpr auto operator/(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept - -> unit::conversion_factor, - inverse::conversion_factor>>>, + -> unit::conversion_factor, inverse::conversion_factor>>>, std::common_type_t> { using CompoundUnit = decltype(lhs / rhs); @@ -3238,8 +3214,8 @@ namespace units /// Division by a dimensionless unit for unit types with a linear scale template requires(traits::has_linear_scale_v) - constexpr traits::replace_underlying_t> - operator/(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept + constexpr traits::replace_underlying_t> operator/( + const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept { using CommonUnit = decltype(lhs / rhs); using CommonUnderlying = typename CommonUnit::underlying_type; @@ -3249,9 +3225,8 @@ namespace units /// Division of a dimensionless unit by a unit type with a linear scale template requires(traits::has_linear_scale_v && traits::is_dimensionless_unit_v) - constexpr auto operator/(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept - -> unit::conversion_factor>>, - std::common_type_t> + constexpr auto operator/(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept -> unit::conversion_factor>>, + std::common_type_t> { using CommonUnit = decltype(lhs / rhs); using CommonUnderlying = typename CommonUnit::underlying_type; @@ -3261,8 +3236,7 @@ namespace units /// Division by a dimensionless for unit types with a linear scale template requires(traits::has_linear_scale_v) - constexpr traits::replace_underlying_t> operator/( - const UnitTypeLhs& lhs, T rhs) noexcept + constexpr traits::replace_underlying_t> operator/(const UnitTypeLhs& lhs, T rhs) noexcept { using CommonUnit = decltype(lhs / rhs); return CommonUnit(CommonUnit(lhs).raw() / rhs); @@ -3272,8 +3246,7 @@ namespace units template requires(traits::has_linear_scale_v) constexpr auto operator/(T lhs, const UnitTypeRhs& rhs) noexcept - -> unit::conversion_factor>>, - std::common_type_t> + -> unit::conversion_factor>>, std::common_type_t> { using InverseUnit = decltype(lhs / rhs); using UnitConversion = typename traits::unit_traits::conversion_factor; @@ -3286,8 +3259,7 @@ namespace units /// is their common type template requires(same_dimension && traits::has_linear_scale_v) - constexpr traits::replace_underlying_t::underlying_type> operator%( - const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept + constexpr traits::replace_underlying_t::underlying_type> operator%(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept { using CommonUnit = decltype(lhs % rhs); return CommonUnit(CommonUnit(lhs).raw() % CommonUnit(rhs).raw()); @@ -3296,8 +3268,8 @@ namespace units /// Modulo by a dimensionless for unit types with a linear scale template requires(traits::has_linear_scale_v) - constexpr traits::replace_underlying_t> - operator%(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept + constexpr traits::replace_underlying_t> operator%( + const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept { using CommonUnit = decltype(lhs % rhs); using CommonUnderlying = typename CommonUnit::underlying_type; @@ -3308,8 +3280,7 @@ namespace units /// @returns the lhs value modulo the rhs value, whose type is their common type template requires(same_dimension && traits::has_linear_scale_v) - constexpr traits::replace_underlying_t::underlying_type> operator%( - const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept + constexpr traits::replace_underlying_t::underlying_type> operator%(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept { using CommonUnit = decltype(lhs % rhs); return CommonUnit(lhs.raw() % rhs.raw()); @@ -3318,8 +3289,7 @@ namespace units /// Modulo by an arithmetic type for unit types with a linear scale template requires(traits::has_linear_scale_v) - constexpr traits::replace_underlying_t> operator%( - const UnitTypeLhs& lhs, const T& rhs) noexcept + constexpr traits::replace_underlying_t> operator%(const UnitTypeLhs& lhs, const T& rhs) noexcept { using CommonUnit = decltype(lhs % rhs); return CommonUnit(CommonUnit(lhs).raw() % rhs); @@ -3459,6 +3429,7 @@ namespace units { typedef U type; }; + template struct power_of_unit<0, U> { @@ -3477,9 +3448,8 @@ namespace units */ template requires(traits::has_linear_scale_v) - constexpr auto pow(const UnitType& value) noexcept - -> unit::conversion_factor>::type>, - detail::floating_point_promotion_t::underlying_type>, linear_scale> + constexpr auto pow(const UnitType& value) noexcept -> unit::conversion_factor>::type>, + detail::floating_point_promotion_t::underlying_type>, linear_scale> { return decltype(units::pow(value))(pow(value.raw())); } @@ -3497,7 +3467,7 @@ namespace units { /** * @brief linearizes `value` - * @tparam T underlying type of an unit + * @tparam T underlying type of unit * @tparam[in] value value to linearize * @returns `std::pow(10, value / 10)` */ @@ -3509,7 +3479,7 @@ namespace units /** * @brief returns `value` in dB - * @tparam T underlying type of an unit + * @tparam T underlying type of unit * @tparam[in] value value to scale * @returns `10 * std::log10(value)` */ @@ -3562,8 +3532,8 @@ namespace units /// Addition between unit types with a decibel_scale and dimensionless dB units template requires(traits::has_decibel_scale_v) - constexpr traits::replace_underlying_t> - operator+(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept + constexpr traits::replace_underlying_t> operator+( + const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept { using CommonUnit = decltype(lhs + rhs); return CommonUnit(lhs.to_linearized() * rhs.to_linearized(), linearized_value); @@ -3572,8 +3542,8 @@ namespace units /// Addition between unit types with a decibel_scale and dimensionless dB units template requires(traits::has_decibel_scale_v) - constexpr traits::replace_underlying_t> - operator+(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept + constexpr traits::replace_underlying_t> operator+( + const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept { using CommonUnit = decltype(lhs + rhs); return CommonUnit(lhs.to_linearized() * rhs.to_linearized(), linearized_value); @@ -3582,8 +3552,7 @@ namespace units /// Subtraction for convertible unit types with a decibel_scale template requires(same_dimension && traits::has_decibel_scale_v) - constexpr auto operator-(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept - -> decibels::underlying_type> + constexpr auto operator-(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept -> decibels::underlying_type> { using Dimensionless = decltype(lhs - rhs); using CommonUnit = std::common_type_t; @@ -3594,8 +3563,8 @@ namespace units /// Subtraction between unit types with a decibel_scale and dimensionless dB units template requires(traits::has_decibel_scale_v) - constexpr traits::replace_underlying_t> - operator-(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept + constexpr traits::replace_underlying_t> operator-( + const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept { using CommonUnit = decltype(lhs - rhs); return CommonUnit(lhs.to_linearized() / rhs.to_linearized(), linearized_value); @@ -3604,9 +3573,8 @@ namespace units /// Subtraction between unit types with a decibel_scale and dimensionless dB units template requires(traits::has_decibel_scale_v) - constexpr auto operator-(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept - -> unit::conversion_factor>>, - std::common_type_t, decibel_scale> + constexpr auto operator-(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept -> unit::conversion_factor>>, + std::common_type_t, decibel_scale> { using InverseUnit = decltype(lhs - rhs); return InverseUnit(lhs.to_linearized() / rhs.to_linearized(), linearized_value); @@ -3784,8 +3752,8 @@ namespace units */ template requires(traits::has_linear_scale_v) - constexpr auto sqrt(const UnitType& value) noexcept -> unit::conversion_factor>>, - detail::floating_point_promotion_t::underlying_type>> + constexpr auto sqrt(const UnitType& value) noexcept + -> unit::conversion_factor>>, detail::floating_point_promotion_t::underlying_type>> { return decltype(units::sqrt(value))(sqrt(value.value())); } @@ -4001,8 +3969,8 @@ namespace units * @returns The result of x*y+z */ template - requires(traits::is_same_dimension_conversion_factor_v::conversion_factor, - typename traits::unit_traits::conversion_factor>, + requires(traits::is_same_dimension_conversion_factor_v< + compound_conversion_factor::conversion_factor, typename traits::unit_traits::conversion_factor>, typename traits::unit_traits::conversion_factor>) constexpr auto fma(const UnitTypeLhs x, const UnitMultiply y, const UnitAdd z) noexcept -> std::common_type_t(x) * detail::floating_point_promotion_t(y)), UnitAdd> @@ -4045,7 +4013,6 @@ namespace units { return std::isunordered(lhs.value(), rhs.value()); } - } // end namespace units //---------------------------------------------------------------------------------------------------------------------- @@ -4086,38 +4053,47 @@ namespace std { return units::unit(std::numeric_limits::min()); } + static constexpr units::unit denorm_min() noexcept { return units::unit(std::numeric_limits::denorm_min()); } + static constexpr units::unit max() { return units::unit(std::numeric_limits::max()); } + static constexpr units::unit lowest() { return units::unit(std::numeric_limits::lowest()); } + static constexpr units::unit epsilon() { return units::unit(std::numeric_limits::epsilon()); } + static constexpr units::unit round_error() { return units::unit(std::numeric_limits::round_error()); } + static constexpr units::unit infinity() { return units::unit(std::numeric_limits::infinity()); } + static constexpr units::unit quiet_NaN() { return units::unit(std::numeric_limits::quiet_NaN()); } + static constexpr units::unit signaling_NaN() { return units::unit(std::numeric_limits::signaling_NaN()); } + static constexpr bool is_specialized = std::numeric_limits::is_specialized; static constexpr bool is_signed = std::numeric_limits::is_signed; static constexpr bool is_integer = std::numeric_limits::is_integer; @@ -4150,69 +4126,51 @@ namespace std // UNIT DEDUCTION GUIDES //------------------------------ -namespace units { - - // Concept to ensure we only apply the dimensionless fallback - // to a pure, unmodified dimensionless unit. - template - concept PureDimensionlessCF = - std::is_same_v && - std::ratio_equal_v> && - std::ratio_equal_v> && - std::ratio_equal_v>; - - // 1) chrono deduction guide - template - unit(std::chrono::duration) -> unit, Rep>; - - // 2) Dimensionless fallback: - // Only applies if the source is exactly the base dimensionless unit. - template - requires( - traits::is_unit_v> && - PureDimensionlessCF - ) - unit(const unit&) -> unit, dimension::dimensionless>, SourceTy>; - - // 3) Lossless integral conversion: - // For dimensionally compatible units where the conversion is integral and lossless. - // This applies only if is_losslessly_convertible_unit is true. - template - requires( - traits::is_unit_v> && - traits::is_conversion_factor_v && - traits::is_same_dimension_conversion_factor_v && - !std::is_same_v && - detail::is_losslessly_convertible_unit, unit> - ) - unit(const unit&) -> unit; - - // 4) Non-lossless conversions: - // For dimensionally compatible units where integral conversion is not possible. - // Falls back to floating point. - template - requires( - traits::is_unit_v> && - traits::is_conversion_factor_v && - traits::is_same_dimension_conversion_factor_v && - !std::is_same_v && - !detail::is_losslessly_convertible_unit, unit> - ) - unit(const unit&) -> unit>; - - // 5) Exact matches: - // If the unit already matches `unit`, use it directly. - template - requires traits::is_unit_v> - unit(const unit&) -> unit; - - // 6) Deduce type from arithmetic type (dimensionless by default) - template>> - unit(T) -> unit; - +namespace units +{ + // Concept to ensure we only apply the dimensionless fallback + // to a pure, unmodified dimensionless unit. + template + concept PureDimensionlessCF = std::is_same_v && std::ratio_equal_v> && + std::ratio_equal_v> && std::ratio_equal_v>; + + // 1) chrono deduction guide + template + unit(std::chrono::duration) -> unit, Rep>; + + // 2) Dimensionless fallback: + // Only applies if the source is exactly the base dimensionless unit. + template + requires(traits::is_unit_v> && PureDimensionlessCF) + unit(const unit&) -> unit, dimension::dimensionless>, SourceTy>; + + // 3) Lossless integral conversion: + // For dimensionally compatible units where the conversion is integral and lossless. + // This applies only if is_losslessly_convertible_unit is true. + template + requires(traits::is_unit_v> && traits::is_conversion_factor_v && traits::is_same_dimension_conversion_factor_v && + !std::is_same_v && detail::is_losslessly_convertible_unit, unit>) + unit(const unit&) -> unit; + + // 4) Non-lossless conversions: + // For dimensionally compatible units where integral conversion is not possible. + // Falls back to floating point. + template + requires(traits::is_unit_v> && traits::is_conversion_factor_v && traits::is_same_dimension_conversion_factor_v && + !std::is_same_v && !detail::is_losslessly_convertible_unit, unit>) + unit(const unit&) -> unit>; + + // 5) Exact matches: + // If the unit already matches `unit`, use it directly. + template + requires traits::is_unit_v> + unit(const unit&) -> unit; + + // 6) Deduce type from arithmetic type (dimensionless by default) + template>> + unit(T) -> unit; } // namespace units - //---------------------------------------------------------------------------------------------------------------------- // JSON SUPPORT //---------------------------------------------------------------------------------------------------------------------- diff --git a/include/units/current.h b/include/units/current.h index 9b759672..e2168f9a 100644 --- a/include/units/current.h +++ b/include/units/current.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_current_h__ -#define units_current_h__ +#ifndef units_current_h_ +#define units_current_h_ #include @@ -63,4 +63,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(current) } // namespace units -#endif // units_current_h__ +#endif // units_current_h_ \ No newline at end of file diff --git a/include/units/data.h b/include/units/data.h index 53b328df..5dbf3378 100644 --- a/include/units/data.h +++ b/include/units/data.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_data_h__ -#define units_data_h__ +#ifndef units_data_h_ +#define units_data_h_ #include @@ -66,4 +66,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(data) } // namespace units -#endif // units_data_h__ +#endif // units_data_h_ \ No newline at end of file diff --git a/include/units/data_transfer_rate.h b/include/units/data_transfer_rate.h index e69c2b03..7f782513 100644 --- a/include/units/data_transfer_rate.h +++ b/include/units/data_transfer_rate.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_data_transfer_rate_h__ -#define units_data_transfer_rate_h__ +#ifndef units_data_transfer_rate_h_ +#define units_data_transfer_rate_h_ #include @@ -66,4 +66,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(data_transfer_rate) } // namespace units -#endif // units_data_transfer_rate_h__ \ No newline at end of file +#endif // units_data_transfer_rate_h_ \ No newline at end of file diff --git a/include/units/density.h b/include/units/density.h index e2eef197..85982a24 100644 --- a/include/units/density.h +++ b/include/units/density.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_density_h__ -#define units_density_h__ +#ifndef units_density_h_ +#define units_density_h_ #include #include @@ -73,4 +73,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(density) } // namespace units -#endif // units_density_h__ +#endif // units_density_h_ \ No newline at end of file diff --git a/include/units/energy.h b/include/units/energy.h index 03f7a54f..994fa091 100644 --- a/include/units/energy.h +++ b/include/units/energy.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_energy_h__ -#define units_energy_h__ +#ifndef units_energy_h_ +#define units_energy_h_ #include @@ -71,4 +71,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(energy) } // namespace units -#endif // units_energy_h__ +#endif // units_energy_h_ \ No newline at end of file diff --git a/include/units/energy_density.h b/include/units/energy_density.h new file mode 100644 index 00000000..a86b67fa --- /dev/null +++ b/include/units/energy_density.h @@ -0,0 +1,67 @@ +//-------------------------------------------------------------------------------------------------- +// +// UnitConversion: A compile-time c++14 unit conversion library with no dependencies +// +//-------------------------------------------------------------------------------------------------- +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software +// and associated documentation files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//-------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2016 Nic Holthaus +// +//-------------------------------------------------------------------------------------------------- +// +// ATTRIBUTION: +// Parts of this work have been adapted from: +// http://stackoverflow.com/questions/35069778/create-comparison-trait-for-template-classes-whose-parameters-are-in-a-different +// http://stackoverflow.com/questions/28253399/check-traits-for-all-variadic-template-arguments/28253503 +// http://stackoverflow.com/questions/36321295/rational-approximation-of-square-root-of-stdratio-at-compile-time?noredirect=1#comment60266601_36321295 +// https://github.com/swatanabe/cppnow17-units +// +//-------------------------------------------------------------------------------------------------- +// +/// @file units/energy_density.h +/// @brief units representing energy density values +// +//-------------------------------------------------------------------------------------------------- + +#pragma once + +#ifndef units_energy_density_h_ +#define units_energy_density_h_ + +#include + +namespace units +{ + /** + * @namespace units::energy_density + * @brief namespace for unit types and containers representing energy_density values + * @note Energy per unit volume has the same physical units as pressure, and in many situations is synonymous. + * For example, the energy density of a magnetic field may be expressed as and + * behaves like a physical pressure. + * @anchor energy_densityContainers + * @sa See unit for more information on unit type containers. + */ + UNIT_ADD_WITH_METRIC_PREFIXES(energy_density, joules_per_meter_cubed, Jpm3, pascals_) + + UNIT_ADD_DIMENSION_TRAIT(energy_density) +} // namespace units + +#endif // units_energy_density_h_ \ No newline at end of file diff --git a/include/units/force.h b/include/units/force.h index 13602ffa..944e7999 100644 --- a/include/units/force.h +++ b/include/units/force.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_force_h__ -#define units_force_h__ +#ifndef units_force_h_ +#define units_force_h_ #include #include @@ -70,4 +70,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(force) } // namespace units -#endif // units_force_h__ +#endif // units_force_h_ \ No newline at end of file diff --git a/include/units/frequency.h b/include/units/frequency.h index 65da5c3d..f787d1b0 100644 --- a/include/units/frequency.h +++ b/include/units/frequency.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_frequency_h__ -#define units_frequency_h__ +#ifndef units_frequency_h_ +#define units_frequency_h_ #include @@ -63,4 +63,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(frequency) } // namespace units -#endif // units_frequency_h__ +#endif // units_frequency_h_ \ No newline at end of file diff --git a/include/units/illuminance.h b/include/units/illuminance.h index beb74e51..591ea5ac 100644 --- a/include/units/illuminance.h +++ b/include/units/illuminance.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_illuminance_h__ -#define units_illuminance_h__ +#ifndef units_illuminance_h_ +#define units_illuminance_h_ #include #include @@ -67,4 +67,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(illuminance) } // namespace units -#endif // units_illuminance_h__ +#endif // units_illuminance_h_ \ No newline at end of file diff --git a/include/units/impedance.h b/include/units/impedance.h index 43ceeabb..bed0d34e 100644 --- a/include/units/impedance.h +++ b/include/units/impedance.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_impedance_h__ -#define units_impedance_h__ +#ifndef units_impedance_h_ +#define units_impedance_h_ #include @@ -63,4 +63,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(impedance) } // namespace units -#endif // units_impedance_h__ +#endif // units_impedance_h_ \ No newline at end of file diff --git a/include/units/inductance.h b/include/units/inductance.h index 4edec172..64800b75 100644 --- a/include/units/inductance.h +++ b/include/units/inductance.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_inductance_h__ -#define units_inductance_h__ +#ifndef units_inductance_h_ +#define units_inductance_h_ #include @@ -63,4 +63,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(inductance) } // namespace units -#endif // units_inductance_h__ +#endif // units_inductance_h__ \ No newline at end of file diff --git a/include/units/irradiance.h b/include/units/irradiance.h new file mode 100644 index 00000000..1e8ac7a8 --- /dev/null +++ b/include/units/irradiance.h @@ -0,0 +1,64 @@ +//-------------------------------------------------------------------------------------------------- +// +// UnitConversion: A compile-time c++14 unit conversion library with no dependencies +// +//-------------------------------------------------------------------------------------------------- +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software +// and associated documentation files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//-------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2016 Nic Holthaus +// +//-------------------------------------------------------------------------------------------------- +// +// ATTRIBUTION: +// Parts of this work have been adapted from: +// http://stackoverflow.com/questions/35069778/create-comparison-trait-for-template-classes-whose-parameters-are-in-a-different +// http://stackoverflow.com/questions/28253399/check-traits-for-all-variadic-template-arguments/28253503 +// http://stackoverflow.com/questions/36321295/rational-approximation-of-square-root-of-stdratio-at-compile-time?noredirect=1#comment60266601_36321295 +// https://github.com/swatanabe/cppnow17-units +// +//-------------------------------------------------------------------------------------------------- +// +/// @file units/irradiance.h +/// @brief units representing irradiance values +// +//-------------------------------------------------------------------------------------------------- + +#pragma once + +#ifndef units_irradiance_h_ +#define units_irradiance_h_ + +#include + +namespace units +{ + /** + * @namespace units::irradiance + * @brief namespace for unit types and containers representing irradiance values + * @anchor irradianceContainers + * @sa See unit for more information on unit type containers. + */ + UNIT_ADD_WITH_METRIC_PREFIXES(irradiance, watts_per_meter_squared, Wpm2, conversion_factor, dimension::irradiance>) + + UNIT_ADD_DIMENSION_TRAIT(irradiance) +} // namespace units + +#endif // units_irradiance_h_ \ No newline at end of file diff --git a/include/units/jerk.h b/include/units/jerk.h index 487fe324..6d66f8dc 100644 --- a/include/units/jerk.h +++ b/include/units/jerk.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_jerk_h__ -#define units_jerk_h__ +#ifndef units_jerk_h_ +#define units_jerk_h_ #include #include @@ -71,4 +71,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(jerk) } // namespace units -#endif // units_jerk_h__ +#endif // units_jerk_h_ \ No newline at end of file diff --git a/include/units/length.h b/include/units/length.h index 2cf275b7..bc5f7032 100644 --- a/include/units/length.h +++ b/include/units/length.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_length_h__ -#define units_length_h__ +#ifndef units_length_h_ +#define units_length_h_ #include @@ -84,4 +84,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(length) } // namespace units -#endif // units_length_h__ \ No newline at end of file +#endif // units_length_h_ \ No newline at end of file diff --git a/include/units/luminance.h b/include/units/luminance.h index 8d867ef1..357d52f5 100644 --- a/include/units/luminance.h +++ b/include/units/luminance.h @@ -44,7 +44,7 @@ #pragma once -#ifndef units_luminance_h__ +#ifndef units_luminance_h_ #define units_luminance_h__ #include diff --git a/include/units/luminous_flux.h b/include/units/luminous_flux.h index c8cddf4d..d38543ca 100644 --- a/include/units/luminous_flux.h +++ b/include/units/luminous_flux.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_luminous_flux_h__ -#define units_luminous_flux_h__ +#ifndef units_luminous_flux_h_ +#define units_luminous_flux_h_ #include @@ -63,4 +63,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(luminous_flux) } // namespace units -#endif // units_luminous_flux_h__ +#endif // units_luminous_flux_h_ \ No newline at end of file diff --git a/include/units/luminous_intensity.h b/include/units/luminous_intensity.h index a82a9e5a..1d090e0f 100644 --- a/include/units/luminous_intensity.h +++ b/include/units/luminous_intensity.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_luminous_intensity_h__ -#define units_luminous_intensity_h__ +#ifndef units_luminous_intensity_h_ +#define units_luminous_intensity_h_ #include @@ -63,4 +63,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(luminous_intensity) } // namespace units -#endif // units_luminous_intensity_h__ +#endif // units_luminous_intensity_h_ \ No newline at end of file diff --git a/include/units/magnetic_field_strength.h b/include/units/magnetic_field_strength.h index 7b9c104b..825378bb 100644 --- a/include/units/magnetic_field_strength.h +++ b/include/units/magnetic_field_strength.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_magnetic_field_strength_h__ -#define units_magnetic_field_strength_h__ +#ifndef units_magnetic_field_strength_h_ +#define units_magnetic_field_strength_h_ #include #include @@ -66,4 +66,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(magnetic_field_strength) } // namespace units -#endif // units_magnetic_field_strength_h__ +#endif // units_magnetic_field_strength_h_ \ No newline at end of file diff --git a/include/units/magnetic_flux.h b/include/units/magnetic_flux.h index da1bd626..3a35522a 100644 --- a/include/units/magnetic_flux.h +++ b/include/units/magnetic_flux.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_magnetic_flux_h__ -#define units_magnetic_flux_h__ +#ifndef units_magnetic_flux_h_ +#define units_magnetic_flux_h_ #include @@ -64,4 +64,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(magnetic_flux) } // namespace units -#endif // units_magnetic_flux_h__ +#endif // units_magnetic_flux_h_ \ No newline at end of file diff --git a/include/units/mass.h b/include/units/mass.h index 5c768344..4bc651ad 100644 --- a/include/units/mass.h +++ b/include/units/mass.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_mass_h__ -#define units_mass_h__ +#ifndef units_mass_h_ +#define units_mass_h_ #include @@ -71,4 +71,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(mass) } // namespace units -#endif // units_mass_h__ \ No newline at end of file +#endif // units_mass_h_ \ No newline at end of file diff --git a/include/units/power.h b/include/units/power.h index 5193e104..da59d5d0 100644 --- a/include/units/power.h +++ b/include/units/power.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_power_h__ -#define units_power_h__ +#ifndef units_power_h_ +#define units_power_h_ #include @@ -66,4 +66,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(power) } // namespace units -#endif // units_power_h__ +#endif // units_power_h_ \ No newline at end of file diff --git a/include/units/pressure.h b/include/units/pressure.h index 27fbc88d..0f4ff7c8 100644 --- a/include/units/pressure.h +++ b/include/units/pressure.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_pressure_h__ -#define units_pressure_h__ +#ifndef units_pressure_h_ +#define units_pressure_h_ #ifdef _MSC_VER #pragma push_macro("pascal") @@ -87,6 +87,6 @@ namespace units #if defined(__MINGW64__) || defined(__MINGW32__) # pragma pop_macro("pascal") -#endif // __MINGW64__ or __MINGW32__ +#endif // __MINGW64__ or __MINGW32_ -#endif // units_pressure_h__ +#endif // units_pressure_h_ \ No newline at end of file diff --git a/include/units/radiance.h b/include/units/radiance.h new file mode 100644 index 00000000..369f15a4 --- /dev/null +++ b/include/units/radiance.h @@ -0,0 +1,64 @@ +//-------------------------------------------------------------------------------------------------- +// +// UnitConversion: A compile-time c++14 unit conversion library with no dependencies +// +//-------------------------------------------------------------------------------------------------- +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software +// and associated documentation files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//-------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2016 Nic Holthaus +// +//-------------------------------------------------------------------------------------------------- +// +// ATTRIBUTION: +// Parts of this work have been adapted from: +// http://stackoverflow.com/questions/35069778/create-comparison-trait-for-template-classes-whose-parameters-are-in-a-different +// http://stackoverflow.com/questions/28253399/check-traits-for-all-variadic-template-arguments/28253503 +// http://stackoverflow.com/questions/36321295/rational-approximation-of-square-root-of-stdratio-at-compile-time?noredirect=1#comment60266601_36321295 +// https://github.com/swatanabe/cppnow17-units +// +//-------------------------------------------------------------------------------------------------- +// +/// @file units/radiance.h +/// @brief units representing radiance values +// +//-------------------------------------------------------------------------------------------------- + +#pragma once + +#ifndef units_radiance_h_ +#define units_radiance_h_ + +#include + +namespace units +{ + /** + * @namespace units::radiance + * @brief namespace for unit types and containers representing radiance values + * @anchor radianceContainers + * @sa See unit for more information on unit type containers. + */ + UNIT_ADD_WITH_METRIC_PREFIXES(radiance, watts_per_steradian_per_meter_squared, Wpsrm2, conversion_factor, dimension::radiance>) + + UNIT_ADD_DIMENSION_TRAIT(radiance) +} // namespace units + +#endif // units_radiance_h_ \ No newline at end of file diff --git a/include/units/radiant_intensity.h b/include/units/radiant_intensity.h new file mode 100644 index 00000000..f5d06a2b --- /dev/null +++ b/include/units/radiant_intensity.h @@ -0,0 +1,64 @@ +//-------------------------------------------------------------------------------------------------- +// +// UnitConversion: A compile-time c++14 unit conversion library with no dependencies +// +//-------------------------------------------------------------------------------------------------- +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software +// and associated documentation files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//-------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2016 Nic Holthaus +// +//-------------------------------------------------------------------------------------------------- +// +// ATTRIBUTION: +// Parts of this work have been adapted from: +// http://stackoverflow.com/questions/35069778/create-comparison-trait-for-template-classes-whose-parameters-are-in-a-different +// http://stackoverflow.com/questions/28253399/check-traits-for-all-variadic-template-arguments/28253503 +// http://stackoverflow.com/questions/36321295/rational-approximation-of-square-root-of-stdratio-at-compile-time?noredirect=1#comment60266601_36321295 +// https://github.com/swatanabe/cppnow17-units +// +//-------------------------------------------------------------------------------------------------- +// +/// @file units/radiant_intensity.h +/// @brief units representing radiant intensity values +// +//-------------------------------------------------------------------------------------------------- + +#pragma once + +#ifndef units_radiant_intensity_h_ +#define units_radiant_intensity_h_ + +#include + +namespace units +{ + /** + * @namespace units::radiant_intensity + * @brief namespace for unit types and containers representing radiant intensity values + * @anchor radiant_intensityContainers + * @sa See unit for more information on unit type containers. + */ + UNIT_ADD_WITH_METRIC_PREFIXES(radiant_intensity, watts_per_steradian, Wpsr, conversion_factor, dimension::radiant_intensity>) + + UNIT_ADD_DIMENSION_TRAIT(radiant_intensity) +} // namespace units + +#endif // units_radiant_intensity_h_ \ No newline at end of file diff --git a/include/units/radiation.h b/include/units/radiation.h index 993c42e1..f28e9347 100644 --- a/include/units/radiation.h +++ b/include/units/radiation.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_radiation_h__ -#define units_radiation_h__ +#ifndef units_radiation_h_ +#define units_radiation_h_ #include #include @@ -72,4 +72,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(radioactivity) } // namespace units -#endif // units_radiation_h__ +#endif // units_radiation_h_ \ No newline at end of file diff --git a/include/units/solid_angle.h b/include/units/solid_angle.h index 451dd16e..7692812c 100644 --- a/include/units/solid_angle.h +++ b/include/units/solid_angle.h @@ -43,7 +43,7 @@ #pragma once -#ifndef units_solid_angle_h__ +#ifndef units_solid_angle_h_ #define units_solid_angle_h__ #include @@ -65,4 +65,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(solid_angle) } // namespace units -#endif // units_solid_angle_h__ +#endif // units_solid_angle_h__ \ No newline at end of file diff --git a/include/units/spectral_flux.h b/include/units/spectral_flux.h new file mode 100644 index 00000000..7c7b3241 --- /dev/null +++ b/include/units/spectral_flux.h @@ -0,0 +1,64 @@ +//-------------------------------------------------------------------------------------------------- +// +// UnitConversion: A compile-time c++14 unit conversion library with no dependencies +// +//-------------------------------------------------------------------------------------------------- +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software +// and associated documentation files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//-------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2016 Nic Holthaus +// +//-------------------------------------------------------------------------------------------------- +// +// ATTRIBUTION: +// Parts of this work have been adapted from: +// http://stackoverflow.com/questions/35069778/create-comparison-trait-for-template-classes-whose-parameters-are-in-a-different +// http://stackoverflow.com/questions/28253399/check-traits-for-all-variadic-template-arguments/28253503 +// http://stackoverflow.com/questions/36321295/rational-approximation-of-square-root-of-stdratio-at-compile-time?noredirect=1#comment60266601_36321295 +// https://github.com/swatanabe/cppnow17-units +// +//-------------------------------------------------------------------------------------------------- +// +/// @file units/spectral_flux.h +/// @brief units representing spectral flux values +// +//-------------------------------------------------------------------------------------------------- + +#pragma once + +#ifndef units_spectral_flux_h_ +#define units_spectral_flux_h_ + +#include + +namespace units +{ + /** + * @namespace units::spectral_flux + * @brief namespace for unit types and containers representing spectral_flux values + * @anchor spectral_fluxContainers + * @sa See unit for more information on unit type containers. + */ + UNIT_ADD_WITH_METRIC_PREFIXES(spectral_flux, watts_per_meter, Wpm, conversion_factor, dimension::spectral_flux>) + + UNIT_ADD_DIMENSION_TRAIT(spectral_flux) +} // namespace units + +#endif // units_spectral_flux_h_ \ No newline at end of file diff --git a/include/units/radiometry.h b/include/units/spectral_intensity.h similarity index 69% rename from include/units/radiometry.h rename to include/units/spectral_intensity.h index fc9f5637..a213d51d 100644 --- a/include/units/radiometry.h +++ b/include/units/spectral_intensity.h @@ -36,44 +36,30 @@ // //-------------------------------------------------------------------------------------------------- // -/// @file units/radiometry.h -/// @brief units representing radiometry values +/// @file units/spectral_intensity.h +/// @brief units representing spectral intensity values // //-------------------------------------------------------------------------------------------------- #pragma once -#ifndef units_radiometry_h__ -#define units_radiometry_h__ +#ifndef units_spectral_intensity_h_ +#define units_spectral_intensity_h_ -#include -#include -#include #include #include -#include -#include -#include - namespace units { /** - * @namespace units::radiometry - * @brief namespace for unit types and containers representing radiometry values - * @details The SI units for radiometry are: - * - source activity: becquerel - * @anchor radiometryContainers + * @namespace units::spectral_intensity + * @brief namespace for unit types and containers representing spectral_intensity values + * @anchor spectral_intensityContainers * @sa See unit for more information on unit type containers. */ - // UNIT_ADD_WITH_METRIC_PREFIXES(radiation, becquerels, Bq, conversion_factor, frequency::hertz<>>) - // UNIT_ADD_WITH_METRIC_PREFIXES(radiation, grays, Gy, compound_conversion_factor, inverse>>) - // UNIT_ADD_WITH_METRIC_PREFIXES(radiation, sieverts, Sv, conversion_factor, grays<>>) - // UNIT_ADD(radiation, curies, Ci, conversion_factor, gigabecquerels<>>) - // UNIT_ADD(radiation, rutherfords, rd, conversion_factor, megabecquerels<>>) - // UNIT_ADD(radiation, rads, rads, conversion_factor, centigrays<>>) - // - // UNIT_ADD_DIMENSION_TRAIT(radioactivity) + UNIT_ADD_WITH_METRIC_PREFIXES(spectral_intensity, watts_per_steradian_per_meter, Wpsrm, conversion_factor, dimension::spectral_intensity>) + + UNIT_ADD_DIMENSION_TRAIT(spectral_intensity) } // namespace units -#endif // units_radiometry_h__ +#endif // units_spectral_intensity_h_ \ No newline at end of file diff --git a/include/units/spectral_irradiance.h b/include/units/spectral_irradiance.h new file mode 100644 index 00000000..71444760 --- /dev/null +++ b/include/units/spectral_irradiance.h @@ -0,0 +1,64 @@ +//-------------------------------------------------------------------------------------------------- +// +// UnitConversion: A compile-time c++14 unit conversion library with no dependencies +// +//-------------------------------------------------------------------------------------------------- +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software +// and associated documentation files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//-------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2016 Nic Holthaus +// +//-------------------------------------------------------------------------------------------------- +// +// ATTRIBUTION: +// Parts of this work have been adapted from: +// http://stackoverflow.com/questions/35069778/create-comparison-trait-for-template-classes-whose-parameters-are-in-a-different +// http://stackoverflow.com/questions/28253399/check-traits-for-all-variadic-template-arguments/28253503 +// http://stackoverflow.com/questions/36321295/rational-approximation-of-square-root-of-stdratio-at-compile-time?noredirect=1#comment60266601_36321295 +// https://github.com/swatanabe/cppnow17-units +// +//-------------------------------------------------------------------------------------------------- +// +/// @file units/spectral_irradiance.h +/// @brief units representing spectral irradiance values +// +//-------------------------------------------------------------------------------------------------- + +#pragma once + +#ifndef units_spectral_irradiance_h_ +#define units_spectral_irradiance_h_ + +#include + +namespace units +{ + /** + * @namespace units::spectral_irradiance + * @brief namespace for unit types and containers representing spectral irradiance values + * @anchor spectral_irradianceContainers + * @sa See unit for more information on unit type containers. + */ + UNIT_ADD_WITH_METRIC_PREFIXES(spectral_irradiance, watts_per_meter_cubed, Wpm3, conversion_factor, dimension::spectral_irradiance>) + + UNIT_ADD_DIMENSION_TRAIT(spectral_irradiance) +} // namespace units + +#endif // units_spectral_irradiance_h_ \ No newline at end of file diff --git a/include/units/spectral_radiance.h b/include/units/spectral_radiance.h new file mode 100644 index 00000000..eaa60217 --- /dev/null +++ b/include/units/spectral_radiance.h @@ -0,0 +1,65 @@ +//-------------------------------------------------------------------------------------------------- +// +// UnitConversion: A compile-time c++14 unit conversion library with no dependencies +// +//-------------------------------------------------------------------------------------------------- +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software +// and associated documentation files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//-------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2016 Nic Holthaus +// +//-------------------------------------------------------------------------------------------------- +// +// ATTRIBUTION: +// Parts of this work have been adapted from: +// http://stackoverflow.com/questions/35069778/create-comparison-trait-for-template-classes-whose-parameters-are-in-a-different +// http://stackoverflow.com/questions/28253399/check-traits-for-all-variadic-template-arguments/28253503 +// http://stackoverflow.com/questions/36321295/rational-approximation-of-square-root-of-stdratio-at-compile-time?noredirect=1#comment60266601_36321295 +// https://github.com/swatanabe/cppnow17-units +// +//-------------------------------------------------------------------------------------------------- +// +/// @file units/spectral_radiance.h +/// @brief units representing spectral radiance values +// +//-------------------------------------------------------------------------------------------------- + +#pragma once + +#ifndef units_spectral_radiance_h_ +#define units_spectral_radiance_h_ + +#include +#include + +namespace units +{ + /** + * @namespace units::spectral_radiance + * @brief namespace for unit types and containers representing spectral_radiance values + * @anchor spectral_radianceContainers + * @sa See unit for more information on unit type containers. + */ + UNIT_ADD_WITH_METRIC_PREFIXES(spectral_radiance, watts_per_steradian_per_meter_cubed, Wpsrm3, conversion_factor, dimension::spectral_radiance>) + + UNIT_ADD_DIMENSION_TRAIT(spectral_radiance) +} // namespace units + +#endif // units_spectral_radiance_h_ \ No newline at end of file diff --git a/include/units/substance.h b/include/units/substance.h index 75c86240..17cbd3fe 100644 --- a/include/units/substance.h +++ b/include/units/substance.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_substance_h__ -#define units_substance_h__ +#ifndef units_substance_h_ +#define units_substance_h_ #include @@ -63,4 +63,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(substance) } // namespace units -#endif // units_substance_h__ +#endif // units_substance_h_ \ No newline at end of file diff --git a/include/units/substance_concentration.h b/include/units/substance_concentration.h index c214db8c..2f0e7fab 100644 --- a/include/units/substance_concentration.h +++ b/include/units/substance_concentration.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_substance_concentration_h__ -#define units_substance_concentration_h__ +#ifndef units_substance_concentration_h_ +#define units_substance_concentration_h_ #include @@ -64,4 +64,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(substance_concentration) } // namespace units -#endif // units_substance_concentration_h__ +#endif // units_substance_concentration_h_ \ No newline at end of file diff --git a/include/units/substance_mass.h b/include/units/substance_mass.h index 49e15537..bcbd27dc 100644 --- a/include/units/substance_mass.h +++ b/include/units/substance_mass.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_substance_mass_h__ -#define units_substance_mass_h__ +#ifndef units_substance_mass_h_ +#define units_substance_mass_h_ #include @@ -63,4 +63,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(substance_mass) } // namespace units -#endif // units_substance_mass_h__ +#endif // units_substance_mass_h_ \ No newline at end of file diff --git a/include/units/temperature.h b/include/units/temperature.h index 2ff97427..f8a2990c 100644 --- a/include/units/temperature.h +++ b/include/units/temperature.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_temperature_h__ -#define units_temperature_h__ +#ifndef units_temperature_h_ +#define units_temperature_h_ #include @@ -70,4 +70,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(temperature) } // namespace units -#endif // units_temperature_h__ +#endif // units_temperature_h_ \ No newline at end of file diff --git a/include/units/time.h b/include/units/time.h index 87b7a8d8..d370f20a 100644 --- a/include/units/time.h +++ b/include/units/time.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_time_h__ -#define units_time_h__ +#ifndef units_time_h_ +#define units_time_h_ #include @@ -80,4 +80,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(time) } // namespace units -#endif // units_time_h__ \ No newline at end of file +#endif // units_time_h_ \ No newline at end of file diff --git a/include/units/torque.h b/include/units/torque.h index 185f2d4b..4c0865cc 100644 --- a/include/units/torque.h +++ b/include/units/torque.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_torque_h__ -#define units_torque_h__ +#ifndef units_torque_h_ +#define units_torque_h_ #include #include @@ -69,4 +69,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(torque) } // namespace units -#endif // units_torque_h__ +#endif // units_torque_h_ \ No newline at end of file diff --git a/include/units/velocity.h b/include/units/velocity.h index 24c2ce13..c36706d7 100644 --- a/include/units/velocity.h +++ b/include/units/velocity.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_velocity_h__ -#define units_velocity_h__ +#ifndef units_velocity_h_ +#define units_velocity_h_ #include #include @@ -68,4 +68,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(velocity) } // namespace units -#endif // units_velocity_h__ +#endif // units_velocity_h_ \ No newline at end of file diff --git a/include/units/voltage.h b/include/units/voltage.h index f7146337..77512036 100644 --- a/include/units/voltage.h +++ b/include/units/voltage.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_voltage_h__ -#define units_voltage_h__ +#ifndef units_voltage_h_ +#define units_voltage_h_ #include @@ -65,4 +65,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(voltage) } // namespace units -#endif // units_voltage_h__ +#endif // units_voltage_h_ \ No newline at end of file diff --git a/include/units/volume.h b/include/units/volume.h index f8995a0f..54d3c3ba 100644 --- a/include/units/volume.h +++ b/include/units/volume.h @@ -43,8 +43,8 @@ #pragma once -#ifndef units_volume_h__ -#define units_volume_h__ +#ifndef units_volume_h_ +#define units_volume_h_ #include @@ -91,4 +91,4 @@ namespace units UNIT_ADD_DIMENSION_TRAIT(volume) } // namespace units -#endif // units_volume_h__ +#endif // units_volume_h_ \ No newline at end of file diff --git a/unitTests/main.cpp b/unitTests/main.cpp index 5bc80623..2687eefb 100644 --- a/unitTests/main.cpp +++ b/unitTests/main.cpp @@ -91,8 +91,7 @@ namespace { using T = std::decay_t; using U = std::decay_t; - return units::traits::is_same_dimension_unit_v && - std::ratio_equal_v; + return units::traits::is_same_dimension_unit_v && std::ratio_equal_v; }; } // namespace @@ -658,9 +657,7 @@ TEST_F(STDTypeTraits, std_common_type) static_assert(std::is_same_v, dimensionless>, dimensionless>); static_assert(std::is_same_v, dimensionless>, dimensionless>); - static_assert(std::is_same_v< - traits::conversion_factor_traits>::conversion_factor>::conversion_ratio, - std::ratio<1, 2>>); + static_assert(std::is_same_v>::conversion_factor>::conversion_ratio, std::ratio<1, 2>>); using T = std::common_type_t, double>; T a = 50_pct; @@ -1027,7 +1024,7 @@ TEST_F(UnitType, CTAD) static_assert(std::is_same_v, radians>); constexpr radians o_dim(degrees{1.0}); - static_assert(std::is_same_v, radians>); + static_assert(std::is_same_v, radians>); } TEST_F(UnitType, implicitChronoConversions) @@ -1244,22 +1241,22 @@ TEST_F(UnitType, unitTypeMixedEquality) EXPECT_FALSE(a_m != b_f); EXPECT_FALSE(b_m != a_f); - constexpr percent a(1.0); - constexpr parts_per_million b(20000.0); + constexpr percent a_pct(1.0); + constexpr parts_per_million b_ppm(20000.0); - EXPECT_FALSE(a == b); - EXPECT_TRUE(a != b); + EXPECT_FALSE(a_pct == b_ppm); + EXPECT_TRUE(a_pct != b_ppm); - constexpr percent c(1); - constexpr parts_per_million d(20000); + constexpr percent c_pct(1); + constexpr parts_per_million d_ppm(20000); - EXPECT_FALSE(c == d); - EXPECT_TRUE(c != d); + EXPECT_FALSE(c_pct == d_ppm); + EXPECT_TRUE(c_pct != d_ppm); - EXPECT_TRUE(a == c); - EXPECT_TRUE(b == d); - EXPECT_FALSE(a != c); - EXPECT_FALSE(b != d); + EXPECT_TRUE(a_pct == c_pct); + EXPECT_TRUE(b_ppm == d_ppm); + EXPECT_FALSE(a_pct != c_pct); + EXPECT_FALSE(b_ppm != d_ppm); } TEST_F(UnitType, unitTypeRelational) @@ -1425,8 +1422,8 @@ TEST_F(UnitType, unitTypeMixedRelational) TEST_F(UnitType, unitTypeArithmeticOperatorReturnType) { - percent p; - meters m; + percent pcnt; + meters length; constexpr dimensionless dim{1}; constexpr auto test = dim - 0; @@ -1435,68 +1432,68 @@ TEST_F(UnitType, unitTypeArithmeticOperatorReturnType) EXPECT_EQ(test, dim); static_assert(std::is_same_v, decltype(+dim)>); - static_assert(std::is_same_v, decltype(+p)>); - static_assert(std::is_same_v, decltype(+m)>); + static_assert(std::is_same_v, decltype(+pcnt)>); + static_assert(std::is_same_v, decltype(+length)>); static_assert(std::is_same_v, decltype(-dim)>); - static_assert(std::is_same_v, decltype(-p)>); - static_assert(std::is_same_v, decltype(-m)>); + static_assert(std::is_same_v, decltype(-pcnt)>); + static_assert(std::is_same_v, decltype(-length)>); static_assert(std::is_same_v, decltype(dim + 0)>); static_assert(std::is_same_v, decltype(0 + dim)>); static_assert(std::is_same_v, decltype(dim + dim)>); - static_assert(std::is_same_v, decltype(p + 0)>); - static_assert(std::is_same_v, decltype(0 + p)>); - static_assert(std::is_same_v, decltype(p + p)>); - static_assert(std::is_same_v, decltype(m + m)>); + static_assert(std::is_same_v, decltype(pcnt + 0)>); + static_assert(std::is_same_v, decltype(0 + pcnt)>); + static_assert(std::is_same_v, decltype(pcnt + pcnt)>); + static_assert(std::is_same_v, decltype(length + length)>); static_assert(std::is_same_v, decltype(dim - 0)>); static_assert(std::is_same_v, decltype(0 - dim)>); static_assert(std::is_same_v, decltype(dim - dim)>); - static_assert(std::is_same_v, decltype(p - 0)>); - static_assert(std::is_same_v, decltype(0 - p)>); - static_assert(std::is_same_v, decltype(p - p)>); - static_assert(std::is_same_v, decltype(m - m)>); + static_assert(std::is_same_v, decltype(pcnt - 0)>); + static_assert(std::is_same_v, decltype(0 - pcnt)>); + static_assert(std::is_same_v, decltype(pcnt - pcnt)>); + static_assert(std::is_same_v, decltype(length - length)>); static_assert(std::is_same_v, decltype(dim * 1)>); static_assert(std::is_same_v, decltype(1 * dim)>); static_assert(std::is_same_v, decltype(dim * dim)>); - static_assert(std::is_same_v, decltype(p * 1)>); - static_assert(std::is_same_v, decltype(1 * p)>); - static_assert(std::is_same_v, units::dimension::dimensionless>, int>, decltype(p * p)>); - - static_assert(std::is_same_v, decltype(m * 1)>); - static_assert(std::is_same_v, decltype(1 * m)>); - static_assert(std::is_same_v, decltype(m * dim)>); - static_assert(std::is_same_v, decltype(dim * m)>); - static_assert(std::is_same_v, decltype(m * p)>); - static_assert(std::is_same_v, decltype(p * m)>); - static_assert(std::is_same_v, decltype(m * m)>); + static_assert(std::is_same_v, decltype(pcnt * 1)>); + static_assert(std::is_same_v, decltype(1 * pcnt)>); + static_assert(std::is_same_v, units::dimension::dimensionless>, int>, decltype(pcnt * pcnt)>); + + static_assert(std::is_same_v, decltype(length * 1)>); + static_assert(std::is_same_v, decltype(1 * length)>); + static_assert(std::is_same_v, decltype(length * dim)>); + static_assert(std::is_same_v, decltype(dim * length)>); + static_assert(std::is_same_v, decltype(length * pcnt)>); + static_assert(std::is_same_v, decltype(pcnt * length)>); + static_assert(std::is_same_v, decltype(length * length)>); static_assert(std::is_same_v, decltype(dim / 1)>); static_assert(std::is_same_v, decltype(1 / dim)>); static_assert(std::is_same_v, decltype(dim / dim)>); - static_assert(std::is_same_v, decltype(p / 1)>); - static_assert(std::is_same_v>, int>, decltype(1 / p)>); - static_assert(std::is_same_v, decltype(p / p)>); - - static_assert(std::is_same_v, decltype(m / 1)>); - static_assert(std::is_same_v>, int>, decltype(1 / m)>); - static_assert(std::is_same_v, decltype(m / dim)>); - static_assert(std::is_same_v>, int>, decltype(dim / m)>); - static_assert(std::is_same_v, decltype(m / p)>); - static_assert(std::is_same_v>, int>, decltype(p / m)>); - static_assert(std::is_same_v, decltype(m / m)>); + static_assert(std::is_same_v, decltype(pcnt / 1)>); + static_assert(std::is_same_v>, int>, decltype(1 / pcnt)>); + static_assert(std::is_same_v, decltype(pcnt / pcnt)>); + + static_assert(std::is_same_v, decltype(length / 1)>); + static_assert(std::is_same_v>, int>, decltype(1 / length)>); + static_assert(std::is_same_v, decltype(length / dim)>); + static_assert(std::is_same_v>, int>, decltype(dim / length)>); + static_assert(std::is_same_v, decltype(length / pcnt)>); + static_assert(std::is_same_v>, int>, decltype(pcnt / length)>); + static_assert(std::is_same_v, decltype(length / length)>); static_assert(std::is_same_v, decltype(dim % 1)>); static_assert(std::is_same_v, decltype(dim % dim)>); - static_assert(std::is_same_v, decltype(p % 1)>); - static_assert(std::is_same_v, decltype(p % p)>); + static_assert(std::is_same_v, decltype(pcnt % 1)>); + static_assert(std::is_same_v, decltype(pcnt % pcnt)>); - static_assert(std::is_same_v, decltype(m % 1)>); - static_assert(std::is_same_v, decltype(m % dim)>); - static_assert(std::is_same_v, decltype(m % p)>); - static_assert(std::is_same_v, decltype(m % m)>); + static_assert(std::is_same_v, decltype(length % 1)>); + static_assert(std::is_same_v, decltype(length % dim)>); + static_assert(std::is_same_v, decltype(length % pcnt)>); + static_assert(std::is_same_v, decltype(length % length)>); } TEST_F(UnitType, unitTypeAddition) @@ -1506,38 +1503,38 @@ TEST_F(UnitType, unitTypeAddition) constexpr feet b_ft(3.28084); meters c_m{0.0}; constexpr meters f_m(1); - constexpr std::common_type_t, feet> g(f_m); + constexpr std::common_type_t, feet> g_m(f_m); - double d = meters(b_ft).value(); - EXPECT_NEAR(1.0, d, 5.0e-5); - d = meters(g).value(); - EXPECT_NEAR(1.0, d, 5.0e-5); + double d_m = meters(b_ft).value(); + EXPECT_NEAR(1.0, d_m, 5.0e-5); + d_m = meters(g_m).value(); + EXPECT_NEAR(1.0, d_m, 5.0e-5); c_m = a_m + b_ft; EXPECT_NEAR(2.0, c_m.value(), 5.0e-5); - c_m = f_m + g; + c_m = f_m + g_m; EXPECT_NEAR(2.0, c_m.value(), 5.0e-5); - c_m = a_m + g; + c_m = a_m + g_m; EXPECT_NEAR(2.0, c_m.value(), 5.0e-5); c_m = f_m + b_ft; EXPECT_NEAR(2.0, c_m.value(), 5.0e-5); c_m = b_ft + meters(3); EXPECT_NEAR(4.0, c_m.value(), 5.0e-5); - c_m = g + meters(3); + c_m = g_m + meters(3); EXPECT_NEAR(4.0, c_m.value(), 5.0e-5); c_m = b_ft + meters(3); EXPECT_NEAR(4.0, c_m.value(), 5.0e-5); - c_m = g + meters(3); + c_m = g_m + meters(3); EXPECT_NEAR(4.0, c_m.value(), 5.0e-5); feet e_ft = b_ft + meters(3); EXPECT_NEAR(13.12336, e_ft.value(), 5.0e-6); - e_ft = g + meters(3); + e_ft = g_m + meters(3); EXPECT_NEAR(13.12336, e_ft.value(), 5.0e-6); e_ft = b_ft + meters(3); EXPECT_NEAR(13.12336, e_ft.value(), 5.0e-6); - e_ft = g + meters(3); + e_ft = g_m + meters(3); EXPECT_NEAR(13.12336, e_ft.value(), 5.0e-6); // dimensionless @@ -1568,32 +1565,32 @@ TEST_F(UnitType, unitTypeAddition) result = 1 + dimensionless(1.0); EXPECT_NEAR(2.0, result, 5.0e-6); - d = dimensionless(1.0) + dimensionless(1.0); - EXPECT_NEAR(2.0, d, 5.0e-6); - d = dimensionless(1) + dimensionless(1); - EXPECT_NEAR(2.0, d, 5.0e-6); - d = dimensionless(1.0) + dimensionless(1); - EXPECT_NEAR(2.0, d, 5.0e-6); - d = dimensionless(1) + dimensionless(1.0); - EXPECT_NEAR(2.0, d, 5.0e-6); - - d = dimensionless(1.0) + 1.0; - EXPECT_NEAR(2.0, d, 5.0e-6); - d = dimensionless(1) + 1; - EXPECT_NEAR(2.0, d, 5.0e-6); - d = dimensionless(1.0) + 1; - EXPECT_NEAR(2.0, d, 5.0e-6); - d = dimensionless(1) + 1.0; - EXPECT_NEAR(2.0, d, 5.0e-6); - - d = 1.0 + dimensionless(1.0); - EXPECT_NEAR(2.0, d, 5.0e-6); - d = 1. + dimensionless(1); - EXPECT_NEAR(2.0, d, 5.0e-6); - d = 1.0 + dimensionless(1); - EXPECT_NEAR(2.0, d, 5.0e-6); - d = 1 + dimensionless(1.0); - EXPECT_NEAR(2.0, d, 5.0e-6); + d_m = dimensionless(1.0) + dimensionless(1.0); + EXPECT_NEAR(2.0, d_m, 5.0e-6); + d_m = dimensionless(1) + dimensionless(1); + EXPECT_NEAR(2.0, d_m, 5.0e-6); + d_m = dimensionless(1.0) + dimensionless(1); + EXPECT_NEAR(2.0, d_m, 5.0e-6); + d_m = dimensionless(1) + dimensionless(1.0); + EXPECT_NEAR(2.0, d_m, 5.0e-6); + + d_m = dimensionless(1.0) + 1.0; + EXPECT_NEAR(2.0, d_m, 5.0e-6); + d_m = dimensionless(1) + 1; + EXPECT_NEAR(2.0, d_m, 5.0e-6); + d_m = dimensionless(1.0) + 1; + EXPECT_NEAR(2.0, d_m, 5.0e-6); + d_m = dimensionless(1) + 1.0; + EXPECT_NEAR(2.0, d_m, 5.0e-6); + + d_m = 1.0 + dimensionless(1.0); + EXPECT_NEAR(2.0, d_m, 5.0e-6); + d_m = 1. + dimensionless(1); + EXPECT_NEAR(2.0, d_m, 5.0e-6); + d_m = 1.0 + dimensionless(1); + EXPECT_NEAR(2.0, d_m, 5.0e-6); + d_m = 1 + dimensionless(1.0); + EXPECT_NEAR(2.0, d_m, 5.0e-6); // concentration percent pResult = percent(1.0) + percent(1.0); @@ -1635,32 +1632,32 @@ TEST_F(UnitType, unitTypeAddition) EXPECT_NEAR(1.01, pResult, 5.0e-6); EXPECT_EQ(101_pct, pResult); - d = percent(1.0) + percent(1.0); - EXPECT_NEAR(0.02, d, 5.0e-6); - d = percent(1) + percent(1); - EXPECT_NEAR(0.02, d, 5.0e-6); - d = percent(1.0) + percent(1); - EXPECT_NEAR(0.02, d, 5.0e-6); - d = percent(1) + percent(1.0); - EXPECT_NEAR(0.02, d, 5.0e-6); - - d = percent(1.0) + 1.0; - EXPECT_NEAR(1.01, d, 5.0e-6); - d = percent(1) + 1; - EXPECT_NEAR(1.01, d, 5.0e-6); - d = percent(1.0) + 1; - EXPECT_NEAR(1.01, d, 5.0e-6); - d = percent(1) + 1.0; - EXPECT_NEAR(1.01, d, 5.0e-6); - - d = 1.0 + percent(1.0); - EXPECT_NEAR(1.01, d, 5.0e-6); - d = 1. + percent(1); - EXPECT_NEAR(1.01, d, 5.0e-6); - d = 1.0 + percent(1); - EXPECT_NEAR(1.01, d, 5.0e-6); - d = 1 + percent(1.0); - EXPECT_NEAR(1.01, d, 5.0e-6); + d_m = percent(1.0) + percent(1.0); + EXPECT_NEAR(0.02, d_m, 5.0e-6); + d_m = percent(1) + percent(1); + EXPECT_NEAR(0.02, d_m, 5.0e-6); + d_m = percent(1.0) + percent(1); + EXPECT_NEAR(0.02, d_m, 5.0e-6); + d_m = percent(1) + percent(1.0); + EXPECT_NEAR(0.02, d_m, 5.0e-6); + + d_m = percent(1.0) + 1.0; + EXPECT_NEAR(1.01, d_m, 5.0e-6); + d_m = percent(1) + 1; + EXPECT_NEAR(1.01, d_m, 5.0e-6); + d_m = percent(1.0) + 1; + EXPECT_NEAR(1.01, d_m, 5.0e-6); + d_m = percent(1) + 1.0; + EXPECT_NEAR(1.01, d_m, 5.0e-6); + + d_m = 1.0 + percent(1.0); + EXPECT_NEAR(1.01, d_m, 5.0e-6); + d_m = 1. + percent(1); + EXPECT_NEAR(1.01, d_m, 5.0e-6); + d_m = 1.0 + percent(1); + EXPECT_NEAR(1.01, d_m, 5.0e-6); + d_m = 1 + percent(1.0); + EXPECT_NEAR(1.01, d_m, 5.0e-6); percent p = 5_pct + 25_pct; EXPECT_EQ(30_pct, p); @@ -1706,33 +1703,33 @@ TEST_F(UnitType, unitTypeSubtraction) constexpr feet b_ft(3.28084); meters c_m{0.0}; constexpr meters f_m(1); - constexpr std::common_type_t, feet> g(f_m); + constexpr std::common_type_t, feet> g_m(f_m); c_m = a_m - b_ft; EXPECT_NEAR(0.0, c_m.value(), 5.0e-5); - c_m = f_m - g; + c_m = f_m - g_m; EXPECT_NEAR(0.0, c_m.value(), 5.0e-5); - c_m = a_m - g; + c_m = a_m - g_m; EXPECT_NEAR(0.0, c_m.value(), 5.0e-5); c_m = f_m - b_ft; EXPECT_NEAR(0.0, c_m.value(), 5.0e-5); c_m = b_ft - meters(1); EXPECT_NEAR(0.0, c_m.value(), 5.0e-5); - c_m = g - meters(1); + c_m = g_m - meters(1); EXPECT_NEAR(0.0, c_m.value(), 5.0e-5); c_m = b_ft - meters(1); EXPECT_NEAR(0.0, c_m.value(), 5.0e-5); - c_m = g - meters(1); + c_m = g_m - meters(1); EXPECT_NEAR(0.0, c_m.value(), 5.0e-5); feet e_ft = b_ft - meters(1); EXPECT_NEAR(0.0, e_ft.value(), 5.0e-6); - e_ft = g - meters(1); + e_ft = g_m - meters(1); EXPECT_NEAR(0.0, e_ft.value(), 5.0e-6); e_ft = b_ft - meters(1); EXPECT_NEAR(0.0, e_ft.value(), 5.0e-6); - e_ft = g - meters(1); + e_ft = g_m - meters(1); EXPECT_NEAR(0.0, e_ft.value(), 5.0e-6); // dimensionless @@ -1763,32 +1760,32 @@ TEST_F(UnitType, unitTypeSubtraction) sResult = 1 - dimensionless(1.0); EXPECT_NEAR(0.0, sResult, 5.0e-6); - double d = dimensionless(1.0) - dimensionless(1.0); - EXPECT_NEAR(0.0, d, 5.0e-6); - d = dimensionless(1) - dimensionless(1); - EXPECT_NEAR(0.0, d, 5.0e-6); - d = dimensionless(1.0) - dimensionless(1); - EXPECT_NEAR(0.0, d, 5.0e-6); - d = dimensionless(1) - dimensionless(1.0); - EXPECT_NEAR(0.0, d, 5.0e-6); - - d = dimensionless(1.0) - 1.0; - EXPECT_NEAR(0.0, d, 5.0e-6); - d = dimensionless(1) - 1; - EXPECT_NEAR(0.0, d, 5.0e-6); - d = dimensionless(1.0) - 1; - EXPECT_NEAR(0.0, d, 5.0e-6); - d = dimensionless(1) - 1.0; - EXPECT_NEAR(0.0, d, 5.0e-6); - - d = 1.0 - dimensionless(1.0); - EXPECT_NEAR(0.0, d, 5.0e-6); - d = 1 - dimensionless(1); - EXPECT_NEAR(0.0, d, 5.0e-6); - d = 1.0 - dimensionless(1); - EXPECT_NEAR(0.0, d, 5.0e-6); - d = 1 - dimensionless(1.0); - EXPECT_NEAR(0.0, d, 5.0e-6); + double dim = dimensionless(1.0) - dimensionless(1.0); + EXPECT_NEAR(0.0, dim, 5.0e-6); + dim = dimensionless(1) - dimensionless(1); + EXPECT_NEAR(0.0, dim, 5.0e-6); + dim = dimensionless(1.0) - dimensionless(1); + EXPECT_NEAR(0.0, dim, 5.0e-6); + dim = dimensionless(1) - dimensionless(1.0); + EXPECT_NEAR(0.0, dim, 5.0e-6); + + dim = dimensionless(1.0) - 1.0; + EXPECT_NEAR(0.0, dim, 5.0e-6); + dim = dimensionless(1) - 1; + EXPECT_NEAR(0.0, dim, 5.0e-6); + dim = dimensionless(1.0) - 1; + EXPECT_NEAR(0.0, dim, 5.0e-6); + dim = dimensionless(1) - 1.0; + EXPECT_NEAR(0.0, dim, 5.0e-6); + + dim = 1.0 - dimensionless(1.0); + EXPECT_NEAR(0.0, dim, 5.0e-6); + dim = 1 - dimensionless(1); + EXPECT_NEAR(0.0, dim, 5.0e-6); + dim = 1.0 - dimensionless(1); + EXPECT_NEAR(0.0, dim, 5.0e-6); + dim = 1 - dimensionless(1.0); + EXPECT_NEAR(0.0, dim, 5.0e-6); // concentration percent pResult = percent(5) - percent(1.0); @@ -1818,32 +1815,32 @@ TEST_F(UnitType, unitTypeSubtraction) pResult = 1 - percent(100.0); EXPECT_NEAR(0.0, pResult, 5.0e-6); - d = percent(100.0) - percent(10.0); - EXPECT_NEAR(0.9, d, 5.0e-6); - d = percent(100) - percent(10); - EXPECT_NEAR(0.9, d, 5.0e-6); - d = percent(100.0) - percent(10); - EXPECT_NEAR(0.9, d, 5.0e-6); - d = percent(100) - percent(10.0); - EXPECT_NEAR(0.9, d, 5.0e-6); - - d = percent(100.0) - 1.0; - EXPECT_NEAR(0.0, d, 5.0e-6); - d = percent(100) - 1; - EXPECT_NEAR(0.0, d, 5.0e-6); - d = percent(100.0) - 1; - EXPECT_NEAR(0.0, d, 5.0e-6); - d = percent(100) - 1.0; - EXPECT_NEAR(0.0, d, 5.0e-6); - - d = 1.0 - percent(100.0); - EXPECT_NEAR(0.0, d, 5.0e-6); - d = 1 - percent(100); - EXPECT_NEAR(0.0, d, 5.0e-6); - d = 1.0 - percent(100); - EXPECT_NEAR(0.0, d, 5.0e-6); - d = 1 - percent(100.0); - EXPECT_NEAR(0.0, d, 5.0e-6); + dim = percent(100.0) - percent(10.0); + EXPECT_NEAR(0.9, dim, 5.0e-6); + dim = percent(100) - percent(10); + EXPECT_NEAR(0.9, dim, 5.0e-6); + dim = percent(100.0) - percent(10); + EXPECT_NEAR(0.9, dim, 5.0e-6); + dim = percent(100) - percent(10.0); + EXPECT_NEAR(0.9, dim, 5.0e-6); + + dim = percent(100.0) - 1.0; + EXPECT_NEAR(0.0, dim, 5.0e-6); + dim = percent(100) - 1; + EXPECT_NEAR(0.0, dim, 5.0e-6); + dim = percent(100.0) - 1; + EXPECT_NEAR(0.0, dim, 5.0e-6); + dim = percent(100) - 1.0; + EXPECT_NEAR(0.0, dim, 5.0e-6); + + dim = 1.0 - percent(100.0); + EXPECT_NEAR(0.0, dim, 5.0e-6); + dim = 1 - percent(100); + EXPECT_NEAR(0.0, dim, 5.0e-6); + dim = 1.0 - percent(100); + EXPECT_NEAR(0.0, dim, 5.0e-6); + dim = 1 - percent(100.0); + EXPECT_NEAR(0.0, dim, 5.0e-6); } TEST_F(UnitType, unitTypeUnarySubtraction) @@ -2119,14 +2116,14 @@ TEST_F(UnitType, unitTypeMixedUnitMultiplication) EXPECT_NEAR(4.0, e_m.value(), 5.0e-5); // unit times its inverse results in a dimensionless - dimensionless s = a_m * i_m; - EXPECT_NEAR(2.0, s, 5.0e-5); - s = b_m * i_i_m; - EXPECT_NEAR(2.0, s, 5.0e-5); - s = a_m * i_i_m; - EXPECT_NEAR(2.0, s, 5.0e-5); - s = b_m * i_m; - EXPECT_NEAR(2.0, s, 5.0e-5); + dimensionless dim = a_m * i_m; + EXPECT_NEAR(2.0, dim, 5.0e-5); + dim = b_m * i_i_m; + EXPECT_NEAR(2.0, dim, 5.0e-5); + dim = a_m * i_i_m; + EXPECT_NEAR(2.0, dim, 5.0e-5); + dim = b_m * i_m; + EXPECT_NEAR(2.0, dim, 5.0e-5); c_m2 = b_ft * meters(2); EXPECT_NEAR(2.0, c_m2.value(), 5.0e-5); @@ -2146,14 +2143,14 @@ TEST_F(UnitType, unitTypeMixedUnitMultiplication) e_ft2 = f * meters(3); EXPECT_NEAR(32.2917333168, e_ft2.value(), 5.0e-6); - auto mps = meters(10.0) * unit>>(1.0); - EXPECT_EQ(mps, meters_per_second(10)); - mps = meters(10) * unit>, int>(1); - EXPECT_EQ(mps, meters_per_second(10)); - mps = meters(10.0) * unit>, int>(1); - EXPECT_EQ(mps, meters_per_second(10)); - mps = meters(10) * unit>>(1.0); - EXPECT_EQ(mps, meters_per_second(10)); + auto metersPerSecond = meters(10.0) * unit>>(1.0); + EXPECT_EQ(metersPerSecond, meters_per_second(10)); + metersPerSecond = meters(10) * unit>, int>(1); + EXPECT_EQ(metersPerSecond, meters_per_second(10)); + metersPerSecond = meters(10.0) * unit>, int>(1); + EXPECT_EQ(metersPerSecond, meters_per_second(10)); + metersPerSecond = meters(10) * unit>>(1.0); + EXPECT_EQ(metersPerSecond, meters_per_second(10)); } TEST_F(UnitType, unitTypeDimensionlessMultiplication) @@ -2175,8 +2172,8 @@ TEST_F(UnitType, unitTypeDimensionlessMultiplication) bool isSame = std::is_same_v>; EXPECT_TRUE(isSame); - kilometers km = 50.0_pct * 2000_m; - EXPECT_EQ(km, 1_km); + kilometers dist = 50.0_pct * 2000_m; + EXPECT_EQ(dist, 1_km); } TEST_F(UnitType, unitTypeDivision) @@ -2244,18 +2241,18 @@ TEST_F(UnitType, unitTypeDivision) isSame = std::is_same_v>; EXPECT_TRUE(isSame); - double d = dimensionless(1.0) / 2.0; - EXPECT_NEAR(0.5, d, 5.0e-5); - - auto e = a_m / a_sec; - EXPECT_NEAR(0.1, e.value(), 5.0e-5); - e = d_m / b_sec; - EXPECT_EQ(0, e.value()); - e = a_m / b_sec; - EXPECT_NEAR(0.1, e.value(), 5.0e-5); - e = d_m / a_sec; - EXPECT_NEAR(0.1, e.value(), 5.0e-5); - isSame = std::is_same_v>; + double d_dim = dimensionless(1.0) / 2.0; + EXPECT_NEAR(0.5, d_dim, 5.0e-5); + + auto e_mps = a_m / a_sec; + EXPECT_NEAR(0.1, e_mps.value(), 5.0e-5); + e_mps = d_m / b_sec; + EXPECT_EQ(0, e_mps.value()); + e_mps = a_m / b_sec; + EXPECT_NEAR(0.1, e_mps.value(), 5.0e-5); + e_mps = d_m / a_sec; + EXPECT_NEAR(0.1, e_mps.value(), 5.0e-5); + isSame = std::is_same_v>; EXPECT_TRUE(isSame); auto f = a_m / 8.0; @@ -2269,36 +2266,36 @@ TEST_F(UnitType, unitTypeDivision) isSame = std::is_same_v>; EXPECT_TRUE(isSame); - auto g = 4.0 / b_m; - EXPECT_NEAR(2.0, g.value(), 5.0e-5); - g = 4 / e_m; - EXPECT_NEAR(2.0, g.value(), 5.0e-5); - g = 4.0 / e_m; - EXPECT_NEAR(2.0, g.value(), 5.0e-5); - g = 4 / b_m; - EXPECT_NEAR(2.0, g.value(), 5.0e-5); - isSame = std::is_same_v>>>; + auto invMeters = 4.0 / b_m; + EXPECT_NEAR(2.0, invMeters.value(), 5.0e-5); + invMeters = 4 / e_m; + EXPECT_NEAR(2.0, invMeters.value(), 5.0e-5); + invMeters = 4.0 / e_m; + EXPECT_NEAR(2.0, invMeters.value(), 5.0e-5); + invMeters = 4 / b_m; + EXPECT_NEAR(2.0, invMeters.value(), 5.0e-5); + isSame = std::is_same_v>>>; EXPECT_TRUE(isSame); - auto mph = miles(60.0) / hours(1.0); - meters_per_second mps = mph; - EXPECT_NEAR(26.8224, mps.value(), 5.0e-5); - mps = miles(60) / hours(1); - EXPECT_NEAR(26.8224, mps.value(), 5.0e-5); - mps = miles(60.0) / hours(1); - EXPECT_NEAR(26.8224, mps.value(), 5.0e-5); - mps = miles(60) / hours(1.0); - EXPECT_NEAR(26.8224, mps.value(), 5.0e-5); - - auto h = 10.0_rad / 2.0_rad; - EXPECT_NEAR(5, h, 5.0e-5); - h = radians(10) / radians(2); - EXPECT_NEAR(5, h, 5.0e-5); - h = 10.0_rad / radians(2); - EXPECT_NEAR(5, h, 5.0e-5); - h = radians(10) / 2.0_rad; - EXPECT_NEAR(5, h, 5.0e-5); - isSame = std::is_same_v>; + auto miles_speed = miles(60.0) / hours(1.0); + meters_per_second speed = miles_speed; + EXPECT_NEAR(26.8224, speed.value(), 5.0e-5); + speed = miles(60) / hours(1); + EXPECT_NEAR(26.8224, speed.value(), 5.0e-5); + speed = miles(60.0) / hours(1); + EXPECT_NEAR(26.8224, speed.value(), 5.0e-5); + speed = miles(60) / hours(1.0); + EXPECT_NEAR(26.8224, speed.value(), 5.0e-5); + + auto h_dim = 10.0_rad / 2.0_rad; + EXPECT_NEAR(5, h_dim, 5.0e-5); + h_dim = radians(10) / radians(2); + EXPECT_NEAR(5, h_dim, 5.0e-5); + h_dim = 10.0_rad / radians(2); + EXPECT_NEAR(5, h_dim, 5.0e-5); + h_dim = radians(10) / 2.0_rad; + EXPECT_NEAR(5, h_dim, 5.0e-5); + isSame = std::is_same_v>; EXPECT_TRUE(isSame); auto i = (3.0_N * 2.0_m) / 6.0_J; @@ -2316,8 +2313,8 @@ TEST_F(UnitType, unitTypeDivision) EXPECT_DOUBLE_EQ(k.value(), 0.5); meters l = 10.0_km / 25.0_pct; EXPECT_EQ(l, 40'000.0_m); - dimensionless m = 5.0_pct / 4.0_pct; - EXPECT_EQ(m, 1.25); + dimensionless m_dim = 5.0_pct / 4.0_pct; + EXPECT_EQ(m_dim, 1.25); dimensionless n = 5_pct / 4_pct; EXPECT_EQ(n, 1); @@ -2438,49 +2435,49 @@ TEST_F(UnitType, compoundAssignmentAddition) EXPECT_EQ((meters(1001)), c); // dimensionless - dimensionless b(0); - b += dimensionless(1.0); + dimensionless b_dim(0); + b_dim += dimensionless(1.0); - EXPECT_EQ(dimensionless(1.0), b); + EXPECT_EQ(dimensionless(1.0), b_dim); - b += 1.0; + b_dim += 1.0; - EXPECT_EQ(dimensionless(2.0), b); + EXPECT_EQ(dimensionless(2.0), b_dim); - b += dimensionless(1); + b_dim += dimensionless(1); - EXPECT_EQ(dimensionless(3.0), b); + EXPECT_EQ(dimensionless(3.0), b_dim); - b += 1; + b_dim += 1; - EXPECT_EQ(dimensionless(4.0), b); + EXPECT_EQ(dimensionless(4.0), b_dim); - dimensionless d(0); - d += dimensionless(1); + dimensionless e_dim(0); + e_dim += dimensionless(1); - EXPECT_EQ((dimensionless(1)), d); + EXPECT_EQ((dimensionless(1)), e_dim); - d += 1; + e_dim += 1; - EXPECT_EQ((dimensionless(2)), d); + EXPECT_EQ((dimensionless(2)), e_dim); // concentration - percent e(0); - e += percent(1.0); + percent e_pct(0); + e_pct += percent(1.0); - EXPECT_EQ(percent(1.0), e); + EXPECT_EQ(percent(1.0), e_pct); - e += 1.0; + e_pct += 1.0; - EXPECT_EQ(percent(101.0), e); + EXPECT_EQ(percent(101.0), e_pct); - e += percent(1); + e_pct += percent(1); - EXPECT_EQ(percent(102.0), e); + EXPECT_EQ(percent(102.0), e_pct); - e += 1; + e_pct += 1; - EXPECT_EQ(percent(202.0), e); + EXPECT_EQ(percent(202.0), e_pct); percent f(0); f += percent(1); @@ -2526,49 +2523,49 @@ TEST_F(UnitType, compoundAssignmentSubtraction) EXPECT_EQ((meters(-1000)), c); // dimensionless - dimensionless b(2); - b -= dimensionless(1.0); + dimensionless b_dim(2); + b_dim -= dimensionless(1.0); - EXPECT_EQ(dimensionless(1.0), b); + EXPECT_EQ(dimensionless(1.0), b_dim); - b -= 1.0; + b_dim -= 1.0; - EXPECT_EQ(dimensionless(0), b); + EXPECT_EQ(dimensionless(0), b_dim); - b -= dimensionless(1); + b_dim -= dimensionless(1); - EXPECT_EQ(dimensionless(-1.0), b); + EXPECT_EQ(dimensionless(-1.0), b_dim); - b -= 1; + b_dim -= 1; - EXPECT_EQ(dimensionless(-2.0), b); + EXPECT_EQ(dimensionless(-2.0), b_dim); - dimensionless d(2); - d -= dimensionless(1); + dimensionless d_dim(2); + d_dim -= dimensionless(1); - EXPECT_EQ((dimensionless(1)), d); + EXPECT_EQ((dimensionless(1)), d_dim); - d -= 1; + d_dim -= 1; - EXPECT_EQ((dimensionless(0)), d); + EXPECT_EQ((dimensionless(0)), d_dim); // concentration - percent e(200); - e -= percent(1.0); + percent e_pct(200); + e_pct -= percent(1.0); - EXPECT_EQ(percent(199.0), e); + EXPECT_EQ(percent(199.0), e_pct); - e -= 1.0; + e_pct -= 1.0; - EXPECT_EQ(percent(99.0), e); + EXPECT_EQ(percent(99.0), e_pct); - e -= percent(100); + e_pct -= percent(100); - EXPECT_EQ(percent(-1.0), e); + EXPECT_EQ(percent(-1.0), e_pct); - e -= 1; + e_pct -= 1; - EXPECT_EQ(percent(-101.0), e); + EXPECT_EQ(percent(-101.0), e_pct); percent f(2); f -= percent(1); @@ -2626,61 +2623,61 @@ TEST_F(UnitType, compoundAssignmentMultiplication) EXPECT_EQ((meters(64)), c); // dimensionless - dimensionless b(2); - b *= dimensionless(2.0); + dimensionless b_dim(2); + b_dim *= dimensionless(2.0); - EXPECT_EQ(dimensionless(4.0), b); + EXPECT_EQ(dimensionless(4.0), b_dim); - b *= 2.0; + b_dim *= 2.0; - EXPECT_EQ(dimensionless(8.0), b); + EXPECT_EQ(dimensionless(8.0), b_dim); - b *= dimensionless(2); + b_dim *= dimensionless(2); - EXPECT_EQ(dimensionless(16.0), b); + EXPECT_EQ(dimensionless(16.0), b_dim); - b *= 2; + b_dim *= 2; - EXPECT_EQ(dimensionless(32.0), b); + EXPECT_EQ(dimensionless(32.0), b_dim); - dimensionless d(2); - d *= dimensionless(2); + dimensionless d_dim(2); + d_dim *= dimensionless(2); - EXPECT_EQ((dimensionless(4)), d); + EXPECT_EQ((dimensionless(4)), d_dim); - d *= dimensionless(2.0); + d_dim *= dimensionless(2.0); - EXPECT_EQ((dimensionless(8)), d); + EXPECT_EQ((dimensionless(8)), d_dim); - d *= 2; + d_dim *= 2; - EXPECT_EQ((dimensionless(16)), d); + EXPECT_EQ((dimensionless(16)), d_dim); - d *= 2.0; + d_dim *= 2.0; - EXPECT_EQ((dimensionless(32)), d); + EXPECT_EQ((dimensionless(32)), d_dim); // concentration - percent e(2); - e *= percent(2.0); + percent e_pct(2); + e_pct *= percent(2.0); - EXPECT_EQ(percent(0.04), e); - EXPECT_EQ(0.0004, e.value()); + EXPECT_EQ(percent(0.04), e_pct); + EXPECT_EQ(0.0004, e_pct.value()); - e *= 2.0; + e_pct *= 2.0; - EXPECT_EQ(percent(0.08), e); - EXPECT_EQ(0.0008, e.value()); + EXPECT_EQ(percent(0.08), e_pct); + EXPECT_EQ(0.0008, e_pct.value()); - e *= percent(2); + e_pct *= percent(2); - EXPECT_EQ(percent(0.0016), e); - EXPECT_EQ(0.000016, e.value()); + EXPECT_EQ(percent(0.0016), e_pct); + EXPECT_EQ(0.000016, e_pct.value()); - e *= 2; + e_pct *= 2; - EXPECT_EQ(percent(0.0032), e); - EXPECT_EQ(0.000032, e.value()); + EXPECT_EQ(percent(0.0032), e_pct); + EXPECT_EQ(0.000032, e_pct.value()); percent f(2); f *= percent(200); @@ -2746,61 +2743,61 @@ TEST_F(UnitType, compoundAssignmentDivision) EXPECT_EQ((meters(2)), c); // dimensionless - dimensionless b(8); - b /= dimensionless(2.0); + dimensionless b_dim(8); + b_dim /= dimensionless(2.0); - EXPECT_EQ(dimensionless(4.0), b); + EXPECT_EQ(dimensionless(4.0), b_dim); - b /= 2.0; + b_dim /= 2.0; - EXPECT_EQ(dimensionless(2.0), b); + EXPECT_EQ(dimensionless(2.0), b_dim); - b /= dimensionless(2); + b_dim /= dimensionless(2); - EXPECT_EQ(dimensionless(1.0), b); + EXPECT_EQ(dimensionless(1.0), b_dim); - b /= 2; + b_dim /= 2; - EXPECT_EQ(dimensionless(0.5), b); + EXPECT_EQ(dimensionless(0.5), b_dim); - dimensionless d(32); - d /= dimensionless(2); + dimensionless d_dim(32); + d_dim /= dimensionless(2); - EXPECT_EQ((dimensionless(16)), d); + EXPECT_EQ((dimensionless(16)), d_dim); - d /= dimensionless(2.0); + d_dim /= dimensionless(2.0); - EXPECT_EQ((dimensionless(8)), d); + EXPECT_EQ((dimensionless(8)), d_dim); - d /= 2; + d_dim /= 2; - EXPECT_EQ((dimensionless(4)), d); + EXPECT_EQ((dimensionless(4)), d_dim); - d /= 2.0; + d_dim /= 2.0; - EXPECT_EQ((dimensionless(2)), d); + EXPECT_EQ((dimensionless(2)), d_dim); // concentration - percent e(8); - e /= percent(50.0); + percent e_pct(8); + e_pct /= percent(50.0); - EXPECT_EQ(percent(16.0), e); - EXPECT_EQ(0.16, e.value()); + EXPECT_EQ(percent(16.0), e_pct); + EXPECT_EQ(0.16, e_pct.value()); - e /= 2.0; + e_pct /= 2.0; - EXPECT_EQ(percent(8.0), e); - EXPECT_EQ(0.08, e.value()); + EXPECT_EQ(percent(8.0), e_pct); + EXPECT_EQ(0.08, e_pct.value()); - e /= percent(2); + e_pct /= percent(2); - EXPECT_EQ(percent(400.0), e); - EXPECT_EQ(4, e.value()); + EXPECT_EQ(percent(400.0), e_pct); + EXPECT_EQ(4, e_pct.value()); - e /= 2; + e_pct /= 2; - EXPECT_EQ(percent(200.0), e); - EXPECT_EQ(2, e.value()); + EXPECT_EQ(percent(200.0), e_pct); + EXPECT_EQ(2, e_pct.value()); } TEST_F(UnitType, compoundAssignmentModulo) @@ -2880,8 +2877,8 @@ TEST_F(UnitType, valueMethod) EXPECT_DOUBLE_EQ(4.0, test2); static_assert(std::is_same_v, double>); - constexpr miles_per_hour mph = 100.0_ft / 1.0_min; - EXPECT_DOUBLE_EQ(mph.value(), 1.1363636363636365); + constexpr miles_per_hour speed = 100.0_ft / 1.0_min; + EXPECT_DOUBLE_EQ(speed.value(), 1.1363636363636365); constexpr auto test3 = 5.0_m * (2.0 / 1000.0_mm); EXPECT_DOUBLE_EQ(test3.value(), test3.to()); @@ -3003,14 +3000,14 @@ TEST_F(UnitType, cout) TEST_F(UnitType, to_string) { - feet a(3.5); - EXPECT_STREQ("3.5 ft", to_string(a).c_str()); + feet a_ft(3.5); + EXPECT_STREQ("3.5 ft", to_string(a_ft).c_str()); - meters b(8); - EXPECT_STREQ("8 m", to_string(b).c_str()); + meters b_m(8); + EXPECT_STREQ("8 m", to_string(b_m).c_str()); - percent c(25.1); - EXPECT_STREQ("25.1 pct", to_string(c).c_str()); + percent c_pct(25.1); + EXPECT_STREQ("25.1 pct", to_string(c_pct).c_str()); } TEST_F(UnitType, to_string_locale) @@ -3056,11 +3053,11 @@ TEST_F(UnitType, to_string_locale) char point_us = *lc->decimal_point; EXPECT_EQ(point_us, '.'); - miles us = 2.0_mi; - EXPECT_STREQ("2 mi", to_string(us).c_str()); + miles dist = 2.0_mi; + EXPECT_STREQ("2 mi", to_string(dist).c_str()); - us = 2.5_mi; - EXPECT_STREQ("2.5 mi", to_string(us).c_str()); + dist = 2.5_mi; + EXPECT_STREQ("2.5 mi", to_string(dist).c_str()); os2 << std::setprecision(11) << constants::mu_B; output = os2.str(); @@ -3069,15 +3066,15 @@ TEST_F(UnitType, to_string_locale) TEST_F(UnitType, nameAndAbbreviation) { - feet a(3.5); - EXPECT_STREQ("ft", unit_abbreviation_v); - EXPECT_STREQ("ft", a.abbreviation()); - EXPECT_STREQ("feet", a.name()); + feet a_ft(3.5); + EXPECT_STREQ("ft", unit_abbreviation_v); + EXPECT_STREQ("ft", a_ft.abbreviation()); + EXPECT_STREQ("feet", a_ft.name()); - meters b(8); - EXPECT_STREQ("m", unit_abbreviation_v); - EXPECT_STREQ("m", b.abbreviation()); - EXPECT_STREQ("meters", b.name()); + meters b_m(8.0); + EXPECT_STREQ("m", unit_abbreviation_v); + EXPECT_STREQ("m", b_m.abbreviation()); + EXPECT_STREQ("meters", b_m.name()); } #endif @@ -3091,44 +3088,44 @@ TEST(Consistency, recovers_input_values) TEST(Consistency, percent) { - percent a(50); - percent b = 50; + percent a_pct(50); + percent b_pct = 50; - EXPECT_DOUBLE_EQ(a, 50_pct); - EXPECT_DOUBLE_EQ(b, 50_pct); + EXPECT_DOUBLE_EQ(a_pct, 50_pct); + EXPECT_DOUBLE_EQ(b_pct, 50_pct); } TEST_F(UnitType, identity) { - auto a = percent(50); - percent b = a; - percent d = 1.0 * a; - percent f = a * 1.0; - EXPECT_EQ(a, percent(50)); - EXPECT_EQ(b, percent(50)); - EXPECT_EQ(d, percent(50)); - EXPECT_EQ(f, percent(50)); - EXPECT_NEAR(0.5, a, 5.0e-10); - EXPECT_NEAR(0.5, b, 5.0e-10); - EXPECT_NEAR(0.5, d, 5.0e-10); - EXPECT_NEAR(0.5, f, 5.0e-10); - EXPECT_NEAR(0.5, a.value(), 5.0e-10); - EXPECT_NEAR(0.5, b.value(), 5.0e-10); - EXPECT_NEAR(0.5, d.value(), 5.0e-10); - EXPECT_NEAR(0.5, f.value(), 5.0e-10); - - a = percent(50); - b = a / 1; - EXPECT_EQ(a, b); - EXPECT_EQ(b, percent(50)); - - a = percent(50); - a *= 1; - EXPECT_EQ(a, percent(50)); - - a = percent(50); - a /= 1; - EXPECT_EQ(a, percent(50)); + auto a_pct = percent(50); + percent b_pct = a_pct; + percent d_pct = 1.0 * a_pct; + percent f_pct = a_pct * 1.0; + EXPECT_EQ(a_pct, percent(50)); + EXPECT_EQ(b_pct, percent(50)); + EXPECT_EQ(d_pct, percent(50)); + EXPECT_EQ(f_pct, percent(50)); + EXPECT_NEAR(0.5, a_pct, 5.0e-10); + EXPECT_NEAR(0.5, b_pct, 5.0e-10); + EXPECT_NEAR(0.5, d_pct, 5.0e-10); + EXPECT_NEAR(0.5, f_pct, 5.0e-10); + EXPECT_NEAR(0.5, a_pct.value(), 5.0e-10); + EXPECT_NEAR(0.5, b_pct.value(), 5.0e-10); + EXPECT_NEAR(0.5, d_pct.value(), 5.0e-10); + EXPECT_NEAR(0.5, f_pct.value(), 5.0e-10); + + a_pct = percent(50); + b_pct = a_pct / 1; + EXPECT_EQ(a_pct, b_pct); + EXPECT_EQ(b_pct, percent(50)); + + a_pct = percent(50); + a_pct *= 1; + EXPECT_EQ(a_pct, percent(50)); + + a_pct = percent(50); + a_pct /= 1; + EXPECT_EQ(a_pct, percent(50)); meters w(5.3); meters x = w; @@ -3151,41 +3148,41 @@ TEST_F(UnitType, identity) TEST_F(UnitType, negative) { - meters a(5.3); - meters b(-5.3); - EXPECT_NEAR(a.to(), -b.to(), 5.0e-320); - EXPECT_NEAR(b.to(), -a.to(), 5.0e-320); + meters a_m(5.3); + meters b_m(-5.3); + EXPECT_NEAR(a_m.to(), -b_m.to(), 5.0e-320); + EXPECT_NEAR(b_m.to(), -a_m.to(), 5.0e-320); - decibels c(2.87); - decibels d(-2.87); - EXPECT_NEAR(c.to(), -d.to(), 5.0e-320); - EXPECT_NEAR(d.to(), -c.to(), 5.0e-320); + decibels c_dB(2.87); + decibels d_dB(-2.87); + EXPECT_NEAR(c_dB.to(), -d_dB.to(), 5.0e-320); + EXPECT_NEAR(d_dB.to(), -c_dB.to(), 5.0e-320); - parts_per_million e = -1 * parts_per_million(10); - EXPECT_EQ(e, -parts_per_million(10)); - EXPECT_NEAR(-0.00001, e, 5.0e-10); + parts_per_million e_ppm = -1 * parts_per_million(10); + EXPECT_EQ(e_ppm, -parts_per_million(10)); + EXPECT_NEAR(-0.00001, e_ppm, 5.0e-10); percent f = -1 * percent(50); EXPECT_EQ(f, -percent(50)); EXPECT_NEAR(-0.5, f, 5.0e-10); - percent g = percent(50) * -1; - EXPECT_EQ(g, -percent(50)); - EXPECT_NEAR(-0.5, g, 5.0e-10); + percent g_pct = percent(50) * -1; + EXPECT_EQ(g_pct, -percent(50)); + EXPECT_NEAR(-0.5, g_pct, 5.0e-10); } TEST_F(UnitType, concentration) { - parts_per_billion a(parts_per_million(1)); - EXPECT_EQ(parts_per_billion(1000), a); - EXPECT_EQ(0.000001, a); - EXPECT_EQ(0.000001, a.to()); + parts_per_billion a_ppb(parts_per_million(1)); + EXPECT_EQ(parts_per_billion(1000), a_ppb); + EXPECT_EQ(0.000001, a_ppb); + EXPECT_EQ(0.000001, a_ppb.to()); - dimensionless b(parts_per_million(1)); - EXPECT_EQ(0.000001, b); + dimensionless b_ppm(parts_per_million(1)); + EXPECT_EQ(0.000001, b_ppm); - dimensionless c = parts_per_billion(1); - EXPECT_EQ(0.000000001, c); + dimensionless c_dim = parts_per_billion(1); + EXPECT_EQ(0.000000001, c_dim); static_assert(traits::is_same_dimension_unit_v, dimensionless>); } @@ -3305,10 +3302,10 @@ TEST_F(UnitType, literals) EXPECT_TRUE(1.0_ft == y); // Pythagorean theorem - meters a = 3.0_m; - meters b = 4.0_m; - meters c = sqrt(pow<2>(a) + pow<2>(b)); - EXPECT_TRUE(c == 5.0_m); + meters a_m = 3.0_m; + meters b_m = 4.0_m; + meters c_m = sqrt(pow<2>(a_m) + pow<2>(b_m)); + EXPECT_TRUE(c_m == 5.0_m); } TEST_F(UnitType, Constants) @@ -3419,7 +3416,7 @@ TEST_F(ConversionFactor, mass) TEST_F(ConversionFactor, time) { - double result = 0; + double result = 0; constexpr double daysPerYear = 365; constexpr double hoursPerDay = 24; @@ -4336,6 +4333,80 @@ TEST_F(ConversionFactor, data_transfer_rate) EXPECT_NEAR(percent(15.3), exbibytes_per_second(1) / exabytes_per_second(1) - 1, 0.005); } +TEST_F(ConversionFactor, energy_density) +{ + static_assert(units::traits::is_same_dimension_unit_v, decltype(J / (m * m * m))>); + static_assert(traits::is_energy_density_unit_v); + static_assert(traits::is_pressure_unit_v); // energy density IS pressure + + constexpr joules_per_meter_cubed test = 64.0 * J / 2.0_cu_m; + EXPECT_EQ(test, 32.0_Jpm3); + +} + +TEST_F(ConversionFactor, irradiance) +{ + static_assert(std::is_same_v, decltype(W / sq_m)>); + static_assert(traits::is_irradiance_unit_v); + + constexpr watts_per_meter_squared test = 42.0 * W / 2.0_sq_m; + EXPECT_EQ(test, 21.0_Wpm2); +} + +TEST_F(ConversionFactor, radiance) +{ + static_assert(std::is_same_v, decltype(W / sr / sq_m)>); + static_assert(traits::is_radiance_unit_v); + + constexpr watts_per_steradian_per_meter_squared test = 44.0 * W / 2.0_sr / 2.0_sq_m; + EXPECT_EQ(test, 11.0_Wpsrm2); +} + +TEST_F(ConversionFactor, radiant_intensity) +{ + static_assert(std::is_same_v, decltype(W / sr)>); + static_assert(traits::is_radiant_intensity_unit_v); + + constexpr watts_per_steradian test = 44.0 * W / 2.0_sr; + EXPECT_EQ(test, 22.0_Wpsr); +} + +TEST_F(ConversionFactor, spectral_flux) +{ + static_assert(std::is_same_v, decltype(W / m)>); + static_assert(traits::is_spectral_flux_unit_v); + + constexpr watts_per_meter test = 44.0 * W / 4.0_m; + EXPECT_EQ(test, 11.0_Wpm); +} + +TEST_F(ConversionFactor, spectral_intensity) +{ + static_assert(std::is_same_v, decltype(W / sr / m)>); + static_assert(traits::is_spectral_intensity_unit_v); + + constexpr watts_per_steradian_per_meter test = 44.0 * W / 2.0_sr / 4.0_m; + EXPECT_EQ(test, 5.5_Wpsrm); +} + +TEST_F(ConversionFactor, spectral_irradiance) +{ + static_assert(std::is_same_v, decltype(W / cu_m)>); + static_assert(traits::is_spectral_irradiance_unit_v); + + constexpr watts_per_meter_cubed test = 44.0 * W / 2.0_cu_m; + EXPECT_EQ(test, 22_Wpm3); +} + +TEST_F(ConversionFactor, spectral_radiance) +{ + static_assert(std::is_same_v, decltype(W / sr / cu_m)>); + static_assert(traits::is_spectral_radiance_unit_v); + + constexpr watts_per_steradian_per_meter_cubed test = 44.0 * W / 2.0_sr / 2.0_cu_m; + EXPECT_EQ(test, 11_Wpsrm3); +} + TEST_F(ConversionFactor, pi) { EXPECT_TRUE(units::traits::is_dimensionless_unit_v); @@ -4366,11 +4437,11 @@ TEST_F(ConversionFactor, pi) EXPECT_NEAR(detail::PI_VAL, (meters(1) * constants::pi).to(), 5.0e-10); // explicit multiplication - meters a = constants::pi * meters(1); - meters b = meters(1) * constants::pi; + meters a_m = pi * meters(1); + meters b_m = meters(1) * pi; - EXPECT_NEAR(detail::PI_VAL, a.to(), 5.0e-10); - EXPECT_NEAR(detail::PI_VAL, b.to(), 5.0e-10); + EXPECT_NEAR(detail::PI_VAL, a_m.to(), 5.0e-10); + EXPECT_NEAR(detail::PI_VAL, b_m.to(), 5.0e-10); // auto division static_assert(std::is_same_v, decltype(constants::pi / seconds(1))>); @@ -4380,11 +4451,11 @@ TEST_F(ConversionFactor, pi) EXPECT_NEAR(1.0 / detail::PI_VAL, (seconds(1) / constants::pi).to(), 5.0e-10); // explicit - hertz c = constants::pi / seconds(1); - seconds d = seconds(1) / constants::pi; + hertz c_Hz = constants::pi / seconds(1); + seconds d_s = seconds(1) / constants::pi; - EXPECT_NEAR(detail::PI_VAL, c.to(), 5.0e-10); - EXPECT_NEAR(1.0 / detail::PI_VAL, d.to(), 5.0e-10); + EXPECT_NEAR(detail::PI_VAL, c_Hz.to(), 5.0e-10); + EXPECT_NEAR(1.0 / detail::PI_VAL, d_s.to(), 5.0e-10); } TEST_F(ConversionFactor, constants) @@ -4412,31 +4483,32 @@ TEST_F(ConversionFactor, constants) TEST_F(ConversionFactor, std_chrono) { - nanoseconds a = std::chrono::nanoseconds(10); - EXPECT_EQ(nanoseconds(10), a); - microseconds b = std::chrono::microseconds(10); - EXPECT_EQ(microseconds(10), b); - milliseconds c = std::chrono::milliseconds(10); - EXPECT_EQ(milliseconds(10), c); - seconds d = std::chrono::seconds(1); - EXPECT_EQ(seconds(1), d); - minutes e = std::chrono::minutes(120); - EXPECT_EQ(minutes(120), e); - hours f = std::chrono::hours(2); - EXPECT_EQ(hours(2), f); - - std::chrono::nanoseconds g = nanoseconds(100); - EXPECT_EQ(std::chrono::duration_cast(g).count(), 100); - std::chrono::nanoseconds h = microseconds(2); - EXPECT_EQ(std::chrono::duration_cast(h).count(), 2000); - std::chrono::nanoseconds i = milliseconds(1); - EXPECT_EQ(std::chrono::duration_cast(i).count(), 1000000); - std::chrono::nanoseconds j = seconds(1); - EXPECT_EQ(std::chrono::duration_cast(j).count(), 1000000000); - std::chrono::nanoseconds k = minutes(1); - EXPECT_EQ(std::chrono::duration_cast(k).count(), 60000000000); - std::chrono::nanoseconds l = hours(1); - EXPECT_EQ(std::chrono::duration_cast(l).count(), 3600000000000); + nanoseconds a_ns(std::chrono::nanoseconds(10)); + EXPECT_EQ(nanoseconds(10), a_ns); + microseconds b_us(std::chrono::microseconds(10)); + + EXPECT_EQ(microseconds(10), b_us); + milliseconds c_ms = std::chrono::milliseconds(10); + EXPECT_EQ(milliseconds(10), c_ms); + seconds d_s = std::chrono::seconds(1); + EXPECT_EQ(seconds(1), d_s); + minutes e_min = std::chrono::minutes(120); + EXPECT_EQ(minutes(120), e_min); + hours f_hr = std::chrono::hours(2); + EXPECT_EQ(hours(2), f_hr); + + std::chrono::nanoseconds g_ns = nanoseconds(100); + EXPECT_EQ(std::chrono::duration_cast(g_ns).count(), 100); + std::chrono::nanoseconds h_ns = microseconds(2); + EXPECT_EQ(std::chrono::duration_cast(h_ns).count(), 2000); + std::chrono::nanoseconds i_ns = milliseconds(1); + EXPECT_EQ(std::chrono::duration_cast(i_ns).count(), 1000000); + std::chrono::nanoseconds j_ns = seconds(1); + EXPECT_EQ(std::chrono::duration_cast(j_ns).count(), 1000000000); + std::chrono::nanoseconds k_ns = minutes(1); + EXPECT_EQ(std::chrono::duration_cast(k_ns).count(), 60000000000); + std::chrono::nanoseconds l_ns = hours(1); + EXPECT_EQ(std::chrono::duration_cast(l_ns).count(), 3600000000000); } TEST_F(ConversionFactor, squaredTemperature) @@ -4450,24 +4522,24 @@ TEST_F(ConversionFactor, squaredTemperature) TEST_F(UnitMath, min) { - meters a(1.0); - feet c(1.0); - EXPECT_EQ(c, units::min(a, c)); + meters a_m(1.0); + feet c_ft(1.0); + EXPECT_EQ(c_ft, units::min(a_m, c_ft)); - constexpr meters d(1); - constexpr centimeters e(99); - EXPECT_EQ(e, units::min(d, e)); + constexpr meters d_m(1); + constexpr centimeters e_cm(99); + EXPECT_EQ(e_cm, units::min(d_m, e_cm)); } TEST_F(UnitMath, max) { - meters a(1); - feet c(1); - EXPECT_EQ(a, max(a, c)); + meters a_m(1); + feet c_ft(1); + EXPECT_EQ(a_m, max(a_m, c_ft)); - meters d(1); - centimeters e(101); - EXPECT_EQ(e, max(d, e)); + meters d_m(1); + centimeters e_cm(101); + EXPECT_EQ(e_cm, max(d_m, e_cm)); } TEST_F(UnitMath, ternaryOperator) @@ -4598,17 +4670,14 @@ TEST_F(UnitMath, atan2) static_assert(std::is_same_v, decltype(atan2(dimensionless(1), dimensionless(1)))>); EXPECT_NEAR(angle::radians(detail::PI_VAL / 4).to(), atan2(dimensionless(2), dimensionless(2)).to(), 5.0e-12); EXPECT_NEAR(angle::radians(detail::PI_VAL / 4).to(), atan2(dimensionless(2), dimensionless(2)).to(), 5.0e-12); - EXPECT_NEAR( - angle::degrees(45).to(), angle::degrees(atan2(dimensionless(2), dimensionless(2))).to(), 5.0e-12); + EXPECT_NEAR(angle::degrees(45).to(), angle::degrees(atan2(dimensionless(2), dimensionless(2))).to(), 5.0e-12); EXPECT_NEAR(angle::degrees(45).to(), angle::degrees(atan2(dimensionless(2), dimensionless(2))).to(), 5.0e-12); static_assert(std::is_same_v, decltype(atan2(dimensionless(1), dimensionless(1)))>); EXPECT_NEAR(angle::radians(detail::PI_VAL / 6).to(), atan2(dimensionless(1), sqrt(dimensionless(3))).to(), 5.0e-12); EXPECT_NEAR(angle::radians(detail::PI_VAL / 6).to(), atan2(dimensionless(1), sqrt(dimensionless(3))).to(), 5.0e-12); - EXPECT_NEAR( - angle::degrees(30).to(), angle::degrees(atan2(dimensionless(1), sqrt(dimensionless(3)))).to(), 5.0e-12); - EXPECT_NEAR( - angle::degrees(30).to(), angle::degrees(atan2(dimensionless(1), sqrt(dimensionless(3)))).to(), 5.0e-12); + EXPECT_NEAR(angle::degrees(30).to(), angle::degrees(atan2(dimensionless(1), sqrt(dimensionless(3)))).to(), 5.0e-12); + EXPECT_NEAR(angle::degrees(30).to(), angle::degrees(atan2(dimensionless(1), sqrt(dimensionless(3)))).to(), 5.0e-12); } TEST_F(UnitMath, cosh) @@ -5030,13 +5099,13 @@ TEST_F(Constexpr, arithmetic) EXPECT_TRUE(noexcept(pow<3>(2.0_m))); EXPECT_TRUE(noexcept(2.0_m * 2.0_m)); - meters m{42}; - EXPECT_TRUE(noexcept(+m)); - EXPECT_TRUE(noexcept(-m)); - EXPECT_TRUE(noexcept(++m)); - EXPECT_TRUE(noexcept(--m)); - EXPECT_TRUE(noexcept(m++)); - EXPECT_TRUE(noexcept(m--)); + meters length{42}; + EXPECT_TRUE(noexcept(+length)); + EXPECT_TRUE(noexcept(-length)); + EXPECT_TRUE(noexcept(++length)); + EXPECT_TRUE(noexcept(--length)); + EXPECT_TRUE(noexcept(length++)); + EXPECT_TRUE(noexcept(length--)); EXPECT_EQ(8.0_cu_m, result9); EXPECT_EQ(4.0_sq_m, result10); @@ -5046,21 +5115,21 @@ TEST_F(Constexpr, assignment) { auto testConstexpr = []() constexpr noexcept { - meters m{42.}; - +m; - -m; - ++m; - --m; - m++; - m--; - m += 2.0_m; - m -= 2.0_m; - m *= 2; - m /= 2; - return m; + meters length{42.}; + +length; + -length; + ++length; + --length; + length++; + length--; + length += 2.0_m; + length -= 2.0_m; + length *= 2; + length /= 2; + return length; }; - [[maybe_unused]] constexpr auto m = testConstexpr(); + [[maybe_unused]] constexpr auto length = testConstexpr(); } TEST_F(Constexpr, realtional) @@ -5201,34 +5270,34 @@ TEST_F(UnitLimits, UnitHasSignalingNaN) TEST_F(CaseStudies, radarRangeEquation) { watts<> P_t; // transmit power - dimensionless<> G; // gain + dimensionless<> gain; // gain meters<> lambda; // wavelength - square_meters<> sigma; // radar cross-section - meters<> R; // range + square_meters<> rcs; // radar cross-section + meters<> range; // range kelvin<> T_s; // system noise temp hertz<> B_n; // bandwidth - dimensionless<> L; // loss + dimensionless<> loss; // loss P_t = megawatts<>(1.4); - G = decibels<>(33.0); + gain = decibels<>(33.0); lambda = constants::c / megahertz<>(2800.0); - sigma = square_meters<>(1.0); - R = meters<>(111000.0); + rcs = square_meters<>(1.0); + range = meters<>(111000.0); T_s = kelvin<>(950.0); B_n = megahertz<>(1.67); - L = decibels<>(8.0); + loss = decibels<>(8.0); - dimensionless SNR = (P_t * pow<2>(G) * pow<2>(lambda) * sigma) / (pow<3>(4 * constants::pi) * pow<4>(R) * constants::k_B * T_s * B_n * L); + const dimensionless SNR = (P_t * pow<2>(gain) * pow<2>(lambda) * rcs) / (pow<3>(4 * pi) * pow<4>(range) * k_B * T_s * B_n * loss); EXPECT_NEAR(1.535, SNR.value(), 5.0e-4); } TEST_F(CaseStudies, rightTriangle) { - constexpr auto a = 3.0_m; - constexpr auto b = 4.0_m; - constexpr auto c = sqrt(pow<2>(a) + pow<2>(b)); - EXPECT_EQ(5.0_m, c); + constexpr auto a_m = 3.0_m; + constexpr auto b_m = 4.0_m; + constexpr auto c_m = sqrt(pow<2>(a_m) + pow<2>(b_m)); + EXPECT_EQ(5.0_m, c_m); } TEST_F(CaseStudies, dataReadSimulation)