Merge branch 'master' into feature/more-value-casts

This commit is contained in:
Mateusz Pusz
2024-06-14 21:44:19 +09:00
committed by GitHub
102 changed files with 1293 additions and 1021 deletions

View File

@@ -22,6 +22,7 @@
#include <catch2/matchers/catch_matchers_templated.hpp>
#include <mp-units/compat_macros.h>
#include <mp-units/ext/format.h>
#include <algorithm>
#ifdef MP_UNITS_MODULES
import mp_units;

View File

@@ -23,6 +23,7 @@
#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_exception.hpp>
#include <mp-units/compat_macros.h>
#include <mp-units/ext/format.h>
#include <sstream>
#include <string_view>
#ifdef MP_UNITS_MODULES

View File

@@ -24,6 +24,7 @@
#include <catch2/matchers/catch_matchers.hpp>
#include <catch2/matchers/catch_matchers_exception.hpp>
#include <mp-units/compat_macros.h>
#include <mp-units/ext/format.h>
#include <cstdint>
#include <iomanip>
#include <limits>

View File

@@ -22,6 +22,7 @@
#include <catch2/catch_test_macros.hpp>
#include <mp-units/compat_macros.h>
#include <mp-units/ext/format.h>
#include <matrix>
#include <ostream>
#ifdef MP_UNITS_MODULES

View File

@@ -24,6 +24,7 @@
#include <catch2/catch_template_test_macros.hpp>
#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers.hpp>
#include <mp-units/ext/format.h>
#include <limits>
#include <numbers>
#ifdef MP_UNITS_MODULES
@@ -37,7 +38,7 @@ using namespace mp_units;
using namespace mp_units::angular;
using namespace mp_units::angular::unit_symbols;
inline constexpr struct half_revolution : named_unit<"hrev", mag_pi * radian> {
inline constexpr struct half_revolution final : named_unit<"hrev", mag_pi * radian> {
} half_revolution;
inline constexpr auto hrev = half_revolution;

View File

@@ -40,12 +40,12 @@ namespace {
using namespace mp_units;
inline constexpr struct my_origin : absolute_point_origin<my_origin, isq::length> {
inline constexpr struct my_origin final : absolute_point_origin<isq::length> {
} my_origin;
inline constexpr struct my_relative_origin : relative_point_origin<my_origin + isq::length(42 * si::metre)> {
inline constexpr struct my_relative_origin final : relative_point_origin<my_origin + isq::length(42 * si::metre)> {
} my_relative_origin;
struct dim_speed : decltype(isq::dim_length / isq::dim_time) {};
inline constexpr auto dim_speed = isq::dim_length / isq::dim_time;
// BaseDimension
static_assert(detail::BaseDimension<struct isq::dim_length>);
@@ -53,7 +53,7 @@ static_assert(!detail::BaseDimension<decltype(isq::dim_length / isq::dim_time)>)
static_assert(!detail::BaseDimension<decltype(inverse(isq::dim_time))>);
static_assert(!detail::BaseDimension<decltype(pow<2>(isq::dim_length))>);
static_assert(!detail::BaseDimension<derived_dimension<struct isq::dim_length, per<struct isq::dim_time>>>);
static_assert(!detail::BaseDimension<dim_speed>);
static_assert(!detail::BaseDimension<std::remove_const_t<decltype(dim_speed)>>);
static_assert(!detail::BaseDimension<base_dimension<"L">>);
static_assert(!detail::BaseDimension<struct si::metre>);
static_assert(!detail::BaseDimension<int>);
@@ -64,7 +64,7 @@ static_assert(detail::DerivedDimension<decltype(inverse(isq::dim_time))>);
static_assert(detail::DerivedDimension<decltype(pow<2>(isq::dim_length))>);
static_assert(detail::DerivedDimension<derived_dimension<struct isq::dim_length, per<struct isq::dim_time>>>);
static_assert(detail::DerivedDimension<struct dimension_one>);
static_assert(!detail::DerivedDimension<dim_speed>);
static_assert(detail::DerivedDimension<std::remove_const_t<decltype(dim_speed)>>);
static_assert(!detail::DerivedDimension<struct isq::dim_length>);
static_assert(!detail::DerivedDimension<struct si::metre>);
static_assert(!detail::DerivedDimension<int>);
@@ -76,7 +76,7 @@ static_assert(Dimension<decltype(inverse(isq::dim_time))>);
static_assert(Dimension<decltype(pow<2>(isq::dim_length))>);
static_assert(Dimension<derived_dimension<struct isq::dim_length, per<struct isq::dim_time>>>);
static_assert(Dimension<struct dimension_one>);
static_assert(!Dimension<dim_speed>);
static_assert(Dimension<std::remove_const_t<decltype(dim_speed)>>);
static_assert(!Dimension<base_dimension<"L">>);
static_assert(!Dimension<struct si::metre>);
static_assert(!Dimension<int>);
@@ -85,7 +85,7 @@ static_assert(!Dimension<int>);
// TODO add tests
// QuantitySpec
struct speed : decltype(isq::length / isq::time) {}; // this is not recommended
inline constexpr auto speed = isq::length / isq::time;
static_assert(QuantitySpec<struct isq::length>);
static_assert(QuantitySpec<struct isq::radius>);
@@ -94,7 +94,7 @@ static_assert(QuantitySpec<decltype(kind_of<isq::length>)>);
static_assert(QuantitySpec<decltype(isq::length / isq::time)>);
static_assert(QuantitySpec<decltype(pow<2>(isq::length))>);
static_assert(QuantitySpec<struct dimensionless>);
static_assert(!QuantitySpec<speed>);
static_assert(QuantitySpec<std::remove_const_t<decltype(speed)>>);
static_assert(!QuantitySpec<struct isq::dim_length>);
static_assert(!QuantitySpec<int>);
@@ -106,21 +106,21 @@ static_assert(!detail::NamedQuantitySpec<std::remove_const_t<decltype(kind_of<is
static_assert(!detail::NamedQuantitySpec<decltype(isq::length / isq::time)>);
static_assert(!detail::NamedQuantitySpec<decltype(pow<2>(isq::length))>);
static_assert(detail::NamedQuantitySpec<struct dimensionless>);
static_assert(!detail::NamedQuantitySpec<speed>);
static_assert(!detail::NamedQuantitySpec<std::remove_const_t<decltype(speed)>>);
static_assert(!detail::NamedQuantitySpec<struct isq::dim_length>);
static_assert(!detail::NamedQuantitySpec<int>);
// IntermediateDerivedQuantitySpec
static_assert(!detail::IntermediateDerivedQuantitySpec<struct isq::length>);
static_assert(!detail::IntermediateDerivedQuantitySpec<struct isq::radius>);
static_assert(!detail::IntermediateDerivedQuantitySpec<decltype(kind_of<isq::length>)>);
static_assert(!detail::IntermediateDerivedQuantitySpec<struct isq::speed>);
static_assert(detail::IntermediateDerivedQuantitySpec<decltype(isq::length / isq::time)>);
static_assert(detail::IntermediateDerivedQuantitySpec<decltype(pow<2>(isq::length))>);
static_assert(!detail::IntermediateDerivedQuantitySpec<struct dimensionless>);
static_assert(!detail::IntermediateDerivedQuantitySpec<speed>);
static_assert(!detail::IntermediateDerivedQuantitySpec<struct isq::dim_length>);
static_assert(!detail::IntermediateDerivedQuantitySpec<int>);
// DerivedQuantitySpec
static_assert(!detail::DerivedQuantitySpec<struct isq::length>);
static_assert(!detail::DerivedQuantitySpec<struct isq::radius>);
static_assert(!detail::DerivedQuantitySpec<decltype(kind_of<isq::length>)>);
static_assert(!detail::DerivedQuantitySpec<struct isq::speed>);
static_assert(detail::DerivedQuantitySpec<decltype(isq::length / isq::time)>);
static_assert(detail::DerivedQuantitySpec<decltype(pow<2>(isq::length))>);
static_assert(!detail::DerivedQuantitySpec<struct dimensionless>);
static_assert(detail::DerivedQuantitySpec<std::remove_const_t<decltype(speed)>>);
static_assert(!detail::DerivedQuantitySpec<struct isq::dim_length>);
static_assert(!detail::DerivedQuantitySpec<int>);
// QuantityKindSpec
static_assert(!detail::QuantityKindSpec<struct isq::length>);
@@ -130,7 +130,7 @@ static_assert(!detail::QuantityKindSpec<struct isq::speed>);
static_assert(!detail::QuantityKindSpec<decltype(isq::length / isq::time)>);
static_assert(!detail::QuantityKindSpec<decltype(pow<2>(isq::length))>);
static_assert(!detail::QuantityKindSpec<struct dimensionless>);
static_assert(!detail::QuantityKindSpec<speed>);
static_assert(!detail::QuantityKindSpec<std::remove_const_t<decltype(speed)>>);
static_assert(!detail::QuantityKindSpec<struct isq::dim_length>);
static_assert(!detail::QuantityKindSpec<int>);
@@ -138,10 +138,8 @@ static_assert(!detail::QuantityKindSpec<int>);
// TODO add tests
// Unit
struct metre_per_second : decltype(si::metre / si::second) {};
static_assert(Unit<struct si::metre>);
static_assert(Unit<struct si::kilogram>);
static_assert(Unit<decltype(si::kilogram)>);
static_assert(Unit<decltype(si::kilo<si::gram>)>);
static_assert(Unit<struct natural::electronvolt>);
static_assert(Unit<decltype(si::metre / si::second)>);
@@ -151,13 +149,12 @@ static_assert(Unit<decltype(square(si::metre))>);
static_assert(Unit<decltype(pow<2>(si::metre))>);
static_assert(Unit<struct si::standard_gravity>);
static_assert(Unit<scaled_unit<mag<10>, struct si::second>>);
static_assert(Unit<metre_per_second>);
static_assert(Unit<derived_unit<struct si::metre, per<struct si::second>>>);
static_assert(Unit<struct one>);
static_assert(!Unit<named_unit<"?", isq::length>>);
static_assert(!Unit<named_unit<"?", kind_of<isq::length>>>);
static_assert(!Unit<named_unit<"?">>);
static_assert(!Unit<named_unit<"?", si::metre / si::second>>);
static_assert(!Unit<named_unit<"?", si::metre, isq::length>>);
static_assert(!Unit<named_unit<"?", si::metre, kind_of<isq::length>>>);
static_assert(!Unit<prefixed_unit<"?", mag<10>, si::second>>);
static_assert(!Unit<struct isq::dim_length>);
static_assert(!Unit<int>);
@@ -168,7 +165,7 @@ static_assert(!Unit<std::chrono::seconds>);
// NamedUnit
static_assert(detail::NamedUnit<struct si::metre>);
static_assert(detail::NamedUnit<struct natural::electronvolt>);
static_assert(!detail::NamedUnit<struct si::kilogram>);
static_assert(!detail::NamedUnit<decltype(si::kilogram)>);
static_assert(!detail::NamedUnit<decltype(si::kilo<si::gram>)>);
static_assert(!detail::NamedUnit<decltype(si::metre / si::second)>);
static_assert(!detail::NamedUnit<decltype(inverse(si::second))>);
@@ -177,13 +174,12 @@ static_assert(!detail::NamedUnit<decltype(square(si::metre))>);
static_assert(!detail::NamedUnit<decltype(pow<2>(si::metre))>);
static_assert(detail::NamedUnit<struct si::standard_gravity>);
static_assert(!detail::NamedUnit<scaled_unit<mag<10>, struct si::second>>);
static_assert(!detail::NamedUnit<metre_per_second>);
static_assert(!detail::NamedUnit<derived_unit<struct si::metre, per<struct si::second>>>);
static_assert(!detail::NamedUnit<struct one>);
static_assert(!detail::NamedUnit<named_unit<"?", isq::length>>);
static_assert(!detail::NamedUnit<named_unit<"?", kind_of<isq::length>>>);
static_assert(!detail::NamedUnit<named_unit<"?">>);
static_assert(!detail::NamedUnit<named_unit<"?", si::metre / si::second>>);
static_assert(!detail::NamedUnit<named_unit<"?", si::metre, isq::length>>);
static_assert(!detail::NamedUnit<named_unit<"?", si::metre, kind_of<isq::length>>>);
static_assert(!detail::NamedUnit<prefixed_unit<"?", mag<10>, si::second>>);
static_assert(!detail::NamedUnit<struct isq::dim_length>);
static_assert(!detail::NamedUnit<int>);
@@ -194,7 +190,7 @@ static_assert(!detail::NamedUnit<std::chrono::seconds>);
// PrefixableUnit
static_assert(PrefixableUnit<struct si::metre>);
static_assert(PrefixableUnit<struct natural::electronvolt>);
static_assert(!PrefixableUnit<struct si::kilogram>);
static_assert(!PrefixableUnit<decltype(si::kilogram)>);
static_assert(!PrefixableUnit<decltype(si::kilo<si::gram>)>);
static_assert(!PrefixableUnit<decltype(si::metre / si::second)>);
static_assert(!PrefixableUnit<decltype(inverse(si::second))>);
@@ -203,13 +199,12 @@ static_assert(!PrefixableUnit<decltype(square(si::metre))>);
static_assert(!PrefixableUnit<decltype(pow<2>(si::metre))>);
static_assert(PrefixableUnit<struct si::standard_gravity>);
static_assert(!PrefixableUnit<scaled_unit<mag<10>, struct si::second>>);
static_assert(!PrefixableUnit<metre_per_second>);
static_assert(!PrefixableUnit<derived_unit<struct si::metre, per<struct si::second>>>);
static_assert(!PrefixableUnit<struct one>);
static_assert(!PrefixableUnit<named_unit<"?", isq::length>>);
static_assert(!PrefixableUnit<named_unit<"?", kind_of<isq::length>>>);
static_assert(!PrefixableUnit<named_unit<"?">>);
static_assert(!PrefixableUnit<named_unit<"?", si::metre / si::second>>);
static_assert(!PrefixableUnit<named_unit<"?", si::metre, isq::length>>);
static_assert(!PrefixableUnit<named_unit<"?", si::metre, kind_of<isq::length>>>);
static_assert(!PrefixableUnit<prefixed_unit<"?", mag<10>, si::second>>);
static_assert(!PrefixableUnit<struct isq::dim_length>);
static_assert(!PrefixableUnit<int>);
@@ -220,7 +215,7 @@ static_assert(!PrefixableUnit<std::chrono::seconds>);
// AssociatedUnit
static_assert(AssociatedUnit<struct si::metre>);
static_assert(!AssociatedUnit<struct natural::electronvolt>);
static_assert(AssociatedUnit<struct si::kilogram>);
static_assert(AssociatedUnit<decltype(si::kilogram)>);
static_assert(AssociatedUnit<decltype(si::kilo<si::gram>)>);
static_assert(AssociatedUnit<decltype(si::metre / si::second)>);
static_assert(AssociatedUnit<decltype(inverse(si::second))>);
@@ -229,13 +224,12 @@ static_assert(AssociatedUnit<decltype(square(si::metre))>);
static_assert(AssociatedUnit<decltype(pow<2>(si::metre))>);
static_assert(AssociatedUnit<struct si::standard_gravity>);
static_assert(AssociatedUnit<scaled_unit<mag<10>, struct si::second>>);
static_assert(AssociatedUnit<metre_per_second>);
static_assert(AssociatedUnit<derived_unit<struct si::metre, per<struct si::second>>>);
static_assert(AssociatedUnit<struct one>);
static_assert(!AssociatedUnit<named_unit<"?", isq::length>>);
static_assert(!AssociatedUnit<named_unit<"?", kind_of<isq::length>>>);
static_assert(!AssociatedUnit<named_unit<"?">>);
static_assert(!AssociatedUnit<named_unit<"?", si::metre / si::second>>);
static_assert(!AssociatedUnit<named_unit<"?", si::metre, isq::length>>);
static_assert(!AssociatedUnit<named_unit<"?", si::metre, kind_of<isq::length>>>);
static_assert(!AssociatedUnit<prefixed_unit<"?", mag<10>, si::second>>);
static_assert(!AssociatedUnit<struct isq::dim_length>);
static_assert(!AssociatedUnit<int>);
@@ -246,7 +240,7 @@ static_assert(!AssociatedUnit<std::chrono::seconds>);
// UnitOf
static_assert(UnitOf<struct si::metre, isq::length>);
static_assert(UnitOf<struct si::metre, isq::radius>);
static_assert(UnitOf<struct si::kilogram, isq::mass>);
static_assert(UnitOf<decltype(si::kilogram), isq::mass>);
static_assert(UnitOf<struct si::hertz, isq::frequency>);
static_assert(UnitOf<struct si::hertz, inverse(isq::time)>);
static_assert(UnitOf<struct one, dimensionless>);
@@ -366,7 +360,7 @@ static_assert(QuantityPoint<quantity_point<isq::length[si::metre], my_relative_o
static_assert(QuantityPoint<quantity_point<isq::radius[si::metre], my_origin>>);
static_assert(QuantityPoint<quantity_point<isq::radius[si::metre], my_relative_origin>>);
static_assert(!QuantityPoint<decltype(isq::length[si::metre])>);
static_assert(!QuantityPoint<absolute_point_origin<struct my_origin, isq::length>>);
static_assert(!QuantityPoint<absolute_point_origin<isq::length>>);
static_assert(!QuantityPoint<struct my_origin>);
static_assert(!QuantityPoint<struct my_relative_origin>);
#if MP_UNITS_HOSTED
@@ -400,7 +394,7 @@ static_assert(QuantityPointOf<quantity_point<isq::radius[si::metre], my_relative
// PointOrigin
static_assert(PointOrigin<struct my_origin>);
static_assert(PointOrigin<struct my_relative_origin>);
static_assert(!PointOrigin<absolute_point_origin<struct my_origin, isq::length>>);
static_assert(!PointOrigin<absolute_point_origin<isq::length>>);
static_assert(!PointOrigin<relative_point_origin<my_origin + 42 * si::metre>>);
static_assert(!PointOrigin<quantity_point<si::metre, my_origin>>);
static_assert(!PointOrigin<quantity_point<isq::length[si::metre], my_origin>>);

View File

@@ -32,15 +32,15 @@ using namespace mp_units;
using dimension_one_ = struct dimension_one;
// clang-format off
inline constexpr struct length_ : base_dimension<"L"> {} length;
inline constexpr struct mass_ : base_dimension<"M"> {} mass;
inline constexpr struct time_ : base_dimension<"T"> {} time;
inline constexpr struct length_ final : base_dimension<"L"> {} length;
inline constexpr struct mass_ final : base_dimension<"M"> {} mass;
inline constexpr struct time_ final : base_dimension<"T"> {} time;
inline constexpr struct my_length1_ : decltype(length) {} my_length1;
inline constexpr struct my_length2_ : decltype(length) {} my_length2;
inline constexpr auto my_length1 = length;
inline constexpr auto my_length2 = length;
QUANTITY_SPEC_(q_time, time);
inline constexpr struct second_ : named_unit<"s", kind_of<q_time>> {} second;
inline constexpr struct second_ final : named_unit<"s", kind_of<q_time>> {} second;
inline constexpr auto frequency = inverse(time);
inline constexpr auto action = inverse(time);

View File

@@ -46,40 +46,38 @@ using namespace std::chrono_literals;
using sys_seconds = std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>;
#endif
inline constexpr struct zeroth_length : absolute_point_origin<zeroth_length, isq::length> {
inline constexpr struct zeroth_length final : absolute_point_origin<isq::length> {
} zeroth_length;
inline constexpr struct mean_sea_level : absolute_point_origin<mean_sea_level, isq::height> {
inline constexpr struct mean_sea_level final : absolute_point_origin<isq::height> {
} mean_sea_level;
inline constexpr struct my_mean_sea_level : decltype(mean_sea_level) {
} my_mean_sea_level;
inline constexpr auto my_mean_sea_level = mean_sea_level;
inline constexpr struct same_mean_sea_level : relative_point_origin<mean_sea_level + 0 * isq::height[m]> {
inline constexpr struct same_mean_sea_level final : relative_point_origin<mean_sea_level + 0 * isq::height[m]> {
} same_mean_sea_level;
inline constexpr struct ground_level : relative_point_origin<mean_sea_level + 42 * isq::height[m]> {
inline constexpr struct ground_level final : relative_point_origin<mean_sea_level + 42 * isq::height[m]> {
} ground_level;
inline constexpr struct my_ground_level : decltype(ground_level) {
} my_ground_level;
inline constexpr auto my_ground_level = ground_level;
inline constexpr struct same_ground_level1 : relative_point_origin<mean_sea_level + 42 * isq::height[m]> {
inline constexpr struct same_ground_level1 final : relative_point_origin<mean_sea_level + 42 * isq::height[m]> {
} same_ground_level1;
inline constexpr struct same_ground_level2 : relative_point_origin<my_mean_sea_level + 42 * isq::height[m]> {
inline constexpr struct same_ground_level2 final : relative_point_origin<my_mean_sea_level + 42 * isq::height[m]> {
} same_ground_level2;
inline constexpr struct tower_peak : relative_point_origin<ground_level + 42 * isq::height[m]> {
inline constexpr struct tower_peak final : relative_point_origin<ground_level + 42 * isq::height[m]> {
} tower_peak;
inline constexpr struct other_ground_level : relative_point_origin<mean_sea_level + 123 * isq::height[m]> {
inline constexpr struct other_ground_level final : relative_point_origin<mean_sea_level + 123 * isq::height[m]> {
} other_ground_level;
inline constexpr struct other_absolute_level : absolute_point_origin<other_absolute_level, isq::height> {
inline constexpr struct other_absolute_level final : absolute_point_origin<isq::height> {
} other_absolute_level;
inline constexpr struct zero : absolute_point_origin<zero, dimensionless> {
inline constexpr struct zero final : absolute_point_origin<dimensionless> {
} zero;
QUANTITY_SPEC(special_height, isq::height);
@@ -107,12 +105,12 @@ static_assert(my_mean_sea_level != other_absolute_level);
static_assert(ground_level != other_ground_level);
template<auto QS>
struct absolute_po_ : absolute_point_origin<absolute_po_<QS>, QS> {};
struct absolute_po_ final : absolute_point_origin<QS> {};
template<auto QS>
inline constexpr absolute_po_<QS> absolute_po;
template<auto QP>
struct relative_po_ : relative_point_origin<QP> {};
struct relative_po_ final : relative_point_origin<QP> {};
template<auto QP>
inline constexpr relative_po_<QP> relative_po;
@@ -120,7 +118,7 @@ static_assert(relative_po<absolute_po<isq::length> + isq::height(42 * m)>.quanti
static_assert(relative_po<absolute_po<kind_of<isq::length>> + isq::height(42 * m)>.quantity_spec == isq::height);
static_assert(relative_po<absolute_po<isq::height> + 42 * m>.quantity_spec == isq::height);
inline constexpr struct my_kelvin : named_unit<"my_K", mag<10> * si::kelvin> {
inline constexpr struct my_kelvin final : named_unit<"my_K", mag<10> * si::kelvin> {
} my_kelvin;
static_assert(default_point_origin(si::kelvin) == si::absolute_zero);
@@ -311,7 +309,7 @@ static_assert(quantity_point<si::degree_Celsius, si::ice_point>::dimension == is
static_assert(quantity_point<si::degree_Celsius, si::ice_point>::unit == si::degree_Celsius);
static_assert(is_of_type<quantity_point<si::degree_Celsius, si::ice_point>::point_origin, struct si::ice_point>);
static_assert(
is_of_type<quantity_point<si::degree_Celsius, si::ice_point>::absolute_point_origin, struct si::zeroth_kelvin>);
is_of_type<quantity_point<si::degree_Celsius, si::ice_point>::absolute_point_origin, struct si::absolute_zero>);
static_assert(quantity_point<isq::Celsius_temperature[si::degree_Celsius], si::ice_point>::reference ==
isq::Celsius_temperature[si::degree_Celsius]);
@@ -324,7 +322,7 @@ static_assert(is_of_type<quantity_point<isq::Celsius_temperature[si::degree_Cels
struct si::ice_point>);
static_assert(
is_of_type<quantity_point<isq::Celsius_temperature[si::degree_Celsius], si::ice_point>::absolute_point_origin,
struct si::zeroth_kelvin>);
struct si::absolute_zero>);
//////////////////
@@ -892,10 +890,10 @@ static_assert(quantity_point{isq::height(123 * m)}.unit == si::metre);
static_assert(quantity_point{isq::height(123 * m)}.quantity_spec == isq::height);
static_assert(std::is_same_v<decltype(quantity_point{20 * deg_C})::rep, int>);
static_assert(std::is_same_v<std::remove_const_t<decltype(quantity_point{20 * deg_C}.point_origin)>,
struct si::zeroth_degree_Celsius>);
static_assert(
std::is_same_v<std::remove_const_t<decltype(quantity_point{20 * deg_C}.point_origin)>, struct si::ice_point>);
static_assert(std::is_same_v<std::remove_const_t<decltype(quantity_point{20 * deg_C}.absolute_point_origin)>,
struct si::zeroth_kelvin>);
struct si::absolute_zero>);
static_assert(quantity_point{20 * deg_C}.unit == si::degree_Celsius);
static_assert(quantity_point{20 * deg_C}.quantity_spec == kind_of<isq::thermodynamic_temperature>);
@@ -1493,7 +1491,7 @@ static_assert(ground_level - other_ground_level == -81 * m);
static_assert(other_ground_level - tower_peak == 39 * m);
static_assert(tower_peak - other_ground_level == -39 * m);
inline constexpr struct zero_m_per_s : absolute_point_origin<zero_m_per_s, kind_of<isq::speed>> {
inline constexpr struct zero_m_per_s final : absolute_point_origin<kind_of<isq::speed>> {
} zero_m_per_s;
// commutativity and associativity
@@ -1581,7 +1579,7 @@ static_assert(
is_of_type<quantity_point{10 * isq::height[m] / (2 * isq::time[s])} + (10 * isq::height[m] / (2 * isq::time[s])),
quantity_point<(isq::height / isq::time)[m / s], zeroth_point_origin<isq::height / isq::time>, int>>);
inline constexpr struct zero_Hz : absolute_point_origin<zero_Hz, kind_of<isq::frequency>> {
inline constexpr struct zero_Hz final : absolute_point_origin<kind_of<isq::frequency>> {
} zero_Hz;
static_assert(((zero_Hz + 10 / (2 * isq::period_duration[s])) + 5 * isq::frequency[Hz]).quantity_from(zero_Hz) ==
@@ -1665,7 +1663,7 @@ consteval bool invalid_subtraction(Ts... ts)
return !requires { (... - ts); };
}
inline constexpr struct zero_Bq : absolute_point_origin<zero_Bq, kind_of<isq::activity>> {
inline constexpr struct zero_Bq final : absolute_point_origin<kind_of<isq::activity>> {
} zero_Bq;
static_assert(invalid_addition(zero_Bq + 5 * isq::activity[Bq], 5 * isq::frequency[Hz]));

View File

@@ -33,16 +33,16 @@ using dimensionless_ = struct dimensionless;
using dim_one_ = struct dimension_one;
// clang-format off
inline constexpr struct dim_length_ : base_dimension<"L"> {} dim_length;
inline constexpr struct dim_mass_ : base_dimension<"M"> {} dim_mass;
inline constexpr struct dim_time_ : base_dimension<"T"> {} dim_time;
inline constexpr struct dim_length_ final : base_dimension<"L"> {} dim_length;
inline constexpr struct dim_mass_ final : base_dimension<"M"> {} dim_mass;
inline constexpr struct dim_time_ final : base_dimension<"T"> {} dim_time;
// quantities specification
QUANTITY_SPEC_(length, dim_length);
QUANTITY_SPEC_(mass, dim_mass);
QUANTITY_SPEC_(time, dim_time);
inline constexpr struct second_ : named_unit<"s", kind_of<time>> {} second;
inline constexpr struct second_ final : named_unit<"s", kind_of<time>> {} second;
QUANTITY_SPEC_(height, length);
QUANTITY_SPEC_(width, length);
@@ -88,98 +88,98 @@ QUANTITY_SPEC_(kinetic_energy, mechanical_energy, mass* pow<2>(speed));
// concepts verification
static_assert(QuantitySpec<length_>);
static_assert(detail::NamedQuantitySpec<length_>);
static_assert(!detail::IntermediateDerivedQuantitySpec<length_>);
static_assert(!detail::DerivedQuantitySpec<length_>);
static_assert(!detail::QuantityKindSpec<length_>);
static_assert(QuantitySpec<frequency_>);
static_assert(detail::NamedQuantitySpec<frequency_>);
static_assert(!detail::IntermediateDerivedQuantitySpec<frequency_>);
static_assert(!detail::DerivedQuantitySpec<frequency_>);
static_assert(!detail::QuantityKindSpec<frequency_>);
static_assert(QuantitySpec<decltype(inverse(time))>);
static_assert(!detail::NamedQuantitySpec<decltype(inverse(time))>);
static_assert(detail::IntermediateDerivedQuantitySpec<decltype(inverse(time))>);
static_assert(detail::DerivedQuantitySpec<decltype(inverse(time))>);
static_assert(!detail::QuantityKindSpec<decltype(inverse(time))>);
static_assert(QuantitySpec<dimensionless_>);
static_assert(detail::NamedQuantitySpec<dimensionless_>);
static_assert(!detail::IntermediateDerivedQuantitySpec<dimensionless_>);
static_assert(!detail::DerivedQuantitySpec<dimensionless_>);
static_assert(!detail::QuantityKindSpec<dimensionless_>);
static_assert(QuantitySpec<kind_of_<length_>>);
static_assert(!detail::NamedQuantitySpec<kind_of_<length_>>);
static_assert(!detail::IntermediateDerivedQuantitySpec<kind_of_<length_>>);
static_assert(!detail::DerivedQuantitySpec<kind_of_<length_>>);
static_assert(detail::QuantityKindSpec<kind_of_<length_>>);
static_assert(QuantitySpec<frequency_>);
static_assert(detail::NamedQuantitySpec<frequency_>);
static_assert(!detail::IntermediateDerivedQuantitySpec<frequency_>);
static_assert(!detail::DerivedQuantitySpec<frequency_>);
static_assert(!detail::QuantityKindSpec<frequency_>);
static_assert(QuantitySpec<decltype(inverse(time))>);
static_assert(!detail::NamedQuantitySpec<decltype(inverse(time))>);
static_assert(detail::IntermediateDerivedQuantitySpec<decltype(inverse(time))>);
static_assert(detail::DerivedQuantitySpec<decltype(inverse(time))>);
static_assert(!detail::QuantityKindSpec<decltype(inverse(time))>);
static_assert(QuantitySpec<kind_of_<decltype(length / time)>>);
static_assert(!detail::NamedQuantitySpec<kind_of_<decltype(length / time)>>);
static_assert(detail::IntermediateDerivedQuantitySpec<kind_of_<decltype(length / time)>>);
static_assert(detail::DerivedQuantitySpec<kind_of_<decltype(length / time)>>);
static_assert(detail::QuantityKindSpec<kind_of_<decltype(length / time)>>);
static_assert(QuantitySpec<decltype(kind_of<length> / kind_of<time>)>);
static_assert(!detail::NamedQuantitySpec<decltype(kind_of<length> / kind_of<time>)>);
static_assert(detail::IntermediateDerivedQuantitySpec<decltype(kind_of<length> / kind_of<time>)>);
static_assert(detail::DerivedQuantitySpec<decltype(kind_of<length> / kind_of<time>)>);
static_assert(detail::QuantityKindSpec<decltype(kind_of<length> / kind_of<time>)>);
static_assert(QuantitySpec<decltype(kind_of<length> * kind_of<time>)>);
static_assert(!detail::NamedQuantitySpec<decltype(kind_of<length> * kind_of<time>)>);
static_assert(detail::IntermediateDerivedQuantitySpec<decltype(kind_of<length> * kind_of<time>)>);
static_assert(detail::DerivedQuantitySpec<decltype(kind_of<length> * kind_of<time>)>);
static_assert(detail::QuantityKindSpec<decltype(kind_of<length> * kind_of<time>)>);
// dimensionless
static_assert(QuantitySpec<dimensionless_>);
static_assert(detail::NamedQuantitySpec<dimensionless_>);
static_assert(!detail::IntermediateDerivedQuantitySpec<dimensionless_>);
static_assert(!detail::DerivedQuantitySpec<dimensionless_>);
static_assert(!detail::QuantityKindSpec<dimensionless_>);
static_assert(QuantitySpec<decltype(length / length)>);
static_assert(detail::NamedQuantitySpec<decltype(length / length)>);
static_assert(!detail::IntermediateDerivedQuantitySpec<decltype(length / length)>);
static_assert(!detail::DerivedQuantitySpec<decltype(length / length)>);
static_assert(!detail::QuantityKindSpec<decltype(length / length)>);
static_assert(QuantitySpec<decltype(width / length)>);
static_assert(!detail::NamedQuantitySpec<decltype(width / length)>);
static_assert(detail::IntermediateDerivedQuantitySpec<decltype(width / length)>);
static_assert(detail::DerivedQuantitySpec<decltype(width / length)>);
static_assert(!detail::QuantityKindSpec<decltype(width / length)>);
static_assert(QuantitySpec<decltype(kind_of<length> / kind_of<length>)>);
static_assert(!detail::NamedQuantitySpec<decltype(kind_of<length> / kind_of<length>)>);
static_assert(!detail::IntermediateDerivedQuantitySpec<decltype(kind_of<length> / kind_of<length>)>);
static_assert(!detail::DerivedQuantitySpec<decltype(kind_of<length> / kind_of<length>)>);
static_assert(detail::QuantityKindSpec<decltype(kind_of<length> / kind_of<length>)>);
static_assert(QuantitySpec<decltype(kind_of<length> / length)>);
static_assert(detail::NamedQuantitySpec<decltype(kind_of<length> / length)>);
static_assert(!detail::IntermediateDerivedQuantitySpec<decltype(kind_of<length> / length)>);
static_assert(!detail::DerivedQuantitySpec<decltype(kind_of<length> / length)>);
static_assert(!detail::QuantityKindSpec<decltype(kind_of<length> / length)>);
static_assert(QuantitySpec<decltype(length / kind_of<length>)>);
static_assert(detail::NamedQuantitySpec<decltype(length / kind_of<length>)>);
static_assert(!detail::IntermediateDerivedQuantitySpec<decltype(length / kind_of<length>)>);
static_assert(!detail::DerivedQuantitySpec<decltype(length / kind_of<length>)>);
static_assert(!detail::QuantityKindSpec<decltype(length / kind_of<length>)>);
static_assert(QuantitySpec<decltype(width / kind_of<length>)>);
static_assert(!detail::NamedQuantitySpec<decltype(width / kind_of<length>)>);
static_assert(detail::IntermediateDerivedQuantitySpec<decltype(width / kind_of<length>)>);
static_assert(detail::DerivedQuantitySpec<decltype(width / kind_of<length>)>);
static_assert(!detail::QuantityKindSpec<decltype(width / kind_of<length>)>);
// length
static_assert(QuantitySpec<decltype(speed * time)>);
static_assert(!detail::NamedQuantitySpec<decltype(speed * time)>);
static_assert(detail::IntermediateDerivedQuantitySpec<decltype(speed * time)>);
static_assert(detail::DerivedQuantitySpec<decltype(speed * time)>);
// derived QuantitySpec expression template syntax verification
static_assert(!detail::NamedQuantitySpec<decltype(speed * time)>);
static_assert(detail::IntermediateDerivedQuantitySpec<decltype(speed * time)>);
static_assert(detail::DerivedQuantitySpec<decltype(speed * time)>);
static_assert(is_of_type<dimensionless * time, time_>);
static_assert(is_of_type<time * dimensionless, time_>);

View File

@@ -35,9 +35,9 @@ using one_ = struct one;
// base dimensions
// clang-format off
inline constexpr struct dim_length_ : base_dimension<"L"> {} dim_length;
inline constexpr struct dim_mass_ : base_dimension<"M"> {} dim_mass;
inline constexpr struct dim_time_ : base_dimension<"T"> {} dim_time;
inline constexpr struct dim_length_ final : base_dimension<"L"> {} dim_length;
inline constexpr struct dim_mass_ final : base_dimension<"M"> {} dim_mass;
inline constexpr struct dim_time_ final : base_dimension<"T"> {} dim_time;
// quantities specification
QUANTITY_SPEC_(length, dim_length);
@@ -60,16 +60,16 @@ QUANTITY_SPEC_(power, force* speed);
QUANTITY_SPEC_(storage_capacity, dimensionless, is_kind);
// base units
inline constexpr struct second_ : named_unit<"s", kind_of<time>> {} second;
inline constexpr struct metre_ : named_unit<"m", kind_of<length>> {} metre;
inline constexpr struct gram_ : named_unit<"g", kind_of<mass>> {} gram;
inline constexpr struct kilogram_ : decltype(si::kilo<gram>) {} kilogram;
inline constexpr struct second_ final : named_unit<"s", kind_of<time>> {} second;
inline constexpr struct metre_ final : named_unit<"m", kind_of<length>> {} metre;
inline constexpr struct gram_ final : named_unit<"g", kind_of<mass>> {} gram;
inline constexpr auto kilogram = si::kilo<gram>;
namespace nu {
// hypothetical natural system of units for c=1
inline constexpr struct second_ : named_unit<"s"> {} second;
inline constexpr struct minute_ : named_unit<"min", mag<60> * second> {} minute;
inline constexpr struct second_ final : named_unit<"s"> {} second;
inline constexpr struct minute_ final : named_unit<"min", mag<60> * second> {} minute;
inline constexpr struct time : system_reference<time_{}, second> {} time;
inline constexpr struct length : system_reference<length_{}, second> {} length;
@@ -78,19 +78,19 @@ inline constexpr struct speed : system_reference<speed_{}, second / second> {} s
}
// derived named units
inline constexpr struct radian_ : named_unit<"rad", metre / metre, kind_of<angular_measure>> {} radian;
inline constexpr struct steradian_ : named_unit<"sr", square(metre) / square(metre), kind_of<solid_angular_measure>> {} steradian;
inline constexpr struct hertz_ : named_unit<"Hz", inverse(second), kind_of<frequency>> {} hertz;
inline constexpr struct becquerel_ : named_unit<"Bq", inverse(second), kind_of<activity>> {} becquerel;
inline constexpr struct newton_ : named_unit<"N", kilogram * metre / square(second)> {} newton;
inline constexpr struct joule_ : named_unit<"J", newton * metre> {} joule;
inline constexpr struct watt_ : named_unit<"W", joule / second> {} watt;
inline constexpr struct radian_ final : named_unit<"rad", metre / metre, kind_of<angular_measure>> {} radian;
inline constexpr struct steradian_ final : named_unit<"sr", square(metre) / square(metre), kind_of<solid_angular_measure>> {} steradian;
inline constexpr struct hertz_ final : named_unit<"Hz", inverse(second), kind_of<frequency>> {} hertz;
inline constexpr struct becquerel_ final : named_unit<"Bq", inverse(second), kind_of<activity>> {} becquerel;
inline constexpr struct newton_ final : named_unit<"N", kilogram * metre / square(second)> {} newton;
inline constexpr struct joule_ final : named_unit<"J", newton * metre> {} joule;
inline constexpr struct watt_ final : named_unit<"W", joule / second> {} watt;
inline constexpr struct minute_ : named_unit<"min", mag<60> * second> {} minute;
inline constexpr struct hour_ : named_unit<"h", mag<60> * minute> {} hour;
inline constexpr struct kilometre_ : decltype(si::kilo<metre>) {} kilometre;
inline constexpr struct minute_ final : named_unit<"min", mag<60> * second> {} minute;
inline constexpr struct hour_ final : named_unit<"h", mag<60> * minute> {} hour;
inline constexpr auto kilometre = si::kilo<metre>;
inline constexpr struct bit_ : named_unit<"bit", one, kind_of<storage_capacity>> {} bit;
inline constexpr struct bit_ final : named_unit<"bit", one, kind_of<storage_capacity>> {} bit;
// clang-format on
@@ -189,27 +189,27 @@ static_assert(
constexpr auto m_per_s = speed[metre / second];
static_assert(is_of_type<2 * m_per_s, quantity<reference<speed_, derived_unit<metre_, per<second_>>>{}, int>>);
static_assert(
is_of_type<
120 * length[kilometre] / (2 * time[hour]),
quantity<reference<derived_quantity_spec<length_, per<time_>>, derived_unit<kilometre_, per<hour_>>>{}, int>>);
static_assert(is_of_type<120 * length[kilometre] / (2 * time[hour]),
quantity<reference<derived_quantity_spec<length_, per<time_>>,
derived_unit<std::remove_const_t<decltype(si::kilo<metre>)>, per<hour_>>>{},
int>>);
static_assert(120 * length[kilometre] / (2 * time[hour]) == 60 * speed[kilometre / hour]);
static_assert(
is_of_type<
[] {
const auto distance = 120;
const auto duration = 2;
return distance * length[kilometre] / (duration * time[hour]);
}(),
quantity<reference<derived_quantity_spec<length_, per<time_>>, derived_unit<kilometre_, per<hour_>>>{}, int>>);
static_assert(
is_of_type<std::int64_t{120} * length[kilometre] / (2 * time[hour]),
quantity<reference<derived_quantity_spec<length_, per<time_>>, derived_unit<kilometre_, per<hour_>>>{},
std::int64_t>>);
static_assert(
is_of_type<120.L * length[kilometre] / (2 * time[hour]),
quantity<reference<derived_quantity_spec<length_, per<time_>>, derived_unit<kilometre_, per<hour_>>>{},
long double>>);
static_assert(is_of_type<[] {
const auto distance = 120;
const auto duration = 2;
return distance * length[kilometre] / (duration * time[hour]);
}(),
quantity<reference<derived_quantity_spec<length_, per<time_>>,
derived_unit<std::remove_const_t<decltype(si::kilo<metre>)>, per<hour_>>>{},
int>>);
static_assert(is_of_type<std::int64_t{120} * length[kilometre] / (2 * time[hour]),
quantity<reference<derived_quantity_spec<length_, per<time_>>,
derived_unit<std::remove_const_t<decltype(si::kilo<metre>)>, per<hour_>>>{},
std::int64_t>>);
static_assert(is_of_type<120.L * length[kilometre] / (2 * time[hour]),
quantity<reference<derived_quantity_spec<length_, per<time_>>,
derived_unit<std::remove_const_t<decltype(si::kilo<metre>)>, per<hour_>>>{},
long double>>);
static_assert(is_of_type<1. / 4 * area[square(metre)], decltype(1. * area[square(metre)] / 4)>);
static_assert(1. / 4 * area[square(metre)] == 1. * area[square(metre)] / 4);
@@ -226,7 +226,9 @@ static_assert(is_of_type<42 * nu::length[nu::second] / (42 * nu::time[nu::second
static_assert(is_of_type<42 * nu::speed[nu::second / nu::second], quantity<reference<speed_, one_>{}, int>>);
static_assert(is_of_type<42 * nu::speed[one], quantity<reference<speed_, one_>{}, int>>);
static_assert(is_of_type<42 * mass[kilogram] * (1 * nu::length[nu::second]) / (1 * nu::time[nu::second]),
quantity<reference<derived_quantity_spec<length_, mass_, per<time_>>, kilogram_>{}, int>>);
quantity<reference<derived_quantity_spec<length_, mass_, per<time_>>,
std::remove_const_t<decltype(si::kilo<gram>)>>{},
int>>);
template<auto dim, auto unit>
concept invalid_nu_unit = !requires { dim[unit]; };

View File

@@ -32,14 +32,14 @@ inline constexpr bool is_of_type = std::is_same_v<MP_UNITS_REMOVE_CONST(decltype
// NOLINTBEGIN(cppcoreguidelines-macro-usage)
#ifdef MP_UNITS_API_NO_CRTP
#define QUANTITY_SPEC_(name, ...) \
inline constexpr struct name##_ : quantity_spec<__VA_ARGS__> { \
#define QUANTITY_SPEC_(name, ...) \
inline constexpr struct name##_ final : quantity_spec<__VA_ARGS__> { \
} name
#else
#define QUANTITY_SPEC_(name, ...) \
inline constexpr struct name##_ : quantity_spec<name##_, __VA_ARGS__> { \
#define QUANTITY_SPEC_(name, ...) \
inline constexpr struct name##_ final : quantity_spec<name##_, __VA_ARGS__> { \
} name
#endif

View File

@@ -36,10 +36,10 @@ using percent_ = struct percent;
// base dimensions
// clang-format off
inline constexpr struct dim_length_ : base_dimension<"L"> {} dim_length;
inline constexpr struct dim_mass_ : base_dimension<"M"> {} dim_mass;
inline constexpr struct dim_time_ : base_dimension<"T"> {} dim_time;
inline constexpr struct dim_thermodynamic_temperature_ : base_dimension<symbol_text{u8"Θ", "O"}> {} dim_thermodynamic_temperature;
inline constexpr struct dim_length_ final : base_dimension<"L"> {} dim_length;
inline constexpr struct dim_mass_ final : base_dimension<"M"> {} dim_mass;
inline constexpr struct dim_time_ final : base_dimension<"T"> {} dim_time;
inline constexpr struct dim_thermodynamic_temperature_ final : base_dimension<symbol_text{u8"Θ", "O"}> {} dim_thermodynamic_temperature;
// quantities specification
QUANTITY_SPEC_(length, dim_length);
@@ -48,39 +48,39 @@ QUANTITY_SPEC_(time, dim_time);
QUANTITY_SPEC_(thermodynamic_temperature, dim_thermodynamic_temperature);
// base units
inline constexpr struct second_ : named_unit<"s", kind_of<time>> {} second;
inline constexpr struct metre_ : named_unit<"m", kind_of<length>> {} metre;
inline constexpr struct gram_ : named_unit<"g", kind_of<mass>> {} gram;
inline constexpr struct kilogram_ : decltype(si::kilo<gram>) {} kilogram;
inline constexpr struct kelvin_ : named_unit<"K", kind_of<thermodynamic_temperature>> {} kelvin;
inline constexpr struct second_ final : named_unit<"s", kind_of<time>> {} second;
inline constexpr struct metre_ final : named_unit<"m", kind_of<length>> {} metre;
inline constexpr struct gram_ final : named_unit<"g", kind_of<mass>> {} gram;
inline constexpr auto kilogram = si::kilo<gram>;
inline constexpr struct kelvin_ final : named_unit<"K", kind_of<thermodynamic_temperature>> {} kelvin;
// hypothetical natural units for c=1
inline constexpr struct nu_second_ : named_unit<"s"> {} nu_second;
inline constexpr struct nu_second_ final : named_unit<"s"> {} nu_second;
// derived named units
inline constexpr struct radian_ : named_unit<"rad", metre / metre> {} radian;
inline constexpr struct steradian_ : named_unit<"sr", square(metre) / square(metre)> {} steradian;
inline constexpr struct hertz_ : named_unit<"Hz", inverse(second)> {} hertz;
inline constexpr struct becquerel_ : named_unit<"Bq", inverse(second)> {} becquerel;
inline constexpr struct newton_ : named_unit<"N", kilogram * metre / square(second)> {} newton;
inline constexpr struct pascal_ : named_unit<"Pa", newton / square(metre)> {} pascal;
inline constexpr struct joule_ : named_unit<"J", newton * metre> {} joule;
inline constexpr struct watt_ : named_unit<"W", joule / second> {} watt;
inline constexpr struct degree_Celsius_ : named_unit<symbol_text{u8"°C", "`C"}, kelvin> {} degree_Celsius;
inline constexpr struct radian_ final : named_unit<"rad", metre / metre> {} radian;
inline constexpr struct steradian_ final : named_unit<"sr", square(metre) / square(metre)> {} steradian;
inline constexpr struct hertz_ final : named_unit<"Hz", inverse(second)> {} hertz;
inline constexpr struct becquerel_ final : named_unit<"Bq", inverse(second)> {} becquerel;
inline constexpr struct newton_ final : named_unit<"N", kilogram * metre / square(second)> {} newton;
inline constexpr struct pascal_ final : named_unit<"Pa", newton / square(metre)> {} pascal;
inline constexpr struct joule_ final : named_unit<"J", newton * metre> {} joule;
inline constexpr struct watt_ final : named_unit<"W", joule / second> {} watt;
inline constexpr struct degree_Celsius_ final : named_unit<symbol_text{u8"°C", "`C"}, kelvin> {} degree_Celsius;
inline constexpr struct minute_ : named_unit<"min", mag<60> * second> {} minute;
inline constexpr struct hour_ : named_unit<"h", mag<60> * minute> {} hour;
inline constexpr struct degree_ : named_unit<symbol_text{u8"°", "deg"}, mag_pi / mag<180> * radian> {} degree;
inline constexpr struct minute_ final : named_unit<"min", mag<60> * second> {} minute;
inline constexpr struct hour_ final : named_unit<"h", mag<60> * minute> {} hour;
inline constexpr struct degree_ final : named_unit<symbol_text{u8"°", "deg"}, mag_pi / mag<180> * radian> {} degree;
inline constexpr struct yard_ : named_unit<"yd", mag_ratio<9'144, 10'000> * metre> {} yard;
inline constexpr struct mile_ : named_unit<"mi", mag<1760> * yard> {} mile;
inline constexpr struct yard_ final : named_unit<"yd", mag_ratio<9'144, 10'000> * metre> {} yard;
inline constexpr struct mile_ final : named_unit<"mi", mag<1760> * yard> {} mile;
inline constexpr struct kilometre_ : decltype(si::kilo<metre>) {} kilometre;
inline constexpr struct kilojoule_ : decltype(si::kilo<joule>) {} kilojoule;
inline constexpr auto kilometre = si::kilo<metre>;
inline constexpr auto kilojoule = si::kilo<joule>;
// physical constant units
inline constexpr struct standard_gravity_ : named_unit<symbol_text{u8"g₀", "g_0"}, mag_ratio<980'665, 100'000> * metre / square(second)> {} standard_gravity;
inline constexpr struct speed_of_light_in_vacuum_ : named_unit<"c", mag<299'792'458> * metre / second> {} speed_of_light_in_vacuum;
inline constexpr struct standard_gravity_ final : named_unit<symbol_text{u8"g₀", "g_0"}, mag_ratio<980'665, 100'000> * metre / square(second)> {} standard_gravity;
inline constexpr struct speed_of_light_in_vacuum_ final : named_unit<"c", mag<299'792'458> * metre / second> {} speed_of_light_in_vacuum;
// clang-format on
@@ -88,7 +88,7 @@ inline constexpr struct speed_of_light_in_vacuum_ : named_unit<"c", mag<299'792'
static_assert(Unit<metre_>);
static_assert(Unit<second_>);
static_assert(Unit<nu_second_>);
static_assert(Unit<kilogram_>);
static_assert(Unit<decltype(kilogram)>);
static_assert(Unit<hertz_>);
static_assert(Unit<newton_>);
static_assert(Unit<minute_>);
@@ -100,20 +100,20 @@ static_assert(Unit<decltype(second * second)>);
static_assert(Unit<decltype(nu_second * nu_second)>);
static_assert(Unit<decltype(metre / second)>);
static_assert(Unit<decltype(nu_second / nu_second)>);
static_assert(Unit<kilometre_>);
static_assert(Unit<decltype(kilometre)>);
static_assert(detail::NamedUnit<metre_>);
static_assert(detail::NamedUnit<hertz_>);
static_assert(detail::NamedUnit<newton_>);
static_assert(detail::NamedUnit<minute_>);
static_assert(detail::NamedUnit<radian_>);
static_assert(!detail::NamedUnit<kilogram_>);
static_assert(!detail::NamedUnit<kilojoule_>);
static_assert(!detail::NamedUnit<decltype(kilogram)>);
static_assert(!detail::NamedUnit<decltype(kilojoule)>);
static_assert(!detail::NamedUnit<decltype(si::kilo<gram>)>);
static_assert(!detail::NamedUnit<decltype(square(metre))>);
static_assert(!detail::NamedUnit<decltype(cubic(metre))>);
static_assert(!detail::NamedUnit<decltype(mag<60> * second)>);
static_assert(!detail::NamedUnit<kilometre_>);
static_assert(!detail::NamedUnit<decltype(kilometre)>);
// named unit
static_assert(is_of_type<metre, metre_>);
@@ -192,14 +192,14 @@ static_assert(standard_gravity != metre / square(second)); // magnitude is diff
static_assert(standard_gravity.symbol == symbol_text{u8"g₀", "g_0"});
// prefixed_unit
static_assert(is_of_type<kilometre, kilometre_>);
static_assert(is_of_type<kilometre, std::remove_const_t<decltype(si::kilo<metre>)>>);
static_assert(is_of_type<get_canonical_unit(kilometre).reference_unit, metre_>);
static_assert(get_canonical_unit(kilometre).mag == mag<1000>);
static_assert(convertible(kilometre, metre));
static_assert(kilometre != metre);
static_assert(kilometre.symbol == "km");
static_assert(is_of_type<kilojoule, kilojoule_>);
static_assert(is_of_type<kilojoule, std::remove_const_t<decltype(si::kilo<joule>)>>);
static_assert(is_of_type<get_canonical_unit(kilojoule).reference_unit,
derived_unit<gram_, power<metre_, 2>, per<power<second_, 2>>>>);
static_assert(get_canonical_unit(kilojoule).mag == mag<1'000'000>);
@@ -210,8 +210,10 @@ static_assert(kilojoule.symbol == "kJ");
static_assert(is_of_type<si::kilo<metre>, si::kilo_<metre_>>);
static_assert(is_of_type<si::kilo<joule>, si::kilo_<joule_>>);
static_assert(is_of_type<kilometre * metre, derived_unit<kilometre_, metre_>>); // !!!
static_assert(is_of_type<kilometre / metre, derived_unit<kilometre_, per<metre_>>>); // !!!
static_assert(
is_of_type<kilometre * metre, derived_unit<std::remove_const_t<decltype(si::kilo<metre>)>, metre_>>); // !!!
static_assert(
is_of_type<kilometre / metre, derived_unit<std::remove_const_t<decltype(si::kilo<metre>)>, per<metre_>>>); // !!!
// prefixes
@@ -252,7 +254,7 @@ static_assert(is_of_type<get_canonical_unit(m_2).reference_unit, metre_>);
static_assert(get_canonical_unit(m_2).mag == mag<2>);
constexpr auto km_2 = mag<2> * kilometre;
static_assert(is_of_type<km_2, scaled_unit<mag<2>, kilometre_>>);
static_assert(is_of_type<km_2, scaled_unit<mag<2>, std::remove_const_t<decltype(si::kilo<metre>)>>>);
static_assert(is_of_type<get_canonical_unit(km_2).reference_unit, metre_>);
static_assert(get_canonical_unit(km_2).mag == mag<2000>);
@@ -346,12 +348,12 @@ static_assert(is_of_type<get_canonical_unit(m_per_s).reference_unit, derived_uni
static_assert(get_canonical_unit(m_per_s).mag == mag<1>);
constexpr auto km_per_s = kilometre / second;
static_assert(is_of_type<km_per_s, derived_unit<kilometre_, per<second_>>>);
static_assert(is_of_type<km_per_s, derived_unit<std::remove_const_t<decltype(si::kilo<metre>)>, per<second_>>>);
static_assert(is_of_type<get_canonical_unit(km_per_s).reference_unit, derived_unit<metre_, per<second_>>>);
static_assert(get_canonical_unit(km_per_s).mag == mag<1000>);
constexpr auto km_per_h = kilometre / hour;
static_assert(is_of_type<km_per_h, derived_unit<kilometre_, per<hour_>>>);
static_assert(is_of_type<km_per_h, derived_unit<std::remove_const_t<decltype(si::kilo<metre>)>, per<hour_>>>);
static_assert(is_of_type<get_canonical_unit(km_per_h).reference_unit, derived_unit<metre_, per<second_>>>);
static_assert(get_canonical_unit(km_per_h).mag == mag_ratio<1000, 3600>);
@@ -373,17 +375,20 @@ static_assert(is_of_type<get_canonical_unit(standard_gravity / speed_of_light_in
// operations commutativity
constexpr auto u1 = mag<1000> * kilometre / hour;
static_assert(is_of_type<u1, scaled_unit<mag<1000>, derived_unit<kilometre_, per<hour_>>>>);
static_assert(
is_of_type<u1, scaled_unit<mag<1000>, derived_unit<std::remove_const_t<decltype(si::kilo<metre>)>, per<hour_>>>>);
static_assert(is_of_type<get_canonical_unit(u1).reference_unit, derived_unit<metre_, per<second_>>>);
static_assert(get_canonical_unit(u1).mag == mag_ratio<1'000'000, 3'600>);
constexpr auto u2 = mag<1000> * (kilometre / hour);
static_assert(is_of_type<u2, scaled_unit<mag<1000>, derived_unit<kilometre_, per<hour_>>>>);
static_assert(
is_of_type<u2, scaled_unit<mag<1000>, derived_unit<std::remove_const_t<decltype(si::kilo<metre>)>, per<hour_>>>>);
static_assert(is_of_type<get_canonical_unit(u2).reference_unit, derived_unit<metre_, per<second_>>>);
static_assert(get_canonical_unit(u2).mag == mag_ratio<1'000'000, 3'600>);
constexpr auto u3 = one / hour * (mag<1000> * kilometre);
static_assert(is_of_type<u3, scaled_unit<mag<1000>, derived_unit<kilometre_, per<hour_>>>>);
static_assert(
is_of_type<u3, scaled_unit<mag<1000>, derived_unit<std::remove_const_t<decltype(si::kilo<metre>)>, per<hour_>>>>);
static_assert(is_of_type<get_canonical_unit(u3).reference_unit, derived_unit<metre_, per<second_>>>);
static_assert(get_canonical_unit(u3).mag == mag_ratio<1'000'000, 3'600>);
@@ -499,9 +504,10 @@ static_assert(is_of_type<pow<1, 3>(metre* metre* metre), metre_>);
static_assert(is_of_type<pow<1, 3>(metre* metre), derived_unit<power<metre_, 2, 3>>>);
static_assert(is_of_type<pow<1, 2>(metre / second), derived_unit<power<metre_, 1, 2>, per<power<second_, 1, 2>>>>);
static_assert(is_of_type<pow<1, 2>(metre / (second * second)), derived_unit<power<metre_, 1, 2>, per<second_>>>);
static_assert(is_of_type<kilometre * kilometre, derived_unit<power<kilometre_, 2>>>);
static_assert(
is_of_type<kilometre * kilometre, derived_unit<power<std::remove_const_t<decltype(si::kilo<metre>)>, 2>>>);
static_assert(is_of_type<pow<2>(kilometre), derived_unit<power<kilometre_, 2>>>);
static_assert(is_of_type<pow<2>(kilometre), derived_unit<power<std::remove_const_t<decltype(si::kilo<metre>)>, 2>>>);
static_assert(is_of_type<pow<2>(si::kilo<metre>), derived_unit<power<si::kilo_<metre_>, 2>>>);
static_assert(is_of_type<pow<2>(hour), derived_unit<power<hour_, 2>>>);
static_assert(
@@ -509,11 +515,11 @@ static_assert(
// common_unit
static_assert(is_of_type<common_unit(gram, gram), gram_>);
static_assert(is_of_type<common_unit(kilogram, kilogram), kilogram_>);
static_assert(is_of_type<common_unit(si::kilo<gram>, kilogram), kilogram_>);
static_assert(is_of_type<common_unit(kilogram, si::kilo<gram>), kilogram_>);
static_assert(is_of_type<common_unit(mag<1000>* gram, kilogram), kilogram_>);
static_assert(is_of_type<common_unit(kilogram, mag<1000>* gram), kilogram_>);
static_assert(is_of_type<common_unit(kilogram, kilogram), std::remove_const_t<decltype(si::kilo<gram>)>>);
static_assert(is_of_type<common_unit(si::kilo<gram>, kilogram), std::remove_const_t<decltype(si::kilo<gram>)>>);
static_assert(is_of_type<common_unit(kilogram, si::kilo<gram>), std::remove_const_t<decltype(si::kilo<gram>)>>);
static_assert(is_of_type<common_unit(mag<1000>* gram, kilogram), std::remove_const_t<decltype(si::kilo<gram>)>>);
static_assert(is_of_type<common_unit(kilogram, mag<1000>* gram), std::remove_const_t<decltype(si::kilo<gram>)>>);
static_assert(is_of_type<common_unit(one / second, hertz), hertz_>);
static_assert(is_of_type<common_unit(hertz, one / second), hertz_>);
static_assert(is_of_type<common_unit(gram, kilogram), gram_>);