From daf97a3a8608207cf41a3b24a7815f5bbef7180f Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 8 Sep 2022 19:11:45 +0200 Subject: [PATCH 001/402] feat: initial very dirty version of V2 framework --- CMakeLists.txt | 9 +- example/CMakeLists.txt | 26 +- example/hello_units.cpp | 416 +++++++++++++++-- example/v2_framework.cpp | 418 ++++++++++++++++++ src/core/CMakeLists.txt | 5 +- src/core/include/units/base_dimension.h | 66 --- .../units/bits/derived_dimension_base.h | 60 --- .../include/units/bits/derived_scaled_unit.h | 48 -- src/core/include/units/bits/dim_consolidate.h | 67 --- src/core/include/units/bits/dim_unpack.h | 59 --- src/core/include/units/bits/dimension_op.h | 208 --------- .../include/units/bits/expression_template.h | 390 ++++++++++++++++ .../include/units/bits/external/type_list.h | 50 +++ .../include/units/bits/external/type_name.h | 27 ++ src/core/include/units/derived_dimension.h | 92 ---- src/core/include/units/dimension.h | 260 +++++++++++ src/core/include/units/exponent.h | 85 ---- src/core/include/units/magnitude.h | 2 +- src/core/include/units/prefix.h | 62 --- src/core/include/units/reference.h | 139 +++--- src/core/include/units/unit.h | 272 +++++++----- .../si/include/units/isq/si/prefixes.h | 64 ++- 22 files changed, 1829 insertions(+), 996 deletions(-) create mode 100644 example/v2_framework.cpp delete mode 100644 src/core/include/units/base_dimension.h delete mode 100644 src/core/include/units/bits/derived_dimension_base.h delete mode 100644 src/core/include/units/bits/derived_scaled_unit.h delete mode 100644 src/core/include/units/bits/dim_consolidate.h delete mode 100644 src/core/include/units/bits/dim_unpack.h delete mode 100644 src/core/include/units/bits/dimension_op.h create mode 100644 src/core/include/units/bits/expression_template.h create mode 100644 src/core/include/units/bits/external/type_name.h delete mode 100644 src/core/include/units/derived_dimension.h create mode 100644 src/core/include/units/dimension.h delete mode 100644 src/core/include/units/exponent.h delete mode 100644 src/core/include/units/prefix.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f0ca1045..29e11b68 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,7 @@ add_compile_definitions($<$:gsl_CONFIG_CONTRACT_CHECKING_AUDIT>) # enable include-what-you-use option(${projectPrefix}IWYU "Enables include-what-you-use" OFF) + if(${projectPrefix}IWYU) include(include-what-you-use) enable_iwyu( @@ -52,12 +53,13 @@ if(${projectPrefix}IWYU) MAX_LINE_LENGTH 120 NO_COMMENTS ) + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(${projectPrefix}AS_SYSTEM_HEADERS ON) endif() endif() -#enable_clang_tidy() +# enable_clang_tidy() # add project code add_subdirectory(src) @@ -66,11 +68,12 @@ add_subdirectory(src) add_subdirectory(example) # generate project documentation -add_subdirectory(docs) +# add_subdirectory(docs) # add unit tests enable_testing() -add_subdirectory(test) + +# add_subdirectory(test) # tests for standalone headers include(TestPublicHeaders) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 6733348b..686b57ac 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -33,17 +33,19 @@ function(add_example target) target_link_libraries(${target} PRIVATE ${ARGN}) endfunction() -add_example(conversion_factor mp-units::core-fmt mp-units::core-io mp-units::si) -add_example(custom_systems mp-units::core-io mp-units::si) -add_example(hello_units mp-units::core-fmt mp-units::core-io mp-units::si mp-units::si-international) -add_example(measurement mp-units::core-io mp-units::si) -add_example(si_constants mp-units::core-fmt mp-units::si) +add_example(v2_framework mp-units::core-fmt mp-units::core-io mp-units::si) -if(NOT ${projectPrefix}LIBCXX) - add_subdirectory(glide_computer) -endif() +# add_example(conversion_factor mp-units::core-fmt mp-units::core-io mp-units::si) +# add_example(custom_systems mp-units::core-io mp-units::si) +# add_example(hello_units mp-units::core-fmt mp-units::core-io mp-units::si mp-units::si-international) +# add_example(measurement mp-units::core-io mp-units::si) +# add_example(si_constants mp-units::core-fmt mp-units::si) -add_subdirectory(aliases) -add_subdirectory(kalman_filter) -add_subdirectory(literals) -add_subdirectory(references) +# if(NOT ${projectPrefix}LIBCXX) +# add_subdirectory(glide_computer) +# endif() + +# add_subdirectory(aliases) +# add_subdirectory(kalman_filter) +# add_subdirectory(literals) +# add_subdirectory(references) diff --git a/example/hello_units.cpp b/example/hello_units.cpp index 5bfbc860..d9620410 100644 --- a/example/hello_units.cpp +++ b/example/hello_units.cpp @@ -20,43 +20,391 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -#include -#include -#include // IWYU pragma: keep -#include -#include // IWYU pragma: keep -#include -#include -#include +// #include +#include -using namespace units::isq; +namespace units::isq { -constexpr Speed auto avg_speed(Length auto d, Time auto t) { return d / t; } +inline constexpr struct dim_length : base_dimension<"L"> { +} dim_length; + +// template +// concept Length = QuantityOf; + +inline constexpr struct dim_time : base_dimension<"T"> { +} dim_time; +inline constexpr struct dim_frequency : decltype(1 / dim_time) { +} dim_frequency; +inline constexpr struct dim_area : decltype(dim_length * dim_length) { +} dim_area; +inline constexpr struct dim_volume : decltype(dim_area * dim_length) { +} dim_volume; +inline constexpr struct dim_speed : decltype(dim_length / dim_time) { +} dim_speed; +inline constexpr struct dim_acceleration : decltype(dim_speed / dim_time) { +} dim_acceleration; + +// inline constexpr auto speed = length / time; + +} // namespace units::isq + +#include +#include + +namespace units { + +namespace isq::si { + +// length units +inline constexpr struct metre : named_unit<"m"> { +} metre; +inline constexpr struct kilometre : kilo { +} kilometre; + +inline constexpr struct astronomical_unit : named_scaled_unit<"au", mag<149'597'870'700>(), metre> { +} astronomical_unit; + +// area units +inline constexpr struct square_metre : derived_unit { +} square_metre; + +// volume units +inline constexpr struct cubic_metre : derived_unit { +} cubic_metre; + +// time units +inline constexpr struct second : named_unit<"s"> { +} second; +inline constexpr struct minute : named_scaled_unit<"min", mag<60>(), second> { +} minute; +inline constexpr struct hour : named_scaled_unit<"h", mag<60>(), minute> { +} hour; +inline constexpr struct day : named_scaled_unit<"d", mag<24>(), hour> { +} day; + +// not a time unit! +inline constexpr struct second_squared : derived_unit { +} second_squared; + +// mass units +inline constexpr struct gram : named_unit<"g"> { +} gram; +inline constexpr struct kilogram : kilo { +} kilogram; +inline constexpr struct tonne : named_scaled_unit<"t", mag<1000>(), gram> { +} tonne; + +// other units +inline constexpr struct hertz : named_unit<"Hz", 1 / second> { +} hertz; +inline constexpr struct newton : named_unit<"N", kilogram * metre / second_squared> { +} newton; +inline constexpr struct pascal : named_unit<"Pa", kilogram / (metre * second_squared)> { +} pascal; +inline constexpr struct joule : named_unit<"J", newton * metre> { +} joule; +inline constexpr struct watt : named_unit<"W", joule / second> { +} watt; + +namespace short_units { + +// TODO collide with reference names +// inline namespace length { + +inline constexpr auto m = metre; +inline constexpr auto km = kilometre; +inline constexpr auto au = astronomical_unit; + +// } // namespace length + +// inline namespace area { + +inline constexpr auto m2 = square_metre; + +// } + +// inline namespace volume { + +inline constexpr auto m3 = cubic_metre; + +// } + +// inline namespace time { + +inline constexpr auto s = second; +inline constexpr auto min = minute; +inline constexpr auto h = hour; +inline constexpr auto d = day; + +inline constexpr auto s2 = second_squared; + +// } // namespace time + +// inline namespace mass { + +inline constexpr auto g = gram; +inline constexpr auto kg = kilogram; +inline constexpr auto t = tonne; + +// } // namespace mass + +// inline namespace frequency { + +inline constexpr auto Hz = hertz; + +// } + +// inline namespace force { + +inline constexpr auto N = newton; + +// } + +// inline namespace pressure { + +inline constexpr auto Pa = pascal; + +// } + +// inline namespace energy { + +inline constexpr auto J = joule; + +// } + +// inline namespace power { + +inline constexpr auto W = watt; + +// } + +} // namespace short_units + +} // namespace isq::si +} // namespace units + +#include + +namespace units::isq::si { + +inline constexpr struct length : system_reference { +} length; +inline constexpr struct time : system_reference { +} time; +inline constexpr struct frequency : system_reference { +} frequency; +inline constexpr struct area : system_reference { +} area; +inline constexpr struct volume : system_reference { +} volume; +inline constexpr struct speed : system_reference { +} speed; +inline constexpr struct acceleration : system_reference { +} acceleration; + +} // namespace units::isq::si + + +template +inline constexpr bool is_of_type = std::is_same_v, T>; + +namespace units::isq { + +// derived dimension expression template syntax verification +static_assert(is_of_type<1 / dim_time, derived_dimension>>); +static_assert(is_of_type<1 / (1 / dim_time), struct dim_time>); + +static_assert(is_of_type); +static_assert(is_of_type); +static_assert(is_of_type>>); +static_assert(is_of_type<1 / dim_time * dim_one, derived_dimension>>); + +static_assert(is_of_type>); +static_assert(is_of_type>>); + +static_assert( + is_of_type, struct dim_time>>); +static_assert( + is_of_type, struct dim_time>>); + +static_assert( + is_of_type, struct dim_time>>); +static_assert( + is_of_type, struct dim_time>>); + +static_assert(is_of_type<1 / dim_time * dim_length, derived_dimension>>); +static_assert(is_of_type<1 / dim_time * dim_time, struct dim_one>); + +static_assert(is_of_type); +static_assert(is_of_type<1 / dim_time / dim_one, derived_dimension>>); + +static_assert(is_of_type); +static_assert( + is_of_type<1 / dim_time * (1 / dim_time), derived_dimension>>>); +static_assert(is_of_type<1 / (dim_time * dim_time), derived_dimension>>>); +static_assert(is_of_type<1 / (1 / (dim_time * dim_time)), derived_dimension>>); + +static_assert(is_of_type>>>); +static_assert(is_of_type, per>>>); +static_assert(is_of_type); + +static_assert( + is_of_type>>); +static_assert( + is_of_type>>); +static_assert(is_of_type, per>>); +static_assert(is_of_type<1 / (dim_speed * dim_speed) * dim_length, + derived_dimension>>>); + +// comparisons of equivalent dimensions +static_assert(dim_length / dim_length == dim_one); + +static_assert(1 / dim_time == dim_frequency); +static_assert(1 / dim_frequency == dim_time); +static_assert(dim_frequency * dim_time == dim_one); + +static_assert(dim_length * dim_length == dim_area); +static_assert(dim_length * dim_length != dim_volume); +static_assert(dim_area / dim_length == dim_length); + +static_assert(dim_length * dim_length * dim_length == dim_volume); +static_assert(dim_area * dim_length == dim_volume); +static_assert(dim_volume / dim_length == dim_area); +static_assert(dim_volume / dim_length / dim_length == dim_length); +static_assert(dim_area * dim_area / dim_length == dim_volume); +static_assert(dim_area * (dim_area / dim_length) == dim_volume); +static_assert(dim_volume / (dim_length * dim_length) == dim_length); + +static_assert(dim_length / dim_time == dim_speed); +static_assert(dim_length * dim_time != dim_speed); +static_assert(dim_length / dim_time / dim_time != dim_speed); +static_assert(dim_length / dim_speed == dim_time); +static_assert(dim_speed * dim_time == dim_length); + +static_assert(dim_length / dim_time / dim_time == dim_acceleration); +static_assert(dim_length / (dim_time * dim_time) == dim_acceleration); +static_assert(dim_speed / dim_time == dim_acceleration); +static_assert(dim_speed / dim_acceleration == dim_time); +static_assert(dim_acceleration * dim_time == dim_speed); +static_assert(dim_acceleration * (dim_time * dim_time) == dim_length); +static_assert(dim_acceleration / dim_speed == dim_frequency); + +} // namespace units::isq + + +namespace units::isq::si { + +// derived unit expression template syntax verification +static_assert(is_of_type<1 / second, derived_unit>>); +static_assert(is_of_type<1 / (1 / second), struct second>); + +static_assert(is_of_type); +static_assert(is_of_type); +static_assert(is_of_type>>); +static_assert(is_of_type<1 / second * one, derived_unit>>); + +static_assert(is_of_type>); +static_assert(is_of_type>>); + +static_assert(is_of_type, struct second>>); +static_assert(is_of_type, struct second>>); + +static_assert(is_of_type, struct second>>); +static_assert(is_of_type, struct second>>); + +static_assert(is_of_type<1 / second * metre, derived_unit>>); +static_assert(is_of_type<1 / second * second, struct one>); + +static_assert(is_of_type); +static_assert(is_of_type<1 / second / one, derived_unit>>); + +static_assert(is_of_type); +static_assert(is_of_type<1 / second * (1 / second), derived_unit>>>); +static_assert(is_of_type<1 / (second * second), derived_unit>>>); +static_assert(is_of_type<1 / (1 / (second * second)), derived_unit>>); + +static_assert(is_of_type>>>); +static_assert( + is_of_type, per>>>); +static_assert(is_of_type); + +static_assert(is_of_type>>); +static_assert(is_of_type>>); + +// comparisons of equivalent dimensions +// static_assert(metre / metre == one); + +// static_assert(1 / second == dim_frequency); +// static_assert(1 / dim_frequency == second); +// static_assert(dim_frequency * second == one); + +// static_assert(metre * metre == dim_area); +// static_assert(metre * metre != dim_volume); +// static_assert(dim_area / metre == metre); + +// static_assert(metre * metre * metre == dim_volume); +// static_assert(dim_area * metre == dim_volume); +// static_assert(dim_volume / metre == dim_area); +// static_assert(dim_volume / metre / metre == metre); +// static_assert(dim_area * dim_area / metre == dim_volume); +// static_assert(dim_area * (dim_area / metre) == dim_volume); +// static_assert(dim_volume / (metre * metre) == metre); + +// static_assert(metre / second == dim_speed); +// static_assert(metre * second != dim_speed); +// static_assert(metre / second / second != dim_speed); +// static_assert(metre / dim_speed == second); +// static_assert(dim_speed * second == metre); + +// static_assert(metre / second / second == dim_acceleration); +// static_assert(metre / (second * second) == dim_acceleration); +// static_assert(dim_speed / second == dim_acceleration); +// static_assert(dim_speed / dim_acceleration == second); +// static_assert(dim_acceleration * second == dim_speed); +// static_assert(dim_acceleration * (second * second) == metre); +// static_assert(dim_acceleration / dim_speed == dim_frequency); + + +// Bq + Hz should not compile + +// Bq + Hz + 1/s should compile? + + +} // namespace units::isq::si + + +using namespace units; +using namespace units::isq::si; +using namespace units::isq::si::short_units; + +/* Frequency */ auto freq1 = 20 * frequency[Hz]; +// /* Frequency */ auto freq2 = 20 / (1 * time[s]); +quantity freq3(20); +// quantity freq4(20); +// quantity<1 / time[s]> freq5(20); + + +/* Speed */ auto speed1 = 20 * speed[m / s]; +/* Speed */ auto speed2 = 20 * (length[m] / isq::si::time[s]); +// quantity speed3(20); +// quantity speed4(20); + + +// quantity / second> speed1(123); +// quantity speed2(123); +// auto speed3 = 123 * (kilo / second); +// auto speed4 = 123 * (km / s); + +template +void print(); + +// constexpr auto avg_speed(quantity d, quantity t) { return d / t; } int main() { - using namespace units::isq::si::literals; - using namespace units::isq::si::references; - using namespace units::aliases::isq::si::international; - - constexpr Speed auto v1 = 110 * (km / h); - constexpr Speed auto v2 = mi_per_h<>(70.); - constexpr Speed auto v3 = avg_speed(220_q_km, 2_q_h); - constexpr Speed auto v4 = avg_speed(si::length(140), si::time(2)); -#if UNITS_DOWNCAST_MODE == 0 - constexpr Speed auto v5 = quantity_cast>(v3); - constexpr Speed auto v6 = quantity_cast(v4); -#else - constexpr Speed auto v5 = quantity_cast>(v3); - constexpr Speed auto v6 = quantity_cast(v4); -#endif - constexpr Speed auto v7 = quantity_cast(v6); - - std::cout << v1 << '\n'; // 110 km/h - std::cout << v2 << '\n'; // 70 mi/h - std::cout << STD_FMT::format("{}", v3) << '\n'; // 110 km/h - std::cout << STD_FMT::format("{:*^14}", v4) << '\n'; // ***70 mi/h**** - std::cout << STD_FMT::format("{:%Q in %q}", v5) << '\n'; // 30.5556 in m/s - std::cout << STD_FMT::format("{0:%Q} in {0:%q}", v6) << '\n'; // 31.2928 in m/s - std::cout << STD_FMT::format("{:%Q}", v7) << '\n'; // 31 + print(); + print(); } diff --git a/example/v2_framework.cpp b/example/v2_framework.cpp new file mode 100644 index 00000000..9fbf1f4c --- /dev/null +++ b/example/v2_framework.cpp @@ -0,0 +1,418 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// 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. + +// #include +#include + +namespace units::isq { + +inline constexpr struct dim_length : base_dimension<"L"> { +} dim_length; + +// template +// concept Length = QuantityOf; + +inline constexpr struct dim_time : base_dimension<"T"> { +} dim_time; +inline constexpr struct dim_frequency : decltype(1 / dim_time) { +} dim_frequency; +inline constexpr struct dim_area : decltype(dim_length * dim_length) { +} dim_area; +inline constexpr struct dim_volume : decltype(dim_area * dim_length) { +} dim_volume; +inline constexpr struct dim_speed : decltype(dim_length / dim_time) { +} dim_speed; +inline constexpr struct dim_acceleration : decltype(dim_speed / dim_time) { +} dim_acceleration; + +// inline constexpr auto speed = length / time; + +} // namespace units::isq + +#include +#include + +namespace units { + +namespace isq::si { + +// length units +inline constexpr struct metre : named_unit<"m"> { +} metre; +inline constexpr struct kilometre : kilo { +} kilometre; + +inline constexpr struct astronomical_unit : named_scaled_unit<"au", mag<149'597'870'700>(), metre> { +} astronomical_unit; + +// area units +inline constexpr struct square_metre : derived_unit { +} square_metre; + +// volume units +inline constexpr struct cubic_metre : derived_unit { +} cubic_metre; + +// time units +inline constexpr struct second : named_unit<"s"> { +} second; +inline constexpr struct minute : named_scaled_unit<"min", mag<60>(), second> { +} minute; +inline constexpr struct hour : named_scaled_unit<"h", mag<60>(), minute> { +} hour; +inline constexpr struct day : named_scaled_unit<"d", mag<24>(), hour> { +} day; + +// not a time unit! +inline constexpr struct second_squared : derived_unit { +} second_squared; + +// mass units +inline constexpr struct gram : named_unit<"g"> { +} gram; +inline constexpr struct kilogram : kilo { +} kilogram; +inline constexpr struct tonne : named_scaled_unit<"t", mag<1000>(), gram> { +} tonne; + +// other units +inline constexpr struct hertz : named_unit<"Hz", 1 / second> { +} hertz; +inline constexpr struct newton : named_unit<"N", kilogram * metre / second_squared> { +} newton; +inline constexpr struct pascal : named_unit<"Pa", kilogram / (metre * second_squared)> { +} pascal; +inline constexpr struct joule : named_unit<"J", newton * metre> { +} joule; +inline constexpr struct watt : named_unit<"W", joule / second> { +} watt; + +namespace short_units { + +// TODO collide with reference names +// inline namespace length { + +inline constexpr auto m = metre; +inline constexpr auto km = kilometre; +inline constexpr auto au = astronomical_unit; + +// } // namespace length + +// inline namespace area { + +inline constexpr auto m2 = square_metre; + +// } + +// inline namespace volume { + +inline constexpr auto m3 = cubic_metre; + +// } + +// inline namespace time { + +inline constexpr auto s = second; +inline constexpr auto min = minute; +inline constexpr auto h = hour; +inline constexpr auto d = day; + +inline constexpr auto s2 = second_squared; + +// } // namespace time + +// inline namespace mass { + +inline constexpr auto g = gram; +inline constexpr auto kg = kilogram; +inline constexpr auto t = tonne; + +// } // namespace mass + +// inline namespace frequency { + +inline constexpr auto Hz = hertz; + +// } + +// inline namespace force { + +inline constexpr auto N = newton; + +// } + +// inline namespace pressure { + +inline constexpr auto Pa = pascal; + +// } + +// inline namespace energy { + +inline constexpr auto J = joule; + +// } + +// inline namespace power { + +inline constexpr auto W = watt; + +// } + +} // namespace short_units + +} // namespace isq::si +} // namespace units + +#include + +namespace units { + +inline constexpr struct dimensionless : system_reference { +} dimensionless; + +} // namespace units + +namespace units::isq::si { + +inline constexpr struct length : system_reference { +} length; +inline constexpr struct time : system_reference { +} time; +inline constexpr struct frequency : system_reference { +} frequency; +inline constexpr struct area : system_reference { +} area; +inline constexpr struct volume : system_reference { +} volume; +inline constexpr struct speed : system_reference { +} speed; +inline constexpr struct acceleration : system_reference { +} acceleration; + +} // namespace units::isq::si + + +template +inline constexpr bool is_of_type = std::is_same_v, T>; + +namespace units::isq { + +// derived dimension expression template syntax verification +static_assert(is_of_type<1 / dim_time, derived_dimension>>); +static_assert(is_of_type<1 / (1 / dim_time), struct dim_time>); + +static_assert(is_of_type); +static_assert(is_of_type); +static_assert(is_of_type>>); +static_assert(is_of_type<1 / dim_time * dim_one, derived_dimension>>); + +static_assert(is_of_type>); +static_assert(is_of_type>>); + +static_assert( + is_of_type, struct dim_time>>); +static_assert( + is_of_type, struct dim_time>>); + +static_assert( + is_of_type, struct dim_time>>); +static_assert( + is_of_type, struct dim_time>>); + +static_assert(is_of_type<1 / dim_time * dim_length, derived_dimension>>); +static_assert(is_of_type<1 / dim_time * dim_time, struct dim_one>); + +static_assert(is_of_type); +static_assert(is_of_type<1 / dim_time / dim_one, derived_dimension>>); + +static_assert(is_of_type); +static_assert( + is_of_type<1 / dim_time * (1 / dim_time), derived_dimension>>>); +static_assert(is_of_type<1 / (dim_time * dim_time), derived_dimension>>>); +static_assert(is_of_type<1 / (1 / (dim_time * dim_time)), derived_dimension>>); + +static_assert(is_of_type>>>); +static_assert(is_of_type, per>>>); +static_assert(is_of_type); + +static_assert( + is_of_type>>); +static_assert( + is_of_type>>); +static_assert(is_of_type, per>>); +static_assert(is_of_type<1 / (dim_speed * dim_speed) * dim_length, + derived_dimension>>>); + +// comparisons of equivalent dimensions +static_assert(dim_length / dim_length == dim_one); + +static_assert(1 / dim_time == dim_frequency); +static_assert(1 / dim_frequency == dim_time); +static_assert(dim_frequency * dim_time == dim_one); + +static_assert(dim_length * dim_length == dim_area); +static_assert(dim_length * dim_length != dim_volume); +static_assert(dim_area / dim_length == dim_length); + +static_assert(dim_length * dim_length * dim_length == dim_volume); +static_assert(dim_area * dim_length == dim_volume); +static_assert(dim_volume / dim_length == dim_area); +static_assert(dim_volume / dim_length / dim_length == dim_length); +static_assert(dim_area * dim_area / dim_length == dim_volume); +static_assert(dim_area * (dim_area / dim_length) == dim_volume); +static_assert(dim_volume / (dim_length * dim_length) == dim_length); + +static_assert(dim_length / dim_time == dim_speed); +static_assert(dim_length * dim_time != dim_speed); +static_assert(dim_length / dim_time / dim_time != dim_speed); +static_assert(dim_length / dim_speed == dim_time); +static_assert(dim_speed * dim_time == dim_length); + +static_assert(dim_length / dim_time / dim_time == dim_acceleration); +static_assert(dim_length / (dim_time * dim_time) == dim_acceleration); +static_assert(dim_speed / dim_time == dim_acceleration); +static_assert(dim_speed / dim_acceleration == dim_time); +static_assert(dim_acceleration * dim_time == dim_speed); +static_assert(dim_acceleration * (dim_time * dim_time) == dim_length); +static_assert(dim_acceleration / dim_speed == dim_frequency); + +} // namespace units::isq + + +namespace units::isq::si { + +// derived unit expression template syntax verification +static_assert(is_of_type<1 / second, derived_unit>>); +static_assert(is_of_type<1 / (1 / second), struct second>); + +static_assert(is_of_type); +static_assert(is_of_type); +static_assert(is_of_type>>); +static_assert(is_of_type<1 / second * one, derived_unit>>); + +static_assert(is_of_type>); +static_assert(is_of_type>>); + +static_assert(is_of_type, struct second>>); +static_assert(is_of_type, struct second>>); + +static_assert(is_of_type, struct second>>); +static_assert(is_of_type, struct second>>); + +static_assert(is_of_type<1 / second * metre, derived_unit>>); +static_assert(is_of_type<1 / second * second, struct one>); + +static_assert(is_of_type); +static_assert(is_of_type<1 / second / one, derived_unit>>); + +static_assert(is_of_type); +static_assert(is_of_type<1 / second * (1 / second), derived_unit>>>); +static_assert(is_of_type<1 / (second * second), derived_unit>>>); +static_assert(is_of_type<1 / (1 / (second * second)), derived_unit>>); + +static_assert(is_of_type>>>); +static_assert( + is_of_type, per>>>); +static_assert(is_of_type); + +static_assert(is_of_type>>); +static_assert(is_of_type>>); + +// comparisons of equivalent dimensions +// static_assert(metre / metre == one); + +// static_assert(1 / second == dim_frequency); +// static_assert(1 / dim_frequency == second); +// static_assert(dim_frequency * second == one); + +// static_assert(metre * metre == dim_area); +// static_assert(metre * metre != dim_volume); +// static_assert(dim_area / metre == metre); + +// static_assert(metre * metre * metre == dim_volume); +// static_assert(dim_area * metre == dim_volume); +// static_assert(dim_volume / metre == dim_area); +// static_assert(dim_volume / metre / metre == metre); +// static_assert(dim_area * dim_area / metre == dim_volume); +// static_assert(dim_area * (dim_area / metre) == dim_volume); +// static_assert(dim_volume / (metre * metre) == metre); + +// static_assert(metre / second == dim_speed); +// static_assert(metre * second != dim_speed); +// static_assert(metre / second / second != dim_speed); +// static_assert(metre / dim_speed == second); +// static_assert(dim_speed * second == metre); + +// static_assert(metre / second / second == dim_acceleration); +// static_assert(metre / (second * second) == dim_acceleration); +// static_assert(dim_speed / second == dim_acceleration); +// static_assert(dim_speed / dim_acceleration == second); +// static_assert(dim_acceleration * second == dim_speed); +// static_assert(dim_acceleration * (second * second) == metre); +// static_assert(dim_acceleration / dim_speed == dim_frequency); + + +// Bq + Hz should not compile + +// Bq + Hz + 1/s should compile? + + +} // namespace units::isq::si + + +using namespace units; +using namespace units::isq::si; +using namespace units::isq::si::short_units; + +/* Frequency */ auto freq1 = 20 * frequency[Hz]; +// /* Frequency */ auto freq2 = 20 / (1 * isq::si::time[s]); +quantity freq3(20); +quantity freq4(20); +quantity freq5(20); + +/* Speed */ auto speed1 = 20 * speed[m / s]; +/* Speed */ auto speed2 = 20 * (length[m] / isq::si::time[s]); +quantity speed3(20); +quantity speed4(20); + +template +void print(); + +// constexpr auto avg_speed(quantity d, quantity t) { return d / t; } + +int main() +{ + print(); + // print(); + print(); + print(); + print(); + + print(); + print(); + print(); + print(); +} diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 56f462af..e39c7bd9 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -37,12 +37,10 @@ check_libcxx_in_use(${projectPrefix}LIBCXX) add_library( mp-units-core INTERFACE - include/units/base_dimension.h include/units/chrono.h include/units/concepts.h include/units/customization_points.h - include/units/derived_dimension.h - include/units/exponent.h + include/units/dimension.h include/units/generic/angle.h include/units/generic/dimensionless.h include/units/generic/solid_angle.h @@ -50,7 +48,6 @@ add_library( include/units/magnitude.h include/units/math.h include/units/point_origin.h - include/units/prefix.h include/units/quantity.h include/units/quantity_cast.h include/units/quantity_kind.h diff --git a/src/core/include/units/base_dimension.h b/src/core/include/units/base_dimension.h deleted file mode 100644 index 0af40adb..00000000 --- a/src/core/include/units/base_dimension.h +++ /dev/null @@ -1,66 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -// IWYU pragma: end_exports - -#include - -namespace units { - -/** - * @brief A dimension of a base quantity - * - * Base quantity is a quantity in a conventionally chosen subset of a given system of quantities, where no quantity - * in the subset can be expressed in terms of the other quantities within that subset. They are referred to as - * being mutually independent since a base quantity cannot be expressed as a product of powers of the other base - * quantities. - * - * Base unit is a measurement unit that is adopted by convention for a base quantity in a specific system of units. - * - * Pair of Symbol and Unit template parameters form an unique identifier of the base dimension. The same identifiers can - * be multiplied and divided which will result with an adjustment of its factor in an Exponent of a DerivedDimension - * (in case of zero the dimension will be simplified and removed from further analysis of current expresion). In case - * the Symbol is the same but the Unit differs (i.e. mixing SI and CGS length), there is no automatic simplification but - * is possible to force it with a quantity_cast. - * - * @tparam Symbol an unique identifier of the base dimension used to provide dimensional analysis support - * @tparam U a base unit to be used for this base dimension - */ -template -struct base_dimension { - static constexpr auto symbol = Symbol; ///< Unique base dimension identifier - using base_unit = U; ///< Base unit adopted for this dimension - static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag = magnitude{}; -}; - -// base_dimension_less -template -struct base_dimension_less : - std::bool_constant<(D1::symbol < D2::symbol) || - (D1::symbol == D2::symbol && D1::base_unit::symbol < D1::base_unit::symbol)> {}; - -} // namespace units diff --git a/src/core/include/units/bits/derived_dimension_base.h b/src/core/include/units/bits/derived_dimension_base.h deleted file mode 100644 index 9284eb0e..00000000 --- a/src/core/include/units/bits/derived_dimension_base.h +++ /dev/null @@ -1,60 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::detail { - -/** - * @brief A dimension of a derived quantity - * - * Expression of the dependence of a quantity on the base quantities (and their base dimensions) of a system of - * quantities as a product of powers of factors corresponding to the base quantities, omitting any numerical factors. - * A power of a factor is the factor raised to an exponent. - * - * A derived dimension can be formed from multiple exponents (i.e. speed is represented as "exponent, exponent"). It is also possible to form a derived dimension with only one exponent (i.e. frequency is represented as just - * "exponent"). - * - * @note This class template is used by the library engine and should not be directly instantiated by the user. - * - * @tparam Es zero or more exponents of a derived dimension - */ -template - requires(BaseDimension && ...) -struct derived_dimension_base : downcast_base> { - using exponents = exponent_list; -}; - -template -struct to_derived_dimension_base; - -template -struct to_derived_dimension_base> { - using type = derived_dimension_base; -}; - -} // namespace units::detail diff --git a/src/core/include/units/bits/derived_scaled_unit.h b/src/core/include/units/bits/derived_scaled_unit.h deleted file mode 100644 index d62b6f45..00000000 --- a/src/core/include/units/bits/derived_scaled_unit.h +++ /dev/null @@ -1,48 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include - -namespace units::detail { - -// compatible_units -template -inline constexpr bool compatible_units = false; - -template -inline constexpr bool compatible_units, Us...> = (UnitOf && ...); - -// derived_scaled_unit - -template -constexpr Magnitude auto derived_mag(exponent_list) -{ - return (magnitude<>{} * ... * pow(Us::mag / dimension_unit::mag)); -} - -template -using derived_scaled_unit = scaled_unit(typename D::recipe()), typename D::coherent_unit::reference>; - -} // namespace units::detail diff --git a/src/core/include/units/bits/dim_consolidate.h b/src/core/include/units/bits/dim_consolidate.h deleted file mode 100644 index 2590b460..00000000 --- a/src/core/include/units/bits/dim_consolidate.h +++ /dev/null @@ -1,67 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::detail { - -/** - * @brief Consolidates contiguous ranges of exponents of the same dimension - * - * If there is more than one exponent with the same dimension they are aggregated into one exponent by adding - * their exponents. If this accumulation will result with 0, such a dimension is removed from the list. - * - * @tparam D derived dimension to consolidate - */ -template -struct dim_consolidate; - -template<> -struct dim_consolidate> { - using type = exponent_list<>; -}; - -template -struct dim_consolidate> { - using type = exponent_list; -}; - -template -struct dim_consolidate> { - using type = type_list_push_front>::type, E1>; -}; - -template -struct dim_consolidate, exponent, ERest...>> { - using r1 = std::ratio; - using r2 = std::ratio; - using r = std::ratio_add; - using type = conditional>::type, - typename dim_consolidate, ERest...>>::type>; -}; - -} // namespace units::detail diff --git a/src/core/include/units/bits/dim_unpack.h b/src/core/include/units/bits/dim_unpack.h deleted file mode 100644 index ae018f2a..00000000 --- a/src/core/include/units/bits/dim_unpack.h +++ /dev/null @@ -1,59 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::detail { - -/** - * @brief Unpacks the list of potentially derived dimensions to a list containing only base dimensions - * - * @tparam Es Exponents of potentially derived dimensions - */ -template -struct dim_unpack; - -template<> -struct dim_unpack<> { - using type = exponent_list<>; -}; - -template -struct dim_unpack, ERest...> { - using type = type_list_push_front::type, exponent>; -}; - -template -struct dim_unpack, ERest...> { - using type = TYPENAME dim_unpack, Num, Den>, ERest...>::type; -}; - -template -struct dim_unpack, Num, Den>, ERest...> { - using type = type_list_push_front::type, exponent_multiply...>; -}; - -} // namespace units::detail diff --git a/src/core/include/units/bits/dimension_op.h b/src/core/include/units/bits/dimension_op.h deleted file mode 100644 index 820fbc82..00000000 --- a/src/core/include/units/bits/dimension_op.h +++ /dev/null @@ -1,208 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -namespace units { - -/** - * @brief Unknown dimension - * - * Sometimes a temporary partial result of a complex calculation may not result in a predefined - * dimension. In such a case an `unknown_dimension` is created with a coherent unit of `unknown_coherent_unit` - * with a magnitude being the absolute one of all the exponents of such a dimension. - * - * @tparam Es the list of exponents of ingredient dimensions - */ -template -struct unknown_dimension : derived_dimension, unknown_coherent_unit, Es...> {}; - -namespace detail { - -template -struct check_unknown { - using type = D; -}; - -// downcast did not find a user predefined type -template -struct check_unknown> { - using type = unknown_dimension; -}; - -template -struct downcast_dimension_impl; - -template -struct downcast_dimension_impl { - using type = D; -}; - -template -struct downcast_dimension_impl { - using type = TYPENAME check_unknown>::type; -}; - -} // namespace detail - -template -using downcast_dimension = TYPENAME detail::downcast_dimension_impl::type; - -// dim_invert -namespace detail { - -template -struct dim_invert_impl; - -template -struct dim_invert_impl { - using type = downcast_dimension>>; -}; - -template -struct dim_invert_impl>> { - using type = D; -}; - -template -struct dim_invert_impl> { - using type = downcast_dimension...>>; -}; - -template -struct dim_invert_impl : dim_invert_impl> {}; - -} // namespace detail - -template -using dim_invert = TYPENAME detail::dim_invert_impl::type; - -// dimension_multiply -namespace detail { - -template -struct to_dimension; - -template -struct to_dimension> { - using type = derived_dimension_base; -}; - -template -struct to_dimension>> { - using type = D; -}; - -/** - * @brief Merges 2 sorted derived dimensions into one units::derived_dimension_base - * - * A result of a dimensional calculation may result with many exponents of the same base dimension orginated - * from different parts of the equation. As the exponents lists of both operands it is enough to merge them - * into one list and consolidate duplicates. Also it is possible that final exponents list will contain only - * one element being a base dimension with exponent 1. In such a case the final dimension should be the base - * dimension itself. - */ -template -using merge_dimension = TYPENAME to_dimension>::type>::type; - -template -struct dimension_multiply_impl; - -template -struct dimension_multiply_impl { - using type = downcast_dimension< - merge_dimension>, derived_dimension_base>>>; -}; - -template -struct dimension_multiply_impl { - using type = - downcast_dimension>, typename D2::downcast_base_type>>; -}; - -template -struct dimension_multiply_impl { - using type = TYPENAME dimension_multiply_impl::type; -}; - -template -struct dimension_multiply_impl { - using type = downcast_dimension>; -}; - -} // namespace detail - -template -using dimension_multiply = TYPENAME detail::dimension_multiply_impl::type; - -template -using dimension_divide = TYPENAME detail::dimension_multiply_impl>::type; - -// dimension_pow -namespace detail { - -template -struct dimension_pow_impl; - -template -struct dimension_pow_impl { - using type = downcast_dimension>>; -}; - -template -struct dimension_pow_impl { - using type = D; -}; - -template -struct dimension_pow_impl>, Num, Den> { - using type = D; -}; - -template -struct dimension_pow_impl { - using type = TYPENAME dimension_pow_impl, Num, Den>::type; -}; - -template -struct dimension_pow_impl, Num, Den> { - using type = downcast_dimension...>>; -}; - -} // namespace detail - -template -using dimension_pow = TYPENAME detail::dimension_pow_impl::type; - -template -using dimension_sqrt = TYPENAME detail::dimension_pow_impl::type; - -} // namespace units diff --git a/src/core/include/units/bits/expression_template.h b/src/core/include/units/bits/expression_template.h new file mode 100644 index 00000000..638fc8c6 --- /dev/null +++ b/src/core/include/units/bits/expression_template.h @@ -0,0 +1,390 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// 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. + +#pragma once + +#include +#include +#include + +namespace units { + +template +struct type_list {}; + +template +struct per {}; + +template +struct power; + +// TODO make_power() that will simplify cases like ? + +namespace detail { + +template +inline constexpr bool is_specialization_of_power = false; + +template +inline constexpr bool is_specialization_of_power> = true; + +} // namespace detail + +template +struct power { + using factor = F; + static constexpr int num = Num; + static constexpr int den = 1; +}; + +template +struct power { + using factor = F; + static constexpr int num = Num; + static constexpr int den = Den; +}; + +namespace detail { + +template +constexpr auto power_or_T_impl() +{ + constexpr ratio r{Num, Den}; + if constexpr (r.den == 1) { + if constexpr (r.num == 1) + return T{}; + else + return power{}; + } else { + return power{}; + } +}; + +template +using power_or_T = decltype(power_or_T_impl()); + +// type_power +template +struct type_power { + using type = conditional, power>; +}; + +template +struct type_power, Num, 1> { + using type = power; +}; + +template +struct type_power, Num, Den> { + static constexpr ratio r = ratio(power::num, power::den) * ratio(Num, Den); + using type = power_or_T; +}; + +// expr_power +template +struct expr_power; + +template +struct expr_power, Num, Den> { + using type = type_list::type...>; +}; + +/** + * @brief Consolidates contiguous ranges of exponents of the same dimension + * + * If there is more than one exponent with the same dimension they are aggregated into one exponent by adding + * their exponents. If this accumulation will result with 0, such a dimension is removed from the list. + * + * @tparam D derived dimension to consolidate + */ +template +struct expr_consolidate_impl; + +template<> +struct expr_consolidate_impl> { + using type = type_list<>; +}; + +template +struct expr_consolidate_impl> { + using type = type_list; +}; + +template +struct expr_consolidate_impl> { + using type = type_list_push_front>::type, T>; +}; + +template +struct expr_consolidate_impl> { + using type = expr_consolidate_impl, Rest...>>::type; +}; + +template +struct expr_consolidate_impl, Rest...>> { + using type = expr_consolidate_impl< + type_list::num + power::den, power::den>, Rest...>>::type; +}; + +template +struct expr_consolidate_impl, power, Rest...>> { + static constexpr ratio r = + ratio(power::num, power::den) + ratio(power::num, power::den); + using type = conditional>::type, + typename expr_consolidate_impl, Rest...>>::type>; +}; + +template +using expr_consolidate = typename expr_consolidate_impl::type; + + +// expr_simplify + +template +struct expr_simplify_power { + static constexpr ratio r = ratio(powerNum::num, powerNum::den) - ratio(powerDen::num, powerDen::den); + using type = power_or_T; + using num = conditional<(r > 0), type_list, type_list<>>; + using den = conditional<(r < 0), type_list, type_list<>>; +}; + +template typename Pred> +struct expr_simplify; + +template typename Pred> + requires(type_list_size == 0) || (type_list_size == 0) +struct expr_simplify { + using num = NumList; + using den = DenList; +}; + +template typename Pred> +struct expr_simplify, type_list, Pred> { + using impl = conditional::value, expr_simplify, type_list, Pred>, + expr_simplify, type_list, Pred>>; + using num = conditional::value, type_list_push_front, typename impl::num>; + using den = conditional::value, typename impl::den, type_list_push_front>; +}; + +template typename Pred> +struct expr_simplify, type_list, Pred> : + expr_simplify, type_list, Pred> {}; + +template typename Pred> +struct expr_simplify, NRest...>, type_list, Pred> { + using impl = expr_simplify, type_list, Pred>; + using type = expr_simplify_power, power>; + using num = type_list_join; + using den = type_list_join; +}; + +template typename Pred> +struct expr_simplify, type_list, DRest...>, Pred> { + using impl = expr_simplify, type_list, Pred>; + using type = expr_simplify_power, power>; + using num = type_list_join; + using den = type_list_join; +}; + +template typename Pred> + requires(!std::same_as, power>) +struct expr_simplify, NRest...>, type_list, DRest...>, Pred> { + using impl = expr_simplify, type_list, Pred>; + using type = expr_simplify_power, power>; + using num = type_list_join; + using den = type_list_join; +}; + + +// expr_less +template typename Pred> +struct expr_less_impl : Pred {}; + +template typename Pred> +struct expr_less_impl, power, Pred> : Pred {}; + +template typename Pred> +struct expr_less_impl, T2, Pred> : Pred {}; + +template typename Pred> +struct expr_less_impl, Pred> : Pred {}; + +template typename Pred> +struct expr_less_impl, Pred> : std::true_type {}; + +template typename Pred> +using expr_less = expr_less_impl; + + +// expr_fractions +template +struct expr_fractions_impl; + +template +struct expr_fractions_impl { + using den = type_list<>; +}; + +template +struct expr_fractions_impl { + using den = type_list_push_front::den, T>; +}; + +template T, typename... Rest> +struct expr_fractions_impl : + TYPENAME expr_fractions_impl::den {}; + +template +struct expr_fractions_impl { + using num = type_list<>; + using den = type_list<>; +}; + +template +struct expr_fractions_impl> { + using num = type_list<>; + using den = TYPENAME expr_fractions_impl::den; +}; + +template T, typename... Rest> +struct expr_fractions_impl : expr_fractions_impl {}; + +template +struct expr_fractions_impl { + using impl = expr_fractions_impl; + using num = type_list_push_front; + using den = TYPENAME impl::den; +}; + +template +struct expr_fractions { +private: + using impl = expr_fractions_impl; +public: + using num = TYPENAME impl::num; + using den = TYPENAME impl::den; +}; + +template typename To> +constexpr auto expr_expression_impl() +{ + constexpr std::size_t num = type_list_size; + constexpr std::size_t den = type_list_size; + + if constexpr (num == 0 && den == 0) { + return OneType{}; + } else if constexpr (num > 0 && den > 0) { + return type_list_map>, To>{}; + } else if constexpr (den > 0) { + return To>{}; + } else { + if constexpr (num == 1 && !is_specialization_of_power>) + // temporary derived type not needed -> just return the original one + return type_list_front{}; + else + return type_list_map{}; + } +} + +template typename To> +using expr_expression = decltype(expr_expression_impl()); + +template typename Pred, + template typename To> +constexpr auto get_optimized_expression() +{ + using num_list = expr_consolidate; + using den_list = expr_consolidate; + using simple = expr_simplify; + using expr = expr_expression; + return expr{}; +} + +/** + * @brief Merges 2 sorted derived dimensions into one units::normalized_dimension + * + * A result of a dimensional calculation may result with many exponents of the same base dimension originated + * from different parts of the equation. As the exponents lists of both operands it is enough to merge them + * into one list and consolidate duplicates. Also it is possible that final exponents list will contain only + * one element being a base dimension with exponent 1. In such a case the final dimension should be the base + * dimension itself. + */ +template typename Pred, + template typename To> +constexpr auto expr_multiply() +{ + if constexpr (is_same_v) { + return T2{}; + } else if constexpr (is_same_v) { + return T1{}; + } else if constexpr (is_specialization_of && is_specialization_of) { + return get_optimized_expression, + type_list_merge_sorted, OneType, Pred, + To>(); + } else if constexpr (is_specialization_of) { + return get_optimized_expression, Pred>, typename T1::den, + OneType, Pred, To>(); + } else if constexpr (is_specialization_of) { + return get_optimized_expression, Pred>, typename T2::den, + OneType, Pred, To>(); + } else { + return get_optimized_expression, type_list, Pred>, type_list<>, OneType, + Pred, To>(); + } +} + +template typename Pred, + template typename To> +constexpr auto expr_divide() +{ + if constexpr (is_same_v) { + return OneType{}; + } else if constexpr (is_same_v) { + return T1{}; + } else if constexpr (is_specialization_of && is_specialization_of) { + return get_optimized_expression, + type_list_merge_sorted, OneType, Pred, + To>(); + } else if constexpr (is_specialization_of) { + return get_optimized_expression, Pred>, + OneType, Pred, To>(); + } else if constexpr (is_specialization_of) { + return get_optimized_expression, Pred>, typename T2::num, + OneType, Pred, To>(); + } else { + return To>{}; + } +} + +template typename To> +constexpr auto expr_invert() +{ + if constexpr (is_specialization_of) + return expr_expression{}; + else + return To>{}; +} + +} // namespace detail + +} // namespace units diff --git a/src/core/include/units/bits/external/type_list.h b/src/core/include/units/bits/external/type_list.h index b6b6e7ec..28007478 100644 --- a/src/core/include/units/bits/external/type_list.h +++ b/src/core/include/units/bits/external/type_list.h @@ -22,6 +22,7 @@ #pragma once +#include // IWYU pragma: keep #include UNITS_DIAGNOSTIC_PUSH @@ -42,6 +43,38 @@ inline constexpr bool is_type_list> = true; template concept TypeList = detail::is_type_list; +// size + +namespace detail { + +template typename List, typename... Ts> +constexpr std::size_t type_list_size_impl(List) +{ + return sizeof...(Ts); +} + +} // namespace detail + +template +inline constexpr std::size_t type_list_size = detail::type_list_size_impl(List{}); + +// front + +namespace detail { + +template +struct type_list_front_impl; + +template typename List, typename T, typename... Ts> +struct type_list_front_impl> { + using type = T; +}; + +} // namespace detail + +template +using type_list_front = TYPENAME detail::type_list_front_impl::type; + // push_front namespace detail { @@ -218,6 +251,23 @@ struct type_list_sort_impl, Pred> { template typename Pred> using type_list_sort = TYPENAME detail::type_list_sort_impl::type; +// map + +namespace detail { + +template typename To> +struct type_list_map_impl; + +template typename From, template typename To, typename... Args> +struct type_list_map_impl, To> { + using type = To; +}; + +} // namespace detail + +template typename To> +using type_list_map = TYPENAME detail::type_list_map_impl::type; + } // namespace units UNITS_DIAGNOSTIC_POP diff --git a/src/core/include/units/bits/external/type_name.h b/src/core/include/units/bits/external/type_name.h new file mode 100644 index 00000000..e65ec9d1 --- /dev/null +++ b/src/core/include/units/bits/external/type_name.h @@ -0,0 +1,27 @@ +// https://stackoverflow.com/questions/81870/is-it-possible-to-print-a-variables-type-in-standard-c/56766138#56766138 + +#pragma once + +#include + +template +constexpr auto type_name() +{ + std::string_view name, prefix, suffix; +#ifdef __clang__ + name = __PRETTY_FUNCTION__; + prefix = "auto type_name() [T = "; + suffix = "]"; +#elif defined(__GNUC__) + name = __PRETTY_FUNCTION__; + prefix = "constexpr auto type_name() [with T = "; + suffix = "]"; +#elif defined(_MSC_VER) + name = __FUNCSIG__; + prefix = "auto __cdecl type_name<"; + suffix = ">(void)"; +#endif + name.remove_prefix(prefix.size()); + name.remove_suffix(suffix.size()); + return name; +} diff --git a/src/core/include/units/derived_dimension.h b/src/core/include/units/derived_dimension.h deleted file mode 100644 index 0af2e096..00000000 --- a/src/core/include/units/derived_dimension.h +++ /dev/null @@ -1,92 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -// IWYU pragma: begin_exports -#include -// IWYU pragma: end_exports - -namespace units { - -namespace detail { - -/** - * @brief Converts user provided derived dimension specification into a valid units::derived_dimension_base definition - * - * User provided definition of a derived dimension may contain the same base dimension repeated more than once on the - * list possibly hidden in other derived units provided by the user. The process here should: - * 1. Extract derived dimensions into exponents of base dimensions. - * 2. Sort the exponents so the same dimensions are placed next to each other. - * 3. Consolidate contiguous range of exponents of the same base dimensions to a one (or possibly zero) exponent for - * this base dimension. - */ -template -using make_dimension = TYPENAME to_derived_dimension_base< - typename dim_consolidate::type, exponent_less>>::type>::type; - -} // namespace detail - -/** - * @brief The list of exponents of dimensions (both base and derived) provided by the user - * - * This is the user's interface to create derived dimensions. Exponents list can contain powers of factors of both - * base and derived dimensions. This is called a "recipe" of the dimension and among others is used to print - * unnamed coherent units of this dimension. - * - * Coherent unit is a unit that, for a given system of quantities and for a chosen set of base units, is a product - * of powers of base units with no other proportionality factor than one. - * - * The implementation is responsible for unpacking all of the dimensions into a list containing only base dimensions - * and their factors and putting them to derived_dimension_base class template. - * - * Sometimes units of equivalent quantities in different systems of units do not share the same reference so they - * cannot be easily converted to each other. An example can be a pressure for which a coherent unit in SI is pascal - * and in CGS barye. Those two units are not directly related with each other with some ratio. As they both are - * coherent units of their dimensions, the ratio between them is directly determined by the ratios of base units - * defined in base dimensions end their exponents in the derived dimension recipe. To provide interoperability of - * such quantities of different systems mag is being used. The result of the division of two - * mag of two quantities of equivalent dimensions in two different systems gives a ratio between their - * coherent units. Alternatively, the user would always have to directly define a barye in terms of pascal or vice - * versa. - * - * @tparam Child inherited class type used by the downcasting facility (CRTP Idiom) - * @tparam U a coherent unit of a derived dimension - * @tparam Es the list of exponents of ingredient dimensions - */ -template -struct derived_dimension : downcast_dispatch> { - using recipe = exponent_list; - using coherent_unit = U; - static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag = - detail::absolute_magnitude(typename derived_dimension::exponents()) / U::mag; -}; - -} // namespace units diff --git a/src/core/include/units/dimension.h b/src/core/include/units/dimension.h new file mode 100644 index 00000000..08015f25 --- /dev/null +++ b/src/core/include/units/dimension.h @@ -0,0 +1,260 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// 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. + +#pragma once + +#include +#include +#include +#include + +namespace units { + +/** + * @brief A dimension of a base quantity + * + * Base quantity is a quantity in a conventionally chosen subset of a given system of quantities, where no quantity + * in the subset can be expressed in terms of the other quantities within that subset. They are referred to as + * being mutually independent since a base quantity cannot be expressed as a product of powers of the other base + * quantities. + * + * Symbol template parameters is an unique identifier of the base dimension. The same identifiers can be multiplied + * and divided which will result with an adjustment of its factor in an Exponent of a DerivedDimension + * (in case of zero the dimension will be simplified and removed from further analysis of current expresion). + * + * @tparam Symbol an unique identifier of the base dimension used to provide dimensional analysis support + */ +template +struct base_dimension { + static constexpr auto symbol = Symbol; ///< Unique base dimension identifier +}; + +namespace detail { + +template +void to_base_base_dimension(const volatile base_dimension*); + +} // namespace detail + +/** + * @brief A concept matching all base dimensions in the library. + * + * Satisfied by all dimension types derived from an specialization of `base_dimension`. + */ +template +concept BaseDimension = requires(T* t) { detail::to_base_base_dimension(t); }; + +template +struct base_dimension_less : std::bool_constant<(D1::symbol < D2::symbol)> {}; + +// TODO Can we provide a smarter implementation? +std::false_type is_derived_dimension(...); + +/** + * @brief A concept matching all derived dimensions in the library. + * + * Satisfied by all dimension types derived from an specialization of `derived_dimension`. + */ +template +concept DerivedDimension = decltype(is_derived_dimension(std::declval()))::value; + +/** + * @brief A concept matching all dimensions in the library. + * + * Satisfied by all dimension types for which either `BaseDimension` or `DerivedDimension` is `true`. + */ +template +concept Dimension = BaseDimension || DerivedDimension; + +namespace detail { + +/** + * @brief Unpacks the list of potentially derived dimensions to a list containing only base dimensions + * + * @tparam Es Exponents of potentially derived dimensions + */ +template +struct dim_extract; + +template<> +struct dim_extract, type_list<>> { + using num = type_list<>; + using den = type_list<>; +}; + +template + requires BaseDimension || BaseDimension +struct dim_extract, type_list> { + using impl = dim_extract, type_list>; + using num = type_list_push_front; + using den = TYPENAME impl::den; +}; + +template + requires BaseDimension || BaseDimension +struct dim_extract, type_list> { + using impl = dim_extract, type_list>; + using num = TYPENAME impl::num; + using den = type_list_push_front; +}; + +template +struct dim_extract, type_list> : + dim_extract, + type_list_push_back> {}; + +template +struct dim_extract, NRest...>, type_list> : + dim_extract::num, power::den>::type, + NRest...>, + type_list_push_back< + typename expr_power::num, power::den>::type, + Dens...>> {}; + + +template +struct dim_extract, type_list> : + dim_extract> {}; + +template +struct dim_extract, type_list, DRest...>> : + dim_extract::num, power::den>::type, + type_list_push_back< + typename expr_power::num, power::den>::type, + DRest...>> {}; + +template +using type_list_of_base_dimension_less = expr_less; + +/** + * @brief Converts user provided derived dimension specification into a valid units::normalized_dimension definition + * + * User provided definition of a derived dimension may contain the same base dimension repeated more than once on the + * list possibly hidden in other derived units provided by the user. The process here should: + * 1. Extract derived dimensions into exponents of base dimensions. + * 2. Sort the exponents so the same dimensions are placed next to each other. + * 3. Consolidate contiguous range of exponents of the same base dimensions to a one (or possibly zero) exponent for + * this base dimension. + */ +template +struct normalized_dimension : detail::expr_fractions { +private: + using base = detail::expr_fractions; + using extracted = dim_extract; + using num_list = expr_consolidate>; + using den_list = expr_consolidate>; + using simple = expr_simplify; +public: + using normalized_num = TYPENAME simple::num; + using normalized_den = TYPENAME simple::den; +}; + +} // namespace detail + +// TODO add checking for `per` and power elements as well +template +concept DimensionSpec = Dimension || is_specialization_of || detail::is_specialization_of_power; + +// User should not instantiate this type!!! +template +struct derived_dimension : detail::normalized_dimension, Ds...> {}; + +// TODO move type_list_fractions out of + +template +std::true_type is_derived_dimension(const volatile derived_dimension*); + +/** + * @brief Dimension one + * + * Dimension for which all the exponents of the factors corresponding to the base + * dimensions are zero. Also commonly named as "dimensionless". + */ +inline constexpr struct dim_one : derived_dimension<> { +} dim_one; + +namespace detail { + +template +struct dimension_less : std::bool_constant() < type_name()> {}; + +template +using type_list_of_dimension_less = expr_less; + +} // namespace detail + +template +constexpr Dimension auto operator*(D1, D2) +{ + return detail::expr_multiply(); +} + +template +constexpr Dimension auto operator/(D1, D2) +{ + return detail::expr_divide(); +} + +template +constexpr Dimension auto operator/(int value, D) +{ + gsl_Assert(value == 1); + return detail::expr_invert(); +} + +template +constexpr bool operator==(D1, D2) +{ + return false; +} + +template +constexpr bool operator==(D1, D2) +{ + return D1::symbol == D2::symbol; +} + +template + requires(type_list_size == 0) && (type_list_size == 1) && + BaseDimension> +constexpr bool operator==(D1, D2) +{ + return D1::symbol == type_list_front::symbol; +} + +template + requires(type_list_size == 0) && (type_list_size == 1) && + BaseDimension> +constexpr bool operator==(D1, D2) +{ + return type_list_front::symbol == D2::symbol; +} + +template +constexpr bool operator==(D1, D2) +{ + return is_same_v && + is_same_v; +} + +} // namespace units diff --git a/src/core/include/units/exponent.h b/src/core/include/units/exponent.h deleted file mode 100644 index 2f713af2..00000000 --- a/src/core/include/units/exponent.h +++ /dev/null @@ -1,85 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include - -namespace units { - -/** - * @brief A power of factor corresponding to the dimension of a quantity - * - * @tparam Dim component dimension of a derived quantity - * @tparam Num numinator of the factor - * @tparam Den denominator of the factor - */ -template -struct exponent { - using dimension = Dim; - static constexpr std::intmax_t num = Num; - static constexpr std::intmax_t den = Den; -}; - -// is_exponent -namespace detail { - -template -inline constexpr bool is_exponent> = true; - -} // namespace detail - -// exponent_less -template - requires BaseDimension && BaseDimension -struct exponent_less : base_dimension_less {}; - -// exponent_invert -namespace detail { - -template -constexpr exponent exponent_invert_impl(exponent); - -} // namespace detail - -template -using exponent_invert = decltype(detail::exponent_invert_impl(E())); - -// exponent_multiply -namespace detail { - -template -struct exponent_multiply_impl { - static constexpr ratio r = ratio(E::num, E::den) * ratio(Num, Den); - using type = exponent; -}; - -} // namespace detail - -template -using exponent_multiply = TYPENAME detail::exponent_multiply_impl::type; - -template -struct exponent_list {}; - -} // namespace units diff --git a/src/core/include/units/magnitude.h b/src/core/include/units/magnitude.h index 0195cf8e..d0bd6501 100644 --- a/src/core/include/units/magnitude.h +++ b/src/core/include/units/magnitude.h @@ -595,7 +595,7 @@ constexpr auto common_magnitude(magnitude, magnitude) } else { // When the bases are equal, pick whichever has the lower power. constexpr auto common_tail = common_magnitude(magnitude{}, magnitude{}); - if constexpr (H1.power < H2.power) { + if constexpr ((H1.power) < (H2.power)) { return magnitude

{} * common_tail; } else { return magnitude

{} * common_tail; diff --git a/src/core/include/units/prefix.h b/src/core/include/units/prefix.h deleted file mode 100644 index 803cf341..00000000 --- a/src/core/include/units/prefix.h +++ /dev/null @@ -1,62 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -namespace units { - -namespace detail { - -template -struct prefix_base : downcast_base> { - static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag = M; -}; - -} // namespace detail - -/** - * @brief A prefix used to scale units - * - * Data from a prefix class is used in two cases: - * - when defining a prefixed_unit its ratio is used to scale the reference unit and its - * symbol is used to prepend to the symbol of referenced unit - * - when printing the symbol of a scaled unit that was not predefined by the user but its - * factor matches ratio of a prefix, its symbol will be prepended to the symbol of the unit - * - * @tparam Child inherited class type used by the downcasting facility (CRTP Idiom) - * @tparam Symbol a text representation of the prefix - * @tparam R factor to be used to scale a unit - */ -template -struct prefix : downcast_dispatch, downcast_mode::on> { - static constexpr auto symbol = Symbol; -}; - -} // namespace units diff --git a/src/core/include/units/reference.h b/src/core/include/units/reference.h index c6a68fb1..6fa3c6cc 100644 --- a/src/core/include/units/reference.h +++ b/src/core/include/units/reference.h @@ -22,35 +22,37 @@ #pragma once -#include -#include +#include +#include namespace units { -template U, Representation Rep> -class quantity; +// TODO Concept for system reference +template +class quantity { +public: + using reference = decltype(R); + static constexpr auto dimension = reference::dimension; + static constexpr auto unit = reference::unit; -template U> -struct reference; + quantity(Rep) {} +}; + +template +struct system_reference; namespace detail { -template -using reference_multiply_impl = reference>; +template +void to_base_specialization_of_system_reference(const volatile system_reference*); -template -using reference_divide_impl = reference>; +template +// inline constexpr bool // TODO: Replace with concept when it works with MSVC +concept is_derived_from_specialization_of_system_reference = + requires(T* t) { detail::to_base_specialization_of_system_reference(t); }; } // namespace detail -template -using reference_multiply = - detail::reference_multiply_impl, R1, R2>; - -template -using reference_divide = - detail::reference_divide_impl, R1, R2>; - /** * @brief The type for quantity references * @@ -90,50 +92,71 @@ using reference_divide = * The following syntaxes are not allowed: * `2 / s`, `km * 3`, `s / 4`, `70 * km / h`. */ -template U> -struct reference { - using dimension = D; - using unit = U; - static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag = dimension::mag * unit::mag; +template +struct reference; - // Hidden Friends - // Below friend functions are to be found via argument-dependent lookup only - - template - [[nodiscard]] friend constexpr reference_multiply operator*(reference, R2) - { - return {}; - } - - template - [[nodiscard]] friend constexpr reference_divide operator/(reference, R2) - { - return {}; - } - - template - [[nodiscard]] friend constexpr Quantity auto operator*(const Rep& lhs, reference) - { - return quantity(lhs); - } - - friend void /*Use `q * (1 * r)` rather than `q * r`.*/ operator*(Quantity auto, reference) = delete; - - template - [[nodiscard]] friend constexpr bool operator==(reference, R2) - { - return false; - } - - [[nodiscard]] friend constexpr bool operator==(reference, reference) { return true; } +template + requires detail::is_derived_from_specialization_of_system_reference +struct reference { + using system_reference = R; + static constexpr auto dimension = R::dimension; + static constexpr U unit{}; + // static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag = dimension::mag * unit::mag; }; -// type traits -namespace detail { +template +struct reference { + static constexpr D dimension{}; + static constexpr U unit{}; + // static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag = dimension::mag * unit::mag; +}; -template -inline constexpr bool is_reference> = true; +// Reference +/** + * @brief A concept matching all references in the library. + * + * Satisfied by all specializations of @c reference. + */ +template +concept Reference = is_specialization_of; -} // namespace detail +template +[[nodiscard]] constexpr reference operator*(R1, + R2) +{ + return {}; +} + +template +[[nodiscard]] constexpr reference operator/(R1, + R2) +{ + return {}; +} + +// TODO Update when quantity is done +// template +// [[nodiscard]] friend constexpr Quantity auto operator*(const Rep& lhs, reference) +template +[[nodiscard]] constexpr quantity operator*(const Rep& lhs, R) +{ + return quantity(lhs); +} + +// friend void /*Use `q * (1 * r)` rather than `q * r`.*/ operator*(Quantity auto, reference) = delete; + +// TODO will use deducing this +template +struct system_reference { + static constexpr auto dimension = Dim; + static constexpr auto coherent_unit = CoU; + + template + // requires same_unit_reference + [[nodiscard]] constexpr reference operator[](U) const + { + return {}; + } +}; } // namespace units diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index c388369c..24e1b0eb 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -22,27 +22,28 @@ #pragma once -#include -#include +#include +#include +#include #include +#include +#include + +// #include // IWYU pragma: begin_exports -#include -#include -#include -#include -#include -#include +// #include +// #include // IWYU pragma: end_exports namespace units { -namespace detail { +// namespace detail { -template -inline constexpr bool can_be_prefixed = false; +// template +// inline constexpr bool can_be_prefixed = false; -} // namespace detail +// } // namespace detail /** * @brief A common point for a hierarchy of units @@ -63,16 +64,56 @@ inline constexpr bool can_be_prefixed = false; * it gets the incomplete child's type with the CRTP idiom. */ template -struct scaled_unit : downcast_base> { +struct scaled_unit { static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag = M; using reference = U; }; -template -using downcast_unit = downcast::reference>>; +// TODO: Remove when P1985 accepted +namespace detail { -template -struct same_unit_reference : is_same {}; +template +void to_base_scaled_unit(const volatile scaled_unit*); + +} // namespace detail + +/** + * @brief A concept matching all unit types in the library + * + * Satisfied by all unit types derived from an specialization of :class:`scaled_unit`. + */ +template +concept Unit = requires(T* t) { detail::to_base_scaled_unit(t); }; + +namespace detail { + +template +inline constexpr bool is_named = false; + +} + +template +concept NamedUnit = Unit && detail::is_named; + +template +struct same_unit_reference : is_same {}; + +// TODO add checking for `per` and power elements as well +template +concept UnitSpec = Unit || is_specialization_of || detail::is_specialization_of_power; + +template +struct derived_unit : detail::expr_fractions, Us...>, scaled_unit(), derived_unit> {}; + +// : detail::normalized_dimension, Ds...> {}; + +/** + * @brief Unit one + * + * Unit of a dimensionless quantity. + */ +inline constexpr struct one : derived_unit<> { +} one; /** * @brief A named unit @@ -80,27 +121,35 @@ struct same_unit_reference : is_same -struct named_unit : downcast_dispatch(), Child>> { +template +struct named_unit; + +template +struct named_unit : scaled_unit(), named_unit> { static constexpr auto symbol = Symbol; }; +template + requires is_specialization_of, derived_unit> +struct named_unit : decltype(U) { + static constexpr auto symbol = Symbol; +}; + + /** * @brief A named scaled unit * * Defines a new named unit that is a scaled version of another unit. * A named unit may be composed with a prefix to create a prefixed_unit. * - * @tparam Child inherited class type used by the downcasting facility (CRTP Idiom) * @tparam Symbol a short text representation of the unit * @tparam M the Magnitude by which to scale U * @tparam U a reference unit to scale */ -template -struct named_scaled_unit : downcast_dispatch> { +template +struct named_scaled_unit : scaled_unit { static constexpr auto symbol = Symbol; }; @@ -115,11 +164,15 @@ struct named_scaled_unit : downcast_dispatch - requires detail::can_be_prefixed -struct prefixed_unit : downcast_dispatch> { - static constexpr auto symbol = P::symbol + U::symbol; -}; +// template +// requires detail::can_be_prefixed +// struct prefixed_unit : downcast_dispatch> { +// static constexpr auto symbol = P::symbol + U::symbol; +// }; + + +template +struct prefixed_unit : scaled_unit {}; /** * @brief A coherent unit of a derived quantity @@ -129,105 +182,96 @@ struct prefixed_unit : downcast_dispatch -struct derived_unit : downcast_dispatch(), Child>> {}; - -/** - * @brief A unit with a deduced ratio and symbol - * - * Defines a new unit with a deduced ratio and symbol based on the recipe from the provided - * derived dimension. The number and order of provided units should match the recipe of the - * derived dimension. All of the units provided should also be a named ones so it is possible - * to create a deduced symbol text. - * - * @tparam Child inherited class type used by the downcasting facility (CRTP Idiom) - * @tparam Dim a derived dimension recipe to use for deduction - * @tparam U the unit of the first composite dimension from provided derived dimension's recipe - * @tparam URest the units for the rest of dimensions from the recipe - */ -template - requires detail::compatible_units -struct derived_scaled_unit : downcast_dispatch> { - static constexpr auto symbol = detail::derived_symbol_text(); -}; - -/** - * @brief An aliased named unit - * - * Defines a named alias for another unit. It is useful to assign alternative names and symbols - * to the already predefined units (i.e. "tonne" for "megagram"). - * A alias unit may be composed with a prefix to create a prefixed_alias_unit. - * - * @tparam U Unit for which an alias is defined - * @tparam Symbol a short text representation of the unit - */ -template -struct alias_unit : U { - static constexpr auto symbol = Symbol; -}; - -/** - * @brief A prefixed alias unit - * - * Defines a new unit that is an alias for a scaled version of another unit by the provided - * prefix. It is only possible to create such a unit if the given prefix type matches the one - * defined in a reference unit. - * - * @tparam U Unit for which an alias is defined - * @tparam P prefix to be appied to the reference unit - * @tparam AU reference alias unit - */ -template - requires(!AliasUnit) -struct prefixed_alias_unit : U { - static constexpr auto symbol = P::symbol + AU::symbol; -}; - -/** - * @brief Unknown coherent unit - * - * Used as a coherent unit of an unknown dimension. - */ -template -struct unknown_coherent_unit : - downcast_dispatch, - scaled_unit()), unknown_coherent_unit>> {}; +// template +// struct derived_unit : downcast_dispatch(), Child>> {}; namespace detail { -template -void is_named_impl(const volatile named_unit*); +template +void is_named_impl(const volatile named_unit*); -template -void is_named_impl(const volatile named_scaled_unit*); - -template -void is_named_impl(const volatile prefixed_unit*); - -template -void is_named_impl(const volatile alias_unit*); - -template -void is_named_impl(const volatile prefixed_alias_unit*); +template +void is_named_impl(const volatile named_scaled_unit*); template inline constexpr bool is_named = requires(U * u) { is_named_impl(u); }; -template -void can_be_prefixed_impl(const volatile named_unit*); +// template +// void can_be_prefixed_impl(const volatile named_unit*); -template -void can_be_prefixed_impl(const volatile named_scaled_unit*); +// template +// void can_be_prefixed_impl(const volatile named_scaled_unit*); -template -void can_be_prefixed_impl(const volatile alias_unit*); +// template +// void can_be_prefixed_impl(const volatile alias_unit*); -template -inline constexpr bool can_be_prefixed = requires(U * u) { can_be_prefixed_impl(u); }; +// template +// inline constexpr bool can_be_prefixed = requires(U * u) { can_be_prefixed_impl(u); }; -template -inline constexpr bool can_be_prefixed> = can_be_prefixed; +// template +// inline constexpr bool can_be_prefixed> = can_be_prefixed; + + +template +struct unit_less : std::bool_constant() < type_name()> {}; + +template +using type_list_of_unit_less = expr_less; } // namespace detail +template +constexpr Unit auto operator*(U1, U2) +{ + return detail::expr_multiply(); +} + +template +constexpr Unit auto operator/(U1, U2) +{ + return detail::expr_divide(); +} + +template +constexpr Unit auto operator/(int value, U) +{ + gsl_Assert(value == 1); + return detail::expr_invert(); +} + +template +constexpr bool operator==(U1, U2) +{ + return false; +} + +// template +// constexpr bool operator==(D1, D2) +// { +// return D1::symbol == D2::symbol; +// } + +// template +// requires(type_list_size == 0) && (type_list_size == 1) && +// BaseDimension> +// constexpr bool operator==(D1, D2) +// { +// return D1::symbol == type_list_front::symbol; +// } + +// template +// requires(type_list_size == 0) && (type_list_size == 1) && +// BaseDimension> +// constexpr bool operator==(D1, D2) +// { +// return type_list_front::symbol == D2::symbol; +// } + +// template +// constexpr bool operator==(D1, D2) +// { +// return std::is_same_v && +// std::is_same_v; +// } + } // namespace units diff --git a/src/systems/si/include/units/isq/si/prefixes.h b/src/systems/si/include/units/isq/si/prefixes.h index 562370b6..e150426e 100644 --- a/src/systems/si/include/units/isq/si/prefixes.h +++ b/src/systems/si/include/units/isq/si/prefixes.h @@ -22,31 +22,49 @@ #pragma once -#include +#include namespace units::isq::si { -// clang-format off -struct yocto : prefix(mag<10>())> {}; -struct zepto : prefix(mag<10>())> {}; -struct atto : prefix(mag<10>())> {}; -struct femto : prefix(mag<10>())> {}; -struct pico : prefix(mag<10>())> {}; -struct nano : prefix(mag<10>())> {}; -struct micro : prefix(mag<10>())> {}; -struct milli : prefix(mag<10>())> {}; -struct centi : prefix(mag<10>())> {}; -struct deci : prefix(mag<10>())> {}; -struct deca : prefix(mag<10>())> {}; -struct hecto : prefix(mag<10>())> {}; -struct kilo : prefix(mag<10>())> {}; -struct mega : prefix(mag<10>())> {}; -struct giga : prefix(mag<10>())> {}; -struct tera : prefix(mag<10>())> {}; -struct peta : prefix(mag<10>())> {}; -struct exa : prefix(mag<10>())> {}; -struct zetta : prefix(mag<10>())> {}; -struct yotta : prefix(mag<10>())> {}; -// clang-format on +template +struct yocto : prefixed_unit<"y", pow<-24>(mag<10>()), U> {}; +template +struct zepto : prefixed_unit<"z", pow<-21>(mag<10>()), U> {}; +template +struct atto : prefixed_unit<"a", pow<-18>(mag<10>()), U> {}; +template +struct femto : prefixed_unit<"f", pow<-15>(mag<10>()), U> {}; +template +struct pico : prefixed_unit<"p", pow<-12>(mag<10>()), U> {}; +template +struct nano : prefixed_unit<"n", pow<-9>(mag<10>()), U> {}; +template +struct micro : prefixed_unit(mag<10>()), U> {}; +template +struct milli : prefixed_unit<"m", pow<-3>(mag<10>()), U> {}; +template +struct centi : prefixed_unit<"c", pow<-2>(mag<10>()), U> {}; +template +struct deci : prefixed_unit<"d", pow<-1>(mag<10>()), U> {}; +template +struct deca : prefixed_unit<"da", pow<1>(mag<10>()), U> {}; +template +struct hecto : prefixed_unit<"h", pow<2>(mag<10>()), U> {}; +template +struct kilo : prefixed_unit<"k", pow<3>(mag<10>()), U> {}; +template +struct mega : prefixed_unit<"M", pow<6>(mag<10>()), U> {}; +template +struct giga : prefixed_unit<"G", pow<9>(mag<10>()), U> {}; +template +struct tera : prefixed_unit<"T", pow<12>(mag<10>()), U> {}; +template +struct peta : prefixed_unit<"P", pow<15>(mag<10>()), U> {}; +template +struct exa : prefixed_unit<"E", pow<18>(mag<10>()), U> {}; +template +struct zetta : prefixed_unit<"Z", pow<21>(mag<10>()), U> {}; +template +struct yotta : prefixed_unit<"Y", pow<24>(mag<10>()), U> {}; } // namespace units::isq::si From 8d711cdf8ef9d6b05c7327a681b6359c5701e0fd Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 8 Sep 2022 19:21:47 +0200 Subject: [PATCH 002/402] fix: hello_units reverted to the original state --- example/hello_units.cpp | 420 ++++------------------------------------ 1 file changed, 36 insertions(+), 384 deletions(-) diff --git a/example/hello_units.cpp b/example/hello_units.cpp index d9620410..5bfbc860 100644 --- a/example/hello_units.cpp +++ b/example/hello_units.cpp @@ -20,391 +20,43 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -// #include -#include - -namespace units::isq { - -inline constexpr struct dim_length : base_dimension<"L"> { -} dim_length; - -// template -// concept Length = QuantityOf; - -inline constexpr struct dim_time : base_dimension<"T"> { -} dim_time; -inline constexpr struct dim_frequency : decltype(1 / dim_time) { -} dim_frequency; -inline constexpr struct dim_area : decltype(dim_length * dim_length) { -} dim_area; -inline constexpr struct dim_volume : decltype(dim_area * dim_length) { -} dim_volume; -inline constexpr struct dim_speed : decltype(dim_length / dim_time) { -} dim_speed; -inline constexpr struct dim_acceleration : decltype(dim_speed / dim_time) { -} dim_acceleration; - -// inline constexpr auto speed = length / time; - -} // namespace units::isq - -#include -#include - -namespace units { - -namespace isq::si { - -// length units -inline constexpr struct metre : named_unit<"m"> { -} metre; -inline constexpr struct kilometre : kilo { -} kilometre; - -inline constexpr struct astronomical_unit : named_scaled_unit<"au", mag<149'597'870'700>(), metre> { -} astronomical_unit; - -// area units -inline constexpr struct square_metre : derived_unit { -} square_metre; - -// volume units -inline constexpr struct cubic_metre : derived_unit { -} cubic_metre; - -// time units -inline constexpr struct second : named_unit<"s"> { -} second; -inline constexpr struct minute : named_scaled_unit<"min", mag<60>(), second> { -} minute; -inline constexpr struct hour : named_scaled_unit<"h", mag<60>(), minute> { -} hour; -inline constexpr struct day : named_scaled_unit<"d", mag<24>(), hour> { -} day; - -// not a time unit! -inline constexpr struct second_squared : derived_unit { -} second_squared; - -// mass units -inline constexpr struct gram : named_unit<"g"> { -} gram; -inline constexpr struct kilogram : kilo { -} kilogram; -inline constexpr struct tonne : named_scaled_unit<"t", mag<1000>(), gram> { -} tonne; - -// other units -inline constexpr struct hertz : named_unit<"Hz", 1 / second> { -} hertz; -inline constexpr struct newton : named_unit<"N", kilogram * metre / second_squared> { -} newton; -inline constexpr struct pascal : named_unit<"Pa", kilogram / (metre * second_squared)> { -} pascal; -inline constexpr struct joule : named_unit<"J", newton * metre> { -} joule; -inline constexpr struct watt : named_unit<"W", joule / second> { -} watt; - -namespace short_units { - -// TODO collide with reference names -// inline namespace length { - -inline constexpr auto m = metre; -inline constexpr auto km = kilometre; -inline constexpr auto au = astronomical_unit; - -// } // namespace length - -// inline namespace area { - -inline constexpr auto m2 = square_metre; - -// } - -// inline namespace volume { - -inline constexpr auto m3 = cubic_metre; - -// } - -// inline namespace time { - -inline constexpr auto s = second; -inline constexpr auto min = minute; -inline constexpr auto h = hour; -inline constexpr auto d = day; - -inline constexpr auto s2 = second_squared; - -// } // namespace time - -// inline namespace mass { - -inline constexpr auto g = gram; -inline constexpr auto kg = kilogram; -inline constexpr auto t = tonne; - -// } // namespace mass - -// inline namespace frequency { - -inline constexpr auto Hz = hertz; - -// } - -// inline namespace force { - -inline constexpr auto N = newton; - -// } - -// inline namespace pressure { - -inline constexpr auto Pa = pascal; - -// } - -// inline namespace energy { - -inline constexpr auto J = joule; - -// } - -// inline namespace power { - -inline constexpr auto W = watt; - -// } - -} // namespace short_units - -} // namespace isq::si -} // namespace units - -#include - -namespace units::isq::si { - -inline constexpr struct length : system_reference { -} length; -inline constexpr struct time : system_reference { -} time; -inline constexpr struct frequency : system_reference { -} frequency; -inline constexpr struct area : system_reference { -} area; -inline constexpr struct volume : system_reference { -} volume; -inline constexpr struct speed : system_reference { -} speed; -inline constexpr struct acceleration : system_reference { -} acceleration; - -} // namespace units::isq::si - - -template -inline constexpr bool is_of_type = std::is_same_v, T>; - -namespace units::isq { - -// derived dimension expression template syntax verification -static_assert(is_of_type<1 / dim_time, derived_dimension>>); -static_assert(is_of_type<1 / (1 / dim_time), struct dim_time>); - -static_assert(is_of_type); -static_assert(is_of_type); -static_assert(is_of_type>>); -static_assert(is_of_type<1 / dim_time * dim_one, derived_dimension>>); - -static_assert(is_of_type>); -static_assert(is_of_type>>); - -static_assert( - is_of_type, struct dim_time>>); -static_assert( - is_of_type, struct dim_time>>); - -static_assert( - is_of_type, struct dim_time>>); -static_assert( - is_of_type, struct dim_time>>); - -static_assert(is_of_type<1 / dim_time * dim_length, derived_dimension>>); -static_assert(is_of_type<1 / dim_time * dim_time, struct dim_one>); - -static_assert(is_of_type); -static_assert(is_of_type<1 / dim_time / dim_one, derived_dimension>>); - -static_assert(is_of_type); -static_assert( - is_of_type<1 / dim_time * (1 / dim_time), derived_dimension>>>); -static_assert(is_of_type<1 / (dim_time * dim_time), derived_dimension>>>); -static_assert(is_of_type<1 / (1 / (dim_time * dim_time)), derived_dimension>>); - -static_assert(is_of_type>>>); -static_assert(is_of_type, per>>>); -static_assert(is_of_type); - -static_assert( - is_of_type>>); -static_assert( - is_of_type>>); -static_assert(is_of_type, per>>); -static_assert(is_of_type<1 / (dim_speed * dim_speed) * dim_length, - derived_dimension>>>); - -// comparisons of equivalent dimensions -static_assert(dim_length / dim_length == dim_one); - -static_assert(1 / dim_time == dim_frequency); -static_assert(1 / dim_frequency == dim_time); -static_assert(dim_frequency * dim_time == dim_one); - -static_assert(dim_length * dim_length == dim_area); -static_assert(dim_length * dim_length != dim_volume); -static_assert(dim_area / dim_length == dim_length); - -static_assert(dim_length * dim_length * dim_length == dim_volume); -static_assert(dim_area * dim_length == dim_volume); -static_assert(dim_volume / dim_length == dim_area); -static_assert(dim_volume / dim_length / dim_length == dim_length); -static_assert(dim_area * dim_area / dim_length == dim_volume); -static_assert(dim_area * (dim_area / dim_length) == dim_volume); -static_assert(dim_volume / (dim_length * dim_length) == dim_length); - -static_assert(dim_length / dim_time == dim_speed); -static_assert(dim_length * dim_time != dim_speed); -static_assert(dim_length / dim_time / dim_time != dim_speed); -static_assert(dim_length / dim_speed == dim_time); -static_assert(dim_speed * dim_time == dim_length); - -static_assert(dim_length / dim_time / dim_time == dim_acceleration); -static_assert(dim_length / (dim_time * dim_time) == dim_acceleration); -static_assert(dim_speed / dim_time == dim_acceleration); -static_assert(dim_speed / dim_acceleration == dim_time); -static_assert(dim_acceleration * dim_time == dim_speed); -static_assert(dim_acceleration * (dim_time * dim_time) == dim_length); -static_assert(dim_acceleration / dim_speed == dim_frequency); - -} // namespace units::isq - - -namespace units::isq::si { - -// derived unit expression template syntax verification -static_assert(is_of_type<1 / second, derived_unit>>); -static_assert(is_of_type<1 / (1 / second), struct second>); - -static_assert(is_of_type); -static_assert(is_of_type); -static_assert(is_of_type>>); -static_assert(is_of_type<1 / second * one, derived_unit>>); - -static_assert(is_of_type>); -static_assert(is_of_type>>); - -static_assert(is_of_type, struct second>>); -static_assert(is_of_type, struct second>>); - -static_assert(is_of_type, struct second>>); -static_assert(is_of_type, struct second>>); - -static_assert(is_of_type<1 / second * metre, derived_unit>>); -static_assert(is_of_type<1 / second * second, struct one>); - -static_assert(is_of_type); -static_assert(is_of_type<1 / second / one, derived_unit>>); - -static_assert(is_of_type); -static_assert(is_of_type<1 / second * (1 / second), derived_unit>>>); -static_assert(is_of_type<1 / (second * second), derived_unit>>>); -static_assert(is_of_type<1 / (1 / (second * second)), derived_unit>>); - -static_assert(is_of_type>>>); -static_assert( - is_of_type, per>>>); -static_assert(is_of_type); - -static_assert(is_of_type>>); -static_assert(is_of_type>>); - -// comparisons of equivalent dimensions -// static_assert(metre / metre == one); - -// static_assert(1 / second == dim_frequency); -// static_assert(1 / dim_frequency == second); -// static_assert(dim_frequency * second == one); - -// static_assert(metre * metre == dim_area); -// static_assert(metre * metre != dim_volume); -// static_assert(dim_area / metre == metre); - -// static_assert(metre * metre * metre == dim_volume); -// static_assert(dim_area * metre == dim_volume); -// static_assert(dim_volume / metre == dim_area); -// static_assert(dim_volume / metre / metre == metre); -// static_assert(dim_area * dim_area / metre == dim_volume); -// static_assert(dim_area * (dim_area / metre) == dim_volume); -// static_assert(dim_volume / (metre * metre) == metre); - -// static_assert(metre / second == dim_speed); -// static_assert(metre * second != dim_speed); -// static_assert(metre / second / second != dim_speed); -// static_assert(metre / dim_speed == second); -// static_assert(dim_speed * second == metre); - -// static_assert(metre / second / second == dim_acceleration); -// static_assert(metre / (second * second) == dim_acceleration); -// static_assert(dim_speed / second == dim_acceleration); -// static_assert(dim_speed / dim_acceleration == second); -// static_assert(dim_acceleration * second == dim_speed); -// static_assert(dim_acceleration * (second * second) == metre); -// static_assert(dim_acceleration / dim_speed == dim_frequency); - - -// Bq + Hz should not compile - -// Bq + Hz + 1/s should compile? - - -} // namespace units::isq::si - - -using namespace units; -using namespace units::isq::si; -using namespace units::isq::si::short_units; - -/* Frequency */ auto freq1 = 20 * frequency[Hz]; -// /* Frequency */ auto freq2 = 20 / (1 * time[s]); -quantity freq3(20); -// quantity freq4(20); -// quantity<1 / time[s]> freq5(20); - - -/* Speed */ auto speed1 = 20 * speed[m / s]; -/* Speed */ auto speed2 = 20 * (length[m] / isq::si::time[s]); -// quantity speed3(20); -// quantity speed4(20); - - -// quantity / second> speed1(123); -// quantity speed2(123); -// auto speed3 = 123 * (kilo / second); -// auto speed4 = 123 * (km / s); - -template -void print(); - -// constexpr auto avg_speed(quantity d, quantity t) { return d / t; } +#include +#include +#include // IWYU pragma: keep +#include +#include // IWYU pragma: keep +#include +#include +#include + +using namespace units::isq; + +constexpr Speed auto avg_speed(Length auto d, Time auto t) { return d / t; } int main() { - print(); - print(); + using namespace units::isq::si::literals; + using namespace units::isq::si::references; + using namespace units::aliases::isq::si::international; + + constexpr Speed auto v1 = 110 * (km / h); + constexpr Speed auto v2 = mi_per_h<>(70.); + constexpr Speed auto v3 = avg_speed(220_q_km, 2_q_h); + constexpr Speed auto v4 = avg_speed(si::length(140), si::time(2)); +#if UNITS_DOWNCAST_MODE == 0 + constexpr Speed auto v5 = quantity_cast>(v3); + constexpr Speed auto v6 = quantity_cast(v4); +#else + constexpr Speed auto v5 = quantity_cast>(v3); + constexpr Speed auto v6 = quantity_cast(v4); +#endif + constexpr Speed auto v7 = quantity_cast(v6); + + std::cout << v1 << '\n'; // 110 km/h + std::cout << v2 << '\n'; // 70 mi/h + std::cout << STD_FMT::format("{}", v3) << '\n'; // 110 km/h + std::cout << STD_FMT::format("{:*^14}", v4) << '\n'; // ***70 mi/h**** + std::cout << STD_FMT::format("{:%Q in %q}", v5) << '\n'; // 30.5556 in m/s + std::cout << STD_FMT::format("{0:%Q} in {0:%q}", v6) << '\n'; // 31.2928 in m/s + std::cout << STD_FMT::format("{:%Q}", v7) << '\n'; // 31 } From 5e36dd6167a931c2af795752c30f065245b53f28 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 8 Sep 2022 21:08:06 +0200 Subject: [PATCH 003/402] fix: `expr_consolidate` fixed for two the same powers --- src/core/include/units/bits/expression_template.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/include/units/bits/expression_template.h b/src/core/include/units/bits/expression_template.h index 638fc8c6..15e8be56 100644 --- a/src/core/include/units/bits/expression_template.h +++ b/src/core/include/units/bits/expression_template.h @@ -135,6 +135,7 @@ struct expr_consolidate_impl> { }; template + requires(!is_specialization_of_power) struct expr_consolidate_impl> { using type = expr_consolidate_impl, Rest...>>::type; }; From a3d4c8f01f6fb2e5dc7e6af73596dbb19ca3653e Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 8 Sep 2022 23:03:45 +0200 Subject: [PATCH 004/402] refactor: `derived_dimension` can now store only powers of base dimensions --- example/v2_framework.cpp | 174 ++++++++++++++++------------- src/core/include/units/dimension.h | 136 +++------------------- 2 files changed, 117 insertions(+), 193 deletions(-) diff --git a/example/v2_framework.cpp b/example/v2_framework.cpp index 9fbf1f4c..1167c7f0 100644 --- a/example/v2_framework.cpp +++ b/example/v2_framework.cpp @@ -27,22 +27,36 @@ namespace units::isq { 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_electric_current : base_dimension<"I"> { +} dim_electric_current; +// TODO Should the below use basic_symbol_text? How to name it for ASCII? +inline constexpr struct dim_thermodynamic_temperature : base_dimension<"Θ"> { +} dim_thermodynamic_temperature; +inline constexpr struct dim_amount_of_substance : base_dimension<"N"> { +} dim_amount_of_substance; +inline constexpr struct dim_luminous_intensity : base_dimension<"J"> { +} dim_luminous_intensity; + +// using dim_speed = decltype(dim_length / dim_time); +// inline constexpr dim_speed dim_speed; // template // concept Length = QuantityOf; -inline constexpr struct dim_time : base_dimension<"T"> { -} dim_time; -inline constexpr struct dim_frequency : decltype(1 / dim_time) { -} dim_frequency; -inline constexpr struct dim_area : decltype(dim_length * dim_length) { -} dim_area; -inline constexpr struct dim_volume : decltype(dim_area * dim_length) { -} dim_volume; -inline constexpr struct dim_speed : decltype(dim_length / dim_time) { -} dim_speed; -inline constexpr struct dim_acceleration : decltype(dim_speed / dim_time) { -} dim_acceleration; +// inline constexpr struct dim_frequency : decltype(1 / dim_time) { +// } dim_frequency; +// inline constexpr struct dim_area : decltype(dim_length * dim_length) { +// } dim_area; +// inline constexpr struct dim_volume : decltype(dim_area * dim_length) { +// } dim_volume; +// inline constexpr struct dim_speed : decltype(dim_length / dim_time) { +// } dim_speed; +// inline constexpr struct dim_acceleration : decltype(dim_speed / dim_time) { +// } dim_acceleration; // inline constexpr auto speed = length / time; @@ -198,15 +212,21 @@ inline constexpr struct length : system_reference { } length; inline constexpr struct time : system_reference { } time; -inline constexpr struct frequency : system_reference { +// inline constexpr struct frequency : system_reference { +inline constexpr struct frequency : system_reference { } frequency; -inline constexpr struct area : system_reference { +// inline constexpr struct area : system_reference { +inline constexpr struct area : system_reference { } area; -inline constexpr struct volume : system_reference { +// inline constexpr struct volume : system_reference { +inline constexpr struct volume : system_reference { } volume; -inline constexpr struct speed : system_reference { +// inline constexpr struct speed : system_reference { +inline constexpr struct speed : system_reference { } speed; -inline constexpr struct acceleration : system_reference { +// inline constexpr struct acceleration : system_reference { +inline constexpr struct acceleration : + system_reference { } acceleration; } // namespace units::isq::si @@ -257,47 +277,51 @@ static_assert(is_of_type, per>>>); static_assert(is_of_type); -static_assert( - is_of_type>>); -static_assert( - is_of_type>>); -static_assert(is_of_type, per>>); -static_assert(is_of_type<1 / (dim_speed * dim_speed) * dim_length, - derived_dimension>>>); +// static_assert( +// is_of_type>>); +// static_assert( +// is_of_type>>); +// static_assert(is_of_type, per>>); +// static_assert(is_of_type<1 / (dim_speed * dim_speed) * dim_length, +// derived_dimension>>>); + +namespace si { // comparisons of equivalent dimensions static_assert(dim_length / dim_length == dim_one); -static_assert(1 / dim_time == dim_frequency); -static_assert(1 / dim_frequency == dim_time); -static_assert(dim_frequency * dim_time == dim_one); +static_assert(1 / dim_time == frequency::dimension); +static_assert(1 / frequency::dimension == dim_time); +static_assert(frequency::dimension * dim_time == dim_one); -static_assert(dim_length * dim_length == dim_area); -static_assert(dim_length * dim_length != dim_volume); -static_assert(dim_area / dim_length == dim_length); +static_assert(dim_length * dim_length == area::dimension); +static_assert(dim_length * dim_length != volume::dimension); +static_assert(area::dimension / dim_length == dim_length); -static_assert(dim_length * dim_length * dim_length == dim_volume); -static_assert(dim_area * dim_length == dim_volume); -static_assert(dim_volume / dim_length == dim_area); -static_assert(dim_volume / dim_length / dim_length == dim_length); -static_assert(dim_area * dim_area / dim_length == dim_volume); -static_assert(dim_area * (dim_area / dim_length) == dim_volume); -static_assert(dim_volume / (dim_length * dim_length) == dim_length); +static_assert(dim_length * dim_length * dim_length == volume::dimension); +static_assert(area::dimension * dim_length == volume::dimension); +static_assert(volume::dimension / dim_length == area::dimension); +static_assert(volume::dimension / dim_length / dim_length == dim_length); +static_assert(area::dimension * area::dimension / dim_length == volume::dimension); +static_assert(area::dimension * (area::dimension / dim_length) == volume::dimension); +static_assert(volume::dimension / (dim_length * dim_length) == dim_length); -static_assert(dim_length / dim_time == dim_speed); -static_assert(dim_length * dim_time != dim_speed); -static_assert(dim_length / dim_time / dim_time != dim_speed); -static_assert(dim_length / dim_speed == dim_time); -static_assert(dim_speed * dim_time == dim_length); +static_assert(dim_length / dim_time == speed::dimension); +static_assert(dim_length * dim_time != speed::dimension); +static_assert(dim_length / dim_time / dim_time != speed::dimension); +static_assert(dim_length / speed::dimension == dim_time); +static_assert(speed::dimension * dim_time == dim_length); -static_assert(dim_length / dim_time / dim_time == dim_acceleration); -static_assert(dim_length / (dim_time * dim_time) == dim_acceleration); -static_assert(dim_speed / dim_time == dim_acceleration); -static_assert(dim_speed / dim_acceleration == dim_time); -static_assert(dim_acceleration * dim_time == dim_speed); -static_assert(dim_acceleration * (dim_time * dim_time) == dim_length); -static_assert(dim_acceleration / dim_speed == dim_frequency); +static_assert(dim_length / dim_time / dim_time == acceleration::dimension); +static_assert(dim_length / (dim_time * dim_time) == acceleration::dimension); +static_assert(speed::dimension / dim_time == acceleration::dimension); +static_assert(speed::dimension / acceleration::dimension == dim_time); +static_assert(acceleration::dimension * dim_time == speed::dimension); +static_assert(acceleration::dimension * (dim_time * dim_time) == dim_length); +static_assert(acceleration::dimension / speed::dimension == frequency::dimension); + +} // namespace si } // namespace units::isq @@ -344,35 +368,35 @@ static_assert(is_of_type #include -#include #include namespace units { @@ -87,99 +86,24 @@ concept Dimension = BaseDimension || DerivedDimension; namespace detail { -/** - * @brief Unpacks the list of potentially derived dimensions to a list containing only base dimensions - * - * @tparam Es Exponents of potentially derived dimensions - */ -template -struct dim_extract; - -template<> -struct dim_extract, type_list<>> { - using num = type_list<>; - using den = type_list<>; -}; - -template - requires BaseDimension || BaseDimension -struct dim_extract, type_list> { - using impl = dim_extract, type_list>; - using num = type_list_push_front; - using den = TYPENAME impl::den; -}; - -template - requires BaseDimension || BaseDimension -struct dim_extract, type_list> { - using impl = dim_extract, type_list>; - using num = TYPENAME impl::num; - using den = type_list_push_front; -}; - -template -struct dim_extract, type_list> : - dim_extract, - type_list_push_back> {}; - -template -struct dim_extract, NRest...>, type_list> : - dim_extract::num, power::den>::type, - NRest...>, - type_list_push_back< - typename expr_power::num, power::den>::type, - Dens...>> {}; - - -template -struct dim_extract, type_list> : - dim_extract> {}; - -template -struct dim_extract, type_list, DRest...>> : - dim_extract::num, power::den>::type, - type_list_push_back< - typename expr_power::num, power::den>::type, - DRest...>> {}; template using type_list_of_base_dimension_less = expr_less; -/** - * @brief Converts user provided derived dimension specification into a valid units::normalized_dimension definition - * - * User provided definition of a derived dimension may contain the same base dimension repeated more than once on the - * list possibly hidden in other derived units provided by the user. The process here should: - * 1. Extract derived dimensions into exponents of base dimensions. - * 2. Sort the exponents so the same dimensions are placed next to each other. - * 3. Consolidate contiguous range of exponents of the same base dimensions to a one (or possibly zero) exponent for - * this base dimension. - */ -template -struct normalized_dimension : detail::expr_fractions { -private: - using base = detail::expr_fractions; - using extracted = dim_extract; - using num_list = expr_consolidate>; - using den_list = expr_consolidate>; - using simple = expr_simplify; -public: - using normalized_num = TYPENAME simple::num; - using normalized_den = TYPENAME simple::den; -}; +template +inline constexpr bool is_dim_one = false; } // namespace detail // TODO add checking for `per` and power elements as well template -concept DimensionSpec = Dimension || is_specialization_of || detail::is_specialization_of_power; +concept DimensionSpec = + BaseDimension || detail::is_dim_one || is_specialization_of || detail::is_specialization_of_power; // User should not instantiate this type!!! +// It should not be exported from the module template -struct derived_dimension : detail::normalized_dimension, Ds...> {}; - -// TODO move type_list_fractions out of +struct derived_dimension : detail::expr_fractions, Ds...> {}; template std::true_type is_derived_dimension(const volatile derived_dimension*); @@ -195,66 +119,42 @@ inline constexpr struct dim_one : derived_dimension<> { namespace detail { -template -struct dimension_less : std::bool_constant() < type_name()> {}; - -template -using type_list_of_dimension_less = expr_less; +template<> +inline constexpr bool is_dim_one = true; } // namespace detail template -constexpr Dimension auto operator*(D1, D2) +[[nodiscard]] constexpr Dimension auto operator*(D1, D2) { - return detail::expr_multiply(); + return detail::expr_multiply(); } template -constexpr Dimension auto operator/(D1, D2) +[[nodiscard]] constexpr Dimension auto operator/(D1, D2) { - return detail::expr_divide(); + return detail::expr_divide(); } template -constexpr Dimension auto operator/(int value, D) +[[nodiscard]] constexpr Dimension auto operator/(int value, D) { gsl_Assert(value == 1); return detail::expr_invert(); } template -constexpr bool operator==(D1, D2) +[[nodiscard]] constexpr bool operator==(D1, D2) { return false; } -template -constexpr bool operator==(D1, D2) +template +[[nodiscard]] constexpr bool operator==(D, D) { - return D1::symbol == D2::symbol; + return true; } -template - requires(type_list_size == 0) && (type_list_size == 1) && - BaseDimension> -constexpr bool operator==(D1, D2) -{ - return D1::symbol == type_list_front::symbol; -} - -template - requires(type_list_size == 0) && (type_list_size == 1) && - BaseDimension> -constexpr bool operator==(D1, D2) -{ - return type_list_front::symbol == D2::symbol; -} - -template -constexpr bool operator==(D1, D2) -{ - return is_same_v && - is_same_v; -} +// TODO consider adding the support for text output of the dimensional equation } // namespace units From f516e3287e75afdedaa540e8630445de954aeaaf Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 8 Sep 2022 23:08:00 +0200 Subject: [PATCH 005/402] refactor: `nodiscard` added --- src/core/include/units/bits/expression_template.h | 10 +++++----- src/core/include/units/unit.h | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/core/include/units/bits/expression_template.h b/src/core/include/units/bits/expression_template.h index 15e8be56..f7ee9ff0 100644 --- a/src/core/include/units/bits/expression_template.h +++ b/src/core/include/units/bits/expression_template.h @@ -287,7 +287,7 @@ public: }; template typename To> -constexpr auto expr_expression_impl() +[[nodiscard]] constexpr auto expr_expression_impl() { constexpr std::size_t num = type_list_size; constexpr std::size_t den = type_list_size; @@ -312,7 +312,7 @@ using expr_expression = decltype(expr_expression_impl typename Pred, template typename To> -constexpr auto get_optimized_expression() +[[nodiscard]] constexpr auto get_optimized_expression() { using num_list = expr_consolidate; using den_list = expr_consolidate; @@ -332,7 +332,7 @@ constexpr auto get_optimized_expression() */ template typename Pred, template typename To> -constexpr auto expr_multiply() +[[nodiscard]] constexpr auto expr_multiply() { if constexpr (is_same_v) { return T2{}; @@ -356,7 +356,7 @@ constexpr auto expr_multiply() template typename Pred, template typename To> -constexpr auto expr_divide() +[[nodiscard]] constexpr auto expr_divide() { if constexpr (is_same_v) { return OneType{}; @@ -378,7 +378,7 @@ constexpr auto expr_divide() } template typename To> -constexpr auto expr_invert() +[[nodiscard]] constexpr auto expr_invert() { if constexpr (is_specialization_of) return expr_expression{}; diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index 24e1b0eb..697100f3 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -221,26 +221,26 @@ using type_list_of_unit_less = expr_less; } // namespace detail template -constexpr Unit auto operator*(U1, U2) +[[nodiscard]] constexpr Unit auto operator*(U1, U2) { return detail::expr_multiply(); } template -constexpr Unit auto operator/(U1, U2) +[[nodiscard]] constexpr Unit auto operator/(U1, U2) { return detail::expr_divide(); } template -constexpr Unit auto operator/(int value, U) +[[nodiscard]] constexpr Unit auto operator/(int value, U) { gsl_Assert(value == 1); return detail::expr_invert(); } template -constexpr bool operator==(U1, U2) +[[nodiscard]] constexpr bool operator==(U1, U2) { return false; } From 1a2c215578575cd1dfa2d32e46ceba370f02413b Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Fri, 9 Sep 2022 11:46:08 +0200 Subject: [PATCH 006/402] refactor: derived dimensions now can be used in the equations but will not be visible in the final type --- example/v2_framework.cpp | 156 ++++++++++++++--------------- src/core/include/units/dimension.h | 33 ++++-- 2 files changed, 96 insertions(+), 93 deletions(-) diff --git a/example/v2_framework.cpp b/example/v2_framework.cpp index 1167c7f0..c117af2a 100644 --- a/example/v2_framework.cpp +++ b/example/v2_framework.cpp @@ -41,25 +41,25 @@ inline constexpr struct dim_amount_of_substance : base_dimension<"N"> { inline constexpr struct dim_luminous_intensity : base_dimension<"J"> { } dim_luminous_intensity; +inline constexpr struct dim_frequency : decltype(1 / dim_time) { +} dim_frequency; +inline constexpr struct dim_area : decltype(dim_length * dim_length) { +} dim_area; +inline constexpr struct dim_volume : decltype(dim_area * dim_length) { +} dim_volume; +inline constexpr struct dim_speed : decltype(dim_length / dim_time) { +} dim_speed; +inline constexpr struct dim_acceleration : decltype(dim_speed / dim_time) { +} dim_acceleration; + +// inline constexpr auto speed = length / time; + // using dim_speed = decltype(dim_length / dim_time); // inline constexpr dim_speed dim_speed; // template // concept Length = QuantityOf; -// inline constexpr struct dim_frequency : decltype(1 / dim_time) { -// } dim_frequency; -// inline constexpr struct dim_area : decltype(dim_length * dim_length) { -// } dim_area; -// inline constexpr struct dim_volume : decltype(dim_area * dim_length) { -// } dim_volume; -// inline constexpr struct dim_speed : decltype(dim_length / dim_time) { -// } dim_speed; -// inline constexpr struct dim_acceleration : decltype(dim_speed / dim_time) { -// } dim_acceleration; - -// inline constexpr auto speed = length / time; - } // namespace units::isq #include @@ -212,21 +212,15 @@ inline constexpr struct length : system_reference { } length; inline constexpr struct time : system_reference { } time; -// inline constexpr struct frequency : system_reference { -inline constexpr struct frequency : system_reference { +inline constexpr struct frequency : system_reference { } frequency; -// inline constexpr struct area : system_reference { -inline constexpr struct area : system_reference { +inline constexpr struct area : system_reference { } area; -// inline constexpr struct volume : system_reference { -inline constexpr struct volume : system_reference { +inline constexpr struct volume : system_reference { } volume; -// inline constexpr struct speed : system_reference { -inline constexpr struct speed : system_reference { +inline constexpr struct speed : system_reference { } speed; -// inline constexpr struct acceleration : system_reference { -inline constexpr struct acceleration : - system_reference { +inline constexpr struct acceleration : system_reference { } acceleration; } // namespace units::isq::si @@ -277,49 +271,47 @@ static_assert(is_of_type, per>>>); static_assert(is_of_type); -// static_assert( -// is_of_type>>); -// static_assert( -// is_of_type>>); -// static_assert(is_of_type, per>>); -// static_assert(is_of_type<1 / (dim_speed * dim_speed) * dim_length, -// derived_dimension>>>); +static_assert(is_of_type); +static_assert(is_of_type>>); +static_assert( + is_of_type>>>); +static_assert(is_of_type<1 / (dim_speed * dim_speed) * dim_length, + derived_dimension, per>>); namespace si { // comparisons of equivalent dimensions static_assert(dim_length / dim_length == dim_one); -static_assert(1 / dim_time == frequency::dimension); -static_assert(1 / frequency::dimension == dim_time); -static_assert(frequency::dimension * dim_time == dim_one); +static_assert(1 / dim_time == dim_frequency); +static_assert(1 / dim_frequency == dim_time); +static_assert(dim_frequency * dim_time == dim_one); -static_assert(dim_length * dim_length == area::dimension); -static_assert(dim_length * dim_length != volume::dimension); -static_assert(area::dimension / dim_length == dim_length); +static_assert(dim_length * dim_length == dim_area); +static_assert(dim_length * dim_length != dim_volume); +static_assert(dim_area / dim_length == dim_length); -static_assert(dim_length * dim_length * dim_length == volume::dimension); -static_assert(area::dimension * dim_length == volume::dimension); -static_assert(volume::dimension / dim_length == area::dimension); -static_assert(volume::dimension / dim_length / dim_length == dim_length); -static_assert(area::dimension * area::dimension / dim_length == volume::dimension); -static_assert(area::dimension * (area::dimension / dim_length) == volume::dimension); -static_assert(volume::dimension / (dim_length * dim_length) == dim_length); +static_assert(dim_length * dim_length * dim_length == dim_volume); +static_assert(dim_area * dim_length == dim_volume); +static_assert(dim_volume / dim_length == dim_area); +static_assert(dim_volume / dim_length / dim_length == dim_length); +static_assert(dim_area * dim_area / dim_length == dim_volume); +static_assert(dim_area * (dim_area / dim_length) == dim_volume); +static_assert(dim_volume / (dim_length * dim_length) == dim_length); -static_assert(dim_length / dim_time == speed::dimension); -static_assert(dim_length * dim_time != speed::dimension); -static_assert(dim_length / dim_time / dim_time != speed::dimension); -static_assert(dim_length / speed::dimension == dim_time); -static_assert(speed::dimension * dim_time == dim_length); +static_assert(dim_length / dim_time == dim_speed); +static_assert(dim_length * dim_time != dim_speed); +static_assert(dim_length / dim_time / dim_time != dim_speed); +static_assert(dim_length / dim_speed == dim_time); +static_assert(dim_speed * dim_time == dim_length); -static_assert(dim_length / dim_time / dim_time == acceleration::dimension); -static_assert(dim_length / (dim_time * dim_time) == acceleration::dimension); -static_assert(speed::dimension / dim_time == acceleration::dimension); -static_assert(speed::dimension / acceleration::dimension == dim_time); -static_assert(acceleration::dimension * dim_time == speed::dimension); -static_assert(acceleration::dimension * (dim_time * dim_time) == dim_length); -static_assert(acceleration::dimension / speed::dimension == frequency::dimension); +static_assert(dim_length / dim_time / dim_time == dim_acceleration); +static_assert(dim_length / (dim_time * dim_time) == dim_acceleration); +static_assert(dim_speed / dim_time == dim_acceleration); +static_assert(dim_speed / dim_acceleration == dim_time); +static_assert(dim_acceleration * dim_time == dim_speed); +static_assert(dim_acceleration * (dim_time * dim_time) == dim_length); +static_assert(dim_acceleration / dim_speed == dim_frequency); } // namespace si @@ -368,35 +360,35 @@ static_assert(is_of_type -struct derived_dimension : detail::expr_fractions, Ds...> {}; +struct derived_dimension : detail::expr_fractions, Ds...> { + using type = derived_dimension; +}; template std::true_type is_derived_dimension(const volatile derived_dimension*); @@ -122,37 +124,46 @@ namespace detail { template<> inline constexpr bool is_dim_one = true; +template +struct dim_type_impl { + using type = T; +}; + +template +struct dim_type_impl { + using type = T::type; +}; + +template +using dim_type = dim_type_impl::type; + } // namespace detail template [[nodiscard]] constexpr Dimension auto operator*(D1, D2) { - return detail::expr_multiply(); + return detail::expr_multiply, detail::dim_type, struct dim_one, + detail::type_list_of_base_dimension_less, derived_dimension>(); } template [[nodiscard]] constexpr Dimension auto operator/(D1, D2) { - return detail::expr_divide(); + return detail::expr_divide, detail::dim_type, struct dim_one, + detail::type_list_of_base_dimension_less, derived_dimension>(); } template [[nodiscard]] constexpr Dimension auto operator/(int value, D) { gsl_Assert(value == 1); - return detail::expr_invert(); + return detail::expr_invert, struct dim_one, derived_dimension>(); } template [[nodiscard]] constexpr bool operator==(D1, D2) { - return false; -} - -template -[[nodiscard]] constexpr bool operator==(D, D) -{ - return true; + return is_same_v, detail::dim_type>; } // TODO consider adding the support for text output of the dimensional equation From 1c7ea897711c50650939c19eb6f4f6e8435092cf Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Fri, 9 Sep 2022 11:50:47 +0200 Subject: [PATCH 007/402] refactor: short units inlined subnamespaces introduced to limit possible name clashes --- example/v2_framework.cpp | 41 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/example/v2_framework.cpp b/example/v2_framework.cpp index c117af2a..51ca79e6 100644 --- a/example/v2_framework.cpp +++ b/example/v2_framework.cpp @@ -122,28 +122,27 @@ inline constexpr struct watt : named_unit<"W", joule / second> { namespace short_units { -// TODO collide with reference names -// inline namespace length { +inline namespace length_units { inline constexpr auto m = metre; inline constexpr auto km = kilometre; inline constexpr auto au = astronomical_unit; -// } // namespace length +} // namespace length_units -// inline namespace area { +inline namespace area_units { inline constexpr auto m2 = square_metre; -// } +} -// inline namespace volume { +inline namespace volume_units { inline constexpr auto m3 = cubic_metre; -// } +} -// inline namespace time { +inline namespace time_units { inline constexpr auto s = second; inline constexpr auto min = minute; @@ -152,45 +151,45 @@ inline constexpr auto d = day; inline constexpr auto s2 = second_squared; -// } // namespace time +} // namespace time_units -// inline namespace mass { +inline namespace mass_units { inline constexpr auto g = gram; inline constexpr auto kg = kilogram; inline constexpr auto t = tonne; -// } // namespace mass +} // namespace mass_units -// inline namespace frequency { +inline namespace frequency_units { inline constexpr auto Hz = hertz; -// } +} -// inline namespace force { +inline namespace force_units { inline constexpr auto N = newton; -// } +} -// inline namespace pressure { +inline namespace pressure_units { inline constexpr auto Pa = pascal; -// } +} -// inline namespace energy { +inline namespace energy_units { inline constexpr auto J = joule; -// } +} -// inline namespace power { +inline namespace power_units { inline constexpr auto W = watt; -// } +} } // namespace short_units From 9d3a1445513cc2cbbf8040d70cdcc5da07c1353b Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Fri, 9 Sep 2022 15:18:49 +0200 Subject: [PATCH 008/402] test: a few more tests added to the framework v2 example --- example/v2_framework.cpp | 48 +++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/example/v2_framework.cpp b/example/v2_framework.cpp index 51ca79e6..6c67a247 100644 --- a/example/v2_framework.cpp +++ b/example/v2_framework.cpp @@ -83,7 +83,7 @@ inline constexpr struct square_metre : derived_unit { } square_metre; // volume units -inline constexpr struct cubic_metre : derived_unit { +inline constexpr struct cubic_metre : derived_unit { } cubic_metre; // time units @@ -96,9 +96,12 @@ inline constexpr struct hour : named_scaled_unit<"h", mag<60>(), minute> { inline constexpr struct day : named_scaled_unit<"d", mag<24>(), hour> { } day; -// not a time unit! +// not time units! +// TODO should those be provided for other scaled units like ms, h, ... inline constexpr struct second_squared : derived_unit { } second_squared; +inline constexpr struct second_cubed : derived_unit { +} second_cubed; // mass units inline constexpr struct gram : named_unit<"g"> { @@ -356,10 +359,28 @@ static_assert(is_of_type); static_assert(is_of_type>>); static_assert(is_of_type>>); -// comparisons of equivalent dimensions -// static_assert(metre / metre == one); +// comparisons of equivalent units +static_assert(metre / metre == one); +static_assert(metre * metre == square_metre); +static_assert(second * second == second_squared); +static_assert(second * second * second == second_cubed); +static_assert(second * (second * second) == second_cubed); +static_assert(second_squared * second == second_cubed); +static_assert(second * second_squared == second_cubed); + +static_assert(1 / second * metre == metre / second); +static_assert(metre * (1 / second) == metre / second); +static_assert((metre / second) * (1 / second) == metre / second / second); +static_assert((metre / second) * (1 / second) == metre / (second * second)); +static_assert((metre / second) * (1 / second) == metre / second_squared); + +static_assert(hertz == 1 / second); +static_assert(newton == kilogram * metre / second_squared); +static_assert(joule == kilogram * square_metre / second_squared); +static_assert(joule == newton * metre); +static_assert(watt == joule / second); +static_assert(watt == kilogram * square_metre / second_cubed); -// static_assert(1 / second == dim_frequency); // static_assert(1 / dim_frequency == second); // static_assert(dim_frequency * second == one); @@ -398,6 +419,23 @@ static_assert(is_of_type +inline constexpr bool is_exactly_quantity_of = + is_same_v && is_same_v; + +namespace units::isq::si { + +// quantity tests +static_assert( + is_exactly_quantity_of>>); + +// static_assert(QuantityOf>); +// static_assert(QuantityOf>); +// // TODO Should this compile? + +} // namespace units::isq::si + + using namespace units; using namespace units::isq::si; using namespace units::isq::si::short_units; From b614a8c8871be57885f1aa60f285f926e24cf3c3 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Fri, 9 Sep 2022 15:22:35 +0200 Subject: [PATCH 009/402] refactor: all dimension types now have `_dim` as a suffix --- example/v2_framework.cpp | 236 ++++++++++++++--------------- src/core/include/units/dimension.h | 16 +- 2 files changed, 126 insertions(+), 126 deletions(-) diff --git a/example/v2_framework.cpp b/example/v2_framework.cpp index 6c67a247..a0c4652e 100644 --- a/example/v2_framework.cpp +++ b/example/v2_framework.cpp @@ -25,40 +25,40 @@ namespace units::isq { -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_electric_current : base_dimension<"I"> { -} dim_electric_current; +inline constexpr struct length_dim : base_dimension<"L"> { +} length_dim; +inline constexpr struct mass_dim : base_dimension<"M"> { +} mass_dim; +inline constexpr struct time_dim : base_dimension<"T"> { +} time_dim; +inline constexpr struct electric_current_dim : base_dimension<"I"> { +} electric_current_dim; // TODO Should the below use basic_symbol_text? How to name it for ASCII? -inline constexpr struct dim_thermodynamic_temperature : base_dimension<"Θ"> { -} dim_thermodynamic_temperature; -inline constexpr struct dim_amount_of_substance : base_dimension<"N"> { -} dim_amount_of_substance; -inline constexpr struct dim_luminous_intensity : base_dimension<"J"> { -} dim_luminous_intensity; +inline constexpr struct thermodynamic_temperature_dim : base_dimension<"Θ"> { +} thermodynamic_temperature_dim; +inline constexpr struct amount_of_substance_dim : base_dimension<"N"> { +} amount_of_substance_dim; +inline constexpr struct luminous_intensity_dim : base_dimension<"J"> { +} luminous_intensity_dim; -inline constexpr struct dim_frequency : decltype(1 / dim_time) { -} dim_frequency; -inline constexpr struct dim_area : decltype(dim_length * dim_length) { -} dim_area; -inline constexpr struct dim_volume : decltype(dim_area * dim_length) { -} dim_volume; -inline constexpr struct dim_speed : decltype(dim_length / dim_time) { -} dim_speed; -inline constexpr struct dim_acceleration : decltype(dim_speed / dim_time) { -} dim_acceleration; +inline constexpr struct frequency_dim : decltype(1 / time_dim) { +} frequency_dim; +inline constexpr struct area_dim : decltype(length_dim * length_dim) { +} area_dim; +inline constexpr struct volume_dim : decltype(area_dim * length_dim) { +} volume_dim; +inline constexpr struct speed_dim : decltype(length_dim / time_dim) { +} speed_dim; +inline constexpr struct acceleration_dim : decltype(speed_dim / time_dim) { +} acceleration_dim; // inline constexpr auto speed = length / time; -// using dim_speed = decltype(dim_length / dim_time); -// inline constexpr dim_speed dim_speed; +// using speed_dim = decltype(length_dim / time_dim); +// inline constexpr speed_dim speed_dim; // template -// concept Length = QuantityOf; +// concept Length = QuantityOf; } // namespace units::isq @@ -203,26 +203,26 @@ inline constexpr auto W = watt; namespace units { -inline constexpr struct dimensionless : system_reference { +inline constexpr struct dimensionless : system_reference { } dimensionless; } // namespace units namespace units::isq::si { -inline constexpr struct length : system_reference { +inline constexpr struct length : system_reference { } length; -inline constexpr struct time : system_reference { +inline constexpr struct time : system_reference { } time; -inline constexpr struct frequency : system_reference { +inline constexpr struct frequency : system_reference { } frequency; -inline constexpr struct area : system_reference { +inline constexpr struct area : system_reference { } area; -inline constexpr struct volume : system_reference { +inline constexpr struct volume : system_reference { } volume; -inline constexpr struct speed : system_reference { +inline constexpr struct speed : system_reference { } speed; -inline constexpr struct acceleration : system_reference { +inline constexpr struct acceleration : system_reference { } acceleration; } // namespace units::isq::si @@ -234,86 +234,86 @@ inline constexpr bool is_of_type = std::is_same_v>>); -static_assert(is_of_type<1 / (1 / dim_time), struct dim_time>); +static_assert(is_of_type<1 / time_dim, derived_dimension>>); +static_assert(is_of_type<1 / (1 / time_dim), struct time_dim>); -static_assert(is_of_type); -static_assert(is_of_type); -static_assert(is_of_type>>); -static_assert(is_of_type<1 / dim_time * dim_one, derived_dimension>>); +static_assert(is_of_type); +static_assert(is_of_type); +static_assert(is_of_type>>); +static_assert(is_of_type<1 / time_dim * one_dim, derived_dimension>>); -static_assert(is_of_type>); -static_assert(is_of_type>>); +static_assert(is_of_type>); +static_assert(is_of_type>>); static_assert( - is_of_type, struct dim_time>>); + is_of_type, struct time_dim>>); static_assert( - is_of_type, struct dim_time>>); + is_of_type, struct time_dim>>); static_assert( - is_of_type, struct dim_time>>); + is_of_type, struct time_dim>>); static_assert( - is_of_type, struct dim_time>>); + is_of_type, struct time_dim>>); -static_assert(is_of_type<1 / dim_time * dim_length, derived_dimension>>); -static_assert(is_of_type<1 / dim_time * dim_time, struct dim_one>); +static_assert(is_of_type<1 / time_dim * length_dim, derived_dimension>>); +static_assert(is_of_type<1 / time_dim * time_dim, struct one_dim>); -static_assert(is_of_type); -static_assert(is_of_type<1 / dim_time / dim_one, derived_dimension>>); +static_assert(is_of_type); +static_assert(is_of_type<1 / time_dim / one_dim, derived_dimension>>); -static_assert(is_of_type); +static_assert(is_of_type); static_assert( - is_of_type<1 / dim_time * (1 / dim_time), derived_dimension>>>); -static_assert(is_of_type<1 / (dim_time * dim_time), derived_dimension>>>); -static_assert(is_of_type<1 / (1 / (dim_time * dim_time)), derived_dimension>>); + is_of_type<1 / time_dim * (1 / time_dim), derived_dimension>>>); +static_assert(is_of_type<1 / (time_dim * time_dim), derived_dimension>>>); +static_assert(is_of_type<1 / (1 / (time_dim * time_dim)), derived_dimension>>); -static_assert(is_of_type>>>); -static_assert(is_of_type, per>>>); -static_assert(is_of_type); +static_assert(is_of_type>>>); +static_assert(is_of_type, per>>>); +static_assert(is_of_type); -static_assert(is_of_type); -static_assert(is_of_type>>); +static_assert(is_of_type); +static_assert(is_of_type>>); static_assert( - is_of_type>>>); -static_assert(is_of_type<1 / (dim_speed * dim_speed) * dim_length, - derived_dimension, per>>); + is_of_type>>>); +static_assert(is_of_type<1 / (speed_dim * speed_dim) * length_dim, + derived_dimension, per>>); namespace si { // comparisons of equivalent dimensions -static_assert(dim_length / dim_length == dim_one); +static_assert(length_dim / length_dim == one_dim); -static_assert(1 / dim_time == dim_frequency); -static_assert(1 / dim_frequency == dim_time); -static_assert(dim_frequency * dim_time == dim_one); +static_assert(1 / time_dim == frequency_dim); +static_assert(1 / frequency_dim == time_dim); +static_assert(frequency_dim * time_dim == one_dim); -static_assert(dim_length * dim_length == dim_area); -static_assert(dim_length * dim_length != dim_volume); -static_assert(dim_area / dim_length == dim_length); +static_assert(length_dim * length_dim == area_dim); +static_assert(length_dim * length_dim != volume_dim); +static_assert(area_dim / length_dim == length_dim); -static_assert(dim_length * dim_length * dim_length == dim_volume); -static_assert(dim_area * dim_length == dim_volume); -static_assert(dim_volume / dim_length == dim_area); -static_assert(dim_volume / dim_length / dim_length == dim_length); -static_assert(dim_area * dim_area / dim_length == dim_volume); -static_assert(dim_area * (dim_area / dim_length) == dim_volume); -static_assert(dim_volume / (dim_length * dim_length) == dim_length); +static_assert(length_dim * length_dim * length_dim == volume_dim); +static_assert(area_dim * length_dim == volume_dim); +static_assert(volume_dim / length_dim == area_dim); +static_assert(volume_dim / length_dim / length_dim == length_dim); +static_assert(area_dim * area_dim / length_dim == volume_dim); +static_assert(area_dim * (area_dim / length_dim) == volume_dim); +static_assert(volume_dim / (length_dim * length_dim) == length_dim); -static_assert(dim_length / dim_time == dim_speed); -static_assert(dim_length * dim_time != dim_speed); -static_assert(dim_length / dim_time / dim_time != dim_speed); -static_assert(dim_length / dim_speed == dim_time); -static_assert(dim_speed * dim_time == dim_length); +static_assert(length_dim / time_dim == speed_dim); +static_assert(length_dim * time_dim != speed_dim); +static_assert(length_dim / time_dim / time_dim != speed_dim); +static_assert(length_dim / speed_dim == time_dim); +static_assert(speed_dim * time_dim == length_dim); -static_assert(dim_length / dim_time / dim_time == dim_acceleration); -static_assert(dim_length / (dim_time * dim_time) == dim_acceleration); -static_assert(dim_speed / dim_time == dim_acceleration); -static_assert(dim_speed / dim_acceleration == dim_time); -static_assert(dim_acceleration * dim_time == dim_speed); -static_assert(dim_acceleration * (dim_time * dim_time) == dim_length); -static_assert(dim_acceleration / dim_speed == dim_frequency); +static_assert(length_dim / time_dim / time_dim == acceleration_dim); +static_assert(length_dim / (time_dim * time_dim) == acceleration_dim); +static_assert(speed_dim / time_dim == acceleration_dim); +static_assert(speed_dim / acceleration_dim == time_dim); +static_assert(acceleration_dim * time_dim == speed_dim); +static_assert(acceleration_dim * (time_dim * time_dim) == length_dim); +static_assert(acceleration_dim / speed_dim == frequency_dim); } // namespace si @@ -381,34 +381,34 @@ static_assert(joule == newton * metre); static_assert(watt == joule / second); static_assert(watt == kilogram * square_metre / second_cubed); -// static_assert(1 / dim_frequency == second); -// static_assert(dim_frequency * second == one); +// static_assert(1 / frequency_dim == second); +// static_assert(frequency_dim * second == one); -// static_assert(metre * metre == dim_area); -// static_assert(metre * metre != dim_volume); -// static_assert(dim_area / metre == metre); +// static_assert(metre * metre == area_dim); +// static_assert(metre * metre != volume_dim); +// static_assert(area_dim / metre == metre); -// static_assert(metre * metre * metre == dim_volume); -// static_assert(dim_area * metre == dim_volume); -// static_assert(dim_volume / metre == dim_area); -// static_assert(dim_volume / metre / metre == metre); -// static_assert(dim_area * dim_area / metre == dim_volume); -// static_assert(dim_area * (dim_area / metre) == dim_volume); -// static_assert(dim_volume / (metre * metre) == metre); +// static_assert(metre * metre * metre == volume_dim); +// static_assert(area_dim * metre == volume_dim); +// static_assert(volume_dim / metre == area_dim); +// static_assert(volume_dim / metre / metre == metre); +// static_assert(area_dim * area_dim / metre == volume_dim); +// static_assert(area_dim * (area_dim / metre) == volume_dim); +// static_assert(volume_dim / (metre * metre) == metre); -// static_assert(metre / second == dim_speed); -// static_assert(metre * second != dim_speed); -// static_assert(metre / second / second != dim_speed); -// static_assert(metre / dim_speed == second); -// static_assert(dim_speed * second == metre); +// static_assert(metre / second == speed_dim); +// static_assert(metre * second != speed_dim); +// static_assert(metre / second / second != speed_dim); +// static_assert(metre / speed_dim == second); +// static_assert(speed_dim * second == metre); -// static_assert(metre / second / second == dim_acceleration); -// static_assert(metre / (second * second) == dim_acceleration); -// static_assert(dim_speed / second == dim_acceleration); -// static_assert(dim_speed / dim_acceleration == second); -// static_assert(dim_acceleration * second == dim_speed); -// static_assert(dim_acceleration * (second * second) == metre); -// static_assert(dim_acceleration / dim_speed == dim_frequency); +// static_assert(metre / second / second == acceleration_dim); +// static_assert(metre / (second * second) == acceleration_dim); +// static_assert(speed_dim / second == acceleration_dim); +// static_assert(speed_dim / acceleration_dim == second); +// static_assert(acceleration_dim * second == speed_dim); +// static_assert(acceleration_dim * (second * second) == metre); +// static_assert(acceleration_dim / speed_dim == frequency_dim); // Bq + Hz should not compile @@ -427,10 +427,10 @@ namespace units::isq::si { // quantity tests static_assert( - is_exactly_quantity_of>>); + is_exactly_quantity_of>>); -// static_assert(QuantityOf>); -// static_assert(QuantityOf>); +// static_assert(QuantityOf>); +// static_assert(QuantityOf>); // // TODO Should this compile? } // namespace units::isq::si diff --git a/src/core/include/units/dimension.h b/src/core/include/units/dimension.h index 0dee97aa..b07a0076 100644 --- a/src/core/include/units/dimension.h +++ b/src/core/include/units/dimension.h @@ -91,14 +91,14 @@ template using type_list_of_base_dimension_less = expr_less; template -inline constexpr bool is_dim_one = false; +inline constexpr bool is_one_dim = false; } // namespace detail // TODO add checking for `per` and power elements as well template concept DimensionSpec = - BaseDimension || detail::is_dim_one || is_specialization_of || detail::is_specialization_of_power; + BaseDimension || detail::is_one_dim || is_specialization_of || detail::is_specialization_of_power; // User should not instantiate this type!!! // It should not be exported from the module @@ -116,13 +116,13 @@ std::true_type is_derived_dimension(const volatile derived_dimension*); * Dimension for which all the exponents of the factors corresponding to the base * dimensions are zero. Also commonly named as "dimensionless". */ -inline constexpr struct dim_one : derived_dimension<> { -} dim_one; +inline constexpr struct one_dim : derived_dimension<> { +} one_dim; namespace detail { template<> -inline constexpr bool is_dim_one = true; +inline constexpr bool is_one_dim = true; template struct dim_type_impl { @@ -142,14 +142,14 @@ using dim_type = dim_type_impl::type; template [[nodiscard]] constexpr Dimension auto operator*(D1, D2) { - return detail::expr_multiply, detail::dim_type, struct dim_one, + return detail::expr_multiply, detail::dim_type, struct one_dim, detail::type_list_of_base_dimension_less, derived_dimension>(); } template [[nodiscard]] constexpr Dimension auto operator/(D1, D2) { - return detail::expr_divide, detail::dim_type, struct dim_one, + return detail::expr_divide, detail::dim_type, struct one_dim, detail::type_list_of_base_dimension_less, derived_dimension>(); } @@ -157,7 +157,7 @@ template [[nodiscard]] constexpr Dimension auto operator/(int value, D) { gsl_Assert(value == 1); - return detail::expr_invert, struct dim_one, derived_dimension>(); + return detail::expr_invert, struct one_dim, derived_dimension>(); } template From 806fb0751bac13ec0b67e136204d45a4714f2bf5 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Sat, 10 Sep 2022 08:44:46 +0200 Subject: [PATCH 010/402] refactor: `short_units` renamed to `unit_symbols` --- example/v2_framework.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/example/v2_framework.cpp b/example/v2_framework.cpp index a0c4652e..6b9803ac 100644 --- a/example/v2_framework.cpp +++ b/example/v2_framework.cpp @@ -123,7 +123,7 @@ inline constexpr struct joule : named_unit<"J", newton * metre> { inline constexpr struct watt : named_unit<"W", joule / second> { } watt; -namespace short_units { +namespace unit_symbols { inline namespace length_units { @@ -194,7 +194,7 @@ inline constexpr auto W = watt; } -} // namespace short_units +} // namespace unit_symbols } // namespace isq::si } // namespace units @@ -438,7 +438,7 @@ static_assert( using namespace units; using namespace units::isq::si; -using namespace units::isq::si::short_units; +using namespace units::isq::si::unit_symbols; /* Frequency */ auto freq1 = 20 * frequency[Hz]; // /* Frequency */ auto freq2 = 20 / (1 * isq::si::time[s]); From 70185b49c28ceb856229955f068a8a119f1423f8 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 15 Sep 2022 14:52:54 -0600 Subject: [PATCH 011/402] refactor: `constexpr` replaced with `consteval` --- src/core/include/units/bits/expression_template.h | 12 ++++++------ src/core/include/units/bits/external/type_list.h | 2 +- src/core/include/units/dimension.h | 8 ++++---- src/core/include/units/reference.h | 6 +++--- src/core/include/units/unit.h | 8 ++++---- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/core/include/units/bits/expression_template.h b/src/core/include/units/bits/expression_template.h index f7ee9ff0..ed3bcb70 100644 --- a/src/core/include/units/bits/expression_template.h +++ b/src/core/include/units/bits/expression_template.h @@ -66,7 +66,7 @@ struct power { namespace detail { template -constexpr auto power_or_T_impl() +consteval auto power_or_T_impl() { constexpr ratio r{Num, Den}; if constexpr (r.den == 1) { @@ -287,7 +287,7 @@ public: }; template typename To> -[[nodiscard]] constexpr auto expr_expression_impl() +[[nodiscard]] consteval auto expr_expression_impl() { constexpr std::size_t num = type_list_size; constexpr std::size_t den = type_list_size; @@ -312,7 +312,7 @@ using expr_expression = decltype(expr_expression_impl typename Pred, template typename To> -[[nodiscard]] constexpr auto get_optimized_expression() +[[nodiscard]] consteval auto get_optimized_expression() { using num_list = expr_consolidate; using den_list = expr_consolidate; @@ -332,7 +332,7 @@ template typename Pred, template typename To> -[[nodiscard]] constexpr auto expr_multiply() +[[nodiscard]] consteval auto expr_multiply() { if constexpr (is_same_v) { return T2{}; @@ -356,7 +356,7 @@ template typename Pred, template typename To> -[[nodiscard]] constexpr auto expr_divide() +[[nodiscard]] consteval auto expr_divide() { if constexpr (is_same_v) { return OneType{}; @@ -378,7 +378,7 @@ template typename To> -[[nodiscard]] constexpr auto expr_invert() +[[nodiscard]] consteval auto expr_invert() { if constexpr (is_specialization_of) return expr_expression{}; diff --git a/src/core/include/units/bits/external/type_list.h b/src/core/include/units/bits/external/type_list.h index 28007478..3eddfcfe 100644 --- a/src/core/include/units/bits/external/type_list.h +++ b/src/core/include/units/bits/external/type_list.h @@ -48,7 +48,7 @@ concept TypeList = detail::is_type_list; namespace detail { template typename List, typename... Ts> -constexpr std::size_t type_list_size_impl(List) +consteval std::size_t type_list_size_impl(List) { return sizeof...(Ts); } diff --git a/src/core/include/units/dimension.h b/src/core/include/units/dimension.h index b07a0076..407088f1 100644 --- a/src/core/include/units/dimension.h +++ b/src/core/include/units/dimension.h @@ -140,28 +140,28 @@ using dim_type = dim_type_impl::type; } // namespace detail template -[[nodiscard]] constexpr Dimension auto operator*(D1, D2) +[[nodiscard]] consteval Dimension auto operator*(D1, D2) { return detail::expr_multiply, detail::dim_type, struct one_dim, detail::type_list_of_base_dimension_less, derived_dimension>(); } template -[[nodiscard]] constexpr Dimension auto operator/(D1, D2) +[[nodiscard]] consteval Dimension auto operator/(D1, D2) { return detail::expr_divide, detail::dim_type, struct one_dim, detail::type_list_of_base_dimension_less, derived_dimension>(); } template -[[nodiscard]] constexpr Dimension auto operator/(int value, D) +[[nodiscard]] consteval Dimension auto operator/(int value, D) { gsl_Assert(value == 1); return detail::expr_invert, struct one_dim, derived_dimension>(); } template -[[nodiscard]] constexpr bool operator==(D1, D2) +[[nodiscard]] consteval bool operator==(D1, D2) { return is_same_v, detail::dim_type>; } diff --git a/src/core/include/units/reference.h b/src/core/include/units/reference.h index 6fa3c6cc..291a7fab 100644 --- a/src/core/include/units/reference.h +++ b/src/core/include/units/reference.h @@ -121,14 +121,14 @@ template concept Reference = is_specialization_of; template -[[nodiscard]] constexpr reference operator*(R1, +[[nodiscard]] consteval reference operator*(R1, R2) { return {}; } template -[[nodiscard]] constexpr reference operator/(R1, +[[nodiscard]] consteval reference operator/(R1, R2) { return {}; @@ -153,7 +153,7 @@ struct system_reference { template // requires same_unit_reference - [[nodiscard]] constexpr reference operator[](U) const + [[nodiscard]] consteval reference operator[](U) const { return {}; } diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index 697100f3..5081cb5b 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -221,26 +221,26 @@ using type_list_of_unit_less = expr_less; } // namespace detail template -[[nodiscard]] constexpr Unit auto operator*(U1, U2) +[[nodiscard]] consteval Unit auto operator*(U1, U2) { return detail::expr_multiply(); } template -[[nodiscard]] constexpr Unit auto operator/(U1, U2) +[[nodiscard]] consteval Unit auto operator/(U1, U2) { return detail::expr_divide(); } template -[[nodiscard]] constexpr Unit auto operator/(int value, U) +[[nodiscard]] consteval Unit auto operator/(int value, U) { gsl_Assert(value == 1); return detail::expr_invert(); } template -[[nodiscard]] constexpr bool operator==(U1, U2) +[[nodiscard]] consteval bool operator==(U1, U2) { return false; } From 2f365b51354c49646322411ca8e43cad6c4369f3 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 15 Sep 2022 15:13:46 -0600 Subject: [PATCH 012/402] refactor: `mag` and `mag_power` changed to variable templates --- src/core/include/units/magnitude.h | 11 ++--- src/core/include/units/unit.h | 4 +- .../si/include/units/isq/si/prefixes.h | 40 +++++++++---------- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/src/core/include/units/magnitude.h b/src/core/include/units/magnitude.h index d0bd6501..5f27f66c 100644 --- a/src/core/include/units/magnitude.h +++ b/src/core/include/units/magnitude.h @@ -653,22 +653,17 @@ inline constexpr auto prime_factorization_v = prime_factorization::value; * This will be the main way end users create Magnitudes. They should rarely (if ever) create a magnitude<...> by * manually adding base powers. */ + template requires(R.num > 0) -constexpr Magnitude auto mag() -{ - return detail::prime_factorization_v / detail::prime_factorization_v; -} +inline constexpr Magnitude auto mag = detail::prime_factorization_v / detail::prime_factorization_v; /** * @brief Create a Magnitude which is some rational number raised to a rational power. */ template requires(Base.num > 0) -constexpr Magnitude auto mag_power() -{ - return pow(mag()); -} +inline constexpr Magnitude auto mag_power = pow(mag); namespace detail { template diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index 5081cb5b..d3c5b068 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -103,7 +103,7 @@ template concept UnitSpec = Unit || is_specialization_of || detail::is_specialization_of_power; template -struct derived_unit : detail::expr_fractions, Us...>, scaled_unit(), derived_unit> {}; +struct derived_unit : detail::expr_fractions, Us...>, scaled_unit, derived_unit> {}; // : detail::normalized_dimension, Ds...> {}; @@ -127,7 +127,7 @@ template struct named_unit; template -struct named_unit : scaled_unit(), named_unit> { +struct named_unit : scaled_unit, named_unit> { static constexpr auto symbol = Symbol; }; diff --git a/src/systems/si/include/units/isq/si/prefixes.h b/src/systems/si/include/units/isq/si/prefixes.h index e150426e..5ecd21e6 100644 --- a/src/systems/si/include/units/isq/si/prefixes.h +++ b/src/systems/si/include/units/isq/si/prefixes.h @@ -27,44 +27,44 @@ namespace units::isq::si { template -struct yocto : prefixed_unit<"y", pow<-24>(mag<10>()), U> {}; +struct yocto : prefixed_unit<"y", mag_power<10, -24>, U> {}; template -struct zepto : prefixed_unit<"z", pow<-21>(mag<10>()), U> {}; +struct zepto : prefixed_unit<"z", mag_power<10, -21>, U> {}; template -struct atto : prefixed_unit<"a", pow<-18>(mag<10>()), U> {}; +struct atto : prefixed_unit<"a", mag_power<10, -18>, U> {}; template -struct femto : prefixed_unit<"f", pow<-15>(mag<10>()), U> {}; +struct femto : prefixed_unit<"f", mag_power<10, -15>, U> {}; template -struct pico : prefixed_unit<"p", pow<-12>(mag<10>()), U> {}; +struct pico : prefixed_unit<"p", mag_power<10, -12>, U> {}; template -struct nano : prefixed_unit<"n", pow<-9>(mag<10>()), U> {}; +struct nano : prefixed_unit<"n", mag_power<10, -9>, U> {}; template -struct micro : prefixed_unit(mag<10>()), U> {}; +struct micro : prefixed_unit, U> {}; template -struct milli : prefixed_unit<"m", pow<-3>(mag<10>()), U> {}; +struct milli : prefixed_unit<"m", mag_power<10, -3>, U> {}; template -struct centi : prefixed_unit<"c", pow<-2>(mag<10>()), U> {}; +struct centi : prefixed_unit<"c", mag_power<10, -2>, U> {}; template -struct deci : prefixed_unit<"d", pow<-1>(mag<10>()), U> {}; +struct deci : prefixed_unit<"d", mag_power<10, -1>, U> {}; template -struct deca : prefixed_unit<"da", pow<1>(mag<10>()), U> {}; +struct deca : prefixed_unit<"da", mag_power<10, 1>, U> {}; template -struct hecto : prefixed_unit<"h", pow<2>(mag<10>()), U> {}; +struct hecto : prefixed_unit<"h", mag_power<10, 2>, U> {}; template -struct kilo : prefixed_unit<"k", pow<3>(mag<10>()), U> {}; +struct kilo : prefixed_unit<"k", mag_power<10, 3>, U> {}; template -struct mega : prefixed_unit<"M", pow<6>(mag<10>()), U> {}; +struct mega : prefixed_unit<"M", mag_power<10, 6>, U> {}; template -struct giga : prefixed_unit<"G", pow<9>(mag<10>()), U> {}; +struct giga : prefixed_unit<"G", mag_power<10, 9>, U> {}; template -struct tera : prefixed_unit<"T", pow<12>(mag<10>()), U> {}; +struct tera : prefixed_unit<"T", mag_power<10, 12>, U> {}; template -struct peta : prefixed_unit<"P", pow<15>(mag<10>()), U> {}; +struct peta : prefixed_unit<"P", mag_power<10, 15>, U> {}; template -struct exa : prefixed_unit<"E", pow<18>(mag<10>()), U> {}; +struct exa : prefixed_unit<"E", mag_power<10, 18>, U> {}; template -struct zetta : prefixed_unit<"Z", pow<21>(mag<10>()), U> {}; +struct zetta : prefixed_unit<"Z", mag_power<10, 21>, U> {}; template -struct yotta : prefixed_unit<"Y", pow<24>(mag<10>()), U> {}; +struct yotta : prefixed_unit<"Y", mag_power<10, 24>, U> {}; } // namespace units::isq::si From 2d5386504d3a4c73e18c303646f16d4f9212cd10 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Fri, 16 Sep 2022 17:38:40 -0600 Subject: [PATCH 013/402] refactor: Unused code commented for now --- .../include/units/bits/expression_template.h | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/core/include/units/bits/expression_template.h b/src/core/include/units/bits/expression_template.h index ed3bcb70..054a5900 100644 --- a/src/core/include/units/bits/expression_template.h +++ b/src/core/include/units/bits/expression_template.h @@ -83,30 +83,30 @@ template using power_or_T = decltype(power_or_T_impl()); // type_power -template -struct type_power { - using type = conditional, power>; -}; +// template +// struct type_power { +// using type = conditional, power>; +// }; -template -struct type_power, Num, 1> { - using type = power; -}; +// template +// struct type_power, Num, 1> { +// using type = power; +// }; -template -struct type_power, Num, Den> { - static constexpr ratio r = ratio(power::num, power::den) * ratio(Num, Den); - using type = power_or_T; -}; +// template +// struct type_power, Num, Den> { +// static constexpr ratio r = ratio(power::num, power::den) * ratio(Num, Den); +// using type = power_or_T; +// }; // expr_power -template -struct expr_power; +// template +// struct expr_power; -template -struct expr_power, Num, Den> { - using type = type_list::type...>; -}; +// template +// struct expr_power, Num, Den> { +// using type = type_list::type...>; +// }; /** * @brief Consolidates contiguous ranges of exponents of the same dimension From 726c67b19403bd21e9f00c205fc3eff3a082d709 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Fri, 16 Sep 2022 17:40:13 -0600 Subject: [PATCH 014/402] refactor: `ratio` usage added to `power` --- .../include/units/bits/expression_template.h | 52 +++++++------------ 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/src/core/include/units/bits/expression_template.h b/src/core/include/units/bits/expression_template.h index 054a5900..e911428d 100644 --- a/src/core/include/units/bits/expression_template.h +++ b/src/core/include/units/bits/expression_template.h @@ -31,11 +31,14 @@ namespace units { template struct type_list {}; -template +template struct per {}; -template -struct power; +template +struct power { + using factor = F; + static constexpr ::units::ratio ratio{Num, Den...}; +}; // TODO make_power() that will simplify cases like ? @@ -49,38 +52,25 @@ inline constexpr bool is_specialization_of_power> = true; } // namespace detail -template -struct power { - using factor = F; - static constexpr int num = Num; - static constexpr int den = 1; -}; - -template -struct power { - using factor = F; - static constexpr int num = Num; - static constexpr int den = Den; -}; - namespace detail { -template +template +// template // TODO consteval auto power_or_T_impl() { - constexpr ratio r{Num, Den}; - if constexpr (r.den == 1) { - if constexpr (r.num == 1) + if constexpr (R.den == 1) { + if constexpr (R.num == 1) return T{}; else - return power{}; + return power{}; } else { - return power{}; + return power{}; } }; -template -using power_or_T = decltype(power_or_T_impl()); +template +// template // TODO +using power_or_T = decltype(power_or_T_impl()); // type_power // template @@ -142,16 +132,14 @@ struct expr_consolidate_impl> { template struct expr_consolidate_impl, Rest...>> { - using type = expr_consolidate_impl< - type_list::num + power::den, power::den>, Rest...>>::type; + using type = expr_consolidate_impl::ratio + 1>, Rest...>>::type; }; template struct expr_consolidate_impl, power, Rest...>> { - static constexpr ratio r = - ratio(power::num, power::den) + ratio(power::num, power::den); + static constexpr ratio r = power::ratio + power::ratio; using type = conditional>::type, - typename expr_consolidate_impl, Rest...>>::type>; + typename expr_consolidate_impl, Rest...>>::type>; }; template @@ -162,8 +150,8 @@ using expr_consolidate = typename expr_consolidate_impl::type; template struct expr_simplify_power { - static constexpr ratio r = ratio(powerNum::num, powerNum::den) - ratio(powerDen::num, powerDen::den); - using type = power_or_T; + static constexpr ratio r = powerNum::ratio - powerDen::ratio; + using type = power_or_T; using num = conditional<(r > 0), type_list, type_list<>>; using den = conditional<(r < 0), type_list, type_list<>>; }; From 79ef21b2a5c432031d854a6f3f54bda7c3211e9a Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 22 Sep 2022 10:23:41 +0200 Subject: [PATCH 015/402] refactor: `power::ratio` renamed to `power::exponent` --- src/core/include/units/bits/expression_template.h | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/core/include/units/bits/expression_template.h b/src/core/include/units/bits/expression_template.h index e911428d..089cf147 100644 --- a/src/core/include/units/bits/expression_template.h +++ b/src/core/include/units/bits/expression_template.h @@ -37,11 +37,9 @@ struct per {}; template struct power { using factor = F; - static constexpr ::units::ratio ratio{Num, Den...}; + static constexpr ratio exponent{Num, Den...}; }; -// TODO make_power() that will simplify cases like ? - namespace detail { template @@ -55,7 +53,7 @@ inline constexpr bool is_specialization_of_power> = true; namespace detail { template -// template // TODO +// template // TODO consteval auto power_or_T_impl() { if constexpr (R.den == 1) { @@ -132,12 +130,12 @@ struct expr_consolidate_impl> { template struct expr_consolidate_impl, Rest...>> { - using type = expr_consolidate_impl::ratio + 1>, Rest...>>::type; + using type = expr_consolidate_impl::exponent + 1>, Rest...>>::type; }; template struct expr_consolidate_impl, power, Rest...>> { - static constexpr ratio r = power::ratio + power::ratio; + static constexpr ratio r = power::exponent + power::exponent; using type = conditional>::type, typename expr_consolidate_impl, Rest...>>::type>; }; @@ -150,7 +148,7 @@ using expr_consolidate = typename expr_consolidate_impl::type; template struct expr_simplify_power { - static constexpr ratio r = powerNum::ratio - powerDen::ratio; + static constexpr ratio r = powerNum::exponent - powerDen::exponent; using type = power_or_T; using num = conditional<(r > 0), type_list, type_list<>>; using den = conditional<(r < 0), type_list, type_list<>>; From f375797372f2226e17020d488ef8a46cfa9ebda3 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 22 Sep 2022 10:24:32 +0200 Subject: [PATCH 016/402] refactor: `constexpr` replaced with `consteval` --- src/core/include/units/bits/prime.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/core/include/units/bits/prime.h b/src/core/include/units/bits/prime.h index 56a65168..174cee4e 100644 --- a/src/core/include/units/bits/prime.h +++ b/src/core/include/units/bits/prime.h @@ -32,7 +32,7 @@ namespace units::detail { -constexpr bool is_prime_by_trial_division(std::uintmax_t n) +[[nodiscard]] consteval bool is_prime_by_trial_division(std::uintmax_t n) { for (std::uintmax_t f = 2; f * f <= n; f += 1 + (f % 2)) { if (n % f == 0) { @@ -45,7 +45,7 @@ constexpr bool is_prime_by_trial_division(std::uintmax_t n) // Return the first factor of n, as long as it is either k or n. // // Precondition: no integer smaller than k evenly divides n. -constexpr std::optional first_factor_maybe(std::uintmax_t n, std::uintmax_t k) +[[nodiscard]] constexpr std::optional first_factor_maybe(std::uintmax_t n, std::uintmax_t k) { if (n % k == 0) { return k; @@ -57,7 +57,7 @@ constexpr std::optional first_factor_maybe(std::uintmax_t n, std } template -constexpr std::array first_n_primes() +[[nodiscard]] consteval std::array first_n_primes() { std::array primes; primes[0] = 2; @@ -71,7 +71,7 @@ constexpr std::array first_n_primes() } template -constexpr void call_for_coprimes_up_to(std::uintmax_t n, const std::array& basis, Callable&& call) +consteval void call_for_coprimes_up_to(std::uintmax_t n, const std::array& basis, Callable&& call) { for (std::uintmax_t i = 0u; i < n; ++i) { if (std::apply([&i](auto... primes) { return ((i % primes != 0) && ...); }, basis)) { @@ -81,7 +81,7 @@ constexpr void call_for_coprimes_up_to(std::uintmax_t n, const std::array -constexpr std::size_t num_coprimes_up_to(std::uintmax_t n, const std::array& basis) +[[nodiscard]] consteval std::size_t num_coprimes_up_to(std::uintmax_t n, const std::array& basis) { std::size_t count = 0u; call_for_coprimes_up_to(n, basis, [&count](auto) { ++count; }); @@ -89,7 +89,7 @@ constexpr std::size_t num_coprimes_up_to(std::uintmax_t n, const std::array -constexpr auto coprimes_up_to(std::size_t n, const std::array& basis) +[[nodiscard]] consteval auto coprimes_up_to(std::size_t n, const std::array& basis) { std::array coprimes; std::size_t i = 0u; @@ -100,7 +100,7 @@ constexpr auto coprimes_up_to(std::size_t n, const std::array } template -constexpr std::uintmax_t product(const std::array& values) +[[nodiscard]] consteval std::uintmax_t product(const std::array& values) { std::uintmax_t product = 1; for (const auto& v : values) { @@ -135,7 +135,7 @@ struct wheel_factorizer { static constexpr auto coprimes_in_first_wheel = coprimes_up_to(wheel_size, basis); - static constexpr std::uintmax_t find_first_factor(std::uintmax_t n) + [[nodiscard]] static consteval std::uintmax_t find_first_factor(std::uintmax_t n) { if (const auto k = detail::get_first_of(basis, [&](auto p) { return first_factor_maybe(n, p); })) return *k; @@ -150,7 +150,7 @@ struct wheel_factorizer { return n; } - static constexpr bool is_prime(std::size_t n) { return (n > 1) && find_first_factor(n) == n; } + [[nodiscard]] static consteval bool is_prime(std::size_t n) { return (n > 1) && find_first_factor(n) == n; } }; } // namespace units::detail From a9b482a661894169107e32ee0a7d9f64cef0797d Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 22 Sep 2022 10:26:55 +0200 Subject: [PATCH 017/402] refactor: `magnitude` types are much shorter now `units::magnitude{2l, units::ratio{-42l, 1l}}, units::base_power{3l, units::ratio{1l, 1l}}, units::base_power{5l, units::ratio{-41l, 1l}}, units::base_power{7l, units::ratio{1l, 1l}}, units::base_power{6310543l, units::ratio{1l, 1l}}>{}` is now `units::magnitude{}, 3, units::power_v<5, -41>{}, 7, 6310543>{}` --- src/core/include/units/magnitude.h | 446 +++++++++++++++++------------ 1 file changed, 258 insertions(+), 188 deletions(-) diff --git a/src/core/include/units/magnitude.h b/src/core/include/units/magnitude.h index 5f27f66c..50dfc232 100644 --- a/src/core/include/units/magnitude.h +++ b/src/core/include/units/magnitude.h @@ -32,13 +32,42 @@ #include namespace units { + namespace detail { + // Higher numbers use fewer trial divisions, at the price of more storage space. using factorizer = wheel_factorizer<4>; + } // namespace detail /** - * @brief Any type which can be used as a basis vector in a BasePower. + * @brief A type to represent a standalone constant value. + */ +template +struct constant { + static constexpr auto value = V; +}; + +// is_derived_from_specialization_of_constant +namespace detail { + +template +void to_base_specialization_of_constant(const volatile constant*); + +template +inline constexpr bool is_derived_from_specialization_of_constant = + requires(T * t) { to_base_specialization_of_constant(t); }; + +} // namespace detail + + +template +concept Constant = detail::is_derived_from_specialization_of_constant; + +struct pi_v : constant> {}; + +/** + * @brief Any type which can be used as a basis vector in a PowerV. * * We have two categories. * @@ -52,9 +81,6 @@ using factorizer = wheel_factorizer<4>; * The reason we can't hold the value directly for floating point bases is so that we can support some compilers (e.g., * GCC 10) which don't yet permit floating point NTTPs. */ -template -concept BaseRep = - std::is_same_v || std::is_same_v, long double>; /** * @brief A basis vector in our magnitude representation, raised to some rational power. @@ -80,42 +106,36 @@ concept BaseRep = * _existing_ bases, including both prime numbers and any other irrational bases. For example, even though `sqrt(2)` is * irrational, we must not ever use it as a base; instead, we would use `base_power{2, ratio{1, 2}}`. */ -template -struct base_power { - // The rational power to which the base is raised. - ratio power{1}; +template +concept PowerVBase = Constant || std::integral; - constexpr long double get_base() const { return T::value; } +// TODO Unify with `power` if UTPs (P1985) are accepted by the Committee +template + requires(Num != 0) +struct power_v { + static constexpr auto base = V; + static constexpr ratio exponent{Num, Den...}; + static_assert(exponent != 1); }; -/** - * @brief Specialization for prime number bases. - */ -template<> -struct base_power { - // The value of the basis "vector". Must be prime to be used with `magnitude` (below). - std::intmax_t base; +namespace detail { - // The rational power to which the base is raised. - ratio power{1}; - - constexpr std::intmax_t get_base() const { return base; } -}; /** * @brief Deduction guides for base_power: only permit deducing integral bases. */ -template U> -base_power(T, U) -> base_power; -template -base_power(T) -> base_power; +// template U> +// base_power(T, U) -> base_power; +// template +// base_power(T) -> base_power; -// Implementation for BasePower concept (below). -namespace detail { +// Implementation for PowerV concept (below). template -inline constexpr bool is_base_power = false; -template -inline constexpr bool is_base_power> = true; +inline constexpr bool is_specialization_of_power_v = false; + +template +inline constexpr bool is_specialization_of_power_v> = true; + } // namespace detail /** @@ -125,130 +145,178 @@ inline constexpr bool is_base_power> = true; * `magnitude<...>`. We will defer that second check to the constraints on the `magnitude` template. */ template -concept BasePower = detail::is_base_power; +concept PowerV = detail::is_specialization_of_power_v; namespace detail { -constexpr auto inverse(BasePower auto bp) +template +[[nodiscard]] consteval auto shorten_T() { - bp.power.num *= -1; - return bp; + if constexpr (std::integral) { + if constexpr (V <= std::numeric_limits::max()) { + return static_cast(V); + } else { + return V; + } + } else { + return V; + } } +template +[[nodiscard]] consteval auto power_v_or_T() +{ + constexpr auto shortT = shorten_T(); + + if constexpr (R.den == 1) { + if constexpr (R.num == 1) + return shortT; + else + return power_v{}; + } else { + return power_v{}; + } +}; + +consteval auto inverse(PowerV auto bp) { return power_v_or_T(); } + // `widen_t` gives the widest arithmetic type in the same category, for intermediate computations. -template -using widen_t = - std::conditional_t, - std::conditional_t, long double, - std::conditional_t, std::intmax_t, std::uintmax_t>>, - T>; +// template +// using widen_t = conditional, +// conditional, long double, +// conditional, std::intmax_t, std::uintmax_t>>, +// T>; // Raise an arbitrary arithmetic type to a positive integer power at compile time. -template -constexpr T int_power(T base, std::integral auto exp) -{ - // As this function should only be called at compile time, the exceptions herein function as - // "parameter-compatible static_asserts", and should not result in exceptions at runtime. - if (exp < 0) { - throw std::invalid_argument{"int_power only supports positive integer powers"}; - } +// template +// constexpr T int_power(T base, std::integral auto exp) +// { +// // As this function should only be called at compile time, the exceptions herein function as +// // "parameter-compatible static_asserts", and should not result in exceptions at runtime. +// if (exp < 0) { +// throw std::invalid_argument{"int_power only supports positive integer powers"}; +// } - constexpr auto checked_multiply = [](auto a, auto b) { - const auto result = a * b; - UNITS_DIAGNOSTIC_PUSH - UNITS_DIAGNOSTIC_IGNORE_FLOAT_EQUAL - if (result / a != b) { - throw std::overflow_error{"Wraparound detected"}; - } - UNITS_DIAGNOSTIC_POP - return result; - }; +// constexpr auto checked_multiply = [](auto a, auto b) { +// const auto result = a * b; +// UNITS_DIAGNOSTIC_PUSH +// UNITS_DIAGNOSTIC_IGNORE_FLOAT_EQUAL +// if (result / a != b) { +// throw std::overflow_error{"Wraparound detected"}; +// } +// UNITS_DIAGNOSTIC_POP +// return result; +// }; - constexpr auto checked_square = [checked_multiply](auto a) { return checked_multiply(a, a); }; +// constexpr auto checked_square = [checked_multiply](auto a) { return checked_multiply(a, a); }; - // TODO(chogg): Unify this implementation with the one in pow.h. That one takes its exponent as a - // template parameter, rather than a function parameter. +// // TODO(chogg): Unify this implementation with the one in pow.h. That one takes its exponent as a +// // template parameter, rather than a function parameter. - if (exp == 0) { - return T{1}; - } +// if (exp == 0) { +// return T{1}; +// } - if (exp % 2 == 1) { - return checked_multiply(base, int_power(base, exp - 1)); - } +// if (exp % 2 == 1) { +// return checked_multiply(base, int_power(base, exp - 1)); +// } - return checked_square(int_power(base, exp / 2)); -} +// return checked_square(int_power(base, exp / 2)); +// } -template -constexpr widen_t compute_base_power(BasePower auto bp) -{ - // This utility can only handle integer powers. To compute rational powers at compile time, we'll - // need to write a custom function. - // - // Note that since this function should only be called at compile time, the point of these - // exceptions is to act as "static_assert substitutes", not to throw actual exceptions at runtime. - if (bp.power.den != 1) { - throw std::invalid_argument{"Rational powers not yet supported"}; - } +// template +// constexpr widen_t compute_base_power(PowerV auto bp) +// { +// // This utility can only handle integer powers. To compute rational powers at compile time, we'll +// // need to write a custom function. +// // +// // Note that since this function should only be called at compile time, the point of these +// // exceptions is to act as "static_assert substitutes", not to throw actual exceptions at runtime. +// if (bp.power.den != 1) { +// throw std::invalid_argument{"Rational powers not yet supported"}; +// } - if (bp.power.num < 0) { - if constexpr (std::is_integral_v) { - throw std::invalid_argument{"Cannot represent reciprocal as integer"}; - } else { - return T{1} / compute_base_power(inverse(bp)); - } - } +// if (bp.power.num < 0) { +// if constexpr (std::is_integral_v) { +// throw std::invalid_argument{"Cannot represent reciprocal as integer"}; +// } else { +// return T{1} / compute_base_power(inverse(bp)); +// } +// } - auto power = bp.power.num; - return int_power(static_cast>(bp.get_base()), power); -} +// auto power = bp.power.num; +// return int_power(static_cast>(bp.get_base()), power); +// } // A converter for the value member variable of magnitude (below). // // The input is the desired result, but in a (wider) intermediate type. The point of this function // is to cast to the desired type, but avoid overflow in doing so. -template -// TODO(chogg): Migrate this to use `treat_as_floating_point`. - requires(!std::is_integral_v || std::is_integral_v) -constexpr To checked_static_cast(From x) -{ - // This function should only ever be called at compile time. The purpose of these exceptions is - // to produce compiler errors, because we cannot `static_assert` on function arguments. - if constexpr (std::is_integral_v) { - if (!std::in_range(x)) { - throw std::invalid_argument{"Cannot represent magnitude in this type"}; - } - } +// template +// // TODO(chogg): Migrate this to use `treat_as_floating_point`. +// requires(!std::is_integral_v || std::is_integral_v) +// constexpr To checked_static_cast(From x) +// { +// // This function should only ever be called at compile time. The purpose of these exceptions is +// // to produce compiler errors, because we cannot `static_assert` on function arguments. +// if constexpr (std::is_integral_v) { +// if (!std::in_range(x)) { +// throw std::invalid_argument{"Cannot represent magnitude in this type"}; +// } +// } - return static_cast(x); -} +// return static_cast(x); +// } } // namespace detail /** * @brief Equality detection for two base powers. */ -template -constexpr bool operator==(T t, U u) +template +[[nodiscard]] consteval bool operator==(T, U) { - return std::is_same_v && (t.get_base() == u.get_base()) && (t.power == u.power); + return std::is_same_v; } -/** - * @brief A BasePower, raised to a rational power E. - */ -constexpr auto pow(BasePower auto bp, ratio p) -{ - bp.power = bp.power * p; - return bp; -} +template +concept MagnitudeSpec = std::integral || Constant || PowerV; + // A variety of implementation detail helpers. namespace detail { +template +[[nodiscard]] consteval auto get_base(Element element) +{ + if constexpr (PowerV) + return Element::base; + else + return element; +} + +template +[[nodiscard]] consteval auto get_base_value(Element element) +{ + const auto base = get_base(element); + using base_type = decltype(base); + if constexpr (std::integral) + return base; + else + return base_type::value; +} + +template +[[nodiscard]] consteval ratio get_exponent(Element) +{ + if constexpr (PowerV) + return Element::exponent; + else + return ratio{1}; +} + // The exponent of `factor` in the prime factorization of `n`. -constexpr std::intmax_t multiplicity(std::intmax_t factor, std::intmax_t n) +[[nodiscard]] consteval std::intmax_t multiplicity(std::intmax_t factor, std::intmax_t n) { std::intmax_t m = 0; while (n % factor == 0) { @@ -261,7 +329,7 @@ constexpr std::intmax_t multiplicity(std::intmax_t factor, std::intmax_t n) // Divide a number by a given base raised to some power. // // Undefined unless base > 1, pow >= 0, and (base ^ pow) evenly divides n. -constexpr std::intmax_t remove_power(std::intmax_t base, std::intmax_t pow, std::intmax_t n) +[[nodiscard]] consteval std::intmax_t remove_power(std::intmax_t base, std::intmax_t pow, std::intmax_t n) { while (pow-- > 0) { n /= base; @@ -270,15 +338,18 @@ constexpr std::intmax_t remove_power(std::intmax_t base, std::intmax_t pow, std: } // A way to check whether a number is prime at compile time. -constexpr bool is_prime(std::intmax_t n) { return (n >= 0) && factorizer::is_prime(static_cast(n)); } - -constexpr bool is_valid_base_power(const BasePower auto& bp) +[[nodiscard]] consteval bool is_prime(std::intmax_t n) { - if (bp.power == 0) { + return (n >= 0) && factorizer::is_prime(static_cast(n)); +} + +template +[[nodiscard]] consteval bool is_valid_element(Element element) +{ + if (get_exponent(element) == 0) { return false; } - - if constexpr (std::is_same_v) { + if constexpr (std::integral) { // Some prime numbers are so big, that we can't check their primality without exhausting limits on constexpr steps // and/or iterations. We can still _perform_ the factorization for these by using the `known_first_factor` // workaround. However, we can't _check_ that they are prime, because this workaround depends on the input being @@ -289,13 +360,13 @@ constexpr bool is_valid_base_power(const BasePower auto& bp) // // In our case: we simply give up on excluding every possible ill-formed base power, and settle for catching the // most likely and common mistakes. - if (const bool too_big_to_check = (bp.get_base() > 1'000'000'000)) { + if (const bool too_big_to_check = (get_base_value(element) > 1'000'000'000)) { return true; } - return is_prime(bp.get_base()); + return is_prime(get_base_value(element)); } else { - return bp.get_base() > 0; + return get_base_value(element) > 0; } } @@ -305,7 +376,7 @@ struct pairwise_all { Predicate predicate; template - constexpr bool operator()(Ts&&... ts) const + [[nodiscard]] consteval bool operator()(Ts&&... ts) const { // Carefully handle different sizes, avoiding unsigned integer underflow. constexpr auto num_comparisons = [](auto num_elements) { @@ -322,52 +393,58 @@ struct pairwise_all { }; // Deduction guide: permit constructions such as `pairwise_all{std::less{}}`. -template -pairwise_all(T) -> pairwise_all; +// template +// pairwise_all(T) -> pairwise_all; // Check whether a sequence of (possibly heterogeneously typed) values are strictly increasing. template requires(std::is_signed_v && ...) -constexpr bool strictly_increasing(Ts&&... ts) +[[nodiscard]] consteval bool strictly_increasing(Ts&&... ts) { return pairwise_all{std::less{}}(std::forward(ts)...); } -template -inline constexpr bool all_base_powers_valid = (is_valid_base_power(BPs) && ...); +template +inline constexpr bool all_elements_valid = (is_valid_element(Elements) && ...); -template -inline constexpr bool all_bases_in_order = strictly_increasing(BPs.get_base()...); +template +inline constexpr bool all_elements_in_order = strictly_increasing(get_base_value(Elements)...); -template -inline constexpr bool is_base_power_pack_valid = all_base_powers_valid && all_bases_in_order; +template +inline constexpr bool is_element_pack_valid = all_elements_valid && all_elements_in_order; -constexpr bool is_rational(BasePower auto bp) +[[nodiscard]] consteval bool is_rational(MagnitudeSpec auto element) { - return std::is_integral_v && (bp.power.den == 1); + return std::is_integral_v && (get_exponent(element).den == 1); +} + +[[nodiscard]] consteval bool is_integral(MagnitudeSpec auto element) +{ + return is_rational(element) && get_exponent(element).num > 0; } -constexpr bool is_integral(BasePower auto bp) { return is_rational(bp) && bp.power.num > 0; } } // namespace detail + /** * @brief A representation for positive real numbers which optimizes taking products and rational powers. * * Magnitudes can be treated as values. Each type encodes exactly one value. Users can multiply, divide, raise to * rational powers, and compare for equality. */ -template - requires detail::is_base_power_pack_valid +template + requires detail::is_element_pack_valid struct magnitude { // Whether this magnitude represents an integer. - friend constexpr bool is_integral(const magnitude&) { return (detail::is_integral(BPs) && ...); } + [[nodiscard]] friend consteval bool is_integral(const magnitude&) { return (detail::is_integral(Ms) && ...); } // Whether this magnitude represents a rational number. - friend constexpr bool is_rational(const magnitude&) { return (detail::is_rational(BPs) && ...); } + [[nodiscard]] friend consteval bool is_rational(const magnitude&) { return (detail::is_rational(Ms) && ...); } }; -// Implementation for Magnitude concept (below). namespace detail { + +// Implementation for Magnitude concept (below). template inline constexpr bool is_magnitude = false; template @@ -383,28 +460,21 @@ concept Magnitude = detail::is_magnitude; /** * @brief The value of a Magnitude in a desired type T. */ -template -// TODO(chogg): Migrate this to use `treat_as_floating_point`. - requires(!std::is_integral_v || is_integral(magnitude{})) -constexpr T get_value(const magnitude&) -{ - // Force the expression to be evaluated in a constexpr context, to catch, e.g., overflow. - constexpr auto result = detail::checked_static_cast((detail::compute_base_power(BPs) * ... * T{1})); +// template +// // TODO(chogg): Migrate this to use `treat_as_floating_point`. +// requires(!std::integral || is_integral(magnitude{})) +// constexpr T get_value(const magnitude&) +// { +// // Force the expression to be evaluated in a constexpr context, to catch, e.g., overflow. +// constexpr auto result = detail::checked_static_cast((detail::compute_base_power(BPs) * ... * T{1})); - return result; -} - -/** - * @brief A base to represent pi. - */ -struct pi_base { - static constexpr long double value = std::numbers::pi_v; -}; +// return result; +// } /** * @brief A convenient Magnitude constant for pi, which we can manipulate like a regular number. */ -inline constexpr Magnitude auto mag_pi = magnitude{}>{}; +inline constexpr Magnitude auto mag_pi = magnitude{}; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Magnitude equality implementation. @@ -422,24 +492,24 @@ constexpr bool operator==(magnitude, magnitude) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Magnitude rational powers implementation. -template -constexpr auto pow(magnitude) +template +constexpr auto pow(magnitude) { if constexpr (E.num == 0) { return magnitude<>{}; } else { - return magnitude{}; + return magnitude()...>{}; } } -template -constexpr auto sqrt(magnitude m) +template +constexpr auto sqrt(magnitude m) { return pow(m); } -template -constexpr auto cbrt(magnitude m) +template +constexpr auto cbrt(magnitude m) { return pow(m); } @@ -456,8 +526,10 @@ constexpr Magnitude auto operator*(Magnitude auto m, magnitude<>) { return m; } template constexpr Magnitude auto operator*(magnitude, magnitude) { + using namespace detail; + // Case for when H1 has the smaller base. - if constexpr (H1.get_base() < H2.get_base()) { + if constexpr (get_base_value(H1) < get_base_value(H2)) { if constexpr (sizeof...(T1) == 0) { // Shortcut for the "pure prepend" case, which makes it easier to implement some of the other cases. return magnitude{}; @@ -467,21 +539,18 @@ constexpr Magnitude auto operator*(magnitude, magnitude) } // Case for when H2 has the smaller base. - if constexpr (H1.get_base() > H2.get_base()) { + if constexpr (get_base_value(H1) > get_base_value(H2)) { return magnitude

{} * (magnitude{} * magnitude{}); } // "Same leading base" case. - if constexpr (H1.get_base() == H2.get_base()) { + if constexpr (get_base(H1) == get_base(H2)) { constexpr auto partial_product = magnitude{} * magnitude{}; - // Make a new base_power with the common base of H1 and H2, whose power is their powers' sum. - constexpr auto new_head = [&](auto head) { - head.power = H1.power + H2.power; - return head; - }(H1); + // Make a new power_v with the common base of H1 and H2, whose power is their powers' sum. + constexpr auto new_head = power_v_or_T(); - if constexpr (new_head.power == 0) { + if constexpr (get_exponent(new_head) == 0) { return partial_product; } else { return magnitude{} * partial_product; @@ -507,7 +576,7 @@ constexpr auto integer_part(magnitude) constexpr auto power_den = BP.power.den; if constexpr (std::is_integral_v && (power_num >= power_den)) { - constexpr auto largest_integer_power = [=](BasePower auto bp) { + constexpr auto largest_integer_power = [=](PowerV auto bp) { bp.power = (power_num / power_den); // Note: integer division intended. return bp; }(BP); // Note: lambda is immediately invoked. @@ -529,14 +598,14 @@ constexpr auto numerator(magnitude) constexpr auto denominator(Magnitude auto m) { return numerator(pow<-1>(m)); } // Implementation of conversion to ratio goes here, because it needs `numerator()` and `denominator()`. -constexpr ratio as_ratio(Magnitude auto m) - requires(is_rational(decltype(m){})) -{ - return ratio{ - get_value(numerator(m)), - get_value(denominator(m)), - }; -} +// constexpr ratio as_ratio(Magnitude auto m) +// requires(is_rational(decltype(m){})) +// { +// return ratio{ +// get_value(numerator(m)), +// get_value(denominator(m)), +// }; +// } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -616,6 +685,7 @@ template inline constexpr std::optional known_first_factor = std::nullopt; namespace detail { + // Helper to perform prime factorization at compile time. template requires(N > 0) @@ -634,7 +704,7 @@ struct prime_factorization { static constexpr std::intmax_t remainder = remove_power(first_base, first_power, N); static constexpr auto value = - magnitude{} * prime_factorization::value; + magnitude()>{} * prime_factorization::value; }; // Specialization for the prime factorization of 1 (base case). @@ -666,7 +736,7 @@ template inline constexpr Magnitude auto mag_power = pow(mag); namespace detail { -template +template constexpr ratio get_power(T base, magnitude) { return ((BPs.get_base() == base ? BPs.power : ratio{0}) + ... + ratio{0}); From 4411b8ea6dd2bce87e2bb9e2cbc748b48d89d989 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Wed, 28 Sep 2022 12:49:28 +0200 Subject: [PATCH 018/402] test: `dimension` unit tests added --- test/unit_test/static/dimension_test.cpp | 136 +++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 test/unit_test/static/dimension_test.cpp diff --git a/test/unit_test/static/dimension_test.cpp b/test/unit_test/static/dimension_test.cpp new file mode 100644 index 00000000..c2d3a62d --- /dev/null +++ b/test/unit_test/static/dimension_test.cpp @@ -0,0 +1,136 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// 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. + +#include + +using namespace units; + +namespace { + +template +inline constexpr bool is_of_type = std::is_same_v, T>; + +using one_dim_ = struct one_dim; + +// clang-format off +inline constexpr struct length_dim_ : base_dimension<"L"> {} length_dim; +inline constexpr struct time_dim_ : base_dimension<"T"> {} time_dim; + +inline constexpr struct frequency_dim_ : decltype(1 / time_dim) {} frequency_dim; +inline constexpr struct area_dim_ : decltype(length_dim * length_dim) {} area_dim; +inline constexpr struct volume_dim_ : decltype(area_dim * length_dim) {} volume_dim; +inline constexpr struct speed_dim_ : decltype(length_dim / time_dim) {} speed_dim; +inline constexpr struct acceleration_dim_ : decltype(speed_dim / time_dim) {} acceleration_dim; +// clang-format on + +} // namespace + +// concepts verification +static_assert(BaseDimension); +static_assert(!BaseDimension); +static_assert(!DerivedDimension); +static_assert(DerivedDimension); +static_assert(Dimension); +static_assert(Dimension); + +static_assert(DerivedDimension); +static_assert(DerivedDimension); // one_dim +static_assert(BaseDimension); // length_dim + +// derived dimension expression template syntax verification +static_assert(is_of_type<1 / time_dim, derived_dimension>>); +static_assert(is_of_type<1 / (1 / time_dim), time_dim_>); + +static_assert(is_of_type); +static_assert(is_of_type); +static_assert(is_of_type>>); +static_assert(is_of_type<1 / time_dim * one_dim, derived_dimension>>); + +static_assert(is_of_type>); +static_assert(is_of_type>>); + +static_assert( + is_of_type, time_dim_>>); +static_assert( + is_of_type, time_dim_>>); + +static_assert( + is_of_type, time_dim_>>); +static_assert( + is_of_type, time_dim_>>); + +static_assert(is_of_type<1 / time_dim * length_dim, derived_dimension>>); +static_assert(is_of_type<1 / time_dim * time_dim, one_dim_>); + +static_assert(is_of_type); +static_assert(is_of_type<1 / time_dim / one_dim, derived_dimension>>); + +static_assert(is_of_type); +static_assert(is_of_type<1 / time_dim * (1 / time_dim), derived_dimension>>>); +static_assert(is_of_type<1 / (time_dim * time_dim), derived_dimension>>>); +static_assert(is_of_type<1 / (1 / (time_dim * time_dim)), derived_dimension>>); + +static_assert( + is_of_type>>>); +static_assert(is_of_type, per>>>); +static_assert(is_of_type); + +static_assert(is_of_type); +static_assert(is_of_type>>); +static_assert( + is_of_type>>>); +static_assert(is_of_type<1 / (speed_dim * speed_dim) * length_dim, + derived_dimension, per>>); + +// comparisons of equivalent dimensions +static_assert(length_dim / length_dim == one_dim); + +static_assert(1 / time_dim == frequency_dim); +static_assert(1 / frequency_dim == time_dim); +static_assert(frequency_dim * time_dim == one_dim); + +static_assert(length_dim * length_dim == area_dim); +static_assert(length_dim * length_dim != volume_dim); +static_assert(area_dim / length_dim == length_dim); + +static_assert(length_dim * length_dim * length_dim == volume_dim); +static_assert(area_dim * length_dim == volume_dim); +static_assert(volume_dim / length_dim == area_dim); +static_assert(volume_dim / length_dim / length_dim == length_dim); +static_assert(area_dim * area_dim / length_dim == volume_dim); +static_assert(area_dim * (area_dim / length_dim) == volume_dim); +static_assert(volume_dim / (length_dim * length_dim) == length_dim); + +static_assert(length_dim / time_dim == speed_dim); +static_assert(length_dim * time_dim != speed_dim); +static_assert(length_dim / time_dim / time_dim != speed_dim); +static_assert(length_dim / speed_dim == time_dim); +static_assert(speed_dim * time_dim == length_dim); + +static_assert(length_dim / time_dim / time_dim == acceleration_dim); +static_assert(length_dim / (time_dim * time_dim) == acceleration_dim); +static_assert(speed_dim / time_dim == acceleration_dim); +static_assert(speed_dim / acceleration_dim == time_dim); +static_assert(acceleration_dim * time_dim == speed_dim); +static_assert(acceleration_dim * (time_dim * time_dim) == length_dim); +static_assert(acceleration_dim / speed_dim == frequency_dim); From 4a49bdda053ade87b72c6efca0824a1579dd3ee1 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 6 Oct 2022 23:43:01 +0100 Subject: [PATCH 019/402] refactor: V2 design update --- CMakeLists.txt | 2 +- docs/design/quantity.rst | 5 + docs/framework/dimensions.rst | 65 ++ docs/framework/units.rst | 15 + example/CMakeLists.txt | 2 +- example/v2_framework.cpp | 502 ++++---------- src/CMakeLists.txt | 14 +- src/core/CMakeLists.txt | 26 +- src/core/include/units/bits/common_type.h | 117 ++-- .../include/units/bits/expression_template.h | 42 +- .../include/units/bits/external/type_name.h | 2 +- .../include/units/bits/external/type_traits.h | 3 + src/core/include/units/bits/unit_text.h | 2 +- src/core/include/units/concepts.h | 92 ++- src/core/include/units/dimension.h | 41 +- src/core/include/units/magnitude.h | 369 +++++----- src/core/include/units/quantity.h | 121 ++-- src/core/include/units/reference.h | 91 ++- src/core/include/units/unit.h | 186 +++-- src/systems/CMakeLists.txt | 38 +- src/systems/isq/CMakeLists.txt | 51 +- ...gular_acceleration.h => base_dimensions.h} | 22 +- .../isq/include/units/isq/dimensions.h | 74 -- .../units/isq/dimensions/absorbed_dose.h | 40 -- .../units/isq/dimensions/acceleration.h | 40 -- .../isq/dimensions/amount_of_substance.h | 35 - .../units/isq/dimensions/angular_velocity.h | 40 -- .../units/isq/dimensions/capacitance.h | 40 -- .../units/isq/dimensions/catalytic_activity.h | 40 -- .../units/isq/dimensions/charge_density.h | 49 -- .../units/isq/dimensions/concentration.h | 40 -- .../units/isq/dimensions/current_density.h | 40 -- .../include/units/isq/dimensions/density.h | 40 -- .../units/isq/dimensions/dynamic_viscosity.h | 40 -- .../units/isq/dimensions/electric_charge.h | 40 -- .../units/isq/dimensions/electric_current.h | 35 - .../isq/dimensions/electric_field_strength.h | 40 -- .../isq/include/units/isq/dimensions/energy.h | 43 -- .../units/isq/dimensions/energy_density.h | 40 -- .../isq/include/units/isq/dimensions/force.h | 40 -- .../include/units/isq/dimensions/frequency.h | 39 -- .../units/isq/dimensions/heat_capacity.h | 60 -- .../include/units/isq/dimensions/inductance.h | 40 -- .../isq/include/units/isq/dimensions/length.h | 35 - .../include/units/isq/dimensions/luminance.h | 40 -- .../units/isq/dimensions/luminous_flux.h | 40 -- .../units/isq/dimensions/magnetic_flux.h | 40 -- .../units/isq/dimensions/magnetic_induction.h | 42 -- .../isq/include/units/isq/dimensions/mass.h | 35 - .../units/isq/dimensions/molar_energy.h | 40 -- .../include/units/isq/dimensions/momentum.h | 40 -- .../units/isq/dimensions/permeability.h | 40 -- .../units/isq/dimensions/permittivity.h | 40 -- .../isq/include/units/isq/dimensions/power.h | 43 -- .../include/units/isq/dimensions/pressure.h | 40 -- .../units/isq/dimensions/radioactivity.h | 39 -- .../include/units/isq/dimensions/resistance.h | 40 -- .../isq/include/units/isq/dimensions/speed.h | 40 -- .../units/isq/dimensions/surface_tension.h | 40 -- .../isq/dimensions/thermal_conductivity.h | 43 -- .../dimensions/thermodynamic_temperature.h | 35 - .../isq/include/units/isq/dimensions/torque.h | 40 -- .../include/units/isq/dimensions/voltage.h | 40 -- .../isq/include/units/isq/dimensions/volume.h | 39 -- .../units/isq/{dimensions/time.h => isq.h} | 15 +- src/systems/isq/include/units/isq/mechanics.h | 72 ++ .../isq/include/units/isq/space_and_time.h | 68 ++ .../conductance.h => thermodynamics.h} | 19 +- src/systems/si-cgs/CMakeLists.txt | 16 +- .../include/units/isq/si/cgs/acceleration.h | 86 --- .../si-cgs/include/units/isq/si/cgs/area.h | 88 --- .../si-cgs/include/units/isq/si/cgs/cgs.h | 36 - .../si-cgs/include/units/isq/si/cgs/energy.h | 88 --- .../si-cgs/include/units/isq/si/cgs/force.h | 89 --- .../si-cgs/include/units/isq/si/cgs/length.h | 87 --- .../si-cgs/include/units/isq/si/cgs/mass.h | 87 --- .../si-cgs/include/units/isq/si/cgs/power.h | 71 -- .../include/units/isq/si/cgs/pressure.h | 89 --- .../si-cgs/include/units/isq/si/cgs/speed.h | 70 -- src/systems/si-cgs/include/units/si/cgs/cgs.h | 57 ++ src/systems/si/CMakeLists.txt | 58 +- .../si/include/units/isq/si/absorbed_dose.h | 328 --------- .../si/include/units/isq/si/acceleration.h | 69 -- .../units/isq/si/amount_of_substance.h | 87 --- .../units/isq/si/angular_acceleration.h | 76 -- .../include/units/isq/si/angular_velocity.h | 73 -- src/systems/si/include/units/isq/si/area.h | 382 ----------- .../si/include/units/isq/si/capacitance.h | 329 --------- .../include/units/isq/si/catalytic_activity.h | 343 --------- .../si/include/units/isq/si/charge_density.h | 93 --- .../si/include/units/isq/si/concentration.h | 71 -- .../si/include/units/isq/si/conductance.h | 280 -------- .../si/include/units/isq/si/constants.h | 61 -- .../si/include/units/isq/si/current_density.h | 73 -- src/systems/si/include/units/isq/si/density.h | 72 -- .../include/units/isq/si/dynamic_viscosity.h | 71 -- .../si/include/units/isq/si/electric_charge.h | 88 --- .../include/units/isq/si/electric_current.h | 327 --------- .../units/isq/si/electric_field_strength.h | 70 -- src/systems/si/include/units/isq/si/energy.h | 310 --------- .../si/include/units/isq/si/energy_density.h | 70 -- src/systems/si/include/units/isq/si/force.h | 329 --------- .../si/include/units/isq/si/frequency.h | 279 -------- .../si/include/units/isq/si/heat_capacity.h | 114 --- .../si/include/units/isq/si/inductance.h | 281 -------- src/systems/si/include/units/isq/si/length.h | 340 --------- .../si/include/units/isq/si/luminance.h | 70 -- .../si/include/units/isq/si/luminous_flux.h | 90 --- .../include/units/isq/si/luminous_intensity.h | 327 --------- .../si/include/units/isq/si/magnetic_flux.h | 281 -------- .../include/units/isq/si/magnetic_induction.h | 297 -------- src/systems/si/include/units/isq/si/mass.h | 595 ---------------- .../si/include/units/isq/si/molar_energy.h | 73 -- .../si/include/units/isq/si/momentum.h | 70 -- .../si/include/units/isq/si/permeability.h | 71 -- .../si/include/units/isq/si/permittivity.h | 71 -- src/systems/si/include/units/isq/si/power.h | 280 -------- .../si/include/units/isq/si/prefixes.h | 70 -- .../si/include/units/isq/si/pressure.h | 329 --------- .../si/include/units/isq/si/radioactivity.h | 327 --------- .../si/include/units/isq/si/resistance.h | 281 -------- src/systems/si/include/units/isq/si/si.h | 78 --- src/systems/si/include/units/isq/si/speed.h | 82 --- .../si/include/units/isq/si/surface_tension.h | 70 -- .../units/isq/si/thermal_conductivity.h | 76 -- .../units/isq/si/thermodynamic_temperature.h | 87 --- src/systems/si/include/units/isq/si/time.h | 219 ------ src/systems/si/include/units/isq/si/torque.h | 72 -- src/systems/si/include/units/isq/si/voltage.h | 329 --------- src/systems/si/include/units/isq/si/volume.h | 582 ---------------- .../include/units/si/base_quantities.h} | 63 +- src/systems/si/include/units/si/constants.h | 80 +++ src/systems/si/include/units/si/mechanics.h | 68 ++ src/systems/si/include/units/si/prefixes.h | 111 +++ .../include/units/si/si.h} | 19 +- .../si/include/units/si/space_and_time.h | 64 ++ .../include/units/si/thermodynamics.h} | 22 +- .../si/include/units/si/unit_symbols.h | 637 +++++++++++++++++ src/systems/si/include/units/si/units.h | 88 +++ test/CMakeLists.txt | 5 +- test/unit_test/runtime/CMakeLists.txt | 4 +- test/unit_test/runtime/magnitude_test.cpp | 622 ----------------- test/unit_test/static/CMakeLists.txt | 78 ++- test/unit_test/static/dimension_test.cpp | 39 +- test/unit_test/static/magnitude_test.cpp | 648 ++++++++++++++++++ test/unit_test/static/unit_test.cpp | 77 +++ 146 files changed, 3076 insertions(+), 13622 deletions(-) rename src/systems/isq/include/units/isq/{dimensions/angular_acceleration.h => base_dimensions.h} (61%) delete mode 100644 src/systems/isq/include/units/isq/dimensions.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/absorbed_dose.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/acceleration.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/amount_of_substance.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/angular_velocity.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/capacitance.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/catalytic_activity.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/charge_density.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/concentration.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/current_density.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/density.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/dynamic_viscosity.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/electric_charge.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/electric_current.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/electric_field_strength.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/energy.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/energy_density.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/force.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/frequency.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/heat_capacity.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/inductance.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/length.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/luminance.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/luminous_flux.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/magnetic_flux.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/magnetic_induction.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/mass.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/molar_energy.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/momentum.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/permeability.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/permittivity.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/power.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/pressure.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/radioactivity.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/resistance.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/speed.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/surface_tension.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/thermal_conductivity.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/thermodynamic_temperature.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/torque.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/voltage.h delete mode 100644 src/systems/isq/include/units/isq/dimensions/volume.h rename src/systems/isq/include/units/isq/{dimensions/time.h => isq.h} (84%) create mode 100644 src/systems/isq/include/units/isq/mechanics.h create mode 100644 src/systems/isq/include/units/isq/space_and_time.h rename src/systems/isq/include/units/isq/{dimensions/conductance.h => thermodynamics.h} (71%) delete mode 100644 src/systems/si-cgs/include/units/isq/si/cgs/acceleration.h delete mode 100644 src/systems/si-cgs/include/units/isq/si/cgs/area.h delete mode 100644 src/systems/si-cgs/include/units/isq/si/cgs/cgs.h delete mode 100644 src/systems/si-cgs/include/units/isq/si/cgs/energy.h delete mode 100644 src/systems/si-cgs/include/units/isq/si/cgs/force.h delete mode 100644 src/systems/si-cgs/include/units/isq/si/cgs/length.h delete mode 100644 src/systems/si-cgs/include/units/isq/si/cgs/mass.h delete mode 100644 src/systems/si-cgs/include/units/isq/si/cgs/power.h delete mode 100644 src/systems/si-cgs/include/units/isq/si/cgs/pressure.h delete mode 100644 src/systems/si-cgs/include/units/isq/si/cgs/speed.h create mode 100644 src/systems/si-cgs/include/units/si/cgs/cgs.h delete mode 100644 src/systems/si/include/units/isq/si/absorbed_dose.h delete mode 100644 src/systems/si/include/units/isq/si/acceleration.h delete mode 100644 src/systems/si/include/units/isq/si/amount_of_substance.h delete mode 100644 src/systems/si/include/units/isq/si/angular_acceleration.h delete mode 100644 src/systems/si/include/units/isq/si/angular_velocity.h delete mode 100644 src/systems/si/include/units/isq/si/area.h delete mode 100644 src/systems/si/include/units/isq/si/capacitance.h delete mode 100644 src/systems/si/include/units/isq/si/catalytic_activity.h delete mode 100644 src/systems/si/include/units/isq/si/charge_density.h delete mode 100644 src/systems/si/include/units/isq/si/concentration.h delete mode 100644 src/systems/si/include/units/isq/si/conductance.h delete mode 100644 src/systems/si/include/units/isq/si/constants.h delete mode 100644 src/systems/si/include/units/isq/si/current_density.h delete mode 100644 src/systems/si/include/units/isq/si/density.h delete mode 100644 src/systems/si/include/units/isq/si/dynamic_viscosity.h delete mode 100644 src/systems/si/include/units/isq/si/electric_charge.h delete mode 100644 src/systems/si/include/units/isq/si/electric_current.h delete mode 100644 src/systems/si/include/units/isq/si/electric_field_strength.h delete mode 100644 src/systems/si/include/units/isq/si/energy.h delete mode 100644 src/systems/si/include/units/isq/si/energy_density.h delete mode 100644 src/systems/si/include/units/isq/si/force.h delete mode 100644 src/systems/si/include/units/isq/si/frequency.h delete mode 100644 src/systems/si/include/units/isq/si/heat_capacity.h delete mode 100644 src/systems/si/include/units/isq/si/inductance.h delete mode 100644 src/systems/si/include/units/isq/si/length.h delete mode 100644 src/systems/si/include/units/isq/si/luminance.h delete mode 100644 src/systems/si/include/units/isq/si/luminous_flux.h delete mode 100644 src/systems/si/include/units/isq/si/luminous_intensity.h delete mode 100644 src/systems/si/include/units/isq/si/magnetic_flux.h delete mode 100644 src/systems/si/include/units/isq/si/magnetic_induction.h delete mode 100644 src/systems/si/include/units/isq/si/mass.h delete mode 100644 src/systems/si/include/units/isq/si/molar_energy.h delete mode 100644 src/systems/si/include/units/isq/si/momentum.h delete mode 100644 src/systems/si/include/units/isq/si/permeability.h delete mode 100644 src/systems/si/include/units/isq/si/permittivity.h delete mode 100644 src/systems/si/include/units/isq/si/power.h delete mode 100644 src/systems/si/include/units/isq/si/prefixes.h delete mode 100644 src/systems/si/include/units/isq/si/pressure.h delete mode 100644 src/systems/si/include/units/isq/si/radioactivity.h delete mode 100644 src/systems/si/include/units/isq/si/resistance.h delete mode 100644 src/systems/si/include/units/isq/si/si.h delete mode 100644 src/systems/si/include/units/isq/si/speed.h delete mode 100644 src/systems/si/include/units/isq/si/surface_tension.h delete mode 100644 src/systems/si/include/units/isq/si/thermal_conductivity.h delete mode 100644 src/systems/si/include/units/isq/si/thermodynamic_temperature.h delete mode 100644 src/systems/si/include/units/isq/si/time.h delete mode 100644 src/systems/si/include/units/isq/si/torque.h delete mode 100644 src/systems/si/include/units/isq/si/voltage.h delete mode 100644 src/systems/si/include/units/isq/si/volume.h rename src/systems/{si-cgs/include/units/isq/si/cgs/time.h => si/include/units/si/base_quantities.h} (56%) create mode 100644 src/systems/si/include/units/si/constants.h create mode 100644 src/systems/si/include/units/si/mechanics.h create mode 100644 src/systems/si/include/units/si/prefixes.h rename src/systems/{isq/include/units/isq/dimensions/luminous_intensity.h => si/include/units/si/si.h} (81%) create mode 100644 src/systems/si/include/units/si/space_and_time.h rename src/systems/{isq/include/units/isq/dimensions/area.h => si/include/units/si/thermodynamics.h} (71%) create mode 100644 src/systems/si/include/units/si/unit_symbols.h create mode 100644 src/systems/si/include/units/si/units.h delete mode 100644 test/unit_test/runtime/magnitude_test.cpp create mode 100644 test/unit_test/static/magnitude_test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 29e11b68..37125b1b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,7 +73,7 @@ add_subdirectory(example) # add unit tests enable_testing() -# add_subdirectory(test) +add_subdirectory(test) # tests for standalone headers include(TestPublicHeaders) diff --git a/docs/design/quantity.rst b/docs/design/quantity.rst index 8c6b6fd5..47f65096 100644 --- a/docs/design/quantity.rst +++ b/docs/design/quantity.rst @@ -6,6 +6,11 @@ quantity Interface --------- + The value of a quantity is generally expressed as the product of a number and a unit. The + unit is simply a particular example of the quantity concerned which is used as a reference, + and the number is the ratio of the value of the quantity to the unit. + + `quantity` class template provides a similar interface to `std::chrono::duration `_. The difference is that it uses ``double`` as a default representation and has diff --git a/docs/framework/dimensions.rst b/docs/framework/dimensions.rst index 524d1b8b..fbcc02a0 100644 --- a/docs/framework/dimensions.rst +++ b/docs/framework/dimensions.rst @@ -125,3 +125,68 @@ In order to obtain the base/coherent unit of any dimension type a static_assert(is_same_v, si::metre>); static_assert(is_same_v, si::metre_per_second>); + + + + +How do you feel about: + +inline constexpr second second; +? + +We could do the same to dimensions to not have to type dim_length{} all the time. + +6 replies 2 new +@JohelEGP +JohelEGP +2 days ago +mp_units::units::second is a variable. The reference isq::si::second could stay a type and s continue to be a variable. + +@mpusz +mpusz +2 days ago +Maintainer +Author +The problem is the following: + +Variables are really needed for a new design. We can ask users to put {} after every dimension unit, and reference types but it would be really nasty and a lot of boilerplate. +Short names have to be opt-in as they collide with a lot of code (especially on MSVC). +@JohelEGP +JohelEGP +yesterday +As pointed out by #389 (reply in thread), I think it'd be OK suffix _t to the types. + +@mpusz +mpusz +10 hours ago +Maintainer +Author +It will be visible in the compilation errors, which is inconvenient :-( + +Instead of: + +quantity>, derived_unit>> +we will have something like: + +quantity>, derived_unit>> +Personally, I like the first output more. + +Note that definition like: + +inline constexpr second second; +besides, being really unconventional, is allowed by the language and will not impact our users at all. A user is about to always work with values in the code and observe types in the compilation errors. Using the same nicely blends those two domains together. + +@mpusz +mpusz +10 hours ago +Maintainer +Author +I could use a list of values instead of types as template parameters in the dervied_dimension and derived_unit but in such case the error would look like: + +quantity{}>{}, derived_unit{}>{}>> +which also is not that nice. + +@JohelEGP +JohelEGP +6 hours ago +That's convincing. This justification should definitely be part of the documentation. diff --git a/docs/framework/units.rst b/docs/framework/units.rst index c3ad6b96..d0541ccf 100644 --- a/docs/framework/units.rst +++ b/docs/framework/units.rst @@ -417,3 +417,18 @@ class template:: To learn more about unknown units please refer to the :ref:`use_cases/unknown_dimensions:Working with Unknown Dimensions and Their Units` chapter. + + +## System reference + +"It is important to emphasize that each physical quantity has only one coherent SI unit, even +though this unit can be expressed in different forms by using some of the special names and +symbols." +The converse, however, is not true, because in general several different quantities may +share the same SI unit. + + +For example, for the quantity heat capacity as well as for the +quantity entropy the SI unit is joule per kelvin. Similarly, for the base quantity electric +current as well as the derived quantity magnetomotive force the SI unit is the ampere. It is +therefore important not to use the unit alone to specify the quantity. diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 686b57ac..c04c32c0 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -33,7 +33,7 @@ function(add_example target) target_link_libraries(${target} PRIVATE ${ARGN}) endfunction() -add_example(v2_framework mp-units::core-fmt mp-units::core-io mp-units::si) +add_example(v2_framework mp-units::core mp-units::si) # add_example(conversion_factor mp-units::core-fmt mp-units::core-io mp-units::si) # add_example(custom_systems mp-units::core-io mp-units::si) diff --git a/example/v2_framework.cpp b/example/v2_framework.cpp index 6b9803ac..952f02bc 100644 --- a/example/v2_framework.cpp +++ b/example/v2_framework.cpp @@ -20,366 +20,135 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -// #include -#include +#include -namespace units::isq { - -inline constexpr struct length_dim : base_dimension<"L"> { -} length_dim; -inline constexpr struct mass_dim : base_dimension<"M"> { -} mass_dim; -inline constexpr struct time_dim : base_dimension<"T"> { -} time_dim; -inline constexpr struct electric_current_dim : base_dimension<"I"> { -} electric_current_dim; -// TODO Should the below use basic_symbol_text? How to name it for ASCII? -inline constexpr struct thermodynamic_temperature_dim : base_dimension<"Θ"> { -} thermodynamic_temperature_dim; -inline constexpr struct amount_of_substance_dim : base_dimension<"N"> { -} amount_of_substance_dim; -inline constexpr struct luminous_intensity_dim : base_dimension<"J"> { -} luminous_intensity_dim; - -inline constexpr struct frequency_dim : decltype(1 / time_dim) { -} frequency_dim; -inline constexpr struct area_dim : decltype(length_dim * length_dim) { -} area_dim; -inline constexpr struct volume_dim : decltype(area_dim * length_dim) { -} volume_dim; -inline constexpr struct speed_dim : decltype(length_dim / time_dim) { -} speed_dim; -inline constexpr struct acceleration_dim : decltype(speed_dim / time_dim) { -} acceleration_dim; - -// inline constexpr auto speed = length / time; - -// using speed_dim = decltype(length_dim / time_dim); -// inline constexpr speed_dim speed_dim; - -// template -// concept Length = QuantityOf; - -} // namespace units::isq - -#include -#include - -namespace units { - -namespace isq::si { - -// length units -inline constexpr struct metre : named_unit<"m"> { -} metre; -inline constexpr struct kilometre : kilo { -} kilometre; - -inline constexpr struct astronomical_unit : named_scaled_unit<"au", mag<149'597'870'700>(), metre> { -} astronomical_unit; - -// area units -inline constexpr struct square_metre : derived_unit { -} square_metre; - -// volume units -inline constexpr struct cubic_metre : derived_unit { -} cubic_metre; - -// time units -inline constexpr struct second : named_unit<"s"> { -} second; -inline constexpr struct minute : named_scaled_unit<"min", mag<60>(), second> { -} minute; -inline constexpr struct hour : named_scaled_unit<"h", mag<60>(), minute> { -} hour; -inline constexpr struct day : named_scaled_unit<"d", mag<24>(), hour> { -} day; - -// not time units! -// TODO should those be provided for other scaled units like ms, h, ... -inline constexpr struct second_squared : derived_unit { -} second_squared; -inline constexpr struct second_cubed : derived_unit { -} second_cubed; - -// mass units -inline constexpr struct gram : named_unit<"g"> { -} gram; -inline constexpr struct kilogram : kilo { -} kilogram; -inline constexpr struct tonne : named_scaled_unit<"t", mag<1000>(), gram> { -} tonne; - -// other units -inline constexpr struct hertz : named_unit<"Hz", 1 / second> { -} hertz; -inline constexpr struct newton : named_unit<"N", kilogram * metre / second_squared> { -} newton; -inline constexpr struct pascal : named_unit<"Pa", kilogram / (metre * second_squared)> { -} pascal; -inline constexpr struct joule : named_unit<"J", newton * metre> { -} joule; -inline constexpr struct watt : named_unit<"W", joule / second> { -} watt; - -namespace unit_symbols { - -inline namespace length_units { - -inline constexpr auto m = metre; -inline constexpr auto km = kilometre; -inline constexpr auto au = astronomical_unit; - -} // namespace length_units - -inline namespace area_units { - -inline constexpr auto m2 = square_metre; +template +constexpr bool is_of_type(Expr) +{ + return std::is_same_v; } -inline namespace volume_units { +namespace { -inline constexpr auto m3 = cubic_metre; +using namespace units; +using namespace units::si::unit_symbols; -} - -inline namespace time_units { - -inline constexpr auto s = second; -inline constexpr auto min = minute; -inline constexpr auto h = hour; -inline constexpr auto d = day; - -inline constexpr auto s2 = second_squared; - -} // namespace time_units - -inline namespace mass_units { - -inline constexpr auto g = gram; -inline constexpr auto kg = kilogram; -inline constexpr auto t = tonne; - -} // namespace mass_units - -inline namespace frequency_units { - -inline constexpr auto Hz = hertz; - -} - -inline namespace force_units { - -inline constexpr auto N = newton; - -} - -inline namespace pressure_units { - -inline constexpr auto Pa = pascal; - -} - -inline namespace energy_units { - -inline constexpr auto J = joule; - -} - -inline namespace power_units { - -inline constexpr auto W = watt; - -} - -} // namespace unit_symbols - -} // namespace isq::si -} // namespace units - -#include - -namespace units { - -inline constexpr struct dimensionless : system_reference { -} dimensionless; - -} // namespace units - -namespace units::isq::si { - -inline constexpr struct length : system_reference { -} length; -inline constexpr struct time : system_reference { -} time; -inline constexpr struct frequency : system_reference { -} frequency; -inline constexpr struct area : system_reference { -} area; -inline constexpr struct volume : system_reference { -} volume; -inline constexpr struct speed : system_reference { -} speed; -inline constexpr struct acceleration : system_reference { -} acceleration; - -} // namespace units::isq::si - - -template -inline constexpr bool is_of_type = std::is_same_v, T>; - -namespace units::isq { - -// derived dimension expression template syntax verification -static_assert(is_of_type<1 / time_dim, derived_dimension>>); -static_assert(is_of_type<1 / (1 / time_dim), struct time_dim>); - -static_assert(is_of_type); -static_assert(is_of_type); -static_assert(is_of_type>>); -static_assert(is_of_type<1 / time_dim * one_dim, derived_dimension>>); - -static_assert(is_of_type>); -static_assert(is_of_type>>); +constexpr auto power = 5 * si::power[W]; +static_assert(is_of_type{}, int>>(power)); +constexpr auto speed = 5 * si::speed[m / s]; static_assert( - is_of_type, struct time_dim>>); -static_assert( - is_of_type, struct time_dim>>); + is_of_type>>{}, int>>( + speed)); -static_assert( - is_of_type, struct time_dim>>); -static_assert( - is_of_type, struct time_dim>>); +constexpr auto q = 10 * si::length[m] / (2 * si::time[s]); +static_assert(is_of_type>, + derived_unit>>{}, + int>>(q)); -static_assert(is_of_type<1 / time_dim * length_dim, derived_dimension>>); -static_assert(is_of_type<1 / time_dim * time_dim, struct one_dim>); +constexpr auto distance = 5 * si::speed[m / s] * (5 * si::time[s]); -static_assert(is_of_type); -static_assert(is_of_type<1 / time_dim / one_dim, derived_dimension>>); +static_assert(is_of_type{}, int>>(distance)); -static_assert(is_of_type); -static_assert( - is_of_type<1 / time_dim * (1 / time_dim), derived_dimension>>>); -static_assert(is_of_type<1 / (time_dim * time_dim), derived_dimension>>>); -static_assert(is_of_type<1 / (1 / (time_dim * time_dim)), derived_dimension>>); +constexpr auto dimensionless = 20 * si::speed[m / s] / (10 * si::length[m]) * (5 * si::time[s]); -static_assert(is_of_type>>>); -static_assert(is_of_type, per>>>); -static_assert(is_of_type); - -static_assert(is_of_type); -static_assert(is_of_type>>); -static_assert( - is_of_type>>>); -static_assert(is_of_type<1 / (speed_dim * speed_dim) * length_dim, - derived_dimension, per>>); - -namespace si { - -// comparisons of equivalent dimensions -static_assert(length_dim / length_dim == one_dim); - -static_assert(1 / time_dim == frequency_dim); -static_assert(1 / frequency_dim == time_dim); -static_assert(frequency_dim * time_dim == one_dim); - -static_assert(length_dim * length_dim == area_dim); -static_assert(length_dim * length_dim != volume_dim); -static_assert(area_dim / length_dim == length_dim); - -static_assert(length_dim * length_dim * length_dim == volume_dim); -static_assert(area_dim * length_dim == volume_dim); -static_assert(volume_dim / length_dim == area_dim); -static_assert(volume_dim / length_dim / length_dim == length_dim); -static_assert(area_dim * area_dim / length_dim == volume_dim); -static_assert(area_dim * (area_dim / length_dim) == volume_dim); -static_assert(volume_dim / (length_dim * length_dim) == length_dim); - -static_assert(length_dim / time_dim == speed_dim); -static_assert(length_dim * time_dim != speed_dim); -static_assert(length_dim / time_dim / time_dim != speed_dim); -static_assert(length_dim / speed_dim == time_dim); -static_assert(speed_dim * time_dim == length_dim); - -static_assert(length_dim / time_dim / time_dim == acceleration_dim); -static_assert(length_dim / (time_dim * time_dim) == acceleration_dim); -static_assert(speed_dim / time_dim == acceleration_dim); -static_assert(speed_dim / acceleration_dim == time_dim); -static_assert(acceleration_dim * time_dim == speed_dim); -static_assert(acceleration_dim * (time_dim * time_dim) == length_dim); -static_assert(acceleration_dim / speed_dim == frequency_dim); - -} // namespace si - -} // namespace units::isq +static_assert(is_of_type{}, int>>(dimensionless)); -namespace units::isq::si { +// constexpr auto q1 = 10 * si::length[m] / (2 * si::time[s]) + 5 * si::speed[m / s]; +// static_assert(is_of_type>, +// derived_unit>>{}, +// int>>(q1)); + +// static_assert(quantity_of); +// static_assert(quantity_of); +// static_assert(!quantity_of); + + +// quantity>>, int> s = 5 * speed[m / s]; +// quantity>, derived_unit>>, int> q = +// 10 * length[m] / (2 * si::time[s]); + +// auto q1 = 10 * length[m] / (2 * si::time[s]) + 5 * speed[m / s]; // should this be allowed? +// bool b1 = (10 * length[m] / (2 * si::time[s]) == 5 * speed[m / s]); // should this be allowed? + +// auto q2 = 10 / (2 * si::time[s]) + 5 * frequency[Hz]; // should this be allowed? +// bool b2 = (10 / (2 * si::time[s]) == 5 * frequency[Hz]); // should this be allowed? + +// auto q3 = 5 * activity[Bq] + 5 * frequency[Hz]; // should this be allowed? +// auto b3 = (5 * activity[Bq] == 5 * frequency[Hz]); // should this be allowed? + +// auto q4 = 5 * activity[Bq] + 10 / (2 * si::time[s]) + 5 * frequency[Hz]; // should this be allowed? + +// auto q5 = 120 * length[km] / (2 * si::time[h]); // not speed +// auto q6 = quantity_cast(120 * length[km] / (2 * si::time[h])); +// auto q7 = quantity_cast(120 * length[km] / (2 * si::time[h])); +// quantity s = q5; // should this implicit conversion be allowed? + +} // namespace + +namespace units::si { // derived unit expression template syntax verification -static_assert(is_of_type<1 / second, derived_unit>>); -static_assert(is_of_type<1 / (1 / second), struct second>); +static_assert(is_of_type>>(1 / second)); +static_assert(is_of_type(1 / (1 / second))); -static_assert(is_of_type); -static_assert(is_of_type); -static_assert(is_of_type>>); -static_assert(is_of_type<1 / second * one, derived_unit>>); +static_assert(is_of_type(one * second)); +static_assert(is_of_type(second * one)); +static_assert(is_of_type>>(one * (1 / second))); +static_assert(is_of_type>>(1 / second * one)); -static_assert(is_of_type>); -static_assert(is_of_type>>); +static_assert(is_of_type>(metre * second)); +static_assert(is_of_type>>(metre * metre)); -static_assert(is_of_type, struct second>>); -static_assert(is_of_type, struct second>>); +static_assert(is_of_type, struct second>>(metre * metre * second)); +static_assert(is_of_type, struct second>>(metre * second * metre)); -static_assert(is_of_type, struct second>>); -static_assert(is_of_type, struct second>>); +static_assert(is_of_type, struct second>>(metre * (second * metre))); +static_assert(is_of_type, struct second>>(second * (metre * metre))); -static_assert(is_of_type<1 / second * metre, derived_unit>>); -static_assert(is_of_type<1 / second * second, struct one>); +static_assert(is_of_type>>(1 / second * metre)); +static_assert(is_of_type(1 / second * second)); -static_assert(is_of_type); -static_assert(is_of_type<1 / second / one, derived_unit>>); +static_assert(is_of_type(second / one)); +static_assert(is_of_type>>(1 / second / one)); -static_assert(is_of_type); -static_assert(is_of_type<1 / second * (1 / second), derived_unit>>>); -static_assert(is_of_type<1 / (second * second), derived_unit>>>); -static_assert(is_of_type<1 / (1 / (second * second)), derived_unit>>); +static_assert(is_of_type(metre / second * second)); +static_assert(is_of_type>>>(1 / second * (1 / second))); +static_assert(is_of_type>>>(1 / (second * second))); +static_assert(is_of_type>>(1 / (1 / (second * second)))); -static_assert(is_of_type>>>); -static_assert( - is_of_type, per>>>); -static_assert(is_of_type); +static_assert(is_of_type>>>(metre / second * + (1 / second))); +static_assert(is_of_type, per>>>( + metre / second * (metre / second))); +static_assert(is_of_type(metre / second * (second / metre))); -static_assert(is_of_type>>); -static_assert(is_of_type>>); +static_assert(is_of_type>>(watt / joule)); +static_assert(is_of_type>>(joule / watt)); // comparisons of equivalent units static_assert(metre / metre == one); -static_assert(metre * metre == square_metre); -static_assert(second * second == second_squared); -static_assert(second * second * second == second_cubed); -static_assert(second * (second * second) == second_cubed); -static_assert(second_squared * second == second_cubed); -static_assert(second * second_squared == second_cubed); +// static_assert(metre * metre == square_metre); +// static_assert(second * second == second_squared); +// static_assert(second * second * second == second_cubed); +// static_assert(second * (second * second) == second_cubed); +// static_assert(second_squared * second == second_cubed); +// static_assert(second * second_squared == second_cubed); -static_assert(1 / second * metre == metre / second); -static_assert(metre * (1 / second) == metre / second); -static_assert((metre / second) * (1 / second) == metre / second / second); -static_assert((metre / second) * (1 / second) == metre / (second * second)); -static_assert((metre / second) * (1 / second) == metre / second_squared); +// static_assert(1 / second * metre == metre / second); +// static_assert(metre * (1 / second) == metre / second); +// static_assert((metre / second) * (1 / second) == metre / second / second); +// static_assert((metre / second) * (1 / second) == metre / (second * second)); +// static_assert((metre / second) * (1 / second) == metre / second_squared); -static_assert(hertz == 1 / second); -static_assert(newton == kilogram * metre / second_squared); -static_assert(joule == kilogram * square_metre / second_squared); -static_assert(joule == newton * metre); -static_assert(watt == joule / second); -static_assert(watt == kilogram * square_metre / second_cubed); +// static_assert(hertz == 1 / second); +// static_assert(newton == kilogram * metre / second_squared); +// static_assert(joule == kilogram * square_metre / second_squared); +// static_assert(joule == newton * metre); +// static_assert(watt == joule / second); +// static_assert(watt == kilogram * square_metre / second_cubed); // static_assert(1 / frequency_dim == second); // static_assert(frequency_dim * second == one); @@ -416,18 +185,21 @@ static_assert(watt == kilogram * square_metre / second_cubed); // Bq + Hz + 1/s should compile? -} // namespace units::isq::si +} // namespace units::si +namespace units { template inline constexpr bool is_exactly_quantity_of = is_same_v && is_same_v; +} + namespace units::isq::si { // quantity tests -static_assert( - is_exactly_quantity_of>>); +// static_assert( +// is_exactly_quantity_of>>); // static_assert(QuantityOf>); // static_assert(QuantityOf>); @@ -435,37 +207,57 @@ static_assert( } // namespace units::isq::si +// using namespace units; +// using namespace units::si; +// using namespace units::si::unit_symbols; -using namespace units; -using namespace units::isq::si; -using namespace units::isq::si::unit_symbols; +// /* Frequency */ auto freq1 = 20 * frequency[Hz]; +// // /* Frequency */ auto freq2 = 20 / (1 * si::time[s]); +// quantity freq3(20); +// quantity freq4(20); +// quantity freq5(20); -/* Frequency */ auto freq1 = 20 * frequency[Hz]; -// /* Frequency */ auto freq2 = 20 / (1 * isq::si::time[s]); -quantity freq3(20); -quantity freq4(20); -quantity freq5(20); - -/* Speed */ auto speed1 = 20 * speed[m / s]; -/* Speed */ auto speed2 = 20 * (length[m] / isq::si::time[s]); -quantity speed3(20); -quantity speed4(20); +// /* Speed */ auto speed1 = 20 * speed[m / s]; +// /* Speed */ auto speed2 = 20 * (length[m] / si::time[s]); +// quantity speed3(20); +// quantity speed4(20); template void print(); -// constexpr auto avg_speed(quantity d, quantity t) { return d / t; } +// constexpr auto avg_speed(quantity d, quantity t) { return d / t; } int main() { - print(); - // print(); - print(); - print(); - print(); + // print(); + // print(); + // // print(); + // print(); + // print(); + // print(); - print(); - print(); - print(); - print(); + // print(); + // print(); + // print(); + // print(); } + + +// 1 * joule + 1 * erg ??? + +// joule * erg??? +// joule / erg??? + +// auto d1 = 42 * isq::length_dim[si::kilo]; +// auto d2 = 42 * isq::length_dim[cgs::centimetre]; + +// auto s1 = 42 * isq::speed_dim[si::metre / si::second]; +// auto s2 = 42 * isq::speed_dim[cgs::centimetre / si::second]; +// auto e1 = 42 * isq::energy_dim[si::joule]; +// auto e2 = 42 * isq::energy_dim[cgs::erg]; +// auto e2_bad = 42 * isq::energy_dim[cgs::erg / si::second]; +// auto p1 = 42 * isq::power_dim[si::watt]; +// auto p2 = 42 * isq::power_dim[cgs::erg / si::second]; + +// type of Rep{1} * (mag * mag_power<10, -34> * energy[joule] * time[second]) +// and inline constexpr auto planck_constant = Rep{1} * mag_planck * energy[joule] * time[second]; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 32a5e555..ba908f6f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -38,13 +38,21 @@ if(${projectPrefix}AS_SYSTEM_HEADERS) endif() add_subdirectory(core) -add_subdirectory(core-fmt) -add_subdirectory(core-io) + +# add_subdirectory(core-fmt) +# add_subdirectory(core-io) add_subdirectory(systems) # project-wide wrapper add_library(mp-units INTERFACE) -target_link_libraries(mp-units INTERFACE mp-units::core mp-units::core-io mp-units::core-fmt mp-units::systems) +target_link_libraries( + mp-units + INTERFACE + mp-units::core + # mp-units::core-io + # mp-units::core-fmt + mp-units::systems +) add_library(mp-units::mp-units ALIAS mp-units) install(TARGETS mp-units EXPORT mp-unitsTargets) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index e39c7bd9..f9a1e98b 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -37,26 +37,26 @@ check_libcxx_in_use(${projectPrefix}LIBCXX) add_library( mp-units-core INTERFACE - include/units/chrono.h + # include/units/chrono.h include/units/concepts.h include/units/customization_points.h include/units/dimension.h - include/units/generic/angle.h - include/units/generic/dimensionless.h - include/units/generic/solid_angle.h - include/units/kind.h + # include/units/generic/angle.h + # include/units/generic/dimensionless.h + # include/units/generic/solid_angle.h + # include/units/kind.h include/units/magnitude.h - include/units/math.h - include/units/point_origin.h + # include/units/math.h + # include/units/point_origin.h include/units/quantity.h - include/units/quantity_cast.h - include/units/quantity_kind.h - include/units/quantity_point.h - include/units/quantity_point_kind.h - include/units/random.h + # include/units/quantity_cast.h + # include/units/quantity_kind.h + # include/units/quantity_point.h + # include/units/quantity_point_kind.h + # include/units/random.h include/units/ratio.h include/units/reference.h - include/units/symbol_text.h + # include/units/symbol_text.h include/units/unit.h ) target_compile_features(mp-units-core INTERFACE cxx_std_20) diff --git a/src/core/include/units/bits/common_type.h b/src/core/include/units/bits/common_type.h index 8955d5ab..05288572 100644 --- a/src/core/include/units/bits/common_type.h +++ b/src/core/include/units/bits/common_type.h @@ -22,58 +22,56 @@ #pragma once -#include -#include -#include +#include +#include +#include +// #include +// #include namespace units { -template U> -struct reference; +// template U, Representation Rep> +// class quantity_point; -template U, Representation Rep> -class quantity; +// template U, Representation Rep> +// class quantity_kind; -template U, Representation Rep> -class quantity_point; +// template U, Representation Rep> +// class quantity_point_kind; -template U, Representation Rep> -class quantity_kind; +// TODO common_unit should use common_magnitude(U1::mag, U2::mag) -template U, Representation Rep> -class quantity_point_kind; +template + requires(equivalent(D1{}, D2{})) +using common_dimension = conditional, D1, detail::dim_type>; + +template +// requires(equivalent) +using common_unit = U1; namespace detail { template struct common_quantity_reference_impl; -template -struct common_quantity_reference_impl, reference> { - using type = reference; +template +struct common_quantity_reference_impl { + using type = R; }; template struct common_quantity_reference_impl, reference> { - using type = reference>; + using type = reference>; }; -template - requires(same_unit_reference, dimension_unit>::value) -struct common_quantity_reference_impl, reference> { - using type = reference>; +template + requires(equivalent(R1::dimension, R2::dimension)) +struct common_quantity_reference_impl { + using type = reference, + common_unit>; }; -template -struct common_quantity_reference_impl, reference> { - static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag = common_magnitude(reference::mag, - reference::mag); - using dimension = conditional, D2, D1>; - using unit = downcast_unit; - using type = reference; -}; - -template Q2> +template Q2> using common_quantity_reference = TYPENAME detail::common_quantity_reference_impl, std::remove_const_t>::type; @@ -83,43 +81,42 @@ using common_quantity_reference = namespace std { -template Q2> +template Q2> requires requires { typename common_type_t; } struct common_type { private: using ref = units::detail::common_quantity_reference; public: - using type = - units::quantity>; + using type = units::quantity>; }; -template QP2> - requires requires { typename common_type_t; } -struct common_type { - using type = - units::quantity_point::dimension>, - typename common_type_t::unit, - typename common_type_t::rep>; -}; +// template QP2> +// requires requires { typename common_type_t; } +// struct common_type { +// using type = +// units::quantity_point::dimension>, +// typename common_type_t::unit, +// typename common_type_t::rep>; +// }; -template QK2> - requires requires { typename common_type_t; } -struct common_type { - using type = - units::quantity_kind::unit, - typename common_type_t::rep>; -}; +// template QK2> +// requires requires { typename common_type_t; } +// struct common_type { +// using type = +// units::quantity_kind::unit, +// typename common_type_t::rep>; +// }; -template QPK2> - requires requires { typename common_type_t; } -struct common_type { - using type = units::quantity_point_kind< - typename QPK1::point_kind_type, - typename common_type_t::unit, - typename common_type_t::rep>; -}; +// template QPK2> +// requires requires { typename common_type_t; } +// struct common_type { +// using type = units::quantity_point_kind< +// typename QPK1::point_kind_type, +// typename common_type_t::unit, +// typename common_type_t::rep>; +// }; } // namespace std diff --git a/src/core/include/units/bits/expression_template.h b/src/core/include/units/bits/expression_template.h index 089cf147..e702b0bc 100644 --- a/src/core/include/units/bits/expression_template.h +++ b/src/core/include/units/bits/expression_template.h @@ -34,7 +34,39 @@ struct type_list {}; template struct per {}; +namespace detail { + +template +inline constexpr bool valid_ratio = true; + +template +inline constexpr bool valid_ratio<0, Den...> = false; + +template +inline constexpr bool valid_ratio = false; + +template<> +inline constexpr bool valid_ratio<0, 0> = false; + +template +inline constexpr bool positive_ratio = (Num > 0); + +template +inline constexpr bool positive_ratio = (Num * Den > 0); + +template +inline constexpr bool ratio_one = false; + +template<> +inline constexpr bool ratio_one<1> = true; + +template +inline constexpr bool ratio_one = true; + +} // namespace detail + template + requires(detail::valid_ratio && detail::positive_ratio && !detail::ratio_one) struct power { using factor = F; static constexpr ratio exponent{Num, Den...}; @@ -146,9 +178,9 @@ using expr_consolidate = typename expr_consolidate_impl::type; // expr_simplify -template +template struct expr_simplify_power { - static constexpr ratio r = powerNum::exponent - powerDen::exponent; + static constexpr ratio r = Num - Den; using type = power_or_T; using num = conditional<(r > 0), type_list, type_list<>>; using den = conditional<(r < 0), type_list, type_list<>>; @@ -179,7 +211,7 @@ struct expr_simplify, type_list, Pred> : template typename Pred> struct expr_simplify, NRest...>, type_list, Pred> { using impl = expr_simplify, type_list, Pred>; - using type = expr_simplify_power, power>; + using type = expr_simplify_power::exponent, ratio{1}>; using num = type_list_join; using den = type_list_join; }; @@ -187,7 +219,7 @@ struct expr_simplify, NRest...>, type_list typename Pred> struct expr_simplify, type_list, DRest...>, Pred> { using impl = expr_simplify, type_list, Pred>; - using type = expr_simplify_power, power>; + using type = expr_simplify_power::exponent>; using num = type_list_join; using den = type_list_join; }; @@ -197,7 +229,7 @@ template, power>) struct expr_simplify, NRest...>, type_list, DRest...>, Pred> { using impl = expr_simplify, type_list, Pred>; - using type = expr_simplify_power, power>; + using type = expr_simplify_power::exponent, power::exponent>; using num = type_list_join; using den = type_list_join; }; diff --git a/src/core/include/units/bits/external/type_name.h b/src/core/include/units/bits/external/type_name.h index e65ec9d1..9a74759f 100644 --- a/src/core/include/units/bits/external/type_name.h +++ b/src/core/include/units/bits/external/type_name.h @@ -5,7 +5,7 @@ #include template -constexpr auto type_name() +[[nodiscard]] consteval std::string_view type_name() { std::string_view name, prefix, suffix; #ifdef __clang__ diff --git a/src/core/include/units/bits/external/type_traits.h b/src/core/include/units/bits/external/type_traits.h index 286a713e..6d9df5df 100644 --- a/src/core/include/units/bits/external/type_traits.h +++ b/src/core/include/units/bits/external/type_traits.h @@ -77,4 +77,7 @@ template typename Type> // inline constexpr bool // TODO: Replace with concept when it works with MSVC concept is_derived_from_specialization_of = requires(T* t) { detail::to_base_specialization_of(t); }; +template +concept one_of = (... || std::same_as); + } // namespace units diff --git a/src/core/include/units/bits/unit_text.h b/src/core/include/units/bits/unit_text.h index db0cf31a..9421e5ef 100644 --- a/src/core/include/units/bits/unit_text.h +++ b/src/core/include/units/bits/unit_text.h @@ -37,7 +37,7 @@ constexpr auto magnitude_text() { constexpr auto exp10 = extract_power_of_10(M); - constexpr Magnitude auto base = M / pow(mag<10>()); + constexpr Magnitude auto base = M / mag_power<10, exp10>; constexpr Magnitude auto num = numerator(base); constexpr Magnitude auto den = denominator(base); static_assert(base == num / den, "Printing rational powers, or irrational bases, not yet supported"); diff --git a/src/core/include/units/concepts.h b/src/core/include/units/concepts.h index edf5e4b0..c506c2ac 100644 --- a/src/core/include/units/concepts.h +++ b/src/core/include/units/concepts.h @@ -23,6 +23,94 @@ #pragma once // IWYU pragma: begin_exports -#include -#include +// #include +// #include // IWYU pragma: end_exports +#include +#include +#include + +namespace units { + +template +struct reference; + +/** + * @brief A concept matching all references in the library. + * + * Satisfied by all specializations of @c reference. + */ +template +concept Reference = is_specialization_of; + +namespace detail { + +template +inline constexpr bool is_quantity = false; + +} + +template +concept Quantity = detail::is_quantity; + +template +concept common_type_with_ = // exposition only + (std::same_as, std::common_type_t>) && + (std::constructible_from, T>) && (std::constructible_from, U>); + +template +concept scalable_number_ = // exposition only + (std::regular_invocable, T, U>) && (std::regular_invocable, T, U>); + +template +concept castable_number_ = // exposition only + common_type_with_ && scalable_number_>; + +template +concept scalable_ = // exposition only + castable_number_ || (requires { typename T::value_type; } && castable_number_ && + scalable_number_>); + +template +concept scalable_with_ = // exposition only + common_type_with_ && scalable_>; + +template +concept Representation = (!Quantity) && + // (!QuantityLike) && (!wrapped_quantity_) && + std::regular && scalable_; + +template +class quantity; + +namespace detail { + +template +inline constexpr bool is_quantity> = true; + +// template +// requires units::is_derived_from_specialization_of +// inline constexpr bool is_quantity = true; + +} // namespace detail + +/** + * @brief A concept matching all quantities with provided dimension + * + * Satisfied by all quantities with a dimension being the instantiation derived from + * the provided dimension type. + */ +template +concept quantity_of = Quantity && ((Dimension> && Q::dimension == V) || + (Reference> && Q::dimension == V.dimension)); + +/** + * @brief A concept matching two equivalent quantities + * + * Satisfied by quantities having equivalent dimensions and units. + */ +template +concept quantity_equivalent_to = Quantity && equivalent(Q1::dimension, Q2::dimension) && + equivalent(Q1::unit, Q2::unit); + +} // namespace units diff --git a/src/core/include/units/dimension.h b/src/core/include/units/dimension.h index 407088f1..fd3740a5 100644 --- a/src/core/include/units/dimension.h +++ b/src/core/include/units/dimension.h @@ -52,6 +52,12 @@ namespace detail { template void to_base_base_dimension(const volatile base_dimension*); +template +inline constexpr bool is_specialization_of_base_dimension = false; + +template +inline constexpr bool is_specialization_of_base_dimension> = true; + } // namespace detail /** @@ -60,13 +66,18 @@ void to_base_base_dimension(const volatile base_dimension*); * Satisfied by all dimension types derived from an specialization of `base_dimension`. */ template -concept BaseDimension = requires(T* t) { detail::to_base_base_dimension(t); }; +concept BaseDimension = requires(T* t) { detail::to_base_base_dimension(t); } && + (!detail::is_specialization_of_base_dimension); template struct base_dimension_less : std::bool_constant<(D1::symbol < D2::symbol)> {}; -// TODO Can we provide a smarter implementation? -std::false_type is_derived_dimension(...); +namespace detail { + +template +inline constexpr bool is_derived_dimension = false; + +} /** * @brief A concept matching all derived dimensions in the library. @@ -74,7 +85,7 @@ std::false_type is_derived_dimension(...); * Satisfied by all dimension types derived from an specialization of `derived_dimension`. */ template -concept DerivedDimension = decltype(is_derived_dimension(std::declval()))::value; +concept DerivedDimension = detail::is_derived_dimension; /** * @brief A concept matching all dimensions in the library. @@ -107,8 +118,20 @@ struct derived_dimension : detail::expr_fractions, Ds...> { using type = derived_dimension; }; -template -std::true_type is_derived_dimension(const volatile derived_dimension*); +namespace detail { + +template +void to_base_specialization_of_derived_dimension(const volatile derived_dimension*); + +template +inline constexpr bool is_derived_from_specialization_of_derived_dimension = + requires(T * t) { to_base_specialization_of_derived_dimension(t); }; + +template + requires is_derived_from_specialization_of_derived_dimension +inline constexpr bool is_derived_dimension = true; + +} // namespace detail /** * @brief Dimension one @@ -162,6 +185,12 @@ template template [[nodiscard]] consteval bool operator==(D1, D2) +{ + return is_same_v; +} + +template +[[nodiscard]] consteval bool equivalent(D1, D2) { return is_same_v, detail::dim_type>; } diff --git a/src/core/include/units/magnitude.h b/src/core/include/units/magnitude.h index 50dfc232..f81da0c5 100644 --- a/src/core/include/units/magnitude.h +++ b/src/core/include/units/magnitude.h @@ -22,7 +22,10 @@ #pragma once +#include #include +#include +#include #include #include #include @@ -40,31 +43,47 @@ using factorizer = wheel_factorizer<4>; } // namespace detail -/** - * @brief A type to represent a standalone constant value. - */ -template -struct constant { - static constexpr auto value = V; -}; - -// is_derived_from_specialization_of_constant namespace detail { -template -void to_base_specialization_of_constant(const volatile constant*); +template +inline constexpr bool is_magnitude = false; template -inline constexpr bool is_derived_from_specialization_of_constant = - requires(T * t) { to_base_specialization_of_constant(t); }; +inline constexpr bool is_specialization_of_magnitude = false; } // namespace detail - +/** + * @brief Concept to detect whether T is a valid Magnitude. + */ template -concept Constant = detail::is_derived_from_specialization_of_constant; +concept Magnitude = detail::is_magnitude; -struct pi_v : constant> {}; +/** + * @brief A type to represent a standalone constant value. + */ +// template +// struct constant { +// static constexpr auto value = V; +// }; + +// // is_derived_from_specialization_of_constant +// namespace detail { + +// template +// void to_base_specialization_of_constant(const volatile constant*); + +// template +// inline constexpr bool is_derived_from_specialization_of_constant = +// requires(T * t) { to_base_specialization_of_constant(t); }; + +// } // namespace detail + + +// template +// concept Constant = detail::is_derived_from_specialization_of_constant; + +// struct pi_v : constant> {}; /** * @brief Any type which can be used as a basis vector in a PowerV. @@ -106,20 +125,26 @@ struct pi_v : constant> {}; * _existing_ bases, including both prime numbers and any other irrational bases. For example, even though `sqrt(2)` is * irrational, we must not ever use it as a base; instead, we would use `base_power{2, ratio{1, 2}}`. */ -template -concept PowerVBase = Constant || std::integral; - -// TODO Unify with `power` if UTPs (P1985) are accepted by the Committee -template - requires(Num != 0) -struct power_v { - static constexpr auto base = V; - static constexpr ratio exponent{Num, Den...}; - static_assert(exponent != 1); -}; namespace detail { +template +inline constexpr bool is_named_magnitude = Magnitude && !detail::is_specialization_of_magnitude; + +} + +template +concept PowerVBase = one_of || detail::is_named_magnitude; + +// TODO Unify with `power` if UTPs (P1985) are accepted by the Committee +template + requires(detail::valid_ratio && !detail::ratio_one) +struct power_v { + static constexpr auto base = V; + static constexpr ratio exponent{Num, Den...}; +}; + +namespace detail { /** * @brief Deduction guides for base_power: only permit deducing integral bases. @@ -149,6 +174,8 @@ concept PowerV = detail::is_specialization_of_power_v; namespace detail { +// We do not want magnitude type to have the `l` literal after a value for a small integral number. +// For example this modifies `magnitude<3l>` to be `magnitude<3>` template [[nodiscard]] consteval auto shorten_T() { @@ -156,8 +183,10 @@ template if constexpr (V <= std::numeric_limits::max()) { return static_cast(V); } else { - return V; + return static_cast(V); } + } else if constexpr (std::floating_point) { + return static_cast(V); } else { return V; } @@ -178,7 +207,7 @@ template } }; -consteval auto inverse(PowerV auto bp) { return power_v_or_T(); } +// consteval auto inverse(PowerV auto bp) { return power_v_or_T(); } // `widen_t` gives the widest arithmetic type in the same category, for intermediate computations. // template @@ -253,35 +282,35 @@ consteval auto inverse(PowerV auto bp) { return power_v_or_T -// // TODO(chogg): Migrate this to use `treat_as_floating_point`. -// requires(!std::is_integral_v || std::is_integral_v) -// constexpr To checked_static_cast(From x) -// { -// // This function should only ever be called at compile time. The purpose of these exceptions is -// // to produce compiler errors, because we cannot `static_assert` on function arguments. -// if constexpr (std::is_integral_v) { -// if (!std::in_range(x)) { -// throw std::invalid_argument{"Cannot represent magnitude in this type"}; -// } -// } +template +// TODO(chogg): Migrate this to use `treat_as_floating_point`. + requires(!std::is_integral_v || std::is_integral_v) +constexpr To checked_static_cast(From x) +{ + // This function should only ever be called at compile time. The purpose of these exceptions is + // to produce compiler errors, because we cannot `static_assert` on function arguments. + if constexpr (std::is_integral_v) { + if (!std::in_range(x)) { + throw std::invalid_argument{"Cannot represent magnitude in this type"}; + } + } + + return static_cast(x); +} -// return static_cast(x); -// } } // namespace detail /** * @brief Equality detection for two base powers. */ -template -[[nodiscard]] consteval bool operator==(T, U) -{ - return std::is_same_v; -} +// template +// [[nodiscard]] consteval bool operator==(T, U) +// { +// return std::is_same_v; +// } template -concept MagnitudeSpec = std::integral || Constant || PowerV; - +concept MagnitudeSpec = PowerVBase || PowerV; // A variety of implementation detail helpers. namespace detail { @@ -295,17 +324,6 @@ template return element; } -template -[[nodiscard]] consteval auto get_base_value(Element element) -{ - const auto base = get_base(element); - using base_type = decltype(base); - if constexpr (std::integral) - return base; - else - return base_type::value; -} - template [[nodiscard]] consteval ratio get_exponent(Element) { @@ -338,88 +356,92 @@ template } // A way to check whether a number is prime at compile time. -[[nodiscard]] consteval bool is_prime(std::intmax_t n) -{ - return (n >= 0) && factorizer::is_prime(static_cast(n)); -} +// [[nodiscard]] consteval bool is_prime(std::intmax_t n) +// { +// return (n >= 0) && factorizer::is_prime(static_cast(n)); +// } -template -[[nodiscard]] consteval bool is_valid_element(Element element) -{ - if (get_exponent(element) == 0) { - return false; - } - if constexpr (std::integral) { - // Some prime numbers are so big, that we can't check their primality without exhausting limits on constexpr steps - // and/or iterations. We can still _perform_ the factorization for these by using the `known_first_factor` - // workaround. However, we can't _check_ that they are prime, because this workaround depends on the input being - // usable in a constexpr expression. This is true for `prime_factorization` (below), where the input `N` is a - // template parameter, but is not true for our case, where the input `bp.get_base()` is a function parameter. (See - // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1045r1.html for some background reading on this - // distinction.) - // - // In our case: we simply give up on excluding every possible ill-formed base power, and settle for catching the - // most likely and common mistakes. - if (const bool too_big_to_check = (get_base_value(element) > 1'000'000'000)) { - return true; - } +// template +// [[nodiscard]] consteval bool is_valid_element(Element element) +// { +// if (get_exponent(element) == 0) { +// return false; +// } +// if constexpr (std::integral) { +// // Some prime numbers are so big, that we can't check their primality without exhausting limits on constexpr +// steps +// // and/or iterations. We can still _perform_ the factorization for these by using the `known_first_factor` +// // workaround. However, we can't _check_ that they are prime, because this workaround depends on the input being +// // usable in a constexpr expression. This is true for `prime_factorization` (below), where the input `N` is a +// // template parameter, but is not true for our case, where the input `bp.get_base()` is a function parameter. +// (See +// // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1045r1.html for some background reading on this +// // distinction.) +// // +// // In our case: we simply give up on excluding every possible ill-formed base power, and settle for catching the +// // most likely and common mistakes. +// if (const bool too_big_to_check = (get_base_value(element) > 1'000'000'000)) { +// return true; +// } - return is_prime(get_base_value(element)); - } else { - return get_base_value(element) > 0; - } -} +// return is_prime(get_base_value(element)); +// } else { +// return get_base_value(element) > 0; +// } +// } // A function object to apply a predicate to all consecutive pairs of values in a sequence. -template -struct pairwise_all { - Predicate predicate; +// template +// struct pairwise_all { +// Predicate predicate; - template - [[nodiscard]] consteval bool operator()(Ts&&... ts) const - { - // Carefully handle different sizes, avoiding unsigned integer underflow. - constexpr auto num_comparisons = [](auto num_elements) { - return (num_elements > 1) ? (num_elements - 1) : 0; - }(sizeof...(Ts)); +// template +// [[nodiscard]] consteval bool operator()(Ts&&... ts) const +// { +// // Carefully handle different sizes, avoiding unsigned integer underflow. +// constexpr auto num_comparisons = [](auto num_elements) { +// return (num_elements > 1) ? (num_elements - 1) : 0; +// }(sizeof...(Ts)); - // Compare zero or more pairs of neighbours as needed. - return [this](std::tuple && t, std::index_sequence) - { - return (predicate(std::get(t), std::get(t)) && ...); - } - (std::make_tuple(std::forward(ts)...), std::make_index_sequence()); - } -}; +// // Compare zero or more pairs of neighbours as needed. +// return [this](std::tuple && t, std::index_sequence) +// { +// return (predicate(std::get(t), std::get(t)) && ...); +// } +// (std::make_tuple(std::forward(ts)...), std::make_index_sequence()); +// } +// }; // Deduction guide: permit constructions such as `pairwise_all{std::less{}}`. // template // pairwise_all(T) -> pairwise_all; // Check whether a sequence of (possibly heterogeneously typed) values are strictly increasing. -template - requires(std::is_signed_v && ...) -[[nodiscard]] consteval bool strictly_increasing(Ts&&... ts) -{ - return pairwise_all{std::less{}}(std::forward(ts)...); -} +// template +// requires(std::is_signed_v && ...) +// [[nodiscard]] consteval bool strictly_increasing(Ts&&... ts) +// { +// return pairwise_all{std::less{}}(std::forward(ts)...); +// } -template -inline constexpr bool all_elements_valid = (is_valid_element(Elements) && ...); +// template +// inline constexpr bool all_elements_valid = (is_valid_element(Elements) && ...); -template -inline constexpr bool all_elements_in_order = strictly_increasing(get_base_value(Elements)...); +// template +// inline constexpr bool all_elements_in_order = strictly_increasing(get_base_value(Elements)...); -template -inline constexpr bool is_element_pack_valid = all_elements_valid && all_elements_in_order; +// template +// inline constexpr bool is_element_pack_valid = all_elements_valid && all_elements_in_order; [[nodiscard]] consteval bool is_rational(MagnitudeSpec auto element) { - return std::is_integral_v && (get_exponent(element).den == 1); + static_assert(!Magnitude); // magnitudes are handles by another overload + return std::is_integral_v && (get_exponent(element).den == 1); } [[nodiscard]] consteval bool is_integral(MagnitudeSpec auto element) { + static_assert(!Magnitude); // magnitudes are handles by another overload return is_rational(element) && get_exponent(element).num > 0; } @@ -433,29 +455,40 @@ inline constexpr bool is_element_pack_valid = all_elements_valid && * rational powers, and compare for equality. */ template - requires detail::is_element_pack_valid +// requires detail::is_element_pack_valid struct magnitude { - // Whether this magnitude represents an integer. - [[nodiscard]] friend consteval bool is_integral(const magnitude&) { return (detail::is_integral(Ms) && ...); } + [[nodiscard]] friend consteval bool is_integral(const magnitude&) + { + using namespace detail; // needed for recursive case when magnitudes are in the MagnitudeSpec + return (is_integral(Ms) && ...); + } - // Whether this magnitude represents a rational number. - [[nodiscard]] friend consteval bool is_rational(const magnitude&) { return (detail::is_rational(Ms) && ...); } + [[nodiscard]] friend consteval bool is_rational(const magnitude&) + { + using namespace detail; // needed for recursive case when magnitudes are in the MagnitudeSpec + return (is_rational(Ms) && ...); + } }; + namespace detail { -// Implementation for Magnitude concept (below). +template +void to_base_specialization_of_magnitude(const volatile magnitude*); + template -inline constexpr bool is_magnitude = false; -template -inline constexpr bool is_magnitude> = true; +inline constexpr bool is_derived_from_specialization_of_magnitude = + requires(T * t) { to_base_specialization_of_magnitude(t); }; + +template + requires is_derived_from_specialization_of_magnitude +inline constexpr bool is_magnitude = true; + +template +inline constexpr bool is_specialization_of_magnitude> = true; + } // namespace detail -/** - * @brief Concept to detect whether T is a valid Magnitude. - */ -template -concept Magnitude = detail::is_magnitude; /** * @brief The value of a Magnitude in a desired type T. @@ -471,23 +504,25 @@ concept Magnitude = detail::is_magnitude; // return result; // } + /** * @brief A convenient Magnitude constant for pi, which we can manipulate like a regular number. */ -inline constexpr Magnitude auto mag_pi = magnitude{}; +inline constexpr struct mag_pi : magnitude> { +} mag_pi; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Magnitude equality implementation. -template -constexpr bool operator==(magnitude, magnitude) -{ - if constexpr (sizeof...(LeftBPs) == sizeof...(RightBPs)) { - return ((LeftBPs == RightBPs) && ...); - } else { - return false; - } -} +// template +// constexpr bool operator==(magnitude, magnitude) +// { +// if constexpr (sizeof...(LeftBPs) == sizeof...(RightBPs)) { +// return ((LeftBPs == RightBPs) && ...); +// } else { +// return false; +// } +// } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Magnitude rational powers implementation. @@ -517,6 +552,21 @@ constexpr auto cbrt(magnitude m) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Magnitude product implementation. +namespace detail { + +consteval bool less(MagnitudeSpec auto lhs, MagnitudeSpec auto rhs) +{ + if constexpr (is_named_magnitude && is_named_magnitude) + return type_name(lhs) < type_name(rhs); + else if constexpr (!is_named_magnitude && !is_named_magnitude) + return get_base(lhs) < get_base(rhs); + else + return is_named_magnitude; +} + +} // namespace detail + + // Base cases, for when either (or both) inputs are the identity. constexpr Magnitude auto operator*(magnitude<>, magnitude<>) { return magnitude<>{}; } constexpr Magnitude auto operator*(magnitude<>, Magnitude auto m) { return m; } @@ -528,32 +578,31 @@ constexpr Magnitude auto operator*(magnitude, magnitude) { using namespace detail; - // Case for when H1 has the smaller base. - if constexpr (get_base_value(H1) < get_base_value(H2)) { + if constexpr (less(H1, H2)) { if constexpr (sizeof...(T1) == 0) { // Shortcut for the "pure prepend" case, which makes it easier to implement some of the other cases. return magnitude{}; } else { return magnitude

{} * (magnitude{} * magnitude{}); } - } - - // Case for when H2 has the smaller base. - if constexpr (get_base_value(H1) > get_base_value(H2)) { + } else if constexpr (less(H2, H1)) { return magnitude

{} * (magnitude{} * magnitude{}); - } - - // "Same leading base" case. - if constexpr (get_base(H1) == get_base(H2)) { + } else { constexpr auto partial_product = magnitude{} * magnitude{}; - // Make a new power_v with the common base of H1 and H2, whose power is their powers' sum. - constexpr auto new_head = power_v_or_T(); + if constexpr (is_same_v) { + // Make a new power_v with the common base of H1 and H2, whose power is their powers' sum. + constexpr auto new_head = power_v_or_T(); - if constexpr (get_exponent(new_head) == 0) { - return partial_product; + if constexpr (get_exponent(new_head) == 0) { + return partial_product; + } else { + return magnitude{} * partial_product; + } + } else if constexpr (is_named_magnitude) { + return magnitude

{} * (magnitude{} * magnitude{}); } else { - return magnitude{} * partial_product; + return magnitude

{} * (magnitude{} * magnitude{}); } } } diff --git a/src/core/include/units/quantity.h b/src/core/include/units/quantity.h index 84c6042e..7507359e 100644 --- a/src/core/include/units/quantity.h +++ b/src/core/include/units/quantity.h @@ -23,33 +23,37 @@ #pragma once -#include -#include +// #include +// #include // IWYU pragma: begin_exports -#include -#include +// #include +// #include +#include +#include +#include +#include +#include +#include #include // IWYU pragma: end_exports -#include -#include +// #include +// #include namespace units { namespace detail { -template // TODO: Replace with `v * R` pending https://github.com/BobSteagall/wg21/issues/58. -inline constexpr auto make_quantity = [](auto&& v) { +// TODO: Replace with `v * R` pending https://github.com/BobSteagall/wg21/issues/58. +template +inline constexpr auto make_quantity = [](Representation auto&& v) { using Rep = std::remove_cvref_t; - return quantity(std::forward(v)); + return quantity(std::forward(v)); }; template -concept quantity_one = - Quantity && - (std::same_as || std::same_as>) && - detail::equivalent_unit::value; +concept quantity_one = Quantity && (T::dimension == one_dim) && (T::unit == one); } // namespace detail @@ -65,12 +69,12 @@ concept safe_convertible_to_ = // exposition only // QFrom ratio is an exact multiple of QTo template concept harmonic_ = // exposition only - Quantity && Quantity && is_integral(detail::quantity_magnitude / detail::quantity_magnitude); + true; // TODO fix it when magnitudes are ready +// Quantity && Quantity && is_integral(detail::quantity_magnitude / detail::quantity_magnitude); template concept safe_castable_to_ = // exposition only - Quantity && QuantityOf && - scalable_with_ && + Quantity && quantity_of && scalable_with_ && (floating_point_ || (!floating_point_ && harmonic_)); template @@ -83,9 +87,23 @@ concept invoke_result_convertible_to_ = template concept have_quantity_for_ = Quantity && (!Quantity) && quantity_value_for_; +template +concept QuantityLike = requires(T q) { + typename quantity_like_traits::dimension; + typename quantity_like_traits::unit; + typename quantity_like_traits::rep; + requires Dimension::dimension>; + requires Unit::unit>; + requires Representation::rep>; + { + quantity_like_traits::number(q) + } -> std::convertible_to::rep>; + }; + template -using quantity_like_type = quantity::dimension, typename quantity_like_traits::unit, - typename quantity_like_traits::rep>; +using quantity_like_type = + quantity::dimension, typename quantity_like_traits::unit>{}, + typename quantity_like_traits::rep>; /** * @brief A quantity @@ -97,15 +115,15 @@ using quantity_like_type = quantity::dimension, * @tparam U a measurement unit of the quantity * @tparam Rep a type to be used to represent values of a quantity */ -template U, Representation Rep = double> +template class quantity { Rep number_; public: // member types and values - using dimension = D; - using unit = U; using rep = Rep; - static constexpr units::reference reference{}; + static constexpr auto reference = R; + static constexpr auto dimension = R.dimension; + static constexpr auto unit = R.unit; // static member functions [[nodiscard]] static constexpr quantity zero() noexcept @@ -171,14 +189,14 @@ public: } -> std::common_with; } { - using ret = quantity; + using ret = quantity; return ret(+number()); } [[nodiscard]] constexpr Quantity auto operator-() const requires(std::regular_invocable, rep>) { - using ret = quantity; + using ret = quantity; return ret(-number()); } @@ -380,7 +398,7 @@ public: requires(invoke_result_convertible_to_, rep, const Value&>) [[nodiscard]] friend constexpr Quantity auto operator*(const quantity& q, const Value& v) { - using ret = quantity, rep, Value>>; + using ret = quantity, rep, Value>>; return ret(q.number() * v); } @@ -388,7 +406,7 @@ public: requires(invoke_result_convertible_to_, const Value&, rep>) [[nodiscard]] friend constexpr Quantity auto operator*(const Value& v, const quantity& q) { - using ret = quantity, Value, rep>>; + using ret = quantity, Value, rep>>; return ret(v * q.number()); } @@ -397,7 +415,7 @@ public: [[nodiscard]] friend constexpr Quantity auto operator/(const quantity& q, const Value& v) { gsl_ExpectsAudit(v != quantity_values::zero()); - using ret = quantity, rep, Value>>; + using ret = quantity, rep, Value>>; return ret(q.number() / v); } @@ -405,7 +423,7 @@ public: requires(!Quantity) && (invoke_result_convertible_to_, const Value&, rep>) [[nodiscard]] friend constexpr Quantity auto operator/(const Value& v, const quantity& q) { - return detail::make_quantity<::units::reference{} / reference>(v / q.number()); + return detail::make_quantity(v / q.number()); } template @@ -414,7 +432,7 @@ public: [[nodiscard]] friend constexpr Quantity auto operator%(const quantity& q, const Value& v) { gsl_ExpectsAudit(v != quantity_values::zero()); - using ret = quantity, rep, Value>>; + using ret = quantity, rep, Value>>; return ret(q.number() % v); } @@ -422,7 +440,7 @@ public: requires(!floating_point_) && (invoke_result_convertible_to_, rep, rep>) { gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); - using ret = quantity, rep, rep>>; + using ret = quantity, rep, rep>>; return ret(lhs.number() % rhs.number()); } @@ -441,36 +459,37 @@ public: // CTAD #if !UNITS_COMP_CLANG || UNITS_COMP_CLANG > 16 -template -explicit(false) quantity(Rep&&)->quantity; +template +explicit(false) quantity(Rep&&) -> quantity; #endif -template -explicit(false) quantity(quantity)->quantity; +template +explicit(false) quantity(quantity) -> quantity; template -explicit(false) quantity(Rep)->quantity; +explicit(false) quantity(Rep)->quantity; template -explicit quantity(Q) -> quantity::dimension, typename quantity_like_traits::unit, - typename quantity_like_traits::rep>; +explicit quantity(Q) + -> quantity::dimension, typename quantity_like_traits::unit>{}, + typename quantity_like_traits::rep>; // non-member binary operators -template Q2> +template Q2> requires(quantity_value_for_, typename Q1::rep, typename Q2::rep>) [[nodiscard]] constexpr Quantity auto operator+(const Q1& lhs, const Q2& rhs) { using ref = detail::common_quantity_reference; - using ret = quantity; + using ret = quantity; return ret(ret(lhs).number() + ret(rhs).number()); } -template Q2> +template Q2> requires(quantity_value_for_, typename Q1::rep, typename Q2::rep>) [[nodiscard]] constexpr Quantity auto operator-(const Q1& lhs, const Q2& rhs) { using ref = detail::common_quantity_reference; - using ret = quantity; + using ret = quantity; return ret(ret(lhs).number() - ret(rhs).number()); } @@ -491,17 +510,17 @@ template template requires(!floating_point_) && (!floating_point_) && - (QuantityEquivalentTo || Dimensionless) && + (quantity_equivalent_to || quantity_of) && (quantity_value_for_, typename Q1::rep, typename Q2::rep>) [[nodiscard]] constexpr Quantity auto operator%(const Q1& lhs, const Q2& rhs) { gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); - using ret = quantity{}, std::invoke_result_t, typename Q1::rep, typename Q2::rep>>; return ret(lhs.number() % rhs.number()); } -template Q2> +template Q2> requires std::three_way_comparable_with [[nodiscard]] constexpr auto operator<=>(const Q1& lhs, const Q2& rhs) { @@ -509,7 +528,7 @@ template Q2> return cq(lhs).number() <=> cq(rhs).number(); } -template Q2> +template Q2> requires std::equality_comparable_with [[nodiscard]] constexpr bool operator==(const Q1& lhs, const Q2& rhs) { @@ -517,16 +536,4 @@ template Q2> return cq(lhs).number() == cq(rhs).number(); } -// type traits -namespace detail { - -template -inline constexpr bool is_quantity> = true; - -template - requires units::is_derived_from_specialization_of -inline constexpr bool is_quantity = true; - -} // namespace detail - } // namespace units diff --git a/src/core/include/units/reference.h b/src/core/include/units/reference.h index 291a7fab..62e151de 100644 --- a/src/core/include/units/reference.h +++ b/src/core/include/units/reference.h @@ -22,36 +22,27 @@ #pragma once +#include #include #include namespace units { -// TODO Concept for system reference -template -class quantity { -public: - using reference = decltype(R); - static constexpr auto dimension = reference::dimension; - static constexpr auto unit = reference::unit; - - quantity(Rep) {} -}; - -template +template struct system_reference; -namespace detail { +// namespace detail { -template -void to_base_specialization_of_system_reference(const volatile system_reference*); +// template +// void to_base_specialization_of_inline constexpr struct const volatile system_reference*> {} const volatile system_reference -// inline constexpr bool // TODO: Replace with concept when it works with MSVC -concept is_derived_from_specialization_of_system_reference = - requires(T* t) { detail::to_base_specialization_of_system_reference(t); }; +// template +// // inline constexpr bool // TODO: Replace with concept when it works with MSVC +// concept is_derived_from_specialization_of_system_reference = +// requires(T* t) { detail::to_base_specialization_of_system_reference(t); }; -} // namespace detail +// } // namespace detail /** * @brief The type for quantity references @@ -92,33 +83,36 @@ concept is_derived_from_specialization_of_system_reference = * The following syntaxes are not allowed: * `2 / s`, `km * 3`, `s / 4`, `70 * km / h`. */ -template -struct reference; +// template +// requires detail::is_derived_from_specialization_of_system_reference +// struct reference { +// using system_reference = R; +// static constexpr auto dimension = R::dimension; +// static constexpr U unit{}; +// // static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag = dimension::mag * unit::mag; +// }; -template - requires detail::is_derived_from_specialization_of_system_reference -struct reference { - using system_reference = R; - static constexpr auto dimension = R::dimension; - static constexpr U unit{}; - // static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag = dimension::mag * unit::mag; -}; - -template -struct reference { +template +struct reference { static constexpr D dimension{}; static constexpr U unit{}; // static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag = dimension::mag * unit::mag; }; // Reference -/** - * @brief A concept matching all references in the library. - * - * Satisfied by all specializations of @c reference. - */ -template -concept Reference = is_specialization_of; + +template +[[nodiscard]] consteval reference operator*(M, R) +{ + return {}; +} + +// template +// requires requires { typename R::system_reference; } +// [[nodiscard]] consteval reference operator*(M, R) +// { +// return {}; +// } template [[nodiscard]] consteval reference operator*(R1, @@ -134,29 +128,28 @@ template return {}; } -// TODO Update when quantity is done -// template -// [[nodiscard]] friend constexpr Quantity auto operator*(const Rep& lhs, reference) -template +template [[nodiscard]] constexpr quantity operator*(const Rep& lhs, R) { return quantity(lhs); } -// friend void /*Use `q * (1 * r)` rather than `q * r`.*/ operator*(Quantity auto, reference) = delete; +void /*Use `q * (1 * r)` rather than `q * r`.*/ operator*(Quantity auto, Reference auto) = delete; -// TODO will use deducing this -template +template struct system_reference { static constexpr auto dimension = Dim; static constexpr auto coherent_unit = CoU; template - // requires same_unit_reference - [[nodiscard]] consteval reference operator[](U) const + // requires same_unit_reference + [[nodiscard]] constexpr reference, U> operator[](U) const { return {}; } }; +inline constexpr struct dimensionless : system_reference { +} dimensionless; + } // namespace units diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index d3c5b068..0646e2fd 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -75,6 +75,12 @@ namespace detail { template void to_base_scaled_unit(const volatile scaled_unit*); +template +inline constexpr bool is_specialization_of_scaled_unit = false; + +template +inline constexpr bool is_specialization_of_scaled_unit> = true; + } // namespace detail /** @@ -98,14 +104,106 @@ concept NamedUnit = Unit && detail::is_named; template struct same_unit_reference : is_same {}; +namespace detail { + +template +struct unit_less : std::bool_constant() < type_name()> {}; + +template +using type_list_of_unit_less = expr_less; + +/** + * @brief Unpacks the list of potentially derived dimensions to a list containing only base dimensions + * + * @tparam Es Exponents of potentially derived dimensions + */ +// template +// struct unit_extract; + +// template<> +// struct unit_extract, type_list<>> { +// using num = type_list<>; +// using den = type_list<>; +// }; + +// template +// requires BaseUnit || BaseUnit +// struct unit_extract, type_list> { +// using impl = unit_extract, type_list>; +// using num = type_list_push_front; +// using den = TYPENAME impl::den; +// }; + +// template +// requires BaseUnit || BaseUnit +// struct unit_extract, type_list> { +// using impl = unit_extract, type_list>; +// using num = TYPENAME impl::num; +// using den = type_list_push_front; +// }; + +// template +// struct unit_extract, type_list> : +// unit_extract, +// type_list_push_back> {}; + +// template +// struct unit_extract, NRest...>, type_list> : +// unit_extract::num, +// power::den>::type, +// NRest...>, +// type_list_push_back::num, +// power::den>::type, +// Dens...>> {}; + + +// template +// struct unit_extract, type_list> : +// unit_extract> {}; + +// template +// struct unit_extract, type_list, DRest...>> : +// unit_extract::num, power::den>::type, +// type_list_push_back::num, +// power::den>::type, +// DRest...>> {}; + +/** + * @brief Converts user provided derived dimension specification into a valid units::normalized_dimension definition + * + * User provided definition of a derived dimension may contain the same base dimension repeated more than once on the + * list possibly hidden in other derived units provided by the user. The process here should: + * 1. Extract derived dimensions into exponents of base dimensions. + * 2. Sort the exponents so the same dimensions are placed next to each other. + * 3. Consolidate contiguous range of exponents of the same base dimensions to a one (or possibly zero) exponent for + * this base dimension. + */ +template +struct normalized_unit : detail::expr_fractions { + // private: + // using base = detail::expr_fractions; + // using extracted = unit_extract; + // using num_list = expr_consolidate>; + // using den_list = expr_consolidate>; + // using simple = expr_simplify; + // public: + // using normalized_num = TYPENAME simple::num; + // using normalized_den = TYPENAME simple::den; +}; + +} // namespace detail + // TODO add checking for `per` and power elements as well template concept UnitSpec = Unit || is_specialization_of || detail::is_specialization_of_power; +// User should not instantiate this type!!! +// It should not be exported from the module template -struct derived_unit : detail::expr_fractions, Us...>, scaled_unit, derived_unit> {}; - -// : detail::normalized_dimension, Ds...> {}; +struct derived_unit : detail::normalized_unit, Us...>, scaled_unit, derived_unit> { + static constexpr bool is_base = false; +}; /** * @brief Unit one @@ -129,28 +227,13 @@ struct named_unit; template struct named_unit : scaled_unit, named_unit> { static constexpr auto symbol = Symbol; + static constexpr bool is_base = true; }; -template - requires is_specialization_of, derived_unit> +template struct named_unit : decltype(U) { static constexpr auto symbol = Symbol; -}; - - -/** - * @brief A named scaled unit - * - * Defines a new named unit that is a scaled version of another unit. - * A named unit may be composed with a prefix to create a prefixed_unit. - * - * @tparam Symbol a short text representation of the unit - * @tparam M the Magnitude by which to scale U - * @tparam U a reference unit to scale - */ -template -struct named_scaled_unit : scaled_unit { - static constexpr auto symbol = Symbol; + static constexpr bool is_base = decltype(U)::is_base; }; /** @@ -164,15 +247,12 @@ struct named_scaled_unit : scaled_unit -// requires detail::can_be_prefixed -// struct prefixed_unit : downcast_dispatch> { -// static constexpr auto symbol = P::symbol + U::symbol; -// }; - - template -struct prefixed_unit : scaled_unit {}; +// requires detail::can_be_prefixed +struct prefixed_unit : scaled_unit { + // static constexpr auto symbol = symbol + decltype(U)::symbol; + static constexpr bool is_base = decltype(U)::is_base; +}; /** * @brief A coherent unit of a derived quantity @@ -187,11 +267,11 @@ struct prefixed_unit : scaled_unit -void is_named_impl(const volatile named_unit*); +template +void is_named_impl(const volatile named_unit*); -template -void is_named_impl(const volatile named_scaled_unit*); +template +void is_named_impl(const volatile prefixed_unit*); template inline constexpr bool is_named = requires(U * u) { is_named_impl(u); }; @@ -211,15 +291,20 @@ inline constexpr bool is_named = requires(U * u) { is_named_impl(u); }; // template // inline constexpr bool can_be_prefixed> = can_be_prefixed; - -template -struct unit_less : std::bool_constant() < type_name()> {}; - -template -using type_list_of_unit_less = expr_less; - } // namespace detail +template +[[nodiscard]] consteval Unit auto operator*(M mag, U) +{ + return scaled_unit{}; +} + +template +[[nodiscard]] consteval Unit auto operator*(M1 mag, scaled_unit) +{ + return scaled_unit{}; +} + template [[nodiscard]] consteval Unit auto operator*(U1, U2) { @@ -242,9 +327,16 @@ template template [[nodiscard]] consteval bool operator==(U1, U2) { - return false; + return is_same_v; } +template +[[nodiscard]] consteval bool equivalent(U1, U2) +{ + return true; // TODO implement this +} + + // template // constexpr bool operator==(D1, D2) // { @@ -274,4 +366,16 @@ template // std::is_same_v; // } +template +struct square_ : decltype(U{} * U{}) {}; + +template +inline constexpr square_> square; + +template +struct cubic_ : decltype(U{} * U{} * U{}) {}; + +template +inline constexpr cubic_> cubic; + } // namespace units diff --git a/src/systems/CMakeLists.txt b/src/systems/CMakeLists.txt index 06a3169d..d313f744 100644 --- a/src/systems/CMakeLists.txt +++ b/src/systems/CMakeLists.txt @@ -24,17 +24,19 @@ cmake_minimum_required(VERSION 3.19) # systems add_subdirectory(isq) -add_subdirectory(isq-iec80000) -add_subdirectory(isq-natural) + +# add_subdirectory(isq-iec80000) +# add_subdirectory(isq-natural) add_subdirectory(si) add_subdirectory(si-cgs) -add_subdirectory(si-fps) -add_subdirectory(si-hep) -add_subdirectory(si-iau) -add_subdirectory(si-imperial) -add_subdirectory(si-international) -add_subdirectory(si-typographic) -add_subdirectory(si-uscs) + +# add_subdirectory(si-fps) +# add_subdirectory(si-hep) +# add_subdirectory(si-iau) +# add_subdirectory(si-imperial) +# add_subdirectory(si-international) +# add_subdirectory(si-typographic) +# add_subdirectory(si-uscs) # wrapper for all the systems add_library(mp-units-systems INTERFACE) @@ -42,17 +44,17 @@ target_link_libraries( mp-units-systems INTERFACE mp-units::isq - mp-units::isq-iec80000 - mp-units::isq-natural + # mp-units::isq-iec80000 + # mp-units::isq-natural mp-units::si mp-units::si-cgs - mp-units::si-fps - mp-units::si-hep - mp-units::si-iau - mp-units::si-imperial - mp-units::si-international - mp-units::si-typographic - mp-units::si-uscs + # mp-units::si-fps + # mp-units::si-hep + # mp-units::si-iau + # mp-units::si-imperial + # mp-units::si-international + # mp-units::si-typographic + # mp-units::si-uscs ) add_library(mp-units::systems ALIAS mp-units-systems) set_target_properties(mp-units-systems PROPERTIES EXPORT_NAME systems) diff --git a/src/systems/isq/CMakeLists.txt b/src/systems/isq/CMakeLists.txt index 029ebfe2..8824cf29 100644 --- a/src/systems/isq/CMakeLists.txt +++ b/src/systems/isq/CMakeLists.txt @@ -23,53 +23,6 @@ cmake_minimum_required(VERSION 3.19) add_units_module( - isq - DEPENDENCIES mp-units::core - HEADERS include/units/isq/dimensions/absorbed_dose.h - include/units/isq/dimensions/acceleration.h - include/units/isq/dimensions/amount_of_substance.h - include/units/isq/dimensions/angular_acceleration.h - include/units/isq/dimensions/angular_velocity.h - include/units/isq/dimensions/area.h - include/units/isq/dimensions/capacitance.h - include/units/isq/dimensions/catalytic_activity.h - include/units/isq/dimensions/charge_density.h - include/units/isq/dimensions/concentration.h - include/units/isq/dimensions/conductance.h - include/units/isq/dimensions/current_density.h - include/units/isq/dimensions/density.h - include/units/isq/dimensions/dynamic_viscosity.h - include/units/isq/dimensions/electric_charge.h - include/units/isq/dimensions/electric_current.h - include/units/isq/dimensions/electric_field_strength.h - include/units/isq/dimensions/energy.h - include/units/isq/dimensions/energy_density.h - include/units/isq/dimensions/force.h - include/units/isq/dimensions/frequency.h - include/units/isq/dimensions/heat_capacity.h - include/units/isq/dimensions/inductance.h - include/units/isq/dimensions/length.h - include/units/isq/dimensions/luminance.h - include/units/isq/dimensions/luminous_flux.h - include/units/isq/dimensions/luminous_intensity.h - include/units/isq/dimensions/magnetic_flux.h - include/units/isq/dimensions/magnetic_induction.h - include/units/isq/dimensions/mass.h - include/units/isq/dimensions/molar_energy.h - include/units/isq/dimensions/momentum.h - include/units/isq/dimensions/permeability.h - include/units/isq/dimensions/permittivity.h - include/units/isq/dimensions/power.h - include/units/isq/dimensions/pressure.h - include/units/isq/dimensions/radioactivity.h - include/units/isq/dimensions/resistance.h - include/units/isq/dimensions/speed.h - include/units/isq/dimensions/surface_tension.h - include/units/isq/dimensions/thermal_conductivity.h - include/units/isq/dimensions/thermodynamic_temperature.h - include/units/isq/dimensions/time.h - include/units/isq/dimensions/torque.h - include/units/isq/dimensions/voltage.h - include/units/isq/dimensions/volume.h - include/units/isq/dimensions.h + isq DEPENDENCIES mp-units::core HEADERS include/units/isq/base_dimensions.h include/units/isq/isq.h + include/units/isq/mechanics.h include/units/isq/space_and_time.h ) diff --git a/src/systems/isq/include/units/isq/dimensions/angular_acceleration.h b/src/systems/isq/include/units/isq/base_dimensions.h similarity index 61% rename from src/systems/isq/include/units/isq/dimensions/angular_acceleration.h rename to src/systems/isq/include/units/isq/base_dimensions.h index a5d38a23..cabf9b61 100644 --- a/src/systems/isq/include/units/isq/dimensions/angular_acceleration.h +++ b/src/systems/isq/include/units/isq/base_dimensions.h @@ -22,19 +22,19 @@ #pragma once -#include -#include -#include +#include namespace units::isq { -template -struct dim_angular_acceleration; - -template A, DimensionOfT T> -struct dim_angular_acceleration : derived_dimension, exponent> {}; - -template -concept AngularAcceleration = QuantityOfT; +// clang-format off +inline constexpr struct length_dim : base_dimension<"L"> {} length_dim; +inline constexpr struct mass_dim : base_dimension<"M"> {} mass_dim; +inline constexpr struct time_dim : base_dimension<"T"> {} time_dim; +inline constexpr struct electric_current_dim : base_dimension<"I"> {} electric_current_dim; +// TODO Should the below use basic_symbol_text? How to name it for ASCII? +inline constexpr struct thermodynamic_temperature_dim : base_dimension<"Θ"> {} thermodynamic_temperature_dim; +inline constexpr struct amount_of_substance_dim : base_dimension<"N"> {} amount_of_substance_dim; +inline constexpr struct luminous_intensity_dim : base_dimension<"J"> {} luminous_intensity_dim; +// clang-format on } // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions.h b/src/systems/isq/include/units/isq/dimensions.h deleted file mode 100644 index 5d226fcb..00000000 --- a/src/systems/isq/include/units/isq/dimensions.h +++ /dev/null @@ -1,74 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -// TODO Add when downcasting issue is solved (collides with pressure) -// #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -// TODO Add when downcasting issue is solved (collides with frequency) -// #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -// IWYU pragma: end_exports diff --git a/src/systems/isq/include/units/isq/dimensions/absorbed_dose.h b/src/systems/isq/include/units/isq/dimensions/absorbed_dose.h deleted file mode 100644 index 633af9a7..00000000 --- a/src/systems/isq/include/units/isq/dimensions/absorbed_dose.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_absorbed_dose; - -template E, DimensionOfT M> -struct dim_absorbed_dose : derived_dimension, exponent> {}; - -template -concept AbsorbedDose = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/acceleration.h b/src/systems/isq/include/units/isq/dimensions/acceleration.h deleted file mode 100644 index a122ec6d..00000000 --- a/src/systems/isq/include/units/isq/dimensions/acceleration.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_acceleration; - -template L, DimensionOfT T> -struct dim_acceleration : derived_dimension, exponent> {}; - -template -concept Acceleration = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/amount_of_substance.h b/src/systems/isq/include/units/isq/dimensions/amount_of_substance.h deleted file mode 100644 index 099e516f..00000000 --- a/src/systems/isq/include/units/isq/dimensions/amount_of_substance.h +++ /dev/null @@ -1,35 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include - -namespace units::isq { - -template -struct dim_amount_of_substance : base_dimension<"N", U> {}; - -template -concept AmountOfSubstance = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/angular_velocity.h b/src/systems/isq/include/units/isq/dimensions/angular_velocity.h deleted file mode 100644 index e2ae4b69..00000000 --- a/src/systems/isq/include/units/isq/dimensions/angular_velocity.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_angular_velocity; - -template A, DimensionOfT T> -struct dim_angular_velocity : derived_dimension, exponent> {}; - -template -concept AngularVelocity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/capacitance.h b/src/systems/isq/include/units/isq/dimensions/capacitance.h deleted file mode 100644 index 8f474587..00000000 --- a/src/systems/isq/include/units/isq/dimensions/capacitance.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_capacitance; - -template C, DimensionOfT V> -struct dim_capacitance : derived_dimension, exponent> {}; - -template -concept Capacitance = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/catalytic_activity.h b/src/systems/isq/include/units/isq/dimensions/catalytic_activity.h deleted file mode 100644 index f0d67250..00000000 --- a/src/systems/isq/include/units/isq/dimensions/catalytic_activity.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_catalytic_activity; - -template T, DimensionOfT M> -struct dim_catalytic_activity : derived_dimension, exponent> {}; - -template -concept CatalyticActivity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/charge_density.h b/src/systems/isq/include/units/isq/dimensions/charge_density.h deleted file mode 100644 index 8625665a..00000000 --- a/src/systems/isq/include/units/isq/dimensions/charge_density.h +++ /dev/null @@ -1,49 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_charge_density; - -template Q, DimensionOfT L> -struct dim_charge_density : derived_dimension, exponent> {}; - -template -struct dim_surface_charge_density; - -template Q, DimensionOfT L> -struct dim_surface_charge_density : derived_dimension, exponent> {}; - -template -concept ChargeDensity = QuantityOfT; - -template -concept SurfaceChargeDensity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/concentration.h b/src/systems/isq/include/units/isq/dimensions/concentration.h deleted file mode 100644 index c5181d44..00000000 --- a/src/systems/isq/include/units/isq/dimensions/concentration.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_concentration; - -template M, DimensionOfT L> -struct dim_concentration : derived_dimension, exponent> {}; - -template -concept Concentration = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/current_density.h b/src/systems/isq/include/units/isq/dimensions/current_density.h deleted file mode 100644 index f097de77..00000000 --- a/src/systems/isq/include/units/isq/dimensions/current_density.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_current_density; - -template I, DimensionOfT L> -struct dim_current_density : derived_dimension, exponent> {}; - -template -concept CurrentDensity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/density.h b/src/systems/isq/include/units/isq/dimensions/density.h deleted file mode 100644 index cb5196d9..00000000 --- a/src/systems/isq/include/units/isq/dimensions/density.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_density; - -template M, DimensionOfT L> -struct dim_density : derived_dimension, exponent> {}; - -template -concept Density = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/dynamic_viscosity.h b/src/systems/isq/include/units/isq/dimensions/dynamic_viscosity.h deleted file mode 100644 index ceac79e5..00000000 --- a/src/systems/isq/include/units/isq/dimensions/dynamic_viscosity.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_dynamic_viscosity; - -template P, DimensionOfT T> -struct dim_dynamic_viscosity : derived_dimension, exponent> {}; - -template -concept DynamicViscosity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/electric_charge.h b/src/systems/isq/include/units/isq/dimensions/electric_charge.h deleted file mode 100644 index 2c7db791..00000000 --- a/src/systems/isq/include/units/isq/dimensions/electric_charge.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_electric_charge; - -template T, DimensionOfT C> -struct dim_electric_charge : derived_dimension, exponent> {}; - -template -concept ElectricCharge = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/electric_current.h b/src/systems/isq/include/units/isq/dimensions/electric_current.h deleted file mode 100644 index 52a3a4a1..00000000 --- a/src/systems/isq/include/units/isq/dimensions/electric_current.h +++ /dev/null @@ -1,35 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include - -namespace units::isq { - -template -struct dim_electric_current : base_dimension<"I", U> {}; - -template -concept ElectricCurrent = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/electric_field_strength.h b/src/systems/isq/include/units/isq/dimensions/electric_field_strength.h deleted file mode 100644 index 4bcd78f6..00000000 --- a/src/systems/isq/include/units/isq/dimensions/electric_field_strength.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_electric_field_strength; - -template V, DimensionOfT L> -struct dim_electric_field_strength : derived_dimension, exponent> {}; - -template -concept ElectricFieldStrength = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/energy.h b/src/systems/isq/include/units/isq/dimensions/energy.h deleted file mode 100644 index db090615..00000000 --- a/src/systems/isq/include/units/isq/dimensions/energy.h +++ /dev/null @@ -1,43 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_energy; - -template F, DimensionOfT L> -struct dim_energy : derived_dimension, exponent> {}; - -template L, DimensionOfT F> -struct dim_energy : derived_dimension, exponent> {}; - -template -concept Energy = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/energy_density.h b/src/systems/isq/include/units/isq/dimensions/energy_density.h deleted file mode 100644 index aa63cbca..00000000 --- a/src/systems/isq/include/units/isq/dimensions/energy_density.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_energy_density; - -template E, DimensionOfT V> -struct dim_energy_density : derived_dimension, exponent> {}; - -template -concept EnergyDensity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/force.h b/src/systems/isq/include/units/isq/dimensions/force.h deleted file mode 100644 index 20dc9540..00000000 --- a/src/systems/isq/include/units/isq/dimensions/force.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_force; - -template M, DimensionOfT A> -struct dim_force : derived_dimension, exponent> {}; - -template -concept Force = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/frequency.h b/src/systems/isq/include/units/isq/dimensions/frequency.h deleted file mode 100644 index 4b3dc285..00000000 --- a/src/systems/isq/include/units/isq/dimensions/frequency.h +++ /dev/null @@ -1,39 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include - -namespace units::isq { - -template -struct dim_frequency; - -template T> -struct dim_frequency : derived_dimension> {}; - -template -concept Frequency = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/heat_capacity.h b/src/systems/isq/include/units/isq/dimensions/heat_capacity.h deleted file mode 100644 index d4c3e0d4..00000000 --- a/src/systems/isq/include/units/isq/dimensions/heat_capacity.h +++ /dev/null @@ -1,60 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include -#include -#include - -namespace units::isq { - -template -struct dim_heat_capacity; - -template E, DimensionOfT T> -struct dim_heat_capacity : derived_dimension, exponent> {}; - -template -struct dim_specific_heat_capacity; - -template C, DimensionOfT M> -struct dim_specific_heat_capacity : derived_dimension, exponent> {}; - -template -struct dim_molar_heat_capacity; - -template C, DimensionOfT M> -struct dim_molar_heat_capacity : derived_dimension, exponent> {}; - -template -concept HeatCapacity = QuantityOfT; - -template -concept SpecificHeatCapacity = QuantityOfT; - -template -concept MolarHeatCapacity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/inductance.h b/src/systems/isq/include/units/isq/dimensions/inductance.h deleted file mode 100644 index 90ae21cd..00000000 --- a/src/systems/isq/include/units/isq/dimensions/inductance.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_inductance; - -template F, DimensionOfT I> -struct dim_inductance : derived_dimension, exponent> {}; - -template -concept Inductance = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/length.h b/src/systems/isq/include/units/isq/dimensions/length.h deleted file mode 100644 index 39170399..00000000 --- a/src/systems/isq/include/units/isq/dimensions/length.h +++ /dev/null @@ -1,35 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include - -namespace units::isq { - -template -struct dim_length : base_dimension<"L", U> {}; - -template -concept Length = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/luminance.h b/src/systems/isq/include/units/isq/dimensions/luminance.h deleted file mode 100644 index c5215828..00000000 --- a/src/systems/isq/include/units/isq/dimensions/luminance.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_luminance; - -template I, DimensionOfT L> -struct dim_luminance : derived_dimension, exponent> {}; - -template -concept Luminance = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/luminous_flux.h b/src/systems/isq/include/units/isq/dimensions/luminous_flux.h deleted file mode 100644 index ffa81053..00000000 --- a/src/systems/isq/include/units/isq/dimensions/luminous_flux.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_luminous_flux; - -template I, DimensionOfT A> -struct dim_luminous_flux : derived_dimension, exponent> {}; - -template -concept LuminousFlux = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/magnetic_flux.h b/src/systems/isq/include/units/isq/dimensions/magnetic_flux.h deleted file mode 100644 index d0f2dab5..00000000 --- a/src/systems/isq/include/units/isq/dimensions/magnetic_flux.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_magnetic_flux; - -template B, DimensionOfT A> -struct dim_magnetic_flux : derived_dimension, exponent> {}; - -template -concept MagneticFlux = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/magnetic_induction.h b/src/systems/isq/include/units/isq/dimensions/magnetic_induction.h deleted file mode 100644 index b7b54c0b..00000000 --- a/src/systems/isq/include/units/isq/dimensions/magnetic_induction.h +++ /dev/null @@ -1,42 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include -#include - -namespace units::isq { - -template -struct dim_magnetic_induction; - -template V, DimensionOfT T, DimensionOfT L> -struct dim_magnetic_induction : - derived_dimension, exponent, exponent> {}; - -template -concept MagneticInduction = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/mass.h b/src/systems/isq/include/units/isq/dimensions/mass.h deleted file mode 100644 index a2706b61..00000000 --- a/src/systems/isq/include/units/isq/dimensions/mass.h +++ /dev/null @@ -1,35 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include - -namespace units::isq { - -template -struct dim_mass : base_dimension<"M", U> {}; - -template -concept Mass = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/molar_energy.h b/src/systems/isq/include/units/isq/dimensions/molar_energy.h deleted file mode 100644 index a8b152b0..00000000 --- a/src/systems/isq/include/units/isq/dimensions/molar_energy.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_molar_energy; - -template E, DimensionOfT M> -struct dim_molar_energy : derived_dimension, exponent> {}; - -template -concept MolarEnergy = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/momentum.h b/src/systems/isq/include/units/isq/dimensions/momentum.h deleted file mode 100644 index 8508fb0a..00000000 --- a/src/systems/isq/include/units/isq/dimensions/momentum.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_momentum; - -template M, DimensionOfT V> -struct dim_momentum : derived_dimension, exponent> {}; - -template -concept Momentum = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/permeability.h b/src/systems/isq/include/units/isq/dimensions/permeability.h deleted file mode 100644 index 01543a57..00000000 --- a/src/systems/isq/include/units/isq/dimensions/permeability.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_permeability; - -template H, DimensionOfT L> -struct dim_permeability : derived_dimension, exponent> {}; - -template -concept Permeability = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/permittivity.h b/src/systems/isq/include/units/isq/dimensions/permittivity.h deleted file mode 100644 index 70601e6d..00000000 --- a/src/systems/isq/include/units/isq/dimensions/permittivity.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_permittivity; - -template C, DimensionOfT L> -struct dim_permittivity : derived_dimension, exponent> {}; - -template -concept Permittivity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/power.h b/src/systems/isq/include/units/isq/dimensions/power.h deleted file mode 100644 index 5a0b24ca..00000000 --- a/src/systems/isq/include/units/isq/dimensions/power.h +++ /dev/null @@ -1,43 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_power; - -template E, DimensionOfT T> -struct dim_power : derived_dimension, exponent> {}; - -template L, DimensionOfT F, DimensionOfT T> -struct dim_power : derived_dimension, exponent, exponent> {}; - -template -concept Power = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/pressure.h b/src/systems/isq/include/units/isq/dimensions/pressure.h deleted file mode 100644 index 47578401..00000000 --- a/src/systems/isq/include/units/isq/dimensions/pressure.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_pressure; - -template F, DimensionOfT A> -struct dim_pressure : derived_dimension, exponent> {}; - -template -concept Pressure = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/radioactivity.h b/src/systems/isq/include/units/isq/dimensions/radioactivity.h deleted file mode 100644 index 591a1da9..00000000 --- a/src/systems/isq/include/units/isq/dimensions/radioactivity.h +++ /dev/null @@ -1,39 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include - -namespace units::isq { - -template -struct dim_radioactivity; - -template T> -struct dim_radioactivity : derived_dimension> {}; - -template -concept Radioactivity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/resistance.h b/src/systems/isq/include/units/isq/dimensions/resistance.h deleted file mode 100644 index e9d8f9b5..00000000 --- a/src/systems/isq/include/units/isq/dimensions/resistance.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_resistance; - -template V, DimensionOfT C> -struct dim_resistance : derived_dimension, exponent> {}; - -template -concept Resistance = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/speed.h b/src/systems/isq/include/units/isq/dimensions/speed.h deleted file mode 100644 index d681420a..00000000 --- a/src/systems/isq/include/units/isq/dimensions/speed.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_speed; - -template L, DimensionOfT T> -struct dim_speed : derived_dimension, exponent> {}; - -template -concept Speed = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/surface_tension.h b/src/systems/isq/include/units/isq/dimensions/surface_tension.h deleted file mode 100644 index 52cdd3f3..00000000 --- a/src/systems/isq/include/units/isq/dimensions/surface_tension.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_surface_tension; - -template F, DimensionOfT L> -struct dim_surface_tension : derived_dimension, exponent> {}; - -template -concept SurfaceTension = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/thermal_conductivity.h b/src/systems/isq/include/units/isq/dimensions/thermal_conductivity.h deleted file mode 100644 index 1fe804d5..00000000 --- a/src/systems/isq/include/units/isq/dimensions/thermal_conductivity.h +++ /dev/null @@ -1,43 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include -#include - -namespace units::isq { - -template -struct dim_thermal_conductivity; - -template P, DimensionOfT L, - DimensionOfT T> -struct dim_thermal_conductivity : - derived_dimension, exponent, exponent> {}; - -template -concept ThermalConductivity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/thermodynamic_temperature.h b/src/systems/isq/include/units/isq/dimensions/thermodynamic_temperature.h deleted file mode 100644 index 8db16a23..00000000 --- a/src/systems/isq/include/units/isq/dimensions/thermodynamic_temperature.h +++ /dev/null @@ -1,35 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include - -namespace units::isq { - -template -struct dim_thermodynamic_temperature : base_dimension<"Θ", U> {}; - -template -concept ThermodynamicTemperature = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/torque.h b/src/systems/isq/include/units/isq/dimensions/torque.h deleted file mode 100644 index e134318e..00000000 --- a/src/systems/isq/include/units/isq/dimensions/torque.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_torque; - -template F, DimensionOfT L, DimensionOfT A> -struct dim_torque : derived_dimension, exponent, exponent> {}; - -template -concept Torque = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/voltage.h b/src/systems/isq/include/units/isq/dimensions/voltage.h deleted file mode 100644 index 187d5808..00000000 --- a/src/systems/isq/include/units/isq/dimensions/voltage.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_voltage; - -template P, DimensionOfT C> -struct dim_voltage : derived_dimension, exponent> {}; - -template -concept Voltage = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/volume.h b/src/systems/isq/include/units/isq/dimensions/volume.h deleted file mode 100644 index e8c3149d..00000000 --- a/src/systems/isq/include/units/isq/dimensions/volume.h +++ /dev/null @@ -1,39 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include - -namespace units::isq { - -template -struct dim_volume; - -template L> -struct dim_volume : derived_dimension> {}; - -template -concept Volume = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/time.h b/src/systems/isq/include/units/isq/isq.h similarity index 84% rename from src/systems/isq/include/units/isq/dimensions/time.h rename to src/systems/isq/include/units/isq/isq.h index f07b82d9..b32b820c 100644 --- a/src/systems/isq/include/units/isq/dimensions/time.h +++ b/src/systems/isq/include/units/isq/isq.h @@ -22,14 +22,7 @@ #pragma once -#include - -namespace units::isq { - -template -struct dim_time : base_dimension<"T", U> {}; - -template -concept Time = QuantityOfT; - -} // namespace units::isq +// IWYU pragma: begin_exports +#include +#include +// IWYU pragma: end_exports diff --git a/src/systems/isq/include/units/isq/mechanics.h b/src/systems/isq/include/units/isq/mechanics.h new file mode 100644 index 00000000..3f4271d9 --- /dev/null +++ b/src/systems/isq/include/units/isq/mechanics.h @@ -0,0 +1,72 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// 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. + +#pragma once + +#include +#include +#include + +namespace units::isq { + +// clang-format off +// inline constexpr struct mass_dim : base_dimension<"M"> {} mass_dim; +inline constexpr struct mass_density_dim : decltype(mass_dim / volume_dim) {} mass_density_dim; +inline constexpr struct specific_volume_dim : decltype(1 / mass_density_dim) {} specific_volume_dim; +inline constexpr struct relative_mass_density_dim : decltype(mass_density_dim / mass_density_dim) {} relative_mass_density_dim; +inline constexpr struct surface_mass_density_dim : decltype(mass_dim / area_dim) {} surface_mass_density_dim; +inline constexpr struct linear_mass_density_dim : decltype(mass_dim / length_dim) {} linear_mass_density_dim; +inline constexpr struct momentum_dim : decltype(mass_dim * speed_dim) {} momentum_dim; // TODO velocity_dim? +inline constexpr struct force_dim : decltype(mass_dim * acceleration_dim) {} force_dim; // TODO what is a correct equation here? +// inline constexpr struct weight_dim : decltype(mass_dim * acceleration_dim) {} weight_dim; // TODO should we add it as a quantity or should it be a quantity_kind? +// TODO Should we add other forces as well: static_friction_force, kinematic_friction_force, rolling_resistance, drag_force +inline constexpr struct impulse_dim : decltype(force_dim / time_dim) {} impulse_dim; +inline constexpr struct angular_momentum_dim : decltype(length_dim * momentum_dim) {} angular_momentum_dim; // TODO position_vector +inline constexpr struct moment_of_inertia_dim : decltype(angular_momentum_dim * angular_velocity_dim) {} moment_of_inertia_dim; +inline constexpr struct moment_of_force_dim : decltype(length_dim * force_dim) {} moment_of_force_dim; // TODO position_vector +inline constexpr struct torque_dim : decltype(moment_of_force_dim) {} torque_dim; // TODO angle? +inline constexpr struct angular_impulse_dim : decltype(moment_of_force_dim * time_dim) {} angular_impulse_dim; +inline constexpr struct pressure_dim : decltype(force_dim / area_dim) {} pressure_dim; +inline constexpr struct stress_dim : decltype(pressure_dim) {} stress_dim; // TODO tensor? +inline constexpr struct normal_stress_dim : decltype(force_dim / area_dim) {} normal_stress_dim; +inline constexpr struct strain_dim : decltype(stress_dim / stress_dim) {} strain_dim; // TODO what is a correct equation here? +inline constexpr struct poisson_number_dim : decltype(length_dim / length_dim) {} poisson_number_dim; // TODO width? +// TODO modulus quantities +inline constexpr struct compressibility_dim : decltype(volume_dim / pressure_dim) {} compressibility_dim; +inline constexpr struct second_axial_moment_of_area_dim : decltype(area_dim * area_dim) {} second_axial_moment_of_area_dim; // TODO what is a correct equation here? +inline constexpr struct section_modulus_dim : decltype(second_axial_moment_of_area_dim / length_dim) {} section_modulus_dim; // TODO radial distance +// TODO friction coefficients? +inline constexpr struct dynamic_viscosity_dim : decltype(stress_dim * length_dim / speed_dim) {} dynamic_viscosity_dim; // TODO shear stress, velocity +inline constexpr struct kinematic_viscosity_dim : decltype(dynamic_viscosity_dim / mass_density_dim) {} kinematic_viscosity_dim; +inline constexpr struct surface_tension_dim : decltype(force_dim / length_dim) {} surface_tension_dim; // TODO what is a correct equation here? +inline constexpr struct power_dim : decltype(force_dim * speed_dim) {} power_dim; +// TODO what about energy (potential and kinetic as separate quantities will prevent an equation for mechanical one, is it expected?) +inline constexpr struct efficiency_dim : decltype(power_dim / power_dim) {} efficiency_dim; +inline constexpr struct mass_flow_dim : decltype(mass_density_dim * speed_dim) {} mass_flow_dim; // TODO velocity +inline constexpr struct mass_flow_rate_dim : decltype(mass_flow_dim * area_dim) {} mass_flow_rate_dim; +inline constexpr struct mass_change_rate_dim : decltype(mass_dim / time_dim) {} mass_change_rate_dim; +inline constexpr struct volume_flow_rate_dim : decltype(speed_dim * area_dim) {} volume_flow_rate_dim; // TODO velocity +// inline constexpr struct action_dim : decltype(energy_dim * time_dim) {} action_dim; // TODO make it compile + +// clang-format on + +} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/space_and_time.h b/src/systems/isq/include/units/isq/space_and_time.h new file mode 100644 index 00000000..4357b630 --- /dev/null +++ b/src/systems/isq/include/units/isq/space_and_time.h @@ -0,0 +1,68 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// 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. + +#pragma once + +#include +#include + +namespace units::isq { + +// clang-format off +// inline constexpr struct length_dim : base_dimension<"L"> {} length_dim; +inline constexpr struct curvature_dim : decltype(1 / length_dim) {} curvature_dim; +inline constexpr struct area_dim : decltype(length_dim * length_dim) {} area_dim; +inline constexpr struct volume_dim : decltype(length_dim * length_dim * length_dim) {} volume_dim; +inline constexpr struct angular_measure_dim : decltype(length_dim / length_dim) {} angular_measure_dim; +inline constexpr struct angular_displacement_dim : decltype(length_dim / length_dim) {} angular_displacement_dim; +inline constexpr struct phase_angle_dim : decltype(length_dim / length_dim) {} phase_angle_dim; +inline constexpr struct solid_angular_measure_dim : decltype(area_dim / (length_dim * length_dim)) {} solid_angular_measure_dim; +// inline constexpr struct time_dim : base_dimension<"T"> {} time_dim; // TODO called duration in ISO 80000 +// TODO there is also a velocity in ISO 80000 +inline constexpr struct speed_dim : decltype(length_dim / time_dim) {} speed_dim; +inline constexpr struct acceleration_dim : decltype(speed_dim / time_dim) {} acceleration_dim; +inline constexpr struct angular_velocity_dim : decltype(angular_displacement_dim / time_dim) {} angular_velocity_dim; +inline constexpr struct angular_acceleration_dim : decltype(angular_velocity_dim / time_dim) {} angular_acceleration_dim; +inline constexpr struct period_duration_dim : time_dim {} period_duration_dim; +inline constexpr struct time_constant_dim : time_dim {} time_constant_dim; +inline constexpr struct rotation_dim : angular_displacement_dim {} rotation_dim; +inline constexpr struct frequency_dim : decltype(1 / time_dim) {} frequency_dim; +inline constexpr struct rotational_frequency_dim : decltype(rotation_dim / time_dim) {} rotational_frequency_dim; +inline constexpr struct angular_frequency_dim : decltype(angular_measure_dim / time_dim) {} angular_frequency_dim; +inline constexpr struct wavelength_dim : length_dim {} wavelength_dim; +inline constexpr struct repetency_dim : decltype(1 / wavelength_dim) {} repetency_dim; +inline constexpr struct wave_vector_dim : decltype(1 / length_dim) {} wave_vector_dim; +inline constexpr struct angular_repetency_dim : decltype(1 / wavelength_dim) {} angular_repetency_dim; +inline constexpr struct phase_velocity_dim : decltype(angular_frequency_dim / angular_repetency_dim) {} phase_velocity_dim; +inline constexpr struct damping_coefficient_dim : decltype(1 / time_constant_dim) {} damping_coefficient_dim; +inline constexpr struct logarithmic_decrement_dim : decltype(damping_coefficient_dim * period_duration_dim) {} logarithmic_decrement_dim; +inline constexpr struct attenuation_dim : decltype(1 / length_dim) {} attenuation_dim; +inline constexpr struct phase_coefficient_dim : decltype(phase_angle_dim / length_dim) {} phase_coefficient_dim; +inline constexpr struct propagation_coefficient_dim : decltype(1 / length_dim) {} propagation_coefficient_dim; +// clang-format on + +} // namespace units::isq + + +// inline constexpr struct force_dim : decltype(mass_dim * acceleration_dim) {} force_dim; +// inline constexpr struct energy_dim : decltype(force_dim * length_dim) {} energy_dim; +// inline constexpr struct power_dim : decltype(force_dim * speed_dim) {} power_dim; diff --git a/src/systems/isq/include/units/isq/dimensions/conductance.h b/src/systems/isq/include/units/isq/thermodynamics.h similarity index 71% rename from src/systems/isq/include/units/isq/dimensions/conductance.h rename to src/systems/isq/include/units/isq/thermodynamics.h index 6d7a71fd..afe0bd39 100644 --- a/src/systems/isq/include/units/isq/dimensions/conductance.h +++ b/src/systems/isq/include/units/isq/thermodynamics.h @@ -22,18 +22,21 @@ #pragma once -#include -#include +#include +#include +#include namespace units::isq { -template -struct dim_conductance; +// clang-format off +// inline constexpr struct thermodynamic_temperature_dim : base_dimension<"Θ"> {} thermodynamic_temperature_dim; +// TODO Celsius temperature??? -template R> -struct dim_conductance : derived_dimension> {}; +// inline constexpr struct mass_density_dim : decltype(mass_dim / volume_dim) {} mass_density_dim; -template -concept Conductance = QuantityOfT; + +inline constexpr struct energy_dim : decltype(force_dim * length_dim) {} energy_dim; + +// clang-format on } // namespace units::isq diff --git a/src/systems/si-cgs/CMakeLists.txt b/src/systems/si-cgs/CMakeLists.txt index 08316c20..802ab5df 100644 --- a/src/systems/si-cgs/CMakeLists.txt +++ b/src/systems/si-cgs/CMakeLists.txt @@ -22,18 +22,4 @@ cmake_minimum_required(VERSION 3.19) -add_units_module( - si-cgs - DEPENDENCIES mp-units::si - HEADERS include/units/isq/si/cgs/acceleration.h - include/units/isq/si/cgs/area.h - include/units/isq/si/cgs/cgs.h - include/units/isq/si/cgs/energy.h - include/units/isq/si/cgs/force.h - include/units/isq/si/cgs/length.h - include/units/isq/si/cgs/mass.h - include/units/isq/si/cgs/power.h - include/units/isq/si/cgs/pressure.h - include/units/isq/si/cgs/speed.h - include/units/isq/si/cgs/time.h -) +add_units_module(si-cgs DEPENDENCIES mp-units::si HEADERS include/units/si/cgs/cgs.h) diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/acceleration.h b/src/systems/si-cgs/include/units/isq/si/cgs/acceleration.h deleted file mode 100644 index fc983980..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/acceleration.h +++ /dev/null @@ -1,86 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si::cgs { - -struct gal : named_unit {}; -struct dim_acceleration : isq::dim_acceleration {}; - -template U, Representation Rep = double> -using acceleration = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Gal -constexpr auto operator"" _q_Gal(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return acceleration(static_cast(l)); -} -constexpr auto operator"" _q_Gal(long double l) { return acceleration(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace acceleration_references { - -inline constexpr auto Gal = reference{}; - -} // namespace acceleration_references - -namespace references { - -using namespace acceleration_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline acceleration { - -template -using Gal = units::isq::si::cgs::acceleration; - -} // namespace units::aliases::isq::si::cgs::inline acceleration - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/area.h b/src/systems/si-cgs/include/units/isq/si/cgs/area.h deleted file mode 100644 index ca3e14da..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/area.h +++ /dev/null @@ -1,88 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si::cgs { - -using si::square_centimetre; - -struct dim_area : isq::dim_area {}; - -template U, Representation Rep = double> -using area = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// cm2 -constexpr auto operator"" _q_cm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_cm2(long double l) { return area(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace area_references { - -inline constexpr auto cm2 = reference{}; - -} // namespace area_references - -namespace references { - -using namespace area_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline area { - -template -using cm2 = units::isq::si::cgs::area; - -} // namespace units::aliases::isq::si::cgs::inline area - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/cgs.h b/src/systems/si-cgs/include/units/isq/si/cgs/cgs.h deleted file mode 100644 index 26453d23..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/cgs.h +++ /dev/null @@ -1,36 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -// IWYU pragma: end_exports diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/energy.h b/src/systems/si-cgs/include/units/isq/si/cgs/energy.h deleted file mode 100644 index 7ca8af7f..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/energy.h +++ /dev/null @@ -1,88 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si::cgs { - -struct erg : named_unit {}; - -struct dim_energy : isq::dim_energy {}; - -template U, Representation Rep = double> -using energy = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// erg -constexpr auto operator"" _q_erg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_erg(long double l) { return energy(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace energy_references { - -inline constexpr auto erg = reference{}; - -} // namespace energy_references - -namespace references { - -using namespace energy_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline energy { - -template -using erg = units::isq::si::cgs::energy; - -} // namespace units::aliases::isq::si::cgs::inline energy - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/force.h b/src/systems/si-cgs/include/units/isq/si/cgs/force.h deleted file mode 100644 index f6f7bca3..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/force.h +++ /dev/null @@ -1,89 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si::cgs { - -struct dyne : named_unit {}; - -struct dim_force : isq::dim_force {}; - -template U, Representation Rep = double> -using force = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// dyn -constexpr auto operator"" _q_dyn(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_dyn(long double l) { return force(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace force_references { - -inline constexpr auto dyn = reference{}; - -} // namespace force_references - -namespace references { - -using namespace force_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline force { - -template -using dyn = units::isq::si::cgs::force; - -} // namespace units::aliases::isq::si::cgs::inline force - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/length.h b/src/systems/si-cgs/include/units/isq/si/cgs/length.h deleted file mode 100644 index 52e8dc96..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/length.h +++ /dev/null @@ -1,87 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include - -namespace units::isq::si::cgs { - -using si::centimetre; - -struct dim_length : isq::dim_length {}; - -template U, Representation Rep = double> -using length = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// cm -constexpr auto operator"" _q_cm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_cm(long double l) { return length(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace length_references { - -inline constexpr auto cm = reference{}; - -} // namespace length_references - -namespace references { - -using namespace length_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline length { - -template -using cm = units::isq::si::cgs::length; - -} // namespace units::aliases::isq::si::cgs::inline length - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/mass.h b/src/systems/si-cgs/include/units/isq/si/cgs/mass.h deleted file mode 100644 index 725447a0..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/mass.h +++ /dev/null @@ -1,87 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si::cgs { - -using si::gram; - -struct dim_mass : isq::dim_mass {}; - -template U, Representation Rep = double> -using mass = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// g -constexpr auto operator"" _q_g(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_g(long double l) { return mass(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace mass_references { - -inline constexpr auto g = reference{}; - -} // namespace mass_references - -namespace references { - -using namespace mass_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline mass { - -template -using g = units::isq::si::cgs::mass; - -} // namespace units::aliases::isq::si::cgs::inline mass - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/power.h b/src/systems/si-cgs/include/units/isq/si/cgs/power.h deleted file mode 100644 index 5d2b0483..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/power.h +++ /dev/null @@ -1,71 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si::cgs { - -struct erg_per_second : derived_unit {}; - -struct dim_power : isq::dim_power {}; - -template U, Representation Rep = double> -using power = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// erg/s -constexpr auto operator"" _q_erg_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_erg_per_s(long double l) { return power(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline power { - -template -using erg_per_s = units::isq::si::cgs::power; - -} // namespace units::aliases::isq::si::cgs::inline power - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/pressure.h b/src/systems/si-cgs/include/units/isq/si/cgs/pressure.h deleted file mode 100644 index e3b1a36a..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/pressure.h +++ /dev/null @@ -1,89 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si::cgs { - -struct barye : named_unit {}; - -struct dim_pressure : isq::dim_pressure {}; - -template U, Representation Rep = double> -using pressure = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Ba -constexpr auto operator"" _q_Ba(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_Ba(long double l) { return pressure(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace pressure_references { - -inline constexpr auto Ba = reference{}; - -} // namespace pressure_references - -namespace references { - -using namespace pressure_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline pressure { - -template -using Ba = units::isq::si::cgs::pressure; - -} // namespace units::aliases::isq::si::cgs::inline pressure - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/speed.h b/src/systems/si-cgs/include/units/isq/si/cgs/speed.h deleted file mode 100644 index c70ee197..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/speed.h +++ /dev/null @@ -1,70 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si::cgs { - -struct centimetre_per_second : derived_unit {}; -struct dim_speed : isq::dim_speed {}; - -template U, Representation Rep = double> -using speed = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// cm/s -constexpr auto operator"" _q_cm_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return speed(static_cast(l)); -} -constexpr auto operator"" _q_cm_per_s(long double l) { return speed(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline speed { - -template -using cm_per_s = units::isq::si::cgs::speed; - -} // namespace units::aliases::isq::si::cgs::inline speed - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-cgs/include/units/si/cgs/cgs.h b/src/systems/si-cgs/include/units/si/cgs/cgs.h new file mode 100644 index 00000000..4c68f3b6 --- /dev/null +++ b/src/systems/si-cgs/include/units/si/cgs/cgs.h @@ -0,0 +1,57 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// 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. + +#pragma once + +#include +#include +#include +#include +#include + +namespace units::si::cgs { + +// clang-format off +inline constexpr struct centimetre : si::centi_ {} centimetre; +inline constexpr struct gram : si::gram {} gram; +inline constexpr struct second : si::second {} second; +inline constexpr struct gal : named_unit<"Gal", centimetre / square> {} gal; +inline constexpr struct dyne : named_unit<"dyn", gram * centimetre / square> {} dyne; +inline constexpr struct erg : named_unit<"erg", dyne / centimetre> {} erg; +inline constexpr struct barye : named_unit<"Ba", gram / (centimetre * square)> {} barye; +inline constexpr struct poise : named_unit<"P", gram / (centimetre * second)> {} poise; +inline constexpr struct stokes : named_unit<"St", square / second> {} stokes; +inline constexpr struct kayser : decltype(1 / centimetre) {} kayser; + +inline constexpr struct length : system_reference {} length; +inline constexpr struct mass : system_reference {} mass; +inline constexpr struct time : system_reference {} time; +inline constexpr struct speed : system_reference {} speed; +inline constexpr struct acceleration : system_reference {} acceleration; +inline constexpr struct force : system_reference {} force;inline constexpr struct energy : system_reference {} energy; +inline constexpr struct power : system_reference {} power; +inline constexpr struct dynamic_viscosity : system_reference {} dynamic_viscosity; +inline constexpr struct kinematic_viscosity : system_reference {} kinematic_viscosity; +// inline constexpr struct wavenumber : system_reference {} wavenumber; +// clang-format on + +} // namespace units::si::cgs diff --git a/src/systems/si/CMakeLists.txt b/src/systems/si/CMakeLists.txt index f4a59f96..eb54a1c4 100644 --- a/src/systems/si/CMakeLists.txt +++ b/src/systems/si/CMakeLists.txt @@ -25,53 +25,13 @@ cmake_minimum_required(VERSION 3.19) add_units_module( si DEPENDENCIES mp-units::isq - HEADERS include/units/isq/si/absorbed_dose.h - include/units/isq/si/acceleration.h - include/units/isq/si/amount_of_substance.h - include/units/isq/si/angular_acceleration.h - include/units/isq/si/angular_velocity.h - include/units/isq/si/area.h - include/units/isq/si/capacitance.h - include/units/isq/si/catalytic_activity.h - include/units/isq/si/charge_density.h - include/units/isq/si/concentration.h - include/units/isq/si/conductance.h - include/units/isq/si/constants.h - include/units/isq/si/current_density.h - include/units/isq/si/density.h - include/units/isq/si/dynamic_viscosity.h - include/units/isq/si/electric_charge.h - include/units/isq/si/electric_current.h - include/units/isq/si/electric_field_strength.h - include/units/isq/si/energy.h - include/units/isq/si/energy_density.h - include/units/isq/si/force.h - include/units/isq/si/frequency.h - include/units/isq/si/heat_capacity.h - include/units/isq/si/inductance.h - include/units/isq/si/length.h - include/units/isq/si/luminance.h - include/units/isq/si/luminous_flux.h - include/units/isq/si/luminous_intensity.h - include/units/isq/si/magnetic_flux.h - include/units/isq/si/magnetic_induction.h - include/units/isq/si/mass.h - include/units/isq/si/molar_energy.h - include/units/isq/si/momentum.h - include/units/isq/si/permeability.h - include/units/isq/si/permittivity.h - include/units/isq/si/power.h - include/units/isq/si/prefixes.h - include/units/isq/si/pressure.h - include/units/isq/si/radioactivity.h - include/units/isq/si/resistance.h - include/units/isq/si/si.h - include/units/isq/si/speed.h - include/units/isq/si/surface_tension.h - include/units/isq/si/thermal_conductivity.h - include/units/isq/si/thermodynamic_temperature.h - include/units/isq/si/time.h - include/units/isq/si/torque.h - include/units/isq/si/voltage.h - include/units/isq/si/volume.h + HEADERS include/units/si/base_quantities.h + include/units/si/constants.h + include/units/si/mechanics.h + include/units/si/prefixes.h + include/units/si/si.h + include/units/si/space_and_time.h + include/units/si/thermodynamics.h + include/units/si/unit_symbols.h + include/units/si/units.h ) diff --git a/src/systems/si/include/units/isq/si/absorbed_dose.h b/src/systems/si/include/units/isq/si/absorbed_dose.h deleted file mode 100644 index 40159573..00000000 --- a/src/systems/si/include/units/isq/si/absorbed_dose.h +++ /dev/null @@ -1,328 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct gray : named_unit {}; -struct yoctogray : prefixed_unit {}; -struct zeptogray : prefixed_unit {}; -struct attogray : prefixed_unit {}; -struct femtogray : prefixed_unit {}; -struct picogray : prefixed_unit {}; -struct nanogray : prefixed_unit {}; -struct microgray : prefixed_unit {}; -struct milligray : prefixed_unit {}; -struct centigray : prefixed_unit {}; -struct decigray : prefixed_unit {}; -struct decagray : prefixed_unit {}; -struct hectogray : prefixed_unit {}; -struct kilogray : prefixed_unit {}; -struct megagray : prefixed_unit {}; -struct gigagray : prefixed_unit {}; -struct teragray : prefixed_unit {}; -struct petagray : prefixed_unit {}; -struct exagray : prefixed_unit {}; -struct zettagray : prefixed_unit {}; -struct yottagray : prefixed_unit {}; - -struct dim_absorbed_dose : isq::dim_absorbed_dose {}; - -template U, Representation Rep = double> -using absorbed_dose = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Gy -constexpr auto operator"" _q_Gy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_Gy(long double l) { return absorbed_dose(l); } - -// yGy -constexpr auto operator"" _q_yGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_yGy(long double l) { return absorbed_dose(l); } - -// zGy -constexpr auto operator"" _q_zGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_zGy(long double l) { return absorbed_dose(l); } - -// aGy -constexpr auto operator"" _q_aGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_aGy(long double l) { return absorbed_dose(l); } - -// fGy -constexpr auto operator"" _q_fGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_fGy(long double l) { return absorbed_dose(l); } - -// pGy -constexpr auto operator"" _q_pGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_pGy(long double l) { return absorbed_dose(l); } - -// nGy -constexpr auto operator"" _q_nGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_nGy(long double l) { return absorbed_dose(l); } - -// uGy -constexpr auto operator"" _q_uGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_uGy(long double l) { return absorbed_dose(l); } - -// mGy -constexpr auto operator"" _q_mGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_mGy(long double l) { return absorbed_dose(l); } - -// cGy -constexpr auto operator"" _q_cGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_cGy(long double l) { return absorbed_dose(l); } - -// dGy -constexpr auto operator"" _q_dGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_dGy(long double l) { return absorbed_dose(l); } - -// daGy -constexpr auto operator"" _q_daGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_daGy(long double l) { return absorbed_dose(l); } - -// hGy -constexpr auto operator"" _q_hGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_hGy(long double l) { return absorbed_dose(l); } - -// kGy -constexpr auto operator"" _q_kGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_kGy(long double l) { return absorbed_dose(l); } - -// MGy -constexpr auto operator"" _q_MGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_MGy(long double l) { return absorbed_dose(l); } - -// GGy -constexpr auto operator"" _q_GGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_GGy(long double l) { return absorbed_dose(l); } - -// TGy -constexpr auto operator"" _q_TGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_TGy(long double l) { return absorbed_dose(l); } - -// PGy -constexpr auto operator"" _q_PGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_PGy(long double l) { return absorbed_dose(l); } - -// EGy -constexpr auto operator"" _q_EGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_EGy(long double l) { return absorbed_dose(l); } - -// ZGy -constexpr auto operator"" _q_ZGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_ZGy(long double l) { return absorbed_dose(l); } - -// YGy -constexpr auto operator"" _q_YGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_YGy(long double l) { return absorbed_dose(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace absorbed_dose_references { - -inline constexpr auto Gy = reference{}; -inline constexpr auto yGy = reference{}; -inline constexpr auto zGy = reference{}; -inline constexpr auto aGy = reference{}; -inline constexpr auto fGy = reference{}; -inline constexpr auto pGy = reference{}; -inline constexpr auto nGy = reference{}; -inline constexpr auto uGy = reference{}; -inline constexpr auto mGy = reference{}; -inline constexpr auto cGy = reference{}; -inline constexpr auto dGy = reference{}; -inline constexpr auto daGy = reference{}; -inline constexpr auto hGy = reference{}; -inline constexpr auto kGy = reference{}; -inline constexpr auto MGy = reference{}; -inline constexpr auto GGy = reference{}; -inline constexpr auto TGy = reference{}; -inline constexpr auto PGy = reference{}; -inline constexpr auto EGy = reference{}; -inline constexpr auto ZGy = reference{}; -inline constexpr auto YGy = reference{}; - -} // namespace absorbed_dose_references - -namespace references { - -using namespace absorbed_dose_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline absorbed_dose { - -template -using Gy = units::isq::si::absorbed_dose; -template -using yGy = units::isq::si::absorbed_dose; -template -using zGy = units::isq::si::absorbed_dose; -template -using aGy = units::isq::si::absorbed_dose; -template -using fGy = units::isq::si::absorbed_dose; -template -using pGy = units::isq::si::absorbed_dose; -template -using nGy = units::isq::si::absorbed_dose; -template -using uGy = units::isq::si::absorbed_dose; -template -using mGy = units::isq::si::absorbed_dose; -template -using cGy = units::isq::si::absorbed_dose; -template -using dGy = units::isq::si::absorbed_dose; -template -using daGy = units::isq::si::absorbed_dose; -template -using hGy = units::isq::si::absorbed_dose; -template -using kGy = units::isq::si::absorbed_dose; -template -using MGy = units::isq::si::absorbed_dose; -template -using GGy = units::isq::si::absorbed_dose; -template -using TGy = units::isq::si::absorbed_dose; -template -using PGy = units::isq::si::absorbed_dose; -template -using EGy = units::isq::si::absorbed_dose; -template -using ZGy = units::isq::si::absorbed_dose; -template -using YGy = units::isq::si::absorbed_dose; - -} // namespace units::aliases::isq::si::inline absorbed_dose - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/acceleration.h b/src/systems/si/include/units/isq/si/acceleration.h deleted file mode 100644 index 90f0168a..00000000 --- a/src/systems/si/include/units/isq/si/acceleration.h +++ /dev/null @@ -1,69 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include - -namespace units::isq::si { - -struct metre_per_second_sq : derived_unit {}; -struct dim_acceleration : isq::dim_acceleration {}; - -template U, Representation Rep = double> -using acceleration = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// m/s2 -constexpr auto operator"" _q_m_per_s2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return acceleration(static_cast(l)); -} -constexpr auto operator"" _q_m_per_s2(long double l) { return acceleration(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline acceleration { - -template -using m_per_s2 = units::isq::si::acceleration; - -} // namespace units::aliases::isq::si::inline acceleration - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/amount_of_substance.h b/src/systems/si/include/units/isq/si/amount_of_substance.h deleted file mode 100644 index ba7578d8..00000000 --- a/src/systems/si/include/units/isq/si/amount_of_substance.h +++ /dev/null @@ -1,87 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct mole : named_unit {}; - -struct dim_amount_of_substance : isq::dim_amount_of_substance {}; - -template U, Representation Rep = double> -using amount_of_substance = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// mol -constexpr auto operator"" _q_mol(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return amount_of_substance(static_cast(l)); -} -constexpr auto operator"" _q_mol(long double l) { return amount_of_substance(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace amount_of_substance_references { - -inline constexpr auto mol = reference{}; - -} // namespace amount_of_substance_references - -namespace references { - -using namespace amount_of_substance_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline amount_of_substance { - -template -using mol = units::isq::si::amount_of_substance; - -} // namespace units::aliases::isq::si::inline amount_of_substance - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/angular_acceleration.h b/src/systems/si/include/units/isq/si/angular_acceleration.h deleted file mode 100644 index 4899448b..00000000 --- a/src/systems/si/include/units/isq/si/angular_acceleration.h +++ /dev/null @@ -1,76 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct radian_per_second_sq : derived_unit {}; - -struct dim_angular_acceleration : - isq::dim_angular_acceleration, dim_time> {}; - -template U, Representation Rep = double> -using angular_acceleration = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// rad/s2 -constexpr auto operator"" _q_rad_per_s2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return angular_acceleration(static_cast(l)); -} -constexpr auto operator"" _q_rad_per_s2(long double l) -{ - return angular_acceleration(l); -} - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline angular_acceleration { - -template -using rad_per_s2 = units::isq::si::angular_acceleration; - -} // namespace units::aliases::isq::si::inline angular_acceleration - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/angular_velocity.h b/src/systems/si/include/units/isq/si/angular_velocity.h deleted file mode 100644 index 81bdc296..00000000 --- a/src/systems/si/include/units/isq/si/angular_velocity.h +++ /dev/null @@ -1,73 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct radian_per_second : derived_unit {}; - -struct dim_angular_velocity : - isq::dim_angular_velocity, dim_time> {}; - -template U, Representation Rep = double> -using angular_velocity = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// rad/s -constexpr auto operator"" _q_rad_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return angular_velocity(static_cast(l)); -} -constexpr auto operator"" _q_rad_per_s(long double l) { return angular_velocity(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline angular_velocity { - -template -using rad_per_s = units::isq::si::angular_velocity; - -} // namespace units::aliases::isq::si::inline angular_velocity - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/area.h b/src/systems/si/include/units/isq/si/area.h deleted file mode 100644 index d430a38c..00000000 --- a/src/systems/si/include/units/isq/si/area.h +++ /dev/null @@ -1,382 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct square_metre : derived_unit {}; -struct dim_area : isq::dim_area {}; - -struct square_yoctometre : derived_scaled_unit {}; -struct square_zeptometre : derived_scaled_unit {}; -struct square_attometre : derived_scaled_unit {}; -struct square_femtometre : derived_scaled_unit {}; -struct square_picometre : derived_scaled_unit {}; -struct square_nanometre : derived_scaled_unit {}; -struct square_micrometre : derived_scaled_unit {}; -struct square_millimetre : derived_scaled_unit {}; -struct square_centimetre : derived_scaled_unit {}; -struct square_decimetre : derived_scaled_unit {}; -struct square_decametre : derived_scaled_unit {}; -struct square_hectometre : derived_scaled_unit {}; -struct square_kilometre : derived_scaled_unit {}; -struct square_megametre : derived_scaled_unit {}; -struct square_gigametre : derived_scaled_unit {}; -struct square_terametre : derived_scaled_unit {}; -struct square_petametre : derived_scaled_unit {}; -struct square_exametre : derived_scaled_unit {}; -struct square_zettametre : derived_scaled_unit {}; -struct square_yottametre : derived_scaled_unit {}; - -struct are : alias_unit {}; -struct centiare : prefixed_alias_unit {}; -struct deciare : prefixed_unit {}; -struct decare : prefixed_unit {}; -struct hectare : prefixed_alias_unit {}; - -template U, Representation Rep = double> -using area = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// m2 -constexpr auto operator"" _q_m2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_m2(long double l) { return area(l); } - -// ym2 -constexpr auto operator"" _q_ym2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_ym2(long double l) { return area(l); } - -// zm2 -constexpr auto operator"" _q_zm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_zm2(long double l) { return area(l); } - -// am2 -constexpr auto operator"" _q_am2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_am2(long double l) { return area(l); } - -// fm2 -constexpr auto operator"" _q_fm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_fm2(long double l) { return area(l); } - -// pm2 -constexpr auto operator"" _q_pm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_pm2(long double l) { return area(l); } - -// nm2 -constexpr auto operator"" _q_nm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_nm2(long double l) { return area(l); } - -// um2 -constexpr auto operator"" _q_um2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_um2(long double l) { return area(l); } - -// mm2 -constexpr auto operator"" _q_mm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_mm2(long double l) { return area(l); } - -// cm2 -constexpr auto operator"" _q_cm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_cm2(long double l) { return area(l); } - -// dm2 -constexpr auto operator"" _q_dm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_dm2(long double l) { return area(l); } - -// dam2 -constexpr auto operator"" _q_dam2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_dam2(long double l) { return area(l); } - -// hm2 -constexpr auto operator"" _q_hm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_hm2(long double l) { return area(l); } - -// km2 -constexpr auto operator"" _q_km2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_km2(long double l) { return area(l); } - -// Mm2 -constexpr auto operator"" _q_Mm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_Mm2(long double l) { return area(l); } - -// Gm2 -constexpr auto operator"" _q_Gm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_Gm2(long double l) { return area(l); } - -// Tm2 -constexpr auto operator"" _q_Tm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_Tm2(long double l) { return area(l); } - -// Pm2 -constexpr auto operator"" _q_Pm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_Pm2(long double l) { return area(l); } - -// Em2 -constexpr auto operator"" _q_Em2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_Em2(long double l) { return area(l); } - -// Zm2 -constexpr auto operator"" _q_Zm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_Zm2(long double l) { return area(l); } - -// Ym2 -constexpr auto operator"" _q_Ym2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_Ym2(long double l) { return area(l); } - -// a -constexpr auto operator"" _q_a(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_a(long double l) { return area(l); } - -// ca -constexpr auto operator"" _q_ca(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_ca(long double l) { return area(l); } - -// da -constexpr auto operator"" _q_da(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_da(long double l) { return area(l); } - -// daa -constexpr auto operator"" _q_daa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_daa(long double l) { return area(l); } - -// ha -constexpr auto operator"" _q_ha(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_ha(long double l) { return area(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace area_references { - -inline constexpr auto m2 = reference{}; -inline constexpr auto ym2 = reference{}; -inline constexpr auto zm2 = reference{}; -inline constexpr auto am2 = reference{}; -inline constexpr auto fm2 = reference{}; -inline constexpr auto pm2 = reference{}; -inline constexpr auto nm2 = reference{}; -inline constexpr auto um2 = reference{}; -inline constexpr auto mm2 = reference{}; -inline constexpr auto cm2 = reference{}; -inline constexpr auto dm2 = reference{}; -inline constexpr auto dam2 = reference{}; -inline constexpr auto hm2 = reference{}; -inline constexpr auto km2 = reference{}; -inline constexpr auto Mm2 = reference{}; -inline constexpr auto Gm2 = reference{}; -inline constexpr auto Tm2 = reference{}; -inline constexpr auto Pm2 = reference{}; -inline constexpr auto Em2 = reference{}; -inline constexpr auto Zm2 = reference{}; -inline constexpr auto Ym2 = reference{}; - -inline constexpr auto a = reference{}; -inline constexpr auto ca = reference{}; -inline constexpr auto da = reference{}; -inline constexpr auto daa = reference{}; -inline constexpr auto ha = reference{}; - -} // namespace area_references - -namespace references { - -using namespace area_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline area { - -template -using m2 = units::isq::si::area; -template -using ym2 = units::isq::si::area; -template -using zm2 = units::isq::si::area; -template -using am2 = units::isq::si::area; -template -using fm2 = units::isq::si::area; -template -using pm2 = units::isq::si::area; -template -using nm2 = units::isq::si::area; -template -using um2 = units::isq::si::area; -template -using mm2 = units::isq::si::area; -template -using cm2 = units::isq::si::area; -template -using dm2 = units::isq::si::area; -template -using dam2 = units::isq::si::area; -template -using hm2 = units::isq::si::area; -template -using km2 = units::isq::si::area; -template -using Mm2 = units::isq::si::area; -template -using Gm2 = units::isq::si::area; -template -using Tm2 = units::isq::si::area; -template -using Pm2 = units::isq::si::area; -template -using Em2 = units::isq::si::area; -template -using Zm2 = units::isq::si::area; -template -using Ym2 = units::isq::si::area; - -template -using ha = units::isq::si::area; - -} // namespace units::aliases::isq::si::inline area - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/capacitance.h b/src/systems/si/include/units/isq/si/capacitance.h deleted file mode 100644 index 31a477f9..00000000 --- a/src/systems/si/include/units/isq/si/capacitance.h +++ /dev/null @@ -1,329 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct farad : named_unit {}; -struct yoctofarad : prefixed_unit {}; -struct zeptofarad : prefixed_unit {}; -struct attofarad : prefixed_unit {}; -struct femtofarad : prefixed_unit {}; -struct picofarad : prefixed_unit {}; -struct nanofarad : prefixed_unit {}; -struct microfarad : prefixed_unit {}; -struct millifarad : prefixed_unit {}; -struct centifarad : prefixed_unit {}; -struct decifarad : prefixed_unit {}; -struct decafarad : prefixed_unit {}; -struct hectofarad : prefixed_unit {}; -struct kilofarad : prefixed_unit {}; -struct megafarad : prefixed_unit {}; -struct gigafarad : prefixed_unit {}; -struct terafarad : prefixed_unit {}; -struct petafarad : prefixed_unit {}; -struct exafarad : prefixed_unit {}; -struct zettafarad : prefixed_unit {}; -struct yottafarad : prefixed_unit {}; - -struct dim_capacitance : isq::dim_capacitance {}; - -template U, Representation Rep = double> -using capacitance = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// F -constexpr auto operator"" _q_F(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_F(long double l) { return capacitance(l); } - -// yF -constexpr auto operator"" _q_yF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_yF(long double l) { return capacitance(l); } - -// zF -constexpr auto operator"" _q_zF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_zF(long double l) { return capacitance(l); } - -// aF -constexpr auto operator"" _q_aF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_aF(long double l) { return capacitance(l); } - -// fF -constexpr auto operator"" _q_fF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_fF(long double l) { return capacitance(l); } - -// pF -constexpr auto operator"" _q_pF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_pF(long double l) { return capacitance(l); } - -// nF -constexpr auto operator"" _q_nF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_nF(long double l) { return capacitance(l); } - -// uF -constexpr auto operator"" _q_uF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_uF(long double l) { return capacitance(l); } - -// mF -constexpr auto operator"" _q_mF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_mF(long double l) { return capacitance(l); } - -// cF -constexpr auto operator"" _q_cF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_cF(long double l) { return capacitance(l); } - -// dF -constexpr auto operator"" _q_dF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_dF(long double l) { return capacitance(l); } - -// daF -constexpr auto operator"" _q_daF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_daF(long double l) { return capacitance(l); } - -// hF -constexpr auto operator"" _q_hF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_hF(long double l) { return capacitance(l); } - -// kF -constexpr auto operator"" _q_kF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_kF(long double l) { return capacitance(l); } - -// MF -constexpr auto operator"" _q_MF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_MF(long double l) { return capacitance(l); } - -// GF -constexpr auto operator"" _q_GF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_GF(long double l) { return capacitance(l); } - -// TF -constexpr auto operator"" _q_TF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_TF(long double l) { return capacitance(l); } - -// PF -constexpr auto operator"" _q_PF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_PF(long double l) { return capacitance(l); } - -// EF -constexpr auto operator"" _q_EF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_EF(long double l) { return capacitance(l); } - -// ZF -constexpr auto operator"" _q_ZF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_ZF(long double l) { return capacitance(l); } - -// YF -constexpr auto operator"" _q_YF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_YF(long double l) { return capacitance(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace capacitance_references { - -inline constexpr auto F = reference{}; -inline constexpr auto yF = reference{}; -inline constexpr auto zF = reference{}; -inline constexpr auto aF = reference{}; -inline constexpr auto fF = reference{}; -inline constexpr auto pF = reference{}; -inline constexpr auto nF = reference{}; -inline constexpr auto uF = reference{}; -inline constexpr auto mF = reference{}; -inline constexpr auto cF = reference{}; -inline constexpr auto dF = reference{}; -inline constexpr auto daF = reference{}; -inline constexpr auto hF = reference{}; -inline constexpr auto kF = reference{}; -inline constexpr auto MF = reference{}; -inline constexpr auto GF = reference{}; -inline constexpr auto TF = reference{}; -inline constexpr auto PF = reference{}; -inline constexpr auto EF = reference{}; -inline constexpr auto ZF = reference{}; -inline constexpr auto YF = reference{}; - -} // namespace capacitance_references - -namespace references { - -using namespace capacitance_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline capacitance { - -template -using F = units::isq::si::capacitance; -template -using yF = units::isq::si::capacitance; -template -using zF = units::isq::si::capacitance; -template -using aF = units::isq::si::capacitance; -template -using fF = units::isq::si::capacitance; -template -using pF = units::isq::si::capacitance; -template -using nF = units::isq::si::capacitance; -template -using uF = units::isq::si::capacitance; -template -using mF = units::isq::si::capacitance; -template -using cF = units::isq::si::capacitance; -template -using dF = units::isq::si::capacitance; -template -using daF = units::isq::si::capacitance; -template -using hF = units::isq::si::capacitance; -template -using kF = units::isq::si::capacitance; -template -using MF = units::isq::si::capacitance; -template -using GF = units::isq::si::capacitance; -template -using TF = units::isq::si::capacitance; -template -using PF = units::isq::si::capacitance; -template -using EF = units::isq::si::capacitance; -template -using ZF = units::isq::si::capacitance; -template -using YF = units::isq::si::capacitance; - -} // namespace units::aliases::isq::si::inline capacitance - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/catalytic_activity.h b/src/systems/si/include/units/isq/si/catalytic_activity.h deleted file mode 100644 index 926705d6..00000000 --- a/src/systems/si/include/units/isq/si/catalytic_activity.h +++ /dev/null @@ -1,343 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct katal : named_unit {}; -struct yoctokatal : prefixed_unit {}; -struct zeptokatal : prefixed_unit {}; -struct attokatal : prefixed_unit {}; -struct femtokatal : prefixed_unit {}; -struct picokatal : prefixed_unit {}; -struct nanokatal : prefixed_unit {}; -struct microkatal : prefixed_unit {}; -struct millikatal : prefixed_unit {}; -struct centikatal : prefixed_unit {}; -struct decikatal : prefixed_unit {}; -struct decakatal : prefixed_unit {}; -struct hectokatal : prefixed_unit {}; -struct kilokatal : prefixed_unit {}; -struct megakatal : prefixed_unit {}; -struct gigakatal : prefixed_unit {}; -struct terakatal : prefixed_unit {}; -struct petakatal : prefixed_unit {}; -struct exakatal : prefixed_unit {}; -struct zettakatal : prefixed_unit {}; -struct yottakatal : prefixed_unit {}; - -struct enzyme_unit : named_scaled_unit() * mag_power<10, -6>(), katal> {}; - -struct dim_catalytic_activity : - isq::dim_catalytic_activity {}; - -template U, Representation Rep = double> -using catalytic_activity = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// kat -constexpr auto operator"" _q_kat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_kat(long double l) { return catalytic_activity(l); } - -// ykat -constexpr auto operator"" _q_ykat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_ykat(long double l) { return catalytic_activity(l); } - -// zkat -constexpr auto operator"" _q_zkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_zkat(long double l) { return catalytic_activity(l); } - -// akat -constexpr auto operator"" _q_akat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_akat(long double l) { return catalytic_activity(l); } - -// fkat -constexpr auto operator"" _q_fkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_fkat(long double l) { return catalytic_activity(l); } - -// pkat -constexpr auto operator"" _q_pkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_pkat(long double l) { return catalytic_activity(l); } - -// nkat -constexpr auto operator"" _q_nkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_nkat(long double l) { return catalytic_activity(l); } - -// ukat -constexpr auto operator"" _q_ukat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_ukat(long double l) { return catalytic_activity(l); } - -// mkat -constexpr auto operator"" _q_mkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_mkat(long double l) { return catalytic_activity(l); } - -// ckat -constexpr auto operator"" _q_ckat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_ckat(long double l) { return catalytic_activity(l); } - -// dkat -constexpr auto operator"" _q_dkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_dkat(long double l) { return catalytic_activity(l); } - -// dakat -constexpr auto operator"" _q_dakat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_dakat(long double l) { return catalytic_activity(l); } - -// hkat -constexpr auto operator"" _q_hkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_hkat(long double l) { return catalytic_activity(l); } - -// kkat -constexpr auto operator"" _q_kkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_kkat(long double l) { return catalytic_activity(l); } - -// Mkat -constexpr auto operator"" _q_Mkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_Mkat(long double l) { return catalytic_activity(l); } - -// Gkat -constexpr auto operator"" _q_Gkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_Gkat(long double l) { return catalytic_activity(l); } - -// Tkat -constexpr auto operator"" _q_Tkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_Tkat(long double l) { return catalytic_activity(l); } - -// Pkat -constexpr auto operator"" _q_Pkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_Pkat(long double l) { return catalytic_activity(l); } - -// Ekat -constexpr auto operator"" _q_Ekat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_Ekat(long double l) { return catalytic_activity(l); } - -// Zkat -constexpr auto operator"" _q_Zkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_Zkat(long double l) { return catalytic_activity(l); } - -// Ykat -constexpr auto operator"" _q_Ykat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_Ykat(long double l) { return catalytic_activity(l); } - -// U -constexpr auto operator"" _q_U(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_U(long double l) { return catalytic_activity(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace catalytic_activity_references { - -inline constexpr auto kat = reference{}; -inline constexpr auto ykat = reference{}; -inline constexpr auto zkat = reference{}; -inline constexpr auto akat = reference{}; -inline constexpr auto fkat = reference{}; -inline constexpr auto pkat = reference{}; -inline constexpr auto nkat = reference{}; -inline constexpr auto ukat = reference{}; -inline constexpr auto mkat = reference{}; -inline constexpr auto ckat = reference{}; -inline constexpr auto dkat = reference{}; -inline constexpr auto dakat = reference{}; -inline constexpr auto hkat = reference{}; -inline constexpr auto kkat = reference{}; -inline constexpr auto Mkat = reference{}; -inline constexpr auto Gkat = reference{}; -inline constexpr auto Tkat = reference{}; -inline constexpr auto Pkat = reference{}; -inline constexpr auto Ekat = reference{}; -inline constexpr auto Zkat = reference{}; -inline constexpr auto Ykat = reference{}; -inline constexpr auto U = reference{}; - -} // namespace catalytic_activity_references - -namespace references { - -using namespace catalytic_activity_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline catalytic_activity { - -template -using kat = units::isq::si::catalytic_activity; -template -using ykat = units::isq::si::catalytic_activity; -template -using zkat = units::isq::si::catalytic_activity; -template -using akat = units::isq::si::catalytic_activity; -template -using fkat = units::isq::si::catalytic_activity; -template -using pkat = units::isq::si::catalytic_activity; -template -using nkat = units::isq::si::catalytic_activity; -template -using ukat = units::isq::si::catalytic_activity; -template -using mkat = units::isq::si::catalytic_activity; -template -using ckat = units::isq::si::catalytic_activity; -template -using dkat = units::isq::si::catalytic_activity; -template -using dakat = units::isq::si::catalytic_activity; -template -using hkat = units::isq::si::catalytic_activity; -template -using kkat = units::isq::si::catalytic_activity; -template -using Mkat = units::isq::si::catalytic_activity; -template -using Gkat = units::isq::si::catalytic_activity; -template -using Tkat = units::isq::si::catalytic_activity; -template -using Pkat = units::isq::si::catalytic_activity; -template -using Ekat = units::isq::si::catalytic_activity; -template -using Zkat = units::isq::si::catalytic_activity; -template -using Ykat = units::isq::si::catalytic_activity; -template -using U = units::isq::si::catalytic_activity; - -} // namespace units::aliases::isq::si::inline catalytic_activity - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/charge_density.h b/src/systems/si/include/units/isq/si/charge_density.h deleted file mode 100644 index 52fba248..00000000 --- a/src/systems/si/include/units/isq/si/charge_density.h +++ /dev/null @@ -1,93 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct coulomb_per_metre_cub : derived_unit {}; -struct coulomb_per_metre_sq : derived_unit {}; - -struct dim_charge_density : - isq::dim_charge_density {}; -struct dim_surface_charge_density : - isq::dim_surface_charge_density { -}; - -template U, Representation Rep = double> -using charge_density = quantity; - -template U, Representation Rep = double> -using surface_charge_density = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// C/m³ -constexpr auto operator"" _q_C_per_m3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return charge_density(static_cast(l)); -} -constexpr auto operator"" _q_C_per_m3(long double l) { return charge_density(l); } - -// C/m² -constexpr auto operator"" _q_C_per_m2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return surface_charge_density(static_cast(l)); -} -constexpr auto operator"" _q_C_per_m2(long double l) -{ - return surface_charge_density(l); -} - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline charge_density { - -template -using C_per_m3 = units::isq::si::charge_density; -template -using C_per_m2 = units::isq::si::surface_charge_density; - -} // namespace units::aliases::isq::si::inline charge_density - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/concentration.h b/src/systems/si/include/units/isq/si/concentration.h deleted file mode 100644 index 732583a5..00000000 --- a/src/systems/si/include/units/isq/si/concentration.h +++ /dev/null @@ -1,71 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct mol_per_metre_cub : derived_unit {}; -struct dim_concentration : - isq::dim_concentration {}; - -template U, Representation Rep = double> -using concentration = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// mol/m³ -constexpr auto operator"" _q_mol_per_m3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return concentration(static_cast(l)); -} -constexpr auto operator"" _q_mol_per_m3(long double l) { return concentration(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline concentration { - -template -using mol_per_m3 = units::isq::si::concentration; - -} // namespace units::aliases::isq::si::inline concentration - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/conductance.h b/src/systems/si/include/units/isq/si/conductance.h deleted file mode 100644 index 5442201f..00000000 --- a/src/systems/si/include/units/isq/si/conductance.h +++ /dev/null @@ -1,280 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct siemens : named_unit {}; -struct yoctosiemens : prefixed_unit {}; -struct zeptosiemens : prefixed_unit {}; -struct attosiemens : prefixed_unit {}; -struct femtosiemens : prefixed_unit {}; -struct picosiemens : prefixed_unit {}; -struct nanosiemens : prefixed_unit {}; -struct microsiemens : prefixed_unit {}; -struct millisiemens : prefixed_unit {}; -struct kilosiemens : prefixed_unit {}; -struct megasiemens : prefixed_unit {}; -struct gigasiemens : prefixed_unit {}; -struct terasiemens : prefixed_unit {}; -struct petasiemens : prefixed_unit {}; -struct exasiemens : prefixed_unit {}; -struct zettasiemens : prefixed_unit {}; -struct yottasiemens : prefixed_unit {}; - -struct dim_conductance : isq::dim_conductance {}; - -template U, Representation Rep = double> -using conductance = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// R -constexpr auto operator"" _q_S(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_S(long double l) { return conductance(l); } - -// yS -constexpr auto operator"" _q_yS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_yS(long double l) { return conductance(l); } - -// zS -constexpr auto operator"" _q_zS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_zS(long double l) { return conductance(l); } - -// aS -constexpr auto operator"" _q_aS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_aS(long double l) { return conductance(l); } - -// fS -constexpr auto operator"" _q_fS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_fS(long double l) { return conductance(l); } - -// pS -constexpr auto operator"" _q_pS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_pS(long double l) { return conductance(l); } - -// nS -constexpr auto operator"" _q_nS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_nS(long double l) { return conductance(l); } - -// µS -constexpr auto operator"" _q_uS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_uS(long double l) { return conductance(l); } - -// mS -constexpr auto operator"" _q_mS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_mS(long double l) { return conductance(l); } - -// kS -constexpr auto operator"" _q_kS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_kS(long double l) { return conductance(l); } - -// MS -constexpr auto operator"" _q_MS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_MS(long double l) { return conductance(l); } - -// GS -constexpr auto operator"" _q_GS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_GS(long double l) { return conductance(l); } - -// TS -constexpr auto operator"" _q_TS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_TS(long double l) { return conductance(l); } - -// PS -constexpr auto operator"" _q_PS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_PS(long double l) { return conductance(l); } - -// ES -constexpr auto operator"" _q_ES(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_ES(long double l) { return conductance(l); } - -// ZS -constexpr auto operator"" _q_ZS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_ZS(long double l) { return conductance(l); } - -// YS -constexpr auto operator"" _q_YS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_YS(long double l) { return conductance(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace conductance_references { - -inline constexpr auto S = reference{}; -inline constexpr auto yS = reference{}; -inline constexpr auto zS = reference{}; -inline constexpr auto aS = reference{}; -inline constexpr auto fS = reference{}; -inline constexpr auto pS = reference{}; -inline constexpr auto nS = reference{}; -inline constexpr auto uS = reference{}; -inline constexpr auto mS = reference{}; -inline constexpr auto kS = reference{}; -inline constexpr auto MS = reference{}; -inline constexpr auto GS = reference{}; -inline constexpr auto TS = reference{}; -inline constexpr auto PS = reference{}; -inline constexpr auto ES = reference{}; -inline constexpr auto ZS = reference{}; -inline constexpr auto YS = reference{}; - -} // namespace conductance_references - -namespace references { - -using namespace conductance_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline conductance { - -template -using S = units::isq::si::conductance; -template -using yS = units::isq::si::conductance; -template -using zS = units::isq::si::conductance; -template -using aS = units::isq::si::conductance; -template -using fS = units::isq::si::conductance; -template -using pS = units::isq::si::conductance; -template -using nS = units::isq::si::conductance; -template -using uS = units::isq::si::conductance; -template -using mS = units::isq::si::conductance; -template -using kS = units::isq::si::conductance; -template -using MS = units::isq::si::conductance; -template -using GS = units::isq::si::conductance; -template -using TS = units::isq::si::conductance; -template -using PS = units::isq::si::conductance; -template -using ES = units::isq::si::conductance; -template -using ZS = units::isq::si::conductance; -template -using YS = units::isq::si::conductance; - -} // namespace units::aliases::isq::si::inline conductance - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/constants.h b/src/systems/si/include/units/isq/si/constants.h deleted file mode 100644 index 74209888..00000000 --- a/src/systems/si/include/units/isq/si/constants.h +++ /dev/null @@ -1,61 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace units::isq::si::si2019 { - -template -inline constexpr auto planck_constant = energy(6.62607015e-34) * time(1); - -template -inline constexpr auto elementary_charge = electric_charge(1.602176634e-19); - -template -inline constexpr auto boltzmann_constant = energy(1.380649e-23) / thermodynamic_temperature(1); - -template -inline constexpr auto avogadro_constant = Rep(6.02214076e23) / amount_of_substance(1); - -template -inline constexpr auto speed_of_light = speed(299'792'458); - -template -inline constexpr auto hyperfine_structure_transition_frequency = frequency(Rep{9'192'631'770}); - -template -inline constexpr auto luminous_efficacy = luminous_flux(683) / power(1); - -template -inline constexpr auto standard_gravity = acceleration(9.80665); - -} // namespace units::isq::si::si2019 diff --git a/src/systems/si/include/units/isq/si/current_density.h b/src/systems/si/include/units/isq/si/current_density.h deleted file mode 100644 index 94234b5b..00000000 --- a/src/systems/si/include/units/isq/si/current_density.h +++ /dev/null @@ -1,73 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct ampere_per_metre_sq : derived_unit {}; - -struct dim_current_density : - isq::dim_current_density {}; - -template U, Representation Rep = double> -using current_density = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// A / m² -constexpr auto operator"" _q_A_per_m2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return current_density(static_cast(l)); -} -constexpr auto operator"" _q_A_per_m2(long double l) { return current_density(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline current_density { - -template -using A_per_m2 = units::isq::si::current_density; - -} // namespace units::aliases::isq::si::inline current_density - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/density.h b/src/systems/si/include/units/isq/si/density.h deleted file mode 100644 index d890e225..00000000 --- a/src/systems/si/include/units/isq/si/density.h +++ /dev/null @@ -1,72 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct kilogram_per_metre_cub : derived_unit {}; - -struct dim_density : isq::dim_density {}; - -template U, Representation Rep = double> -using density = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// kg / m³ -constexpr auto operator"" _q_kg_per_m3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return density(static_cast(l)); -} -constexpr auto operator"" _q_kg_per_m3(long double l) { return density(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline density { - -template -using kg_per_m3 = units::isq::si::density; - -} // namespace units::aliases::isq::si::inline density - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/dynamic_viscosity.h b/src/systems/si/include/units/isq/si/dynamic_viscosity.h deleted file mode 100644 index 81f0d2bb..00000000 --- a/src/systems/si/include/units/isq/si/dynamic_viscosity.h +++ /dev/null @@ -1,71 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct pascal_second : derived_unit {}; -struct dim_dynamic_viscosity : - isq::dim_dynamic_viscosity {}; - -template U, Representation Rep = double> -using dynamic_viscosity = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Pa·s -constexpr auto operator"" _q_Pa_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return dynamic_viscosity(static_cast(l)); -} -constexpr auto operator"" _q_Pa_s(long double l) { return dynamic_viscosity(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline dynamic_viscosity { - -template -using Pa_s = units::isq::si::dynamic_viscosity; - -} // namespace units::aliases::isq::si::inline dynamic_viscosity - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/electric_charge.h b/src/systems/si/include/units/isq/si/electric_charge.h deleted file mode 100644 index ca431827..00000000 --- a/src/systems/si/include/units/isq/si/electric_charge.h +++ /dev/null @@ -1,88 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct coulomb : named_unit {}; - -struct dim_electric_charge : isq::dim_electric_charge {}; - -template U, Representation Rep = double> -using electric_charge = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// C -constexpr auto operator"" _q_C(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_charge(static_cast(l)); -} -constexpr auto operator"" _q_C(long double l) { return electric_charge(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace electric_charge_references { - -inline constexpr auto C = reference{}; - -} // namespace electric_charge_references - -namespace references { - -using namespace electric_charge_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline electric_charge { - -template -using C = units::isq::si::electric_charge; - -} // namespace units::aliases::isq::si::inline electric_charge - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/electric_current.h b/src/systems/si/include/units/isq/si/electric_current.h deleted file mode 100644 index 740eb113..00000000 --- a/src/systems/si/include/units/isq/si/electric_current.h +++ /dev/null @@ -1,327 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct ampere : named_unit {}; -struct yoctoampere : prefixed_unit {}; -struct zeptoampere : prefixed_unit {}; -struct attoampere : prefixed_unit {}; -struct femtoampere : prefixed_unit {}; -struct picoampere : prefixed_unit {}; -struct nanoampere : prefixed_unit {}; -struct microampere : prefixed_unit {}; -struct milliampere : prefixed_unit {}; -struct centiampere : prefixed_unit {}; -struct deciampere : prefixed_unit {}; -struct decaampere : prefixed_unit {}; -struct hectoampere : prefixed_unit {}; -struct kiloampere : prefixed_unit {}; -struct megaampere : prefixed_unit {}; -struct gigaampere : prefixed_unit {}; -struct teraampere : prefixed_unit {}; -struct petaampere : prefixed_unit {}; -struct exaampere : prefixed_unit {}; -struct zettaampere : prefixed_unit {}; -struct yottaampere : prefixed_unit {}; - -struct dim_electric_current : isq::dim_electric_current {}; - -template U, Representation Rep = double> -using electric_current = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// A -constexpr auto operator"" _q_A(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_A(long double l) { return electric_current(l); } - -// yA -constexpr auto operator"" _q_yA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_yA(long double l) { return electric_current(l); } - -// zA -constexpr auto operator"" _q_zA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_zA(long double l) { return electric_current(l); } - -// aA -constexpr auto operator"" _q_aA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_aA(long double l) { return electric_current(l); } - -// fA -constexpr auto operator"" _q_fA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_fA(long double l) { return electric_current(l); } - -// pA -constexpr auto operator"" _q_pA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_pA(long double l) { return electric_current(l); } - -// nA -constexpr auto operator"" _q_nA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_nA(long double l) { return electric_current(l); } - -// uA -constexpr auto operator"" _q_uA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_uA(long double l) { return electric_current(l); } - -// mA -constexpr auto operator"" _q_mA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_mA(long double l) { return electric_current(l); } - -// cA -constexpr auto operator"" _q_cA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_cA(long double l) { return electric_current(l); } - -// dA -constexpr auto operator"" _q_dA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_dA(long double l) { return electric_current(l); } - -// daA -constexpr auto operator"" _q_daA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_daA(long double l) { return electric_current(l); } - -// hA -constexpr auto operator"" _q_hA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_hA(long double l) { return electric_current(l); } - -// kA -constexpr auto operator"" _q_kA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_kA(long double l) { return electric_current(l); } - -// MA -constexpr auto operator"" _q_MA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_MA(long double l) { return electric_current(l); } - -// GA -constexpr auto operator"" _q_GA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_GA(long double l) { return electric_current(l); } - -// TA -constexpr auto operator"" _q_TA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_TA(long double l) { return electric_current(l); } - -// PA -constexpr auto operator"" _q_PA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_PA(long double l) { return electric_current(l); } - -// EA -constexpr auto operator"" _q_EA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_EA(long double l) { return electric_current(l); } - -// ZA -constexpr auto operator"" _q_ZA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_ZA(long double l) { return electric_current(l); } - -// YA -constexpr auto operator"" _q_YA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_YA(long double l) { return electric_current(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace electric_current_references { - -inline constexpr auto A = reference{}; -inline constexpr auto yA = reference{}; -inline constexpr auto zA = reference{}; -inline constexpr auto aA = reference{}; -inline constexpr auto fA = reference{}; -inline constexpr auto pA = reference{}; -inline constexpr auto nA = reference{}; -inline constexpr auto uA = reference{}; -inline constexpr auto mA = reference{}; -inline constexpr auto cA = reference{}; -inline constexpr auto dA = reference{}; -inline constexpr auto daA = reference{}; -inline constexpr auto hA = reference{}; -inline constexpr auto kA = reference{}; -inline constexpr auto MA = reference{}; -inline constexpr auto GA = reference{}; -inline constexpr auto TA = reference{}; -inline constexpr auto PA = reference{}; -inline constexpr auto EA = reference{}; -inline constexpr auto ZA = reference{}; -inline constexpr auto YA = reference{}; - -} // namespace electric_current_references - -namespace references { - -using namespace electric_current_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline electric_current { - -template -using A = units::isq::si::electric_current; -template -using yA = units::isq::si::electric_current; -template -using zA = units::isq::si::electric_current; -template -using aA = units::isq::si::electric_current; -template -using fA = units::isq::si::electric_current; -template -using pA = units::isq::si::electric_current; -template -using nA = units::isq::si::electric_current; -template -using uA = units::isq::si::electric_current; -template -using mA = units::isq::si::electric_current; -template -using cA = units::isq::si::electric_current; -template -using dA = units::isq::si::electric_current; -template -using daA = units::isq::si::electric_current; -template -using hA = units::isq::si::electric_current; -template -using kA = units::isq::si::electric_current; -template -using MA = units::isq::si::electric_current; -template -using GA = units::isq::si::electric_current; -template -using TA = units::isq::si::electric_current; -template -using PA = units::isq::si::electric_current; -template -using EA = units::isq::si::electric_current; -template -using ZA = units::isq::si::electric_current; -template -using YA = units::isq::si::electric_current; - -} // namespace units::aliases::isq::si::inline electric_current - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/electric_field_strength.h b/src/systems/si/include/units/isq/si/electric_field_strength.h deleted file mode 100644 index 773640d5..00000000 --- a/src/systems/si/include/units/isq/si/electric_field_strength.h +++ /dev/null @@ -1,70 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct volt_per_metre : derived_unit {}; -struct dim_electric_field_strength : - isq::dim_electric_field_strength {}; - -template U, Representation Rep = double> -using electric_field_strength = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// V/m -constexpr auto operator"" _q_V_per_m(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_field_strength(static_cast(l)); -} -constexpr auto operator"" _q_V_per_m(long double l) { return electric_field_strength(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline electric_field_strength { - -template -using V_per_m = units::isq::si::electric_field_strength; - -} // namespace units::aliases::isq::si::inline electric_field_strength - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/energy.h b/src/systems/si/include/units/isq/si/energy.h deleted file mode 100644 index 7511c4d0..00000000 --- a/src/systems/si/include/units/isq/si/energy.h +++ /dev/null @@ -1,310 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct joule : named_unit {}; -struct yoctojoule : prefixed_unit {}; -struct zeptojoule : prefixed_unit {}; -struct attojoule : prefixed_unit {}; -struct femtojoule : prefixed_unit {}; -struct picojoule : prefixed_unit {}; -struct nanojoule : prefixed_unit {}; -struct microjoule : prefixed_unit {}; -struct millijoule : prefixed_unit {}; -struct kilojoule : prefixed_unit {}; -struct megajoule : prefixed_unit {}; -struct gigajoule : prefixed_unit {}; -struct terajoule : prefixed_unit {}; -struct petajoule : prefixed_unit {}; -struct exajoule : prefixed_unit {}; -struct zettajoule : prefixed_unit {}; -struct yottajoule : prefixed_unit {}; - -// N.B. electron charge (and eV) is an exact constant: -// https://www.bipm.org/documents/20126/41483022/SI-Brochure-9.pdf#page=147 -struct electronvolt : - named_scaled_unit() * mag_power<10, -19>(), joule> {}; -struct gigaelectronvolt : prefixed_unit {}; - -struct dim_energy : isq::dim_energy {}; - -template U, Representation Rep = double> -using energy = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// J -constexpr auto operator"" _q_J(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_J(long double l) { return energy(l); } - -// yJ -constexpr auto operator"" _q_yJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_yJ(long double l) { return energy(l); } - -// zJ -constexpr auto operator"" _q_zJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_zJ(long double l) { return energy(l); } - -// aJ -constexpr auto operator"" _q_aJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_aJ(long double l) { return energy(l); } - -// fJ -constexpr auto operator"" _q_fJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_fJ(long double l) { return energy(l); } - -// pJ -constexpr auto operator"" _q_pJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_pJ(long double l) { return energy(l); } - -// nJ -constexpr auto operator"" _q_nJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_nJ(long double l) { return energy(l); } - -// uJ -constexpr auto operator"" _q_uJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_uJ(long double l) { return energy(l); } - -// mJ -constexpr auto operator"" _q_mJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_mJ(long double l) { return energy(l); } - -// kJ -constexpr auto operator"" _q_kJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_kJ(long double l) { return energy(l); } - -// MJ -constexpr auto operator"" _q_MJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_MJ(long double l) { return energy(l); } - -// GJ -constexpr auto operator"" _q_GJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_GJ(long double l) { return energy(l); } - -// TJ -constexpr auto operator"" _q_TJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_TJ(long double l) { return energy(l); } - -// PJ -constexpr auto operator"" _q_PJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_PJ(long double l) { return energy(l); } - -// EJ -constexpr auto operator"" _q_EJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_EJ(long double l) { return energy(l); } - -// ZJ -constexpr auto operator"" _q_ZJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_ZJ(long double l) { return energy(l); } - -// YJ -constexpr auto operator"" _q_YJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_YJ(long double l) { return energy(l); } - -// eV -constexpr auto operator"" _q_eV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_eV(long double l) { return energy(l); } - -// GeV -constexpr auto operator"" _q_GeV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_GeV(long double l) { return energy(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace energy_references { - -inline constexpr auto J = reference{}; -inline constexpr auto yJ = reference{}; -inline constexpr auto zJ = reference{}; -inline constexpr auto aJ = reference{}; -inline constexpr auto fJ = reference{}; -inline constexpr auto pJ = reference{}; -inline constexpr auto nJ = reference{}; -inline constexpr auto uJ = reference{}; -inline constexpr auto mJ = reference{}; -inline constexpr auto kJ = reference{}; -inline constexpr auto MJ = reference{}; -inline constexpr auto GJ = reference{}; -inline constexpr auto TJ = reference{}; -inline constexpr auto PJ = reference{}; -inline constexpr auto EJ = reference{}; -inline constexpr auto ZJ = reference{}; -inline constexpr auto YJ = reference{}; - -inline constexpr auto eV = reference{}; -inline constexpr auto GeV = reference{}; - -} // namespace energy_references - -namespace references { - -using namespace energy_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline energy { - -template -using J = units::isq::si::energy; -template -using yJ = units::isq::si::energy; -template -using zJ = units::isq::si::energy; -template -using aJ = units::isq::si::energy; -template -using fJ = units::isq::si::energy; -template -using pJ = units::isq::si::energy; -template -using nJ = units::isq::si::energy; -template -using uJ = units::isq::si::energy; -template -using mJ = units::isq::si::energy; -template -using kJ = units::isq::si::energy; -template -using MJ = units::isq::si::energy; -template -using GJ = units::isq::si::energy; -template -using TJ = units::isq::si::energy; -template -using PJ = units::isq::si::energy; -template -using EJ = units::isq::si::energy; -template -using ZJ = units::isq::si::energy; -template -using YJ = units::isq::si::energy; - -template -using eV = units::isq::si::energy; -template -using GeV = units::isq::si::energy; - -} // namespace units::aliases::isq::si::inline energy - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/energy_density.h b/src/systems/si/include/units/isq/si/energy_density.h deleted file mode 100644 index e9e156d7..00000000 --- a/src/systems/si/include/units/isq/si/energy_density.h +++ /dev/null @@ -1,70 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct joule_per_metre_cub : derived_unit {}; -struct dim_energy_density : isq::dim_energy_density {}; - -template U, Representation Rep = double> -using energy_density = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// N/m -constexpr auto operator"" _q_J_per_m3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy_density(static_cast(l)); -} -constexpr auto operator"" _q_J_per_m3(long double l) { return energy_density(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline energy_density { - -template -using J_per_m3 = units::isq::si::energy_density; - -} // namespace units::aliases::isq::si::inline energy_density - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/force.h b/src/systems/si/include/units/isq/si/force.h deleted file mode 100644 index fa2c1880..00000000 --- a/src/systems/si/include/units/isq/si/force.h +++ /dev/null @@ -1,329 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct newton : named_unit {}; -struct yoctonewton : prefixed_unit {}; -struct zeptonewton : prefixed_unit {}; -struct attonewton : prefixed_unit {}; -struct femtonewton : prefixed_unit {}; -struct piconewton : prefixed_unit {}; -struct nanonewton : prefixed_unit {}; -struct micronewton : prefixed_unit {}; -struct millinewton : prefixed_unit {}; -struct centinewton : prefixed_unit {}; -struct decinewton : prefixed_unit {}; -struct decanewton : prefixed_unit {}; -struct hectonewton : prefixed_unit {}; -struct kilonewton : prefixed_unit {}; -struct meganewton : prefixed_unit {}; -struct giganewton : prefixed_unit {}; -struct teranewton : prefixed_unit {}; -struct petanewton : prefixed_unit {}; -struct exanewton : prefixed_unit {}; -struct zettanewton : prefixed_unit {}; -struct yottanewton : prefixed_unit {}; - -struct dim_force : isq::dim_force {}; - -template U, Representation Rep = double> -using force = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// N -constexpr auto operator"" _q_N(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_N(long double l) { return force(l); } - -// yN -constexpr auto operator"" _q_yN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_yN(long double l) { return force(l); } - -// zN -constexpr auto operator"" _q_zN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_zN(long double l) { return force(l); } - -// aN -constexpr auto operator"" _q_aN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_aN(long double l) { return force(l); } - -// fN -constexpr auto operator"" _q_fN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_fN(long double l) { return force(l); } - -// pN -constexpr auto operator"" _q_pN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_pN(long double l) { return force(l); } - -// nN -constexpr auto operator"" _q_nN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_nN(long double l) { return force(l); } - -// uN -constexpr auto operator"" _q_uN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_uN(long double l) { return force(l); } - -// mN -constexpr auto operator"" _q_mN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_mN(long double l) { return force(l); } - -// cN -constexpr auto operator"" _q_cN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_cN(long double l) { return force(l); } - -// dN -constexpr auto operator"" _q_dN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_dN(long double l) { return force(l); } - -// daN -constexpr auto operator"" _q_daN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_daN(long double l) { return force(l); } - -// hN -constexpr auto operator"" _q_hN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_hN(long double l) { return force(l); } - -// kN -constexpr auto operator"" _q_kN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_kN(long double l) { return force(l); } - -// MN -constexpr auto operator"" _q_MN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_MN(long double l) { return force(l); } - -// GN -constexpr auto operator"" _q_GN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_GN(long double l) { return force(l); } - -// TN -constexpr auto operator"" _q_TN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_TN(long double l) { return force(l); } - -// PN -constexpr auto operator"" _q_PN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_PN(long double l) { return force(l); } - -// EN -constexpr auto operator"" _q_EN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_EN(long double l) { return force(l); } - -// ZN -constexpr auto operator"" _q_ZN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_ZN(long double l) { return force(l); } - -// YN -constexpr auto operator"" _q_YN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_YN(long double l) { return force(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace force_references { - -inline constexpr auto N = reference{}; -inline constexpr auto yN = reference{}; -inline constexpr auto zN = reference{}; -inline constexpr auto aN = reference{}; -inline constexpr auto fN = reference{}; -inline constexpr auto pN = reference{}; -inline constexpr auto nN = reference{}; -inline constexpr auto uN = reference{}; -inline constexpr auto mN = reference{}; -inline constexpr auto cN = reference{}; -inline constexpr auto dN = reference{}; -inline constexpr auto daN = reference{}; -inline constexpr auto hN = reference{}; -inline constexpr auto kN = reference{}; -inline constexpr auto MN = reference{}; -inline constexpr auto GN = reference{}; -inline constexpr auto TN = reference{}; -inline constexpr auto PN = reference{}; -inline constexpr auto EN = reference{}; -inline constexpr auto ZN = reference{}; -inline constexpr auto YN = reference{}; - -} // namespace force_references - -namespace references { - -using namespace force_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline force { - -template -using N = units::isq::si::force; -template -using yN = units::isq::si::force; -template -using zN = units::isq::si::force; -template -using aN = units::isq::si::force; -template -using fN = units::isq::si::force; -template -using pN = units::isq::si::force; -template -using nN = units::isq::si::force; -template -using uN = units::isq::si::force; -template -using mN = units::isq::si::force; -template -using cN = units::isq::si::force; -template -using dN = units::isq::si::force; -template -using daN = units::isq::si::force; -template -using hN = units::isq::si::force; -template -using kN = units::isq::si::force; -template -using MN = units::isq::si::force; -template -using GN = units::isq::si::force; -template -using TN = units::isq::si::force; -template -using PN = units::isq::si::force; -template -using EN = units::isq::si::force; -template -using ZN = units::isq::si::force; -template -using YN = units::isq::si::force; - -} // namespace units::aliases::isq::si::inline force - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/frequency.h b/src/systems/si/include/units/isq/si/frequency.h deleted file mode 100644 index 39fa13ee..00000000 --- a/src/systems/si/include/units/isq/si/frequency.h +++ /dev/null @@ -1,279 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct hertz : named_unit {}; -struct yoctohertz : prefixed_unit {}; -struct zeptohertz : prefixed_unit {}; -struct attohertz : prefixed_unit {}; -struct femtohertz : prefixed_unit {}; -struct picohertz : prefixed_unit {}; -struct nanohertz : prefixed_unit {}; -struct microhertz : prefixed_unit {}; -struct millihertz : prefixed_unit {}; -struct kilohertz : prefixed_unit {}; -struct megahertz : prefixed_unit {}; -struct gigahertz : prefixed_unit {}; -struct terahertz : prefixed_unit {}; -struct petahertz : prefixed_unit {}; -struct exahertz : prefixed_unit {}; -struct zettahertz : prefixed_unit {}; -struct yottahertz : prefixed_unit {}; - -struct dim_frequency : isq::dim_frequency {}; - -template U, Representation Rep = double> -using frequency = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Hz -constexpr auto operator"" _q_Hz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_Hz(long double l) { return frequency(l); } - -// yHz -constexpr auto operator"" _q_yHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_yHz(long double l) { return frequency(l); } - -// zHz -constexpr auto operator"" _q_zHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_zHz(long double l) { return frequency(l); } - -// aHz -constexpr auto operator"" _q_aHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_aHz(long double l) { return frequency(l); } - -// fHz -constexpr auto operator"" _q_fHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_fHz(long double l) { return frequency(l); } - -// pHz -constexpr auto operator"" _q_pHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_pHz(long double l) { return frequency(l); } - -// nHz -constexpr auto operator"" _q_nHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_nHz(long double l) { return frequency(l); } - -// uHz -constexpr auto operator"" _q_uHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_uHz(long double l) { return frequency(l); } - -// mHz -constexpr auto operator"" _q_mHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_mHz(long double l) { return frequency(l); } - -// kHz -constexpr auto operator"" _q_kHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_kHz(long double l) { return frequency(l); } - -// MHz -constexpr auto operator"" _q_MHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_MHz(long double l) { return frequency(l); } - -// GHz -constexpr auto operator"" _q_GHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_GHz(long double l) { return frequency(l); } - -// THz -constexpr auto operator"" _q_THz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_THz(long double l) { return frequency(l); } - -// PHz -constexpr auto operator"" _q_PHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_PHz(long double l) { return frequency(l); } - -// EHz -constexpr auto operator"" _q_EHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_EHz(long double l) { return frequency(l); } - -// ZHz -constexpr auto operator"" _q_ZHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_ZHz(long double l) { return frequency(l); } - -// YHz -constexpr auto operator"" _q_YHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_YHz(long double l) { return frequency(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace frequency_references { - -inline constexpr auto Hz = reference{}; -inline constexpr auto yHz = reference{}; -inline constexpr auto zHz = reference{}; -inline constexpr auto aHz = reference{}; -inline constexpr auto fHz = reference{}; -inline constexpr auto pHz = reference{}; -inline constexpr auto nHz = reference{}; -inline constexpr auto uHz = reference{}; -inline constexpr auto mHz = reference{}; -inline constexpr auto kHz = reference{}; -inline constexpr auto MHz = reference{}; -inline constexpr auto GHz = reference{}; -inline constexpr auto THz = reference{}; -inline constexpr auto PHz = reference{}; -inline constexpr auto EHz = reference{}; -inline constexpr auto ZHz = reference{}; -inline constexpr auto YHz = reference{}; - -} // namespace frequency_references - -namespace references { - -using namespace frequency_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline frequency { - -template -using Hz = units::isq::si::frequency; -template -using yHz = units::isq::si::frequency; -template -using zHz = units::isq::si::frequency; -template -using aHz = units::isq::si::frequency; -template -using fHz = units::isq::si::frequency; -template -using pHz = units::isq::si::frequency; -template -using nHz = units::isq::si::frequency; -template -using uHz = units::isq::si::frequency; -template -using mHz = units::isq::si::frequency; -template -using kHz = units::isq::si::frequency; -template -using MHz = units::isq::si::frequency; -template -using GHz = units::isq::si::frequency; -template -using THz = units::isq::si::frequency; -template -using PHz = units::isq::si::frequency; -template -using EHz = units::isq::si::frequency; -template -using ZHz = units::isq::si::frequency; -template -using YHz = units::isq::si::frequency; - -} // namespace units::aliases::isq::si::inline frequency - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/heat_capacity.h b/src/systems/si/include/units/isq/si/heat_capacity.h deleted file mode 100644 index 5ae30cfa..00000000 --- a/src/systems/si/include/units/isq/si/heat_capacity.h +++ /dev/null @@ -1,114 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include -#include - -namespace units::isq::si { - -struct joule_per_kelvin : derived_unit {}; -struct joule_per_kilogram_kelvin : derived_unit {}; -struct joule_per_mole_kelvin : derived_unit {}; - -struct dim_heat_capacity : - isq::dim_heat_capacity {}; -struct dim_specific_heat_capacity : - isq::dim_specific_heat_capacity {}; -struct dim_molar_heat_capacity : - isq::dim_molar_heat_capacity {}; - -template U, Representation Rep = double> -using heat_capacity = quantity; - -template U, Representation Rep = double> -using specific_heat_capacity = quantity; - -template U, Representation Rep = double> -using molar_heat_capacity = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// J/K -constexpr auto operator"" _q_J_per_K(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return heat_capacity(static_cast(l)); -} -constexpr auto operator"" _q_J_per_K(long double l) { return heat_capacity(l); } - -// J/(kg·K) -constexpr auto operator"" _q_J_per_kg_K(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return specific_heat_capacity(static_cast(l)); -} -constexpr auto operator"" _q_J_per_kg_K(long double l) -{ - return specific_heat_capacity(l); -} - -// J/(mol·K) -constexpr auto operator"" _q_J_per_mol_K(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return molar_heat_capacity(static_cast(l)); -} -constexpr auto operator"" _q_J_per_mol_K(long double l) -{ - return molar_heat_capacity(l); -} - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::heat_capacity { - -template -using J_per_K = units::isq::si::heat_capacity; -template -using J_per_kg_K = units::isq::si::specific_heat_capacity; -template -using J_per_mol_K = units::isq::si::molar_heat_capacity; - -} // namespace units::aliases::isq::si::heat_capacity - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/inductance.h b/src/systems/si/include/units/isq/si/inductance.h deleted file mode 100644 index c6a14a98..00000000 --- a/src/systems/si/include/units/isq/si/inductance.h +++ /dev/null @@ -1,281 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct henry : named_unit {}; - -struct yoctohenry : prefixed_unit {}; -struct zeptohenry : prefixed_unit {}; -struct attohenry : prefixed_unit {}; -struct femtohenry : prefixed_unit {}; -struct picohenry : prefixed_unit {}; -struct nanohenry : prefixed_unit {}; -struct microhenry : prefixed_unit {}; -struct millihenry : prefixed_unit {}; -struct kilohenry : prefixed_unit {}; -struct megahenry : prefixed_unit {}; -struct gigahenry : prefixed_unit {}; -struct terahenry : prefixed_unit {}; -struct petahenry : prefixed_unit {}; -struct exahenry : prefixed_unit {}; -struct zettahenry : prefixed_unit {}; -struct yottahenry : prefixed_unit {}; - -struct dim_inductance : isq::dim_inductance {}; - -template U, Representation Rep = double> -using inductance = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// H -constexpr auto operator"" _q_H(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_H(long double l) { return inductance(l); } - -// yH -constexpr auto operator"" _q_yH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_yH(long double l) { return inductance(l); } - -// zH -constexpr auto operator"" _q_zH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_zH(long double l) { return inductance(l); } - -// aH -constexpr auto operator"" _q_aH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_aH(long double l) { return inductance(l); } - -// fH -constexpr auto operator"" _q_fH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_fH(long double l) { return inductance(l); } - -// pH -constexpr auto operator"" _q_pH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_pH(long double l) { return inductance(l); } - -// nH -constexpr auto operator"" _q_nH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_nH(long double l) { return inductance(l); } - -// µH -constexpr auto operator"" _q_uH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_uH(long double l) { return inductance(l); } - -// mH -constexpr auto operator"" _q_mH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_mH(long double l) { return inductance(l); } - -// kH -constexpr auto operator"" _q_kH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_kH(long double l) { return inductance(l); } - -// MH -constexpr auto operator"" _q_MH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_MH(long double l) { return inductance(l); } - -// GH -constexpr auto operator"" _q_GH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_GH(long double l) { return inductance(l); } - -// TH -constexpr auto operator"" _q_TH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_TH(long double l) { return inductance(l); } - -// PH -constexpr auto operator"" _q_PH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_PH(long double l) { return inductance(l); } - -// EH -constexpr auto operator"" _q_EH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_EH(long double l) { return inductance(l); } - -// ZH -constexpr auto operator"" _q_ZH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_ZH(long double l) { return inductance(l); } - -// YH -constexpr auto operator"" _q_YH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_YH(long double l) { return inductance(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace inductance_references { - -inline constexpr auto H = reference{}; -inline constexpr auto yH = reference{}; -inline constexpr auto zH = reference{}; -inline constexpr auto aH = reference{}; -inline constexpr auto fH = reference{}; -inline constexpr auto pH = reference{}; -inline constexpr auto nH = reference{}; -inline constexpr auto uH = reference{}; -inline constexpr auto mH = reference{}; -inline constexpr auto kH = reference{}; -inline constexpr auto MH = reference{}; -inline constexpr auto GH = reference{}; -inline constexpr auto TH = reference{}; -inline constexpr auto PH = reference{}; -inline constexpr auto EH = reference{}; -inline constexpr auto ZH = reference{}; -inline constexpr auto YH = reference{}; - -} // namespace inductance_references - -namespace references { - -using namespace inductance_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline inductance { - -template -using H = units::isq::si::inductance; -template -using yH = units::isq::si::inductance; -template -using zH = units::isq::si::inductance; -template -using aH = units::isq::si::inductance; -template -using fH = units::isq::si::inductance; -template -using pH = units::isq::si::inductance; -template -using nH = units::isq::si::inductance; -template -using uH = units::isq::si::inductance; -template -using mH = units::isq::si::inductance; -template -using kH = units::isq::si::inductance; -template -using MH = units::isq::si::inductance; -template -using GH = units::isq::si::inductance; -template -using TH = units::isq::si::inductance; -template -using PH = units::isq::si::inductance; -template -using EH = units::isq::si::inductance; -template -using ZH = units::isq::si::inductance; -template -using YH = units::isq::si::inductance; - -} // namespace units::aliases::isq::si::inline inductance - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/length.h b/src/systems/si/include/units/isq/si/length.h deleted file mode 100644 index 6585ed92..00000000 --- a/src/systems/si/include/units/isq/si/length.h +++ /dev/null @@ -1,340 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct metre : named_unit {}; -struct yoctometre : prefixed_unit {}; -struct zeptometre : prefixed_unit {}; -struct attometre : prefixed_unit {}; -struct femtometre : prefixed_unit {}; -struct picometre : prefixed_unit {}; -struct nanometre : prefixed_unit {}; -struct micrometre : prefixed_unit {}; -struct millimetre : prefixed_unit {}; -struct centimetre : prefixed_unit {}; -struct decimetre : prefixed_unit {}; -struct decametre : prefixed_unit {}; -struct hectometre : prefixed_unit {}; -struct kilometre : prefixed_unit {}; -struct megametre : prefixed_unit {}; -struct gigametre : prefixed_unit {}; -struct terametre : prefixed_unit {}; -struct petametre : prefixed_unit {}; -struct exametre : prefixed_unit {}; -struct zettametre : prefixed_unit {}; -struct yottametre : prefixed_unit {}; - -struct astronomical_unit : named_scaled_unit(), metre> {}; - -struct dim_length : isq::dim_length {}; - -template U, Representation Rep = double> -using length = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// m -constexpr auto operator"" _q_m(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_m(long double l) { return length(l); } - -// ym -constexpr auto operator"" _q_ym(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_ym(long double l) { return length(l); } - -// zm -constexpr auto operator"" _q_zm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_zm(long double l) { return length(l); } - -// am -constexpr auto operator"" _q_am(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_am(long double l) { return length(l); } - -// fm -constexpr auto operator"" _q_fm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_fm(long double l) { return length(l); } - -// pm -constexpr auto operator"" _q_pm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_pm(long double l) { return length(l); } - -// nm -constexpr auto operator"" _q_nm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_nm(long double l) { return length(l); } - -// um -constexpr auto operator"" _q_um(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_um(long double l) { return length(l); } - -// mm -constexpr auto operator"" _q_mm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_mm(long double l) { return length(l); } - -// cm -constexpr auto operator"" _q_cm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_cm(long double l) { return length(l); } - -// dm -constexpr auto operator"" _q_dm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_dm(long double l) { return length(l); } - -// dam -constexpr auto operator"" _q_dam(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_dam(long double l) { return length(l); } - -// hm -constexpr auto operator"" _q_hm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_hm(long double l) { return length(l); } - -// km -constexpr auto operator"" _q_km(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_km(long double l) { return length(l); } - -// Mm -constexpr auto operator"" _q_Mm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_Mm(long double l) { return length(l); } - -// Gm -constexpr auto operator"" _q_Gm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_Gm(long double l) { return length(l); } - -// Tm -constexpr auto operator"" _q_Tm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_Tm(long double l) { return length(l); } - -// Pm -constexpr auto operator"" _q_Pm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_Pm(long double l) { return length(l); } - -// Em -constexpr auto operator"" _q_Em(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_Em(long double l) { return length(l); } - -// Zm -constexpr auto operator"" _q_Zm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_Zm(long double l) { return length(l); } - -// Ym -constexpr auto operator"" _q_Ym(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_Ym(long double l) { return length(l); } - -// au -constexpr auto operator"" _q_au(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_au(long double l) { return length(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace length_references { - -inline constexpr auto m = reference{}; -inline constexpr auto ym = reference{}; -inline constexpr auto zm = reference{}; -inline constexpr auto am = reference{}; -inline constexpr auto fm = reference{}; -inline constexpr auto pm = reference{}; -inline constexpr auto nm = reference{}; -inline constexpr auto um = reference{}; -inline constexpr auto mm = reference{}; -inline constexpr auto cm = reference{}; -inline constexpr auto dm = reference{}; -inline constexpr auto dam = reference{}; -inline constexpr auto hm = reference{}; -inline constexpr auto km = reference{}; -inline constexpr auto Mm = reference{}; -inline constexpr auto Gm = reference{}; -inline constexpr auto Tm = reference{}; -inline constexpr auto Pm = reference{}; -inline constexpr auto Em = reference{}; -inline constexpr auto Zm = reference{}; -inline constexpr auto Ym = reference{}; -inline constexpr auto au = reference{}; - -} // namespace length_references - -namespace references { - -using namespace length_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline length { - -template -using m = units::isq::si::length; -template -using ym = units::isq::si::length; -template -using zm = units::isq::si::length; -template -using am = units::isq::si::length; -template -using fm = units::isq::si::length; -template -using pm = units::isq::si::length; -template -using nm = units::isq::si::length; -template -using um = units::isq::si::length; -template -using mm = units::isq::si::length; -template -using cm = units::isq::si::length; -template -using dm = units::isq::si::length; -template -using dam = units::isq::si::length; -template -using hm = units::isq::si::length; -template -using km = units::isq::si::length; -template -using Mm = units::isq::si::length; -template -using Gm = units::isq::si::length; -template -using Tm = units::isq::si::length; -template -using Pm = units::isq::si::length; -template -using Em = units::isq::si::length; -template -using Zm = units::isq::si::length; -template -using Ym = units::isq::si::length; -template -using au = units::isq::si::length; - -} // namespace units::aliases::isq::si::inline length - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/luminance.h b/src/systems/si/include/units/isq/si/luminance.h deleted file mode 100644 index 48f01073..00000000 --- a/src/systems/si/include/units/isq/si/luminance.h +++ /dev/null @@ -1,70 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct candela_per_metre_sq : derived_unit {}; -struct dim_luminance : isq::dim_luminance {}; - -template U, Representation Rep = double> -using luminance = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// cd/m² -constexpr auto operator"" _q_cd_per_m2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminance(static_cast(l)); -} -constexpr auto operator"" _q_cd_per_m2(long double l) { return luminance(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline luminance { - -template -using cd_per_m2 = units::isq::si::luminance; - -} // namespace units::aliases::isq::si::inline luminance - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/luminous_flux.h b/src/systems/si/include/units/isq/si/luminous_flux.h deleted file mode 100644 index c35f5e8c..00000000 --- a/src/systems/si/include/units/isq/si/luminous_flux.h +++ /dev/null @@ -1,90 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct lumen : named_unit {}; - -struct dim_luminous_flux : - isq::dim_luminous_flux> {}; - -template U, Representation Rep = double> -using luminous_flux = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// lm -constexpr auto operator"" _q_lm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_flux(static_cast(l)); -} -constexpr auto operator"" _q_lm(long double l) { return luminous_flux(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace luminous_flux_references { - -inline constexpr auto lm = reference{}; - -} // namespace luminous_flux_references - -namespace references { - -using namespace luminous_flux_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline luminous_flux { - -template -using lm = units::isq::si::luminous_flux; - -} // namespace units::aliases::isq::si::inline luminous_flux - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/luminous_intensity.h b/src/systems/si/include/units/isq/si/luminous_intensity.h deleted file mode 100644 index 38e658f0..00000000 --- a/src/systems/si/include/units/isq/si/luminous_intensity.h +++ /dev/null @@ -1,327 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct candela : named_unit {}; -struct yoctocandela : prefixed_unit {}; -struct zeptocandela : prefixed_unit {}; -struct attocandela : prefixed_unit {}; -struct femtocandela : prefixed_unit {}; -struct picocandela : prefixed_unit {}; -struct nanocandela : prefixed_unit {}; -struct microcandela : prefixed_unit {}; -struct millicandela : prefixed_unit {}; -struct centicandela : prefixed_unit {}; -struct decicandela : prefixed_unit {}; -struct decacandela : prefixed_unit {}; -struct hectocandela : prefixed_unit {}; -struct kilocandela : prefixed_unit {}; -struct megacandela : prefixed_unit {}; -struct gigacandela : prefixed_unit {}; -struct teracandela : prefixed_unit {}; -struct petacandela : prefixed_unit {}; -struct exacandela : prefixed_unit {}; -struct zettacandela : prefixed_unit {}; -struct yottacandela : prefixed_unit {}; - -struct dim_luminous_intensity : isq::dim_luminous_intensity {}; - -template U, Representation Rep = double> -using luminous_intensity = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// cd -constexpr auto operator"" _q_cd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_cd(long double l) { return luminous_intensity(l); } - -// ycd -constexpr auto operator"" _q_ycd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_ycd(long double l) { return luminous_intensity(l); } - -// zcd -constexpr auto operator"" _q_zcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_zcd(long double l) { return luminous_intensity(l); } - -// acd -constexpr auto operator"" _q_acd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_acd(long double l) { return luminous_intensity(l); } - -// fcd -constexpr auto operator"" _q_fcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_fcd(long double l) { return luminous_intensity(l); } - -// pcd -constexpr auto operator"" _q_pcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_pcd(long double l) { return luminous_intensity(l); } - -// ncd -constexpr auto operator"" _q_ncd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_ncd(long double l) { return luminous_intensity(l); } - -// ucd -constexpr auto operator"" _q_ucd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_ucd(long double l) { return luminous_intensity(l); } - -// mcd -constexpr auto operator"" _q_mcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_mcd(long double l) { return luminous_intensity(l); } - -// ccd -constexpr auto operator"" _q_ccd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_ccd(long double l) { return luminous_intensity(l); } - -// dcd -constexpr auto operator"" _q_dcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_dcd(long double l) { return luminous_intensity(l); } - -// dacd -constexpr auto operator"" _q_dacd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_dacd(long double l) { return luminous_intensity(l); } - -// hcd -constexpr auto operator"" _q_hcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_hcd(long double l) { return luminous_intensity(l); } - -// kcd -constexpr auto operator"" _q_kcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_kcd(long double l) { return luminous_intensity(l); } - -// Mcd -constexpr auto operator"" _q_Mcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_Mcd(long double l) { return luminous_intensity(l); } - -// Gcd -constexpr auto operator"" _q_Gcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_Gcd(long double l) { return luminous_intensity(l); } - -// Tcd -constexpr auto operator"" _q_Tcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_Tcd(long double l) { return luminous_intensity(l); } - -// Pcd -constexpr auto operator"" _q_Pcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_Pcd(long double l) { return luminous_intensity(l); } - -// Ecd -constexpr auto operator"" _q_Ecd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_Ecd(long double l) { return luminous_intensity(l); } - -// Zcd -constexpr auto operator"" _q_Zcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_Zcd(long double l) { return luminous_intensity(l); } - -// Ycd -constexpr auto operator"" _q_Ycd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_Ycd(long double l) { return luminous_intensity(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace luminous_intensity_references { - -inline constexpr auto cd = reference{}; -inline constexpr auto ycd = reference{}; -inline constexpr auto zcd = reference{}; -inline constexpr auto acd = reference{}; -inline constexpr auto fcd = reference{}; -inline constexpr auto pcd = reference{}; -inline constexpr auto ncd = reference{}; -inline constexpr auto ucd = reference{}; -inline constexpr auto mcd = reference{}; -inline constexpr auto ccd = reference{}; -inline constexpr auto dcd = reference{}; -inline constexpr auto dacd = reference{}; -inline constexpr auto hcd = reference{}; -inline constexpr auto kcd = reference{}; -inline constexpr auto Mcd = reference{}; -inline constexpr auto Gcd = reference{}; -inline constexpr auto Tcd = reference{}; -inline constexpr auto Pcd = reference{}; -inline constexpr auto Ecd = reference{}; -inline constexpr auto Zcd = reference{}; -inline constexpr auto Ycd = reference{}; - -} // namespace luminous_intensity_references - -namespace references { - -using namespace luminous_intensity_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::luminous_intensity { - -template -using cd = units::isq::si::luminous_intensity; -template -using ycd = units::isq::si::luminous_intensity; -template -using zcd = units::isq::si::luminous_intensity; -template -using acd = units::isq::si::luminous_intensity; -template -using fcd = units::isq::si::luminous_intensity; -template -using pcd = units::isq::si::luminous_intensity; -template -using ncd = units::isq::si::luminous_intensity; -template -using ucd = units::isq::si::luminous_intensity; -template -using mcd = units::isq::si::luminous_intensity; -template -using ccd = units::isq::si::luminous_intensity; -template -using dcd = units::isq::si::luminous_intensity; -template -using dacd = units::isq::si::luminous_intensity; -template -using hcd = units::isq::si::luminous_intensity; -template -using kcd = units::isq::si::luminous_intensity; -template -using Mcd = units::isq::si::luminous_intensity; -template -using Gcd = units::isq::si::luminous_intensity; -template -using Tcd = units::isq::si::luminous_intensity; -template -using Pcd = units::isq::si::luminous_intensity; -template -using Ecd = units::isq::si::luminous_intensity; -template -using Zcd = units::isq::si::luminous_intensity; -template -using Ycd = units::isq::si::luminous_intensity; - -} // namespace units::aliases::isq::si::luminous_intensity - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/magnetic_flux.h b/src/systems/si/include/units/isq/si/magnetic_flux.h deleted file mode 100644 index 77b1410c..00000000 --- a/src/systems/si/include/units/isq/si/magnetic_flux.h +++ /dev/null @@ -1,281 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct weber : named_unit {}; - -struct yoctoweber : prefixed_unit {}; -struct zeptoweber : prefixed_unit {}; -struct attoweber : prefixed_unit {}; -struct femtoweber : prefixed_unit {}; -struct picoweber : prefixed_unit {}; -struct nanoweber : prefixed_unit {}; -struct microweber : prefixed_unit {}; -struct milliweber : prefixed_unit {}; -struct kiloweber : prefixed_unit {}; -struct megaweber : prefixed_unit {}; -struct gigaweber : prefixed_unit {}; -struct teraweber : prefixed_unit {}; -struct petaweber : prefixed_unit {}; -struct exaweber : prefixed_unit {}; -struct zettaweber : prefixed_unit {}; -struct yottaweber : prefixed_unit {}; - -struct dim_magnetic_flux : isq::dim_magnetic_flux {}; - -template U, Representation Rep = double> -using magnetic_flux = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Wb -constexpr auto operator"" _q_Wb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_Wb(long double l) { return magnetic_flux(l); } - -// yWb -constexpr auto operator"" _q_yWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_yWb(long double l) { return magnetic_flux(l); } - -// zWb -constexpr auto operator"" _q_zWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_zWb(long double l) { return magnetic_flux(l); } - -// aWb -constexpr auto operator"" _q_aWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_aWb(long double l) { return magnetic_flux(l); } - -// fWb -constexpr auto operator"" _q_fWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_fWb(long double l) { return magnetic_flux(l); } - -// pWb -constexpr auto operator"" _q_pWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_pWb(long double l) { return magnetic_flux(l); } - -// nWb -constexpr auto operator"" _q_nWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_nWb(long double l) { return magnetic_flux(l); } - -// µWb -constexpr auto operator"" _q_uWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_uWb(long double l) { return magnetic_flux(l); } - -// mWb -constexpr auto operator"" _q_mWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_mWb(long double l) { return magnetic_flux(l); } - -// kWb -constexpr auto operator"" _q_kWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_kWb(long double l) { return magnetic_flux(l); } - -// MWb -constexpr auto operator"" _q_MWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_MWb(long double l) { return magnetic_flux(l); } - -// GWb -constexpr auto operator"" _q_GWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_GWb(long double l) { return magnetic_flux(l); } - -// TWb -constexpr auto operator"" _q_TWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_TWb(long double l) { return magnetic_flux(l); } - -// PWb -constexpr auto operator"" _q_PWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_PWb(long double l) { return magnetic_flux(l); } - -// EWb -constexpr auto operator"" _q_EWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_EWb(long double l) { return magnetic_flux(l); } - -// ZWb -constexpr auto operator"" _q_ZWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_ZWb(long double l) { return magnetic_flux(l); } - -// YWb -constexpr auto operator"" _q_YWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_YWb(long double l) { return magnetic_flux(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace magnetic_flux_references { - -inline constexpr auto Wb = reference{}; -inline constexpr auto yWb = reference{}; -inline constexpr auto zWb = reference{}; -inline constexpr auto aWb = reference{}; -inline constexpr auto fWb = reference{}; -inline constexpr auto pWb = reference{}; -inline constexpr auto nWb = reference{}; -inline constexpr auto uWb = reference{}; -inline constexpr auto mWb = reference{}; -inline constexpr auto kWb = reference{}; -inline constexpr auto MWb = reference{}; -inline constexpr auto GWb = reference{}; -inline constexpr auto TWb = reference{}; -inline constexpr auto PWb = reference{}; -inline constexpr auto EWb = reference{}; -inline constexpr auto ZWb = reference{}; -inline constexpr auto YWb = reference{}; - -} // namespace magnetic_flux_references - -namespace references { - -using namespace magnetic_flux_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline magnetic_flux { - -template -using Wb = units::isq::si::magnetic_flux; -template -using yWb = units::isq::si::magnetic_flux; -template -using zWb = units::isq::si::magnetic_flux; -template -using aWb = units::isq::si::magnetic_flux; -template -using fWb = units::isq::si::magnetic_flux; -template -using pWb = units::isq::si::magnetic_flux; -template -using nWb = units::isq::si::magnetic_flux; -template -using uWb = units::isq::si::magnetic_flux; -template -using mWb = units::isq::si::magnetic_flux; -template -using kWb = units::isq::si::magnetic_flux; -template -using MWb = units::isq::si::magnetic_flux; -template -using GWb = units::isq::si::magnetic_flux; -template -using TWb = units::isq::si::magnetic_flux; -template -using PWb = units::isq::si::magnetic_flux; -template -using EWb = units::isq::si::magnetic_flux; -template -using ZWb = units::isq::si::magnetic_flux; -template -using YWb = units::isq::si::magnetic_flux; - -} // namespace units::aliases::isq::si::inline magnetic_flux - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/magnetic_induction.h b/src/systems/si/include/units/isq/si/magnetic_induction.h deleted file mode 100644 index 529a7f9a..00000000 --- a/src/systems/si/include/units/isq/si/magnetic_induction.h +++ /dev/null @@ -1,297 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include -#include - -namespace units::isq::si { - -struct tesla : named_unit {}; - -struct yoctotesla : prefixed_unit {}; -struct zeptotesla : prefixed_unit {}; -struct attotesla : prefixed_unit {}; -struct femtotesla : prefixed_unit {}; -struct picotesla : prefixed_unit {}; -struct nanotesla : prefixed_unit {}; -struct microtesla : prefixed_unit {}; -struct millitesla : prefixed_unit {}; -struct kilotesla : prefixed_unit {}; -struct megatesla : prefixed_unit {}; -struct gigatesla : prefixed_unit {}; -struct teratesla : prefixed_unit {}; -struct petatesla : prefixed_unit {}; -struct exatesla : prefixed_unit {}; -struct zettatesla : prefixed_unit {}; -struct yottatesla : prefixed_unit {}; - -struct gauss : named_scaled_unit(), tesla> {}; - -struct dim_magnetic_induction : - isq::dim_magnetic_induction {}; - -template U, Representation Rep = double> -using magnetic_induction = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// T -constexpr auto operator"" _q_T(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_T(long double l) { return magnetic_induction(l); } - -// yT -constexpr auto operator"" _q_yT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_yT(long double l) { return magnetic_induction(l); } - -// zT -constexpr auto operator"" _q_zT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_zT(long double l) { return magnetic_induction(l); } - -// aT -constexpr auto operator"" _q_aT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_aT(long double l) { return magnetic_induction(l); } - -// fT -constexpr auto operator"" _q_fT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_fT(long double l) { return magnetic_induction(l); } - -// pT -constexpr auto operator"" _q_pT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_pT(long double l) { return magnetic_induction(l); } - -// nT -constexpr auto operator"" _q_nT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_nT(long double l) { return magnetic_induction(l); } - -// µT -constexpr auto operator"" _q_uT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_uT(long double l) { return magnetic_induction(l); } - -// mT -constexpr auto operator"" _q_mT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_mT(long double l) { return magnetic_induction(l); } - -// kT -constexpr auto operator"" _q_kT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_kT(long double l) { return magnetic_induction(l); } - -// MT -constexpr auto operator"" _q_MT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_MT(long double l) { return magnetic_induction(l); } - -// GT -constexpr auto operator"" _q_GT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_GT(long double l) { return magnetic_induction(l); } - -// TT -constexpr auto operator"" _q_TT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_TT(long double l) { return magnetic_induction(l); } - -// PT -constexpr auto operator"" _q_PT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_PT(long double l) { return magnetic_induction(l); } - -// ET -constexpr auto operator"" _q_ET(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_ET(long double l) { return magnetic_induction(l); } - -// ZT -constexpr auto operator"" _q_ZT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_ZT(long double l) { return magnetic_induction(l); } - -// YT -constexpr auto operator"" _q_YT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_YT(long double l) { return magnetic_induction(l); } - -// G -constexpr auto operator"" _q_G(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_G(long double l) { return magnetic_induction(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace magnetic_induction_references { - -inline constexpr auto T = reference{}; -inline constexpr auto yT = reference{}; -inline constexpr auto zT = reference{}; -inline constexpr auto aT = reference{}; -inline constexpr auto fT = reference{}; -inline constexpr auto pT = reference{}; -inline constexpr auto nT = reference{}; -inline constexpr auto uT = reference{}; -inline constexpr auto mT = reference{}; -inline constexpr auto kT = reference{}; -inline constexpr auto MT = reference{}; -inline constexpr auto GT = reference{}; -inline constexpr auto TT = reference{}; -inline constexpr auto PT = reference{}; -inline constexpr auto ET = reference{}; -inline constexpr auto ZT = reference{}; -inline constexpr auto YT = reference{}; -inline constexpr auto G = reference{}; - -} // namespace magnetic_induction_references - -namespace references { - -using namespace magnetic_induction_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline magnetic_induction { - -template -using T = units::isq::si::magnetic_induction; -template -using yT = units::isq::si::magnetic_induction; -template -using zT = units::isq::si::magnetic_induction; -template -using aT = units::isq::si::magnetic_induction; -template -using fT = units::isq::si::magnetic_induction; -template -using pT = units::isq::si::magnetic_induction; -template -using nT = units::isq::si::magnetic_induction; -template -using uT = units::isq::si::magnetic_induction; -template -using mT = units::isq::si::magnetic_induction; -template -using kT = units::isq::si::magnetic_induction; -template -using MT = units::isq::si::magnetic_induction; -template -using GT = units::isq::si::magnetic_induction; -template -using TT = units::isq::si::magnetic_induction; -template -using PT = units::isq::si::magnetic_induction; -template -using ET = units::isq::si::magnetic_induction; -template -using ZT = units::isq::si::magnetic_induction; -template -using YT = units::isq::si::magnetic_induction; -template -using G = units::isq::si::magnetic_induction; - -} // namespace units::aliases::isq::si::inline magnetic_induction - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/mass.h b/src/systems/si/include/units/isq/si/mass.h deleted file mode 100644 index d57069d8..00000000 --- a/src/systems/si/include/units/isq/si/mass.h +++ /dev/null @@ -1,595 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct gram : named_unit {}; -struct yoctogram : prefixed_unit {}; -struct zeptogram : prefixed_unit {}; -struct attogram : prefixed_unit {}; -struct femtogram : prefixed_unit {}; -struct picogram : prefixed_unit {}; -struct nanogram : prefixed_unit {}; -struct microgram : prefixed_unit {}; -struct milligram : prefixed_unit {}; -struct centigram : prefixed_unit {}; -struct decigram : prefixed_unit {}; -struct decagram : prefixed_unit {}; -struct hectogram : prefixed_unit {}; -struct kilogram : prefixed_unit {}; -struct megagram : prefixed_unit {}; -struct gigagram : prefixed_unit {}; -struct teragram : prefixed_unit {}; -struct petagram : prefixed_unit {}; -struct exagram : prefixed_unit {}; -struct zettagram : prefixed_unit {}; -struct yottagram : prefixed_unit {}; - -struct tonne : alias_unit {}; -struct yoctotonne : prefixed_alias_unit {}; -struct zeptotonne : prefixed_alias_unit {}; -struct attotonne : prefixed_alias_unit {}; -struct femtotonne : prefixed_alias_unit {}; -struct picotonne : prefixed_alias_unit {}; -struct nanotonne : prefixed_alias_unit {}; -struct microtonne : prefixed_alias_unit {}; -struct millitonne : prefixed_alias_unit {}; -struct centitonne : prefixed_unit {}; -struct decitonne : prefixed_unit {}; -struct decatonne : prefixed_unit {}; -struct hectotonne : prefixed_unit {}; -struct kilotonne : prefixed_alias_unit {}; -struct megatonne : prefixed_alias_unit {}; -struct gigatonne : prefixed_alias_unit {}; -struct teratonne : prefixed_alias_unit {}; -struct petatonne : prefixed_alias_unit {}; -struct exatonne : prefixed_alias_unit {}; -struct zettatonne : prefixed_unit {}; -struct yottatonne : prefixed_unit {}; - -struct dalton : - named_scaled_unit() * mag_power<10, -27>(), - kilogram> {}; - -struct dim_mass : isq::dim_mass {}; - -template U, Representation Rep = double> -using mass = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// g -constexpr auto operator"" _q_g(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_g(long double l) { return mass(l); } - -// yg -constexpr auto operator"" _q_yg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_yg(long double l) { return mass(l); } - -// zg -constexpr auto operator"" _q_zg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_zg(long double l) { return mass(l); } - -// ag -constexpr auto operator"" _q_ag(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_ag(long double l) { return mass(l); } - -// fg -constexpr auto operator"" _q_fg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_fg(long double l) { return mass(l); } - -// pg -constexpr auto operator"" _q_pg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_pg(long double l) { return mass(l); } - -// ng -constexpr auto operator"" _q_ng(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_ng(long double l) { return mass(l); } - -// ug -constexpr auto operator"" _q_ug(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_ug(long double l) { return mass(l); } - -// mg -constexpr auto operator"" _q_mg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_mg(long double l) { return mass(l); } - -// cg -constexpr auto operator"" _q_cg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_cg(long double l) { return mass(l); } - -// dg -constexpr auto operator"" _q_dg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_dg(long double l) { return mass(l); } - -// dag -constexpr auto operator"" _q_dag(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_dag(long double l) { return mass(l); } - -// hg -constexpr auto operator"" _q_hg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_hg(long double l) { return mass(l); } - -// kg -constexpr auto operator"" _q_kg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_kg(long double l) { return mass(l); } - -// Mg -constexpr auto operator"" _q_Mg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Mg(long double l) { return mass(l); } - -// Gg -constexpr auto operator"" _q_Gg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Gg(long double l) { return mass(l); } - -// Tg -constexpr auto operator"" _q_Tg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Tg(long double l) { return mass(l); } - -// Pg -constexpr auto operator"" _q_Pg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Pg(long double l) { return mass(l); } - -// Eg -constexpr auto operator"" _q_Eg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Eg(long double l) { return mass(l); } - -// Zg -constexpr auto operator"" _q_Zg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Zg(long double l) { return mass(l); } - -// Yg -constexpr auto operator"" _q_Yg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Yg(long double l) { return mass(l); } - -// t -constexpr auto operator"" _q_t(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_t(long double l) { return mass(l); } - -// yt -constexpr auto operator"" _q_yt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_yt(long double l) { return mass(l); } - -// zt -constexpr auto operator"" _q_zt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_zt(long double l) { return mass(l); } - -// at -constexpr auto operator"" _q_at(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_at(long double l) { return mass(l); } - -// TODO Collides with foot -// ft -// constexpr auto operator"" _q_ft(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return -// mass(static_cast(l)); } constexpr auto operator"" _q_ft(long double l) { -// return mass(l); } - -// pt -constexpr auto operator"" _q_pt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_pt(long double l) { return mass(l); } - -// nt -constexpr auto operator"" _q_nt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_nt(long double l) { return mass(l); } - -// ut -constexpr auto operator"" _q_ut(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_ut(long double l) { return mass(l); } - -// mt -constexpr auto operator"" _q_mt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_mt(long double l) { return mass(l); } - -// ct -constexpr auto operator"" _q_ct(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_ct(long double l) { return mass(l); } - -// dt -constexpr auto operator"" _q_dt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_dt(long double l) { return mass(l); } - -// dat -constexpr auto operator"" _q_dat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_dat(long double l) { return mass(l); } - -// ht -constexpr auto operator"" _q_ht(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_ht(long double l) { return mass(l); } - -// kt -constexpr auto operator"" _q_kt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_kt(long double l) { return mass(l); } - -// Mt -constexpr auto operator"" _q_Mt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Mt(long double l) { return mass(l); } - -// Gt -constexpr auto operator"" _q_Gt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Gt(long double l) { return mass(l); } - -// Tt -constexpr auto operator"" _q_Tt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Tt(long double l) { return mass(l); } - -// Pt -constexpr auto operator"" _q_Pt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Pt(long double l) { return mass(l); } - -// Et -constexpr auto operator"" _q_Et(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Et(long double l) { return mass(l); } - -// Zt -constexpr auto operator"" _q_Zt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Zt(long double l) { return mass(l); } - -// Yt -constexpr auto operator"" _q_Yt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Yt(long double l) { return mass(l); } - -// Da -constexpr auto operator"" _q_Da(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Da(long double l) { return mass(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace mass_references { - -inline constexpr auto g = reference{}; -inline constexpr auto yg = reference{}; -inline constexpr auto zg = reference{}; -inline constexpr auto ag = reference{}; -inline constexpr auto fg = reference{}; -inline constexpr auto pg = reference{}; -inline constexpr auto ng = reference{}; -inline constexpr auto ug = reference{}; -inline constexpr auto mg = reference{}; -inline constexpr auto cg = reference{}; -inline constexpr auto dg = reference{}; -inline constexpr auto dag = reference{}; -inline constexpr auto hg = reference{}; -inline constexpr auto kg = reference{}; -inline constexpr auto Mg = reference{}; -inline constexpr auto Gg = reference{}; -inline constexpr auto Tg = reference{}; -inline constexpr auto Pg = reference{}; -inline constexpr auto Eg = reference{}; -inline constexpr auto Zg = reference{}; -inline constexpr auto Yg = reference{}; - -inline constexpr auto t = reference{}; -inline constexpr auto yt = reference{}; -inline constexpr auto zt = reference{}; -inline constexpr auto at = reference{}; -inline constexpr auto ft = reference{}; -inline constexpr auto pt = reference{}; -inline constexpr auto nt = reference{}; -inline constexpr auto ut = reference{}; -inline constexpr auto mt = reference{}; -inline constexpr auto ct = reference{}; -inline constexpr auto dt = reference{}; -inline constexpr auto dat = reference{}; -inline constexpr auto ht = reference{}; -inline constexpr auto kt = reference{}; -inline constexpr auto Mt = reference{}; -inline constexpr auto Gt = reference{}; -inline constexpr auto Tt = reference{}; -inline constexpr auto Pt = reference{}; -inline constexpr auto Et = reference{}; -inline constexpr auto Zt = reference{}; -inline constexpr auto Yt = reference{}; -inline constexpr auto Da = reference{}; - -} // namespace mass_references - -namespace references { - -using namespace mass_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline mass { - -template -using g = units::isq::si::mass; -template -using yg = units::isq::si::mass; -template -using zg = units::isq::si::mass; -template -using ag = units::isq::si::mass; -template -using fg = units::isq::si::mass; -template -using pg = units::isq::si::mass; -template -using ng = units::isq::si::mass; -template -using ug = units::isq::si::mass; -template -using mg = units::isq::si::mass; -template -using cg = units::isq::si::mass; -template -using dg = units::isq::si::mass; -template -using dag = units::isq::si::mass; -template -using hg = units::isq::si::mass; -template -using kg = units::isq::si::mass; -template -using Mg = units::isq::si::mass; -template -using Gg = units::isq::si::mass; -template -using Tg = units::isq::si::mass; -template -using Pg = units::isq::si::mass; -template -using Eg = units::isq::si::mass; -template -using Zg = units::isq::si::mass; -template -using Yg = units::isq::si::mass; - -template -using t = units::isq::si::mass; -template -using yt = units::isq::si::mass; -template -using zt = units::isq::si::mass; -template -using at = units::isq::si::mass; -template -using ft = units::isq::si::mass; -template -using pt = units::isq::si::mass; -template -using nt = units::isq::si::mass; -template -using ut = units::isq::si::mass; -template -using mt = units::isq::si::mass; -template -using ct = units::isq::si::mass; -template -using dt = units::isq::si::mass; -template -using dat = units::isq::si::mass; -template -using ht = units::isq::si::mass; -template -using kt = units::isq::si::mass; -template -using Mt = units::isq::si::mass; -template -using Gt = units::isq::si::mass; -template -using Tt = units::isq::si::mass; -template -using Pt = units::isq::si::mass; -template -using Et = units::isq::si::mass; -template -using Zt = units::isq::si::mass; -template -using Yt = units::isq::si::mass; -template -using Da = units::isq::si::mass; - -} // namespace units::aliases::isq::si::inline mass - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/molar_energy.h b/src/systems/si/include/units/isq/si/molar_energy.h deleted file mode 100644 index 02cb9072..00000000 --- a/src/systems/si/include/units/isq/si/molar_energy.h +++ /dev/null @@ -1,73 +0,0 @@ -// The MIT License (MIT) -// -// Hopyright (c) 2018 Mateusz Pusz -// -// 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 SOHTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OH ANY KIND, EXPRESS OR -// IMPLIED, INHLUDING BUT NOT LIMITED TO THE WARRANTIES OH MERHHANTABILITY, -// HITNESS HOR A PARTIHULAR PURPOSE AND NONINHRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR HOPYRIGHT HOLDERS BE LIABLE HOR ANY HLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN AHTION OH HONTRAHT, TORT OR OTHERWISE, ARISING HROM, -// OUT OH OR IN HONNEHTION WITH THE SOHTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOHTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct joule_per_mole : derived_unit {}; - -struct dim_molar_energy : - isq::dim_molar_energy {}; - -template U, Representation Rep = double> -using molar_energy = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// J/mol -constexpr auto operator"" _q_J_per_mol(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return molar_energy(static_cast(l)); -} -constexpr auto operator"" _q_J_per_mol(long double l) { return molar_energy(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline molar_energy { - -template -using J_per_mol = units::isq::si::molar_energy; - -} // namespace units::aliases::isq::si::inline molar_energy - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/momentum.h b/src/systems/si/include/units/isq/si/momentum.h deleted file mode 100644 index 46446c92..00000000 --- a/src/systems/si/include/units/isq/si/momentum.h +++ /dev/null @@ -1,70 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct kilogram_metre_per_second : derived_unit {}; -struct dim_momentum : isq::dim_momentum {}; - -template U, Representation Rep = double> -using momentum = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// kg*m/s -constexpr auto operator"" _q_kg_m_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return momentum(static_cast(l)); -} -constexpr auto operator"" _q_kg_m_per_s(long double l) { return momentum(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline momentum { - -template -using kg_m_per_s = units::isq::si::momentum; - -} // namespace units::aliases::isq::si::inline momentum - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/permeability.h b/src/systems/si/include/units/isq/si/permeability.h deleted file mode 100644 index 5b961b21..00000000 --- a/src/systems/si/include/units/isq/si/permeability.h +++ /dev/null @@ -1,71 +0,0 @@ -// The MIT License (MIT) -// -// Hopyright (c) 2018 Mateusz Pusz -// -// 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 SOHTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OH ANY KIND, EXPRESS OR -// IMPLIED, INHLUDING BUT NOT LIMITED TO THE WARRANTIES OH MERHHANTABILITY, -// HITNESS HOR A PARTIHULAR PURPOSE AND NONINHRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR HOPYRIGHT HOLDERS BE LIABLE HOR ANY HLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN AHTION OH HONTRAHT, TORT OR OTHERWISE, ARISING HROM, -// OUT OH OR IN HONNEHTION WITH THE SOHTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOHTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct henry_per_metre : derived_unit {}; - -struct dim_permeability : isq::dim_permeability {}; - -template U, Representation Rep = double> -using permeability = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// H/m -constexpr auto operator"" _q_H_per_m(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return permeability(static_cast(l)); -} -constexpr auto operator"" _q_H_per_m(long double l) { return permeability(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline permeability { - -template -using H_per_m = units::isq::si::permeability; - -} // namespace units::aliases::isq::si::inline permeability - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/permittivity.h b/src/systems/si/include/units/isq/si/permittivity.h deleted file mode 100644 index cd99be6c..00000000 --- a/src/systems/si/include/units/isq/si/permittivity.h +++ /dev/null @@ -1,71 +0,0 @@ -// The MIT License (MIT) -// -// Fopyright (c) 2018 Mateusz Pusz -// -// 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, INFLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERFHANTABILITY, -// FITNESS FOR A PARTIFULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR FOPYRIGHT HOLDERS BE LIABLE FOR ANY FLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN AFTION OF FONTRAFT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN FONNEFTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct farad_per_metre : derived_unit {}; - -struct dim_permittivity : isq::dim_permittivity {}; - -template U, Representation Rep = double> -using permittivity = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// F/m -constexpr auto operator"" _q_F_per_m(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return permittivity(static_cast(l)); -} -constexpr auto operator"" _q_F_per_m(long double l) { return permittivity(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline permittivity { - -template -using F_per_m = units::isq::si::permittivity; - -} // namespace units::aliases::isq::si::inline permittivity - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/power.h b/src/systems/si/include/units/isq/si/power.h deleted file mode 100644 index d95d5c30..00000000 --- a/src/systems/si/include/units/isq/si/power.h +++ /dev/null @@ -1,280 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct watt : named_unit {}; -struct yoctowatt : prefixed_unit {}; -struct zeptowatt : prefixed_unit {}; -struct attowatt : prefixed_unit {}; -struct femtowatt : prefixed_unit {}; -struct picowatt : prefixed_unit {}; -struct nanowatt : prefixed_unit {}; -struct microwatt : prefixed_unit {}; -struct milliwatt : prefixed_unit {}; -struct kilowatt : prefixed_unit {}; -struct megawatt : prefixed_unit {}; -struct gigawatt : prefixed_unit {}; -struct terawatt : prefixed_unit {}; -struct petawatt : prefixed_unit {}; -struct exawatt : prefixed_unit {}; -struct zettawatt : prefixed_unit {}; -struct yottawatt : prefixed_unit {}; - -struct dim_power : isq::dim_power {}; - -template U, Representation Rep = double> -using power = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// W -constexpr auto operator"" _q_W(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_W(long double l) { return power(l); } - -// yW -constexpr auto operator"" _q_yW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_yW(long double l) { return power(l); } - -// zW -constexpr auto operator"" _q_zW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_zW(long double l) { return power(l); } - -// aW -constexpr auto operator"" _q_aW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_aW(long double l) { return power(l); } - -// fW -constexpr auto operator"" _q_fW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_fW(long double l) { return power(l); } - -// pW -constexpr auto operator"" _q_pW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_pW(long double l) { return power(l); } - -// nW -constexpr auto operator"" _q_nW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_nW(long double l) { return power(l); } - -// uW -constexpr auto operator"" _q_uW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_uW(long double l) { return power(l); } - -// mW -constexpr auto operator"" _q_mW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_mW(long double l) { return power(l); } - -// kW -constexpr auto operator"" _q_kW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_kW(long double l) { return power(l); } - -// MW -constexpr auto operator"" _q_MW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_MW(long double l) { return power(l); } - -// GW -constexpr auto operator"" _q_GW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_GW(long double l) { return power(l); } - -// TW -constexpr auto operator"" _q_TW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_TW(long double l) { return power(l); } - -// PW -constexpr auto operator"" _q_PW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_PW(long double l) { return power(l); } - -// EW -constexpr auto operator"" _q_EW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_EW(long double l) { return power(l); } - -// ZW -constexpr auto operator"" _q_ZW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_ZW(long double l) { return power(l); } - -// YW -constexpr auto operator"" _q_YW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_YW(long double l) { return power(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace power_references { - -inline constexpr auto W = reference{}; -inline constexpr auto yW = reference{}; -inline constexpr auto zW = reference{}; -inline constexpr auto aW = reference{}; -inline constexpr auto fW = reference{}; -inline constexpr auto pW = reference{}; -inline constexpr auto nW = reference{}; -inline constexpr auto uW = reference{}; -inline constexpr auto mW = reference{}; -inline constexpr auto kW = reference{}; -inline constexpr auto MW = reference{}; -inline constexpr auto GW = reference{}; -inline constexpr auto TW = reference{}; -inline constexpr auto PW = reference{}; -inline constexpr auto EW = reference{}; -inline constexpr auto ZW = reference{}; -inline constexpr auto YW = reference{}; - -} // namespace power_references - -namespace references { - -using namespace power_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline power { - -template -using W = units::isq::si::power; -template -using yW = units::isq::si::power; -template -using zW = units::isq::si::power; -template -using aW = units::isq::si::power; -template -using fW = units::isq::si::power; -template -using pW = units::isq::si::power; -template -using nW = units::isq::si::power; -template -using uW = units::isq::si::power; -template -using mW = units::isq::si::power; -template -using kW = units::isq::si::power; -template -using MW = units::isq::si::power; -template -using GW = units::isq::si::power; -template -using TW = units::isq::si::power; -template -using PW = units::isq::si::power; -template -using EW = units::isq::si::power; -template -using ZW = units::isq::si::power; -template -using YW = units::isq::si::power; - -} // namespace units::aliases::isq::si::inline power - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/prefixes.h b/src/systems/si/include/units/isq/si/prefixes.h deleted file mode 100644 index 5ecd21e6..00000000 --- a/src/systems/si/include/units/isq/si/prefixes.h +++ /dev/null @@ -1,70 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include - -namespace units::isq::si { - -template -struct yocto : prefixed_unit<"y", mag_power<10, -24>, U> {}; -template -struct zepto : prefixed_unit<"z", mag_power<10, -21>, U> {}; -template -struct atto : prefixed_unit<"a", mag_power<10, -18>, U> {}; -template -struct femto : prefixed_unit<"f", mag_power<10, -15>, U> {}; -template -struct pico : prefixed_unit<"p", mag_power<10, -12>, U> {}; -template -struct nano : prefixed_unit<"n", mag_power<10, -9>, U> {}; -template -struct micro : prefixed_unit, U> {}; -template -struct milli : prefixed_unit<"m", mag_power<10, -3>, U> {}; -template -struct centi : prefixed_unit<"c", mag_power<10, -2>, U> {}; -template -struct deci : prefixed_unit<"d", mag_power<10, -1>, U> {}; -template -struct deca : prefixed_unit<"da", mag_power<10, 1>, U> {}; -template -struct hecto : prefixed_unit<"h", mag_power<10, 2>, U> {}; -template -struct kilo : prefixed_unit<"k", mag_power<10, 3>, U> {}; -template -struct mega : prefixed_unit<"M", mag_power<10, 6>, U> {}; -template -struct giga : prefixed_unit<"G", mag_power<10, 9>, U> {}; -template -struct tera : prefixed_unit<"T", mag_power<10, 12>, U> {}; -template -struct peta : prefixed_unit<"P", mag_power<10, 15>, U> {}; -template -struct exa : prefixed_unit<"E", mag_power<10, 18>, U> {}; -template -struct zetta : prefixed_unit<"Z", mag_power<10, 21>, U> {}; -template -struct yotta : prefixed_unit<"Y", mag_power<10, 24>, U> {}; - -} // namespace units::isq::si diff --git a/src/systems/si/include/units/isq/si/pressure.h b/src/systems/si/include/units/isq/si/pressure.h deleted file mode 100644 index 86bed5d2..00000000 --- a/src/systems/si/include/units/isq/si/pressure.h +++ /dev/null @@ -1,329 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct pascal : named_unit {}; -struct yoctopascal : prefixed_unit {}; -struct zeptopascal : prefixed_unit {}; -struct attopascal : prefixed_unit {}; -struct femtopascal : prefixed_unit {}; -struct picopascal : prefixed_unit {}; -struct nanopascal : prefixed_unit {}; -struct micropascal : prefixed_unit {}; -struct millipascal : prefixed_unit {}; -struct centipascal : prefixed_unit {}; -struct decipascal : prefixed_unit {}; -struct decapascal : prefixed_unit {}; -struct hectopascal : prefixed_unit {}; -struct kilopascal : prefixed_unit {}; -struct megapascal : prefixed_unit {}; -struct gigapascal : prefixed_unit {}; -struct terapascal : prefixed_unit {}; -struct petapascal : prefixed_unit {}; -struct exapascal : prefixed_unit {}; -struct zettapascal : prefixed_unit {}; -struct yottapascal : prefixed_unit {}; - -struct dim_pressure : isq::dim_pressure {}; - -template U, Representation Rep = double> -using pressure = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Pa -constexpr auto operator"" _q_Pa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_Pa(long double l) { return pressure(l); } - -// yPa -constexpr auto operator"" _q_yPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_yPa(long double l) { return pressure(l); } - -// zPa -constexpr auto operator"" _q_zPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_zPa(long double l) { return pressure(l); } - -// aPa -constexpr auto operator"" _q_aPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_aPa(long double l) { return pressure(l); } - -// fPa -constexpr auto operator"" _q_fPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_fPa(long double l) { return pressure(l); } - -// pPa -constexpr auto operator"" _q_pPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_pPa(long double l) { return pressure(l); } - -// nPa -constexpr auto operator"" _q_nPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_nPa(long double l) { return pressure(l); } - -// uPa -constexpr auto operator"" _q_uPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_uPa(long double l) { return pressure(l); } - -// mPa -constexpr auto operator"" _q_mPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_mPa(long double l) { return pressure(l); } - -// cPa -constexpr auto operator"" _q_cPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_cPa(long double l) { return pressure(l); } - -// dPa -constexpr auto operator"" _q_dPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_dPa(long double l) { return pressure(l); } - -// daPa -constexpr auto operator"" _q_daPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_daPa(long double l) { return pressure(l); } - -// hPa -constexpr auto operator"" _q_hPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_hPa(long double l) { return pressure(l); } - -// kPa -constexpr auto operator"" _q_kPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_kPa(long double l) { return pressure(l); } - -// MPa -constexpr auto operator"" _q_MPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_MPa(long double l) { return pressure(l); } - -// GPa -constexpr auto operator"" _q_GPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_GPa(long double l) { return pressure(l); } - -// TPa -constexpr auto operator"" _q_TPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_TPa(long double l) { return pressure(l); } - -// PPa -constexpr auto operator"" _q_PPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_PPa(long double l) { return pressure(l); } - -// EPa -constexpr auto operator"" _q_EPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_EPa(long double l) { return pressure(l); } - -// ZPa -constexpr auto operator"" _q_ZPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_ZPa(long double l) { return pressure(l); } - -// YPa -constexpr auto operator"" _q_YPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_YPa(long double l) { return pressure(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace pressure_references { - -inline constexpr auto Pa = reference{}; -inline constexpr auto yPa = reference{}; -inline constexpr auto zPa = reference{}; -inline constexpr auto aPa = reference{}; -inline constexpr auto fPa = reference{}; -inline constexpr auto pPa = reference{}; -inline constexpr auto nPa = reference{}; -inline constexpr auto uPa = reference{}; -inline constexpr auto mPa = reference{}; -inline constexpr auto cPa = reference{}; -inline constexpr auto dPa = reference{}; -inline constexpr auto daPa = reference{}; -inline constexpr auto hPa = reference{}; -inline constexpr auto kPa = reference{}; -inline constexpr auto MPa = reference{}; -inline constexpr auto GPa = reference{}; -inline constexpr auto TPa = reference{}; -inline constexpr auto PPa = reference{}; -inline constexpr auto EPa = reference{}; -inline constexpr auto ZPa = reference{}; -inline constexpr auto YPa = reference{}; - -} // namespace pressure_references - -namespace references { - -using namespace pressure_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline pressure { - -template -using Pa = units::isq::si::pressure; -template -using yPa = units::isq::si::pressure; -template -using zPa = units::isq::si::pressure; -template -using aPa = units::isq::si::pressure; -template -using fPa = units::isq::si::pressure; -template -using pPa = units::isq::si::pressure; -template -using nPa = units::isq::si::pressure; -template -using uPa = units::isq::si::pressure; -template -using mPa = units::isq::si::pressure; -template -using cPa = units::isq::si::pressure; -template -using dPa = units::isq::si::pressure; -template -using daPa = units::isq::si::pressure; -template -using hPa = units::isq::si::pressure; -template -using kPa = units::isq::si::pressure; -template -using MPa = units::isq::si::pressure; -template -using GPa = units::isq::si::pressure; -template -using TPa = units::isq::si::pressure; -template -using PPa = units::isq::si::pressure; -template -using EPa = units::isq::si::pressure; -template -using ZPa = units::isq::si::pressure; -template -using YPa = units::isq::si::pressure; - -} // namespace units::aliases::isq::si::inline pressure - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/radioactivity.h b/src/systems/si/include/units/isq/si/radioactivity.h deleted file mode 100644 index d46c81e4..00000000 --- a/src/systems/si/include/units/isq/si/radioactivity.h +++ /dev/null @@ -1,327 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct becquerel : named_unit {}; -struct yoctobecquerel : prefixed_unit {}; -struct zeptobecquerel : prefixed_unit {}; -struct attobecquerel : prefixed_unit {}; -struct femtobecquerel : prefixed_unit {}; -struct picobecquerel : prefixed_unit {}; -struct nanobecquerel : prefixed_unit {}; -struct microbecquerel : prefixed_unit {}; -struct millibecquerel : prefixed_unit {}; -struct centibecquerel : prefixed_unit {}; -struct decibecquerel : prefixed_unit {}; -struct decabecquerel : prefixed_unit {}; -struct hectobecquerel : prefixed_unit {}; -struct kilobecquerel : prefixed_unit {}; -struct megabecquerel : prefixed_unit {}; -struct gigabecquerel : prefixed_unit {}; -struct terabecquerel : prefixed_unit {}; -struct petabecquerel : prefixed_unit {}; -struct exabecquerel : prefixed_unit {}; -struct zettabecquerel : prefixed_unit {}; -struct yottabecquerel : prefixed_unit {}; - -struct dim_radioactivity : isq::dim_radioactivity {}; - -template U, Representation Rep = double> -using radioactivity = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Bq -constexpr auto operator"" _q_Bq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_Bq(long double l) { return radioactivity(l); } - -// yBq -constexpr auto operator"" _q_yBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_yBq(long double l) { return radioactivity(l); } - -// zBq -constexpr auto operator"" _q_zBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_zBq(long double l) { return radioactivity(l); } - -// aBq -constexpr auto operator"" _q_aBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_aBq(long double l) { return radioactivity(l); } - -// fBq -constexpr auto operator"" _q_fBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_fBq(long double l) { return radioactivity(l); } - -// pBq -constexpr auto operator"" _q_pBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_pBq(long double l) { return radioactivity(l); } - -// nBq -constexpr auto operator"" _q_nBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_nBq(long double l) { return radioactivity(l); } - -// uBq -constexpr auto operator"" _q_uBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_uBq(long double l) { return radioactivity(l); } - -// mBq -constexpr auto operator"" _q_mBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_mBq(long double l) { return radioactivity(l); } - -// cBq -constexpr auto operator"" _q_cBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_cBq(long double l) { return radioactivity(l); } - -// dBq -constexpr auto operator"" _q_dBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_dBq(long double l) { return radioactivity(l); } - -// daBq -constexpr auto operator"" _q_daBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_daBq(long double l) { return radioactivity(l); } - -// hBq -constexpr auto operator"" _q_hBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_hBq(long double l) { return radioactivity(l); } - -// kBq -constexpr auto operator"" _q_kBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_kBq(long double l) { return radioactivity(l); } - -// MBq -constexpr auto operator"" _q_MBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_MBq(long double l) { return radioactivity(l); } - -// GBq -constexpr auto operator"" _q_GBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_GBq(long double l) { return radioactivity(l); } - -// TBq -constexpr auto operator"" _q_TBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_TBq(long double l) { return radioactivity(l); } - -// PBq -constexpr auto operator"" _q_PBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_PBq(long double l) { return radioactivity(l); } - -// EBq -constexpr auto operator"" _q_EBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_EBq(long double l) { return radioactivity(l); } - -// ZBq -constexpr auto operator"" _q_ZBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_ZBq(long double l) { return radioactivity(l); } - -// YBq -constexpr auto operator"" _q_YBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_YBq(long double l) { return radioactivity(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace radioactivity_references { - -inline constexpr auto Bq = reference{}; -inline constexpr auto yBq = reference{}; -inline constexpr auto zBq = reference{}; -inline constexpr auto aBq = reference{}; -inline constexpr auto fBq = reference{}; -inline constexpr auto pBq = reference{}; -inline constexpr auto nBq = reference{}; -inline constexpr auto uBq = reference{}; -inline constexpr auto mBq = reference{}; -inline constexpr auto cBq = reference{}; -inline constexpr auto dBq = reference{}; -inline constexpr auto daBq = reference{}; -inline constexpr auto hBq = reference{}; -inline constexpr auto kBq = reference{}; -inline constexpr auto MBq = reference{}; -inline constexpr auto GBq = reference{}; -inline constexpr auto TBq = reference{}; -inline constexpr auto PBq = reference{}; -inline constexpr auto EBq = reference{}; -inline constexpr auto ZBq = reference{}; -inline constexpr auto YBq = reference{}; - -} // namespace radioactivity_references - -namespace references { - -using namespace radioactivity_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline radioactivity { - -template -using Bq = units::isq::si::radioactivity; -template -using yBq = units::isq::si::radioactivity; -template -using zBq = units::isq::si::radioactivity; -template -using aBq = units::isq::si::radioactivity; -template -using fBq = units::isq::si::radioactivity; -template -using pBq = units::isq::si::radioactivity; -template -using nBq = units::isq::si::radioactivity; -template -using uBq = units::isq::si::radioactivity; -template -using mBq = units::isq::si::radioactivity; -template -using cBq = units::isq::si::radioactivity; -template -using dBq = units::isq::si::radioactivity; -template -using daBq = units::isq::si::radioactivity; -template -using hBq = units::isq::si::radioactivity; -template -using kBq = units::isq::si::radioactivity; -template -using MBq = units::isq::si::radioactivity; -template -using GBq = units::isq::si::radioactivity; -template -using TBq = units::isq::si::radioactivity; -template -using PBq = units::isq::si::radioactivity; -template -using EBq = units::isq::si::radioactivity; -template -using ZBq = units::isq::si::radioactivity; -template -using YBq = units::isq::si::radioactivity; - -} // namespace units::aliases::isq::si::inline radioactivity - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/resistance.h b/src/systems/si/include/units/isq/si/resistance.h deleted file mode 100644 index ea57ed61..00000000 --- a/src/systems/si/include/units/isq/si/resistance.h +++ /dev/null @@ -1,281 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct ohm : named_unit {}; -struct yoctoohm : prefixed_unit {}; -struct zeptoohm : prefixed_unit {}; -struct attoohm : prefixed_unit {}; -struct femtoohm : prefixed_unit {}; -struct picoohm : prefixed_unit {}; -struct nanoohm : prefixed_unit {}; -struct microohm : prefixed_unit {}; -struct milliohm : prefixed_unit {}; -struct kiloohm : prefixed_unit {}; -struct megaohm : prefixed_unit {}; -struct gigaohm : prefixed_unit {}; -struct teraohm : prefixed_unit {}; -struct petaohm : prefixed_unit {}; -struct exaohm : prefixed_unit {}; -struct zettaohm : prefixed_unit {}; -struct yottaohm : prefixed_unit {}; - -struct dim_resistance : isq::dim_resistance {}; - -template U, Representation Rep = double> -using resistance = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// R -constexpr auto operator"" _q_R(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_R(long double l) { return resistance(l); } - -// yR -constexpr auto operator"" _q_yR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_yR(long double l) { return resistance(l); } - -// zR -constexpr auto operator"" _q_zR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_zR(long double l) { return resistance(l); } - -// aR -constexpr auto operator"" _q_aR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_aR(long double l) { return resistance(l); } - -// fR -constexpr auto operator"" _q_fR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_fR(long double l) { return resistance(l); } - -// pR -constexpr auto operator"" _q_pR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_pR(long double l) { return resistance(l); } - -// nR -constexpr auto operator"" _q_nR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_nR(long double l) { return resistance(l); } - -// uR -constexpr auto operator"" _q_uR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_uR(long double l) { return resistance(l); } - -// mR -constexpr auto operator"" _q_mR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_mR(long double l) { return resistance(l); } - -// kR -constexpr auto operator"" _q_kR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_kR(long double l) { return resistance(l); } - -// MR -constexpr auto operator"" _q_MR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_MR(long double l) { return resistance(l); } - -// GR -constexpr auto operator"" _q_GR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_GR(long double l) { return resistance(l); } - -// TR -constexpr auto operator"" _q_TR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_TR(long double l) { return resistance(l); } - -// PR -constexpr auto operator"" _q_PR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_PR(long double l) { return resistance(l); } - -// ER -constexpr auto operator"" _q_ER(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_ER(long double l) { return resistance(l); } - -// ZR -constexpr auto operator"" _q_ZR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_ZR(long double l) { return resistance(l); } - -// YR -constexpr auto operator"" _q_YR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_YR(long double l) { return resistance(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace resistance_references { - -inline constexpr auto R = reference{}; -inline constexpr auto yR = reference{}; -inline constexpr auto zR = reference{}; -inline constexpr auto aR = reference{}; -inline constexpr auto fR = reference{}; -inline constexpr auto pR = reference{}; -inline constexpr auto nR = reference{}; -inline constexpr auto uR = reference{}; -inline constexpr auto mR = reference{}; -inline constexpr auto kR = reference{}; -inline constexpr auto MR = reference{}; -inline constexpr auto GR = reference{}; -inline constexpr auto TR = reference{}; -inline constexpr auto PR = reference{}; -inline constexpr auto ER = reference{}; -inline constexpr auto ZR = reference{}; -inline constexpr auto YR = reference{}; - -} // namespace resistance_references - -namespace references { - -using namespace resistance_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline resistance { - -template -using R = units::isq::si::resistance; -template -using yR = units::isq::si::resistance; -template -using zR = units::isq::si::resistance; -template -using aR = units::isq::si::resistance; -template -using fR = units::isq::si::resistance; -template -using pR = units::isq::si::resistance; -template -using nR = units::isq::si::resistance; -template -using uR = units::isq::si::resistance; -template -using mR = units::isq::si::resistance; -template -using kR = units::isq::si::resistance; -template -using MR = units::isq::si::resistance; -template -using GR = units::isq::si::resistance; -template -using TR = units::isq::si::resistance; -template -using PR = units::isq::si::resistance; -template -using ER = units::isq::si::resistance; -template -using ZR = units::isq::si::resistance; -template -using YR = units::isq::si::resistance; - -} // namespace units::aliases::isq::si::inline resistance - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/si.h b/src/systems/si/include/units/isq/si/si.h deleted file mode 100644 index 683047fb..00000000 --- a/src/systems/si/include/units/isq/si/si.h +++ /dev/null @@ -1,78 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -// TODO Add when downcasting issue is solved (collides with pressure) -// #include - -// TODO Add when downcasting issue is solved (collides with frequency) -// #include diff --git a/src/systems/si/include/units/isq/si/speed.h b/src/systems/si/include/units/isq/si/speed.h deleted file mode 100644 index 8bcc17b7..00000000 --- a/src/systems/si/include/units/isq/si/speed.h +++ /dev/null @@ -1,82 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct metre_per_second : derived_unit {}; -struct dim_speed : isq::dim_speed {}; - -struct kilometre_per_hour : derived_scaled_unit {}; - -template U, Representation Rep = double> -using speed = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// m/s -constexpr auto operator"" _q_m_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return speed(static_cast(l)); -} -constexpr auto operator"" _q_m_per_s(long double l) { return speed(l); } - -// km/h -constexpr auto operator"" _q_km_per_h(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return speed(static_cast(l)); -} -constexpr auto operator"" _q_km_per_h(long double l) { return speed(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline speed { - -template -using m_per_s = units::isq::si::speed; -template -using km_per_h = units::isq::si::speed; - -} // namespace units::aliases::isq::si::inline speed - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/surface_tension.h b/src/systems/si/include/units/isq/si/surface_tension.h deleted file mode 100644 index 382b133f..00000000 --- a/src/systems/si/include/units/isq/si/surface_tension.h +++ /dev/null @@ -1,70 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct newton_per_metre : derived_unit {}; - -struct dim_surface_tension : isq::dim_surface_tension {}; - -template U, Representation Rep = double> -using surface_tension = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// N/m -constexpr auto operator"" _q_N_per_m(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return surface_tension(static_cast(l)); -} -constexpr auto operator"" _q_N_per_m(long double l) { return surface_tension(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline surface_tension { - -template -using N_per_m = units::isq::si::surface_tension; - -} // namespace units::aliases::isq::si::inline surface_tension - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/thermal_conductivity.h b/src/systems/si/include/units/isq/si/thermal_conductivity.h deleted file mode 100644 index 64177b52..00000000 --- a/src/systems/si/include/units/isq/si/thermal_conductivity.h +++ /dev/null @@ -1,76 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct watt_per_metre_kelvin : derived_unit {}; - -struct dim_thermal_conductivity : - isq::dim_thermal_conductivity {}; - -template U, Representation Rep = double> -using thermal_conductivity = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// W/(m K) -constexpr auto operator"" _q_W_per_m_K(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return thermal_conductivity(static_cast(l)); -} -constexpr auto operator"" _q_W_per_m_K(long double l) -{ - return thermal_conductivity(l); -} - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline thermal_conductivity { - -template -using W_per_m_K = units::isq::si::thermal_conductivity; - -} // namespace units::aliases::isq::si::inline thermal_conductivity - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/thermodynamic_temperature.h b/src/systems/si/include/units/isq/si/thermodynamic_temperature.h deleted file mode 100644 index cc0e3206..00000000 --- a/src/systems/si/include/units/isq/si/thermodynamic_temperature.h +++ /dev/null @@ -1,87 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct kelvin : named_unit {}; - -struct dim_thermodynamic_temperature : isq::dim_thermodynamic_temperature {}; - -template U, Representation Rep = double> -using thermodynamic_temperature = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// K -constexpr auto operator"" _q_K(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return thermodynamic_temperature(static_cast(l)); -} -constexpr auto operator"" _q_K(long double l) { return thermodynamic_temperature(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace thermodynamic_temperature_references { - -inline constexpr auto K = reference{}; - -} // namespace thermodynamic_temperature_references - -namespace references { - -using namespace thermodynamic_temperature_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline thermodynamic_temperature { - -template -using K = units::isq::si::thermodynamic_temperature; - -} // namespace units::aliases::isq::si::inline thermodynamic_temperature - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/time.h b/src/systems/si/include/units/isq/si/time.h deleted file mode 100644 index f023377a..00000000 --- a/src/systems/si/include/units/isq/si/time.h +++ /dev/null @@ -1,219 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct second : named_unit {}; -struct yoctosecond : prefixed_unit {}; -struct zeptosecond : prefixed_unit {}; -struct attosecond : prefixed_unit {}; -struct femtosecond : prefixed_unit {}; -struct picosecond : prefixed_unit {}; -struct nanosecond : prefixed_unit {}; -struct microsecond : prefixed_unit {}; -struct millisecond : prefixed_unit {}; -struct minute : named_scaled_unit(), second> {}; -struct hour : named_scaled_unit(), minute> {}; -struct day : named_scaled_unit(), hour> {}; - -struct dim_time : isq::dim_time {}; - -template U, Representation Rep = double> -using time = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// ys -constexpr auto operator"" _q_ys(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_ys(long double l) { return time(l); } - -// zs -constexpr auto operator"" _q_zs(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_zs(long double l) { return time(l); } - -// as -constexpr auto operator"" _q_as(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_as(long double l) { return time(l); } - -// fs -constexpr auto operator"" _q_fs(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_fs(long double l) { return time(l); } - -// ps -constexpr auto operator"" _q_ps(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_ps(long double l) { return time(l); } - -// ns -constexpr auto operator"" _q_ns(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_ns(long double l) { return time(l); } - -// us -constexpr auto operator"" _q_us(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_us(long double l) { return time(l); } - -// ms -constexpr auto operator"" _q_ms(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_ms(long double l) { return time(l); } - -// s -constexpr auto operator"" _q_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_s(long double l) { return time(l); } - -// min -constexpr auto operator"" _q_min(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_min(long double l) { return time(l); } - -// h -constexpr auto operator"" _q_h(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_h(long double l) { return time(l); } - -// d -constexpr auto operator"" _q_d(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_d(long double l) { return time(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace time_references { - -inline constexpr auto ys = reference{}; -inline constexpr auto zs = reference{}; -inline constexpr auto as = reference{}; -inline constexpr auto fs = reference{}; -inline constexpr auto ps = reference{}; -inline constexpr auto ns = reference{}; -inline constexpr auto us = reference{}; -inline constexpr auto ms = reference{}; -inline constexpr auto s = reference{}; -inline constexpr auto min = reference{}; -inline constexpr auto h = reference{}; -inline constexpr auto d = reference{}; - -} // namespace time_references - -namespace references { - -using namespace time_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline time { - -template -using ys = units::isq::si::time; -template -using zs = units::isq::si::time; -template -using as = units::isq::si::time; -template -using fs = units::isq::si::time; -template -using ps = units::isq::si::time; -template -using ns = units::isq::si::time; -template -using us = units::isq::si::time; -template -using ms = units::isq::si::time; -template -using s = units::isq::si::time; -template -using min = units::isq::si::time; -template -using h = units::isq::si::time; -template -using d = units::isq::si::time; - -} // namespace units::aliases::isq::si::inline time - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/torque.h b/src/systems/si/include/units/isq/si/torque.h deleted file mode 100644 index 14e5aec2..00000000 --- a/src/systems/si/include/units/isq/si/torque.h +++ /dev/null @@ -1,72 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct newton_metre_per_radian : derived_unit {}; - -struct dim_torque : isq::dim_torque> {}; - -template U, Representation Rep = double> -using torque = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Nm -constexpr auto operator"" _q_N_m_per_rad(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return torque(static_cast(l)); -} -constexpr auto operator"" _q_N_m_per_rad(long double l) { return torque(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline torque { - -template -using N_m_per_rad = units::isq::si::torque; - -} // namespace units::aliases::isq::si::inline torque - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/voltage.h b/src/systems/si/include/units/isq/si/voltage.h deleted file mode 100644 index e06cc1be..00000000 --- a/src/systems/si/include/units/isq/si/voltage.h +++ /dev/null @@ -1,329 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct volt : named_unit {}; -struct yoctovolt : prefixed_unit {}; -struct zeptovolt : prefixed_unit {}; -struct attovolt : prefixed_unit {}; -struct femtovolt : prefixed_unit {}; -struct picovolt : prefixed_unit {}; -struct nanovolt : prefixed_unit {}; -struct microvolt : prefixed_unit {}; -struct millivolt : prefixed_unit {}; -struct centivolt : prefixed_unit {}; -struct decivolt : prefixed_unit {}; -struct decavolt : prefixed_unit {}; -struct hectovolt : prefixed_unit {}; -struct kilovolt : prefixed_unit {}; -struct megavolt : prefixed_unit {}; -struct gigavolt : prefixed_unit {}; -struct teravolt : prefixed_unit {}; -struct petavolt : prefixed_unit {}; -struct exavolt : prefixed_unit {}; -struct zettavolt : prefixed_unit {}; -struct yottavolt : prefixed_unit {}; - -struct dim_voltage : isq::dim_voltage {}; - -template U, Representation Rep = double> -using voltage = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// V -constexpr auto operator"" _q_V(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_V(long double l) { return voltage(l); } - -// yV -constexpr auto operator"" _q_yV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_yV(long double l) { return voltage(l); } - -// zV -constexpr auto operator"" _q_zV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_zV(long double l) { return voltage(l); } - -// aV -constexpr auto operator"" _q_aV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_aV(long double l) { return voltage(l); } - -// fV -constexpr auto operator"" _q_fV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_fV(long double l) { return voltage(l); } - -// pV -constexpr auto operator"" _q_pV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_pV(long double l) { return voltage(l); } - -// nV -constexpr auto operator"" _q_nV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_nV(long double l) { return voltage(l); } - -// uV -constexpr auto operator"" _q_uV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_uV(long double l) { return voltage(l); } - -// mV -constexpr auto operator"" _q_mV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_mV(long double l) { return voltage(l); } - -// cV -constexpr auto operator"" _q_cV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_cV(long double l) { return voltage(l); } - -// dV -constexpr auto operator"" _q_dV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_dV(long double l) { return voltage(l); } - -// daV -constexpr auto operator"" _q_daV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_daV(long double l) { return voltage(l); } - -// hV -constexpr auto operator"" _q_hV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_hV(long double l) { return voltage(l); } - -// kV -constexpr auto operator"" _q_kV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_kV(long double l) { return voltage(l); } - -// MV -constexpr auto operator"" _q_MV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_MV(long double l) { return voltage(l); } - -// GV -constexpr auto operator"" _q_GV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_GV(long double l) { return voltage(l); } - -// TV -constexpr auto operator"" _q_TV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_TV(long double l) { return voltage(l); } - -// PV -constexpr auto operator"" _q_PV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_PV(long double l) { return voltage(l); } - -// EV -constexpr auto operator"" _q_EV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_EV(long double l) { return voltage(l); } - -// ZV -constexpr auto operator"" _q_ZV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_ZV(long double l) { return voltage(l); } - -// YV -constexpr auto operator"" _q_YV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_YV(long double l) { return voltage(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace voltage_references { - -inline constexpr auto V = reference{}; -inline constexpr auto yV = reference{}; -inline constexpr auto zV = reference{}; -inline constexpr auto aV = reference{}; -inline constexpr auto fV = reference{}; -inline constexpr auto pV = reference{}; -inline constexpr auto nV = reference{}; -inline constexpr auto uV = reference{}; -inline constexpr auto mV = reference{}; -inline constexpr auto cV = reference{}; -inline constexpr auto dV = reference{}; -inline constexpr auto daV = reference{}; -inline constexpr auto hV = reference{}; -inline constexpr auto kV = reference{}; -inline constexpr auto MV = reference{}; -inline constexpr auto GV = reference{}; -inline constexpr auto TV = reference{}; -inline constexpr auto PV = reference{}; -inline constexpr auto EV = reference{}; -inline constexpr auto ZV = reference{}; -inline constexpr auto YV = reference{}; - -} // namespace voltage_references - -namespace references { - -using namespace voltage_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline voltage { - -template -using V = units::isq::si::voltage; -template -using yV = units::isq::si::voltage; -template -using zV = units::isq::si::voltage; -template -using aV = units::isq::si::voltage; -template -using fV = units::isq::si::voltage; -template -using pV = units::isq::si::voltage; -template -using nV = units::isq::si::voltage; -template -using uV = units::isq::si::voltage; -template -using mV = units::isq::si::voltage; -template -using cV = units::isq::si::voltage; -template -using dV = units::isq::si::voltage; -template -using daV = units::isq::si::voltage; -template -using hV = units::isq::si::voltage; -template -using kV = units::isq::si::voltage; -template -using MV = units::isq::si::voltage; -template -using GV = units::isq::si::voltage; -template -using TV = units::isq::si::voltage; -template -using PV = units::isq::si::voltage; -template -using EV = units::isq::si::voltage; -template -using ZV = units::isq::si::voltage; -template -using YV = units::isq::si::voltage; - -} // namespace units::aliases::isq::si::inline voltage - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/volume.h b/src/systems/si/include/units/isq/si/volume.h deleted file mode 100644 index 1f61d874..00000000 --- a/src/systems/si/include/units/isq/si/volume.h +++ /dev/null @@ -1,582 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct cubic_metre : derived_unit {}; -struct dim_volume : isq::dim_volume {}; - -struct cubic_yoctometre : derived_scaled_unit {}; -struct cubic_zeptometre : derived_scaled_unit {}; -struct cubic_attometre : derived_scaled_unit {}; -struct cubic_femtometre : derived_scaled_unit {}; -struct cubic_picometre : derived_scaled_unit {}; -struct cubic_nanometre : derived_scaled_unit {}; -struct cubic_micrometre : derived_scaled_unit {}; -struct cubic_millimetre : derived_scaled_unit {}; -struct cubic_centimetre : derived_scaled_unit {}; -struct cubic_decimetre : derived_scaled_unit {}; -struct cubic_decametre : derived_scaled_unit {}; -struct cubic_hectometre : derived_scaled_unit {}; -struct cubic_kilometre : derived_scaled_unit {}; -struct cubic_megametre : derived_scaled_unit {}; -struct cubic_gigametre : derived_scaled_unit {}; -struct cubic_terametre : derived_scaled_unit {}; -struct cubic_petametre : derived_scaled_unit {}; -struct cubic_exametre : derived_scaled_unit {}; -struct cubic_zettametre : derived_scaled_unit {}; -struct cubic_yottametre : derived_scaled_unit {}; - -struct litre : alias_unit {}; -struct yoctolitre : prefixed_alias_unit {}; -struct zeptolitre : prefixed_unit {}; -struct attolitre : prefixed_unit {}; -struct femtolitre : prefixed_alias_unit {}; -struct picolitre : prefixed_unit {}; -struct nanolitre : prefixed_unit {}; -struct microlitre : prefixed_alias_unit {}; -struct millilitre : prefixed_alias_unit {}; -struct centilitre : prefixed_unit {}; -struct decilitre : prefixed_unit {}; -struct decalitre : prefixed_unit {}; -struct hectolitre : prefixed_alias_unit {}; -struct kilolitre : prefixed_alias_unit {}; -struct megalitre : prefixed_alias_unit {}; -struct gigalitre : prefixed_alias_unit {}; -struct teralitre : prefixed_alias_unit {}; -struct petalitre : prefixed_unit {}; -struct exalitre : prefixed_unit {}; -struct zettalitre : prefixed_alias_unit {}; -struct yottalitre : prefixed_unit {}; - -template U, Representation Rep = double> -using volume = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// m3 -constexpr auto operator"" _q_m3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_m3(long double l) { return volume(l); } - -// ym3 -constexpr auto operator"" _q_ym3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_ym3(long double l) { return volume(l); } - -// zm3 -constexpr auto operator"" _q_zm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_zm3(long double l) { return volume(l); } - -// am3 -constexpr auto operator"" _q_am3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_am3(long double l) { return volume(l); } - -// fm3 -constexpr auto operator"" _q_fm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_fm3(long double l) { return volume(l); } - -// pm3 -constexpr auto operator"" _q_pm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_pm3(long double l) { return volume(l); } - -// nm3 -constexpr auto operator"" _q_nm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_nm3(long double l) { return volume(l); } - -// um3 -constexpr auto operator"" _q_um3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_um3(long double l) { return volume(l); } - -// mm3 -constexpr auto operator"" _q_mm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_mm3(long double l) { return volume(l); } - -// cm3 -constexpr auto operator"" _q_cm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_cm3(long double l) { return volume(l); } - -// dm3 -constexpr auto operator"" _q_dm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_dm3(long double l) { return volume(l); } - -// dam3 -constexpr auto operator"" _q_dam3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_dam3(long double l) { return volume(l); } - -// hm3 -constexpr auto operator"" _q_hm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_hm3(long double l) { return volume(l); } - -// km3 -constexpr auto operator"" _q_km3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_km3(long double l) { return volume(l); } - -// Mm3 -constexpr auto operator"" _q_Mm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Mm3(long double l) { return volume(l); } - -// Gm3 -constexpr auto operator"" _q_Gm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Gm3(long double l) { return volume(l); } - -// Tm3 -constexpr auto operator"" _q_Tm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Tm3(long double l) { return volume(l); } - -// Pm3 -constexpr auto operator"" _q_Pm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Pm3(long double l) { return volume(l); } - -// Em3 -constexpr auto operator"" _q_Em3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Em3(long double l) { return volume(l); } - -// Zm3 -constexpr auto operator"" _q_Zm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Zm3(long double l) { return volume(l); } - -// Ym3 -constexpr auto operator"" _q_Ym3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Ym3(long double l) { return volume(l); } - -// l -constexpr auto operator"" _q_l(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_l(long double l) { return volume(l); } - -// yl -constexpr auto operator"" _q_yl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_yl(long double l) { return volume(l); } - -// zl -constexpr auto operator"" _q_zl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_zl(long double l) { return volume(l); } - -// al -constexpr auto operator"" _q_al(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_al(long double l) { return volume(l); } - -// fl -constexpr auto operator"" _q_fl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_fl(long double l) { return volume(l); } - -// pl -constexpr auto operator"" _q_pl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_pl(long double l) { return volume(l); } - -// nl -constexpr auto operator"" _q_nl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_nl(long double l) { return volume(l); } - -// ul -constexpr auto operator"" _q_ul(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_ul(long double l) { return volume(l); } - -// ml -constexpr auto operator"" _q_ml(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_ml(long double l) { return volume(l); } - -// cl -constexpr auto operator"" _q_cl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_cl(long double l) { return volume(l); } - -// dl -constexpr auto operator"" _q_dl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_dl(long double l) { return volume(l); } - -// dal -constexpr auto operator"" _q_dal(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_dal(long double l) { return volume(l); } - -// hl -constexpr auto operator"" _q_hl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_hl(long double l) { return volume(l); } - -// kl -constexpr auto operator"" _q_kl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_kl(long double l) { return volume(l); } - -// Ml -constexpr auto operator"" _q_Ml(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Ml(long double l) { return volume(l); } - -// Gl -constexpr auto operator"" _q_Gl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Gl(long double l) { return volume(l); } - -// Tl -constexpr auto operator"" _q_Tl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Tl(long double l) { return volume(l); } - -// Pl -constexpr auto operator"" _q_Pl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Pl(long double l) { return volume(l); } - -// El -constexpr auto operator"" _q_El(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_El(long double l) { return volume(l); } - -// Zl -constexpr auto operator"" _q_Zl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Zl(long double l) { return volume(l); } - -// Yl -constexpr auto operator"" _q_Yl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Yl(long double l) { return volume(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace volume_references { - -inline constexpr auto m3 = reference{}; -inline constexpr auto ym3 = reference{}; -inline constexpr auto zm3 = reference{}; -inline constexpr auto am3 = reference{}; -inline constexpr auto fm3 = reference{}; -inline constexpr auto pm3 = reference{}; -inline constexpr auto nm3 = reference{}; -inline constexpr auto um3 = reference{}; -inline constexpr auto mm3 = reference{}; -inline constexpr auto cm3 = reference{}; -inline constexpr auto dm3 = reference{}; -inline constexpr auto dam3 = reference{}; -inline constexpr auto hm3 = reference{}; -inline constexpr auto km3 = reference{}; -inline constexpr auto Mm3 = reference{}; -inline constexpr auto Gm3 = reference{}; -inline constexpr auto Tm3 = reference{}; -inline constexpr auto Pm3 = reference{}; -inline constexpr auto Em3 = reference{}; -inline constexpr auto Zm3 = reference{}; -inline constexpr auto Ym3 = reference{}; - -inline constexpr auto l = reference{}; -inline constexpr auto yl = reference{}; -inline constexpr auto zl = reference{}; -inline constexpr auto al = reference{}; -inline constexpr auto fl = reference{}; -inline constexpr auto pl = reference{}; -inline constexpr auto nl = reference{}; -inline constexpr auto ul = reference{}; -inline constexpr auto ml = reference{}; -inline constexpr auto cl = reference{}; -inline constexpr auto dl = reference{}; -inline constexpr auto dal = reference{}; -inline constexpr auto hl = reference{}; -inline constexpr auto kl = reference{}; -inline constexpr auto Ml = reference{}; -inline constexpr auto Gl = reference{}; -inline constexpr auto Tl = reference{}; -inline constexpr auto Pl = reference{}; -inline constexpr auto El = reference{}; -inline constexpr auto Zl = reference{}; -inline constexpr auto Yl = reference{}; - -} // namespace volume_references - -namespace references { - -using namespace volume_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline volume { - -template -using m3 = units::isq::si::volume; -template -using ym3 = units::isq::si::volume; -template -using zm3 = units::isq::si::volume; -template -using am3 = units::isq::si::volume; -template -using fm3 = units::isq::si::volume; -template -using pm3 = units::isq::si::volume; -template -using nm3 = units::isq::si::volume; -template -using um3 = units::isq::si::volume; -template -using mm3 = units::isq::si::volume; -template -using cm3 = units::isq::si::volume; -template -using dm3 = units::isq::si::volume; -template -using dam3 = units::isq::si::volume; -template -using hm3 = units::isq::si::volume; -template -using km3 = units::isq::si::volume; -template -using Mm3 = units::isq::si::volume; -template -using Gm3 = units::isq::si::volume; -template -using Tm3 = units::isq::si::volume; -template -using Pm3 = units::isq::si::volume; -template -using Em3 = units::isq::si::volume; -template -using Zm3 = units::isq::si::volume; -template -using Ym3 = units::isq::si::volume; - -template -using l = units::isq::si::volume; -template -using yl = units::isq::si::volume; -template -using zl = units::isq::si::volume; -template -using al = units::isq::si::volume; -template -using fl = units::isq::si::volume; -template -using pl = units::isq::si::volume; -template -using nl = units::isq::si::volume; -template -using ul = units::isq::si::volume; -template -using ml = units::isq::si::volume; -template -using cl = units::isq::si::volume; -template -using dl = units::isq::si::volume; -template -using dal = units::isq::si::volume; -template -using hl = units::isq::si::volume; -template -using kl = units::isq::si::volume; -template -using Ml = units::isq::si::volume; -template -using Gl = units::isq::si::volume; -template -using Tl = units::isq::si::volume; -template -using Pl = units::isq::si::volume; -template -using El = units::isq::si::volume; -template -using Zl = units::isq::si::volume; -template -using Yl = units::isq::si::volume; - -} // namespace units::aliases::isq::si::inline volume - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/time.h b/src/systems/si/include/units/si/base_quantities.h similarity index 56% rename from src/systems/si-cgs/include/units/isq/si/cgs/time.h rename to src/systems/si/include/units/si/base_quantities.h index e84ae05c..91d557f5 100644 --- a/src/systems/si-cgs/include/units/isq/si/cgs/time.h +++ b/src/systems/si/include/units/si/base_quantities.h @@ -22,55 +22,22 @@ #pragma once -// IWYU pragma: begin_exports -#include -#include -#include +#include #include -#include -// IWYU pragma: end_exports +#include -namespace units::isq::si::cgs { +namespace units::si { -using si::second; +// inline constexpr struct time : system_reference {} time; +// inline constexpr struct length : system_reference {} length; +// inline constexpr struct mass : system_reference {} mass; +inline constexpr struct electric_current : system_reference { +} electric_current; +inline constexpr struct thermodynamic_temperature : system_reference { +} thermodynamic_temperature; +inline constexpr struct amount_of_substance : system_reference { +} amount_of_substance; +inline constexpr struct luminous_intensity : system_reference { +} luminous_intensity; -using si::dim_time; -using si::time; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -using si::literals::operator"" _q_s; - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace time_references { - -using si::references::s; - -} // namespace time_references - -namespace references { - -using namespace time_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline time { - -using namespace units::aliases::isq::si::time; - -} // namespace units::aliases::isq::si::cgs::inline time - -#endif // UNITS_NO_ALIASES +} // namespace units::si diff --git a/src/systems/si/include/units/si/constants.h b/src/systems/si/include/units/si/constants.h new file mode 100644 index 00000000..1027bf37 --- /dev/null +++ b/src/systems/si/include/units/si/constants.h @@ -0,0 +1,80 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// 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. + +#pragma once + +#include +#include +#include +#include +#include + +namespace units::si { + +namespace si2019 { + +// clang-format off +inline constexpr struct mag_planck : decltype(mag * mag_power<10, -34>) {} mag_planck; +inline constexpr struct mag_speed_of_light : decltype(mag<299'792'458>) {} mag_speed_of_light; +// clang-format on + +template +inline constexpr auto planck_constant = Rep{1} * (mag_planck * energy[joule] * time[second]); + +template +inline constexpr auto speed_of_light = Rep{1} * speed[mag_speed_of_light * metre / second]; + +// template +// inline constexpr auto planck_constant = energy(6.62607015e-34) * time(1); + +// template +// inline constexpr auto elementary_charge = electric_charge(1.602176634e-19); + +// template +// inline constexpr auto boltzmann_constant = energy(1.380649e-23) / thermodynamic_temperature(1); + +// template +// inline constexpr auto avogadro_constant = Rep(6.02214076e23) / amount_of_substance(1); + +// template +// inline constexpr auto speed_of_light = speed(299'792'458); + +// template +// inline constexpr auto hyperfine_structure_transition_frequency = frequency(Rep{9'192'631'770}); + +// template +// inline constexpr auto luminous_efficacy = luminous_flux(683) / power(1); + +// template +// inline constexpr auto standard_gravity = acceleration(9.80665); + +} // namespace si2019 + +// clang-format off +inline constexpr struct mag_standard_gravity : decltype(mag) {} mag_standard_gravity; +// clang-format on + +template +inline constexpr auto standard_gravity = Rep{1} * acceleration[mag_standard_gravity * metre / square]; + +} // namespace units::si diff --git a/src/systems/si/include/units/si/mechanics.h b/src/systems/si/include/units/si/mechanics.h new file mode 100644 index 00000000..e657aca7 --- /dev/null +++ b/src/systems/si/include/units/si/mechanics.h @@ -0,0 +1,68 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// 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. + +#pragma once + +#include +#include +#include +#include + +namespace units::si { + +// clang-format off +inline constexpr struct mass : system_reference {} mass; +inline constexpr struct mass_density : system_reference> {} mass_density; +inline constexpr struct specific_volume : system_reference / kilogram> {} specific_volume; +inline constexpr struct relative_mass_density : system_reference {} relative_mass_density; +inline constexpr struct surface_mass_density : system_reference> {} surface_mass_density; +inline constexpr struct linear_mass_density : system_reference {} linear_mass_density; +inline constexpr struct momentum : system_reference {} momentum; +inline constexpr struct force : system_reference {} force; +// inline constexpr struct weight : system_reference {} weight; +inline constexpr struct impulse : system_reference {} impulse; +inline constexpr struct angular_momentum : system_reference / second> {} angular_momentum; // TODO radian? +inline constexpr struct moment_of_inertia : system_reference> {} moment_of_inertia; +inline constexpr struct moment_of_force : system_reference {} moment_of_force; +inline constexpr struct torque : system_reference {} torque; +inline constexpr struct angular_impulse : system_reference {} angular_impulse; +inline constexpr struct pressure : system_reference {} pressure; +inline constexpr struct stress : system_reference {} stress; +inline constexpr struct normal_stress : system_reference {} normal_stress; +inline constexpr struct strain : system_reference {} strain; +inline constexpr struct poisson_number : system_reference {} poisson_number; +inline constexpr struct compressibility : system_reference {} compressibility; +inline constexpr struct second_axial_moment_of_area : system_reference * square> {} second_axial_moment_of_area; +inline constexpr struct section_modulus : system_reference> {} section_modulus; +inline constexpr struct dynamic_viscosity : system_reference {} dynamic_viscosity; +inline constexpr struct kinematic_viscosity : system_reference / second> {} kinematic_viscosity; +inline constexpr struct surface_tension : system_reference {} surface_tension; +inline constexpr struct power : system_reference {} power; +inline constexpr struct efficiency : system_reference {} efficiency; +inline constexpr struct mass_flow : system_reference * second)> {} mass_flow; +inline constexpr struct mass_flow_rate : system_reference {} mass_flow_rate; +inline constexpr struct mass_change_rate : system_reference {} mass_change_rate; +inline constexpr struct volume_flow_rate : system_reference / second> {} volume_flow_rate; +// inline constexpr struct action : system_reference {} action; // TODO make it compile +// clang-format on + +} // namespace units::si diff --git a/src/systems/si/include/units/si/prefixes.h b/src/systems/si/include/units/si/prefixes.h new file mode 100644 index 00000000..f90bdbde --- /dev/null +++ b/src/systems/si/include/units/si/prefixes.h @@ -0,0 +1,111 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// 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. + +#pragma once + +#include + +namespace units::si { + +template +struct yocto_ : prefixed_unit<"y", mag_power<10, -24>, U> {}; +template +struct zepto_ : prefixed_unit<"z", mag_power<10, -21>, U> {}; +template +struct atto_ : prefixed_unit<"a", mag_power<10, -18>, U> {}; +template +struct femto_ : prefixed_unit<"f", mag_power<10, -15>, U> {}; +template +struct pico_ : prefixed_unit<"p", mag_power<10, -12>, U> {}; +template +struct nano_ : prefixed_unit<"n", mag_power<10, -9>, U> {}; +template +struct micro_ : prefixed_unit, U> {}; +template +struct milli_ : prefixed_unit<"m", mag_power<10, -3>, U> {}; +template +struct centi_ : prefixed_unit<"c", mag_power<10, -2>, U> {}; +template +struct deci_ : prefixed_unit<"d", mag_power<10, -1>, U> {}; +template +struct deca_ : prefixed_unit<"da", mag_power<10, 1>, U> {}; +template +struct hecto_ : prefixed_unit<"h", mag_power<10, 2>, U> {}; +template +struct kilo_ : prefixed_unit<"k", mag_power<10, 3>, U> {}; +template +struct mega_ : prefixed_unit<"M", mag_power<10, 6>, U> {}; +template +struct giga_ : prefixed_unit<"G", mag_power<10, 9>, U> {}; +template +struct tera_ : prefixed_unit<"T", mag_power<10, 12>, U> {}; +template +struct peta_ : prefixed_unit<"P", mag_power<10, 15>, U> {}; +template +struct exa_ : prefixed_unit<"E", mag_power<10, 18>, U> {}; +template +struct zetta_ : prefixed_unit<"Z", mag_power<10, 21>, U> {}; +template +struct yotta_ : prefixed_unit<"Y", mag_power<10, 24>, U> {}; + +template +inline constexpr yocto_ yocto; +template +inline constexpr zepto_ zepto; +template +inline constexpr atto_ atto; +template +inline constexpr femto_ femto; +template +inline constexpr pico_ pico; +template +inline constexpr nano_ nano; +template +inline constexpr micro_ micro; +template +inline constexpr milli_ milli; +template +inline constexpr centi_ centi; +template +inline constexpr deci_ deci; +template +inline constexpr deca_ deca; +template +inline constexpr hecto_ hecto; +template +inline constexpr kilo_ kilo; +template +inline constexpr mega_ mega; +template +inline constexpr giga_ giga; +template +inline constexpr tera_ tera; +template +inline constexpr peta_ peta; +template +inline constexpr exa_ exa; +template +inline constexpr zetta_ zetta; +template +inline constexpr yotta_ yotta; + +} // namespace units::si diff --git a/src/systems/isq/include/units/isq/dimensions/luminous_intensity.h b/src/systems/si/include/units/si/si.h similarity index 81% rename from src/systems/isq/include/units/isq/dimensions/luminous_intensity.h rename to src/systems/si/include/units/si/si.h index fb04a3fe..70878f77 100644 --- a/src/systems/isq/include/units/isq/dimensions/luminous_intensity.h +++ b/src/systems/si/include/units/si/si.h @@ -22,14 +22,11 @@ #pragma once -#include - -namespace units::isq { - -template -struct dim_luminous_intensity : base_dimension<"J", U> {}; - -template -concept LuminousIntensity = QuantityOfT; - -} // namespace units::isq +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/src/systems/si/include/units/si/space_and_time.h b/src/systems/si/include/units/si/space_and_time.h new file mode 100644 index 00000000..697429d0 --- /dev/null +++ b/src/systems/si/include/units/si/space_and_time.h @@ -0,0 +1,64 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// 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. + +#pragma once + +#include +#include +#include + +namespace units::si { + +// clang-format off +inline constexpr struct length : system_reference {} length; +inline constexpr struct curvature : system_reference {} curvature; +inline constexpr struct area : system_reference> {} area; +inline constexpr struct volume : system_reference> {} volume; +inline constexpr struct angular_measure : system_reference {} angular_measure; +inline constexpr struct angular_displacement : system_reference {} angular_displacement; +inline constexpr struct phase_angle : system_reference {} phase_angle; +inline constexpr struct solid_angular_measure : system_reference {} solid_angular_measure; +inline constexpr struct time : system_reference {} time; // TODO called duration in ISO 80000 +// TODO there is also a velocity in ISO 80000 +inline constexpr struct speed : system_reference {} speed; +inline constexpr struct acceleration : system_reference> {} acceleration; +inline constexpr struct angular_velocity : system_reference {} angular_velocity; +inline constexpr struct angular_acceleration : system_reference> {} angular_acceleration; +inline constexpr struct period_duration : system_reference {} period_duration; +inline constexpr struct time_constant : system_reference {} time_constant; +inline constexpr struct rotation : system_reference {} rotation; +inline constexpr struct frequency : system_reference {} frequency; +inline constexpr struct rotational_frequency : system_reference {} rotational_frequency; +inline constexpr struct angular_frequency : system_reference {} angular_frequency; +inline constexpr struct wavelength : system_reference {} wavelength; +inline constexpr struct repetency : system_reference {} repetency; +inline constexpr struct wave_vector : system_reference {} wave_vector; +inline constexpr struct angular_repetency : system_reference {} angular_repetency; +inline constexpr struct phase_velocity : system_reference {} phase_velocity; +inline constexpr struct damping_coefficient : system_reference {} damping_coefficient; +inline constexpr struct logarithmic_decrement : system_reference {} logarithmic_decrement; +inline constexpr struct attenuation : system_reference {} attenuation; +inline constexpr struct phase_coefficient : system_reference {} phase_coefficient; +inline constexpr struct propagation_coefficient : system_reference {} propagation_coefficient; +// clang-format on + +} // namespace units::si diff --git a/src/systems/isq/include/units/isq/dimensions/area.h b/src/systems/si/include/units/si/thermodynamics.h similarity index 71% rename from src/systems/isq/include/units/isq/dimensions/area.h rename to src/systems/si/include/units/si/thermodynamics.h index f03a4209..33538eb9 100644 --- a/src/systems/isq/include/units/isq/dimensions/area.h +++ b/src/systems/si/include/units/si/thermodynamics.h @@ -22,18 +22,18 @@ #pragma once -#include -#include +#include +// #include +#include +#include +#include -namespace units::isq { +namespace units::si { -template -struct dim_area; +// inline constexpr struct thermodynamic_temperature : system_reference {} +// thermodynamic_temperature; -template L> -struct dim_area : derived_dimension> {}; +inline constexpr struct energy : system_reference { +} energy; -template -concept Area = QuantityOfT; - -} // namespace units::isq +} // namespace units::si diff --git a/src/systems/si/include/units/si/unit_symbols.h b/src/systems/si/include/units/si/unit_symbols.h new file mode 100644 index 00000000..49a4418b --- /dev/null +++ b/src/systems/si/include/units/si/unit_symbols.h @@ -0,0 +1,637 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// 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. + +#pragma once + +#include +#include + +namespace units::si::unit_symbols { + +inline constexpr auto ym = yocto; +inline constexpr auto zm = zepto; +inline constexpr auto am = atto; +inline constexpr auto fm = femto; +inline constexpr auto pm = pico; +inline constexpr auto nm = nano; +inline constexpr auto um = micro; +inline constexpr auto mm = milli; +inline constexpr auto cm = centi; +inline constexpr auto dm = deci; +inline constexpr auto m = metre; +inline constexpr auto dam = deca; +inline constexpr auto hm = hecto; +inline constexpr auto km = kilo; +inline constexpr auto Mm = mega; +inline constexpr auto Gm = giga; +inline constexpr auto Tm = tera; +inline constexpr auto Pm = peta; +inline constexpr auto Em = exa; +inline constexpr auto Zm = zetta; +inline constexpr auto Ym = yotta; + +inline constexpr auto ys = yocto; +inline constexpr auto zs = zepto; +inline constexpr auto as = atto; +inline constexpr auto fs = femto; +inline constexpr auto ps = pico; +inline constexpr auto ns = nano; +inline constexpr auto us = micro; +inline constexpr auto ms = milli; +inline constexpr auto cs = centi; +inline constexpr auto ds = deci; +inline constexpr auto s = second; +inline constexpr auto das = deca; +inline constexpr auto hs = hecto; +inline constexpr auto ks = kilo; +inline constexpr auto Ms = mega; +inline constexpr auto Gs = giga; +inline constexpr auto Ts = tera; +inline constexpr auto Ps = peta; +inline constexpr auto Es = exa; +inline constexpr auto Zs = zetta; +inline constexpr auto Ys = yotta; + +inline constexpr auto yg = yocto; +inline constexpr auto zg = zepto; +inline constexpr auto ag = atto; +inline constexpr auto fg = femto; +inline constexpr auto pg = pico; +inline constexpr auto ng = nano; +inline constexpr auto ug = micro; +inline constexpr auto mg = milli; +inline constexpr auto cg = centi; +inline constexpr auto dg = deci; +inline constexpr auto g = gram; +inline constexpr auto dag = deca; +inline constexpr auto hg = hecto; +inline constexpr auto kg = kilo; +inline constexpr auto Mg = mega; +inline constexpr auto Gg = giga; +inline constexpr auto Tg = tera; +inline constexpr auto Pg = peta; +inline constexpr auto Eg = exa; +inline constexpr auto Zg = zetta; +inline constexpr auto Yg = yotta; + +inline constexpr auto yA = yocto; +inline constexpr auto zA = zepto; +inline constexpr auto aA = atto; +inline constexpr auto fA = femto; +inline constexpr auto pA = pico; +inline constexpr auto nA = nano; +inline constexpr auto uA = micro; +inline constexpr auto mA = milli; +inline constexpr auto cA = centi; +inline constexpr auto dA = deci; +inline constexpr auto A = ampere; +inline constexpr auto daA = deca; +inline constexpr auto hA = hecto; +inline constexpr auto kA = kilo; +inline constexpr auto MA = mega; +inline constexpr auto GA = giga; +inline constexpr auto TA = tera; +inline constexpr auto PA = peta; +inline constexpr auto EA = exa; +inline constexpr auto ZA = zetta; +inline constexpr auto YA = yotta; + +inline constexpr auto yK = yocto; +inline constexpr auto zK = zepto; +inline constexpr auto aK = atto; +inline constexpr auto fK = femto; +inline constexpr auto pK = pico; +inline constexpr auto nK = nano; +inline constexpr auto uK = micro; +inline constexpr auto mK = milli; +inline constexpr auto cK = centi; +inline constexpr auto dK = deci; +inline constexpr auto K = kelvin; +inline constexpr auto daK = deca; +inline constexpr auto hK = hecto; +inline constexpr auto kK = kilo; +inline constexpr auto MK = mega; +inline constexpr auto GK = giga; +inline constexpr auto TK = tera; +inline constexpr auto PK = peta; +inline constexpr auto EK = exa; +inline constexpr auto ZK = zetta; +inline constexpr auto YK = yotta; + +inline constexpr auto ymol = yocto; +inline constexpr auto zmol = zepto; +inline constexpr auto amol = atto; +inline constexpr auto fmol = femto; +inline constexpr auto pmol = pico; +inline constexpr auto nmol = nano; +inline constexpr auto umol = micro; +inline constexpr auto mmol = milli; +inline constexpr auto cmol = centi; +inline constexpr auto dmol = deci; +inline constexpr auto mol = mole; +inline constexpr auto damol = deca; +inline constexpr auto hmol = hecto; +inline constexpr auto kmol = kilo; +inline constexpr auto Mmol = mega; +inline constexpr auto Gmol = giga; +inline constexpr auto Tmol = tera; +inline constexpr auto Pmol = peta; +inline constexpr auto Emol = exa; +inline constexpr auto Zmol = zetta; +inline constexpr auto Ymol = yotta; + +inline constexpr auto ycd = yocto; +inline constexpr auto zcd = zepto; +inline constexpr auto acd = atto; +inline constexpr auto fcd = femto; +inline constexpr auto pcd = pico; +inline constexpr auto ncd = nano; +inline constexpr auto ucd = micro; +inline constexpr auto mcd = milli; +inline constexpr auto ccd = centi; +inline constexpr auto dcd = deci; +inline constexpr auto cd = candela; +inline constexpr auto dacd = deca; +inline constexpr auto hcd = hecto; +inline constexpr auto kcd = kilo; +inline constexpr auto Mcd = mega; +inline constexpr auto Gcd = giga; +inline constexpr auto Tcd = tera; +inline constexpr auto Pcd = peta; +inline constexpr auto Ecd = exa; +inline constexpr auto Zcd = zetta; +inline constexpr auto Ycd = yotta; + +inline constexpr auto yrad = yocto; +inline constexpr auto zrad = zepto; +inline constexpr auto arad = atto; +inline constexpr auto frad = femto; +inline constexpr auto prad = pico; +inline constexpr auto nrad = nano; +inline constexpr auto urad = micro; +inline constexpr auto mrad = milli; +inline constexpr auto crad = centi; +inline constexpr auto drad = deci; +inline constexpr auto rad = radian; +inline constexpr auto darad = deca; +inline constexpr auto hrad = hecto; +inline constexpr auto krad = kilo; +inline constexpr auto Mrad = mega; +inline constexpr auto Grad = giga; +inline constexpr auto Trad = tera; +inline constexpr auto Prad = peta; +inline constexpr auto Erad = exa; +inline constexpr auto Zrad = zetta; +inline constexpr auto Yrad = yotta; + +inline constexpr auto ysr = yocto; +inline constexpr auto zsr = zepto; +inline constexpr auto asr = atto; +inline constexpr auto fsr = femto; +inline constexpr auto psr = pico; +inline constexpr auto nsr = nano; +inline constexpr auto usr = micro; +inline constexpr auto msr = milli; +inline constexpr auto csr = centi; +inline constexpr auto dsr = deci; +inline constexpr auto sr = steradian; +inline constexpr auto dasr = deca; +inline constexpr auto hsr = hecto; +inline constexpr auto ksr = kilo; +inline constexpr auto Msr = mega; +inline constexpr auto Gsr = giga; +inline constexpr auto Tsr = tera; +inline constexpr auto Psr = peta; +inline constexpr auto Esr = exa; +inline constexpr auto Zsr = zetta; +inline constexpr auto Ysr = yotta; + +inline constexpr auto yHz = yocto; +inline constexpr auto zHz = zepto; +inline constexpr auto aHz = atto; +inline constexpr auto fHz = femto; +inline constexpr auto pHz = pico; +inline constexpr auto nHz = nano; +inline constexpr auto uHz = micro; +inline constexpr auto mHz = milli; +inline constexpr auto cHz = centi; +inline constexpr auto dHz = deci; +inline constexpr auto Hz = hertz; +inline constexpr auto daHz = deca; +inline constexpr auto hHz = hecto; +inline constexpr auto kHz = kilo; +inline constexpr auto MHz = mega; +inline constexpr auto GHz = giga; +inline constexpr auto THz = tera; +inline constexpr auto PHz = peta; +inline constexpr auto EHz = exa; +inline constexpr auto ZHz = zetta; +inline constexpr auto YHz = yotta; + +inline constexpr auto yN = yocto; +inline constexpr auto zN = zepto; +inline constexpr auto aN = atto; +inline constexpr auto fN = femto; +inline constexpr auto pN = pico; +inline constexpr auto nN = nano; +inline constexpr auto uN = micro; +inline constexpr auto mN = milli; +inline constexpr auto cN = centi; +inline constexpr auto dN = deci; +inline constexpr auto N = newton; +inline constexpr auto daN = deca; +inline constexpr auto hN = hecto; +inline constexpr auto kN = kilo; +inline constexpr auto MN = mega; +inline constexpr auto GN = giga; +inline constexpr auto TN = tera; +inline constexpr auto PN = peta; +inline constexpr auto EN = exa; +inline constexpr auto ZN = zetta; +inline constexpr auto YN = yotta; + +inline constexpr auto yPa = yocto; +inline constexpr auto zPa = zepto; +inline constexpr auto aPa = atto; +inline constexpr auto fPa = femto; +inline constexpr auto pPa = pico; +inline constexpr auto nPa = nano; +inline constexpr auto uPa = micro; +inline constexpr auto mPa = milli; +inline constexpr auto cPa = centi; +inline constexpr auto dPa = deci; +inline constexpr auto Pa = pascal; +inline constexpr auto daPa = deca; +inline constexpr auto hPa = hecto; +inline constexpr auto kPa = kilo; +inline constexpr auto MPa = mega; +inline constexpr auto GPa = giga; +inline constexpr auto TPa = tera; +inline constexpr auto PPa = peta; +inline constexpr auto EPa = exa; +inline constexpr auto ZPa = zetta; +inline constexpr auto YPa = yotta; + +inline constexpr auto yJ = yocto; +inline constexpr auto zJ = zepto; +inline constexpr auto aJ = atto; +inline constexpr auto fJ = femto; +inline constexpr auto pJ = pico; +inline constexpr auto nJ = nano; +inline constexpr auto uJ = micro; +inline constexpr auto mJ = milli; +inline constexpr auto cJ = centi; +inline constexpr auto dJ = deci; +inline constexpr auto J = joule; +inline constexpr auto daJ = deca; +inline constexpr auto hJ = hecto; +inline constexpr auto kJ = kilo; +inline constexpr auto MJ = mega; +inline constexpr auto GJ = giga; +inline constexpr auto TJ = tera; +inline constexpr auto PJ = peta; +inline constexpr auto EJ = exa; +inline constexpr auto ZJ = zetta; +inline constexpr auto YJ = yotta; + +inline constexpr auto yW = yocto; +inline constexpr auto zW = zepto; +inline constexpr auto aW = atto; +inline constexpr auto fW = femto; +inline constexpr auto pW = pico; +inline constexpr auto nW = nano; +inline constexpr auto uW = micro; +inline constexpr auto mW = milli; +inline constexpr auto cW = centi; +inline constexpr auto dW = deci; +inline constexpr auto W = watt; +inline constexpr auto daW = deca; +inline constexpr auto hW = hecto; +inline constexpr auto kW = kilo; +inline constexpr auto MW = mega; +inline constexpr auto GW = giga; +inline constexpr auto TW = tera; +inline constexpr auto PW = peta; +inline constexpr auto EW = exa; +inline constexpr auto ZW = zetta; +inline constexpr auto YW = yotta; + +inline constexpr auto yC = yocto; +inline constexpr auto zC = zepto; +inline constexpr auto aC = atto; +inline constexpr auto fC = femto; +inline constexpr auto pC = pico; +inline constexpr auto nC = nano; +inline constexpr auto uC = micro; +inline constexpr auto mC = milli; +inline constexpr auto cC = centi; +inline constexpr auto dC = deci; +inline constexpr auto C = coulomb; +inline constexpr auto daC = deca; +inline constexpr auto hC = hecto; +inline constexpr auto kC = kilo; +inline constexpr auto MC = mega; +inline constexpr auto GC = giga; +inline constexpr auto TC = tera; +inline constexpr auto PC = peta; +inline constexpr auto EC = exa; +inline constexpr auto ZC = zetta; +inline constexpr auto YC = yotta; + +inline constexpr auto yV = yocto; +inline constexpr auto zV = zepto; +inline constexpr auto aV = atto; +inline constexpr auto fV = femto; +inline constexpr auto pV = pico; +inline constexpr auto nV = nano; +inline constexpr auto uV = micro; +inline constexpr auto mV = milli; +inline constexpr auto cV = centi; +inline constexpr auto dV = deci; +inline constexpr auto V = volt; +inline constexpr auto daV = deca; +inline constexpr auto hV = hecto; +inline constexpr auto kV = kilo; +inline constexpr auto MV = mega; +inline constexpr auto GV = giga; +inline constexpr auto TV = tera; +inline constexpr auto PV = peta; +inline constexpr auto EV = exa; +inline constexpr auto ZV = zetta; +inline constexpr auto YV = yotta; + +inline constexpr auto yF = yocto; +inline constexpr auto zF = zepto; +inline constexpr auto aF = atto; +inline constexpr auto fF = femto; +inline constexpr auto pF = pico; +inline constexpr auto nF = nano; +inline constexpr auto uF = micro; +inline constexpr auto mF = milli; +inline constexpr auto cF = centi; +inline constexpr auto dF = deci; +inline constexpr auto F = farad; +inline constexpr auto daF = deca; +inline constexpr auto hF = hecto; +inline constexpr auto kF = kilo; +inline constexpr auto MF = mega; +inline constexpr auto GF = giga; +inline constexpr auto TF = tera; +inline constexpr auto PF = peta; +inline constexpr auto EF = exa; +inline constexpr auto ZF = zetta; +inline constexpr auto YF = yotta; + +inline constexpr auto yS = yocto; +inline constexpr auto zS = zepto; +inline constexpr auto aS = atto; +inline constexpr auto fS = femto; +inline constexpr auto pS = pico; +inline constexpr auto nS = nano; +inline constexpr auto uS = micro; +inline constexpr auto mS = milli; +inline constexpr auto cS = centi; +inline constexpr auto dS = deci; +inline constexpr auto S = siemens; +inline constexpr auto daS = deca; +inline constexpr auto hS = hecto; +inline constexpr auto kS = kilo; +inline constexpr auto MS = mega; +inline constexpr auto GS = giga; +inline constexpr auto TS = tera; +inline constexpr auto PS = peta; +inline constexpr auto ES = exa; +inline constexpr auto ZS = zetta; +inline constexpr auto YS = yotta; + +inline constexpr auto yWb = yocto; +inline constexpr auto zWb = zepto; +inline constexpr auto aWb = atto; +inline constexpr auto fWb = femto; +inline constexpr auto pWb = pico; +inline constexpr auto nWb = nano; +inline constexpr auto uWb = micro; +inline constexpr auto mWb = milli; +inline constexpr auto cWb = centi; +inline constexpr auto dWb = deci; +inline constexpr auto Wb = weber; +inline constexpr auto daWb = deca; +inline constexpr auto hWb = hecto; +inline constexpr auto kWb = kilo; +inline constexpr auto MWb = mega; +inline constexpr auto GWb = giga; +inline constexpr auto TWb = tera; +inline constexpr auto PWb = peta; +inline constexpr auto EWb = exa; +inline constexpr auto ZWb = zetta; +inline constexpr auto YWb = yotta; + +inline constexpr auto yT = yocto; +inline constexpr auto zT = zepto; +inline constexpr auto aT = atto; +inline constexpr auto fT = femto; +inline constexpr auto pT = pico; +inline constexpr auto nT = nano; +inline constexpr auto uT = micro; +inline constexpr auto mT = milli; +inline constexpr auto cT = centi; +inline constexpr auto dT = deci; +inline constexpr auto T = tesla; +inline constexpr auto daT = deca; +inline constexpr auto hT = hecto; +inline constexpr auto kT = kilo; +inline constexpr auto MT = mega; +inline constexpr auto GT = giga; +inline constexpr auto TT = tera; +inline constexpr auto PT = peta; +inline constexpr auto ET = exa; +inline constexpr auto ZT = zetta; +inline constexpr auto YT = yotta; + +inline constexpr auto yH = yocto; +inline constexpr auto zH = zepto; +inline constexpr auto aH = atto; +inline constexpr auto fH = femto; +inline constexpr auto pH = pico; +inline constexpr auto nH = nano; +inline constexpr auto uH = micro; +inline constexpr auto mH = milli; +inline constexpr auto cH = centi; +inline constexpr auto dH = deci; +inline constexpr auto H = henry; +inline constexpr auto daH = deca; +inline constexpr auto hH = hecto; +inline constexpr auto kH = kilo; +inline constexpr auto MH = mega; +inline constexpr auto GH = giga; +inline constexpr auto TH = tera; +inline constexpr auto PH = peta; +inline constexpr auto EH = exa; +inline constexpr auto ZH = zetta; +inline constexpr auto YH = yotta; + +inline constexpr auto deg_C = degree_Celsius; + +inline constexpr auto ylm = yocto; +inline constexpr auto zlm = zepto; +inline constexpr auto alm = atto; +inline constexpr auto flm = femto; +inline constexpr auto plm = pico; +inline constexpr auto nlm = nano; +inline constexpr auto ulm = micro; +inline constexpr auto mlm = milli; +inline constexpr auto clm = centi; +inline constexpr auto dlm = deci; +inline constexpr auto lm = lumen; +inline constexpr auto dalm = deca; +inline constexpr auto hlm = hecto; +inline constexpr auto klm = kilo; +inline constexpr auto Mlm = mega; +inline constexpr auto Glm = giga; +inline constexpr auto Tlm = tera; +inline constexpr auto Plm = peta; +inline constexpr auto Elm = exa; +inline constexpr auto Zlm = zetta; +inline constexpr auto Ylm = yotta; + +inline constexpr auto ylx = yocto; +inline constexpr auto zlx = zepto; +inline constexpr auto alx = atto; +inline constexpr auto flx = femto; +inline constexpr auto plx = pico; +inline constexpr auto nlx = nano; +inline constexpr auto ulx = micro; +inline constexpr auto mlx = milli; +inline constexpr auto clx = centi; +inline constexpr auto dlx = deci; +inline constexpr auto lx = lux; +inline constexpr auto dalx = deca; +inline constexpr auto hlx = hecto; +inline constexpr auto klx = kilo; +inline constexpr auto Mlx = mega; +inline constexpr auto Glx = giga; +inline constexpr auto Tlx = tera; +inline constexpr auto Plx = peta; +inline constexpr auto Elx = exa; +inline constexpr auto Zlx = zetta; +inline constexpr auto Ylx = yotta; + +inline constexpr auto yBq = yocto; +inline constexpr auto zBq = zepto; +inline constexpr auto aBq = atto; +inline constexpr auto fBq = femto; +inline constexpr auto pBq = pico; +inline constexpr auto nBq = nano; +inline constexpr auto uBq = micro; +inline constexpr auto mBq = milli; +inline constexpr auto cBq = centi; +inline constexpr auto dBq = deci; +inline constexpr auto Bq = becquerel; +inline constexpr auto daBq = deca; +inline constexpr auto hBq = hecto; +inline constexpr auto kBq = kilo; +inline constexpr auto MBq = mega; +inline constexpr auto GBq = giga; +inline constexpr auto TBq = tera; +inline constexpr auto PBq = peta; +inline constexpr auto EBq = exa; +inline constexpr auto ZBq = zetta; +inline constexpr auto YBq = yotta; + +inline constexpr auto yGy = yocto; +inline constexpr auto zGy = zepto; +inline constexpr auto aGy = atto; +inline constexpr auto fGy = femto; +inline constexpr auto pGy = pico; +inline constexpr auto nGy = nano; +inline constexpr auto uGy = micro; +inline constexpr auto mGy = milli; +inline constexpr auto cGy = centi; +inline constexpr auto dGy = deci; +inline constexpr auto Gy = gray; +inline constexpr auto daGy = deca; +inline constexpr auto hGy = hecto; +inline constexpr auto kGy = kilo; +inline constexpr auto MGy = mega; +inline constexpr auto GGy = giga; +inline constexpr auto TGy = tera; +inline constexpr auto PGy = peta; +inline constexpr auto EGy = exa; +inline constexpr auto ZGy = zetta; +inline constexpr auto YGy = yotta; + +inline constexpr auto ySv = yocto; +inline constexpr auto zSv = zepto; +inline constexpr auto aSv = atto; +inline constexpr auto fSv = femto; +inline constexpr auto pSv = pico; +inline constexpr auto nSv = nano; +inline constexpr auto uSv = micro; +inline constexpr auto mSv = milli; +inline constexpr auto cSv = centi; +inline constexpr auto dSv = deci; +inline constexpr auto Sv = sievert; +inline constexpr auto daSv = deca; +inline constexpr auto hSv = hecto; +inline constexpr auto kSv = kilo; +inline constexpr auto MSv = mega; +inline constexpr auto GSv = giga; +inline constexpr auto TSv = tera; +inline constexpr auto PSv = peta; +inline constexpr auto ESv = exa; +inline constexpr auto ZSv = zetta; +inline constexpr auto YSv = yotta; + +inline constexpr auto ykat = yocto; +inline constexpr auto zkat = zepto; +inline constexpr auto akat = atto; +inline constexpr auto fkat = femto; +inline constexpr auto pkat = pico; +inline constexpr auto nkat = nano; +inline constexpr auto ukat = micro; +inline constexpr auto mkat = milli; +inline constexpr auto ckat = centi; +inline constexpr auto dkat = deci; +inline constexpr auto kat = katal; +inline constexpr auto dakat = deca; +inline constexpr auto hkat = hecto; +inline constexpr auto kkat = kilo; +inline constexpr auto Mkat = mega; +inline constexpr auto Gkat = giga; +inline constexpr auto Tkat = tera; +inline constexpr auto Pkat = peta; +inline constexpr auto Ekat = exa; +inline constexpr auto Zkat = zetta; +inline constexpr auto Ykat = yotta; + +inline constexpr auto min = minute; +inline constexpr auto h = hour; +inline constexpr auto d = day; +inline constexpr auto au = astronomical_unit; +inline constexpr auto a = are; +inline constexpr auto ha = hectare; +inline constexpr auto l = litre; +inline constexpr auto t = tonne; +inline constexpr auto Da = dalton; +inline constexpr auto eV = electronvolt; + +} // namespace units::si::unit_symbols diff --git a/src/systems/si/include/units/si/units.h b/src/systems/si/include/units/si/units.h new file mode 100644 index 00000000..2768c444 --- /dev/null +++ b/src/systems/si/include/units/si/units.h @@ -0,0 +1,88 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// 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. + +#pragma once + +#include +#include + +namespace units::si { + +// clang-format off +// base units +inline constexpr struct second : named_unit<"s"> {} second; +inline constexpr struct metre : named_unit<"m"> {} metre; +inline constexpr struct gram : named_unit<"g"> {} gram; +inline constexpr struct kilogram : decltype(kilo) {} kilogram; +inline constexpr struct ampere : named_unit<"A"> {} ampere; +inline constexpr struct kelvin : named_unit<"K"> {} kelvin; +inline constexpr struct mole : named_unit<"mol"> {} mole; +inline constexpr struct candela : named_unit<"cd"> {} candela; + +// derived named units +inline constexpr struct radian : named_unit<"rad", metre / metre> {} radian; +inline constexpr struct steradian : named_unit<"sr", square / square> {} steradian; +inline constexpr struct hertz : named_unit<"Hz", 1 / second> {} hertz; +inline constexpr struct newton : named_unit<"N", kilogram * metre / square> {} newton; +inline constexpr struct pascal : named_unit<"Pa", newton / square> {} pascal; +inline constexpr struct joule : named_unit<"J", newton * metre> {} joule; +inline constexpr struct watt : named_unit<"W", joule / second> {} watt; +inline constexpr struct coulomb : named_unit<"C", ampere * second> {} coulomb; +inline constexpr struct volt : named_unit<"V", watt / ampere> {} volt; +inline constexpr struct farad : named_unit<"F", coulomb / volt> {} farad; +inline constexpr struct ohm : named_unit {} ohm; +inline constexpr struct siemens : named_unit<"S", 1 / ohm> {} siemens; +inline constexpr struct weber : named_unit<"Wb", volt * second> {} weber; +inline constexpr struct tesla : named_unit<"T", weber / square> {} tesla; +inline constexpr struct henry : named_unit<"H", weber / ampere> {} henry; +inline constexpr struct degree_Celsius : named_unit {} degree_Celsius; +inline constexpr struct lumen : named_unit<"lm", candela * steradian> {} lumen; +inline constexpr struct lux : named_unit<"lx", lumen / square> {} lux; +inline constexpr struct becquerel : named_unit<"Bq", 1 / second> {} becquerel; +inline constexpr struct gray : named_unit<"Gy", joule / kilogram> {} gray; +inline constexpr struct sievert : named_unit<"Sv", joule / kilogram> {} sievert; +inline constexpr struct katal : named_unit<"kat", mole / second> {} katal; + +// non-SI units accepted for use with the SI +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 day : named_unit<"d", mag<24> * hour> {} day; +inline constexpr struct astronomical_unit : named_unit<"au", mag<149'597'870'700> * metre> {} astronomical_unit; +inline constexpr struct degree : named_unit * radian> {} degree; +// TODO how to disambiguate below angular units from time units +// inline constexpr struct minute : named_unit * degree> {} minute; +// inline constexpr struct second : named_unit * minute> {} second; +inline constexpr struct are : named_unit<"a", square>> {} are; +inline constexpr struct hectare : decltype(hecto) {} hectare; +inline constexpr struct litre : named_unit<"l", cubic>> {} litre; +inline constexpr struct tonne : named_unit<"t", mag<1000> * kilogram> {} tonne; +inline constexpr struct dalton : named_unit<"Da", mag * mag_power<10, -27> * kilogram> {} dalton; +// TODO A different value is provided in the SI Brochure and different in the ISO 80000 +inline constexpr struct electronvolt : named_unit<"eV", mag * mag_power<10, -19> * joule> {} electronvolt; +// TODO the below are logarithmic units - how to support those? +// neper +// bel +// decibel + +// clang-format on + +} // namespace units::si diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b90032e9..e59fd801 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -22,6 +22,7 @@ cmake_minimum_required(VERSION 3.2) -add_subdirectory(unit_test/runtime) +# add_subdirectory(unit_test/runtime) add_subdirectory(unit_test/static) -#add_subdirectory(metabench) + +# add_subdirectory(metabench) diff --git a/test/unit_test/runtime/CMakeLists.txt b/test/unit_test/runtime/CMakeLists.txt index 61a67670..16cc33be 100644 --- a/test/unit_test/runtime/CMakeLists.txt +++ b/test/unit_test/runtime/CMakeLists.txt @@ -25,7 +25,9 @@ cmake_minimum_required(VERSION 3.2) find_package(Catch2 3 CONFIG REQUIRED) add_executable( - unit_tests_runtime math_test.cpp magnitude_test.cpp fmt_test.cpp fmt_units_test.cpp distribution_test.cpp + unit_tests_runtime + # math_test.cpp + magnitude_test.cpp # fmt_test.cpp fmt_units_test.cpp distribution_test.cpp ) target_link_libraries(unit_tests_runtime PRIVATE mp-units::mp-units Catch2::Catch2WithMain) diff --git a/test/unit_test/runtime/magnitude_test.cpp b/test/unit_test/runtime/magnitude_test.cpp deleted file mode 100644 index dddd2785..00000000 --- a/test/unit_test/runtime/magnitude_test.cpp +++ /dev/null @@ -1,622 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#include -#include -#include -#include - -using namespace units; -using namespace units::detail; - -template<> -inline constexpr std::optional units::known_first_factor<9223372036854775783> = 9223372036854775783; - -namespace { - -// A set of non-standard bases for testing purposes. -struct noninteger_base { - static constexpr long double value = 1.234L; -}; -struct noncanonical_two_base { - static constexpr long double value = 2.0L; -}; -struct other_noncanonical_two_base { - static constexpr long double value = 2.0L; -}; -struct invalid_zero_base { - static constexpr long double value = 0.0L; -}; -struct invalid_negative_base { - static constexpr long double value = -1.234L; -}; - -template -constexpr auto pi_to_the() -{ - return magnitude{Power}>{}; -} - -template -void check_same_type_and_value(T actual, U expected) -{ - CHECK(std::is_same_v); - CHECK(actual == expected); -} - -template -void check_ratio_round_trip_is_identity() -{ - constexpr Magnitude auto m = mag(); - constexpr ratio round_trip = ratio{ - get_value(numerator(m)), - get_value(denominator(m)), - }; - CHECK(round_trip == R); -} - - -TEST_CASE("base_power") -{ - SECTION("base rep deducible for integral base") - { - CHECK(base_power{2} == base_power{2, ratio{1}}); - CHECK(base_power{2, 3} == base_power{2, ratio{3}}); - CHECK(base_power{2, ratio{3, 4}} == base_power{2, ratio{3, 4}}); - } - - SECTION("get_base retrieves base for integral base") - { - CHECK(base_power{2}.get_base() == 2); - CHECK(base_power{3, 5}.get_base() == 3); - CHECK(base_power{5, ratio{1, 3}}.get_base() == 5); - } - - SECTION("get_base retrieves member value for non-integer base") - { - CHECK(base_power{}.get_base() == 1.234L); - CHECK(base_power{2}.get_base() == 1.234L); - CHECK(base_power{ratio{5, 8}}.get_base() == 1.234L); - } - - SECTION("same-base values not equal if types are different") - { - const auto a = base_power{}; - const auto b = base_power{2}; - const auto c = base_power{}; - - REQUIRE(a.get_base() == b.get_base()); - CHECK(a != b); - - REQUIRE(a.get_base() == c.get_base()); - CHECK(a != c); - } - - SECTION("same-type values not equal if bases are different") - { - CHECK(base_power{2} != base_power{3}); - CHECK(base_power{2, ratio{5, 4}} != base_power{3, ratio{5, 4}}); - } - - SECTION("same-type, same-base values not equal if powers are different") - { - CHECK(base_power{2} != base_power{2, 2}); - CHECK(base_power{} != base_power{ratio{1, 3}}); - } - - SECTION("product with inverse equals identity") - { - auto check_product_with_inverse_is_identity = [](auto x) { CHECK(x * pow<-1>(x) == mag<1>()); }; - - check_product_with_inverse_is_identity(mag<3>()); - check_product_with_inverse_is_identity(mag()); - check_product_with_inverse_is_identity(pi_to_the()); - } - - SECTION("pow() multiplies exponent") - { - CHECK(pow(base_power{2}, 0) == base_power{2, 0}); - CHECK(pow(base_power{2, 3}, ratio{-1, 2}) == base_power{2, ratio{-3, 2}}); - CHECK(pow(base_power{ratio{3, 2}}, ratio{1, 3}) == base_power{ratio{1, 2}}); - } -} - -TEST_CASE("make_ratio performs prime factorization correctly") -{ - SECTION("Performs prime factorization when denominator is 1") - { - CHECK(mag<1>() == magnitude<>{}); - CHECK(mag<2>() == magnitude{}); - CHECK(mag<3>() == magnitude{}); - CHECK(mag<4>() == magnitude{}); - - CHECK(mag<792>() == magnitude{}); - } - - SECTION("Supports fractions") { CHECK(mag() == magnitude{}); } - - SECTION("Can handle prime factor which would be large enough to overflow int") - { - // This was taken from a case which failed when we used `int` for our base to store prime numbers. - // The failure was due to a prime factor which is larger than 2^31. - mag(); - } - - SECTION("Can bypass computing primes by providing known_first_factor") - { - // Sometimes, even wheel factorization isn't enough to handle the compilers' limits on constexpr steps and/or - // iterations. To work around these cases, we can explicitly provide the correct answer directly to the compiler. - // - // In this case, we test that we can represent the largest prime that fits in a signed 64-bit int. The reason this - // test can pass is that we have provided the answer, by specializing the `known_first_factor` variable template - // above in this file. - mag<9'223'372'036'854'775'783>(); - } -} - -TEST_CASE("magnitude converts to numerical value") -{ - SECTION("Positive integer powers of integer bases give integer values") - { - constexpr auto mag_412 = mag<412>(); - check_same_type_and_value(get_value(mag_412), 412); - check_same_type_and_value(get_value(mag_412), std::size_t{412}); - check_same_type_and_value(get_value(mag_412), 412.0f); - check_same_type_and_value(get_value(mag_412), 412.0); - } - - SECTION("Negative integer powers of integer bases compute correct values") - { - constexpr auto mag_0p125 = mag(); - check_same_type_and_value(get_value(mag_0p125), 0.125f); - check_same_type_and_value(get_value(mag_0p125), 0.125); - } - - SECTION("pi to the 1 supplies correct values") - { - check_same_type_and_value(get_value(mag_pi), std::numbers::pi_v); - check_same_type_and_value(get_value(mag_pi), std::numbers::pi_v); - check_same_type_and_value(get_value(mag_pi), std::numbers::pi_v); - } - - SECTION("pi to arbitrary power performs computations in most accurate type at compile time") - { - if constexpr (sizeof(float) < sizeof(long double)) { - constexpr auto pi_cubed = pi_to_the<3>(); - - auto cube = [](auto x) { return x * x * x; }; - constexpr auto via_float = cube(std::numbers::pi_v); - constexpr auto via_long_double = static_cast(cube(std::numbers::pi_v)); - - constexpr auto pi_cubed_value = get_value(pi_cubed); - REQUIRE(pi_cubed_value != via_float); - CHECK(pi_cubed_value == via_long_double); - } - } - - SECTION("Impossible requests are prevented at compile time") - { - // Naturally, we cannot actually write a test to verify a compiler error. But any of these can - // be uncommented if desired to verify that it breaks the build. - - // get_value(mag<412>()); - - // Would work for pow<62>: - // get_value(pow<63>(mag<2>())); - - // Would work for pow<63>: - // get_value(pow<64>(mag<2>())); - - get_value(pow<308>(mag<10>())); // Compiles, correctly. - // get_value(pow<309>(mag<10>())); - // get_value(pow<3099>(mag<10>())); - // get_value(pow<3099999>(mag<10>())); - - auto sqrt_2 = pow(mag<2>()); - CHECK(!is_integral(sqrt_2)); - // get_value(sqrt_2); - } -} - -TEST_CASE("Equality works for magnitudes") -{ - SECTION("Equivalent ratios are equal") - { - CHECK(mag<1>() == mag<1>()); - CHECK(mag<3>() == mag<3>()); - CHECK(mag() == mag()); - } - - SECTION("Different ratios are unequal") - { - CHECK(mag<3>() != mag<5>()); - CHECK(mag<3>() != mag()); - } - - SECTION("Supports constexpr") - { - constexpr auto eq = (mag() == mag()); - CHECK(!eq); - } -} - -TEST_CASE("Multiplication works for magnitudes") -{ - SECTION("Reciprocals reduce to null magnitude") { CHECK(mag() * mag() == mag<1>()); } - - SECTION("Products work as expected") { CHECK(mag() * mag() == mag()); } - - SECTION("Products handle pi correctly") - { - CHECK(pi_to_the<1>() * mag() * pi_to_the() == - magnitude{ratio{1, 2}}>{}); - } - - SECTION("Supports constexpr") - { - constexpr auto p = mag() * mag(); - CHECK(p == mag()); - } -} - -TEST_CASE("Common Magnitude") -{ - SECTION("Identity for identical magnitudes") - { - CHECK(common_magnitude(mag<1>(), mag<1>()) == mag<1>()); - CHECK(common_magnitude(mag<15>(), mag<15>()) == mag<15>()); - CHECK(common_magnitude(pi_to_the(), pi_to_the()) == pi_to_the()); - } - - SECTION("Greatest Common Factor for integers") - { - CHECK(common_magnitude(mag<24>(), mag<36>()) == mag<12>()); - CHECK(common_magnitude(mag<24>(), mag<37>()) == mag<1>()); - } - - SECTION("Handles fractions") - { - CHECK(common_magnitude(mag(), mag()) == mag()); - } -} - -TEST_CASE("Division works for magnitudes") -{ - SECTION("Dividing anything by itself reduces to null magnitude") - { - CHECK(mag() / mag() == mag<1>()); - CHECK(mag<15>() / mag<15>() == mag<1>()); - } - - SECTION("Quotients work as expected") { CHECK(mag() / mag() == mag()); } - - SECTION("Supports constexpr") - { - constexpr auto q = mag() / mag(); - CHECK(q == mag()); - } -} - -TEST_CASE("Can raise Magnitudes to rational powers") -{ - SECTION("Anything to the 0 is 1") - { - CHECK(pow<0>(mag<1>()) == mag<1>()); - CHECK(pow<0>(mag<123>()) == mag<1>()); - CHECK(pow<0>(mag()) == mag<1>()); - CHECK(pow<0>(pi_to_the()) == mag<1>()); - } - - SECTION("Anything to the 1 is itself") - { - CHECK(pow<1>(mag<1>()) == mag<1>()); - CHECK(pow<1>(mag<123>()) == mag<123>()); - CHECK(pow<1>(mag()) == mag()); - CHECK(pow<1>(pi_to_the()) == pi_to_the()); - } - - SECTION("Can raise to arbitrary rational power") - { - CHECK(pow(pi_to_the()) == pi_to_the()); - } -} - -TEST_CASE("can distinguish integral, rational, and irrational magnitudes") -{ - SECTION("Integer magnitudes are integral and rational") - { - auto check_rational_and_integral = [](Magnitude auto m) { - CHECK(is_integral(m)); - CHECK(is_rational(m)); - }; - check_rational_and_integral(magnitude<>{}); - check_rational_and_integral(mag<1>()); - check_rational_and_integral(mag<3>()); - check_rational_and_integral(mag<8>()); - check_rational_and_integral(mag<412>()); - check_rational_and_integral(mag()); - } - - SECTION("Fractional magnitudes are rational, but not integral") - { - auto check_rational_but_not_integral = [](Magnitude auto m) { - CHECK(!is_integral(m)); - CHECK(is_rational(m)); - }; - check_rational_but_not_integral(mag()); - check_rational_but_not_integral(mag()); - } -} - -TEST_CASE("Constructing ratio from rational magnitude") -{ - SECTION("Round trip is identity") - { - // Note that not every Magnitude can be represented as a ratio. However, if we _start_ with a - // ratio, we must guarantee to recover the same ratio in a round trip. - check_ratio_round_trip_is_identity<1>(); - check_ratio_round_trip_is_identity<9>(); - check_ratio_round_trip_is_identity(); - } - - SECTION("Rational magnitude converts to ratio") - { - constexpr ratio r = as_ratio(mag()); - CHECK(r == ratio{22, 7}); - } - - SECTION("Irrational magnitude does not convert to ratio") - { - // The following code should not compile. - // as_ratio(pow(mag<2>())); - - // The following code should not compile. - // as_ratio(mag<180>() / pi_to_the<1>()); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Detail function tests below. - -TEST_CASE("int_power computes integer powers") -{ - SECTION("handles floating point") - { - check_same_type_and_value(int_power(0.123L, 0), 1.0L); - check_same_type_and_value(int_power(0.246f, 1), 0.246f); - check_same_type_and_value(int_power(0.5f, 3), 0.125f); - check_same_type_and_value(int_power(2.5, 4), 39.0625); - - CHECK(std::is_same_v(base_power{10, 20}))>); - } - - SECTION("handles integral") - { - check_same_type_and_value(int_power(8, 0), 1); - check_same_type_and_value(int_power(9L, 1), 9L); - check_same_type_and_value(int_power(2, 10), 1024); - } -} - -TEST_CASE("integer_part picks out integer part of single-basis magnitude") -{ - SECTION("integer_part of non-integer base is identity magnitude") - { - CHECK(integer_part(pi_to_the<1>()) == magnitude<>{}); - CHECK(integer_part(pi_to_the<-8>()) == magnitude<>{}); - CHECK(integer_part(pi_to_the()) == magnitude<>{}); - } - - SECTION("integer_part of integer base to negative power is identity magnitude") - { - CHECK(integer_part(magnitude{}) == magnitude<>{}); - CHECK(integer_part(magnitude{}) == magnitude<>{}); - } - - SECTION("integer_part of integer base to fractional power is identity magnitude") - { - CHECK(integer_part(magnitude{}) == magnitude<>{}); - } - - SECTION("integer_part of integer base to power at least one takes integer part") - { - CHECK(integer_part(magnitude{}) == magnitude{}); - CHECK(integer_part(magnitude{}) == magnitude{}); - CHECK(integer_part(magnitude{}) == magnitude{}); - } -} - -TEST_CASE("Prime helper functions") -{ - SECTION("multiplicity") - { - CHECK(multiplicity(2, 8) == 3); - CHECK(multiplicity(2, 1024) == 10); - CHECK(multiplicity(11, 6655) == 3); - } - - SECTION("remove_power()") - { - CHECK(remove_power(17, 0, 5) == 5); - CHECK(remove_power(2, 3, 24) == 3); - CHECK(remove_power(11, 3, 6655) == 5); - } -} - -TEST_CASE("Prime factorization") -{ - SECTION("1 factors into the null magnitude") { CHECK(prime_factorization_v<1> == magnitude<>{}); } - - SECTION("Prime numbers factor into themselves") - { - CHECK(prime_factorization_v<2> == magnitude{}); - CHECK(prime_factorization_v<3> == magnitude{}); - CHECK(prime_factorization_v<5> == magnitude{}); - CHECK(prime_factorization_v<7> == magnitude{}); - CHECK(prime_factorization_v<11> == magnitude{}); - - CHECK(prime_factorization_v<41> == magnitude{}); - } - - SECTION("Prime factorization finds factors and multiplicities") - { - CHECK(prime_factorization_v<792> == magnitude{}); - } -} - -TEST_CASE("is_prime detects primes") -{ - SECTION("Non-positive numbers are not prime") - { - CHECK(!is_prime(-1328)); - CHECK(!is_prime(-1)); - CHECK(!is_prime(0)); - } - - SECTION("1 is not prime") { CHECK(!is_prime(1)); } - - SECTION("Discriminates between primes and non-primes") - { - CHECK(is_prime(2)); - CHECK(is_prime(3)); - CHECK(!is_prime(4)); - CHECK(is_prime(5)); - CHECK(!is_prime(6)); - CHECK(is_prime(7)); - CHECK(!is_prime(8)); - CHECK(!is_prime(9)); - - CHECK(is_prime(7919)); - } -} - -TEST_CASE("is_valid_base_power") -{ - SECTION("0 power is invalid") - { - REQUIRE(is_valid_base_power(base_power{2})); - CHECK(!is_valid_base_power(base_power{2, 0})); - - REQUIRE(is_valid_base_power(base_power{41})); - CHECK(!is_valid_base_power(base_power{41, 0})); - - REQUIRE(is_valid_base_power(base_power{})); - CHECK(!is_valid_base_power(base_power{0})); - } - - SECTION("non-prime integers are invalid") - { - CHECK(!is_valid_base_power(base_power{-8})); - CHECK(!is_valid_base_power(base_power{0})); - CHECK(!is_valid_base_power(base_power{1})); - - CHECK(is_valid_base_power(base_power{2})); - CHECK(is_valid_base_power(base_power{3})); - - CHECK(!is_valid_base_power(base_power{4})); - } - - SECTION("non-positive floating point bases are invalid") - { - CHECK(!is_valid_base_power(base_power{})); - CHECK(!is_valid_base_power(base_power{})); - } -} - -TEST_CASE("pairwise_all evaluates all pairs") -{ - const auto all_pairs_return_true = pairwise_all{[](auto, auto) { return true; }}; - const auto all_pairs_return_false = pairwise_all{[](auto, auto) { return false; }}; - const auto all_increasing = pairwise_all{std::less{}}; - - SECTION("always true for empty tuples") - { - CHECK(all_pairs_return_true()); - CHECK(all_pairs_return_false()); - } - - SECTION("always true for single-element tuples") - { - CHECK(all_pairs_return_true(1)); - CHECK(all_pairs_return_false(3.14)); - CHECK(all_pairs_return_true('x')); - } - - SECTION("true for longer tuples iff true for all neighbouring pairs") - { - CHECK(all_increasing(1, 1.5)); - CHECK(all_increasing(1, 1.5, 2)); - - CHECK(!all_increasing(1, 2.0, 2)); - CHECK(!all_increasing(1, 2.5, 2)); - - CHECK(all_pairs_return_true('c', 1, 8.9, 42u)); - CHECK(!all_pairs_return_false('c', 1, 8.9, 42u)); - } -} - -TEST_CASE("strictly_increasing") -{ - SECTION("Empty input is sorted") { CHECK(strictly_increasing()); } - - SECTION("Single-element input is sorted") - { - CHECK(strictly_increasing(3)); - CHECK(strictly_increasing(15.42)); - CHECK(strictly_increasing('c')); - } - - SECTION("Multi-value inputs compare correctly") - { - CHECK(strictly_increasing(3, 3.14)); - CHECK(!strictly_increasing(3, 3.0)); - CHECK(!strictly_increasing(4, 3.0)); - } -} - -TEST_CASE("extract_power_of_10") -{ - SECTION("Picks out positive powers") - { - CHECK(extract_power_of_10(mag<10>()) == 1); - CHECK(extract_power_of_10(mag<20>()) == 1); - CHECK(extract_power_of_10(mag<40>()) == 1); - CHECK(extract_power_of_10(mag<50>()) == 1); - CHECK(extract_power_of_10(mag<100>()) == 2); - } - - SECTION("Picks out negative powers") - { - constexpr auto ONE = mag<1>(); - CHECK(extract_power_of_10(ONE / mag<10>()) == -1); - CHECK(extract_power_of_10(ONE / mag<20>()) == -1); - CHECK(extract_power_of_10(ONE / mag<40>()) == -1); - CHECK(extract_power_of_10(ONE / mag<50>()) == -1); - CHECK(extract_power_of_10(ONE / mag<100>()) == -2); - } - - SECTION("Zero if signs disagree") { CHECK(extract_power_of_10(mag<2>() / mag<5>()) == 0); } - - SECTION("Handles rational powers") { CHECK(extract_power_of_10(sqrt(mag<1000>())) == 1); } -} - -} // namespace diff --git a/test/unit_test/static/CMakeLists.txt b/test/unit_test/static/CMakeLists.txt index 632592f8..6abc8d0a 100644 --- a/test/unit_test/static/CMakeLists.txt +++ b/test/unit_test/static/CMakeLists.txt @@ -22,48 +22,50 @@ cmake_minimum_required(VERSION 3.2) -add_library(unit_tests_static_truncating quantity_test.cpp) +# add_library(unit_tests_static_truncating quantity_test.cpp) -if(NOT ${projectPrefix}LIBCXX) - target_sources(unit_tests_static_truncating PRIVATE quantity_kind_test.cpp quantity_point_kind_test.cpp) -endif() - -target_link_libraries(unit_tests_static_truncating PRIVATE mp-units::mp-units) -target_compile_options( - unit_tests_static_truncating PRIVATE $,/wd4242 /wd4244,-Wno-conversion> -) +# if(NOT ${projectPrefix}LIBCXX) +# target_sources(unit_tests_static_truncating PRIVATE quantity_kind_test.cpp quantity_point_kind_test.cpp) +# endif() +# target_link_libraries(unit_tests_static_truncating PRIVATE mp-units::mp-units) +# target_compile_options( +# unit_tests_static_truncating PRIVATE $,/wd4242 /wd4244,-Wno-conversion> +# ) add_library( unit_tests_static - angle_test.cpp - cgs_test.cpp - chrono_test.cpp - concepts_test.cpp - custom_rep_test_min_expl.cpp - custom_unit_test.cpp - dimension_op_test.cpp - dimensions_concepts_test.cpp - fixed_string_test.cpp - fps_test.cpp - iec80000_test.cpp - kind_test.cpp - math_test.cpp - point_origin_test.cpp - prime_test.cpp - ratio_test.cpp - references_test.cpp - si_test.cpp - si_cgs_test.cpp - si_fps_test.cpp - si_hep_test.cpp - symbol_text_test.cpp - type_list_test.cpp - unit_test.cpp - us_test.cpp + dimension_test.cpp + # angle_test.cpp + # cgs_test.cpp + # chrono_test.cpp + # concepts_test.cpp + # custom_rep_test_min_expl.cpp + # custom_unit_test.cpp + # dimension_op_test.cpp + # dimensions_concepts_test.cpp + # fixed_string_test.cpp + # fps_test.cpp + # iec80000_test.cpp + # kind_test.cpp + magnitude_test.cpp + # math_test.cpp + # point_origin_test.cpp + # prime_test.cpp + # ratio_test.cpp + # references_test.cpp + # si_test.cpp + # si_cgs_test.cpp + # si_fps_test.cpp + # si_hep_test.cpp + # symbol_text_test.cpp + # type_list_test.cpp + # unit_test.cpp + # us_test.cpp ) -if(NOT ${projectPrefix}LIBCXX) - target_sources(unit_tests_static PRIVATE custom_rep_test_min_impl.cpp quantity_point_test.cpp) -endif() +# if(NOT ${projectPrefix}LIBCXX) +# target_sources(unit_tests_static PRIVATE custom_rep_test_min_impl.cpp quantity_point_test.cpp) +# endif() +target_link_libraries(unit_tests_static PRIVATE mp-units::mp-units) -target_link_libraries(unit_tests_static PRIVATE unit_tests_static_truncating mp-units::mp-units) +# target_link_libraries(unit_tests_static PRIVATE unit_tests_static_truncating mp-units::mp-units) diff --git a/test/unit_test/static/dimension_test.cpp b/test/unit_test/static/dimension_test.cpp index c2d3a62d..4cc2958e 100644 --- a/test/unit_test/static/dimension_test.cpp +++ b/test/unit_test/static/dimension_test.cpp @@ -105,32 +105,45 @@ static_assert(is_of_type<1 / (speed_dim * speed_dim) * length_dim, // comparisons of equivalent dimensions static_assert(length_dim / length_dim == one_dim); -static_assert(1 / time_dim == frequency_dim); +static_assert(1 / time_dim != frequency_dim); +static_assert(equivalent(1 / time_dim, frequency_dim)); static_assert(1 / frequency_dim == time_dim); static_assert(frequency_dim * time_dim == one_dim); -static_assert(length_dim * length_dim == area_dim); +static_assert(length_dim * length_dim != area_dim); +static_assert(equivalent(length_dim * length_dim, area_dim)); static_assert(length_dim * length_dim != volume_dim); static_assert(area_dim / length_dim == length_dim); -static_assert(length_dim * length_dim * length_dim == volume_dim); -static_assert(area_dim * length_dim == volume_dim); -static_assert(volume_dim / length_dim == area_dim); +static_assert(length_dim * length_dim * length_dim != volume_dim); +static_assert(equivalent(length_dim * length_dim * length_dim, volume_dim)); +static_assert(area_dim * length_dim != volume_dim); +static_assert(equivalent(area_dim * length_dim, volume_dim)); +static_assert(volume_dim / length_dim != area_dim); +static_assert(equivalent(volume_dim / length_dim, area_dim)); static_assert(volume_dim / length_dim / length_dim == length_dim); -static_assert(area_dim * area_dim / length_dim == volume_dim); -static_assert(area_dim * (area_dim / length_dim) == volume_dim); +static_assert(area_dim * area_dim / length_dim != volume_dim); +static_assert(equivalent(area_dim * area_dim / length_dim, volume_dim)); +static_assert(area_dim * (area_dim / length_dim) != volume_dim); +static_assert(equivalent(area_dim * (area_dim / length_dim), volume_dim)); static_assert(volume_dim / (length_dim * length_dim) == length_dim); -static_assert(length_dim / time_dim == speed_dim); +static_assert(length_dim / time_dim != speed_dim); +static_assert(equivalent(length_dim / time_dim, speed_dim)); static_assert(length_dim * time_dim != speed_dim); static_assert(length_dim / time_dim / time_dim != speed_dim); static_assert(length_dim / speed_dim == time_dim); static_assert(speed_dim * time_dim == length_dim); -static_assert(length_dim / time_dim / time_dim == acceleration_dim); -static_assert(length_dim / (time_dim * time_dim) == acceleration_dim); -static_assert(speed_dim / time_dim == acceleration_dim); +static_assert(length_dim / time_dim / time_dim != acceleration_dim); +static_assert(equivalent(length_dim / time_dim / time_dim, acceleration_dim)); +static_assert(length_dim / (time_dim * time_dim) != acceleration_dim); +static_assert(equivalent(length_dim / (time_dim * time_dim), acceleration_dim)); +static_assert(speed_dim / time_dim != acceleration_dim); +static_assert(equivalent(speed_dim / time_dim, acceleration_dim)); static_assert(speed_dim / acceleration_dim == time_dim); -static_assert(acceleration_dim * time_dim == speed_dim); +static_assert(acceleration_dim * time_dim != speed_dim); +static_assert(equivalent(acceleration_dim * time_dim, speed_dim)); static_assert(acceleration_dim * (time_dim * time_dim) == length_dim); -static_assert(acceleration_dim / speed_dim == frequency_dim); +static_assert(acceleration_dim / speed_dim != frequency_dim); +static_assert(equivalent(acceleration_dim / speed_dim, frequency_dim)); diff --git a/test/unit_test/static/magnitude_test.cpp b/test/unit_test/static/magnitude_test.cpp new file mode 100644 index 00000000..c986373e --- /dev/null +++ b/test/unit_test/static/magnitude_test.cpp @@ -0,0 +1,648 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// 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. + +#include +#include +#include + +using namespace units; +using namespace units::detail; + +template<> +inline constexpr std::optional units::known_first_factor<9223372036854775783> = 9223372036854775783; + +namespace { + +// A set of non-standard bases for testing purposes. +// struct noninteger_base { +// static constexpr long double value = 1.234L; +// }; +// struct noncanonical_two_base { +// static constexpr long double value = 2.0L; +// }; +// struct other_noncanonical_two_base { +// static constexpr long double value = 2.0L; +// }; +// struct invalid_zero_base { +// static constexpr long double value = 0.0L; +// }; +// struct invalid_negative_base { +// static constexpr long double value = -1.234L; +// }; + +// template +// void check_same_type_and_value(T actual, U expected) +// { +// CHECK(std::is_same_v); +// CHECK(actual == expected); +// } + +// template +// void check_ratio_round_trip_is_identity() +// { +// constexpr Magnitude auto m = mag(); +// constexpr ratio round_trip = ratio{ +// get_value(numerator(m)), +// get_value(denominator(m)), +// }; +// CHECK(round_trip == R); +// } + +inline constexpr struct mag_2_ : magnitude<2> { +} mag_2; +// inline constexpr struct mag_2_other : magnitude<2> { +// } mag_2_other; +// inline constexpr struct mag_3 : magnitude<2> { +// } mag_3; + +// concepts verification +static_assert(Magnitude)>); +static_assert(Magnitude); + +// is_named_magnitude +static_assert(!is_named_magnitude)>>); +static_assert(is_named_magnitude); + +// power_v +template typename P> +concept invalid_power_v = requires { + requires !requires { typename P<123, 0>; }; + requires !requires { typename P<123, 0, 2>; }; + requires !requires { typename P<123, 1, 0>; }; + requires !requires { typename P<123, 0, 0>; }; + requires !requires { typename P<123, 1>; }; + requires !requires { typename P<123, 1, 1>; }; + requires !requires { typename P<123, 5, 5>; }; + }; +static_assert(invalid_power_v); + +// get_base +// get_base retrieves value for integral base +static_assert(get_base(2) == 2); +static_assert(get_base(power_v<3, 5>{}) == 3); +static_assert(get_base(power_v<5, 1, 3>{}) == 5); + +// get_base retrieves value for integral base +static_assert(get_base(2) == 2); +static_assert(get_base(power_v<3, 5>{}) == 3); +static_assert(get_base(power_v<5, 1, 3>{}) == 5); + +// get_base retrieves named magnitude for named base +static_assert(std::is_same_v); +static_assert(std::is_same_v{})), mag_2_>); +static_assert(std::is_same_v{})), mag_2_>); + + +// equality +// static_assert(mag_2 == mag_2); +// static_assert(mag_2 != mag_3); +// static_assert(mag_2 != mag_2_other); + +// { +// const auto a = base_power{}; +// const auto b = base_power{2}; +// const auto c = base_power{}; + +// REQUIRE(a.get_base() == b.get_base()); +// CHECK(a != b); + +// REQUIRE(a.get_base() == c.get_base()); +// CHECK(a != c); +// } + +// SECTION("same-type values not equal if bases are different") +// { +// CHECK(base_power{2} != base_power{3}); +// CHECK(base_power{2, ratio{5, 4}} != base_power{3, ratio{5, 4}}); +// } + +// SECTION("same-type, same-base values not equal if powers are different") +// { +// CHECK(base_power{2} != base_power{2, 2}); +// CHECK(base_power{} != base_power{ratio{1, 3}}); +// } + +// SECTION("product with inverse equals identity") +// { +// auto check_product_with_inverse_is_identity = [](auto x) { CHECK(x * pow<-1>(x) == mag<1>()); }; + +// check_product_with_inverse_is_identity(mag<3>()); +// check_product_with_inverse_is_identity(mag()); +// check_product_with_inverse_is_identity(pi_to_the()); +// } + +// SECTION("pow() multiplies exponent") +// { +// CHECK(pow(base_power{2}, 0) == base_power{2, 0}); +// CHECK(pow(base_power{2, 3}, ratio{-1, 2}) == base_power{2, ratio{-3, 2}}); +// CHECK(pow(base_power{ratio{3, 2}}, ratio{1, 3}) == base_power{ratio{1, 2}}); +// } + +// TEST_CASE("make_ratio performs prime factorization correctly") +// { +// SECTION("Performs prime factorization when denominator is 1") +// { +// CHECK(mag<1>() == magnitude<>{}); +// CHECK(mag<2>() == magnitude{}); +// CHECK(mag<3>() == magnitude{}); +// CHECK(mag<4>() == magnitude{}); + +// CHECK(mag<792>() == magnitude{}); +// } + +// SECTION("Supports fractions") { CHECK(mag() == magnitude{}); } + +// SECTION("Can handle prime factor which would be large enough to overflow int") +// { +// // This was taken from a case which failed when we used `int` for our base to store prime numbers. +// // The failure was due to a prime factor which is larger than 2^31. +// mag(); +// } + +// SECTION("Can bypass computing primes by providing known_first_factor") +// { +// // Sometimes, even wheel factorization isn't enough to handle the compilers' limits on constexpr steps and/or +// // iterations. To work around these cases, we can explicitly provide the correct answer directly to the +// compiler. +// // +// // In this case, we test that we can represent the largest prime that fits in a signed 64-bit int. The reason +// this +// // test can pass is that we have provided the answer, by specializing the `known_first_factor` variable template +// // above in this file. +// mag<9'223'372'036'854'775'783>(); +// } +// } + +// TEST_CASE("magnitude converts to numerical value") +// { +// SECTION("Positive integer powers of integer bases give integer values") +// { +// constexpr auto mag_412 = mag<412>(); +// check_same_type_and_value(get_value(mag_412), 412); +// check_same_type_and_value(get_value(mag_412), std::size_t{412}); +// check_same_type_and_value(get_value(mag_412), 412.0f); +// check_same_type_and_value(get_value(mag_412), 412.0); +// } + +// SECTION("Negative integer powers of integer bases compute correct values") +// { +// constexpr auto mag_0p125 = mag(); +// check_same_type_and_value(get_value(mag_0p125), 0.125f); +// check_same_type_and_value(get_value(mag_0p125), 0.125); +// } + +// SECTION("pi to the 1 supplies correct values") +// { +// check_same_type_and_value(get_value(mag_pi), std::numbers::pi_v); +// check_same_type_and_value(get_value(mag_pi), std::numbers::pi_v); +// check_same_type_and_value(get_value(mag_pi), std::numbers::pi_v); +// } + +// SECTION("pi to arbitrary power performs computations in most accurate type at compile time") +// { +// if constexpr (sizeof(float) < sizeof(long double)) { +// constexpr auto pi_cubed = pi_to_the<3>(); + +// auto cube = [](auto x) { return x * x * x; }; +// constexpr auto via_float = cube(std::numbers::pi_v); +// constexpr auto via_long_double = static_cast(cube(std::numbers::pi_v)); + +// constexpr auto pi_cubed_value = get_value(pi_cubed); +// REQUIRE(pi_cubed_value != via_float); +// CHECK(pi_cubed_value == via_long_double); +// } +// } + +// SECTION("Impossible requests are prevented at compile time") +// { +// // Naturally, we cannot actually write a test to verify a compiler error. But any of these can +// // be uncommented if desired to verify that it breaks the build. + +// // get_value(mag<412>()); + +// // Would work for pow<62>: +// // get_value(pow<63>(mag<2>())); + +// // Would work for pow<63>: +// // get_value(pow<64>(mag<2>())); + +// get_value(pow<308>(mag<10>())); // Compiles, correctly. +// // get_value(pow<309>(mag<10>())); +// // get_value(pow<3099>(mag<10>())); +// // get_value(pow<3099999>(mag<10>())); + +// auto sqrt_2 = pow(mag<2>()); +// CHECK(!is_integral(sqrt_2)); +// // get_value(sqrt_2); +// } +// } + +// TEST_CASE("Equality works for magnitudes") +// { +// SECTION("Equivalent ratios are equal") +// { +// CHECK(mag<1>() == mag<1>()); +// CHECK(mag<3>() == mag<3>()); +// CHECK(mag() == mag()); +// } + +// SECTION("Different ratios are unequal") +// { +// CHECK(mag<3>() != mag<5>()); +// CHECK(mag<3>() != mag()); +// } + +// SECTION("Supports constexpr") +// { +// constexpr auto eq = (mag() == mag()); +// CHECK(!eq); +// } +// } + +// TEST_CASE("Multiplication works for magnitudes") +// { +// SECTION("Reciprocals reduce to null magnitude") { CHECK(mag() * mag() == mag<1>()); } + +// SECTION("Products work as expected") { CHECK(mag() * mag() == mag()); } + +// SECTION("Products handle pi correctly") +// { +// CHECK(pi_to_the<1>() * mag() * pi_to_the() == +// magnitude{ratio{1, 2}}>{}); +// } + +// SECTION("Supports constexpr") +// { +// constexpr auto p = mag() * mag(); +// CHECK(p == mag()); +// } +// } + +// TEST_CASE("Common Magnitude") +// { +// SECTION("Identity for identical magnitudes") +// { +// CHECK(common_magnitude(mag<1>(), mag<1>()) == mag<1>()); +// CHECK(common_magnitude(mag<15>(), mag<15>()) == mag<15>()); +// CHECK(common_magnitude(pi_to_the(), pi_to_the()) == pi_to_the()); +// } + +// SECTION("Greatest Common Factor for integers") +// { +// CHECK(common_magnitude(mag<24>(), mag<36>()) == mag<12>()); +// CHECK(common_magnitude(mag<24>(), mag<37>()) == mag<1>()); +// } + +// SECTION("Handles fractions") +// { +// CHECK(common_magnitude(mag(), mag()) == mag()); +// } +// } + +// TEST_CASE("Division works for magnitudes") +// { +// SECTION("Dividing anything by itself reduces to null magnitude") +// { +// CHECK(mag() / mag() == mag<1>()); +// CHECK(mag<15>() / mag<15>() == mag<1>()); +// } + +// SECTION("Quotients work as expected") { CHECK(mag() / mag() == mag()); } + +// SECTION("Supports constexpr") +// { +// constexpr auto q = mag() / mag(); +// CHECK(q == mag()); +// } +// } + +// TEST_CASE("Can raise Magnitudes to rational powers") +// { +// SECTION("Anything to the 0 is 1") +// { +// CHECK(pow<0>(mag<1>()) == mag<1>()); +// CHECK(pow<0>(mag<123>()) == mag<1>()); +// CHECK(pow<0>(mag()) == mag<1>()); +// CHECK(pow<0>(pi_to_the()) == mag<1>()); +// } + +// SECTION("Anything to the 1 is itself") +// { +// CHECK(pow<1>(mag<1>()) == mag<1>()); +// CHECK(pow<1>(mag<123>()) == mag<123>()); +// CHECK(pow<1>(mag()) == mag()); +// CHECK(pow<1>(pi_to_the()) == pi_to_the()); +// } + +// SECTION("Can raise to arbitrary rational power") +// { +// CHECK(pow(pi_to_the()) == pi_to_the()); +// } +// } + +// TEST_CASE("can distinguish integral, rational, and irrational magnitudes") +// { +// SECTION("Integer magnitudes are integral and rational") +// { +// auto check_rational_and_integral = [](Magnitude auto m) { +// CHECK(is_integral(m)); +// CHECK(is_rational(m)); +// }; +// check_rational_and_integral(magnitude<>{}); +// check_rational_and_integral(mag<1>()); +// check_rational_and_integral(mag<3>()); +// check_rational_and_integral(mag<8>()); +// check_rational_and_integral(mag<412>()); +// check_rational_and_integral(mag()); +// } + +// SECTION("Fractional magnitudes are rational, but not integral") +// { +// auto check_rational_but_not_integral = [](Magnitude auto m) { +// CHECK(!is_integral(m)); +// CHECK(is_rational(m)); +// }; +// check_rational_but_not_integral(mag()); +// check_rational_but_not_integral(mag()); +// } +// } + +// TEST_CASE("Constructing ratio from rational magnitude") +// { +// SECTION("Round trip is identity") +// { +// // Note that not every Magnitude can be represented as a ratio. However, if we _start_ with a +// // ratio, we must guarantee to recover the same ratio in a round trip. +// check_ratio_round_trip_is_identity<1>(); +// check_ratio_round_trip_is_identity<9>(); +// check_ratio_round_trip_is_identity(); +// } + +// SECTION("Rational magnitude converts to ratio") +// { +// constexpr ratio r = as_ratio(mag()); +// CHECK(r == ratio{22, 7}); +// } + +// SECTION("Irrational magnitude does not convert to ratio") +// { +// // The following code should not compile. +// // as_ratio(pow(mag<2>())); + +// // The following code should not compile. +// // as_ratio(mag<180>() / pi_to_the<1>()); +// } +// } + +// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// // Detail function tests below. + +// TEST_CASE("int_power computes integer powers") +// { +// SECTION("handles floating point") +// { +// check_same_type_and_value(int_power(0.123L, 0), 1.0L); +// check_same_type_and_value(int_power(0.246f, 1), 0.246f); +// check_same_type_and_value(int_power(0.5f, 3), 0.125f); +// check_same_type_and_value(int_power(2.5, 4), 39.0625); + +// CHECK(std::is_same_v(base_power{10, 20}))>); +// } + +// SECTION("handles integral") +// { +// check_same_type_and_value(int_power(8, 0), 1); +// check_same_type_and_value(int_power(9L, 1), 9L); +// check_same_type_and_value(int_power(2, 10), 1024); +// } +// } + +// TEST_CASE("integer_part picks out integer part of single-basis magnitude") +// { +// SECTION("integer_part of non-integer base is identity magnitude") +// { +// CHECK(integer_part(pi_to_the<1>()) == magnitude<>{}); +// CHECK(integer_part(pi_to_the<-8>()) == magnitude<>{}); +// CHECK(integer_part(pi_to_the()) == magnitude<>{}); +// } + +// SECTION("integer_part of integer base to negative power is identity magnitude") +// { +// CHECK(integer_part(magnitude{}) == magnitude<>{}); +// CHECK(integer_part(magnitude{}) == magnitude<>{}); +// } + +// SECTION("integer_part of integer base to fractional power is identity magnitude") +// { +// CHECK(integer_part(magnitude{}) == magnitude<>{}); +// } + +// SECTION("integer_part of integer base to power at least one takes integer part") +// { +// CHECK(integer_part(magnitude{}) == magnitude{}); +// CHECK(integer_part(magnitude{}) == magnitude{}); +// CHECK(integer_part(magnitude{}) == magnitude{}); +// } +// } + +// TEST_CASE("Prime helper functions") +// { +// SECTION("multiplicity") +// { +// CHECK(multiplicity(2, 8) == 3); +// CHECK(multiplicity(2, 1024) == 10); +// CHECK(multiplicity(11, 6655) == 3); +// } + +// SECTION("remove_power()") +// { +// CHECK(remove_power(17, 0, 5) == 5); +// CHECK(remove_power(2, 3, 24) == 3); +// CHECK(remove_power(11, 3, 6655) == 5); +// } +// } + +// TEST_CASE("Prime factorization") +// { +// SECTION("1 factors into the null magnitude") { CHECK(prime_factorization_v<1> == magnitude<>{}); } + +// SECTION("Prime numbers factor into themselves") +// { +// CHECK(prime_factorization_v<2> == magnitude{}); +// CHECK(prime_factorization_v<3> == magnitude{}); +// CHECK(prime_factorization_v<5> == magnitude{}); +// CHECK(prime_factorization_v<7> == magnitude{}); +// CHECK(prime_factorization_v<11> == magnitude{}); + +// CHECK(prime_factorization_v<41> == magnitude{}); +// } + +// SECTION("Prime factorization finds factors and multiplicities") +// { +// CHECK(prime_factorization_v<792> == magnitude{}); +// } +// } + +// TEST_CASE("is_prime detects primes") +// { +// SECTION("Non-positive numbers are not prime") +// { +// CHECK(!is_prime(-1328)); +// CHECK(!is_prime(-1)); +// CHECK(!is_prime(0)); +// } + +// SECTION("1 is not prime") { CHECK(!is_prime(1)); } + +// SECTION("Discriminates between primes and non-primes") +// { +// CHECK(is_prime(2)); +// CHECK(is_prime(3)); +// CHECK(!is_prime(4)); +// CHECK(is_prime(5)); +// CHECK(!is_prime(6)); +// CHECK(is_prime(7)); +// CHECK(!is_prime(8)); +// CHECK(!is_prime(9)); + +// CHECK(is_prime(7919)); +// } +// } + +// TEST_CASE("is_valid_base_power") +// { +// SECTION("0 power is invalid") +// { +// REQUIRE(is_valid_base_power(base_power{2})); +// CHECK(!is_valid_base_power(base_power{2, 0})); + +// REQUIRE(is_valid_base_power(base_power{41})); +// CHECK(!is_valid_base_power(base_power{41, 0})); + +// REQUIRE(is_valid_base_power(base_power{})); +// CHECK(!is_valid_base_power(base_power{0})); +// } + +// SECTION("non-prime integers are invalid") +// { +// CHECK(!is_valid_base_power(base_power{-8})); +// CHECK(!is_valid_base_power(base_power{0})); +// CHECK(!is_valid_base_power(base_power{1})); + +// CHECK(is_valid_base_power(base_power{2})); +// CHECK(is_valid_base_power(base_power{3})); + +// CHECK(!is_valid_base_power(base_power{4})); +// } + +// SECTION("non-positive floating point bases are invalid") +// { +// CHECK(!is_valid_base_power(base_power{})); +// CHECK(!is_valid_base_power(base_power{})); +// } +// } + +// TEST_CASE("pairwise_all evaluates all pairs") +// { +// const auto all_pairs_return_true = pairwise_all{[](auto, auto) { return true; }}; +// const auto all_pairs_return_false = pairwise_all{[](auto, auto) { return false; }}; +// const auto all_increasing = pairwise_all{std::less{}}; + +// SECTION("always true for empty tuples") +// { +// CHECK(all_pairs_return_true()); +// CHECK(all_pairs_return_false()); +// } + +// SECTION("always true for single-element tuples") +// { +// CHECK(all_pairs_return_true(1)); +// CHECK(all_pairs_return_false(3.14)); +// CHECK(all_pairs_return_true('x')); +// } + +// SECTION("true for longer tuples iff true for all neighbouring pairs") +// { +// CHECK(all_increasing(1, 1.5)); +// CHECK(all_increasing(1, 1.5, 2)); + +// CHECK(!all_increasing(1, 2.0, 2)); +// CHECK(!all_increasing(1, 2.5, 2)); + +// CHECK(all_pairs_return_true('c', 1, 8.9, 42u)); +// CHECK(!all_pairs_return_false('c', 1, 8.9, 42u)); +// } +// } + +// TEST_CASE("strictly_increasing") +// { +// SECTION("Empty input is sorted") { CHECK(strictly_increasing()); } + +// SECTION("Single-element input is sorted") +// { +// CHECK(strictly_increasing(3)); +// CHECK(strictly_increasing(15.42)); +// CHECK(strictly_increasing('c')); +// } + +// SECTION("Multi-value inputs compare correctly") +// { +// CHECK(strictly_increasing(3, 3.14)); +// CHECK(!strictly_increasing(3, 3.0)); +// CHECK(!strictly_increasing(4, 3.0)); +// } +// } + +// TEST_CASE("extract_power_of_10") +// { +// SECTION("Picks out positive powers") +// { +// CHECK(extract_power_of_10(mag<10>()) == 1); +// CHECK(extract_power_of_10(mag<20>()) == 1); +// CHECK(extract_power_of_10(mag<40>()) == 1); +// CHECK(extract_power_of_10(mag<50>()) == 1); +// CHECK(extract_power_of_10(mag<100>()) == 2); +// } + +// SECTION("Picks out negative powers") +// { +// constexpr auto ONE = mag<1>(); +// CHECK(extract_power_of_10(ONE / mag<10>()) == -1); +// CHECK(extract_power_of_10(ONE / mag<20>()) == -1); +// CHECK(extract_power_of_10(ONE / mag<40>()) == -1); +// CHECK(extract_power_of_10(ONE / mag<50>()) == -1); +// CHECK(extract_power_of_10(ONE / mag<100>()) == -2); +// } + +// SECTION("Zero if signs disagree") { CHECK(extract_power_of_10(mag<2>() / mag<5>()) == 0); } + +// SECTION("Handles rational powers") { CHECK(extract_power_of_10(sqrt(mag<1000>())) == 1); } +// } + +} // namespace + + +// mag<2> * Constant<2> * Constant<3> * Constant<2> * mag<3> * mag<2> * mag<2> * Constant<2> -> pow, 3>, +// pow, 3>, Constant<3>, mag<3> + +// mag_A * mag<2> * magA +// mag<2> * mag_A * magAA * magA -> the same value different name diff --git a/test/unit_test/static/unit_test.cpp b/test/unit_test/static/unit_test.cpp index ded5edad..4c3c4569 100644 --- a/test/unit_test/static/unit_test.cpp +++ b/test/unit_test/static/unit_test.cpp @@ -30,6 +30,83 @@ namespace { +// clang-format off +// base units +inline constexpr struct second_ : named_unit<"s"> {} second; +inline constexpr struct metre_ : named_unit<"m"> {} metre; +inline constexpr struct gram_ : named_unit<"g"> {} gram; +inline constexpr struct kilogram_ : decltype(kilo) {} kilogram; + +// derived named units +inline constexpr struct radian_ : named_unit<"rad", metre / metre> {} radian; +inline constexpr struct steradian_ : named_unit<"sr", square / square> {} steradian; +inline constexpr struct hertz_ : named_unit<"Hz", 1 / second> {} hertz; +inline constexpr struct becquerel : named_unit<"Bq", 1 / second> {} becquerel; +inline constexpr struct newton_ : named_unit<"N", kilogram * metre / square> {} newton; +inline constexpr struct pascal_ : named_unit<"Pa", newton / square> {} pascal; +inline constexpr struct joule_ : named_unit<"J", newton * metre> {} joule; +inline constexpr struct watt_ : 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 day_ : named_unit<"d", mag<24> * hour> {} day; +inline constexpr struct astronomical_unit_ : named_unit<"au", mag<149'597'870'700> * metre> {} astronomical_unit; +inline constexpr struct degree_ : named_unit * radian> {} degree; +inline constexpr struct are_ : named_unit<"a", square>> {} are; +inline constexpr struct hectare_ : decltype(hecto) {} hectare; +inline constexpr struct litre_ : named_unit<"l", cubic>> {} litre; +inline constexpr struct tonne_ : named_unit<"t", mag<1000> * kilogram> {} tonne; +inline constexpr struct dalton_ : named_unit<"Da", mag * mag_power<10, -27> * kilogram> {} dalton; +inline constexpr struct electronvolt_ : named_unit<"eV", mag * mag_power<10, -19> * joule> {} electronvolt; + +inline constexpr struct kilometre_ : decltype(kilo) {} kilometre; +// clang-format on + +} + +// concepts verification +static_assert(Unit); +static_assert(Unit); +static_assert(Unit); +static_assert(Unit); +static_assert(Unit); +static_assert(Unit)>); +static_assert(Unit)>); +static_assert(Unit)>); +static_assert(Unit * second)>); +static_assert(Unit); + +static_assert(NamedUnit); +static_assert(NamedUnit); +static_assert(NamedUnit); +static_assert(NamedUnit); +static_assert(NamedUnit); +static_assert(!NamedUnit)>); +static_assert(!NamedUnit)>); +static_assert(!NamedUnit)>); +static_assert(!NamedUnit * second)>); +static_assert(!NamedUnit); + + +static_assert(kilo == kilometre); +static_assert(mag<1000> * metre == kilo); +static_assert(mag<1000> * metre == kilometre); +static_assert(equivalent, kilometre>); +static_assert(equivalent * metre, kilo>); +static_assert(equivalent * metre, kilometre>); + +static_assert(metre != kilometre); +static_assert(mag<100> * metre != kilometre); +static_assert(milli != kilometre); +static_assert(!equivalent); +static_assert(!equivalent * metre, kilometre>); +static_assert(!equivalent, kilometre>); + +static_assert(1 / second != hertz); +static_assert(becquerel != hertz); +static_assert(equivalent<1 / second, hertz>); +static_assert(!equivalent); + using namespace units; using namespace units::isq; From cf0a770d9bbd4825f4b711b543f34307959fed35 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Sun, 9 Oct 2022 21:32:38 +0100 Subject: [PATCH 020/402] refactor: quantity arithmetics implemented --- example/v2_framework.cpp | 108 ++++- src/core/include/units/bits/common_type.h | 122 ----- src/core/include/units/concepts.h | 12 +- src/core/include/units/dimension.h | 17 + src/core/include/units/quantity.h | 58 ++- src/core/include/units/quantity_cast.h | 537 +++++++++++----------- src/core/include/units/reference.h | 33 +- src/core/include/units/unit.h | 32 +- test/unit_test/static/dimension_test.cpp | 32 +- 9 files changed, 506 insertions(+), 445 deletions(-) delete mode 100644 src/core/include/units/bits/common_type.h diff --git a/example/v2_framework.cpp b/example/v2_framework.cpp index 952f02bc..5328425e 100644 --- a/example/v2_framework.cpp +++ b/example/v2_framework.cpp @@ -23,6 +23,9 @@ #include +template +consteval bool print(); + template constexpr bool is_of_type(Expr) { @@ -34,33 +37,102 @@ namespace { using namespace units; using namespace units::si::unit_symbols; -constexpr auto power = 5 * si::power[W]; -static_assert(is_of_type{}, int>>(power)); +// clang-format off +inline constexpr struct activity_dim : decltype(1 / isq::time_dim) {} activity_dim; +inline constexpr struct activity : system_reference {} activity; +// clang-format on -constexpr auto speed = 5 * si::speed[m / s]; + +// Named quantity/dimension and unit static_assert( - is_of_type>>{}, int>>( - speed)); + is_same_v{}, int>>); -constexpr auto q = 10 * si::length[m] / (2 * si::time[s]); -static_assert(is_of_type>, - derived_unit>>{}, - int>>(q)); +// Named quantity/dimension and derived (unnamed) unit +static_assert( + is_same_v>>{}, int>>); -constexpr auto distance = 5 * si::speed[m / s] * (5 * si::time[s]); +// Derived (unnamed) quantity/dimension and derived (unnamed) unit +static_assert(is_same_v>, + derived_unit>>{}, + int>>); -static_assert(is_of_type{}, int>>(distance)); +// Base quantity as a result of dimensional transformation +static_assert(is_same_v{}, int>>); -constexpr auto dimensionless = 20 * si::speed[m / s] / (10 * si::length[m]) * (5 * si::time[s]); +// Dimensionless +static_assert(is_same_v{}, int>>); -static_assert(is_of_type{}, int>>(dimensionless)); +// Comparisons +// Named and derived dimensions (same units) +static_assert(10 * si::length[m] / (2 * si::time[s]) == 5 * si::speed[m / s]); +static_assert(5 * si::speed[m / s] == 10 * si::length[m] / (2 * si::time[s])); -// constexpr auto q1 = 10 * si::length[m] / (2 * si::time[s]) + 5 * si::speed[m / s]; -// static_assert(is_of_type>, -// derived_unit>>{}, -// int>>(q1)); +// Named and derived dimensions (different units) +static_assert(10 / (2 * si::time[s]) == 5 * si::frequency[Hz]); +static_assert(5 * si::frequency[Hz] == 10 / (2 * si::time[s])); +// Different named dimensions +template +concept invalid_comparison = requires { + requires !requires { 2 * R1 == 2 * R2; }; + requires !requires { 2 * R2 == 2 * R1; }; + }; +static_assert(invalid_comparison); + +// static_assert(print()); + +// Arithmetics + +// Named and derived dimensions (same units) +static_assert(10 * si::length[m] / (2 * si::time[s]) + 5 * si::speed[m / s] == 10 * si::speed[m / s]); +static_assert(5 * si::speed[m / s] + 10 * si::length[m] / (2 * si::time[s]) == 10 * si::speed[m / s]); +static_assert(10 * si::length[m] / (2 * si::time[s]) - 5 * si::speed[m / s] == 0 * si::speed[m / s]); +static_assert(5 * si::speed[m / s] - 10 * si::length[m] / (2 * si::time[s]) == 0 * si::speed[m / s]); +static_assert( + is_same_v>>{}, int>>); +static_assert( + is_same_v>>{}, int>>); +static_assert( + is_same_v>>{}, int>>); +static_assert( + is_same_v>>{}, int>>); + +// Named and derived dimensions (different units) +static_assert(10 / (2 * si::time[s]) + 5 * si::frequency[Hz] == 10 * si::frequency[Hz]); +static_assert(5 * si::frequency[Hz] + 10 / (2 * si::time[s]) == 10 * si::frequency[Hz]); +static_assert(10 / (2 * si::time[s]) - 5 * si::frequency[Hz] == 0 * si::frequency[Hz]); +static_assert(5 * si::frequency[Hz] - 10 / (2 * si::time[s]) == 0 * si::frequency[Hz]); +static_assert(is_same_v{}, int>>); +static_assert(is_same_v{}, int>>); +static_assert(is_same_v{}, int>>); +static_assert(is_same_v{}, int>>); + +// Different named dimensions +template +consteval bool invalid_arithmetic(Ts... ts) +{ + return requires { + requires !requires { (... + ts); }; + requires !requires { (... - ts); }; + }; +} +static_assert(invalid_arithmetic(5 * activity[Bq], 5 * si::frequency[Hz])); +static_assert(invalid_arithmetic(5 * activity[Bq], 10 / (2 * si::time[s]), 5 * si::frequency[Hz])); + +// static_assert(quantity_of); // static_assert(quantity_of); // static_assert(quantity_of); // static_assert(!quantity_of); @@ -222,8 +294,6 @@ namespace units::isq::si { // quantity speed3(20); // quantity speed4(20); -template -void print(); // constexpr auto avg_speed(quantity d, quantity t) { return d / t; } diff --git a/src/core/include/units/bits/common_type.h b/src/core/include/units/bits/common_type.h deleted file mode 100644 index 05288572..00000000 --- a/src/core/include/units/bits/common_type.h +++ /dev/null @@ -1,122 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include -// #include -// #include - -namespace units { - -// template U, Representation Rep> -// class quantity_point; - -// template U, Representation Rep> -// class quantity_kind; - -// template U, Representation Rep> -// class quantity_point_kind; - -// TODO common_unit should use common_magnitude(U1::mag, U2::mag) - -template - requires(equivalent(D1{}, D2{})) -using common_dimension = conditional, D1, detail::dim_type>; - -template -// requires(equivalent) -using common_unit = U1; - -namespace detail { - -template -struct common_quantity_reference_impl; - -template -struct common_quantity_reference_impl { - using type = R; -}; - -template -struct common_quantity_reference_impl, reference> { - using type = reference>; -}; - -template - requires(equivalent(R1::dimension, R2::dimension)) -struct common_quantity_reference_impl { - using type = reference, - common_unit>; -}; - -template Q2> -using common_quantity_reference = - TYPENAME detail::common_quantity_reference_impl, - std::remove_const_t>::type; - -} // namespace detail -} // namespace units - -namespace std { - -template Q2> - requires requires { typename common_type_t; } -struct common_type { -private: - using ref = units::detail::common_quantity_reference; -public: - using type = units::quantity>; -}; - -// template QP2> -// requires requires { typename common_type_t; } -// struct common_type { -// using type = -// units::quantity_point::dimension>, -// typename common_type_t::unit, -// typename common_type_t::rep>; -// }; - -// template QK2> -// requires requires { typename common_type_t; } -// struct common_type { -// using type = -// units::quantity_kind::unit, -// typename common_type_t::rep>; -// }; - -// template QPK2> -// requires requires { typename common_type_t; } -// struct common_type { -// using type = units::quantity_point_kind< -// typename QPK1::point_kind_type, -// typename common_type_t::unit, -// typename common_type_t::rep>; -// }; - -} // namespace std diff --git a/src/core/include/units/concepts.h b/src/core/include/units/concepts.h index c506c2ac..32a91ea6 100644 --- a/src/core/include/units/concepts.h +++ b/src/core/include/units/concepts.h @@ -102,15 +102,7 @@ inline constexpr bool is_quantity> = true; */ template concept quantity_of = Quantity && ((Dimension> && Q::dimension == V) || - (Reference> && Q::dimension == V.dimension)); - -/** - * @brief A concept matching two equivalent quantities - * - * Satisfied by quantities having equivalent dimensions and units. - */ -template -concept quantity_equivalent_to = Quantity && equivalent(Q1::dimension, Q2::dimension) && - equivalent(Q1::unit, Q2::unit); + (Reference> && Q::dimension == V.dimension && + Q::unit == V.unit)); } // namespace units diff --git a/src/core/include/units/dimension.h b/src/core/include/units/dimension.h index fd3740a5..d8d5f7b6 100644 --- a/src/core/include/units/dimension.h +++ b/src/core/include/units/dimension.h @@ -195,6 +195,23 @@ template return is_same_v, detail::dim_type>; } +template +[[nodiscard]] consteval bool convertible(D1, D2) +{ + return std::derived_from || std::derived_from; +} + // TODO consider adding the support for text output of the dimensional equation } // namespace units + +namespace std { + +template + requires(units::convertible(D1{}, D2{})) +struct common_type { + using type = ::units::conditional, std::remove_const_t>, + std::remove_const_t, std::remove_const_t>; +}; + +} // namespace std diff --git a/src/core/include/units/quantity.h b/src/core/include/units/quantity.h index 7507359e..39cbf51b 100644 --- a/src/core/include/units/quantity.h +++ b/src/core/include/units/quantity.h @@ -23,13 +23,9 @@ #pragma once -// #include -// #include - // IWYU pragma: begin_exports -// #include +#include // #include -#include #include #include #include @@ -38,8 +34,7 @@ #include // IWYU pragma: end_exports -// #include -// #include +#include namespace units { @@ -73,8 +68,9 @@ concept harmonic_ = // exposition only // Quantity && Quantity && is_integral(detail::quantity_magnitude / detail::quantity_magnitude); template -concept safe_castable_to_ = // exposition only - Quantity && quantity_of && scalable_with_ && +concept quantity_convertible_to_ = // exposition only + Quantity && Quantity && convertible(QFrom::dimension, QTo::dimension) && + convertible(QFrom::unit, QTo::unit) && scalable_with_ && (floating_point_ || (!floating_point_ && harmonic_)); template @@ -161,13 +157,13 @@ public: { } - template Q> + template Q> constexpr explicit(false) quantity(const Q& q) : number_(quantity_cast(q).number()) { } template - requires(safe_castable_to_, quantity>) + requires(quantity_convertible_to_, quantity>) constexpr explicit quantity(const Q& q) : quantity(quantity_like_type(quantity_like_traits::number(q))) { } @@ -423,7 +419,7 @@ public: requires(!Quantity) && (invoke_result_convertible_to_, const Value&, rep>) [[nodiscard]] friend constexpr Quantity auto operator/(const Value& v, const quantity& q) { - return detail::make_quantity(v / q.number()); + return detail::make_quantity(v / q.number()); } template @@ -475,20 +471,20 @@ explicit quantity(Q) typename quantity_like_traits::rep>; // non-member binary operators -template Q2> +template Q2> requires(quantity_value_for_, typename Q1::rep, typename Q2::rep>) [[nodiscard]] constexpr Quantity auto operator+(const Q1& lhs, const Q2& rhs) { - using ref = detail::common_quantity_reference; + using ref = std::common_type_t; using ret = quantity; return ret(ret(lhs).number() + ret(rhs).number()); } -template Q2> +template Q2> requires(quantity_value_for_, typename Q1::rep, typename Q2::rep>) [[nodiscard]] constexpr Quantity auto operator-(const Q1& lhs, const Q2& rhs) { - using ref = detail::common_quantity_reference; + using ref = std::common_type_t; using ret = quantity; return ret(ret(lhs).number() - ret(rhs).number()); } @@ -510,7 +506,7 @@ template template requires(!floating_point_) && (!floating_point_) && - (quantity_equivalent_to || quantity_of) && + (std::convertible_to || quantity_of) && (quantity_value_for_, typename Q1::rep, typename Q2::rep>) [[nodiscard]] constexpr Quantity auto operator%(const Q1& lhs, const Q2& rhs) { @@ -520,20 +516,36 @@ template return ret(lhs.number() % rhs.number()); } -template Q2> +template Q2> requires std::three_way_comparable_with [[nodiscard]] constexpr auto operator<=>(const Q1& lhs, const Q2& rhs) { - using cq = std::common_type_t; - return cq(lhs).number() <=> cq(rhs).number(); + using ref = std::common_type_t; + return quantity_cast(lhs).number() <=> quantity_cast(rhs).number(); } -template Q2> +template Q2> requires std::equality_comparable_with [[nodiscard]] constexpr bool operator==(const Q1& lhs, const Q2& rhs) { - using cq = std::common_type_t; - return cq(lhs).number() == cq(rhs).number(); + using ref = std::common_type_t; + return quantity_cast(lhs).number() == quantity_cast(rhs).number(); } } // namespace units + +namespace std { + +template + requires requires { + typename common_type_t, remove_const_t>; + typename common_type_t; + } +struct common_type { +private: + using ref = common_type_t, remove_const_t>; +public: + using type = units::quantity>; +}; + +} // namespace std diff --git a/src/core/include/units/quantity_cast.h b/src/core/include/units/quantity_cast.h index 4449d722..bf4da51b 100644 --- a/src/core/include/units/quantity_cast.h +++ b/src/core/include/units/quantity_cast.h @@ -22,12 +22,13 @@ #pragma once -#include #include #include #include +#include #include #include +#include UNITS_DIAGNOSTIC_PUSH // warning C4244: 'argument': conversion from 'intmax_t' to 'T', possible loss of data with T=int @@ -35,53 +36,53 @@ UNITS_DIAGNOSTIC_IGNORE_LOSS_OF_DATA namespace units { -template U, Representation Rep> +template class quantity; -template U, Representation Rep> -class quantity_point; +// template U, Representation Rep> +// class quantity_point; -template U, Representation Rep> -class quantity_kind; +// template U, Representation Rep> +// class quantity_kind; -template U, Representation Rep> -class quantity_point_kind; +// template U, Representation Rep> +// class quantity_point_kind; namespace detail { -template -inline constexpr Magnitude auto quantity_magnitude = decltype(Q::reference)::mag; +// template +// inline constexpr Magnitude auto quantity_magnitude = decltype(Q::reference)::mag; -template -inline constexpr Magnitude auto cast_magnitude = [] { - using FromU = TYPENAME QFrom::unit; - using ToU = TYPENAME QTo::unit; - if constexpr (same_unit_reference::value) { - return FromU::mag / ToU::mag; - } else { - return quantity_magnitude / quantity_magnitude; - } -}(); +// template +// inline constexpr Magnitude auto cast_magnitude = [] { +// using FromU = TYPENAME QFrom::unit; +// using ToU = TYPENAME QTo::unit; +// if constexpr (same_unit_reference::value) { +// return FromU::mag / ToU::mag; +// } else { +// return quantity_magnitude / quantity_magnitude; +// } +// }(); -template -struct cast_traits; +// template +// struct cast_traits; -template - requires common_type_with_, std::intmax_t> -struct cast_traits { - using ratio_type = std::common_type_t, std::intmax_t>; - using rep_type = ratio_type; -}; +// template +// requires common_type_with_, std::intmax_t> +// struct cast_traits { +// using ratio_type = std::common_type_t, std::intmax_t>; +// using rep_type = ratio_type; +// }; -template - requires(!common_type_with_, std::intmax_t> && - scalable_number_, std::intmax_t> && - requires { typename std::common_type_t::value_type; } && - common_type_with_::value_type, std::intmax_t>) -struct cast_traits { - using ratio_type = std::common_type_t::value_type, std::intmax_t>; - using rep_type = std::common_type_t; -}; +// template +// requires(!common_type_with_, std::intmax_t> && +// scalable_number_, std::intmax_t> && +// requires { typename std::common_type_t::value_type; } && +// common_type_with_::value_type, std::intmax_t>) +// struct cast_traits { +// using ratio_type = std::common_type_t::value_type, std::intmax_t>; +// using rep_type = std::common_type_t; +// }; } // namespace detail @@ -97,59 +98,28 @@ struct cast_traits { * * @tparam To a target quantity type to cast to */ -template Rep> - requires QuantityOf && (std::constructible_from>) -[[nodiscard]] constexpr auto quantity_cast(const quantity& q) +template Rep> + requires(convertible(R, To::reference)) +[[nodiscard]] constexpr auto quantity_cast(const quantity& q) { - using traits = detail::cast_traits; - using ratio_type = TYPENAME traits::ratio_type; - using rep_type = TYPENAME traits::rep_type; + // TODO implement same unit magnitude check + if constexpr (std::same_as) { + return To(static_cast(q.number())); + } else { + // using traits = detail::cast_traits; + // using ratio_type = TYPENAME traits::ratio_type; + // using rep_type = TYPENAME traits::rep_type; - constexpr Magnitude auto c_mag = detail::cast_magnitude, To>; - constexpr Magnitude auto num = numerator(c_mag); - constexpr Magnitude auto den = denominator(c_mag); - constexpr Magnitude auto irr = c_mag * (den / num); + // constexpr Magnitude auto c_mag = detail::cast_magnitude, To>; + // constexpr Magnitude auto num = numerator(c_mag); + // constexpr Magnitude auto den = denominator(c_mag); + // constexpr Magnitude auto irr = c_mag * (den / num); - constexpr auto val = [](Magnitude auto m) { return get_value(m); }; - return To(static_cast(static_cast(q.number()) * val(num) / val(den) * val(irr))); -} - -/** - * @brief Explicit cast of a quantity - * - * Implicit conversions between quantities of different types are allowed only for "safe" - * (i.e. non-truncating) conversion. In such cases an explicit cast have to be used. - * - * This cast gets only the target dimension to cast to. For example: - * - * auto q1 = units::quantity_cast(200_q_Gal); - * - * @tparam ToD a dimension type to use for a target quantity - */ -template - requires equivalent -[[nodiscard]] constexpr auto quantity_cast(const quantity& q) -{ - return quantity_cast, Rep>>(q); -} - -/** - * @brief Explicit cast of a quantity - * - * Implicit conversions between quantities of different types are allowed only for "safe" - * (i.e. non-truncating) conversion. In such cases an explicit cast have to be used. - * - * This cast gets only the target unit to cast to. For example: - * - * auto q1 = units::quantity_cast(1_q_ms); - * - * @tparam ToU a unit type to use for a target quantity - */ -template - requires UnitOf -[[nodiscard]] constexpr auto quantity_cast(const quantity& q) -{ - return quantity_cast>(q); + // constexpr auto val = [](Magnitude auto m) { return get_value(m); }; + // return To(static_cast(static_cast(q.number()) * val(num) / val(den) * val(irr))); + // TODO implement that + return q; + } } /** @@ -168,11 +138,52 @@ template * @tparam ToD a dimension type to use for a target quantity * @tparam ToU a unit type to use for a target quantity */ -template - requires equivalent && UnitOf -[[nodiscard]] constexpr auto quantity_cast(const quantity& q) +template + requires(convertible(ToR, R)) +[[nodiscard]] constexpr auto quantity_cast(const quantity& q) { - return quantity_cast>(q); + return quantity_cast>(q); +} + + +/** + * @brief Explicit cast of a quantity + * + * Implicit conversions between quantities of different types are allowed only for "safe" + * (i.e. non-truncating) conversion. In such cases an explicit cast have to be used. + * + * This cast gets only the target dimension to cast to. For example: + * + * auto q1 = units::quantity_cast(200_q_Gal); + * + * @tparam ToD a dimension type to use for a target quantity + */ +template + requires(convertible(ToD, R.dimension)) +[[nodiscard]] constexpr auto quantity_cast(const quantity& q) +{ + constexpr reference, std::remove_const_t> r; + return quantity_cast>(q); +} + +/** + * @brief Explicit cast of a quantity + * + * Implicit conversions between quantities of different types are allowed only for "safe" + * (i.e. non-truncating) conversion. In such cases an explicit cast have to be used. + * + * This cast gets only the target unit to cast to. For example: + * + * auto q1 = units::quantity_cast(1_q_ms); + * + * @tparam ToU a unit type to use for a target quantity + */ +template + requires(convertible(ToU, R.unit)) +[[nodiscard]] constexpr auto quantity_cast(const quantity& q) +{ + constexpr reference, std::remove_const_t> r; + return quantity_cast>(q); } /** @@ -187,185 +198,187 @@ template * * @tparam ToRep a representation type to use for a target quantity */ -template Rep> - requires(std::constructible_from>) -[[nodiscard]] constexpr auto quantity_cast(const quantity& q) +template Rep> +// requires(std::constructible_from>) +[[nodiscard]] constexpr auto quantity_cast(const quantity& q) { - return quantity_cast>(q); + return To(static_cast(q.number())); } -/** - * @brief Explicit cast of a quantity point - * - * Implicit conversions between quantity points of different types are allowed only for "safe" - * (i.e. non-truncating) conversion. In other cases an explicit cast has to be used. - * - * This cast gets the target quantity point type to cast to or anything that works for quantity_cast. For example: - * - * auto q1 = units::quantity_point_cast(quantity_point{1_q_ms}); - * auto q1 = units::quantity_point_cast>(quantity_point{1_q_ms}); - * auto q1 = units::quantity_point_cast(quantity_point{200_q_Gal}); - * auto q1 = units::quantity_point_cast(quantity_point{1_q_ms}); - * auto q1 = units::quantity_point_cast(quantity_point{1_q_ms}); - * - * @tparam CastSpec a target quantity point type to cast to or anything that works for quantity_cast - */ -template -[[nodiscard]] constexpr auto quantity_point_cast(const quantity_point& qp) - requires requires { - requires is_specialization_of; - requires requires { quantity_cast(qp.relative()); }; - requires equivalent; - } || // TODO: Simplify when Clang catches up. - requires { quantity_cast(qp.relative()); } -{ - if constexpr (is_specialization_of) - return quantity_point(quantity_cast(qp.relative())); - else - return quantity_point(quantity_cast(qp.relative())); -} +// /** +// * @brief Explicit cast of a quantity point +// * +// * Implicit conversions between quantity points of different types are allowed only for "safe" +// * (i.e. non-truncating) conversion. In other cases an explicit cast has to be used. +// * +// * This cast gets the target quantity point type to cast to or anything that works for quantity_cast. For example: +// * +// * auto q1 = units::quantity_point_cast(quantity_point{1_q_ms}); +// * auto q1 = units::quantity_point_cast>(quantity_point{1_q_ms}); +// * auto q1 = units::quantity_point_cast(quantity_point{200_q_Gal}); +// * auto q1 = units::quantity_point_cast(quantity_point{1_q_ms}); +// * auto q1 = units::quantity_point_cast(quantity_point{1_q_ms}); +// * +// * @tparam CastSpec a target quantity point type to cast to or anything that works for quantity_cast +// */ +// template +// [[nodiscard]] constexpr auto quantity_point_cast(const quantity_point& qp) +// requires requires { +// requires is_specialization_of; +// requires requires { quantity_cast(qp.relative()); }; +// requires equivalent; +// } || // TODO: Simplify when Clang catches up. +// requires { quantity_cast(qp.relative()); } +// { +// if constexpr (is_specialization_of) +// return quantity_point(quantity_cast(qp.relative())); +// else +// return quantity_point(quantity_cast(qp.relative())); +// } -/** - * @brief Explicit cast of a quantity point - * - * Implicit conversions between quantity points of different types are allowed only for "safe" - * (i.e. non-truncating) conversion. In other cases an explicit cast has to be used. - * - * This cast gets both the target dimension and unit to cast to. For example: - * - * auto q1 = units::quantity_point_cast(v1); - * - * @note This cast is especially useful when working with quantity points of unknown dimensions - * (@c unknown_dimension). - * - * @tparam ToD a dimension type to use for a target quantity - * @tparam ToU a unit type to use for a target quantity - */ -template - requires equivalent && UnitOf && RebindablePointOriginFor -[[nodiscard]] constexpr auto quantity_point_cast(const quantity_point& q) -{ - return quantity_point_cast, ToU, Rep>>(q); -} +// /** +// * @brief Explicit cast of a quantity point +// * +// * Implicit conversions between quantity points of different types are allowed only for "safe" +// * (i.e. non-truncating) conversion. In other cases an explicit cast has to be used. +// * +// * This cast gets both the target dimension and unit to cast to. For example: +// * +// * auto q1 = units::quantity_point_cast(v1); +// * +// * @note This cast is especially useful when working with quantity points of unknown dimensions +// * (@c unknown_dimension). +// * +// * @tparam ToD a dimension type to use for a target quantity +// * @tparam ToU a unit type to use for a target quantity +// */ +// template +// requires equivalent && UnitOf && RebindablePointOriginFor +// [[nodiscard]] constexpr auto quantity_point_cast(const quantity_point& q) +// { +// return quantity_point_cast, ToU, Rep>>(q); +// } -/** - * @brief Explicit cast of a quantity kind - * - * Implicit conversions between quantity kinds of different types are allowed only for "safe" - * (i.e. non-truncating) conversion. In other cases an explicit cast has to be used. - * - * This cast gets the target (quantity) kind type to cast to or anything that works for quantity_cast. For example: - * - * auto q1 = units::quantity_kind_cast(quantity_kind{ns::width{1 * mm}); - * auto q1 = units::quantity_kind_cast(ns::width{1 * m}); - * auto q1 = units::quantity_kind_cast>(ns::width{1 * mm}); - * auto q1 = units::quantity_kind_cast(ns::rate_of_climb{200 * Gal}); - * auto q1 = units::quantity_kind_cast(ns::width{1 * mm}); - * auto q1 = units::quantity_kind_cast(ns::width{1.0 * mm}); - * - * @tparam CastSpec a target (quantity) kind type to cast to or anything that works for quantity_cast - */ -template -[[nodiscard]] constexpr QuantityKind auto quantity_kind_cast(const quantity_kind& qk) - requires requires { - requires is_specialization_of; - requires requires { quantity_cast(qk.common()); }; - } || requires { - requires Kind; - requires UnitOf; - } || requires { quantity_cast(qk.common()); } // TODO: Simplify when Clang catches up. -{ - if constexpr (is_specialization_of) - return CastSpec(quantity_cast(qk.common())); - else if constexpr (Kind) - return quantity_kind(qk.common()); - else { - auto q{quantity_cast(qk.common())}; - using Q = decltype(q); - return quantity_kind(static_cast(q)); - } -} +// /** +// * @brief Explicit cast of a quantity kind +// * +// * Implicit conversions between quantity kinds of different types are allowed only for "safe" +// * (i.e. non-truncating) conversion. In other cases an explicit cast has to be used. +// * +// * This cast gets the target (quantity) kind type to cast to or anything that works for quantity_cast. For example: +// * +// * auto q1 = units::quantity_kind_cast(quantity_kind{ns::width{1 * mm}); +// * auto q1 = units::quantity_kind_cast(ns::width{1 * m}); +// * auto q1 = units::quantity_kind_cast>(ns::width{1 * mm}); +// * auto q1 = units::quantity_kind_cast(ns::rate_of_climb{200 * Gal}); +// * auto q1 = units::quantity_kind_cast(ns::width{1 * mm}); +// * auto q1 = units::quantity_kind_cast(ns::width{1.0 * mm}); +// * +// * @tparam CastSpec a target (quantity) kind type to cast to or anything that works for quantity_cast +// */ +// template +// [[nodiscard]] constexpr QuantityKind auto quantity_kind_cast(const quantity_kind& qk) +// requires requires { +// requires is_specialization_of; +// requires requires { quantity_cast(qk.common()); }; +// } || requires { +// requires Kind; +// requires UnitOf; +// } || requires { quantity_cast(qk.common()); } // TODO: Simplify when Clang catches up. +// { +// if constexpr (is_specialization_of) +// return CastSpec(quantity_cast(qk.common())); +// else if constexpr (Kind) +// return quantity_kind(qk.common()); +// else { +// auto q{quantity_cast(qk.common())}; +// using Q = decltype(q); +// return quantity_kind(static_cast(q)); +// } +// } -/** - * @brief Explicit cast of a quantity kind - * - * Implicit conversions between quantity kinds of different types are allowed only for "safe" - * (i.e. non-truncating) conversion. In other cases an explicit cast has to be used. - * - * This cast gets both the target kind and unit to cast to. For example: - * - * auto q1 = units::quantity_kind_cast(w); - * - * @note This cast is especially useful when working with quantity kinds of unknown kind. - * - * @tparam ToK the kind type to use for the target quantity - * @tparam ToU the unit type to use for the target quantity - */ -template - requires equivalent && UnitOf -[[nodiscard]] constexpr QuantityKind auto quantity_kind_cast(const quantity_kind& qk) -{ - return quantity_kind_cast>(qk); -} +// /** +// * @brief Explicit cast of a quantity kind +// * +// * Implicit conversions between quantity kinds of different types are allowed only for "safe" +// * (i.e. non-truncating) conversion. In other cases an explicit cast has to be used. +// * +// * This cast gets both the target kind and unit to cast to. For example: +// * +// * auto q1 = units::quantity_kind_cast(w); +// * +// * @note This cast is especially useful when working with quantity kinds of unknown kind. +// * +// * @tparam ToK the kind type to use for the target quantity +// * @tparam ToU the unit type to use for the target quantity +// */ +// template +// requires equivalent && UnitOf +// [[nodiscard]] constexpr QuantityKind auto quantity_kind_cast(const quantity_kind& qk) +// { +// return quantity_kind_cast>(qk); +// } -/** - * @brief Explicit cast of a quantity point kind - * - * Implicit conversions between quantity point kinds of different types are allowed only for "safe" - * (i.e. non-truncating) conversion. In other cases an explicit cast has to be used. - * - * This cast gets the target (quantity) point kind type to cast to or anything that works for quantity_kind_cast. For - * example: - * - * auto q1 = units::quantity_point_kind_cast(ns::x_coordinate{1 * mm}); - * auto q1 = units::quantity_point_kind_cast(ns::x_coordinate{1 * mm}); - * auto q1 = units::quantity_point_kind_cast(ns::x_coordinate{1 * m}); - * auto q1 = units::quantity_point_kind_cast(ns::x_coordinate{1 * m}); - * auto q1 = units::quantity_point_kind_cast>(ns::x_coordinate{1 * mm}); - * auto q1 = units::quantity_point_kind_cast(quantity_point_kind(ns::rate_of_climb{200 - * * Gal})); auto q1 = units::quantity_point_kind_cast(ns::x_coordinate{1 * mm}); auto q1 = - * units::quantity_point_kind_cast(ns::x_coordinate{1.0 * mm}); - * - * @tparam CastSpec a target (quantity) point kind type to cast to or anything that works for quantity_kind_cast - */ -template -[[nodiscard]] constexpr QuantityPointKind auto quantity_point_kind_cast(const quantity_point_kind& qpk) - requires requires { - requires is_specialization_of; - requires requires { quantity_kind_cast(qpk.relative()); }; - requires equivalent; - } || requires { requires PointKind && UnitOf; } || - requires { quantity_kind_cast(qpk.relative()); } // TODO: Simplify when Clang catches up. -{ - if constexpr (is_specialization_of) - return CastSpec(quantity_kind_cast(qpk.relative())); - else if constexpr (PointKind) - return quantity_point_kind(quantity_kind_cast(qpk.relative())); - else - return quantity_point_kind(quantity_kind_cast(qpk.relative())); -} +// /** +// * @brief Explicit cast of a quantity point kind +// * +// * Implicit conversions between quantity point kinds of different types are allowed only for "safe" +// * (i.e. non-truncating) conversion. In other cases an explicit cast has to be used. +// * +// * This cast gets the target (quantity) point kind type to cast to or anything that works for quantity_kind_cast. For +// * example: +// * +// * auto q1 = units::quantity_point_kind_cast(ns::x_coordinate{1 * mm}); +// * auto q1 = units::quantity_point_kind_cast(ns::x_coordinate{1 * mm}); +// * auto q1 = units::quantity_point_kind_cast(ns::x_coordinate{1 * m}); +// * auto q1 = units::quantity_point_kind_cast(ns::x_coordinate{1 * m}); +// * auto q1 = units::quantity_point_kind_cast>(ns::x_coordinate{1 * +// mm}); +// * auto q1 = +// units::quantity_point_kind_cast(quantity_point_kind(ns::rate_of_climb{200 +// * * Gal})); auto q1 = units::quantity_point_kind_cast(ns::x_coordinate{1 * mm}); auto q1 = +// * units::quantity_point_kind_cast(ns::x_coordinate{1.0 * mm}); +// * +// * @tparam CastSpec a target (quantity) point kind type to cast to or anything that works for quantity_kind_cast +// */ +// template +// [[nodiscard]] constexpr QuantityPointKind auto quantity_point_kind_cast(const quantity_point_kind& qpk) +// requires requires { +// requires is_specialization_of; +// requires requires { quantity_kind_cast(qpk.relative()); }; +// requires equivalent; +// } || requires { requires PointKind && UnitOf; } || +// requires { quantity_kind_cast(qpk.relative()); } // TODO: Simplify when Clang catches up. +// { +// if constexpr (is_specialization_of) +// return CastSpec(quantity_kind_cast(qpk.relative())); +// else if constexpr (PointKind) +// return quantity_point_kind(quantity_kind_cast(qpk.relative())); +// else +// return quantity_point_kind(quantity_kind_cast(qpk.relative())); +// } -/** - * @brief Explicit cast of a quantity point kind - * - * Implicit conversions between quantity point kinds of different types are allowed only for "safe" - * (i.e. non-truncating) conversion. In other cases an explicit cast has to be used. - * - * This cast gets both the target point kind and unit to cast to. For example: - * - * auto q1 = units::quantity_point_kind_cast(x); - * - * @note This cast is especially useful when working with quantity point kinds of unknown point kind. - * - * @tparam ToPK the point kind type to use for the target quantity - * @tparam ToU the unit type to use for the target quantity - */ -template - requires equivalent && UnitOf -[[nodiscard]] constexpr QuantityPointKind auto quantity_point_kind_cast(const quantity_point_kind& qpk) -{ - return quantity_point_kind_cast>(qpk); -} +// /** +// * @brief Explicit cast of a quantity point kind +// * +// * Implicit conversions between quantity point kinds of different types are allowed only for "safe" +// * (i.e. non-truncating) conversion. In other cases an explicit cast has to be used. +// * +// * This cast gets both the target point kind and unit to cast to. For example: +// * +// * auto q1 = units::quantity_point_kind_cast(x); +// * +// * @note This cast is especially useful when working with quantity point kinds of unknown point kind. +// * +// * @tparam ToPK the point kind type to use for the target quantity +// * @tparam ToU the unit type to use for the target quantity +// */ +// template +// requires equivalent && UnitOf +// [[nodiscard]] constexpr QuantityPointKind auto quantity_point_kind_cast(const quantity_point_kind& qpk) +// { +// return quantity_point_kind_cast>(qpk); +// } } // namespace units diff --git a/src/core/include/units/reference.h b/src/core/include/units/reference.h index 62e151de..30dd479a 100644 --- a/src/core/include/units/reference.h +++ b/src/core/include/units/reference.h @@ -136,13 +136,27 @@ template void /*Use `q * (1 * r)` rather than `q * r`.*/ operator*(Quantity auto, Reference auto) = delete; +template +[[nodiscard]] consteval bool equivalent(R1, R2) +{ + return equivalent(R1::dimension, R2::dimension) && equivalent(R1::unit, R2::unit); +} + +template +[[nodiscard]] consteval bool convertible(R1, R2) +{ + return convertible(R1::dimension, R2::dimension) && convertible(R1::unit, R2::unit); +} + + template struct system_reference { static constexpr auto dimension = Dim; static constexpr auto coherent_unit = CoU; template - // requires same_unit_reference + // TODO enable that + // requires(convertible(coherent_unit, U{})) [[nodiscard]] constexpr reference, U> operator[](U) const { return {}; @@ -153,3 +167,20 @@ inline constexpr struct dimensionless : system_reference { } dimensionless; } // namespace units + +namespace std { + +template + requires requires { + typename common_type_t, remove_const_t>; + typename common_type_t, remove_const_t>; + } +struct common_type { +private: + using dim = common_type_t, remove_const_t>; + using unit = common_type_t, remove_const_t>; +public: + using type = units::reference; +}; + +} // namespace std diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index 0646e2fd..a7b4af77 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -330,12 +330,6 @@ template return is_same_v; } -template -[[nodiscard]] consteval bool equivalent(U1, U2) -{ - return true; // TODO implement this -} - // template // constexpr bool operator==(D1, D2) @@ -366,6 +360,20 @@ template // std::is_same_v; // } +// TODO implement this +// template +// [[nodiscard]] consteval bool equivalent(D1, D2) +// { +// return is_same_v, detail::dim_type>; +// } + +template +[[nodiscard]] consteval bool convertible(U1, U2) +{ + // TODO implement this + return std::derived_from || std::derived_from; +} + template struct square_ : decltype(U{} * U{}) {}; @@ -379,3 +387,15 @@ template inline constexpr cubic_> cubic; } // namespace units + +namespace std { + +// TODO implement this +template + requires(units::convertible(U1{}, U2{})) +struct common_type { + using type = ::units::conditional, std::remove_const_t>, + std::remove_const_t, std::remove_const_t>; +}; + +} // namespace std diff --git a/test/unit_test/static/dimension_test.cpp b/test/unit_test/static/dimension_test.cpp index 4cc2958e..d3dde201 100644 --- a/test/unit_test/static/dimension_test.cpp +++ b/test/unit_test/static/dimension_test.cpp @@ -36,14 +36,14 @@ inline constexpr struct length_dim_ : base_dimension<"L"> {} length_dim; inline constexpr struct time_dim_ : base_dimension<"T"> {} time_dim; inline constexpr struct frequency_dim_ : decltype(1 / time_dim) {} frequency_dim; +inline constexpr struct action_dim_ : decltype(1 / time_dim) {} action_dim; inline constexpr struct area_dim_ : decltype(length_dim * length_dim) {} area_dim; inline constexpr struct volume_dim_ : decltype(area_dim * length_dim) {} volume_dim; inline constexpr struct speed_dim_ : decltype(length_dim / time_dim) {} speed_dim; +inline constexpr struct velocity_dim_ : speed_dim_ {} velocity_dim; inline constexpr struct acceleration_dim_ : decltype(speed_dim / time_dim) {} acceleration_dim; // clang-format on -} // namespace - // concepts verification static_assert(BaseDimension); static_assert(!BaseDimension); @@ -107,13 +107,19 @@ static_assert(length_dim / length_dim == one_dim); static_assert(1 / time_dim != frequency_dim); static_assert(equivalent(1 / time_dim, frequency_dim)); +static_assert(convertible(1 / time_dim, frequency_dim)); static_assert(1 / frequency_dim == time_dim); static_assert(frequency_dim * time_dim == one_dim); +static_assert(std::is_same_v, frequency_dim_>); +static_assert(std::is_same_v, frequency_dim_>); static_assert(length_dim * length_dim != area_dim); static_assert(equivalent(length_dim * length_dim, area_dim)); +static_assert(convertible(length_dim * length_dim, area_dim)); static_assert(length_dim * length_dim != volume_dim); static_assert(area_dim / length_dim == length_dim); +static_assert(std::is_same_v, area_dim_>); +static_assert(std::is_same_v, area_dim_>); static_assert(length_dim * length_dim * length_dim != volume_dim); static_assert(equivalent(length_dim * length_dim * length_dim, volume_dim)); @@ -134,6 +140,10 @@ static_assert(length_dim * time_dim != speed_dim); static_assert(length_dim / time_dim / time_dim != speed_dim); static_assert(length_dim / speed_dim == time_dim); static_assert(speed_dim * time_dim == length_dim); +static_assert(std::is_same_v, speed_dim_>); +static_assert(std::is_same_v, speed_dim_>); +static_assert(std::is_same_v, + decltype(length_dim / time_dim)>); static_assert(length_dim / time_dim / time_dim != acceleration_dim); static_assert(equivalent(length_dim / time_dim / time_dim, acceleration_dim)); @@ -147,3 +157,21 @@ static_assert(equivalent(acceleration_dim * time_dim, speed_dim)); static_assert(acceleration_dim * (time_dim * time_dim) == length_dim); static_assert(acceleration_dim / speed_dim != frequency_dim); static_assert(equivalent(acceleration_dim / speed_dim, frequency_dim)); + +static_assert(frequency_dim != action_dim); +static_assert(equivalent(frequency_dim, action_dim)); +static_assert(!convertible(frequency_dim, action_dim)); +template +concept no_common_type = requires { + requires !requires { typename std::common_type_t; }; + requires !requires { typename std::common_type_t; }; + }; +static_assert(no_common_type); + +static_assert(velocity_dim != speed_dim); +static_assert(equivalent(velocity_dim, speed_dim)); +static_assert(convertible(speed_dim, velocity_dim)); +static_assert(std::is_same_v, velocity_dim_>); +static_assert(std::is_same_v, velocity_dim_>); + +} // namespace From e83b36146509aa020be138ae686978cb9ad87798 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 18 Oct 2022 16:08:22 +0200 Subject: [PATCH 021/402] refactor: `explicit(false)` added for `basic_symbol_text` --- src/core/include/units/symbol_text.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/core/include/units/symbol_text.h b/src/core/include/units/symbol_text.h index 6eb71e6d..e6adbe34 100644 --- a/src/core/include/units/symbol_text.h +++ b/src/core/include/units/symbol_text.h @@ -66,16 +66,20 @@ struct basic_symbol_text { basic_fixed_string standard_; basic_fixed_string ascii_; - constexpr basic_symbol_text(char std) noexcept : standard_(std), ascii_(std) { detail::validate_ascii_char(std); } + constexpr explicit(false) basic_symbol_text(char std) noexcept : standard_(std), ascii_(std) + { + detail::validate_ascii_char(std); + } constexpr basic_symbol_text(StandardCharT std, char a) noexcept : standard_(std), ascii_(a) { detail::validate_ascii_char(a); } - constexpr basic_symbol_text(const char (&std)[N + 1]) noexcept : standard_(std), ascii_(std) + constexpr explicit(false) basic_symbol_text(const char (&std)[N + 1]) noexcept : standard_(std), ascii_(std) { detail::validate_ascii_string(std); } - constexpr basic_symbol_text(const basic_fixed_string& std) noexcept : standard_(std), ascii_(std) + constexpr explicit(false) basic_symbol_text(const basic_fixed_string& std) noexcept : + standard_(std), ascii_(std) { detail::validate_ascii_string(std.data_); } From 6a6fda18373e45e41c846664ac2c07b1b028c3a8 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 18 Oct 2022 16:09:35 +0200 Subject: [PATCH 022/402] style: SI unit symbols definition cleanup --- src/systems/si/include/units/si/unit_symbols.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/systems/si/include/units/si/unit_symbols.h b/src/systems/si/include/units/si/unit_symbols.h index 49a4418b..ed748874 100644 --- a/src/systems/si/include/units/si/unit_symbols.h +++ b/src/systems/si/include/units/si/unit_symbols.h @@ -60,6 +60,7 @@ inline constexpr auto ms = milli; inline constexpr auto cs = centi; inline constexpr auto ds = deci; inline constexpr auto s = second; +// TODO Should the below multiples of second be provided? inline constexpr auto das = deca; inline constexpr auto hs = hecto; inline constexpr auto ks = kilo; @@ -489,8 +490,6 @@ inline constexpr auto EH = exa; inline constexpr auto ZH = zetta; inline constexpr auto YH = yotta; -inline constexpr auto deg_C = degree_Celsius; - inline constexpr auto ylm = yocto; inline constexpr auto zlm = zepto; inline constexpr auto alm = atto; @@ -623,9 +622,7 @@ inline constexpr auto Ekat = exa; inline constexpr auto Zkat = zetta; inline constexpr auto Ykat = yotta; -inline constexpr auto min = minute; -inline constexpr auto h = hour; -inline constexpr auto d = day; +// TODO Should the following non-SI units have prefixes symbols predefiend as well? inline constexpr auto au = astronomical_unit; inline constexpr auto a = are; inline constexpr auto ha = hectare; @@ -634,4 +631,10 @@ inline constexpr auto t = tonne; inline constexpr auto Da = dalton; inline constexpr auto eV = electronvolt; +// No prefixes should be provided for the below units +inline constexpr auto deg_C = degree_Celsius; +inline constexpr auto min = minute; +inline constexpr auto h = hour; +inline constexpr auto d = day; + } // namespace units::si::unit_symbols From 3194d45b08a2242f9dbc460da6e581a25f102ca6 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 18 Oct 2022 17:44:40 +0200 Subject: [PATCH 023/402] refactor: exposition only members added to expression templates --- .../include/units/bits/expression_template.h | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/core/include/units/bits/expression_template.h b/src/core/include/units/bits/expression_template.h index e702b0bc..3d387efa 100644 --- a/src/core/include/units/bits/expression_template.h +++ b/src/core/include/units/bits/expression_template.h @@ -300,8 +300,8 @@ struct expr_fractions { private: using impl = expr_fractions_impl; public: - using num = TYPENAME impl::num; - using den = TYPENAME impl::den; + using _num_ = TYPENAME impl::num; // exposition only + using _den_ = TYPENAME impl::den; // exposition only }; template typename To> @@ -357,14 +357,14 @@ template) { return T1{}; } else if constexpr (is_specialization_of && is_specialization_of) { - return get_optimized_expression, - type_list_merge_sorted, OneType, Pred, + return get_optimized_expression, + type_list_merge_sorted, OneType, Pred, To>(); } else if constexpr (is_specialization_of) { - return get_optimized_expression, Pred>, typename T1::den, + return get_optimized_expression, Pred>, typename T1::_den_, OneType, Pred, To>(); } else if constexpr (is_specialization_of) { - return get_optimized_expression, Pred>, typename T2::den, + return get_optimized_expression, Pred>, typename T2::_den_, OneType, Pred, To>(); } else { return get_optimized_expression, type_list, Pred>, type_list<>, OneType, @@ -381,14 +381,14 @@ template) { return T1{}; } else if constexpr (is_specialization_of && is_specialization_of) { - return get_optimized_expression, - type_list_merge_sorted, OneType, Pred, + return get_optimized_expression, + type_list_merge_sorted, OneType, Pred, To>(); } else if constexpr (is_specialization_of) { - return get_optimized_expression, Pred>, + return get_optimized_expression, Pred>, OneType, Pred, To>(); } else if constexpr (is_specialization_of) { - return get_optimized_expression, Pred>, typename T2::num, + return get_optimized_expression, Pred>, typename T2::_num_, OneType, Pred, To>(); } else { return To>{}; @@ -399,7 +399,7 @@ template typename To> [[nodiscard]] consteval auto expr_invert() { if constexpr (is_specialization_of) - return expr_expression{}; + return expr_expression{}; else return To>{}; } From 6e8ca7267846625be8ed2a8694d1d59fe121e8e5 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 18 Oct 2022 17:45:32 +0200 Subject: [PATCH 024/402] refactor: dimensions design cleanup --- src/core/include/units/dimension.h | 44 +++++++--- src/core/include/units/magnitude.h | 15 ++-- src/core/include/units/quantity.h | 4 +- src/core/include/units/quantity_cast.h | 7 +- src/core/include/units/reference.h | 16 ++-- test/unit_test/static/dimension_test.cpp | 102 +++++++++++++++++------ 6 files changed, 133 insertions(+), 55 deletions(-) diff --git a/src/core/include/units/dimension.h b/src/core/include/units/dimension.h index d8d5f7b6..6aa81a26 100644 --- a/src/core/include/units/dimension.h +++ b/src/core/include/units/dimension.h @@ -104,19 +104,41 @@ using type_list_of_base_dimension_less = expr_less; template inline constexpr bool is_one_dim = false; +template +inline constexpr bool is_power_of_dim = + requires { + requires is_specialization_of_power && (BaseDimension || is_one_dim); + }; + +template +inline constexpr bool is_per_of_dims = false; + +template +inline constexpr bool is_per_of_dims> = + (... && (BaseDimension || is_one_dim || is_power_of_dim)); + } // namespace detail -// TODO add checking for `per` and power elements as well template concept DimensionSpec = - BaseDimension || detail::is_one_dim || is_specialization_of || detail::is_specialization_of_power; + BaseDimension || detail::is_one_dim || detail::is_power_of_dim || detail::is_per_of_dims; + +template +struct derived_dimension; + +namespace detail { + +template +struct derived_dimension_impl : detail::expr_fractions, Ds...> { + using _type_ = derived_dimension; // exposition only +}; + +} // namespace detail // User should not instantiate this type!!! // It should not be exported from the module template -struct derived_dimension : detail::expr_fractions, Ds...> { - using type = derived_dimension; -}; +struct derived_dimension : detail::derived_dimension_impl {}; namespace detail { @@ -154,7 +176,7 @@ struct dim_type_impl { template struct dim_type_impl { - using type = T::type; + using type = T::_type_; }; template @@ -189,11 +211,11 @@ template return is_same_v; } -template -[[nodiscard]] consteval bool equivalent(D1, D2) -{ - return is_same_v, detail::dim_type>; -} +// template +// [[nodiscard]] consteval bool equivalent(D1, D2) +// { +// return is_same_v, detail::dim_type>; +// } template [[nodiscard]] consteval bool convertible(D1, D2) diff --git a/src/core/include/units/magnitude.h b/src/core/include/units/magnitude.h index f81da0c5..c45c40a9 100644 --- a/src/core/include/units/magnitude.h +++ b/src/core/include/units/magnitude.h @@ -514,15 +514,12 @@ inline constexpr struct mag_pi : magnitude> { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Magnitude equality implementation. -// template -// constexpr bool operator==(magnitude, magnitude) -// { -// if constexpr (sizeof...(LeftBPs) == sizeof...(RightBPs)) { -// return ((LeftBPs == RightBPs) && ...); -// } else { -// return false; -// } -// } +template +[[nodiscard]] consteval bool operator==(M1, M2) +{ + return std::is_same_v; +} + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Magnitude rational powers implementation. diff --git a/src/core/include/units/quantity.h b/src/core/include/units/quantity.h index 39cbf51b..afcb74de 100644 --- a/src/core/include/units/quantity.h +++ b/src/core/include/units/quantity.h @@ -69,8 +69,8 @@ concept harmonic_ = // exposition only template concept quantity_convertible_to_ = // exposition only - Quantity && Quantity && convertible(QFrom::dimension, QTo::dimension) && - convertible(QFrom::unit, QTo::unit) && scalable_with_ && + Quantity && Quantity && + convertible(QFrom::reference, QTo::reference) && scalable_with_ && (floating_point_ || (!floating_point_ && harmonic_)); template diff --git a/src/core/include/units/quantity_cast.h b/src/core/include/units/quantity_cast.h index bf4da51b..59df535b 100644 --- a/src/core/include/units/quantity_cast.h +++ b/src/core/include/units/quantity_cast.h @@ -99,11 +99,10 @@ namespace detail { * @tparam To a target quantity type to cast to */ template Rep> - requires(convertible(R, To::reference)) + requires(convertible(To::reference, R)) [[nodiscard]] constexpr auto quantity_cast(const quantity& q) { - // TODO implement same unit magnitude check - if constexpr (std::same_as) { + if constexpr (R.unit == To::unit) { return To(static_cast(q.number())); } else { // using traits = detail::cast_traits; @@ -202,7 +201,7 @@ template Rep> // requires(std::constructible_from>) [[nodiscard]] constexpr auto quantity_cast(const quantity& q) { - return To(static_cast(q.number())); + return quantity_cast>(q); } // /** diff --git a/src/core/include/units/reference.h b/src/core/include/units/reference.h index 30dd479a..1b89a09c 100644 --- a/src/core/include/units/reference.h +++ b/src/core/include/units/reference.h @@ -136,11 +136,11 @@ template void /*Use `q * (1 * r)` rather than `q * r`.*/ operator*(Quantity auto, Reference auto) = delete; -template -[[nodiscard]] consteval bool equivalent(R1, R2) -{ - return equivalent(R1::dimension, R2::dimension) && equivalent(R1::unit, R2::unit); -} +// template +// [[nodiscard]] consteval bool equivalent(R1, R2) +// { +// return equivalent(R1::dimension, R2::dimension) && R1::unit == R2::unit; +// } template [[nodiscard]] consteval bool convertible(R1, R2) @@ -148,6 +148,12 @@ template return convertible(R1::dimension, R2::dimension) && convertible(R1::unit, R2::unit); } +// template +// [[nodiscard]] consteval bool castable(R1, R2) +// { +// return equivalent(R1::dimension, R2::dimension) && convertible(R1::unit, R2::unit); +// } + template struct system_reference { diff --git a/test/unit_test/static/dimension_test.cpp b/test/unit_test/static/dimension_test.cpp index d3dde201..526c0136 100644 --- a/test/unit_test/static/dimension_test.cpp +++ b/test/unit_test/static/dimension_test.cpp @@ -22,10 +22,10 @@ #include -using namespace units; - namespace { +using namespace units; + template inline constexpr bool is_of_type = std::is_same_v, T>; @@ -34,6 +34,7 @@ using one_dim_ = struct one_dim; // clang-format off inline constexpr struct length_dim_ : base_dimension<"L"> {} length_dim; inline constexpr struct time_dim_ : base_dimension<"T"> {} time_dim; +inline constexpr struct mass_dim_ : base_dimension<"M"> {} mass_dim; inline constexpr struct frequency_dim_ : decltype(1 / time_dim) {} frequency_dim; inline constexpr struct action_dim_ : decltype(1 / time_dim) {} action_dim; @@ -42,6 +43,15 @@ inline constexpr struct volume_dim_ : decltype(area_dim * length_dim) {} volume_ inline constexpr struct speed_dim_ : decltype(length_dim / time_dim) {} speed_dim; inline constexpr struct velocity_dim_ : speed_dim_ {} velocity_dim; inline constexpr struct acceleration_dim_ : decltype(speed_dim / time_dim) {} acceleration_dim; +inline constexpr struct force_dim_ : decltype(mass_dim * acceleration_dim) {} force_dim; +inline constexpr struct moment_of_force_dim_ : decltype(length_dim * force_dim) {} moment_of_force_dim; +inline constexpr struct torque_dim_ : decltype(moment_of_force_dim) {} torque_dim; +inline constexpr struct pressure_dim_ : decltype(force_dim / area_dim) {} pressure_dim; +inline constexpr struct stress_dim_ : decltype(pressure_dim) {} stress_dim; +inline constexpr struct strain_dim_ : decltype(stress_dim / stress_dim) {} strain_dim; +inline constexpr struct power_dim_ : decltype(force_dim * speed_dim) {} power_dim; +inline constexpr struct efficiency_dim_ : decltype(power_dim / power_dim) {} efficiency_dim; +inline constexpr struct energy_dim_ : decltype(force_dim * length_dim) {} energy_dim; // clang-format on // concepts verification @@ -102,11 +112,15 @@ static_assert( static_assert(is_of_type<1 / (speed_dim * speed_dim) * length_dim, derived_dimension, per>>); -// comparisons of equivalent dimensions +// comparisons of the same dimensions +static_assert(length_dim == length_dim); +static_assert(speed_dim == speed_dim); + +// comparisons of equivalent dimensions (named vs unnamed/derived) static_assert(length_dim / length_dim == one_dim); static_assert(1 / time_dim != frequency_dim); -static_assert(equivalent(1 / time_dim, frequency_dim)); +// static_assert(equivalent(1 / time_dim, frequency_dim)); static_assert(convertible(1 / time_dim, frequency_dim)); static_assert(1 / frequency_dim == time_dim); static_assert(frequency_dim * time_dim == one_dim); @@ -114,7 +128,7 @@ static_assert(std::is_same_v, frequency_dim_>); static_assert(length_dim * length_dim != area_dim); -static_assert(equivalent(length_dim * length_dim, area_dim)); +// static_assert(equivalent(length_dim * length_dim, area_dim)); static_assert(convertible(length_dim * length_dim, area_dim)); static_assert(length_dim * length_dim != volume_dim); static_assert(area_dim / length_dim == length_dim); @@ -122,20 +136,20 @@ static_assert(std::is_same_v, area_dim_>); static_assert(length_dim * length_dim * length_dim != volume_dim); -static_assert(equivalent(length_dim * length_dim * length_dim, volume_dim)); +// static_assert(equivalent(length_dim * length_dim * length_dim, volume_dim)); static_assert(area_dim * length_dim != volume_dim); -static_assert(equivalent(area_dim * length_dim, volume_dim)); +// static_assert(equivalent(area_dim * length_dim, volume_dim)); static_assert(volume_dim / length_dim != area_dim); -static_assert(equivalent(volume_dim / length_dim, area_dim)); +// static_assert(equivalent(volume_dim / length_dim, area_dim)); static_assert(volume_dim / length_dim / length_dim == length_dim); static_assert(area_dim * area_dim / length_dim != volume_dim); -static_assert(equivalent(area_dim * area_dim / length_dim, volume_dim)); +// static_assert(equivalent(area_dim * area_dim / length_dim, volume_dim)); static_assert(area_dim * (area_dim / length_dim) != volume_dim); -static_assert(equivalent(area_dim * (area_dim / length_dim), volume_dim)); +// static_assert(equivalent(area_dim * (area_dim / length_dim), volume_dim)); static_assert(volume_dim / (length_dim * length_dim) == length_dim); static_assert(length_dim / time_dim != speed_dim); -static_assert(equivalent(length_dim / time_dim, speed_dim)); +// static_assert(equivalent(length_dim / time_dim, speed_dim)); static_assert(length_dim * time_dim != speed_dim); static_assert(length_dim / time_dim / time_dim != speed_dim); static_assert(length_dim / speed_dim == time_dim); @@ -146,32 +160,72 @@ static_assert(std::is_same_v); static_assert(length_dim / time_dim / time_dim != acceleration_dim); -static_assert(equivalent(length_dim / time_dim / time_dim, acceleration_dim)); +// static_assert(equivalent(length_dim / time_dim / time_dim, acceleration_dim)); static_assert(length_dim / (time_dim * time_dim) != acceleration_dim); -static_assert(equivalent(length_dim / (time_dim * time_dim), acceleration_dim)); +// static_assert(equivalent(length_dim / (time_dim * time_dim), acceleration_dim)); static_assert(speed_dim / time_dim != acceleration_dim); -static_assert(equivalent(speed_dim / time_dim, acceleration_dim)); +// static_assert(equivalent(speed_dim / time_dim, acceleration_dim)); static_assert(speed_dim / acceleration_dim == time_dim); static_assert(acceleration_dim * time_dim != speed_dim); -static_assert(equivalent(acceleration_dim * time_dim, speed_dim)); +// static_assert(equivalent(acceleration_dim * time_dim, speed_dim)); static_assert(acceleration_dim * (time_dim * time_dim) == length_dim); static_assert(acceleration_dim / speed_dim != frequency_dim); -static_assert(equivalent(acceleration_dim / speed_dim, frequency_dim)); +// static_assert(equivalent(acceleration_dim / speed_dim, frequency_dim)); -static_assert(frequency_dim != action_dim); -static_assert(equivalent(frequency_dim, action_dim)); -static_assert(!convertible(frequency_dim, action_dim)); +// comparison of convertible named dimensions +static_assert(velocity_dim != speed_dim); +// static_assert(equivalent(velocity_dim, speed_dim)); +static_assert(convertible(speed_dim, velocity_dim)); +static_assert(std::is_same_v, velocity_dim_>); +static_assert(std::is_same_v, velocity_dim_>); + +// comparisons of equivalent but not convertible dimensions +static_assert(energy_dim != torque_dim); +// static_assert(equivalent(energy_dim, torque_dim)); +static_assert(!convertible(energy_dim, torque_dim)); + +static_assert(force_dim * length_dim != energy_dim); +static_assert(force_dim * length_dim != torque_dim); +// static_assert(equivalent(force_dim * length_dim, energy_dim)); +// static_assert(equivalent(force_dim * length_dim, torque_dim)); +static_assert(convertible(force_dim * length_dim, energy_dim)); +static_assert(convertible(force_dim * length_dim, torque_dim)); template concept no_common_type = requires { requires !requires { typename std::common_type_t; }; requires !requires { typename std::common_type_t; }; }; +static_assert(no_common_type); + +static_assert(frequency_dim != action_dim); +// static_assert(equivalent(frequency_dim, action_dim)); +static_assert(!convertible(frequency_dim, action_dim)); static_assert(no_common_type); -static_assert(velocity_dim != speed_dim); -static_assert(equivalent(velocity_dim, speed_dim)); -static_assert(convertible(speed_dim, velocity_dim)); -static_assert(std::is_same_v, velocity_dim_>); -static_assert(std::is_same_v, velocity_dim_>); +// Dimensionless +// static_assert(equivalent(power_dim / power_dim, efficiency_dim)); +static_assert(convertible(power_dim / power_dim, efficiency_dim)); +static_assert(power_dim / power_dim != efficiency_dim); +static_assert(one_dim != efficiency_dim); + +// static_assert(equivalent(efficiency_dim, strain_dim)); +static_assert(!convertible(efficiency_dim, strain_dim)); +static_assert(efficiency_dim != strain_dim); + +static_assert(stress_dim / stress_dim != strain_dim); +static_assert(stress_dim / stress_dim != efficiency_dim); +// static_assert(equivalent(stress_dim / stress_dim, strain_dim)); +// static_assert(equivalent(stress_dim / stress_dim, efficiency_dim)); +static_assert(convertible(stress_dim / stress_dim, strain_dim)); +static_assert(convertible(stress_dim / stress_dim, efficiency_dim)); + +// comparison of not equivalent dimensions +static_assert(length_dim != time_dim); +// static_assert(!equivalent(length_dim, time_dim)); +static_assert(!convertible(length_dim, time_dim)); + +static_assert(acceleration_dim != speed_dim); +// static_assert(!equivalent(acceleration_dim, speed_dim)); +static_assert(!convertible(acceleration_dim, speed_dim)); } // namespace From a5c7934e0e0a3fb125b6349af536a8aef678dc5b Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 18 Oct 2022 21:24:09 +0200 Subject: [PATCH 025/402] refactor: units nearly done --- example/v2_framework.cpp | 164 +++------ src/core/include/units/unit.h | 426 ++++++++++-------------- src/systems/si/include/units/si/units.h | 13 + test/unit_test/static/CMakeLists.txt | 5 +- test/unit_test/static/unit_test.cpp | 391 ++++++++++++++++++---- 5 files changed, 565 insertions(+), 434 deletions(-) diff --git a/example/v2_framework.cpp b/example/v2_framework.cpp index 5328425e..34c0a3c8 100644 --- a/example/v2_framework.cpp +++ b/example/v2_framework.cpp @@ -22,16 +22,6 @@ #include - -template -consteval bool print(); - -template -constexpr bool is_of_type(Expr) -{ - return std::is_same_v; -} - namespace { using namespace units; @@ -42,6 +32,18 @@ inline constexpr struct activity_dim : decltype(1 / isq::time_dim) {} activity_d inline constexpr struct activity : system_reference {} activity; // clang-format on +// check for invalid prefixes + +template +concept can_not_be_prefixed = !requires { typename si::milli_; }; + +static_assert(can_not_be_prefixed); +static_assert(can_not_be_prefixed); +static_assert(can_not_be_prefixed); +static_assert(can_not_be_prefixed); +static_assert(can_not_be_prefixed); +static_assert(can_not_be_prefixed); +static_assert(can_not_be_prefixed); // Named quantity/dimension and unit static_assert( @@ -68,24 +70,28 @@ static_assert(is_same_v -concept invalid_comparison = requires { - requires !requires { 2 * R1 == 2 * R2; }; - requires !requires { 2 * R2 == 2 * R1; }; - }; +concept invalid_comparison = !requires { 2 * R1 == 2 * R2; } && !requires { 2 * R2 == 2 * R1; }; static_assert(invalid_comparison); -// static_assert(print()); - // Arithmetics // Named and derived dimensions (same units) @@ -124,14 +130,28 @@ static_assert(is_same_v consteval bool invalid_arithmetic(Ts... ts) { - return requires { - requires !requires { (... + ts); }; - requires !requires { (... - ts); }; - }; + return !requires { (... + ts); } && !requires { (... - ts); }; } static_assert(invalid_arithmetic(5 * activity[Bq], 5 * si::frequency[Hz])); static_assert(invalid_arithmetic(5 * activity[Bq], 10 / (2 * si::time[s]), 5 * si::frequency[Hz])); +// Implicit conversions allowed between quantities of `convertible` references +constexpr quantity speed = 120 * si::length[km] / (2 * si::time[h]); + +// Explicit casts allow changing all or only a part of the type +static_assert( + std::is_same_v< + decltype(quantity_cast(120 * si::length[km] / (2 * si::time[h]))), + quantity)>, per>>{}, + int>>); +auto q3 = quantity_cast(120 * si::length[km] / (2 * si::time[h])); +auto q4 = quantity_cast(120 * si::length[km] / (2 * si::time[h])); +auto q5 = quantity_cast(120 * si::length[km] / (2 * si::time[h])); +auto q6 = quantity_cast>(120 * si::length[km] / (2 * si::time[h])); + +// cast 1 / time_dim to use Hz + // static_assert(quantity_of); // static_assert(quantity_of); // static_assert(quantity_of); @@ -160,105 +180,6 @@ static_assert(invalid_arithmetic(5 * activity[Bq], 10 / (2 * si::time[s]), 5 * s } // namespace -namespace units::si { - -// derived unit expression template syntax verification -static_assert(is_of_type>>(1 / second)); -static_assert(is_of_type(1 / (1 / second))); - -static_assert(is_of_type(one * second)); -static_assert(is_of_type(second * one)); -static_assert(is_of_type>>(one * (1 / second))); -static_assert(is_of_type>>(1 / second * one)); - -static_assert(is_of_type>(metre * second)); -static_assert(is_of_type>>(metre * metre)); - -static_assert(is_of_type, struct second>>(metre * metre * second)); -static_assert(is_of_type, struct second>>(metre * second * metre)); - -static_assert(is_of_type, struct second>>(metre * (second * metre))); -static_assert(is_of_type, struct second>>(second * (metre * metre))); - -static_assert(is_of_type>>(1 / second * metre)); -static_assert(is_of_type(1 / second * second)); - -static_assert(is_of_type(second / one)); -static_assert(is_of_type>>(1 / second / one)); - -static_assert(is_of_type(metre / second * second)); -static_assert(is_of_type>>>(1 / second * (1 / second))); -static_assert(is_of_type>>>(1 / (second * second))); -static_assert(is_of_type>>(1 / (1 / (second * second)))); - -static_assert(is_of_type>>>(metre / second * - (1 / second))); -static_assert(is_of_type, per>>>( - metre / second * (metre / second))); -static_assert(is_of_type(metre / second * (second / metre))); - -static_assert(is_of_type>>(watt / joule)); -static_assert(is_of_type>>(joule / watt)); - -// comparisons of equivalent units -static_assert(metre / metre == one); -// static_assert(metre * metre == square_metre); -// static_assert(second * second == second_squared); -// static_assert(second * second * second == second_cubed); -// static_assert(second * (second * second) == second_cubed); -// static_assert(second_squared * second == second_cubed); -// static_assert(second * second_squared == second_cubed); - -// static_assert(1 / second * metre == metre / second); -// static_assert(metre * (1 / second) == metre / second); -// static_assert((metre / second) * (1 / second) == metre / second / second); -// static_assert((metre / second) * (1 / second) == metre / (second * second)); -// static_assert((metre / second) * (1 / second) == metre / second_squared); - -// static_assert(hertz == 1 / second); -// static_assert(newton == kilogram * metre / second_squared); -// static_assert(joule == kilogram * square_metre / second_squared); -// static_assert(joule == newton * metre); -// static_assert(watt == joule / second); -// static_assert(watt == kilogram * square_metre / second_cubed); - -// static_assert(1 / frequency_dim == second); -// static_assert(frequency_dim * second == one); - -// static_assert(metre * metre == area_dim); -// static_assert(metre * metre != volume_dim); -// static_assert(area_dim / metre == metre); - -// static_assert(metre * metre * metre == volume_dim); -// static_assert(area_dim * metre == volume_dim); -// static_assert(volume_dim / metre == area_dim); -// static_assert(volume_dim / metre / metre == metre); -// static_assert(area_dim * area_dim / metre == volume_dim); -// static_assert(area_dim * (area_dim / metre) == volume_dim); -// static_assert(volume_dim / (metre * metre) == metre); - -// static_assert(metre / second == speed_dim); -// static_assert(metre * second != speed_dim); -// static_assert(metre / second / second != speed_dim); -// static_assert(metre / speed_dim == second); -// static_assert(speed_dim * second == metre); - -// static_assert(metre / second / second == acceleration_dim); -// static_assert(metre / (second * second) == acceleration_dim); -// static_assert(speed_dim / second == acceleration_dim); -// static_assert(speed_dim / acceleration_dim == second); -// static_assert(acceleration_dim * second == speed_dim); -// static_assert(acceleration_dim * (second * second) == metre); -// static_assert(acceleration_dim / speed_dim == frequency_dim); - - -// Bq + Hz should not compile - -// Bq + Hz + 1/s should compile? - - -} // namespace units::si - namespace units { template @@ -331,3 +252,6 @@ int main() // type of Rep{1} * (mag * mag_power<10, -34> * energy[joule] * time[second]) // and inline constexpr auto planck_constant = Rep{1} * mag_planck * energy[joule] * time[second]; + + +// quantity_cast on equivalent dimensions \ No newline at end of file diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index a7b4af77..12e499d1 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -38,50 +38,12 @@ namespace units { -// namespace detail { - -// template -// inline constexpr bool can_be_prefixed = false; - -// } // namespace detail - -/** - * @brief A common point for a hierarchy of units - * - * A unit is an entity defined and adopted by convention, with which any other quantity of - * the same kind can be compared to express the ratio of the second quantity to the first - * one as a number. - * - * All units of the same dimension can be convereted between each other. To allow this all of - * them are expressed as different ratios of the same one proprietary chosen reference unit - * (i.e. all length units are expressed in terms of meter, all mass units are expressed in - * terms of gram, ...) - * - * @tparam M a Magnitude representing the (relative) size of this unit - * @tparam U a unit to use as a reference for this dimension - * - * @note U cannot be constrained with Unit as for some specializations (i.e. named_unit) - * it gets the incomplete child's type with the CRTP idiom. - */ -template -struct scaled_unit { - static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag = M; - using reference = U; -}; - -// TODO: Remove when P1985 accepted namespace detail { -template -void to_base_scaled_unit(const volatile scaled_unit*); - template -inline constexpr bool is_specialization_of_scaled_unit = false; +inline constexpr bool is_unit = false; -template -inline constexpr bool is_specialization_of_scaled_unit> = true; - -} // namespace detail +} /** * @brief A concept matching all unit types in the library @@ -89,129 +51,12 @@ inline constexpr bool is_specialization_of_scaled_unit> = true * Satisfied by all unit types derived from an specialization of :class:`scaled_unit`. */ template -concept Unit = requires(T* t) { detail::to_base_scaled_unit(t); }; - -namespace detail { - -template -inline constexpr bool is_named = false; - -} - -template -concept NamedUnit = Unit && detail::is_named; - -template -struct same_unit_reference : is_same {}; - -namespace detail { - -template -struct unit_less : std::bool_constant() < type_name()> {}; - -template -using type_list_of_unit_less = expr_less; - -/** - * @brief Unpacks the list of potentially derived dimensions to a list containing only base dimensions - * - * @tparam Es Exponents of potentially derived dimensions - */ -// template -// struct unit_extract; - -// template<> -// struct unit_extract, type_list<>> { -// using num = type_list<>; -// using den = type_list<>; -// }; - -// template -// requires BaseUnit || BaseUnit -// struct unit_extract, type_list> { -// using impl = unit_extract, type_list>; -// using num = type_list_push_front; -// using den = TYPENAME impl::den; -// }; - -// template -// requires BaseUnit || BaseUnit -// struct unit_extract, type_list> { -// using impl = unit_extract, type_list>; -// using num = TYPENAME impl::num; -// using den = type_list_push_front; -// }; - -// template -// struct unit_extract, type_list> : -// unit_extract, -// type_list_push_back> {}; - -// template -// struct unit_extract, NRest...>, type_list> : -// unit_extract::num, -// power::den>::type, -// NRest...>, -// type_list_push_back::num, -// power::den>::type, -// Dens...>> {}; - - -// template -// struct unit_extract, type_list> : -// unit_extract> {}; - -// template -// struct unit_extract, type_list, DRest...>> : -// unit_extract::num, power::den>::type, -// type_list_push_back::num, -// power::den>::type, -// DRest...>> {}; - -/** - * @brief Converts user provided derived dimension specification into a valid units::normalized_dimension definition - * - * User provided definition of a derived dimension may contain the same base dimension repeated more than once on the - * list possibly hidden in other derived units provided by the user. The process here should: - * 1. Extract derived dimensions into exponents of base dimensions. - * 2. Sort the exponents so the same dimensions are placed next to each other. - * 3. Consolidate contiguous range of exponents of the same base dimensions to a one (or possibly zero) exponent for - * this base dimension. - */ -template -struct normalized_unit : detail::expr_fractions { - // private: - // using base = detail::expr_fractions; - // using extracted = unit_extract; - // using num_list = expr_consolidate>; - // using den_list = expr_consolidate>; - // using simple = expr_simplify; - // public: - // using normalized_num = TYPENAME simple::num; - // using normalized_den = TYPENAME simple::den; -}; - -} // namespace detail - -// TODO add checking for `per` and power elements as well -template -concept UnitSpec = Unit || is_specialization_of || detail::is_specialization_of_power; +concept Unit = detail::is_unit; // User should not instantiate this type!!! // It should not be exported from the module -template -struct derived_unit : detail::normalized_unit, Us...>, scaled_unit, derived_unit> { - static constexpr bool is_base = false; -}; - -/** - * @brief Unit one - * - * Unit of a dimensionless quantity. - */ -inline constexpr struct one : derived_unit<> { -} one; +template +struct scaled_unit {}; /** * @brief A named unit @@ -225,85 +70,186 @@ template struct named_unit; template -struct named_unit : scaled_unit, named_unit> { +struct named_unit { static constexpr auto symbol = Symbol; - static constexpr bool is_base = true; }; template -struct named_unit : decltype(U) { +struct named_unit { static constexpr auto symbol = Symbol; - static constexpr bool is_base = decltype(U)::is_base; }; +namespace detail { + +template +void to_base_specialization_of_named_unit(const volatile named_unit*); + +} // namespace detail + +template +concept NamedUnit = Unit && requires(T* t) { detail::to_base_specialization_of_named_unit(t); }; + +template +inline constexpr bool unit_can_be_prefixed = NamedUnit>; + /** * @brief A prefixed unit * * Defines a new unit that is a scaled version of another unit by the provided prefix. It is * only possible to create such a unit if the given prefix type matches the one defined in a - * reference unit. + * coherent_unit unit. * * @tparam Child inherited class type used by the downcasting facility (CRTP Idiom) - * @tparam P prefix to be appied to the reference unit - * @tparam U reference unit + * @tparam P prefix to be appied to the coherent_unit unit + * @tparam U coherent_unit unit */ template -// requires detail::can_be_prefixed -struct prefixed_unit : scaled_unit { - // static constexpr auto symbol = symbol + decltype(U)::symbol; - static constexpr bool is_base = decltype(U)::is_base; + requires unit_can_be_prefixed +struct prefixed_unit : std::remove_const_t { + static constexpr auto symbol = Symbol + U.symbol; }; -/** - * @brief A coherent unit of a derived quantity - * - * Defines a new coherent unit of a derived quantity. It should be passed as a coherent unit - * in the dimension's definition for such a quantity. - * - * @tparam Child inherited class type used by the downcasting facility (CRTP Idiom) - */ -// template -// struct derived_unit : downcast_dispatch(), Child>> {}; - namespace detail { -template -void is_named_impl(const volatile named_unit*); +template +inline constexpr bool is_power_of_unit = + requires { requires is_specialization_of_power && Unit; }; -template -void is_named_impl(const volatile prefixed_unit*); +template +concept UnitLike = Unit || is_power_of_unit; -template -inline constexpr bool is_named = requires(U * u) { is_named_impl(u); }; +template +inline constexpr bool is_per_of_units = false; -// template -// void can_be_prefixed_impl(const volatile named_unit*); - -// template -// void can_be_prefixed_impl(const volatile named_scaled_unit*); - -// template -// void can_be_prefixed_impl(const volatile alias_unit*); - -// template -// inline constexpr bool can_be_prefixed = requires(U * u) { can_be_prefixed_impl(u); }; - -// template -// inline constexpr bool can_be_prefixed> = can_be_prefixed; +template +inline constexpr bool is_per_of_units> = (... && UnitLike); } // namespace detail +template +concept UnitSpec = detail::UnitLike || detail::is_per_of_units; + +// User should not instantiate this type!!! +// It should not be exported from the module +template +struct derived_unit : detail::expr_fractions, Us...> {}; + +/** + * @brief Unit one + * + * Unit of a dimensionless quantity. + */ +inline constexpr struct one : derived_unit<> { +} one; + + +namespace detail { + +template +void is_unit_impl(const volatile scaled_unit*); + +template +void is_unit_impl(const volatile named_unit*); + +template +void is_unit_impl(const volatile derived_unit*); + +template + requires requires(T* t) { is_unit_impl(t); } +inline constexpr bool is_unit = true; + +/** + * @brief A common point for a hierarchy of units + * + * A unit is an entity defined and adopted by convention, with which any other quantity of + * the same kind can be compared to express the ratio of the second quantity to the first + * one as a number. + * + * All units of the same dimension can be convereted between each other. To allow this all of + * them are expressed as different ratios of the same one proprietary chosen coherent_unit unit + * (i.e. all length units are expressed in terms of meter, all mass units are expressed in + * terms of gram, ...) + * + * @tparam M a Magnitude representing the (relative) size of this unit + * @tparam U a unit to use as a coherent_unit for this dimension + * + * @note U cannot be constrained with Unit as for some specializations (i.e. named_unit) + * it gets the incomplete child's type with the CRTP idiom. + */ +template +struct canonical_unit { + U reference_unit; + M mag; +}; + +[[nodiscard]] constexpr auto get_canonical_unit(UnitLike auto u); + +template +[[nodiscard]] constexpr auto get_canonical_unit_impl(T, const volatile scaled_unit&) +{ + auto base = get_canonical_unit(U{}); + return canonical_unit{base.reference_unit, M * base.mag}; +} + +template +[[nodiscard]] constexpr auto get_canonical_unit_impl(T t, const volatile named_unit&) +{ + return canonical_unit{t, mag<1>}; +} + +template +[[nodiscard]] constexpr auto get_canonical_unit_impl(T, const volatile named_unit&) +{ + return get_canonical_unit(U); +} + +template +[[nodiscard]] constexpr auto get_canonical_unit_impl(T, const volatile power&) +{ + auto base = get_canonical_unit(F{}); + return canonical_unit{ + derived_unit, power::exponent>>{}, + pow::exponent>(base.mag)}; +} + +template +[[nodiscard]] constexpr auto get_canonical_unit_impl(T, const volatile derived_unit&) +{ + if constexpr (type_list_size::_den_> != 0) { + auto num = get_canonical_unit(type_list_map::_num_, derived_unit>{}); + auto den = get_canonical_unit(type_list_map::_den_, derived_unit>{}); + return canonical_unit{num.reference_unit / den.reference_unit, num.mag / den.mag}; + } else { + auto num = (one * ... * get_canonical_unit(Us{}).reference_unit); + auto mag = (units::mag<1> * ... * get_canonical_unit(Us{}).mag); + return canonical_unit{num, mag}; + } +} + +[[nodiscard]] constexpr auto get_canonical_unit(UnitLike auto u) { return get_canonical_unit_impl(u, u); } + + +template +struct unit_less : std::bool_constant() < type_name()> {}; + +template +using type_list_of_unit_less = expr_less; + +} // namespace detail + + +// Operators + template [[nodiscard]] consteval Unit auto operator*(M mag, U) { - return scaled_unit{}; + // TODO Try passing magnitude parameters rather than magnitude type itself in case of a trivial magnitude + // (single integer, ratio...) + return scaled_unit>{}; } -template -[[nodiscard]] consteval Unit auto operator*(M1 mag, scaled_unit) -{ - return scaled_unit{}; -} +template +[[nodiscard]] consteval Unit auto operator*(U, M) = delete; template [[nodiscard]] consteval Unit auto operator*(U1, U2) @@ -324,72 +270,46 @@ template return detail::expr_invert(); } +template +[[nodiscard]] consteval Unit auto operator/(U, int) = delete; + template -[[nodiscard]] consteval bool operator==(U1, U2) +[[nodiscard]] consteval bool operator==(U1 lhs, U2 rhs) { - return is_same_v; + auto canonical_lhs = detail::get_canonical_unit(lhs); + auto canonical_rhs = detail::get_canonical_unit(rhs); + return is_same_v && + canonical_lhs.mag == canonical_rhs.mag; } -// template -// constexpr bool operator==(D1, D2) -// { -// return D1::symbol == D2::symbol; -// } - -// template -// requires(type_list_size == 0) && (type_list_size == 1) && -// BaseDimension> -// constexpr bool operator==(D1, D2) -// { -// return D1::symbol == type_list_front::symbol; -// } - -// template -// requires(type_list_size == 0) && (type_list_size == 1) && -// BaseDimension> -// constexpr bool operator==(D1, D2) -// { -// return type_list_front::symbol == D2::symbol; -// } - -// template -// constexpr bool operator==(D1, D2) -// { -// return std::is_same_v && -// std::is_same_v; -// } - -// TODO implement this -// template -// [[nodiscard]] consteval bool equivalent(D1, D2) -// { -// return is_same_v, detail::dim_type>; -// } - +// Convertible template -[[nodiscard]] consteval bool convertible(U1, U2) +[[nodiscard]] consteval bool convertible(U1 lhs, U2 rhs) { - // TODO implement this - return std::derived_from || std::derived_from; + auto canonical_lhs = detail::get_canonical_unit(lhs); + auto canonical_rhs = detail::get_canonical_unit(rhs); + return is_same_v; } +// Helper types and variable factories template struct square_ : decltype(U{} * U{}) {}; -template -inline constexpr square_> square; - template struct cubic_ : decltype(U{} * U{} * U{}) {}; +// it is not allowed to use the same name for a variable and class template +// (even though it works for objects of regular class types) +template +inline constexpr square_> square; + template inline constexpr cubic_> cubic; } // namespace units namespace std { - // TODO implement this template requires(units::convertible(U1{}, U2{})) diff --git a/src/systems/si/include/units/si/units.h b/src/systems/si/include/units/si/units.h index 2768c444..26b46db8 100644 --- a/src/systems/si/include/units/si/units.h +++ b/src/systems/si/include/units/si/units.h @@ -86,3 +86,16 @@ inline constexpr struct electronvolt : named_unit<"eV", mag +inline constexpr bool unit_can_be_prefixed = false; +template<> +inline constexpr bool unit_can_be_prefixed = false; +template<> +inline constexpr bool unit_can_be_prefixed = false; +template<> +inline constexpr bool unit_can_be_prefixed = false; + +} // namespace units diff --git a/test/unit_test/static/CMakeLists.txt b/test/unit_test/static/CMakeLists.txt index 6abc8d0a..5d48f53d 100644 --- a/test/unit_test/static/CMakeLists.txt +++ b/test/unit_test/static/CMakeLists.txt @@ -35,6 +35,7 @@ cmake_minimum_required(VERSION 3.2) add_library( unit_tests_static dimension_test.cpp + # angle_test.cpp # cgs_test.cpp # chrono_test.cpp @@ -48,6 +49,7 @@ add_library( # iec80000_test.cpp # kind_test.cpp magnitude_test.cpp + # math_test.cpp # point_origin_test.cpp # prime_test.cpp @@ -59,7 +61,8 @@ add_library( # si_hep_test.cpp # symbol_text_test.cpp # type_list_test.cpp - # unit_test.cpp + unit_test.cpp + # us_test.cpp ) diff --git a/test/unit_test/static/unit_test.cpp b/test/unit_test/static/unit_test.cpp index 4c3c4569..907f461b 100644 --- a/test/unit_test/static/unit_test.cpp +++ b/test/unit_test/static/unit_test.cpp @@ -20,22 +20,26 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -#include "test_tools.h" -#include -#include -#include -#include -#include +#include #include namespace { +using namespace units; +using namespace units::detail; + +template +inline constexpr bool is_of_type = std::is_same_v, T>; + +using one_ = struct one; + // clang-format off // base units inline constexpr struct second_ : named_unit<"s"> {} second; inline constexpr struct metre_ : named_unit<"m"> {} metre; inline constexpr struct gram_ : named_unit<"g"> {} gram; -inline constexpr struct kilogram_ : decltype(kilo) {} kilogram; +inline constexpr struct kilogram_ : decltype(si::kilo) {} kilogram; +inline constexpr struct kelvin_ : named_unit<"K"> {} kelvin; // derived named units inline constexpr struct radian_ : named_unit<"rad", metre / metre> {} radian; @@ -46,104 +50,371 @@ inline constexpr struct newton_ : named_unit<"N", kilogram * metre / square> {} 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 {} 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 day_ : named_unit<"d", mag<24> * hour> {} day; inline constexpr struct astronomical_unit_ : named_unit<"au", mag<149'597'870'700> * metre> {} astronomical_unit; inline constexpr struct degree_ : named_unit * radian> {} degree; -inline constexpr struct are_ : named_unit<"a", square>> {} are; -inline constexpr struct hectare_ : decltype(hecto) {} hectare; -inline constexpr struct litre_ : named_unit<"l", cubic>> {} litre; +inline constexpr struct are_ : named_unit<"a", square>> {} are; +inline constexpr struct hectare_ : decltype(si::hecto) {} hectare; +inline constexpr struct litre_ : named_unit<"l", cubic>> {} litre; inline constexpr struct tonne_ : named_unit<"t", mag<1000> * kilogram> {} tonne; inline constexpr struct dalton_ : named_unit<"Da", mag * mag_power<10, -27> * kilogram> {} dalton; inline constexpr struct electronvolt_ : named_unit<"eV", mag * mag_power<10, -19> * joule> {} electronvolt; -inline constexpr struct kilometre_ : decltype(kilo) {} kilometre; +inline constexpr struct kilometre_ : decltype(si::kilo) {} kilometre; +inline constexpr struct kilojoule_ : decltype(si::kilo) {} kilojoule; // clang-format on -} - // concepts verification static_assert(Unit); static_assert(Unit); static_assert(Unit); static_assert(Unit); static_assert(Unit); -static_assert(Unit)>); +static_assert(Unit)>); static_assert(Unit)>); static_assert(Unit)>); static_assert(Unit * second)>); static_assert(Unit); static_assert(NamedUnit); -static_assert(NamedUnit); static_assert(NamedUnit); static_assert(NamedUnit); static_assert(NamedUnit); -static_assert(!NamedUnit)>); +static_assert(NamedUnit); +static_assert(!NamedUnit); +static_assert(!NamedUnit); +static_assert(!NamedUnit); +static_assert(!NamedUnit)>); static_assert(!NamedUnit)>); static_assert(!NamedUnit)>); static_assert(!NamedUnit * second)>); static_assert(!NamedUnit); +template +constexpr bool print(); -static_assert(kilo == kilometre); -static_assert(mag<1000> * metre == kilo); +// named unit +static_assert(is_of_type); +static_assert(is_of_type); +static_assert(get_canonical_unit(metre).mag == mag<1>); +static_assert(convertible(metre, metre)); +static_assert(!convertible(metre, second)); +static_assert(metre == metre); +static_assert(metre != second); + +static_assert(is_of_type); +static_assert(is_of_type); +static_assert(get_canonical_unit(degree_Celsius).mag == mag<1>); +static_assert(convertible(degree_Celsius, kelvin)); +static_assert(degree_Celsius == kelvin); + +static_assert(is_of_type); +static_assert(is_of_type); +static_assert(get_canonical_unit(radian).mag == mag<1>); +static_assert(convertible(minute, second)); +static_assert(minute != second); + +static_assert(is_of_type); +static_assert(is_of_type); +static_assert(get_canonical_unit(steradian).mag == mag<1>); +static_assert(convertible(radian, steradian)); // !!! +static_assert(radian == steradian); // !!! + +static_assert(is_of_type); +static_assert(is_of_type); +static_assert(get_canonical_unit(minute).mag == mag<60>); +static_assert(convertible(minute, second)); +static_assert(minute != second); + +static_assert(is_of_type); +static_assert(is_of_type); +static_assert(get_canonical_unit(hour).mag == mag<3600>); +static_assert(convertible(hour, second)); + +static_assert(convertible(hour, minute)); +static_assert(convertible(hour, hour)); +static_assert(hour != second); +static_assert(hour != minute); +static_assert(hour == hour); + +static_assert(is_of_type); +static_assert( + is_of_type>>>); +static_assert(get_canonical_unit(newton).mag == mag<1000>); // !!! (because of kilogram) +static_assert(convertible(newton, newton)); +static_assert(newton == newton); + +static_assert(is_of_type); +static_assert( + is_of_type, per>>>); +static_assert(get_canonical_unit(joule).mag == mag<1000>); // !!! (because of kilogram) +static_assert(convertible(joule, joule)); +static_assert(joule == joule); +static_assert(joule != newton); + + +// prefixed_unit +static_assert(is_of_type); +static_assert(is_of_type); +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); +static_assert(is_of_type, per>>>); +static_assert(get_canonical_unit(kilojoule).mag == mag<1'000'000>); +static_assert(convertible(kilojoule, joule)); +static_assert(kilojoule != joule); +static_assert(kilojoule.symbol == "kJ"); + +static_assert(is_of_type, si::kilo_>); +static_assert(is_of_type, si::kilo_>); + + +// prefixes +static_assert(si::yocto.symbol == "ym"); +static_assert(si::zepto.symbol == "zm"); +static_assert(si::atto.symbol == "am"); +static_assert(si::femto.symbol == "fm"); +static_assert(si::pico.symbol == "pm"); +static_assert(si::nano.symbol == "nm"); +static_assert(si::micro.symbol == basic_symbol_text{"µm", "um"}); +static_assert(si::milli.symbol == "mm"); +static_assert(si::centi.symbol == "cm"); +static_assert(si::deci.symbol == "dm"); +static_assert(si::deca.symbol == "dam"); +static_assert(si::hecto.symbol == "hm"); +static_assert(si::kilo.symbol == "km"); +static_assert(si::mega.symbol == "Mm"); +static_assert(si::giga.symbol == "Gm"); +static_assert(si::tera.symbol == "Tm"); +static_assert(si::peta.symbol == "Pm"); +static_assert(si::exa.symbol == "Em"); +static_assert(si::zetta.symbol == "Zm"); +static_assert(si::yotta.symbol == "Ym"); + + +// scaled_unit +constexpr auto u1 = mag<1> * metre; +static_assert(is_of_type, metre_>>); +static_assert(is_of_type); +static_assert(get_canonical_unit(u1).mag == mag<1>); + +constexpr auto u2 = mag<2> * kilometre; +static_assert(is_of_type, kilometre_>>); +static_assert(is_of_type); +static_assert(get_canonical_unit(u2).mag == mag<2000>); + +constexpr auto u3 = mag<42> * si::kilo; +static_assert(is_of_type, si::kilo_>>); +static_assert( + is_of_type, per>>>); +static_assert(get_canonical_unit(u3).mag == mag<42'000'000>); + + +// derived unit expression template syntax verification +static_assert(is_of_type<1 / second, derived_unit>>); +static_assert(is_of_type<1 / (1 / second), second_>); + +static_assert(is_of_type); +static_assert(is_of_type); +static_assert(is_of_type>>); +static_assert(is_of_type<1 / second * one, derived_unit>>); + +static_assert(is_of_type>); +static_assert(is_of_type>>); + +static_assert(is_of_type, second_>>); +static_assert(is_of_type, second_>>); + +static_assert(is_of_type, second_>>); +static_assert(is_of_type, second_>>); + +static_assert(is_of_type<1 / second * metre, derived_unit>>); +static_assert(is_of_type<1 / second * second, one_>); + +static_assert(is_of_type); +static_assert(is_of_type<1 / second / one, derived_unit>>); + +static_assert(is_of_type); +static_assert(is_of_type<1 / second * (1 / second), derived_unit>>>); +static_assert(is_of_type<1 / (second * second), derived_unit>>>); +static_assert(is_of_type<1 / (1 / (second * second)), derived_unit>>); + +static_assert(is_of_type>>>); +static_assert(is_of_type, per>>>); +static_assert(is_of_type); + +static_assert(is_of_type>>); +static_assert(is_of_type>>); + + +// derived unit normalization +constexpr auto u4 = metre / second; +static_assert(is_of_type>>); +static_assert(get_canonical_unit(u4).mag == mag<1>); + +constexpr auto u5 = kilometre / second; +static_assert(is_of_type>>); +static_assert(is_of_type>>); +static_assert(get_canonical_unit(u5).mag == mag<1000>); + +constexpr auto u6 = kilometre / hour; +static_assert(is_of_type>>); +static_assert(is_of_type>>); +static_assert(get_canonical_unit(u6).mag == mag); + +constexpr auto u7 = mag<1000> * kilometre / hour; +static_assert(is_of_type, kilometre_>, per>>); +static_assert(is_of_type>>); +static_assert(get_canonical_unit(u7).mag == mag); + +constexpr auto u8 = mag<1000> * (kilometre / hour); +static_assert(is_of_type, derived_unit>>>); +static_assert(is_of_type>>); +static_assert(get_canonical_unit(u8).mag == mag); + +constexpr auto u9 = 1 / hour * (mag<1000> * kilometre); +static_assert(is_of_type, kilometre_>, per>>); +static_assert(is_of_type>>); +static_assert(get_canonical_unit(u9).mag == mag); + +// comparisons of the same units +static_assert(second == second); +static_assert(metre / second == metre / second); + +// comparisons of equivalent units (named vs unnamed/derived) +static_assert(1 / second == hertz); +static_assert(convertible(1 / second, hertz)); + +// comparisons of equivalent but not convertible units +static_assert(hertz == becquerel); +static_assert(convertible(hertz, becquerel)); + +// comparisons of scaled units +static_assert(si::kilo == kilometre); +static_assert(mag<1000> * metre == si::kilo); static_assert(mag<1000> * metre == kilometre); -static_assert(equivalent, kilometre>); -static_assert(equivalent * metre, kilo>); -static_assert(equivalent * metre, kilometre>); +static_assert(convertible(si::kilo, kilometre)); +static_assert(convertible(mag<1000> * metre, si::kilo)); +static_assert(convertible(mag<1000> * metre, kilometre)); static_assert(metre != kilometre); +static_assert(convertible(metre, kilometre)); static_assert(mag<100> * metre != kilometre); -static_assert(milli != kilometre); -static_assert(!equivalent); -static_assert(!equivalent * metre, kilometre>); -static_assert(!equivalent, kilometre>); +static_assert(convertible(mag<100> * metre, kilometre)); +static_assert(si::milli != kilometre); +static_assert(convertible(si::milli, kilometre)); -static_assert(1 / second != hertz); -static_assert(becquerel != hertz); -static_assert(equivalent<1 / second, hertz>); -static_assert(!equivalent); +// one +static_assert(metre / metre == one); +// static_assert(metre * metre == square_metre); +// static_assert(second * second == second_squared); +// static_assert(second * second * second == second_cubed); +// static_assert(second * (second * second) == second_cubed); +// static_assert(second_squared * second == second_cubed); +// static_assert(second * second_squared == second_cubed); -using namespace units; -using namespace units::isq; +// static_assert(1 / second * metre == metre / second); +// static_assert(metre * (1 / second) == metre / second); +// static_assert((metre / second) * (1 / second) == metre / second / second); +// static_assert((metre / second) * (1 / second) == metre / (second * second)); +// static_assert((metre / second) * (1 / second) == metre / second_squared); -struct metre : named_unit {}; -struct centimetre : prefixed_unit {}; -struct kilometre : prefixed_unit {}; -struct yard : named_scaled_unit(), metre> {}; -struct foot : named_scaled_unit(), yard> {}; -struct dim_length : base_dimension<"length", metre> {}; +// static_assert(hertz == 1 / second); +// static_assert(newton == kilogram * metre / second_squared); +// static_assert(joule == kilogram * square_metre / second_squared); +// static_assert(joule == newton * metre); +// static_assert(watt == joule / second); +// static_assert(watt == kilogram * square_metre / second_cubed); -struct second : named_unit {}; -struct hour : named_scaled_unit(), second> {}; -struct dim_time : base_dimension<"time", second> {}; +// static_assert(1 / frequency_dim == second); +// static_assert(frequency_dim * second == one); -struct kelvin : named_unit {}; +// static_assert(metre * metre == area_dim); +// static_assert(metre * metre != volume_dim); +// static_assert(area_dim / metre == metre); -#if !UNITS_COMP_MSVC -static_assert([](P) { - return !requires { typename prefixed_unit; }; -}(si::kilo{})); // no prefix allowed -#endif +// static_assert(metre * metre * metre == volume_dim); +// static_assert(area_dim * metre == volume_dim); +// static_assert(volume_dim / metre == area_dim); +// static_assert(volume_dim / metre / metre == metre); +// static_assert(area_dim * area_dim / metre == volume_dim); +// static_assert(area_dim * (area_dim / metre) == volume_dim); +// static_assert(volume_dim / (metre * metre) == metre); -struct metre_per_second : derived_unit {}; -struct dim_speed : - derived_dimension, units::exponent> {}; -struct kilometre_per_hour : derived_scaled_unit {}; +// static_assert(metre / second == speed_dim); +// static_assert(metre * second != speed_dim); +// static_assert(metre / second / second != speed_dim); +// static_assert(metre / speed_dim == second); +// static_assert(speed_dim * second == metre); -static_assert(equivalent); -static_assert(equivalent); -static_assert(compare(), metre>>, metre>); -static_assert(compare(), metre>>, centimetre>); -static_assert(compare>, yard>); -static_assert(compare(), metre>>, foot>); -static_assert(compare>, kilometre_per_hour>); +// static_assert(metre / second / second == acceleration_dim); +// static_assert(metre / (second * second) == acceleration_dim); +// static_assert(speed_dim / second == acceleration_dim); +// static_assert(speed_dim / acceleration_dim == second); +// static_assert(acceleration_dim * second == speed_dim); +// static_assert(acceleration_dim * (second * second) == metre); +// static_assert(acceleration_dim / speed_dim == frequency_dim); + + +// milli / milli == micro / micro; +// milli * kilo == deci * deca; + +// Bq + Hz should not compile + +// Bq + Hz + 1/s should compile? + + +// using namespace units; +// using namespace units::isq; + +// struct metre : named_unit {}; +// struct centimetre : prefixed_unit {}; +// struct kilometre : prefixed_unit {}; +// struct yard : named_scaled_unit(), metre> {}; +// struct foot : named_scaled_unit(), yard> {}; +// struct dim_length : base_dimension<"length", metre> {}; + +// struct second : named_unit {}; +// struct hour : named_scaled_unit(), second> {}; +// struct dim_time : base_dimension<"time", second> {}; + +// struct kelvin : named_unit {}; + +// #if !UNITS_COMP_MSVC +// static_assert([](P) { +// return !requires { typename prefixed_unit; }; +// }(si::kilo{})); // no prefix allowed +// #endif + +// struct metre_per_second : derived_unit {}; +// struct dim_speed : +// derived_dimension, units::exponent> {}; +// struct kilometre_per_hour : derived_scaled_unit {}; + +// static_assert(equivalent); +// static_assert(equivalent); +// static_assert(compare(), metre>>, metre>); +// static_assert(compare(), metre>>, centimetre>); +// static_assert(compare>, yard>); +// static_assert(compare(), metre>>, foot>); +// static_assert(compare>, kilometre_per_hour>); + +// static_assert(centimetre::symbol == "cm"); +// static_assert(kilometre::symbol == "km"); +// static_assert(kilometre_per_hour::symbol == "km/h"); + + +// static_assert(si::metre != si::kilometre); +// static_assert(!equivalent(si::metre, si::kilometre)); +// static_assert(convertible(si::metre, si::kilometre)); -static_assert(centimetre::symbol == "cm"); -static_assert(kilometre::symbol == "km"); -static_assert(kilometre_per_hour::symbol == "km/h"); } // namespace From 6d898957abe90bc60bb26625468b160412a0bd4e Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 18 Oct 2022 22:55:58 +0200 Subject: [PATCH 026/402] docs: invalid comment text fixed --- test/unit_test/static/unit_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit_test/static/unit_test.cpp b/test/unit_test/static/unit_test.cpp index 907f461b..6d3701de 100644 --- a/test/unit_test/static/unit_test.cpp +++ b/test/unit_test/static/unit_test.cpp @@ -293,7 +293,7 @@ static_assert(metre / second == metre / second); static_assert(1 / second == hertz); static_assert(convertible(1 / second, hertz)); -// comparisons of equivalent but not convertible units +// comparisons of equivalent units of different quantities static_assert(hertz == becquerel); static_assert(convertible(hertz, becquerel)); From 03e064fccd9b96cfa34509af2b4f2358b4861e3c Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 18 Oct 2022 22:57:02 +0200 Subject: [PATCH 027/402] feat: `equivalent` support removed --- src/core/include/units/dimension.h | 6 ------ src/core/include/units/reference.h | 6 ------ test/unit_test/static/dimension_test.cpp | 24 ------------------------ 3 files changed, 36 deletions(-) diff --git a/src/core/include/units/dimension.h b/src/core/include/units/dimension.h index 6aa81a26..458f45dc 100644 --- a/src/core/include/units/dimension.h +++ b/src/core/include/units/dimension.h @@ -211,12 +211,6 @@ template return is_same_v; } -// template -// [[nodiscard]] consteval bool equivalent(D1, D2) -// { -// return is_same_v, detail::dim_type>; -// } - template [[nodiscard]] consteval bool convertible(D1, D2) { diff --git a/src/core/include/units/reference.h b/src/core/include/units/reference.h index 1b89a09c..992a4df7 100644 --- a/src/core/include/units/reference.h +++ b/src/core/include/units/reference.h @@ -136,12 +136,6 @@ template void /*Use `q * (1 * r)` rather than `q * r`.*/ operator*(Quantity auto, Reference auto) = delete; -// template -// [[nodiscard]] consteval bool equivalent(R1, R2) -// { -// return equivalent(R1::dimension, R2::dimension) && R1::unit == R2::unit; -// } - template [[nodiscard]] consteval bool convertible(R1, R2) { diff --git a/test/unit_test/static/dimension_test.cpp b/test/unit_test/static/dimension_test.cpp index 526c0136..c933488d 100644 --- a/test/unit_test/static/dimension_test.cpp +++ b/test/unit_test/static/dimension_test.cpp @@ -120,7 +120,6 @@ static_assert(speed_dim == speed_dim); static_assert(length_dim / length_dim == one_dim); static_assert(1 / time_dim != frequency_dim); -// static_assert(equivalent(1 / time_dim, frequency_dim)); static_assert(convertible(1 / time_dim, frequency_dim)); static_assert(1 / frequency_dim == time_dim); static_assert(frequency_dim * time_dim == one_dim); @@ -128,7 +127,6 @@ static_assert(std::is_same_v, frequency_dim_>); static_assert(length_dim * length_dim != area_dim); -// static_assert(equivalent(length_dim * length_dim, area_dim)); static_assert(convertible(length_dim * length_dim, area_dim)); static_assert(length_dim * length_dim != volume_dim); static_assert(area_dim / length_dim == length_dim); @@ -136,20 +134,14 @@ static_assert(std::is_same_v, area_dim_>); static_assert(length_dim * length_dim * length_dim != volume_dim); -// static_assert(equivalent(length_dim * length_dim * length_dim, volume_dim)); static_assert(area_dim * length_dim != volume_dim); -// static_assert(equivalent(area_dim * length_dim, volume_dim)); static_assert(volume_dim / length_dim != area_dim); -// static_assert(equivalent(volume_dim / length_dim, area_dim)); static_assert(volume_dim / length_dim / length_dim == length_dim); static_assert(area_dim * area_dim / length_dim != volume_dim); -// static_assert(equivalent(area_dim * area_dim / length_dim, volume_dim)); static_assert(area_dim * (area_dim / length_dim) != volume_dim); -// static_assert(equivalent(area_dim * (area_dim / length_dim), volume_dim)); static_assert(volume_dim / (length_dim * length_dim) == length_dim); static_assert(length_dim / time_dim != speed_dim); -// static_assert(equivalent(length_dim / time_dim, speed_dim)); static_assert(length_dim * time_dim != speed_dim); static_assert(length_dim / time_dim / time_dim != speed_dim); static_assert(length_dim / speed_dim == time_dim); @@ -160,34 +152,25 @@ static_assert(std::is_same_v); static_assert(length_dim / time_dim / time_dim != acceleration_dim); -// static_assert(equivalent(length_dim / time_dim / time_dim, acceleration_dim)); static_assert(length_dim / (time_dim * time_dim) != acceleration_dim); -// static_assert(equivalent(length_dim / (time_dim * time_dim), acceleration_dim)); static_assert(speed_dim / time_dim != acceleration_dim); -// static_assert(equivalent(speed_dim / time_dim, acceleration_dim)); static_assert(speed_dim / acceleration_dim == time_dim); static_assert(acceleration_dim * time_dim != speed_dim); -// static_assert(equivalent(acceleration_dim * time_dim, speed_dim)); static_assert(acceleration_dim * (time_dim * time_dim) == length_dim); static_assert(acceleration_dim / speed_dim != frequency_dim); -// static_assert(equivalent(acceleration_dim / speed_dim, frequency_dim)); // comparison of convertible named dimensions static_assert(velocity_dim != speed_dim); -// static_assert(equivalent(velocity_dim, speed_dim)); static_assert(convertible(speed_dim, velocity_dim)); static_assert(std::is_same_v, velocity_dim_>); static_assert(std::is_same_v, velocity_dim_>); // comparisons of equivalent but not convertible dimensions static_assert(energy_dim != torque_dim); -// static_assert(equivalent(energy_dim, torque_dim)); static_assert(!convertible(energy_dim, torque_dim)); static_assert(force_dim * length_dim != energy_dim); static_assert(force_dim * length_dim != torque_dim); -// static_assert(equivalent(force_dim * length_dim, energy_dim)); -// static_assert(equivalent(force_dim * length_dim, torque_dim)); static_assert(convertible(force_dim * length_dim, energy_dim)); static_assert(convertible(force_dim * length_dim, torque_dim)); template @@ -198,34 +181,27 @@ concept no_common_type = requires { static_assert(no_common_type); static_assert(frequency_dim != action_dim); -// static_assert(equivalent(frequency_dim, action_dim)); static_assert(!convertible(frequency_dim, action_dim)); static_assert(no_common_type); // Dimensionless -// static_assert(equivalent(power_dim / power_dim, efficiency_dim)); static_assert(convertible(power_dim / power_dim, efficiency_dim)); static_assert(power_dim / power_dim != efficiency_dim); static_assert(one_dim != efficiency_dim); -// static_assert(equivalent(efficiency_dim, strain_dim)); static_assert(!convertible(efficiency_dim, strain_dim)); static_assert(efficiency_dim != strain_dim); static_assert(stress_dim / stress_dim != strain_dim); static_assert(stress_dim / stress_dim != efficiency_dim); -// static_assert(equivalent(stress_dim / stress_dim, strain_dim)); -// static_assert(equivalent(stress_dim / stress_dim, efficiency_dim)); static_assert(convertible(stress_dim / stress_dim, strain_dim)); static_assert(convertible(stress_dim / stress_dim, efficiency_dim)); // comparison of not equivalent dimensions static_assert(length_dim != time_dim); -// static_assert(!equivalent(length_dim, time_dim)); static_assert(!convertible(length_dim, time_dim)); static_assert(acceleration_dim != speed_dim); -// static_assert(!equivalent(acceleration_dim, speed_dim)); static_assert(!convertible(acceleration_dim, speed_dim)); } // namespace From 98a19f6b4c2aed4fbd7d07416f075ac88737ea90 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Wed, 19 Oct 2022 11:21:15 +0200 Subject: [PATCH 028/402] feat: dimensions design is now complete --- src/core/include/units/dimension.h | 89 +++++++++++++++++++++--- test/unit_test/static/dimension_test.cpp | 8 +++ 2 files changed, 88 insertions(+), 9 deletions(-) diff --git a/src/core/include/units/dimension.h b/src/core/include/units/dimension.h index 458f45dc..b81dfb56 100644 --- a/src/core/include/units/dimension.h +++ b/src/core/include/units/dimension.h @@ -37,9 +37,23 @@ namespace units { * quantities. * * Symbol template parameters is an unique identifier of the base dimension. The same identifiers can be multiplied - * and divided which will result with an adjustment of its factor in an Exponent of a DerivedDimension + * and divided which will result with an adjustment of its factor in an exponent of a derived_dimension * (in case of zero the dimension will be simplified and removed from further analysis of current expresion). * + * User should derive a strong type from this class template rather than use it directly in the source code. + * For example: + * + * @code{.cpp} + * inline constexpr struct length_dim : base_dimension<"L"> {} length_dim; + * inline constexpr struct time_dim : base_dimension<"T"> {} time_dim; + * inline constexpr struct mass_dim : base_dimension<"M"> {} mass_dim; + * @endcode + * + * @note A common convention in this library is to assign the same name for a type and an object of this type. + * Besides defining them user never works with the dimension types in the source code. All operations + * are done on the objects. Contrarily, the dimension types are the only one visible in the compilation + * errors. Having them of the same names improves user experience and somehow blurs those separate domains. + * * @tparam Symbol an unique identifier of the base dimension used to provide dimensional analysis support */ template @@ -61,17 +75,14 @@ inline constexpr bool is_specialization_of_base_dimension } // namespace detail /** - * @brief A concept matching all base dimensions in the library. + * @brief A concept matching all named base dimensions in the library. * - * Satisfied by all dimension types derived from an specialization of `base_dimension`. + * Satisfied by all dimension types derived from a specialization of `base_dimension`. */ template concept BaseDimension = requires(T* t) { detail::to_base_base_dimension(t); } && (!detail::is_specialization_of_base_dimension); -template -struct base_dimension_less : std::bool_constant<(D1::symbol < D2::symbol)> {}; - namespace detail { template @@ -82,7 +93,8 @@ inline constexpr bool is_derived_dimension = false; /** * @brief A concept matching all derived dimensions in the library. * - * Satisfied by all dimension types derived from an specialization of `derived_dimension`. + * Satisfied by all dimension types either being a specialization of `derived_dimension` + * or derived from it. */ template concept DerivedDimension = detail::is_derived_dimension; @@ -97,6 +109,8 @@ concept Dimension = BaseDimension || DerivedDimension; namespace detail { +template +struct base_dimension_less : std::bool_constant<(D1::symbol < D2::symbol)> {}; template using type_list_of_base_dimension_less = expr_less; @@ -135,8 +149,56 @@ struct derived_dimension_impl : detail::expr_fractions, Ds.. } // namespace detail -// User should not instantiate this type!!! -// It should not be exported from the module + +/** + * @brief A dimension of a derived quantity + * + * Derived dimension is an expression of the dependence of a quantity on the base quantities of a system of quantities + * as a product of powers of factors corresponding to the base quantities, omitting any numerical factors. + * + * Instead of using a raw list of exponents this library decided to use expression template syntax to make types + * more digestable for the user. The positive exponents are ordered first and all negative exponents are put as a list + * into the `per<...>` class template. If a power of exponent is different than `1` the dimension type is enclosed in + * `power` class template. Otherwise, it is just put directly in the list without any wrapper. There + * is also one special case. In case all of the exponents are negative than the `one_dim` being a dimension of + * a dimensionless quantity is put in the front to increase the readability. + * + * For example: + * + * @code{.cpp} + * inline constexpr struct frequency_dim : decltype(1 / time_dim) {} frequency_dim; + * inline constexpr struct speed_dim : decltype(length_dim / time_dim) {} speed_dim; + * inline constexpr struct acceleration_dim : decltype(speed_dim / time_dim) {} acceleration_dim; + * inline constexpr struct force_dim : decltype(mass_dim * acceleration_dim) {} force_dim; + * inline constexpr struct energy_dim : decltype(force_dim * length_dim) {} energy_dim; + * inline constexpr struct moment_of_force_dim : decltype(length_dim * force_dim) {} moment_of_force_dim; + * inline constexpr struct torque_dim : decltype(moment_of_force_dim) {} torque_dim; + * @endcode + * + * - `frequency_dim` will be derived from type `derived_dimension>` + * - `speed_dim` will be derived from type `derived_dimension>` + * - `acceleration_dim` will be derived from type `derived_dimension>>` + * - `force_dim` will be derived from type `derived_dimension>>` + * - `energy_dim` will be derived from type `derived_dimension, mass_dim, per>>` + * + * @note A common convention in this library is to assign the same name for a type and an object of this type. + * Besides defining them user never works with the dimension types in the source code. All operations + * are done on the objects. Contrarily, the dimension types are the only one visible in the compilation + * errors. Having them of the same names improves user experience and somehow blurs those separate domains. + * + * Two dimensions are deemed equal when they are of the same type. With that strong type `speed_dim` and + * `derived_dimension>` are considered not equal. They are convertible though. + * User can implicitly convert up and down the inheritance hierarchy between those two. + * `torque_dim` and `moment_of_force_dim` are convertible as well. However, `energy_dim` and `torque_dim` + * are not convertible as they do not inherit from each other. They are from two separate branches of + * dimensionally equivalent quantities. + * + * @tparam Ds a parameter pack consisting tokens allowed in the dimension specification + * (base dimensions, `one_dim`, `power`, `per<...>`) + * + * @note User should not instantiate this type! It is not exported from the C++ module. The library will + * instantiate this type automatically based on the dimensional arithmetic equation provided by the user. + */ template struct derived_dimension : detail::derived_dimension_impl {}; @@ -205,6 +267,9 @@ template return detail::expr_invert, struct one_dim, derived_dimension>(); } +template +[[nodiscard]] consteval Dimension auto operator/(D, int) = delete; + template [[nodiscard]] consteval bool operator==(D1, D2) { @@ -223,6 +288,12 @@ template namespace std { +/** + * @brief Partial specialization of `std::common_type` for dimensions + * + * Defined only for convertible types and returns the most derived/specific dimension type of + * the two provided. + */ template requires(units::convertible(D1{}, D2{})) struct common_type { diff --git a/test/unit_test/static/dimension_test.cpp b/test/unit_test/static/dimension_test.cpp index c933488d..b8e54c6f 100644 --- a/test/unit_test/static/dimension_test.cpp +++ b/test/unit_test/static/dimension_test.cpp @@ -165,6 +165,14 @@ static_assert(convertible(speed_dim, velocity_dim)); static_assert(std::is_same_v, velocity_dim_>); static_assert(std::is_same_v, velocity_dim_>); +// comparison of convertible unnamed dimensions +static_assert( + is_of_type>>>); +static_assert( + is_of_type>>>); +static_assert(mass_dim * acceleration_dim == acceleration_dim * mass_dim); +static_assert(convertible(mass_dim * acceleration_dim, acceleration_dim* mass_dim)); + // comparisons of equivalent but not convertible dimensions static_assert(energy_dim != torque_dim); static_assert(!convertible(energy_dim, torque_dim)); From f156bc4c71e92670c02b9e161025ab41b552b617 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Wed, 19 Oct 2022 12:23:04 +0200 Subject: [PATCH 029/402] test: `type_list` unit tests added --- .../include/units/bits/external/type_list.h | 13 +-- test/unit_test/static/CMakeLists.txt | 4 +- test/unit_test/static/type_list_test.cpp | 88 ++++++++++++++----- 3 files changed, 77 insertions(+), 28 deletions(-) diff --git a/src/core/include/units/bits/external/type_list.h b/src/core/include/units/bits/external/type_list.h index 3eddfcfe..88f52a87 100644 --- a/src/core/include/units/bits/external/type_list.h +++ b/src/core/include/units/bits/external/type_list.h @@ -24,6 +24,7 @@ #include // IWYU pragma: keep #include +#include UNITS_DIAGNOSTIC_PUSH UNITS_DIAGNOSTIC_IGNORE_EXPR_ALWAYS_TF @@ -47,16 +48,16 @@ concept TypeList = detail::is_type_list; namespace detail { -template typename List, typename... Ts> -consteval std::size_t type_list_size_impl(List) -{ - return sizeof...(Ts); -} +template +struct type_list_size_impl; + +template typename List, typename... Types> +struct type_list_size_impl> : std::integral_constant {}; } // namespace detail template -inline constexpr std::size_t type_list_size = detail::type_list_size_impl(List{}); +inline constexpr std::size_t type_list_size = detail::type_list_size_impl::value; // front diff --git a/test/unit_test/static/CMakeLists.txt b/test/unit_test/static/CMakeLists.txt index 5d48f53d..587f824d 100644 --- a/test/unit_test/static/CMakeLists.txt +++ b/test/unit_test/static/CMakeLists.txt @@ -53,14 +53,14 @@ add_library( # math_test.cpp # point_origin_test.cpp # prime_test.cpp - # ratio_test.cpp + ratio_test.cpp # references_test.cpp # si_test.cpp # si_cgs_test.cpp # si_fps_test.cpp # si_hep_test.cpp # symbol_text_test.cpp - # type_list_test.cpp + type_list_test.cpp unit_test.cpp # us_test.cpp diff --git a/test/unit_test/static/type_list_test.cpp b/test/unit_test/static/type_list_test.cpp index 81f39586..81742907 100644 --- a/test/unit_test/static/type_list_test.cpp +++ b/test/unit_test/static/type_list_test.cpp @@ -20,10 +20,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -#include #include -#include -#include +#include namespace { @@ -32,6 +30,29 @@ using namespace units; template struct type_list; +// TypeList + +static_assert(TypeList>); +static_assert(TypeList>); +static_assert(TypeList>); + +// type_list_size + +static_assert(type_list_size> == 0); +static_assert(type_list_size> == 1); +static_assert(type_list_size> == 2); +static_assert(type_list_size> == 3); + +// type_list_front + +template typename List> +concept type_list_front_invalid_for_empty_list = !requires { typename type_list_front>; }; + +static_assert(type_list_front_invalid_for_empty_list); +static_assert(is_same_v>, int>); +static_assert(is_same_v>, long>); +static_assert(is_same_v>, float>); + // type_list_push_front static_assert(is_same_v, int>, type_list>); @@ -55,6 +76,15 @@ static_assert( static_assert(is_same_v, type_list, type_list>, type_list>); +// type_list_join +static_assert(is_same_v, type_list<>>, type_list<>>); +static_assert(is_same_v, type_list<>>, type_list>); +static_assert(is_same_v, type_list>, type_list>); +static_assert(is_same_v, type_list>, type_list>); +static_assert(is_same_v, type_list>, type_list>); +static_assert( + is_same_v, type_list>, type_list>); + // type_list_split static_assert(is_same_v, 0>::first_list, type_list<>>); @@ -93,28 +123,46 @@ static_assert(is_same_v static_assert( is_same_v>::second_list, type_list>); -// type_list_merge_sorted -struct u0 : named_unit {}; -struct d0 : base_dimension<"d0", u0> {}; -struct u1 : named_unit {}; -struct d1 : base_dimension<"d1", u1> {}; +template +struct constant { + static constexpr auto value = V; +}; +struct v1 : constant<1> {}; +struct v2 : constant<2> {}; +struct v3 : constant<3> {}; +struct v4 : constant<4> {}; + +template +struct constant_less : std::bool_constant<(T1::value < T2::value)> {}; + +// type_list_merge_sorted + +static_assert(is_same_v, type_list<>, constant_less>, type_list<>>); +static_assert(is_same_v, type_list<>, constant_less>, type_list>); +static_assert(is_same_v, type_list, constant_less>, type_list>); +static_assert(is_same_v, type_list, constant_less>, type_list>); static_assert( - is_same_v>, type_list>, exponent_less>, - type_list, units::exponent>>); -static_assert( - is_same_v>, type_list>, exponent_less>, - type_list, units::exponent>>); + is_same_v, type_list, constant_less>, type_list>); +static_assert(is_same_v, type_list, constant_less>, + type_list>); // type_list_sort -template -using exp_sort = type_list_sort; +static_assert(is_same_v, constant_less>, type_list<>>); +static_assert(is_same_v, constant_less>, type_list>); +static_assert(is_same_v, constant_less>, type_list>); +static_assert(is_same_v, constant_less>, type_list>); +static_assert(is_same_v, constant_less>, type_list>); +static_assert(is_same_v, constant_less>, type_list>); -static_assert(is_same_v>>, exponent_list>>); -static_assert(is_same_v, units::exponent>>, - exponent_list, units::exponent>>); -static_assert(is_same_v, units::exponent>>, - exponent_list, units::exponent>>); +// type_list_map + +template +struct other_list; + +static_assert(is_same_v, other_list>, other_list<>>); +static_assert(is_same_v, other_list>, other_list>); +static_assert(is_same_v, other_list>, other_list>); } // namespace From ec1dace1f9b69911a7515d90ba5d269aa49f14c9 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Wed, 19 Oct 2022 13:15:02 +0200 Subject: [PATCH 030/402] feat: `PrefixableUnit` concept introduced --- example/v2_framework.cpp | 18 ++--- src/core/include/units/unit.h | 6 +- src/systems/si/include/units/si/prefixes.h | 80 +++++++++++----------- 3 files changed, 53 insertions(+), 51 deletions(-) diff --git a/example/v2_framework.cpp b/example/v2_framework.cpp index 34c0a3c8..abc075cd 100644 --- a/example/v2_framework.cpp +++ b/example/v2_framework.cpp @@ -34,16 +34,16 @@ inline constexpr struct activity : system_reference // check for invalid prefixes -template -concept can_not_be_prefixed = !requires { typename si::milli_; }; +template typename prefix, Unit auto V1> +concept can_not_be_prefixed = !requires { typename prefix; }; -static_assert(can_not_be_prefixed); -static_assert(can_not_be_prefixed); -static_assert(can_not_be_prefixed); -static_assert(can_not_be_prefixed); -static_assert(can_not_be_prefixed); -static_assert(can_not_be_prefixed); -static_assert(can_not_be_prefixed); +static_assert(can_not_be_prefixed); +static_assert(can_not_be_prefixed); +static_assert(can_not_be_prefixed); +static_assert(can_not_be_prefixed); +static_assert(can_not_be_prefixed); +static_assert(can_not_be_prefixed); +static_assert(can_not_be_prefixed); // Named quantity/dimension and unit static_assert( diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index 12e499d1..4dd877fb 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -92,6 +92,9 @@ concept NamedUnit = Unit && requires(T* t) { detail::to_base_specialization_o template inline constexpr bool unit_can_be_prefixed = NamedUnit>; +template +concept PrefixableUnit = NamedUnit && unit_can_be_prefixed; + /** * @brief A prefixed unit * @@ -103,8 +106,7 @@ inline constexpr bool unit_can_be_prefixed = NamedUnit - requires unit_can_be_prefixed +template struct prefixed_unit : std::remove_const_t { static constexpr auto symbol = Symbol + U.symbol; }; diff --git a/src/systems/si/include/units/si/prefixes.h b/src/systems/si/include/units/si/prefixes.h index f90bdbde..eba32a3c 100644 --- a/src/systems/si/include/units/si/prefixes.h +++ b/src/systems/si/include/units/si/prefixes.h @@ -26,86 +26,86 @@ namespace units::si { -template +template struct yocto_ : prefixed_unit<"y", mag_power<10, -24>, U> {}; -template +template struct zepto_ : prefixed_unit<"z", mag_power<10, -21>, U> {}; -template +template struct atto_ : prefixed_unit<"a", mag_power<10, -18>, U> {}; -template +template struct femto_ : prefixed_unit<"f", mag_power<10, -15>, U> {}; -template +template struct pico_ : prefixed_unit<"p", mag_power<10, -12>, U> {}; -template +template struct nano_ : prefixed_unit<"n", mag_power<10, -9>, U> {}; -template +template struct micro_ : prefixed_unit, U> {}; -template +template struct milli_ : prefixed_unit<"m", mag_power<10, -3>, U> {}; -template +template struct centi_ : prefixed_unit<"c", mag_power<10, -2>, U> {}; -template +template struct deci_ : prefixed_unit<"d", mag_power<10, -1>, U> {}; -template +template struct deca_ : prefixed_unit<"da", mag_power<10, 1>, U> {}; -template +template struct hecto_ : prefixed_unit<"h", mag_power<10, 2>, U> {}; -template +template struct kilo_ : prefixed_unit<"k", mag_power<10, 3>, U> {}; -template +template struct mega_ : prefixed_unit<"M", mag_power<10, 6>, U> {}; -template +template struct giga_ : prefixed_unit<"G", mag_power<10, 9>, U> {}; -template +template struct tera_ : prefixed_unit<"T", mag_power<10, 12>, U> {}; -template +template struct peta_ : prefixed_unit<"P", mag_power<10, 15>, U> {}; -template +template struct exa_ : prefixed_unit<"E", mag_power<10, 18>, U> {}; -template +template struct zetta_ : prefixed_unit<"Z", mag_power<10, 21>, U> {}; -template +template struct yotta_ : prefixed_unit<"Y", mag_power<10, 24>, U> {}; -template +template inline constexpr yocto_ yocto; -template +template inline constexpr zepto_ zepto; -template +template inline constexpr atto_ atto; -template +template inline constexpr femto_ femto; -template +template inline constexpr pico_ pico; -template +template inline constexpr nano_ nano; -template +template inline constexpr micro_ micro; -template +template inline constexpr milli_ milli; -template +template inline constexpr centi_ centi; -template +template inline constexpr deci_ deci; -template +template inline constexpr deca_ deca; -template +template inline constexpr hecto_ hecto; -template +template inline constexpr kilo_ kilo; -template +template inline constexpr mega_ mega; -template +template inline constexpr giga_ giga; -template +template inline constexpr tera_ tera; -template +template inline constexpr peta_ peta; -template +template inline constexpr exa_ exa; -template +template inline constexpr zetta_ zetta; -template +template inline constexpr yotta_ yotta; } // namespace units::si From 8793aeec23f69bbc7594f13d848ec873c5c24455 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Wed, 19 Oct 2022 13:16:10 +0200 Subject: [PATCH 031/402] feat: convertibility check added for the target unit in the `system_reference` --- src/core/include/units/reference.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/include/units/reference.h b/src/core/include/units/reference.h index 992a4df7..eaa8c65b 100644 --- a/src/core/include/units/reference.h +++ b/src/core/include/units/reference.h @@ -155,8 +155,7 @@ struct system_reference { static constexpr auto coherent_unit = CoU; template - // TODO enable that - // requires(convertible(coherent_unit, U{})) + requires(convertible(coherent_unit, U{})) [[nodiscard]] constexpr reference, U> operator[](U) const { return {}; From 5975e4c1cc3ce6da21c47aa051e61a21c64bb5fd Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Wed, 19 Oct 2022 13:16:59 +0200 Subject: [PATCH 032/402] refactor: `named_unit` should inherit from `U` to for a correct inheritance hierarchy --- src/core/include/units/unit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index 4dd877fb..68b465a5 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -75,7 +75,7 @@ struct named_unit { }; template -struct named_unit { +struct named_unit : std::remove_const_t { static constexpr auto symbol = Symbol; }; From 8246b06b4a660a5f68cb658afabb5fd2fb71b6c1 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Wed, 19 Oct 2022 19:39:18 +0200 Subject: [PATCH 033/402] feat: `type_list_element`, `type_list_back` added; `type_list_split` refactored --- .../include/units/bits/external/type_list.h | 119 +++++++++++------- test/unit_test/static/type_list_test.cpp | 36 ++++-- 2 files changed, 99 insertions(+), 56 deletions(-) diff --git a/src/core/include/units/bits/external/type_list.h b/src/core/include/units/bits/external/type_list.h index 88f52a87..ac99b80a 100644 --- a/src/core/include/units/bits/external/type_list.h +++ b/src/core/include/units/bits/external/type_list.h @@ -59,6 +59,55 @@ struct type_list_size_impl> : std::integral_constant inline constexpr std::size_t type_list_size = detail::type_list_size_impl::value; + +// map + +namespace detail { + +template typename To> +struct type_list_map_impl; + +template typename From, template typename To, typename... Args> +struct type_list_map_impl, To> { + using type = To; +}; + +} // namespace detail + +template typename To> +using type_list_map = TYPENAME detail::type_list_map_impl::type; + + +// element + +namespace detail { + +template +struct type_list_leaf { + using type = T; +}; + +template +struct indexed_type_list_impl; + +template +struct indexed_type_list_impl, Ts...> : type_list_leaf... {}; + +template +std::type_identity type_list_element_func(const type_list_leaf&); + +} // namespace detail + +template +struct indexed_type_list : detail::indexed_type_list_impl, Ts...> {}; + +template +using type_list_element_indexed = typename decltype(detail::type_list_element_func(std::declval()))::type; + +template +using type_list_element = type_list_element_indexed, I>; + + // front namespace detail { @@ -76,6 +125,13 @@ struct type_list_front_impl> { template using type_list_front = TYPENAME detail::type_list_front_impl::type; + +// back + +template +using type_list_back = type_list_element - 1>; + + // push_front namespace detail { @@ -93,6 +149,7 @@ struct type_list_push_front_impl, NewTypes...> { template using type_list_push_front = TYPENAME detail::type_list_push_front_impl::type; + // push_back namespace detail { @@ -110,6 +167,7 @@ struct type_list_push_back_impl, NewTypes...> { template using type_list_push_back = TYPENAME detail::type_list_push_back_impl::type; + // join namespace detail { @@ -129,46 +187,29 @@ struct type_list_join_impl, List, Rest...> { template using type_list_join = TYPENAME detail::type_list_join_impl::type; + // split namespace detail { -template typename List, std::size_t Idx, std::size_t N, typename... Types> -struct split_impl; +template +struct type_list_split_impl; -template typename List, std::size_t Idx, std::size_t N> -struct split_impl { - using first_list = List<>; - using second_list = List<>; -}; - -template typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest> - requires(Idx < N) -struct split_impl : split_impl { - using base = split_impl; - using first_list = TYPENAME type_list_push_front_impl::type; - using second_list = TYPENAME base::second_list; -}; - -template typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest> -struct split_impl : split_impl { - using base = split_impl; - using first_list = TYPENAME base::first_list; - using second_list = TYPENAME type_list_push_front_impl::type; +template typename List, typename... Args, std::size_t... First, std::size_t... Second> +struct type_list_split_impl, std::index_sequence, std::index_sequence> { + using indexed_list = indexed_type_list; + using first_list = List...>; + using second_list = List...>; }; } // namespace detail template -struct type_list_split; + requires(N <= type_list_size) +struct type_list_split : + detail::type_list_split_impl, + std::make_index_sequence - N>> {}; -template typename List, std::size_t N, typename... Types> -struct type_list_split, N> { - static_assert(N <= sizeof...(Types), "Invalid index provided"); - using split = detail::split_impl; - using first_list = TYPENAME split::first_list; - using second_list = TYPENAME split::second_list; -}; // split_half @@ -178,6 +219,7 @@ struct type_list_split_half; template typename List, typename... Types> struct type_list_split_half> : type_list_split, (sizeof...(Types) + 1) / 2> {}; + // merge_sorted namespace detail { @@ -200,7 +242,6 @@ struct type_list_merge_sorted_impl, List, Pred> { using type = List; }; - template typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest, template typename Pred> requires Pred::value @@ -221,6 +262,7 @@ struct type_list_merge_sorted_impl, List typename Pred> using type_list_merge_sorted = TYPENAME detail::type_list_merge_sorted_impl::type; + // sort namespace detail { @@ -252,23 +294,6 @@ struct type_list_sort_impl, Pred> { template typename Pred> using type_list_sort = TYPENAME detail::type_list_sort_impl::type; -// map - -namespace detail { - -template typename To> -struct type_list_map_impl; - -template typename From, template typename To, typename... Args> -struct type_list_map_impl, To> { - using type = To; -}; - -} // namespace detail - -template typename To> -using type_list_map = TYPENAME detail::type_list_map_impl::type; - } // namespace units UNITS_DIAGNOSTIC_POP diff --git a/test/unit_test/static/type_list_test.cpp b/test/unit_test/static/type_list_test.cpp index 81742907..9ab7bba4 100644 --- a/test/unit_test/static/type_list_test.cpp +++ b/test/unit_test/static/type_list_test.cpp @@ -43,6 +43,23 @@ static_assert(type_list_size> == 1); static_assert(type_list_size> == 2); static_assert(type_list_size> == 3); +// type_list_map + +template +struct other_list; + +static_assert(is_same_v, other_list>, other_list<>>); +static_assert(is_same_v, other_list>, other_list>); +static_assert(is_same_v, other_list>, other_list>); + +// type_list_element + +static_assert(is_same_v, 0>, int>); +static_assert(is_same_v, 0>, int>); +static_assert(is_same_v, 1>, double>); +static_assert(is_same_v, 2>, float>); +static_assert(is_same_v, 3>, long>); + // type_list_front template typename List> @@ -53,6 +70,16 @@ static_assert(is_same_v>, int>); static_assert(is_same_v>, long>); static_assert(is_same_v>, float>); +// type_list_back + +template typename List> +concept type_list_back_invalid_for_empty_list = !requires { typename type_list_back>; }; + +static_assert(type_list_back_invalid_for_empty_list); +static_assert(is_same_v>, int>); +static_assert(is_same_v>, long>); +static_assert(is_same_v>, float>); + // type_list_push_front static_assert(is_same_v, int>, type_list>); @@ -156,13 +183,4 @@ static_assert(is_same_v, constant_less>, type_l static_assert(is_same_v, constant_less>, type_list>); static_assert(is_same_v, constant_less>, type_list>); -// type_list_map - -template -struct other_list; - -static_assert(is_same_v, other_list>, other_list<>>); -static_assert(is_same_v, other_list>, other_list>); -static_assert(is_same_v, other_list>, other_list>); - } // namespace From aa33964782ae2a7e60649afea4ffdec24605eee6 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Wed, 19 Oct 2022 19:56:35 +0200 Subject: [PATCH 034/402] refactor: expression templates engine refactored --- .../include/units/bits/expression_template.h | 259 ++++++++++-------- 1 file changed, 146 insertions(+), 113 deletions(-) diff --git a/src/core/include/units/bits/expression_template.h b/src/core/include/units/bits/expression_template.h index 3d387efa..e7ead18e 100644 --- a/src/core/include/units/bits/expression_template.h +++ b/src/core/include/units/bits/expression_template.h @@ -28,14 +28,30 @@ namespace units { +/** + * @brief Type list type used by the expression template framework + * + * @tparam Ts The list of types + */ template struct type_list {}; +/** + * @brief Type list type storing the list of components with negative exponents + * + * @note Can't be empty + */ template struct per {}; namespace detail { +template +inline constexpr bool is_specialization_of_per = false; + +template +inline constexpr bool is_specialization_of_per> = true; + template inline constexpr bool valid_ratio = true; @@ -65,6 +81,19 @@ inline constexpr bool ratio_one = true; } // namespace detail + +/** + * @brief Type container for exponents with ratio different than `1` + * + * Ratio must be mathematically valid and non-negative. Negative exponents are passed to + * `per<...>` with inverted sign (as positive exponents). + * + * @tparam F factor to be raised to specified power + * @tparam Num Power ratio numerator + * @tparam Den [optional] Power ration denominator + * + * @note @p Den is an optional parameter to shorten the types presented to the user in the case when @p Den equals `1`. + */ template requires(detail::valid_ratio && detail::positive_ratio && !detail::ratio_one) struct power { @@ -80,12 +109,7 @@ inline constexpr bool is_specialization_of_power = false; template inline constexpr bool is_specialization_of_power> = true; -} // namespace detail - -namespace detail { - -template -// template // TODO +template consteval auto power_or_T_impl() { if constexpr (R.den == 1) { @@ -99,42 +123,15 @@ consteval auto power_or_T_impl() }; template -// template // TODO +// template // TODO ICE gcc 12 using power_or_T = decltype(power_or_T_impl()); -// type_power -// template -// struct type_power { -// using type = conditional, power>; -// }; - -// template -// struct type_power, Num, 1> { -// using type = power; -// }; - -// template -// struct type_power, Num, Den> { -// static constexpr ratio r = ratio(power::num, power::den) * ratio(Num, Den); -// using type = power_or_T; -// }; - -// expr_power -// template -// struct expr_power; - -// template -// struct expr_power, Num, Den> { -// using type = type_list::type...>; -// }; /** - * @brief Consolidates contiguous ranges of exponents of the same dimension + * @brief Consolidates contiguous ranges of exponents of the same type * - * If there is more than one exponent with the same dimension they are aggregated into one exponent by adding - * their exponents. If this accumulation will result with 0, such a dimension is removed from the list. - * - * @tparam D derived dimension to consolidate + * If there is more than one exponent with the same type they are aggregated into one type by adding + * their powers. */ template struct expr_consolidate_impl; @@ -154,29 +151,65 @@ struct expr_consolidate_impl> { using type = type_list_push_front>::type, T>; }; +// replaces two instances of a type with one having the power of `2` template requires(!is_specialization_of_power) struct expr_consolidate_impl> { using type = expr_consolidate_impl, Rest...>>::type; }; +// replaces the instance of a type and a power of it with one with incremented power template struct expr_consolidate_impl, Rest...>> { using type = expr_consolidate_impl::exponent + 1>, Rest...>>::type; }; +// accumulates the powers of instances of the same type (removes the element in case the accumulation result is `0`) template struct expr_consolidate_impl, power, Rest...>> { static constexpr ratio r = power::exponent + power::exponent; - using type = conditional>::type, - typename expr_consolidate_impl, Rest...>>::type>; + using type = typename expr_consolidate_impl, Rest...>>::type; }; template using expr_consolidate = typename expr_consolidate_impl::type; -// expr_simplify +/** + * @brief Simplifies the expression template + * + * Analyzes provided numerator and denominator type lists and simplifies elements with the same type. + * If the same power exists in both list, this elements gets omitted. Otherwise, the power of its + * exponent gets subtracted according to numerator and denominator elements powers. + * + * @tparam NumList type list for expression numerator + * @tparam DenList type list for expression denominator + * @tparam Pred predicate to be used for elements comparisons + */ +template typename Pred> +struct expr_simplify; + +// when one of the lists is empty there is nothing to do +template typename Pred> + requires(type_list_size == 0) || (type_list_size == 0) +struct expr_simplify { + using num = NumList; + using den = DenList; +}; + +// in case when front elements are different progress to the next element +template typename Pred> +struct expr_simplify, type_list, Pred> { + using impl = conditional::value, expr_simplify, type_list, Pred>, + expr_simplify, type_list, Pred>>; + using num = conditional::value, type_list_push_front, typename impl::num>; + using den = conditional::value, typename impl::den, type_list_push_front>; +}; + +// in case two elements are of the same power such element gets omitted +template typename Pred> +struct expr_simplify, type_list, Pred> : + expr_simplify, type_list, Pred> {}; template struct expr_simplify_power { @@ -186,28 +219,7 @@ struct expr_simplify_power { using den = conditional<(r < 0), type_list, type_list<>>; }; -template typename Pred> -struct expr_simplify; - -template typename Pred> - requires(type_list_size == 0) || (type_list_size == 0) -struct expr_simplify { - using num = NumList; - using den = DenList; -}; - -template typename Pred> -struct expr_simplify, type_list, Pred> { - using impl = conditional::value, expr_simplify, type_list, Pred>, - expr_simplify, type_list, Pred>>; - using num = conditional::value, type_list_push_front, typename impl::num>; - using den = conditional::value, typename impl::den, type_list_push_front>; -}; - -template typename Pred> -struct expr_simplify, type_list, Pred> : - expr_simplify, type_list, Pred> {}; - +// in case there are different powers for the same element simplify the power template typename Pred> struct expr_simplify, NRest...>, type_list, Pred> { using impl = expr_simplify, type_list, Pred>; @@ -216,6 +228,7 @@ struct expr_simplify, NRest...>, type_list; }; +// in case there are different powers for the same element simplify the power template typename Pred> struct expr_simplify, type_list, DRest...>, Pred> { using impl = expr_simplify, type_list, Pred>; @@ -224,6 +237,7 @@ struct expr_simplify, type_list, DRest. using den = type_list_join; }; +// in case there are different powers for the same element simplify the power template typename Pred> requires(!std::same_as, power>) @@ -251,61 +265,57 @@ struct expr_less_impl, Pred> : Pred {}; template typename Pred> struct expr_less_impl, Pred> : std::true_type {}; +/** + * @brief Compares two types with a given predicate + * + * Algorithm accounts not only for explicit types but also for the case when they + * are wrapped within `power`. + */ template typename Pred> using expr_less = expr_less_impl; // expr_fractions -template -struct expr_fractions_impl; - -template -struct expr_fractions_impl { - using den = type_list<>; +template, typename Den = type_list<>> +struct expr_fractions_result { + using _num_ = Num; // exposition only + using _den_ = Den; // exposition only }; -template -struct expr_fractions_impl { - using den = type_list_push_front::den, T>; -}; +template +[[nodiscard]] consteval auto expr_fractions_impl() +{ + constexpr std::size_t size = type_list_size; -template T, typename... Rest> -struct expr_fractions_impl : - TYPENAME expr_fractions_impl::den {}; + if constexpr (size == 0) + return expr_fractions_result<>{}; + else if constexpr (size == 1) + return expr_fractions_result{}; + else { + using last_element = type_list_back; -template -struct expr_fractions_impl { - using num = type_list<>; - using den = type_list<>; -}; - -template -struct expr_fractions_impl> { - using num = type_list<>; - using den = TYPENAME expr_fractions_impl::den; -}; - -template T, typename... Rest> -struct expr_fractions_impl : expr_fractions_impl {}; - -template -struct expr_fractions_impl { - using impl = expr_fractions_impl; - using num = type_list_push_front; - using den = TYPENAME impl::den; -}; + if constexpr (is_specialization_of_per) { + if constexpr (size == 2 && std::derived_from, OneTypeBase>) + return expr_fractions_result, type_list_map>{}; + else { + using split = type_list_split; + return expr_fractions_result>{}; + } + } else { + return expr_fractions_result{}; + } + } +} +/** + * @brief Divides expression template spec to numerator and denominator parts + */ template -struct expr_fractions { -private: - using impl = expr_fractions_impl; -public: - using _num_ = TYPENAME impl::num; // exposition only - using _den_ = TYPENAME impl::den; // exposition only -}; +struct expr_fractions : decltype(expr_fractions_impl>()) {}; +// expr_make_spec template typename To> -[[nodiscard]] consteval auto expr_expression_impl() +[[nodiscard]] consteval auto expr_make_spec_impl() { constexpr std::size_t num = type_list_size; constexpr std::size_t den = type_list_size; @@ -325,8 +335,11 @@ template typename To> -using expr_expression = decltype(expr_expression_impl()); +using expr_make_spec = decltype(expr_make_spec_impl()); template typename Pred, template typename To> @@ -335,18 +348,18 @@ template; using den_list = expr_consolidate; using simple = expr_simplify; - using expr = expr_expression; + using expr = expr_make_spec; return expr{}; } /** - * @brief Merges 2 sorted derived dimensions into one units::normalized_dimension + * @brief Multiplies two sorted expression template specs * - * A result of a dimensional calculation may result with many exponents of the same base dimension originated - * from different parts of the equation. As the exponents lists of both operands it is enough to merge them - * into one list and consolidate duplicates. Also it is possible that final exponents list will contain only - * one element being a base dimension with exponent 1. In such a case the final dimension should be the base - * dimension itself. + * @tparam T1 lhs of the operation + * @tparam T2 rhs of the operation + * @tparam OneType type that represents the value `1` + * @tparam Pred binary less then predicate + * @tparam To destination type list to put the result to */ template typename Pred, template typename To> @@ -357,6 +370,7 @@ template) { return T1{}; } else if constexpr (is_specialization_of && is_specialization_of) { + // two derived dimensions return get_optimized_expression, type_list_merge_sorted, OneType, Pred, To>(); @@ -367,11 +381,21 @@ template, Pred>, typename T2::_den_, OneType, Pred, To>(); } else { + // two base dimensions return get_optimized_expression, type_list, Pred>, type_list<>, OneType, Pred, To>(); } } +/** + * @brief Divides two sorted expression template specs + * + * @tparam T1 lhs of the operation + * @tparam T2 rhs of the operation + * @tparam OneType type that represents the value `1` + * @tparam Pred binary less then predicate + * @tparam To destination type list to put the result to + */ template typename Pred, template typename To> [[nodiscard]] consteval auto expr_divide() @@ -381,6 +405,7 @@ template) { return T1{}; } else if constexpr (is_specialization_of && is_specialization_of) { + // two derived dimensions return get_optimized_expression, type_list_merge_sorted, OneType, Pred, To>(); @@ -391,15 +416,23 @@ template, Pred>, typename T2::_num_, OneType, Pred, To>(); } else { + // two base dimensions return To>{}; } } +/** + * @brief Inverts the expression template spec + * + * @tparam T expression template spec to invert + * @tparam OneType type that represents the value `1` + * @tparam To destination type list to put the result to + */ template typename To> [[nodiscard]] consteval auto expr_invert() { if constexpr (is_specialization_of) - return expr_expression{}; + return expr_make_spec{}; else return To>{}; } From c3c087925754a648c06bc87f50600da18ad680be Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Wed, 19 Oct 2022 20:44:12 +0200 Subject: [PATCH 035/402] refactor: `DimensionSpec` concept renamed to `DerivedDimensionSpec` --- src/core/include/units/dimension.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/include/units/dimension.h b/src/core/include/units/dimension.h index b81dfb56..ada246dc 100644 --- a/src/core/include/units/dimension.h +++ b/src/core/include/units/dimension.h @@ -134,10 +134,10 @@ inline constexpr bool is_per_of_dims> = } // namespace detail template -concept DimensionSpec = +concept DerivedDimensionSpec = BaseDimension || detail::is_one_dim || detail::is_power_of_dim || detail::is_per_of_dims; -template +template struct derived_dimension; namespace detail { @@ -199,7 +199,7 @@ struct derived_dimension_impl : detail::expr_fractions, Ds.. * @note User should not instantiate this type! It is not exported from the C++ module. The library will * instantiate this type automatically based on the dimensional arithmetic equation provided by the user. */ -template +template struct derived_dimension : detail::derived_dimension_impl {}; namespace detail { From 0b9b159695ff24bafddd2eb06ea9fc2207cff6dc Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 20 Oct 2022 14:03:15 +0200 Subject: [PATCH 036/402] fix: units design refactored and fixed --- src/core/include/units/dimension.h | 3 + src/core/include/units/unit.h | 279 +++++++++++++++++++++------- test/unit_test/static/unit_test.cpp | 209 ++++++++------------- 3 files changed, 292 insertions(+), 199 deletions(-) diff --git a/src/core/include/units/dimension.h b/src/core/include/units/dimension.h index ada246dc..9e17d108 100644 --- a/src/core/include/units/dimension.h +++ b/src/core/include/units/dimension.h @@ -246,6 +246,9 @@ using dim_type = dim_type_impl::type; } // namespace detail + +// Operators + template [[nodiscard]] consteval Dimension auto operator*(D1, D2) { diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index 68b465a5..5eff0503 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -43,40 +43,94 @@ namespace detail { template inline constexpr bool is_unit = false; -} +} // namespace detail /** * @brief A concept matching all unit types in the library * - * Satisfied by all unit types derived from an specialization of :class:`scaled_unit`. + * Satisfied by all unit types provided by the library. */ template concept Unit = detail::is_unit; -// User should not instantiate this type!!! -// It should not be exported from the module + +/** + * @brief Unit being a scaled version of another unit + * + * @tparam M magnitude describing the scale factor + * @tparam U reference unit being scaled + * + * @note User should not instantiate this type! It is not exported from the C++ module. The library will + * instantiate this type automatically based on the unit arithmetic equation provided by the user. + */ template -struct scaled_unit {}; +struct scaled_unit { + static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag = M; + static constexpr U reference_unit{}; +}; + +namespace detail { + +template +inline constexpr bool is_specialization_of_scaled_unit = false; + +template +inline constexpr bool is_specialization_of_scaled_unit> = true; + +} // namespace detail /** * @brief A named unit * - * Defines a named (in most cases coherent) unit that is then passed to a dimension definition. - * A named unit may be composed with a prefix to create a prefixed_unit. + * Defines a unit with a special name. + * Most of the named units may be composed with a prefix to create a `prefixed_unit`. + * + * For example: + * + * @code{.cpp} + * inline constexpr struct second : named_unit<"s"> {} second; + * inline constexpr struct metre : named_unit<"m"> {} metre; + * inline constexpr struct hertz : named_unit<"Hz", 1 / second> {} hertz; + * inline constexpr struct newton : named_unit<"N", kilogram * metre / square> {} newton; + * inline constexpr struct degree_Celsius : named_unit {} degree_Celsius; + * inline constexpr struct minute : named_unit<"min", mag<60> * second> {} minute; + * @endcode + * + * @note A common convention in this library is to assign the same name for a type and an object of this type. + * Besides defining them user never works with the unit types in the source code. All operations + * are done on the objects. Contrarily, the unit types are the only one visible in the compilation + * errors. Having them of the same names improves user experience and somehow blurs those separate domains. * * @tparam Symbol a short text representation of the unit */ template struct named_unit; +/** + * @brief Specialization for base unit + * + * Defines a base unit in the system of units (i.e. `metre`). + * or a name assigned to another scaled or derived unit (i.e. `hour`, `joule`). + * Most of the named units may be composed with a prefix to create a `prefixed_unit`. + * + * @tparam Symbol a short text representation of the unit + */ template struct named_unit { - static constexpr auto symbol = Symbol; + static constexpr auto symbol = Symbol; ///< Unique base unit identifier }; +/** + * @brief Specialization for a unit with special name + * + * Allows assigning a special name to another scaled or derived unit (i.e. `hour`, `joule`). + * + * @tparam Symbol a short text representation of the unit + * @tparam Unit a unit for which we provide a special name + */ template struct named_unit : std::remove_const_t { - static constexpr auto symbol = Symbol; + static constexpr auto symbol = Symbol; ///< Unique unit identifier }; namespace detail { @@ -84,27 +138,62 @@ namespace detail { template void to_base_specialization_of_named_unit(const volatile named_unit*); +template +inline constexpr bool is_specialization_of_named_unit = false; + +template +inline constexpr bool is_specialization_of_named_unit> = true; + } // namespace detail +/** + * @brief A concept matching all units with special names + * + * Satisfied by all unit types derived from the specialization of `named_unit`. + */ template -concept NamedUnit = Unit && requires(T* t) { detail::to_base_specialization_of_named_unit(t); }; +concept NamedUnit = Unit && requires(T* t) { detail::to_base_specialization_of_named_unit(t); } && + (!detail::is_specialization_of_named_unit); -template -inline constexpr bool unit_can_be_prefixed = NamedUnit>; +/** + * @brief Prevents assignment of a prefix to specific units + * + * By default all named units allow assigning a prefix for them. There are some notable exceptions like + * `hour` or `degree_Celsius`. For those a partial specialization with the value `false` should be + * provided. + */ +template +inline constexpr bool unit_can_be_prefixed = true; + +/** + * @brief A concept to be used to define prefixes for a unit + */ template concept PrefixableUnit = NamedUnit && unit_can_be_prefixed; + /** * @brief A prefixed unit * - * Defines a new unit that is a scaled version of another unit by the provided prefix. It is - * only possible to create such a unit if the given prefix type matches the one defined in a - * coherent_unit unit. + * Defines a new unit that is a scaled version of another unit with the scaling + * factor specified by a predefined prefix. * - * @tparam Child inherited class type used by the downcasting facility (CRTP Idiom) - * @tparam P prefix to be appied to the coherent_unit unit - * @tparam U coherent_unit unit + * For example: + * + * @code{.cpp} + * template + * struct kilo_ : prefixed_unit<"k", mag_power<10, 3>, U> {}; + * + * template + * inline constexpr kilo_ kilo; + * + * inline constexpr struct kilogram : decltype(si::kilo) {} kilogram; + * @endcode + * + * @tparam Symbol a prefix text to prepend to a unit symbol + * @tparam M scaling factor of the prefix + * @tparam U a named unit to be prefixed */ template struct prefixed_unit : std::remove_const_t { @@ -129,11 +218,54 @@ inline constexpr bool is_per_of_units> = (... && UnitLike); } // namespace detail template -concept UnitSpec = detail::UnitLike || detail::is_per_of_units; +concept DerivedUnitSpec = detail::UnitLike || detail::is_per_of_units; -// User should not instantiate this type!!! -// It should not be exported from the module -template +/** + * @brief Measurement unit for a derived quantity + * + * Derived units are defined as products of powers of the base units. + * + * Instead of using a raw list of exponents this library decided to use expression template syntax to make types + * more digestable for the user. The positive exponents are ordered first and all negative exponents are put as a list + * into the `per<...>` class template. If a power of exponent is different than `1` the unit type is enclosed in + * `power` class template. Otherwise, it is just put directly in the list without any wrapper. There + * is also one special case. In case all of the exponents are negative then the `one` being a coherent unit of + * a dimensionless quantity is put in the front to increase the readability. + * + * For example: + * + * @code{.cpp} + * static_assert(is_of_type<1 / second, derived_unit>>); + * static_assert(is_of_type<1 / (1 / second), second>); + * static_assert(is_of_type); + * static_assert(is_of_type>>); + * static_assert(is_of_type>); + * static_assert(is_of_type>>); + * static_assert(is_of_type, derived_unit>>>); + * static_assert(is_of_type>>); + * @endcode + * + * Every unit in the library has its internal canonical representation being the list of exponents of named base units + * (with the exception of `kilogram` which is represented as `gram` here) and a scaling ratio represented with a + * magnitude. + * + * Two units are deemed convertible if their canonical version has units of the same type. + * Two units are equivalent when they are convertible and their canonical versions have the same scaling ratios. + * + * The above means that: + * - `1/s` and `Hz` are both convertible and equal + * - `m` and `km` are convertible but not equal + * - `m` and `m²` ane not convertible and not equal + * + * @note This also means that units like `hertz` and `becquerel` are also considered convertible and equal. + * + * @tparam Us a parameter pack consisting tokens allowed in the unit specification + * (units, `power`, `per<...>`) + * + * @note User should not instantiate this type! It is not exported from the C++ module. The library will + * instantiate this type automatically based on the unit arithmetic equation provided by the user. + */ +template struct derived_unit : detail::expr_fractions, Us...> {}; /** @@ -161,27 +293,26 @@ template inline constexpr bool is_unit = true; /** - * @brief A common point for a hierarchy of units + * @brief A canonical representation of a unit * - * A unit is an entity defined and adopted by convention, with which any other quantity of - * the same kind can be compared to express the ratio of the second quantity to the first - * one as a number. + * A canonical representation of a unit consists of a `reference_unit` and its scaling + * factor represented by the magnitude `mag`. * - * All units of the same dimension can be convereted between each other. To allow this all of - * them are expressed as different ratios of the same one proprietary chosen coherent_unit unit - * (i.e. all length units are expressed in terms of meter, all mass units are expressed in - * terms of gram, ...) + * `reference_unit` is a unit (possibly derived one) that consists only named base units. + * All of the intermediate derived units are extracted, prefixes and magnitudes of scaled + * units are stripped from them and accounted in the `mag`. * - * @tparam M a Magnitude representing the (relative) size of this unit - * @tparam U a unit to use as a coherent_unit for this dimension + * All units having the same canonical unit are deemed equal. + * All units having the same `reference_unit` are convertible (their `mag` may differ + * and is the subject of conversion). * - * @note U cannot be constrained with Unit as for some specializations (i.e. named_unit) - * it gets the incomplete child's type with the CRTP idiom. + * @tparam U a unit to use as a `reference_unit` + * @tparam M a Magnitude representing an absolute scaling factor of this unit */ -template +template struct canonical_unit { - U reference_unit; M mag; + U reference_unit; }; [[nodiscard]] constexpr auto get_canonical_unit(UnitLike auto u); @@ -190,13 +321,13 @@ template [[nodiscard]] constexpr auto get_canonical_unit_impl(T, const volatile scaled_unit&) { auto base = get_canonical_unit(U{}); - return canonical_unit{base.reference_unit, M * base.mag}; + return canonical_unit{M * base.mag, base.reference_unit}; } template [[nodiscard]] constexpr auto get_canonical_unit_impl(T t, const volatile named_unit&) { - return canonical_unit{t, mag<1>}; + return canonical_unit{mag<1>, t}; } template @@ -210,27 +341,29 @@ template { auto base = get_canonical_unit(F{}); return canonical_unit{ - derived_unit, power::exponent>>{}, - pow::exponent>(base.mag)}; + pow::exponent>(base.mag), + derived_unit, power::exponent>>{}}; } -template +template [[nodiscard]] constexpr auto get_canonical_unit_impl(T, const volatile derived_unit&) { if constexpr (type_list_size::_den_> != 0) { auto num = get_canonical_unit(type_list_map::_num_, derived_unit>{}); auto den = get_canonical_unit(type_list_map::_den_, derived_unit>{}); - return canonical_unit{num.reference_unit / den.reference_unit, num.mag / den.mag}; + return canonical_unit{num.mag / den.mag, num.reference_unit / den.reference_unit}; } else { auto num = (one * ... * get_canonical_unit(Us{}).reference_unit); auto mag = (units::mag<1> * ... * get_canonical_unit(Us{}).mag); - return canonical_unit{num, mag}; + return canonical_unit{mag, num}; } } [[nodiscard]] constexpr auto get_canonical_unit(UnitLike auto u) { return get_canonical_unit_impl(u, u); } - +// TODO What if the same unit will have different types (i.e. user will inherit its own type from `metre`)? +// Is there a better way to sort units here? Some of them may not have symbol at all (like all units of +// dimensionless quantities). template struct unit_less : std::bool_constant() < type_name()> {}; @@ -242,27 +375,55 @@ using type_list_of_unit_less = expr_less; // Operators +/** + * Multiplication by `1` returns the same unit, otherwise `scaled_unit` is being returned. + */ template -[[nodiscard]] consteval Unit auto operator*(M mag, U) +[[nodiscard]] consteval Unit auto operator*(M mag, U u) { - // TODO Try passing magnitude parameters rather than magnitude type itself in case of a trivial magnitude - // (single integer, ratio...) - return scaled_unit>{}; + if constexpr (mag == units::mag<1>) + return u; + else + return scaled_unit>{}; } template [[nodiscard]] consteval Unit auto operator*(U, M) = delete; +/** + * `scaled_unit` specializations have priority in this operation. This means that the library framework + * prevents passing it as an element to the `derived_unit`. In such case only the reference unit is passed + * to the derived unit and the magnitude remains outside forming another scaled unit as a result of the operation. + */ template -[[nodiscard]] consteval Unit auto operator*(U1, U2) +[[nodiscard]] consteval Unit auto operator*(U1 u1, U2 u2) { - return detail::expr_multiply(); + if constexpr (detail::is_specialization_of_scaled_unit && detail::is_specialization_of_scaled_unit) + return (U1::mag * U2::mag) * (U1::reference_unit * U2::reference_unit); + else if constexpr (detail::is_specialization_of_scaled_unit) + return U1::mag * (U1::reference_unit * u2); + else if constexpr (detail::is_specialization_of_scaled_unit) + return U2::mag * (u1 * U2::reference_unit); + else + return detail::expr_multiply(); } +/** + * `scaled_unit` specializations have priority in this operation. This means that the library framework + * prevents passing it as an element to the `derived_unit`. In such case only the reference unit is passed + * to the derived unit and the magnitude remains outside forming another scaled unit as a result of the operation. + */ template -[[nodiscard]] consteval Unit auto operator/(U1, U2) +[[nodiscard]] consteval Unit auto operator/(U1 u1, U2 u2) { - return detail::expr_divide(); + if constexpr (detail::is_specialization_of_scaled_unit && detail::is_specialization_of_scaled_unit) + return (U1::mag / U2::mag) * (U1::reference_unit / U2::reference_unit); + else if constexpr (detail::is_specialization_of_scaled_unit) + return U1::mag * (U1::reference_unit / u2); + else if constexpr (detail::is_specialization_of_scaled_unit) + return U2::mag * (u1 / U2::reference_unit); + else + return detail::expr_divide(); } template @@ -294,20 +455,12 @@ template return is_same_v; } -// Helper types and variable factories -template -struct square_ : decltype(U{} * U{}) {}; - -template -struct cubic_ : decltype(U{} * U{} * U{}) {}; - -// it is not allowed to use the same name for a variable and class template -// (even though it works for objects of regular class types) +// Helper variable templates to create common powers template -inline constexpr square_> square; +inline constexpr decltype(U * U) square; template -inline constexpr cubic_> cubic; +inline constexpr decltype(U * U * U) cubic; } // namespace units diff --git a/test/unit_test/static/unit_test.cpp b/test/unit_test/static/unit_test.cpp index 6d3701de..6d8b74d8 100644 --- a/test/unit_test/static/unit_test.cpp +++ b/test/unit_test/static/unit_test.cpp @@ -45,7 +45,7 @@ inline constexpr struct kelvin_ : named_unit<"K"> {} kelvin; inline constexpr struct radian_ : named_unit<"rad", metre / metre> {} radian; inline constexpr struct steradian_ : named_unit<"sr", square / square> {} steradian; inline constexpr struct hertz_ : named_unit<"Hz", 1 / second> {} hertz; -inline constexpr struct becquerel : named_unit<"Bq", 1 / second> {} becquerel; +inline constexpr struct becquerel_ : named_unit<"Bq", 1 / second> {} becquerel; inline constexpr struct newton_ : named_unit<"N", kilogram * metre / square> {} newton; inline constexpr struct pascal_ : named_unit<"Pa", newton / square> {} pascal; inline constexpr struct joule_ : named_unit<"J", newton * metre> {} joule; @@ -94,9 +94,6 @@ static_assert(!NamedUnit)>); static_assert(!NamedUnit * second)>); static_assert(!NamedUnit); -template -constexpr bool print(); - // named unit static_assert(is_of_type); static_assert(is_of_type); @@ -201,21 +198,26 @@ static_assert(si::yotta.symbol == "Ym"); // scaled_unit -constexpr auto u1 = mag<1> * metre; -static_assert(is_of_type, metre_>>); -static_assert(is_of_type); -static_assert(get_canonical_unit(u1).mag == mag<1>); +constexpr auto m_1 = mag<1> * metre; +static_assert(is_of_type); +static_assert(is_of_type); +static_assert(get_canonical_unit(m_1).mag == mag<1>); -constexpr auto u2 = mag<2> * kilometre; -static_assert(is_of_type, kilometre_>>); -static_assert(is_of_type); -static_assert(get_canonical_unit(u2).mag == mag<2000>); +constexpr auto m_2 = mag<2> * metre; +static_assert(is_of_type, metre_>>); +static_assert(is_of_type); +static_assert(get_canonical_unit(m_2).mag == mag<2>); -constexpr auto u3 = mag<42> * si::kilo; -static_assert(is_of_type, si::kilo_>>); +constexpr auto km_2 = mag<2> * kilometre; +static_assert(is_of_type, kilometre_>>); +static_assert(is_of_type); +static_assert(get_canonical_unit(km_2).mag == mag<2000>); + +constexpr auto kJ_42 = mag<42> * si::kilo; +static_assert(is_of_type, si::kilo_>>); static_assert( - is_of_type, per>>>); -static_assert(get_canonical_unit(u3).mag == mag<42'000'000>); + is_of_type, per>>>); +static_assert(get_canonical_unit(kJ_42).mag == mag<42'000'000>); // derived unit expression template syntax verification @@ -229,6 +231,14 @@ static_assert(is_of_type<1 / second * one, derived_unit>>); static_assert(is_of_type>); static_assert(is_of_type>>); +static_assert(is_of_type, derived_unit>>); +static_assert(is_of_type, derived_unit>>); +static_assert(is_of_type * metre, derived_unit>>); +static_assert(is_of_type, derived_unit>>); + +static_assert(is_of_type>>); +static_assert(is_of_type, derived_unit>>>); +static_assert(is_of_type / second, derived_unit>>>); static_assert(is_of_type, second_>>); static_assert(is_of_type, second_>>); @@ -254,40 +264,52 @@ static_assert(is_of_type); static_assert(is_of_type>>); static_assert(is_of_type>>); +static_assert(std::is_same_v); +static_assert(std::is_same_v); +static_assert(std::is_same_v); +static_assert(std::is_same_v); +static_assert(std::is_same_v)>); + // derived unit normalization -constexpr auto u4 = metre / second; -static_assert(is_of_type>>); -static_assert(get_canonical_unit(u4).mag == mag<1>); +constexpr auto m_per_s = metre / second; +static_assert(is_of_type>>); +static_assert(get_canonical_unit(m_per_s).mag == mag<1>); -constexpr auto u5 = kilometre / second; -static_assert(is_of_type>>); -static_assert(is_of_type>>); -static_assert(get_canonical_unit(u5).mag == mag<1000>); +constexpr auto km_per_s = kilometre / second; +static_assert(is_of_type>>); +static_assert(is_of_type>>); +static_assert(get_canonical_unit(km_per_s).mag == mag<1000>); -constexpr auto u6 = kilometre / hour; -static_assert(is_of_type>>); -static_assert(is_of_type>>); -static_assert(get_canonical_unit(u6).mag == mag); +constexpr auto km_per_h = kilometre / hour; +static_assert(is_of_type>>); +static_assert(is_of_type>>); +static_assert(get_canonical_unit(km_per_h).mag == mag); -constexpr auto u7 = mag<1000> * kilometre / hour; -static_assert(is_of_type, kilometre_>, per>>); -static_assert(is_of_type>>); -static_assert(get_canonical_unit(u7).mag == mag); +// operations commutativity +constexpr auto u1 = mag<1000> * kilometre / hour; +static_assert(is_of_type, derived_unit>>>); +static_assert(is_of_type>>); +static_assert(get_canonical_unit(u1).mag == mag); -constexpr auto u8 = mag<1000> * (kilometre / hour); -static_assert(is_of_type, derived_unit>>>); -static_assert(is_of_type>>); -static_assert(get_canonical_unit(u8).mag == mag); +constexpr auto u2 = mag<1000> * (kilometre / hour); +static_assert(is_of_type, derived_unit>>>); +static_assert(is_of_type>>); +static_assert(get_canonical_unit(u2).mag == mag); -constexpr auto u9 = 1 / hour * (mag<1000> * kilometre); -static_assert(is_of_type, kilometre_>, per>>); -static_assert(is_of_type>>); -static_assert(get_canonical_unit(u9).mag == mag); +constexpr auto u3 = 1 / hour * (mag<1000> * kilometre); +static_assert(is_of_type, derived_unit>>>); +static_assert(is_of_type>>); +static_assert(get_canonical_unit(u3).mag == mag); // comparisons of the same units static_assert(second == second); static_assert(metre / second == metre / second); +static_assert(si::milli / si::milli == si::micro / si::micro); +static_assert(si::milli / si::micro == si::micro / si::nano); +static_assert(si::micro / si::milli == si::nano / si::micro); +static_assert(si::milli * si::kilo == si::deci * si::deca); +static_assert(si::kilo * si::milli == si::deca * si::deci); // comparisons of equivalent units (named vs unnamed/derived) static_assert(1 / second == hertz); @@ -312,109 +334,24 @@ static_assert(convertible(mag<100> * metre, kilometre)); static_assert(si::milli != kilometre); static_assert(convertible(si::milli, kilometre)); +// comparisons of non-convertible units +static_assert(metre != metre * metre); +static_assert(!convertible(metre, metre* metre)); + // one +static_assert(is_of_type); static_assert(metre / metre == one); -// static_assert(metre * metre == square_metre); -// static_assert(second * second == second_squared); -// static_assert(second * second * second == second_cubed); -// static_assert(second * (second * second) == second_cubed); -// static_assert(second_squared * second == second_cubed); -// static_assert(second * second_squared == second_cubed); +static_assert(hertz * second == one); -// static_assert(1 / second * metre == metre / second); -// static_assert(metre * (1 / second) == metre / second); -// static_assert((metre / second) * (1 / second) == metre / second / second); -// static_assert((metre / second) * (1 / second) == metre / (second * second)); -// static_assert((metre / second) * (1 / second) == metre / second_squared); - -// static_assert(hertz == 1 / second); -// static_assert(newton == kilogram * metre / second_squared); -// static_assert(joule == kilogram * square_metre / second_squared); -// static_assert(joule == newton * metre); -// static_assert(watt == joule / second); -// static_assert(watt == kilogram * square_metre / second_cubed); - -// static_assert(1 / frequency_dim == second); -// static_assert(frequency_dim * second == one); - -// static_assert(metre * metre == area_dim); -// static_assert(metre * metre != volume_dim); -// static_assert(area_dim / metre == metre); - -// static_assert(metre * metre * metre == volume_dim); -// static_assert(area_dim * metre == volume_dim); -// static_assert(volume_dim / metre == area_dim); -// static_assert(volume_dim / metre / metre == metre); -// static_assert(area_dim * area_dim / metre == volume_dim); -// static_assert(area_dim * (area_dim / metre) == volume_dim); -// static_assert(volume_dim / (metre * metre) == metre); - -// static_assert(metre / second == speed_dim); -// static_assert(metre * second != speed_dim); -// static_assert(metre / second / second != speed_dim); -// static_assert(metre / speed_dim == second); -// static_assert(speed_dim * second == metre); - -// static_assert(metre / second / second == acceleration_dim); -// static_assert(metre / (second * second) == acceleration_dim); -// static_assert(speed_dim / second == acceleration_dim); -// static_assert(speed_dim / acceleration_dim == second); -// static_assert(acceleration_dim * second == speed_dim); -// static_assert(acceleration_dim * (second * second) == metre); -// static_assert(acceleration_dim / speed_dim == frequency_dim); - - -// milli / milli == micro / micro; -// milli * kilo == deci * deca; - -// Bq + Hz should not compile - -// Bq + Hz + 1/s should compile? - - -// using namespace units; -// using namespace units::isq; - -// struct metre : named_unit {}; -// struct centimetre : prefixed_unit {}; -// struct kilometre : prefixed_unit {}; -// struct yard : named_scaled_unit(), metre> {}; -// struct foot : named_scaled_unit(), yard> {}; -// struct dim_length : base_dimension<"length", metre> {}; - -// struct second : named_unit {}; -// struct hour : named_scaled_unit(), second> {}; -// struct dim_time : base_dimension<"time", second> {}; - -// struct kelvin : named_unit {}; - -// #if !UNITS_COMP_MSVC -// static_assert([](P) { -// return !requires { typename prefixed_unit; }; -// }(si::kilo{})); // no prefix allowed -// #endif - -// struct metre_per_second : derived_unit {}; -// struct dim_speed : -// derived_dimension, units::exponent> {}; -// struct kilometre_per_hour : derived_scaled_unit {}; - -// static_assert(equivalent); -// static_assert(equivalent); -// static_assert(compare(), metre>>, metre>); -// static_assert(compare(), metre>>, centimetre>); -// static_assert(compare>, yard>); -// static_assert(compare(), metre>>, foot>); -// static_assert(compare>, kilometre_per_hour>); +static_assert(hertz == 1 / second); +static_assert(newton == kilogram * metre / square); +static_assert(joule == kilogram * square / square); +static_assert(joule == newton * metre); +static_assert(watt == joule / second); +static_assert(watt == kilogram * square / cubic); // static_assert(centimetre::symbol == "cm"); // static_assert(kilometre::symbol == "km"); // static_assert(kilometre_per_hour::symbol == "km/h"); - -// static_assert(si::metre != si::kilometre); -// static_assert(!equivalent(si::metre, si::kilometre)); -// static_assert(convertible(si::metre, si::kilometre)); - - } // namespace From 5a7f58be41f5620b382c3a108f4b983417a38ae8 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 20 Oct 2022 14:05:20 +0200 Subject: [PATCH 037/402] fix: Added a special case for multiplication of opposite magnitude exponents --- src/core/include/units/magnitude.h | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/core/include/units/magnitude.h b/src/core/include/units/magnitude.h index c45c40a9..e4aff28b 100644 --- a/src/core/include/units/magnitude.h +++ b/src/core/include/units/magnitude.h @@ -588,13 +588,17 @@ constexpr Magnitude auto operator*(magnitude, magnitude) constexpr auto partial_product = magnitude{} * magnitude{}; if constexpr (is_same_v) { - // Make a new power_v with the common base of H1 and H2, whose power is their powers' sum. - constexpr auto new_head = power_v_or_T(); - - if constexpr (get_exponent(new_head) == 0) { - return partial_product; + if constexpr (get_exponent(H1) + get_exponent(H2) == 0) { + return magnitude<1>{}; } else { - return magnitude{} * partial_product; + // Make a new power_v with the common base of H1 and H2, whose power is their powers' sum. + constexpr auto new_head = power_v_or_T(); + + if constexpr (get_exponent(new_head) == 0) { + return partial_product; + } else { + return magnitude{} * partial_product; + } } } else if constexpr (is_named_magnitude) { return magnitude

{} * (magnitude{} * magnitude{}); From aca82085682f9d3956cb70978f1df5fb3885f88b Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 20 Oct 2022 14:06:22 +0200 Subject: [PATCH 038/402] test: dimension unit tests cleanup --- test/unit_test/static/dimension_test.cpp | 33 ++++++++++-------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/test/unit_test/static/dimension_test.cpp b/test/unit_test/static/dimension_test.cpp index b8e54c6f..00d68473 100644 --- a/test/unit_test/static/dimension_test.cpp +++ b/test/unit_test/static/dimension_test.cpp @@ -76,17 +76,13 @@ static_assert(is_of_type>>); static_assert(is_of_type>); -static_assert(is_of_type>>); +static_assert(is_of_type>>); -static_assert( - is_of_type, time_dim_>>); -static_assert( - is_of_type, time_dim_>>); +static_assert(is_of_type, time_dim_>>); +static_assert(is_of_type, time_dim_>>); -static_assert( - is_of_type, time_dim_>>); -static_assert( - is_of_type, time_dim_>>); +static_assert(is_of_type, time_dim_>>); +static_assert(is_of_type, time_dim_>>); static_assert(is_of_type<1 / time_dim * length_dim, derived_dimension>>); static_assert(is_of_type<1 / time_dim * time_dim, one_dim_>); @@ -95,22 +91,21 @@ static_assert(is_of_type); static_assert(is_of_type<1 / time_dim / one_dim, derived_dimension>>); static_assert(is_of_type); -static_assert(is_of_type<1 / time_dim * (1 / time_dim), derived_dimension>>>); -static_assert(is_of_type<1 / (time_dim * time_dim), derived_dimension>>>); -static_assert(is_of_type<1 / (1 / (time_dim * time_dim)), derived_dimension>>); +static_assert(is_of_type<1 / time_dim * (1 / time_dim), derived_dimension>>>); +static_assert(is_of_type<1 / (time_dim * time_dim), derived_dimension>>>); +static_assert(is_of_type<1 / (1 / (time_dim * time_dim)), derived_dimension>>); static_assert( - is_of_type>>>); + is_of_type>>>); static_assert(is_of_type, per>>>); + derived_dimension, per>>>); static_assert(is_of_type); static_assert(is_of_type); static_assert(is_of_type>>); +static_assert(is_of_type>>>); static_assert( - is_of_type>>>); -static_assert(is_of_type<1 / (speed_dim * speed_dim) * length_dim, - derived_dimension, per>>); + is_of_type<1 / (speed_dim * speed_dim) * length_dim, derived_dimension, per>>); // comparisons of the same dimensions static_assert(length_dim == length_dim); @@ -167,9 +162,9 @@ static_assert(std::is_same_v>>>); + is_of_type>>>); static_assert( - is_of_type>>>); + is_of_type>>>); static_assert(mass_dim * acceleration_dim == acceleration_dim * mass_dim); static_assert(convertible(mass_dim * acceleration_dim, acceleration_dim* mass_dim)); From b7348809035cb7444360c59af6b669351bad5fff Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Fri, 21 Oct 2022 23:10:12 +0200 Subject: [PATCH 039/402] refactor: `standard` renamed to `unicode` in `basic_symbol_text` --- src/core/include/units/symbol_text.h | 109 ++++++++++++++------------- 1 file changed, 55 insertions(+), 54 deletions(-) diff --git a/src/core/include/units/symbol_text.h b/src/core/include/units/symbol_text.h index e6adbe34..eaef22b4 100644 --- a/src/core/include/units/symbol_text.h +++ b/src/core/include/units/symbol_text.h @@ -57,119 +57,120 @@ constexpr void validate_ascii_string([[maybe_unused]] const char (&s)[N + 1]) no * representation. In the libary it is used to define symbols of units and prefixes. * Each symbol can have two versions: Unicode and ASCI-only. * - * @tparam StandardCharT Character type to be used for a Unicode representation + * @tparam UnicodeCharT Character type to be used for a Unicode representation * @tparam N The size of a Unicode symbol * @tparam M The size of the ASCII-only symbol */ -template +template struct basic_symbol_text { - basic_fixed_string standard_; + basic_fixed_string unicode_; basic_fixed_string ascii_; - constexpr explicit(false) basic_symbol_text(char std) noexcept : standard_(std), ascii_(std) + constexpr explicit(false) basic_symbol_text(char txt) noexcept : unicode_(txt), ascii_(txt) { - detail::validate_ascii_char(std); + detail::validate_ascii_char(txt); } - constexpr basic_symbol_text(StandardCharT std, char a) noexcept : standard_(std), ascii_(a) + constexpr basic_symbol_text(UnicodeCharT u, char a) noexcept : unicode_(u), ascii_(a) { detail::validate_ascii_char(a); } - constexpr explicit(false) basic_symbol_text(const char (&std)[N + 1]) noexcept : standard_(std), ascii_(std) + constexpr explicit(false) basic_symbol_text(const char (&txt)[N + 1]) noexcept : unicode_(txt), ascii_(txt) { - detail::validate_ascii_string(std); + detail::validate_ascii_string(txt); } - constexpr explicit(false) basic_symbol_text(const basic_fixed_string& std) noexcept : - standard_(std), ascii_(std) + constexpr explicit(false) basic_symbol_text(const basic_fixed_string& txt) noexcept : + unicode_(txt), ascii_(txt) { - detail::validate_ascii_string(std.data_); + detail::validate_ascii_string(txt.data_); } - constexpr basic_symbol_text(const StandardCharT (&std)[N + 1], const char (&ascii)[M + 1]) noexcept : - standard_(std), ascii_(ascii) + constexpr basic_symbol_text(const UnicodeCharT (&u)[N + 1], const char (&a)[M + 1]) noexcept : unicode_(u), ascii_(a) { - detail::validate_ascii_string(ascii); + detail::validate_ascii_string(a); } - constexpr basic_symbol_text(const basic_fixed_string& std, - const basic_fixed_string& ascii) noexcept : - standard_(std), ascii_(ascii) + constexpr basic_symbol_text(const basic_fixed_string& u, + const basic_fixed_string& a) noexcept : + unicode_(u), ascii_(a) { - detail::validate_ascii_string(ascii.data_); + detail::validate_ascii_string(a.data_); } - [[nodiscard]] constexpr auto& standard() { return standard_; } - [[nodiscard]] constexpr const auto& standard() const { return standard_; } + [[nodiscard]] constexpr auto& unicode() { return unicode_; } + [[nodiscard]] constexpr const auto& unicode() const { return unicode_; } [[nodiscard]] constexpr auto& ascii() { return ascii_; } [[nodiscard]] constexpr const auto& ascii() const { return ascii_; } + [[nodiscard]] constexpr bool empty() const { return unicode().empty() && ascii().empty(); } + template - [[nodiscard]] constexpr friend basic_symbol_text operator+( - const basic_symbol_text& lhs, const basic_symbol_text& rhs) noexcept + [[nodiscard]] constexpr friend basic_symbol_text operator+( + const basic_symbol_text& lhs, const basic_symbol_text& rhs) noexcept { - return basic_symbol_text(lhs.standard() + rhs.standard(), lhs.ascii() + rhs.ascii()); + return basic_symbol_text(lhs.unicode() + rhs.unicode(), lhs.ascii() + rhs.ascii()); } template - [[nodiscard]] constexpr friend basic_symbol_text operator+( - const basic_symbol_text& lhs, const basic_fixed_string& rhs) noexcept + [[nodiscard]] constexpr friend basic_symbol_text operator+( + const basic_symbol_text& lhs, const basic_fixed_string& rhs) noexcept { - return lhs + basic_symbol_text(rhs); + return lhs + basic_symbol_text(rhs); } template - [[nodiscard]] constexpr friend basic_symbol_text operator+( - const basic_fixed_string& lhs, const basic_symbol_text& rhs) noexcept + [[nodiscard]] constexpr friend basic_symbol_text operator+( + const basic_fixed_string& lhs, const basic_symbol_text& rhs) noexcept { - return basic_symbol_text(lhs) + rhs; + return basic_symbol_text(lhs) + rhs; } template - [[nodiscard]] constexpr friend basic_symbol_text operator+( - const basic_symbol_text& lhs, const StandardCharT (&rhs)[N2]) noexcept + [[nodiscard]] constexpr friend basic_symbol_text operator+( + const basic_symbol_text& lhs, const UnicodeCharT (&rhs)[N2]) noexcept { - return lhs + basic_symbol_text(rhs); + return lhs + basic_symbol_text(rhs); } template - [[nodiscard]] constexpr friend basic_symbol_text operator+( - const StandardCharT (&lhs)[N2], const basic_symbol_text& rhs) noexcept + [[nodiscard]] constexpr friend basic_symbol_text operator+( + const UnicodeCharT (&lhs)[N2], const basic_symbol_text& rhs) noexcept { - return basic_symbol_text(lhs) + rhs; + return basic_symbol_text(lhs) + rhs; } - [[nodiscard]] constexpr friend basic_symbol_text operator+(const basic_symbol_text& lhs, - StandardCharT rhs) noexcept + [[nodiscard]] constexpr friend basic_symbol_text operator+(const basic_symbol_text& lhs, + UnicodeCharT rhs) noexcept { - return lhs + basic_symbol_text(rhs); + return lhs + basic_symbol_text(rhs); } - [[nodiscard]] constexpr friend basic_symbol_text operator+( - StandardCharT lhs, const basic_symbol_text& rhs) noexcept + [[nodiscard]] constexpr friend basic_symbol_text operator+( + UnicodeCharT lhs, const basic_symbol_text& rhs) noexcept { - return basic_symbol_text(lhs) + rhs; + return basic_symbol_text(lhs) + rhs; } - template + template [[nodiscard]] friend constexpr auto operator<=>(const basic_symbol_text& lhs, - const basic_symbol_text& rhs) noexcept + const basic_symbol_text& rhs) noexcept { UNITS_DIAGNOSTIC_PUSH UNITS_DIAGNOSTIC_IGNORE_ZERO_AS_NULLPOINTER_CONSTANT - if (const auto cmp = lhs.standard() <=> rhs.standard(); cmp != 0) return cmp; + if (const auto cmp = lhs.unicode() <=> rhs.unicode(); cmp != 0) return cmp; UNITS_DIAGNOSTIC_POP return lhs.ascii() <=> rhs.ascii(); } - template + template [[nodiscard]] friend constexpr bool operator==(const basic_symbol_text& lhs, - const basic_symbol_text& rhs) noexcept + const basic_symbol_text& rhs) noexcept { - return lhs.standard() == rhs.standard() && lhs.ascii() == rhs.ascii(); + return lhs.unicode() == rhs.unicode() && lhs.ascii() == rhs.ascii(); } }; basic_symbol_text(char)->basic_symbol_text; -template -basic_symbol_text(StandardCharT, char) -> basic_symbol_text; +template +basic_symbol_text(UnicodeCharT, char) -> basic_symbol_text; template basic_symbol_text(const char (&)[N]) -> basic_symbol_text; @@ -177,11 +178,11 @@ basic_symbol_text(const char (&)[N]) -> basic_symbol_text; template basic_symbol_text(const basic_fixed_string&) -> basic_symbol_text; -template -basic_symbol_text(const StandardCharT (&)[N], const char (&)[M]) -> basic_symbol_text; +template +basic_symbol_text(const UnicodeCharT (&)[N], const char (&)[M]) -> basic_symbol_text; -template -basic_symbol_text(const basic_fixed_string&, const basic_fixed_string&) - -> basic_symbol_text; +template +basic_symbol_text(const basic_fixed_string&, const basic_fixed_string&) + -> basic_symbol_text; } // namespace units From 4b83b3a2eed314c4a3badfb22da8cfb9ccf9e815 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Fri, 21 Oct 2022 23:10:56 +0200 Subject: [PATCH 040/402] refactor: `text_tools` made `consteval` and `[[nodiscard]]` --- src/core/include/units/bits/external/text_tools.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/include/units/bits/external/text_tools.h b/src/core/include/units/bits/external/text_tools.h index a70e5107..f09b28a9 100644 --- a/src/core/include/units/bits/external/text_tools.h +++ b/src/core/include/units/bits/external/text_tools.h @@ -57,7 +57,7 @@ inline constexpr basic_symbol_text superscript_minus("\u207b", "-"); inline constexpr basic_symbol_text superscript_prefix("", "^"); template -constexpr auto superscript_helper() +[[nodiscard]] consteval auto superscript_helper() { if constexpr (Value < 0) return superscript_minus + superscript_helper<-Value>(); @@ -68,13 +68,13 @@ constexpr auto superscript_helper() } template -constexpr auto superscript() +[[nodiscard]] consteval auto superscript() { return superscript_prefix + superscript_helper(); } template -constexpr auto regular() +[[nodiscard]] consteval auto regular() { if constexpr (Value < 0) return basic_fixed_string("-") + superscript_helper<-Value>(); From fddc3480a9c6e7c2cd8c1cc2edee9ab7f8b74642 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Fri, 21 Oct 2022 23:11:25 +0200 Subject: [PATCH 041/402] feat: `copy` algorithm added --- src/core/include/units/bits/algorithm.h | 42 +++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/core/include/units/bits/algorithm.h b/src/core/include/units/bits/algorithm.h index 1ac80362..ca3877e4 100644 --- a/src/core/include/units/bits/algorithm.h +++ b/src/core/include/units/bits/algorithm.h @@ -25,6 +25,7 @@ #include // IWYU pragma: keep #include #include +#include namespace units::detail { @@ -97,4 +98,45 @@ constexpr auto lexicographical_compare_three_way(I1 f1, I1 l1, I2 f2, I2 l2) return ::units::detail::lexicographical_compare_three_way(f1, l1, f2, l2, std::compare_three_way()); } +template +struct in_out_result { + [[no_unique_address]] I in; + [[no_unique_address]] O out; + + template + requires std::convertible_to && std::convertible_to + constexpr operator in_out_result() const& + { + return {in, out}; + } + + template + requires std::convertible_to && std::convertible_to + constexpr operator in_out_result() && + { + return {std::move(in), std::move(out)}; + } +}; + +template +using copy_result = in_out_result; + +template S, std::weakly_incrementable O> + requires std::indirectly_copyable +constexpr copy_result copy(I first, S last, O result) +{ + for (; first != last; ++first, (void)++result) { + *result = *first; + } + return {std::move(first), std::move(result)}; +} + +template + requires std::indirectly_copyable, O> +constexpr copy_result, O> copy(R&& r, O result) +{ + return ::units::detail::copy(std::ranges::begin(r), std::ranges::end(r), std::move(result)); +} + + } // namespace units::detail From 914d24a90319b4b08b34c93c24f5050aa6aff531 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Fri, 21 Oct 2022 23:13:10 +0200 Subject: [PATCH 042/402] refactor: not empty constraints added for defining a symbol --- src/core/include/units/unit.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index 5eff0503..f537daac 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -116,6 +116,7 @@ struct named_unit; * @tparam Symbol a short text representation of the unit */ template + requires(!Symbol.empty()) struct named_unit { static constexpr auto symbol = Symbol; ///< Unique base unit identifier }; @@ -129,6 +130,7 @@ struct named_unit { * @tparam Unit a unit for which we provide a special name */ template + requires(!Symbol.empty()) struct named_unit : std::remove_const_t { static constexpr auto symbol = Symbol; ///< Unique unit identifier }; @@ -196,6 +198,7 @@ concept PrefixableUnit = NamedUnit && unit_can_be_prefixed; * @tparam U a named unit to be prefixed */ template + requires(!Symbol.empty()) struct prefixed_unit : std::remove_const_t { static constexpr auto symbol = Symbol + U.symbol; }; From 17fd0900a4cb545d5d9b35f90bc4393956905041 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Sat, 22 Oct 2022 09:02:40 +0200 Subject: [PATCH 043/402] refactor: expression template operations now take function parameters --- .../include/units/bits/expression_template.h | 106 +++++++++--------- src/core/include/units/dimension.h | 28 ++--- 2 files changed, 67 insertions(+), 67 deletions(-) diff --git a/src/core/include/units/bits/expression_template.h b/src/core/include/units/bits/expression_template.h index e7ead18e..07dac42c 100644 --- a/src/core/include/units/bits/expression_template.h +++ b/src/core/include/units/bits/expression_template.h @@ -250,17 +250,17 @@ struct expr_simplify, NRest...>, type_list typename Pred> -struct expr_less_impl : Pred {}; +template typename Pred> +struct expr_less_impl : Pred {}; -template typename Pred> -struct expr_less_impl, power, Pred> : Pred {}; +template typename Pred> +struct expr_less_impl, power, Pred> : Pred {}; -template typename Pred> -struct expr_less_impl, T2, Pred> : Pred {}; +template typename Pred> +struct expr_less_impl, Rhs, Pred> : Pred {}; -template typename Pred> -struct expr_less_impl, Pred> : Pred {}; +template typename Pred> +struct expr_less_impl, Pred> : Pred {}; template typename Pred> struct expr_less_impl, Pred> : std::true_type {}; @@ -271,8 +271,8 @@ struct expr_less_impl, Pred> : std::true_type {}; * Algorithm accounts not only for explicit types but also for the case when they * are wrapped within `power`. */ -template typename Pred> -using expr_less = expr_less_impl; +template typename Pred> +using expr_less = expr_less_impl; // expr_fractions @@ -355,34 +355,34 @@ template typename Pred, - template typename To> -[[nodiscard]] consteval auto expr_multiply() +template typename To, typename OneType, template typename Pred, typename Lhs, + typename Rhs> +[[nodiscard]] consteval auto expr_multiply(Lhs, Rhs) { - if constexpr (is_same_v) { - return T2{}; - } else if constexpr (is_same_v) { - return T1{}; - } else if constexpr (is_specialization_of && is_specialization_of) { + if constexpr (is_same_v) { + return Rhs{}; + } else if constexpr (is_same_v) { + return Lhs{}; + } else if constexpr (is_specialization_of && is_specialization_of) { // two derived dimensions - return get_optimized_expression, - type_list_merge_sorted, OneType, Pred, - To>(); - } else if constexpr (is_specialization_of) { - return get_optimized_expression, Pred>, typename T1::_den_, - OneType, Pred, To>(); - } else if constexpr (is_specialization_of) { - return get_optimized_expression, Pred>, typename T2::_den_, - OneType, Pred, To>(); + return get_optimized_expression, + type_list_merge_sorted, OneType, + Pred, To>(); + } else if constexpr (is_specialization_of) { + return get_optimized_expression, Pred>, + typename Lhs::_den_, OneType, Pred, To>(); + } else if constexpr (is_specialization_of) { + return get_optimized_expression, Pred>, + typename Rhs::_den_, OneType, Pred, To>(); } else { // two base dimensions - return get_optimized_expression, type_list, Pred>, type_list<>, OneType, + return get_optimized_expression, type_list, Pred>, type_list<>, OneType, Pred, To>(); } } @@ -390,34 +390,34 @@ template typename Pred, - template typename To> -[[nodiscard]] consteval auto expr_divide() +template typename To, typename OneType, template typename Pred, typename Lhs, + typename Rhs> +[[nodiscard]] consteval auto expr_divide(Lhs, Rhs) { - if constexpr (is_same_v) { + if constexpr (is_same_v) { return OneType{}; - } else if constexpr (is_same_v) { - return T1{}; - } else if constexpr (is_specialization_of && is_specialization_of) { + } else if constexpr (is_same_v) { + return Lhs{}; + } else if constexpr (is_specialization_of && is_specialization_of) { // two derived dimensions - return get_optimized_expression, - type_list_merge_sorted, OneType, Pred, - To>(); - } else if constexpr (is_specialization_of) { - return get_optimized_expression, Pred>, - OneType, Pred, To>(); - } else if constexpr (is_specialization_of) { - return get_optimized_expression, Pred>, typename T2::_num_, - OneType, Pred, To>(); + return get_optimized_expression, + type_list_merge_sorted, OneType, + Pred, To>(); + } else if constexpr (is_specialization_of) { + return get_optimized_expression< + typename Lhs::_num_, type_list_merge_sorted, Pred>, OneType, Pred, To>(); + } else if constexpr (is_specialization_of) { + return get_optimized_expression, Pred>, + typename Rhs::_num_, OneType, Pred, To>(); } else { // two base dimensions - return To>{}; + return To>{}; } } @@ -428,8 +428,8 @@ template typename To> -[[nodiscard]] consteval auto expr_invert() +template typename To, typename OneType, typename T> +[[nodiscard]] consteval auto expr_invert(T) { if constexpr (is_specialization_of) return expr_make_spec{}; diff --git a/src/core/include/units/dimension.h b/src/core/include/units/dimension.h index 9e17d108..561f99c2 100644 --- a/src/core/include/units/dimension.h +++ b/src/core/include/units/dimension.h @@ -109,8 +109,8 @@ concept Dimension = BaseDimension || DerivedDimension; namespace detail { -template -struct base_dimension_less : std::bool_constant<(D1::symbol < D2::symbol)> {}; +template +struct base_dimension_less : std::bool_constant<(Lhs::symbol < Rhs::symbol)> {}; template using type_list_of_base_dimension_less = expr_less; @@ -249,34 +249,34 @@ using dim_type = dim_type_impl::type; // Operators -template -[[nodiscard]] consteval Dimension auto operator*(D1, D2) +template +[[nodiscard]] consteval Dimension auto operator*(Lhs, Rhs) { - return detail::expr_multiply, detail::dim_type, struct one_dim, - detail::type_list_of_base_dimension_less, derived_dimension>(); + return detail::expr_multiply( + detail::dim_type{}, detail::dim_type{}); } -template -[[nodiscard]] consteval Dimension auto operator/(D1, D2) +template +[[nodiscard]] consteval Dimension auto operator/(Lhs, Rhs) { - return detail::expr_divide, detail::dim_type, struct one_dim, - detail::type_list_of_base_dimension_less, derived_dimension>(); + return detail::expr_divide( + detail::dim_type{}, detail::dim_type{}); } template [[nodiscard]] consteval Dimension auto operator/(int value, D) { gsl_Assert(value == 1); - return detail::expr_invert, struct one_dim, derived_dimension>(); + return detail::expr_invert(detail::dim_type{}); } template [[nodiscard]] consteval Dimension auto operator/(D, int) = delete; -template -[[nodiscard]] consteval bool operator==(D1, D2) +template +[[nodiscard]] consteval bool operator==(Lhs, Rhs) { - return is_same_v; + return is_same_v; } template From 17036cb2d08a292a59a889ab04eccbbaa6850494 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Sat, 22 Oct 2022 19:27:39 +0200 Subject: [PATCH 044/402] feat: unit symbol text output support added --- .../include/units/bits/derived_symbol_text.h | 89 ----- src/core/include/units/bits/unit_text.h | 166 --------- src/core/include/units/magnitude.h | 290 ++++++++------- src/core/include/units/unit.h | 338 +++++++++++++++--- test/unit_test/static/unit_test.cpp | 73 +++- 5 files changed, 499 insertions(+), 457 deletions(-) delete mode 100644 src/core/include/units/bits/derived_symbol_text.h delete mode 100644 src/core/include/units/bits/unit_text.h diff --git a/src/core/include/units/bits/derived_symbol_text.h b/src/core/include/units/bits/derived_symbol_text.h deleted file mode 100644 index 2d358725..00000000 --- a/src/core/include/units/bits/derived_symbol_text.h +++ /dev/null @@ -1,89 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include -#include - -namespace units::detail { - -template -constexpr auto operator_text() -{ - if constexpr (Idx == 0) { - if constexpr (Divide && NegativeExpCount == 1) { - return basic_fixed_string("1/"); - } else { - return basic_fixed_string(""); - } - } else { - if constexpr (Divide && NegativeExpCount == 1) { - return basic_fixed_string("/"); - } else { - return basic_symbol_text("⋅", " "); - } - } -} - -template -constexpr auto exp_text() -{ - // get calculation operator + symbol - const auto txt = operator_text<(E::num < 0), NegativeExpCount, Idx>() + Symbol; - if constexpr (E::den != 1) { - // add root part - return txt + basic_fixed_string("^(") + regular() + basic_fixed_string("/") + regular() + - basic_fixed_string(")"); - } else if constexpr (E::num != 1) { - // add exponent part - if constexpr (NegativeExpCount > 1) { // no '/' sign here (only negative exponents) - return txt + superscript(); - } else if constexpr (E::num != -1) { // -1 is replaced with '/' sign here - return txt + superscript(); - } else { - return txt; - } - } else { - return txt; - } -} - -template -inline constexpr int negative_exp_count = ((Es::num < 0 ? 1 : 0) + ... + 0); - -template -constexpr auto derived_symbol_text(exponent_list, std::index_sequence) -{ - constexpr auto neg_exp = negative_exp_count; - return (exp_text() + ...); -} - -template -constexpr auto derived_symbol_text() -{ - return derived_symbol_text(typename Dim::recipe(), std::index_sequence_for()); -} - -} // namespace units::detail diff --git a/src/core/include/units/bits/unit_text.h b/src/core/include/units/bits/unit_text.h deleted file mode 100644 index 9421e5ef..00000000 --- a/src/core/include/units/bits/unit_text.h +++ /dev/null @@ -1,166 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include -#include -#include - -namespace units::detail { - -inline constexpr basic_symbol_text base_multiplier("\u00D7 10", "x 10"); - -template -constexpr auto magnitude_text() -{ - constexpr auto exp10 = extract_power_of_10(M); - - constexpr Magnitude auto base = M / mag_power<10, exp10>; - constexpr Magnitude auto num = numerator(base); - constexpr Magnitude auto den = denominator(base); - static_assert(base == num / den, "Printing rational powers, or irrational bases, not yet supported"); - - constexpr auto num_value = get_value(num); - constexpr auto den_value = get_value(den); - - - if constexpr (num_value == 1 && den_value == 1 && exp10 != 0) { - return base_multiplier + superscript(); - } else if constexpr (num_value != 1 || den_value != 1 || exp10 != 0) { - auto txt = basic_fixed_string("[") + regular(); - if constexpr (den_value == 1) { - if constexpr (exp10 == 0) { - return txt + basic_fixed_string("]"); - } else { - return txt + " " + base_multiplier + superscript() + basic_fixed_string("]"); - } - } else { - if constexpr (exp10 == 0) { - return txt + basic_fixed_string("/") + regular() + basic_fixed_string("]"); - } else { - return txt + basic_fixed_string("/") + regular() + " " + base_multiplier + superscript() + - basic_fixed_string("]"); - } - } - } else { - return basic_fixed_string(""); - } -} - -template -constexpr auto prefix_or_magnitude_text() -{ - if constexpr (M == mag<1>()) { - // no ratio/prefix - return basic_fixed_string(""); - } else { - // try to form a prefix - using prefix = downcast>; - - if constexpr (can_be_prefixed && !is_same_v>) { - // print as a prefixed unit - return prefix::symbol; - } else { - // print as a ratio of the coherent unit - constexpr auto txt = magnitude_text(); - if constexpr (SymbolLen > 0 && txt.standard().size() > 0) - return txt + basic_fixed_string(" "); - else - return txt; - } - } -} - -template -constexpr auto derived_dimension_unit_text(exponent_list, std::index_sequence) -{ - return (exp_text::symbol, negative_exp_count, Idxs>() + ... + - basic_symbol_text(basic_fixed_string(""))); -} - -template -constexpr auto derived_dimension_unit_text(exponent_list list) -{ - return derived_dimension_unit_text(list, std::index_sequence_for()); -} - -template -constexpr auto exponent_list_with_named_units(exponent_list); - -template -constexpr auto exponent_list_with_named_units(Exp) -{ - using dim = TYPENAME Exp::dimension; - if constexpr (NamedUnit>) { - return exponent_list(); - } else { - using recipe = TYPENAME dim::recipe; - return exponent_list_with_named_units(recipe()); - } -} - -template -constexpr auto exponent_list_with_named_units(exponent_list) -{ - return type_list_join(); -} - -constexpr auto exponent_list_with_named_units(exponent_list<> empty) { return empty; } - -template -constexpr auto derived_dimension_unit_text() -{ - using recipe = TYPENAME Dim::recipe; - return derived_dimension_unit_text(exponent_list_with_named_units(recipe())); -} - -template -// TODO replace with `inline constexpr bool has_symbol` when MSVC cathes up -concept has_symbol = requires { T::symbol; }; - -template -constexpr auto unit_text() -{ - if constexpr (has_symbol) { - // already has a symbol so print it - return U::symbol; - } else { - // print as a prefix or ratio of a coherent unit - using coherent_unit = dimension_unit; - - constexpr auto symbol_text = []() { - if constexpr (has_symbol) - return coherent_unit::symbol; - else - return derived_dimension_unit_text(); - }(); - - constexpr auto prefix_txt = - prefix_or_magnitude_text(); - return prefix_txt + symbol_text; - } -} - -} // namespace units::detail diff --git a/src/core/include/units/magnitude.h b/src/core/include/units/magnitude.h index e4aff28b..234a16d5 100644 --- a/src/core/include/units/magnitude.h +++ b/src/core/include/units/magnitude.h @@ -146,15 +146,6 @@ struct power_v { namespace detail { -/** - * @brief Deduction guides for base_power: only permit deducing integral bases. - */ -// template U> -// base_power(T, U) -> base_power; -// template -// base_power(T) -> base_power; - -// Implementation for PowerV concept (below). template inline constexpr bool is_specialization_of_power_v = false; @@ -163,15 +154,39 @@ inline constexpr bool is_specialization_of_power_v> = true; } // namespace detail + +template +concept MagnitudeSpec = PowerVBase || detail::is_specialization_of_power_v; + +namespace detail { + +template +[[nodiscard]] consteval auto get_base(Element element) +{ + if constexpr (detail::is_specialization_of_power_v) + return Element::base; + else + return element; +} + +template +[[nodiscard]] consteval ratio get_exponent(Element) +{ + if constexpr (detail::is_specialization_of_power_v) + return Element::exponent; + else + return ratio{1}; +} + +} // namespace detail + + /** * @brief Concept to detect whether a _type_ is a valid base power. * * Note that this is somewhat incomplete. We must also detect whether a _value_ of that type is valid for use with * `magnitude<...>`. We will defer that second check to the constraints on the `magnitude` template. */ -template -concept PowerV = detail::is_specialization_of_power_v; - namespace detail { // We do not want magnitude type to have the `l` literal after a value for a small integral number. @@ -205,78 +220,82 @@ template } else { return power_v{}; } -}; +} -// consteval auto inverse(PowerV auto bp) { return power_v_or_T(); } +[[nodiscard]] consteval auto inverse(MagnitudeSpec auto el) +{ + return power_v_or_T(); +} // `widen_t` gives the widest arithmetic type in the same category, for intermediate computations. -// template -// using widen_t = conditional, -// conditional, long double, -// conditional, std::intmax_t, std::uintmax_t>>, -// T>; +template +using widen_t = conditional, + conditional, long double, + conditional, std::intmax_t, std::uintmax_t>>, + T>; // Raise an arbitrary arithmetic type to a positive integer power at compile time. -// template -// constexpr T int_power(T base, std::integral auto exp) -// { -// // As this function should only be called at compile time, the exceptions herein function as -// // "parameter-compatible static_asserts", and should not result in exceptions at runtime. -// if (exp < 0) { -// throw std::invalid_argument{"int_power only supports positive integer powers"}; -// } +template +[[nodiscard]] consteval T int_power(T base, std::integral auto exp) +{ + // As this function should only be called at compile time, the exceptions herein function as + // "parameter-compatible static_asserts", and should not result in exceptions at runtime. + if (exp < 0) { + throw std::invalid_argument{"int_power only supports positive integer powers"}; + } -// constexpr auto checked_multiply = [](auto a, auto b) { -// const auto result = a * b; -// UNITS_DIAGNOSTIC_PUSH -// UNITS_DIAGNOSTIC_IGNORE_FLOAT_EQUAL -// if (result / a != b) { -// throw std::overflow_error{"Wraparound detected"}; -// } -// UNITS_DIAGNOSTIC_POP -// return result; -// }; + constexpr auto checked_multiply = [](auto a, auto b) { + const auto result = a * b; + UNITS_DIAGNOSTIC_PUSH + UNITS_DIAGNOSTIC_IGNORE_FLOAT_EQUAL + if (result / a != b) { + throw std::overflow_error{"Wraparound detected"}; + } + UNITS_DIAGNOSTIC_POP + return result; + }; -// constexpr auto checked_square = [checked_multiply](auto a) { return checked_multiply(a, a); }; + constexpr auto checked_square = [checked_multiply](auto a) { return checked_multiply(a, a); }; -// // TODO(chogg): Unify this implementation with the one in pow.h. That one takes its exponent as a -// // template parameter, rather than a function parameter. + // TODO(chogg): Unify this implementation with the one in pow.h. That one takes its exponent as a + // template parameter, rather than a function parameter. -// if (exp == 0) { -// return T{1}; -// } + if (exp == 0) { + return T{1}; + } -// if (exp % 2 == 1) { -// return checked_multiply(base, int_power(base, exp - 1)); -// } + if (exp % 2 == 1) { + return checked_multiply(base, int_power(base, exp - 1)); + } -// return checked_square(int_power(base, exp / 2)); -// } + return checked_square(int_power(base, exp / 2)); +} -// template -// constexpr widen_t compute_base_power(PowerV auto bp) -// { -// // This utility can only handle integer powers. To compute rational powers at compile time, we'll -// // need to write a custom function. -// // -// // Note that since this function should only be called at compile time, the point of these -// // exceptions is to act as "static_assert substitutes", not to throw actual exceptions at runtime. -// if (bp.power.den != 1) { -// throw std::invalid_argument{"Rational powers not yet supported"}; -// } +template +[[nodiscard]] consteval widen_t compute_base_power(MagnitudeSpec auto el) +{ + // This utility can only handle integer powers. To compute rational powers at compile time, we'll + // need to write a custom function. + // + // Note that since this function should only be called at compile time, the point of these + // exceptions is to act as "static_assert substitutes", not to throw actual exceptions at runtime. + const auto exp = get_exponent(el); + if (exp.den != 1) { + throw std::invalid_argument{"Rational powers not yet supported"}; + } -// if (bp.power.num < 0) { -// if constexpr (std::is_integral_v) { -// throw std::invalid_argument{"Cannot represent reciprocal as integer"}; -// } else { -// return T{1} / compute_base_power(inverse(bp)); -// } -// } + if (exp.num < 0) { + if constexpr (std::is_integral_v) { + throw std::invalid_argument{"Cannot represent reciprocal as integer"}; + } else { + return T{1} / compute_base_power(inverse(el)); + } + } -// auto power = bp.power.num; -// return int_power(static_cast>(bp.get_base()), power); -// } + auto power = exp.num; + return int_power(static_cast>(get_base(el)), power); +} // A converter for the value member variable of magnitude (below). // @@ -285,7 +304,7 @@ template template // TODO(chogg): Migrate this to use `treat_as_floating_point`. requires(!std::is_integral_v || std::is_integral_v) -constexpr To checked_static_cast(From x) +[[nodiscard]] consteval To checked_static_cast(From x) { // This function should only ever be called at compile time. The purpose of these exceptions is // to produce compiler errors, because we cannot `static_assert` on function arguments. @@ -300,39 +319,10 @@ constexpr To checked_static_cast(From x) } // namespace detail -/** - * @brief Equality detection for two base powers. - */ -// template -// [[nodiscard]] consteval bool operator==(T, U) -// { -// return std::is_same_v; -// } - -template -concept MagnitudeSpec = PowerVBase || PowerV; // A variety of implementation detail helpers. namespace detail { -template -[[nodiscard]] consteval auto get_base(Element element) -{ - if constexpr (PowerV) - return Element::base; - else - return element; -} - -template -[[nodiscard]] consteval ratio get_exponent(Element) -{ - if constexpr (PowerV) - return Element::exponent; - else - return ratio{1}; -} - // The exponent of `factor` in the prime factorization of `n`. [[nodiscard]] consteval std::intmax_t multiplicity(std::intmax_t factor, std::intmax_t n) { @@ -493,16 +483,16 @@ inline constexpr bool is_specialization_of_magnitude> = true; /** * @brief The value of a Magnitude in a desired type T. */ -// template -// // TODO(chogg): Migrate this to use `treat_as_floating_point`. -// requires(!std::integral || is_integral(magnitude{})) -// constexpr T get_value(const magnitude&) -// { -// // Force the expression to be evaluated in a constexpr context, to catch, e.g., overflow. -// constexpr auto result = detail::checked_static_cast((detail::compute_base_power(BPs) * ... * T{1})); +template +// TODO(chogg): Migrate this to use `treat_as_floating_point`. + requires(!std::integral || is_integral(magnitude{})) +constexpr T get_value(const magnitude&) +{ + // Force the expression to be evaluated in a constexpr context, to catch, e.g., overflow. + constexpr auto result = detail::checked_static_cast((detail::compute_base_power(Ms) * ... * T{1})); -// return result; -// } + return result; +} /** @@ -525,7 +515,7 @@ template // Magnitude rational powers implementation. template -constexpr auto pow(magnitude) +[[nodiscard]] consteval auto pow(magnitude) { if constexpr (E.num == 0) { return magnitude<>{}; @@ -535,13 +525,13 @@ constexpr auto pow(magnitude) } template -constexpr auto sqrt(magnitude m) +[[nodiscard]] consteval auto sqrt(magnitude m) { return pow(m); } template -constexpr auto cbrt(magnitude m) +[[nodiscard]] consteval auto cbrt(magnitude m) { return pow(m); } @@ -571,7 +561,7 @@ constexpr Magnitude auto operator*(Magnitude auto m, magnitude<>) { return m; } // Recursive case for the product of any two non-identity Magnitudes. template -constexpr Magnitude auto operator*(magnitude, magnitude) +[[nodiscard]] consteval Magnitude auto operator*(magnitude, magnitude) { using namespace detail; @@ -611,7 +601,7 @@ constexpr Magnitude auto operator*(magnitude, magnitude) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Magnitude quotient implementation. -constexpr auto operator/(Magnitude auto l, Magnitude auto r) { return l * pow<-1>(r); } +[[nodiscard]] consteval auto operator/(Magnitude auto l, Magnitude auto r) { return l * pow<-1>(r); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Magnitude numerator and denominator implementation. @@ -619,19 +609,15 @@ constexpr auto operator/(Magnitude auto l, Magnitude auto r) { return l * pow<-1 namespace detail { // The largest integer which can be extracted from any magnitude with only a single basis vector. -template -constexpr auto integer_part(magnitude) +template +[[nodiscard]] consteval auto integer_part(magnitude) { - constexpr auto power_num = BP.power.num; - constexpr auto power_den = BP.power.den; + constexpr auto power_num = get_exponent(M).num; + constexpr auto power_den = get_exponent(M).den; - if constexpr (std::is_integral_v && (power_num >= power_den)) { - constexpr auto largest_integer_power = [=](PowerV auto bp) { - bp.power = (power_num / power_den); // Note: integer division intended. - return bp; - }(BP); // Note: lambda is immediately invoked. - - return magnitude{}; + if constexpr (std::is_integral_v && (power_num >= power_den)) { + // largest integer power + return magnitude()>{}; // Note: integer division intended } else { return magnitude<>{}; } @@ -639,13 +625,13 @@ constexpr auto integer_part(magnitude) } // namespace detail -template -constexpr auto numerator(magnitude) +template +[[nodiscard]] consteval auto numerator(magnitude) { - return (detail::integer_part(magnitude{}) * ... * magnitude<>{}); + return (detail::integer_part(magnitude{}) * ... * magnitude<>{}); } -constexpr auto denominator(Magnitude auto m) { return numerator(pow<-1>(m)); } +[[nodiscard]] consteval auto denominator(Magnitude auto m) { return numerator(pow<-1>(m)); } // Implementation of conversion to ratio goes here, because it needs `numerator()` and `denominator()`. // constexpr ratio as_ratio(Magnitude auto m) @@ -677,44 +663,51 @@ constexpr auto denominator(Magnitude auto m) { return numerator(pow<-1>(m)); } // minimum power for each base (where absent bases implicitly have a power of 0). namespace detail { -template -constexpr auto remove_positive_power(magnitude m) + +template +[[nodiscard]] consteval auto remove_positive_power(magnitude m) { - if constexpr (BP.power.num < 0) { + if constexpr (get_exponent(M).num < 0) { return m; } else { return magnitude<>{}; } } -template -constexpr auto remove_positive_powers(magnitude) +template +[[nodiscard]] consteval auto remove_positive_powers(magnitude) { - return (magnitude<>{} * ... * remove_positive_power(magnitude{})); + return (magnitude<>{} * ... * remove_positive_power(magnitude{})); } } // namespace detail // Base cases, for when either (or both) inputs are the identity. -constexpr auto common_magnitude(magnitude<>, magnitude<>) { return magnitude<>{}; } -constexpr auto common_magnitude(magnitude<>, Magnitude auto m) { return detail::remove_positive_powers(m); } -constexpr auto common_magnitude(Magnitude auto m, magnitude<>) { return detail::remove_positive_powers(m); } +[[nodiscard]] consteval auto common_magnitude(magnitude<>, magnitude<>) { return magnitude<>{}; } +[[nodiscard]] consteval auto common_magnitude(magnitude<>, Magnitude auto m) +{ + return detail::remove_positive_powers(m); +} +[[nodiscard]] consteval auto common_magnitude(Magnitude auto m, magnitude<>) +{ + return detail::remove_positive_powers(m); +} // Recursive case for the common Magnitude of any two non-identity Magnitudes. template -constexpr auto common_magnitude(magnitude, magnitude) +[[nodiscard]] consteval auto common_magnitude(magnitude, magnitude) { using detail::remove_positive_power; - if constexpr (H1.get_base() < H2.get_base()) { + if constexpr (get_base(H1) < get_base(H2)) { // When H1 has the smaller base, prepend to result from recursion. return remove_positive_power(magnitude

{}) * common_magnitude(magnitude{}, magnitude{}); - } else if constexpr (H2.get_base() < H1.get_base()) { + } else if constexpr (get_base(H2) < get_base(H1)) { // When H2 has the smaller base, prepend to result from recursion. return remove_positive_power(magnitude

{}) * common_magnitude(magnitude{}, magnitude{}); } else { // When the bases are equal, pick whichever has the lower power. constexpr auto common_tail = common_magnitude(magnitude{}, magnitude{}); - if constexpr ((H1.power) < (H2.power)) { + if constexpr (get_exponent(H1) < get_exponent(H2)) { return magnitude

{} * common_tail; } else { return magnitude

{} * common_tail; @@ -740,7 +733,7 @@ namespace detail { template requires(N > 0) struct prime_factorization { - static constexpr std::intmax_t get_or_compute_first_factor() + [[nodiscard]] static consteval std::intmax_t get_or_compute_first_factor() { if constexpr (known_first_factor.has_value()) { return known_first_factor.value(); @@ -786,15 +779,16 @@ template inline constexpr Magnitude auto mag_power = pow(mag); namespace detail { -template -constexpr ratio get_power(T base, magnitude) + +template +[[nodiscard]] consteval ratio get_power(T base, magnitude) { - return ((BPs.get_base() == base ? BPs.power : ratio{0}) + ... + ratio{0}); + return ((get_base(Ms) == base ? get_exponent(Ms) : ratio{0}) + ... + ratio{0}); } -constexpr std::intmax_t integer_part(ratio r) { return r.num / r.den; } +[[nodiscard]] consteval std::intmax_t integer_part(ratio r) { return r.num / r.den; } -constexpr std::intmax_t extract_power_of_10(Magnitude auto m) +[[nodiscard]] consteval std::intmax_t extract_power_of_10(Magnitude auto m) { const auto power_of_2 = get_power(2, m); const auto power_of_5 = get_power(5, m); @@ -805,6 +799,6 @@ constexpr std::intmax_t extract_power_of_10(Magnitude auto m) return integer_part((detail::abs(power_of_2) < detail::abs(power_of_5)) ? power_of_2 : power_of_5); } -} // namespace detail +} // namespace detail } // namespace units diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index f537daac..a620c2cb 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -22,12 +22,16 @@ #pragma once +#include #include #include +#include #include #include #include #include +#include +#include // #include @@ -209,19 +213,16 @@ template inline constexpr bool is_power_of_unit = requires { requires is_specialization_of_power && Unit; }; -template -concept UnitLike = Unit || is_power_of_unit; - template inline constexpr bool is_per_of_units = false; template -inline constexpr bool is_per_of_units> = (... && UnitLike); +inline constexpr bool is_per_of_units> = (... && (Unit || is_power_of_unit)); } // namespace detail template -concept DerivedUnitSpec = detail::UnitLike || detail::is_per_of_units; +concept DerivedUnitSpec = Unit || detail::is_power_of_unit || detail::is_per_of_units; /** * @brief Measurement unit for a derived quantity @@ -312,63 +313,75 @@ inline constexpr bool is_unit = true; * @tparam U a unit to use as a `reference_unit` * @tparam M a Magnitude representing an absolute scaling factor of this unit */ -template +template struct canonical_unit { M mag; U reference_unit; }; -[[nodiscard]] constexpr auto get_canonical_unit(UnitLike auto u); +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T t, const named_unit&); -template -[[nodiscard]] constexpr auto get_canonical_unit_impl(T, const volatile scaled_unit&) +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T, const named_unit&); + +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T, const power&); + +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T, const derived_unit&); + +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T, const scaled_unit&) { - auto base = get_canonical_unit(U{}); + auto base = get_canonical_unit_impl(U{}, U{}); return canonical_unit{M * base.mag, base.reference_unit}; } -template -[[nodiscard]] constexpr auto get_canonical_unit_impl(T t, const volatile named_unit&) +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T t, const named_unit&) { return canonical_unit{mag<1>, t}; } -template -[[nodiscard]] constexpr auto get_canonical_unit_impl(T, const volatile named_unit&) +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T, const named_unit&) { - return get_canonical_unit(U); + return get_canonical_unit_impl(U, U); } -template -[[nodiscard]] constexpr auto get_canonical_unit_impl(T, const volatile power&) +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T, const power&) { - auto base = get_canonical_unit(F{}); + auto base = get_canonical_unit_impl(F{}, F{}); return canonical_unit{ pow::exponent>(base.mag), derived_unit, power::exponent>>{}}; } -template -[[nodiscard]] constexpr auto get_canonical_unit_impl(T, const volatile derived_unit&) +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T, const derived_unit&) { if constexpr (type_list_size::_den_> != 0) { - auto num = get_canonical_unit(type_list_map::_num_, derived_unit>{}); - auto den = get_canonical_unit(type_list_map::_den_, derived_unit>{}); + using num_type = type_list_map::_num_, derived_unit>; + using den_type = type_list_map::_den_, derived_unit>; + auto num = get_canonical_unit_impl(num_type{}, num_type{}); + auto den = get_canonical_unit_impl(den_type{}, den_type{}); return canonical_unit{num.mag / den.mag, num.reference_unit / den.reference_unit}; } else { - auto num = (one * ... * get_canonical_unit(Us{}).reference_unit); - auto mag = (units::mag<1> * ... * get_canonical_unit(Us{}).mag); + auto num = (one * ... * get_canonical_unit_impl(Us{}, Us{}).reference_unit); + auto mag = (units::mag<1> * ... * get_canonical_unit_impl(Us{}, Us{}).mag); return canonical_unit{mag, num}; } } -[[nodiscard]] constexpr auto get_canonical_unit(UnitLike auto u) { return get_canonical_unit_impl(u, u); } +[[nodiscard]] consteval auto get_canonical_unit(Unit auto u) { return get_canonical_unit_impl(u, u); } // TODO What if the same unit will have different types (i.e. user will inherit its own type from `metre`)? // Is there a better way to sort units here? Some of them may not have symbol at all (like all units of // dimensionless quantities). -template -struct unit_less : std::bool_constant() < type_name()> {}; +template +struct unit_less : std::bool_constant() < type_name()> {}; template using type_list_of_unit_less = expr_less; @@ -398,17 +411,17 @@ template * prevents passing it as an element to the `derived_unit`. In such case only the reference unit is passed * to the derived unit and the magnitude remains outside forming another scaled unit as a result of the operation. */ -template -[[nodiscard]] consteval Unit auto operator*(U1 u1, U2 u2) +template +[[nodiscard]] consteval Unit auto operator*(Lhs lhs, Rhs rhs) { - if constexpr (detail::is_specialization_of_scaled_unit && detail::is_specialization_of_scaled_unit) - return (U1::mag * U2::mag) * (U1::reference_unit * U2::reference_unit); - else if constexpr (detail::is_specialization_of_scaled_unit) - return U1::mag * (U1::reference_unit * u2); - else if constexpr (detail::is_specialization_of_scaled_unit) - return U2::mag * (u1 * U2::reference_unit); + if constexpr (detail::is_specialization_of_scaled_unit && detail::is_specialization_of_scaled_unit) + return (Lhs::mag * Rhs::mag) * (Lhs::reference_unit * Rhs::reference_unit); + else if constexpr (detail::is_specialization_of_scaled_unit) + return Lhs::mag * (Lhs::reference_unit * rhs); + else if constexpr (detail::is_specialization_of_scaled_unit) + return Rhs::mag * (lhs * Rhs::reference_unit); else - return detail::expr_multiply(); + return detail::expr_multiply(lhs, rhs); } /** @@ -416,31 +429,31 @@ template * prevents passing it as an element to the `derived_unit`. In such case only the reference unit is passed * to the derived unit and the magnitude remains outside forming another scaled unit as a result of the operation. */ -template -[[nodiscard]] consteval Unit auto operator/(U1 u1, U2 u2) +template +[[nodiscard]] consteval Unit auto operator/(Lhs lhs, Rhs rhs) { - if constexpr (detail::is_specialization_of_scaled_unit && detail::is_specialization_of_scaled_unit) - return (U1::mag / U2::mag) * (U1::reference_unit / U2::reference_unit); - else if constexpr (detail::is_specialization_of_scaled_unit) - return U1::mag * (U1::reference_unit / u2); - else if constexpr (detail::is_specialization_of_scaled_unit) - return U2::mag * (u1 / U2::reference_unit); + if constexpr (detail::is_specialization_of_scaled_unit && detail::is_specialization_of_scaled_unit) + return (Lhs::mag / Rhs::mag) * (Lhs::reference_unit / Rhs::reference_unit); + else if constexpr (detail::is_specialization_of_scaled_unit) + return Lhs::mag * (Lhs::reference_unit / rhs); + else if constexpr (detail::is_specialization_of_scaled_unit) + return Rhs::mag * (lhs / Rhs::reference_unit); else - return detail::expr_divide(); + return detail::expr_divide(lhs, rhs); } template -[[nodiscard]] consteval Unit auto operator/(int value, U) +[[nodiscard]] consteval Unit auto operator/(int value, U u) { gsl_Assert(value == 1); - return detail::expr_invert(); + return detail::expr_invert(u); } template [[nodiscard]] consteval Unit auto operator/(U, int) = delete; -template -[[nodiscard]] consteval bool operator==(U1 lhs, U2 rhs) +template +[[nodiscard]] consteval bool operator==(Lhs lhs, Rhs rhs) { auto canonical_lhs = detail::get_canonical_unit(lhs); auto canonical_rhs = detail::get_canonical_unit(rhs); @@ -450,8 +463,8 @@ template // Convertible -template -[[nodiscard]] consteval bool convertible(U1 lhs, U2 rhs) +template +[[nodiscard]] consteval bool convertible(Lhs lhs, Rhs rhs) { auto canonical_lhs = detail::get_canonical_unit(lhs); auto canonical_rhs = detail::get_canonical_unit(rhs); @@ -465,9 +478,232 @@ inline constexpr decltype(U * U) square; template inline constexpr decltype(U * U * U) cubic; + +// get_unit_symbol + +enum class text_encoding { + unicode, // m³; µs + ascii, // m^3; us + default_encoding = unicode +}; + +enum class unit_symbol_denominator { + solidus_one, // m/s; kg m-1 s-1 + always_solidus, // m/s; kg/(m s) + always_negative, // m s-1; kg m-1 s-1 + default_denominator = solidus_one +}; + +enum class unit_symbol_separator { + space, // kg m²/s² + dot, // kg⋅m²/s² (valid only for unicode encoding) + default_separator = space +}; + +struct unit_symbol_formatting { + text_encoding encoding = text_encoding::default_encoding; + unit_symbol_denominator denominator = unit_symbol_denominator::default_denominator; + unit_symbol_separator separator = unit_symbol_separator::default_separator; +}; + +namespace detail { + +// TODO Should `basic_symbol_text` be fixed to use `char` type for both encodings? +template Out> +constexpr Out copy(const basic_symbol_text& txt, text_encoding encoding, Out out) +{ + if (encoding == text_encoding::unicode) { + if (is_same_v) + return copy(txt.unicode(), out).out; + else + static_assert("Unicode text can't be copied to CharT output"); + } else { + if (is_same_v) + return copy(txt.ascii(), out).out; + else + static_assert("ASCII text can't be copied to CharT output"); + } +} + +inline constexpr basic_symbol_text base_multiplier("\u00D7 10", "x 10"); + +template +constexpr auto magnitude_text() +{ + constexpr auto exp10 = extract_power_of_10(M); + + constexpr Magnitude auto base = M / mag_power<10, exp10>; + constexpr Magnitude auto num = numerator(base); + constexpr Magnitude auto den = denominator(base); + static_assert(base == num / den, "Printing rational powers, or irrational bases, not yet supported"); + + constexpr auto num_value = get_value(num); + constexpr auto den_value = get_value(den); + + if constexpr (num_value == 1 && den_value == 1 && exp10 != 0) { + return base_multiplier + superscript(); + } else if constexpr (num_value != 1 || den_value != 1 || exp10 != 0) { + auto txt = basic_fixed_string("[") + regular(); + if constexpr (den_value == 1) { + if constexpr (exp10 == 0) { + return txt + basic_fixed_string("]"); + } else { + return txt + " " + base_multiplier + superscript() + basic_fixed_string("]"); + } + } else { + if constexpr (exp10 == 0) { + return txt + basic_fixed_string("/") + regular() + basic_fixed_string("]"); + } else { + return txt + basic_fixed_string("/") + regular() + " " + base_multiplier + superscript() + + basic_fixed_string("]"); + } + } + } else { + return basic_fixed_string(""); + } +} + +template Out> +constexpr Out print_separator(Out out, unit_symbol_formatting fmt) +{ + if (fmt.separator == unit_symbol_separator::dot) { + if (fmt.encoding != text_encoding::unicode) + throw std::invalid_argument("'unit_symbol_separator::dot' can be only used with 'text_encoding::unicode'"); + copy(std::string_view("⋅"), out); + } else { + *out++ = ' '; + } + return out; +} + +template Out, Unit U> + requires requires { U::symbol; } +constexpr Out unit_symbol_impl(Out out, U, unit_symbol_formatting fmt, bool negative_power) +{ + out = copy(U::symbol, fmt.encoding, out); + if (negative_power) { + constexpr auto txt = superscript<-1>(); + out = copy(txt, fmt.encoding, out); + } + return out; +} + +template Out, auto M, typename U> +constexpr Out unit_symbol_impl(Out out, const scaled_unit& u, unit_symbol_formatting fmt, bool negative_power) +{ + if constexpr (M == mag<1>) { + // no ratio/prefix + return unit_symbol_impl(out, u.reference_unit, fmt, negative_power); + } else { + constexpr auto mag_txt = magnitude_text(); + out = copy(mag_txt, fmt.encoding, out); + + if constexpr (std::derived_from, derived_unit<>>) + return out; + else { + *out++ = ' '; + return unit_symbol_impl(out, u.reference_unit, fmt, negative_power); + } + } +} + +template Out, typename F, int Num, int... Den> +constexpr auto unit_symbol_impl(Out out, const power&, unit_symbol_formatting fmt, bool negative_power) +{ + out = unit_symbol_impl(out, F{}, fmt, false); // negative power component will be added below if needed + + constexpr ratio r = power::exponent; + if constexpr (r.den != 1) { + // add root part + constexpr auto txt = txt + basic_fixed_string("^(") + regular() + basic_fixed_string("/") + + regular() + basic_fixed_string(")"); + return copy(txt, fmt.encoding, out); + } else if constexpr (r.num != 1) { + // add exponent part + if (negative_power) { + constexpr auto txt = superscript<-r.num>(); + return copy(txt, fmt.encoding, out); + } else { + constexpr auto txt = superscript(); + return copy(txt, fmt.encoding, out); + } + } +} + +template Out, DerivedUnitSpec M> +constexpr Out unit_symbol_impl(Out out, M m, std::size_t Idx, unit_symbol_formatting fmt, bool negative_power) +{ + if (Idx > 0) out = print_separator(out, fmt); + return unit_symbol_impl(out, m, fmt, negative_power); +} + +template Out, DerivedUnitSpec... Ms, std::size_t... Idxs> +constexpr Out unit_symbol_impl(Out out, const type_list&, std::index_sequence, + unit_symbol_formatting fmt, bool negative_power) +{ + return (..., (out = unit_symbol_impl(out, Ms{}, Idxs, fmt, negative_power))); +} + +template Out, DerivedUnitSpec... Nums, DerivedUnitSpec... Dens> +constexpr Out unit_symbol_impl(Out out, const type_list& nums, const type_list& dens, + unit_symbol_formatting fmt) +{ + if constexpr (sizeof...(Nums) == 0 && sizeof...(Dens) == 0) { + // dimensionless quantity + return out; + } else if constexpr (sizeof...(Dens) == 0) { + // no denominator + return unit_symbol_impl(out, nums, std::index_sequence_for(), fmt, false); + } else { + using enum unit_symbol_denominator; + if constexpr (sizeof...(Nums) > 0) { + unit_symbol_impl(out, nums, std::index_sequence_for(), fmt, false); + } + + if (fmt.denominator == always_solidus || (fmt.denominator == solidus_one && sizeof...(Dens) == 1)) { + if constexpr (sizeof...(Nums) == 0) *out++ = '1'; + *out++ = '/'; + } else { + out = print_separator(out, fmt); + } + + if (fmt.denominator == always_solidus && sizeof...(Dens) > 1) *out++ = '('; + bool negative_power = fmt.denominator == always_negative || (fmt.denominator == solidus_one && sizeof...(Dens) > 1); + out = unit_symbol_impl(out, dens, std::index_sequence_for(), fmt, negative_power); + if (fmt.denominator == always_solidus && sizeof...(Dens) > 1) *out++ = ')'; + return out; + } +} + +template Out, typename... Us> +constexpr Out unit_symbol_impl(Out out, const derived_unit&, unit_symbol_formatting fmt, bool negative_power) +{ + gsl_Assert(negative_power == false); + return unit_symbol_impl(out, typename derived_unit::_num_{}, typename derived_unit::_den_{}, + fmt); +} + +} // namespace detail + + +template Out, Unit U> +constexpr Out unit_symbol_to(Out out, U u, unit_symbol_formatting fmt = unit_symbol_formatting{}) +{ + return detail::unit_symbol_impl(out, u, fmt, false); +} + +template +[[nodiscard]] constexpr std::basic_string unit_symbol(U u, unit_symbol_formatting fmt = unit_symbol_formatting{}) +{ + std::basic_string buffer; + unit_symbol_to(std::back_inserter(buffer), u, fmt); + return buffer; +} + } // namespace units namespace std { + // TODO implement this template requires(units::convertible(U1{}, U2{})) diff --git a/test/unit_test/static/unit_test.cpp b/test/unit_test/static/unit_test.cpp index 6d8b74d8..9d55eb61 100644 --- a/test/unit_test/static/unit_test.cpp +++ b/test/unit_test/static/unit_test.cpp @@ -235,6 +235,9 @@ static_assert(is_of_type, derived_unit>>); static_assert(is_of_type, derived_unit>>); static_assert(is_of_type * metre, derived_unit>>); static_assert(is_of_type, derived_unit>>); +static_assert(is_of_type / metre, metre_>); +static_assert(is_of_type / metre, derived_unit>>); +static_assert(is_of_type / square, metre_>); static_assert(is_of_type>>); static_assert(is_of_type, derived_unit>>>); @@ -350,8 +353,72 @@ static_assert(joule == newton * metre); static_assert(watt == joule / second); static_assert(watt == kilogram * square / cubic); -// static_assert(centimetre::symbol == "cm"); -// static_assert(kilometre::symbol == "km"); -// static_assert(kilometre_per_hour::symbol == "km/h"); +// unit symbols +#ifdef __cpp_lib_constexpr_string + +using enum text_encoding; +using enum unit_symbol_denominator; +using enum unit_symbol_separator; + +// named units +static_assert(unit_symbol(metre) == "m"); +static_assert(unit_symbol(second) == "s"); +static_assert(unit_symbol(joule) == "J"); +static_assert(unit_symbol(degree_Celsius) == "\u00B0C"); +static_assert(unit_symbol(degree_Celsius, {.encoding = ascii}) == "`C"); +static_assert(unit_symbol(kilometre) == "km"); +static_assert(unit_symbol(si::milli) == "mm"); +static_assert(unit_symbol(si::micro) == "µm"); +static_assert(unit_symbol(si::micro, {.encoding = ascii}) == "um"); +static_assert(unit_symbol(kilojoule) == "kJ"); +static_assert(unit_symbol(hour) == "h"); + +// scaled units +static_assert(unit_symbol(mag<100> * metre) == "× 10² m"); +static_assert(unit_symbol(mag<100> * metre, {.encoding = ascii}) == "x 10^2 m"); +static_assert(unit_symbol(mag<60> * second) == "[6 × 10¹] s"); +static_assert(unit_symbol(mag<60> * second, {.encoding = ascii}) == "[6 x 10^1] s"); + +static_assert(unit_symbol(one) == ""); +static_assert(unit_symbol(square) == "m²"); +static_assert(unit_symbol(square, {.encoding = ascii}) == "m^2"); +static_assert(unit_symbol(cubic) == "m³"); +static_assert(unit_symbol(cubic, {.encoding = ascii}) == "m^3"); +static_assert(unit_symbol(metre / second) == "m/s"); +static_assert(unit_symbol(metre / second, {.denominator = always_solidus}) == "m/s"); +static_assert(unit_symbol(metre / second, {.denominator = always_negative}) == "m s⁻¹"); +static_assert(unit_symbol(metre / second, {.encoding = ascii, .denominator = always_negative}) == "m s^-1"); +static_assert(unit_symbol(metre / second, {.denominator = always_negative, .separator = dot}) == "m⋅s⁻¹"); +static_assert(unit_symbol(metre / square) == "m/s²"); +static_assert(unit_symbol(metre / square, {.encoding = ascii}) == "m/s^2"); +static_assert(unit_symbol(metre / square, {.denominator = always_solidus}) == "m/s²"); +static_assert(unit_symbol(metre / square, {.encoding = ascii, .denominator = always_solidus}) == "m/s^2"); +static_assert(unit_symbol(metre / square, {.denominator = always_negative}) == "m s⁻²"); +static_assert(unit_symbol(metre / square, {.encoding = ascii, .denominator = always_negative}) == "m s^-2"); +static_assert(unit_symbol(metre / square, {.denominator = always_negative, .separator = dot}) == "m⋅s⁻²"); +static_assert(unit_symbol(kilogram * metre / square) == "kg m/s²"); +static_assert(unit_symbol(kilogram * metre / square, {.separator = dot}) == "kg⋅m/s²"); +static_assert(unit_symbol(kilogram * metre / square, {.encoding = ascii}) == "kg m/s^2"); +static_assert(unit_symbol(kilogram * metre / square, {.denominator = always_solidus}) == "kg m/s²"); +static_assert(unit_symbol(kilogram * metre / square, {.encoding = ascii, .denominator = always_solidus}) == + "kg m/s^2"); +static_assert(unit_symbol(kilogram * metre / square, {.denominator = always_negative}) == "kg m s⁻²"); +static_assert(unit_symbol(kilogram * metre / square, {.encoding = ascii, .denominator = always_negative}) == + "kg m s^-2"); +static_assert(unit_symbol(kilogram * metre / square, {.denominator = always_negative, .separator = dot}) == + "kg⋅m⋅s⁻²"); +static_assert(unit_symbol(kilogram / metre / square) == "kg m⁻¹ s⁻²"); +static_assert(unit_symbol(kilogram / metre / square, {.separator = dot}) == "kg⋅m⁻¹⋅s⁻²"); +static_assert(unit_symbol(kilogram / metre / square, {.encoding = ascii}) == "kg m^-1 s^-2"); +static_assert(unit_symbol(kilogram / metre / square, {.denominator = always_solidus}) == "kg/(m s²)"); +static_assert(unit_symbol(kilogram / metre / square, {.encoding = ascii, .denominator = always_solidus}) == + "kg/(m s^2)"); +static_assert(unit_symbol(kilogram / metre / square, {.denominator = always_negative}) == "kg m⁻¹ s⁻²"); +static_assert(unit_symbol(kilogram / metre / square, {.encoding = ascii, .denominator = always_negative}) == + "kg m^-1 s^-2"); +static_assert(unit_symbol(kilogram / metre / square, {.denominator = always_negative, .separator = dot}) == + "kg⋅m⁻¹⋅s⁻²"); + +#endif // __cpp_lib_constexpr_string } // namespace From 7e18694790359f7a8ce2e811637322dab9d0cb86 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Sat, 22 Oct 2022 19:31:20 +0200 Subject: [PATCH 045/402] refactor: `gsl_Assert` replaced with `gsl_Expects` --- src/core/include/units/dimension.h | 2 +- src/core/include/units/unit.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/include/units/dimension.h b/src/core/include/units/dimension.h index 561f99c2..304e5910 100644 --- a/src/core/include/units/dimension.h +++ b/src/core/include/units/dimension.h @@ -266,7 +266,7 @@ template template [[nodiscard]] consteval Dimension auto operator/(int value, D) { - gsl_Assert(value == 1); + gsl_Expects(value == 1); return detail::expr_invert(detail::dim_type{}); } diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index a620c2cb..457ebab2 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -445,7 +445,7 @@ template template [[nodiscard]] consteval Unit auto operator/(int value, U u) { - gsl_Assert(value == 1); + gsl_Expects(value == 1); return detail::expr_invert(u); } @@ -678,7 +678,7 @@ constexpr Out unit_symbol_impl(Out out, const type_list& nums, const ty template Out, typename... Us> constexpr Out unit_symbol_impl(Out out, const derived_unit&, unit_symbol_formatting fmt, bool negative_power) { - gsl_Assert(negative_power == false); + gsl_Expects(negative_power == false); return unit_symbol_impl(out, typename derived_unit::_num_{}, typename derived_unit::_den_{}, fmt); } From b78abce0ae34f0ab6f00c0c716bd9fd0c9f3a6e9 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Sat, 22 Oct 2022 20:19:51 +0200 Subject: [PATCH 046/402] fix: invalid assertions fixed --- src/core/include/units/unit.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index 457ebab2..244621b7 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -516,12 +516,12 @@ constexpr Out copy(const basic_symbol_text& txt, text_encodi if (is_same_v) return copy(txt.unicode(), out).out; else - static_assert("Unicode text can't be copied to CharT output"); + throw std::invalid_argument("Unicode text can't be copied to CharT output"); } else { if (is_same_v) return copy(txt.ascii(), out).out; else - static_assert("ASCII text can't be copied to CharT output"); + throw std::invalid_argument("ASCII text can't be copied to CharT output"); } } From 08b7716f5191571aa33484e3adc0a82c34b2782e Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Sat, 22 Oct 2022 20:59:44 +0200 Subject: [PATCH 047/402] feat: `std::common_type` support for unit added --- src/core/include/units/magnitude.h | 7 +++--- src/core/include/units/unit.h | 36 +++++++++++++++++++++++++---- test/unit_test/static/unit_test.cpp | 36 +++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 8 deletions(-) diff --git a/src/core/include/units/magnitude.h b/src/core/include/units/magnitude.h index 234a16d5..52e4e789 100644 --- a/src/core/include/units/magnitude.h +++ b/src/core/include/units/magnitude.h @@ -679,6 +679,7 @@ template { return (magnitude<>{} * ... * remove_positive_power(magnitude{})); } + } // namespace detail // Base cases, for when either (or both) inputs are the identity. @@ -698,16 +699,16 @@ template { using detail::remove_positive_power; - if constexpr (get_base(H1) < get_base(H2)) { + if constexpr (detail::get_base(H1) < detail::get_base(H2)) { // When H1 has the smaller base, prepend to result from recursion. return remove_positive_power(magnitude

{}) * common_magnitude(magnitude{}, magnitude{}); - } else if constexpr (get_base(H2) < get_base(H1)) { + } else if constexpr (detail::get_base(H2) < detail::get_base(H1)) { // When H2 has the smaller base, prepend to result from recursion. return remove_positive_power(magnitude

{}) * common_magnitude(magnitude{}, magnitude{}); } else { // When the bases are equal, pick whichever has the lower power. constexpr auto common_tail = common_magnitude(magnitude{}, magnitude{}); - if constexpr (get_exponent(H1) < get_exponent(H2)) { + if constexpr (detail::get_exponent(H1) < detail::get_exponent(H2)) { return magnitude

{} * common_tail; } else { return magnitude

{} * common_tail; diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index 244621b7..2f899b34 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -395,12 +395,12 @@ using type_list_of_unit_less = expr_less; * Multiplication by `1` returns the same unit, otherwise `scaled_unit` is being returned. */ template -[[nodiscard]] consteval Unit auto operator*(M mag, U u) +[[nodiscard]] consteval Unit auto operator*(M mag, const U u) { if constexpr (mag == units::mag<1>) return u; else - return scaled_unit>{}; + return scaled_unit{}; } template @@ -700,16 +700,42 @@ template return buffer; } +namespace detail { + + +template +[[nodiscard]] consteval auto common_type_impl(const U1 u1, const U2 u2) +{ + if constexpr (U1{} == U2{}) { + if constexpr (std::derived_from) + return u1; + else + return u2; + } else { + constexpr auto canonical_lhs = detail::get_canonical_unit(U1{}); + constexpr auto canonical_rhs = detail::get_canonical_unit(U2{}); + + if constexpr (is_integral(canonical_lhs.mag / canonical_rhs.mag)) + return u2; + else if constexpr (is_integral(canonical_rhs.mag / canonical_lhs.mag)) + return u1; + else { + constexpr auto cm = common_magnitude(canonical_lhs.mag, canonical_rhs.mag); + return scaled_unit>{}; + } + } +} + +} // namespace detail + } // namespace units namespace std { -// TODO implement this template requires(units::convertible(U1{}, U2{})) struct common_type { - using type = ::units::conditional, std::remove_const_t>, - std::remove_const_t, std::remove_const_t>; + using type = std::remove_const_t; }; } // namespace std diff --git a/test/unit_test/static/unit_test.cpp b/test/unit_test/static/unit_test.cpp index 9d55eb61..eac02572 100644 --- a/test/unit_test/static/unit_test.cpp +++ b/test/unit_test/static/unit_test.cpp @@ -64,6 +64,10 @@ inline constexpr struct tonne_ : named_unit<"t", mag<1000> * kilogram> {} tonne; inline constexpr struct dalton_ : named_unit<"Da", mag * mag_power<10, -27> * kilogram> {} dalton; inline constexpr struct electronvolt_ : named_unit<"eV", mag * mag_power<10, -19> * joule> {} electronvolt; +inline constexpr struct yard_ : named_unit<"yd", mag * metre> {} yard; +inline constexpr struct foot_ : named_unit<"ft", mag * yard> {} foot; +inline constexpr struct mile_ : named_unit<"mi", mag<1760> * yard> {} mile; + inline constexpr struct kilometre_ : decltype(si::kilo) {} kilometre; inline constexpr struct kilojoule_ : decltype(si::kilo) {} kilojoule; // clang-format on @@ -353,6 +357,37 @@ static_assert(joule == newton * metre); static_assert(watt == joule / second); static_assert(watt == kilogram * square / cubic); +// common_type +static_assert(std::is_same_v, gram_>); +static_assert(std::is_same_v, kilogram_>); +static_assert(std::is_same_v), decltype(kilogram)>, kilogram_>); +static_assert(std::is_same_v)>, kilogram_>); +static_assert(std::is_same_v * gram), decltype(kilogram)>, kilogram_>); +static_assert(std::is_same_v * gram)>, kilogram_>); +static_assert(std::is_same_v, hertz_>); +static_assert(std::is_same_v, hertz_>); +static_assert(std::is_same_v, gram_>); +static_assert(std::is_same_v, gram_>); +static_assert(std::is_same_v, second_>); +static_assert(std::is_same_v, second_>); +static_assert(std::is_same_v, minute_>); +static_assert(std::is_same_v, minute_>); +static_assert(std::is_same_v), decltype(si::milli)>, + std::remove_const_t)>>); +static_assert(std::is_same_v), decltype(si::kilo)>, + std::remove_const_t)>>); +static_assert(std::is_same_v, yard_>); +static_assert(std::is_same_v, yard_>); +// TODO The below have long/unreadable magnitude types +static_assert(std::is_same_v, + scaled_unit, derived_unit>>>); +static_assert(std::is_same_v, + scaled_unit, derived_unit>>>); +static_assert( + std::is_same_v, scaled_unit, metre_>>); +static_assert( + std::is_same_v, scaled_unit, metre_>>); + // unit symbols #ifdef __cpp_lib_constexpr_string @@ -379,6 +414,7 @@ static_assert(unit_symbol(mag<100> * metre, {.encoding = ascii}) == "x 10^2 m"); static_assert(unit_symbol(mag<60> * second) == "[6 × 10¹] s"); static_assert(unit_symbol(mag<60> * second, {.encoding = ascii}) == "[6 x 10^1] s"); +// derived units static_assert(unit_symbol(one) == ""); static_assert(unit_symbol(square) == "m²"); static_assert(unit_symbol(square, {.encoding = ascii}) == "m^2"); From 9bfe75ebf642c616792aad1c71529fb88d65aa97 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Sat, 22 Oct 2022 21:05:14 +0200 Subject: [PATCH 048/402] feat: `harmonic_` concept enabled --- src/core/include/units/quantity.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/include/units/quantity.h b/src/core/include/units/quantity.h index afcb74de..f48c3d7f 100644 --- a/src/core/include/units/quantity.h +++ b/src/core/include/units/quantity.h @@ -64,8 +64,8 @@ concept safe_convertible_to_ = // exposition only // QFrom ratio is an exact multiple of QTo template concept harmonic_ = // exposition only - true; // TODO fix it when magnitudes are ready -// Quantity && Quantity && is_integral(detail::quantity_magnitude / detail::quantity_magnitude); + Quantity && Quantity && + is_integral(detail::get_canonical_unit(QFrom::unit).mag / detail::get_canonical_unit(QTo::unit).mag); template concept quantity_convertible_to_ = // exposition only From e7bebac2a74eb6f1d7ac5627fc13378f67e19b64 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Sun, 23 Oct 2022 10:47:12 +0200 Subject: [PATCH 049/402] feat: `power()` support added for dimensions and units --- .../include/units/bits/expression_template.h | 42 ++++++++++++++++--- src/core/include/units/dimension.h | 22 ++++++++++ src/core/include/units/unit.h | 27 ++++++++++++ test/unit_test/static/dimension_test.cpp | 15 +++++++ test/unit_test/static/unit_test.cpp | 24 +++++++++++ 5 files changed, 124 insertions(+), 6 deletions(-) diff --git a/src/core/include/units/bits/expression_template.h b/src/core/include/units/bits/expression_template.h index 07dac42c..b2bdee1e 100644 --- a/src/core/include/units/bits/expression_template.h +++ b/src/core/include/units/bits/expression_template.h @@ -112,13 +112,17 @@ inline constexpr bool is_specialization_of_power> = true; template consteval auto power_or_T_impl() { - if constexpr (R.den == 1) { - if constexpr (R.num == 1) - return T{}; - else - return power{}; + if constexpr (is_specialization_of_power) { + return power_or_T_impl(); } else { - return power{}; + if constexpr (R.den == 1) { + if constexpr (R.num == 1) + return T{}; + else + return power{}; + } else { + return power{}; + } } }; @@ -437,6 +441,32 @@ template typename To, typename OneType, typename T> return To>{}; } + +template typename To, typename OneType, + template typename Pred, typename... Nums, typename... Dens> + requires detail::non_zero +[[nodiscard]] consteval auto expr_pow_impl(type_list, type_list) +{ + return detail::get_optimized_expression...>, + type_list...>, OneType, Pred, To>(); +} + + +/** + * @brief Computes the value of an expression raised to the `Num/Den` power + * + * @tparam Num Exponent numerator + * @tparam Den Exponent denominator + * @tparam T Expression being the base of the operation + */ +template typename To, typename OneType, + template typename Pred, typename T> + requires detail::non_zero +[[nodiscard]] consteval auto expr_pow(T) +{ + return expr_pow_impl(typename T::_num_{}, typename T::_den_{}); +} + } // namespace detail } // namespace units diff --git a/src/core/include/units/dimension.h b/src/core/include/units/dimension.h index 304e5910..742148fb 100644 --- a/src/core/include/units/dimension.h +++ b/src/core/include/units/dimension.h @@ -285,6 +285,28 @@ template return std::derived_from || std::derived_from; } +/** + * @brief Computes the value of a dimension raised to the `Num/Den` power + * + * @tparam Num Exponent numerator + * @tparam Den Exponent denominator + * @param d Dimension being the base of the operation + * + * @return Dimension The result of computation + */ +template + requires detail::non_zero +[[nodiscard]] consteval Dimension auto pow(D d) +{ + if constexpr (BaseDimension) { + if constexpr (Den == 1) + return derived_dimension>{}; + else + return derived_dimension>{}; + } else + return detail::expr_pow(d); +} + // TODO consider adding the support for text output of the dimensional equation } // namespace units diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index 2f899b34..31604c86 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -471,6 +471,33 @@ template return is_same_v; } + +/** + * @brief Computes the value of a unit raised to the `Num/Den` power + * + * @tparam Num Exponent numerator + * @tparam Den Exponent denominator + * @param u Unit being the base of the operation + * + * @return Unit The result of computation + */ +template + requires detail::non_zero +[[nodiscard]] consteval Unit auto pow(U u) +{ + if constexpr (requires { U::symbol; }) { + if constexpr (Den == 1) + return derived_unit>{}; + else + return derived_unit>{}; + } else if constexpr (detail::is_specialization_of_scaled_unit) { + return scaled_unit(U::mag), std::remove_const_t(U::reference_unit))>>{}; + } else { + return detail::expr_pow(u); + } +} + + // Helper variable templates to create common powers template inline constexpr decltype(U * U) square; diff --git a/test/unit_test/static/dimension_test.cpp b/test/unit_test/static/dimension_test.cpp index 00d68473..25cb5c3d 100644 --- a/test/unit_test/static/dimension_test.cpp +++ b/test/unit_test/static/dimension_test.cpp @@ -207,4 +207,19 @@ static_assert(!convertible(length_dim, time_dim)); static_assert(acceleration_dim != speed_dim); static_assert(!convertible(acceleration_dim, speed_dim)); +// power +static_assert(is_of_type(length_dim), derived_dimension>>); +static_assert(is_of_type(length_dim), derived_dimension>>); +static_assert(is_of_type(length_dim* length_dim), length_dim_>); +static_assert(is_of_type(length_dim* length_dim* length_dim), length_dim_>); +static_assert(is_of_type(length_dim* length_dim), derived_dimension>>); +static_assert(is_of_type(length_dim / time_dim), + derived_dimension, per>>>); +static_assert(is_of_type(length_dim / (time_dim * time_dim)), + derived_dimension, per>>); + +static_assert(is_same_v(length_dim)), decltype(length_dim * length_dim)>); +static_assert( + is_same_v(length_dim / time_dim)), decltype(length_dim * length_dim / time_dim / time_dim)>); + } // namespace diff --git a/test/unit_test/static/unit_test.cpp b/test/unit_test/static/unit_test.cpp index eac02572..9df7d453 100644 --- a/test/unit_test/static/unit_test.cpp +++ b/test/unit_test/static/unit_test.cpp @@ -357,6 +357,30 @@ static_assert(joule == newton * metre); static_assert(watt == joule / second); static_assert(watt == kilogram * square / cubic); +// power +static_assert(is_same_v(metre)), decltype(metre * metre)>); +static_assert(is_same_v(kilometre)), decltype(kilometre * kilometre)>); +static_assert(is_same_v(si::kilo)), decltype(si::kilo * si::kilo)>); +static_assert(is_same_v(hour)), decltype(hour * hour)>); +static_assert(is_same_v(mag<3600> * second)), decltype((mag<3600> * second) * (mag<3600> * second))>); +static_assert(is_same_v(metre / second)), decltype(metre * metre / second / second)>); +static_assert(is_same_v(kilometre / hour)), decltype(kilometre * kilometre / hour / hour)>); + +static_assert(is_of_type(metre), derived_unit>>); +static_assert(is_of_type(metre), derived_unit>>); +static_assert(is_of_type(metre* metre), metre_>); +static_assert(is_of_type(metre* metre* metre), metre_>); +static_assert(is_of_type(metre* metre), derived_unit>>); +static_assert(is_of_type(metre / second), derived_unit, per>>>); +static_assert(is_of_type(metre / (second * second)), derived_unit, per>>); +static_assert(is_of_type>>); + +static_assert(is_of_type(kilometre), derived_unit>>); +static_assert(is_of_type(si::kilo), derived_unit, 2>>>); +static_assert(is_of_type(hour), derived_unit>>); +static_assert( + is_of_type(mag<3600>* second), scaled_unit * mag<3600>, derived_unit>>>); + // common_type static_assert(std::is_same_v, gram_>); static_assert(std::is_same_v, kilogram_>); From 8dcdc7bdacca24e8e7451f3196b692fc1ed7e181 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Sun, 23 Oct 2022 22:19:44 +0200 Subject: [PATCH 050/402] fix: printing of symbols with fractional powers fixed --- src/core/include/units/unit.h | 4 ++-- test/unit_test/static/unit_test.cpp | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index 31604c86..31cd3827 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -642,8 +642,8 @@ constexpr auto unit_symbol_impl(Out out, const power&, unit_symb constexpr ratio r = power::exponent; if constexpr (r.den != 1) { // add root part - constexpr auto txt = txt + basic_fixed_string("^(") + regular() + basic_fixed_string("/") + - regular() + basic_fixed_string(")"); + constexpr auto txt = basic_fixed_string("^(") + regular() + basic_fixed_string("/") + regular() + + basic_fixed_string(")"); return copy(txt, fmt.encoding, out); } else if constexpr (r.num != 1) { // add exponent part diff --git a/test/unit_test/static/unit_test.cpp b/test/unit_test/static/unit_test.cpp index 9df7d453..987df90b 100644 --- a/test/unit_test/static/unit_test.cpp +++ b/test/unit_test/static/unit_test.cpp @@ -478,6 +478,10 @@ static_assert(unit_symbol(kilogram / metre / square, {.encoding = ascii, "kg m^-1 s^-2"); static_assert(unit_symbol(kilogram / metre / square, {.denominator = always_negative, .separator = dot}) == "kg⋅m⁻¹⋅s⁻²"); +static_assert(unit_symbol(pow<123>(metre)) == "m¹²³"); +static_assert(unit_symbol(pow<1, 2>(metre)) == "m^(1/2)"); +static_assert(unit_symbol(pow<3, 5>(metre)) == "m^(3/5)"); +static_assert(unit_symbol(pow<1, 2>(metre / second)) == "m^(1/2)/s^(1/2)"); #endif // __cpp_lib_constexpr_string From cb861dd81a168f135e073997a4c990d43e7344aa Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 25 Oct 2022 07:27:08 +0200 Subject: [PATCH 051/402] feat: system's definition highly simplified by removing the need for a `system_reference` for most cases --- example/v2_framework.cpp | 199 +++++++------ src/core/include/units/bits/basic_concepts.h | 6 +- .../include/units/bits/expression_template.h | 41 +++ src/core/include/units/dimension.h | 265 +++++++++++------ src/core/include/units/quantity.h | 4 +- src/core/include/units/reference.h | 3 - src/core/include/units/unit.h | 94 +++++- .../isq/include/units/isq/base_dimensions.h | 16 +- src/systems/isq/include/units/isq/mechanics.h | 76 ++--- .../isq/include/units/isq/space_and_time.h | 70 +++-- .../isq/include/units/isq/thermodynamics.h | 9 +- src/systems/si-cgs/include/units/si/cgs/cgs.h | 10 - src/systems/si/CMakeLists.txt | 14 +- .../si/include/units/si/base_quantities.h | 43 --- src/systems/si/include/units/si/constants.h | 12 +- src/systems/si/include/units/si/mechanics.h | 68 ----- src/systems/si/include/units/si/si.h | 4 - .../si/include/units/si/space_and_time.h | 64 ---- .../si/include/units/si/thermodynamics.h | 39 --- src/systems/si/include/units/si/units.h | 17 +- test/unit_test/static/CMakeLists.txt | 3 - test/unit_test/static/dimension_test.cpp | 281 +++++++++--------- test/unit_test/static/test_tools.h | 202 +++++++------ test/unit_test/static/unit_test.cpp | 19 +- 24 files changed, 779 insertions(+), 780 deletions(-) delete mode 100644 src/systems/si/include/units/si/base_quantities.h delete mode 100644 src/systems/si/include/units/si/mechanics.h delete mode 100644 src/systems/si/include/units/si/space_and_time.h delete mode 100644 src/systems/si/include/units/si/thermodynamics.h diff --git a/example/v2_framework.cpp b/example/v2_framework.cpp index abc075cd..04a88915 100644 --- a/example/v2_framework.cpp +++ b/example/v2_framework.cpp @@ -28,8 +28,7 @@ using namespace units; using namespace units::si::unit_symbols; // clang-format off -inline constexpr struct activity_dim : decltype(1 / isq::time_dim) {} activity_dim; -inline constexpr struct activity : system_reference {} activity; +DERIVED_DIMENSION(activity, decltype(1 / isq::time)); // clang-format on // check for invalid prefixes @@ -46,85 +45,84 @@ static_assert(can_not_be_prefixed); static_assert(can_not_be_prefixed); // Named quantity/dimension and unit -static_assert( - is_same_v{}, int>>); +static_assert(is_same_v{}, int>>); // Named quantity/dimension and derived (unnamed) unit static_assert( - is_same_v>>{}, int>>); + is_same_v>>{}, int>>); // Derived (unnamed) quantity/dimension and derived (unnamed) unit -static_assert(is_same_v>, +static_assert(is_same_v>, derived_unit>>{}, int>>); // Base quantity as a result of dimensional transformation -static_assert(is_same_v{}, int>>); +static_assert(is_same_v{}, int>>); // Dimensionless -static_assert(is_same_v{}, int>>); +static_assert(is_same_v{}, int>>); // Comparisons // Same dimension type & different unit -// static_assert(1000 * si::length[m] == 1 * si::length[km]); +// static_assert(1000 * isq::length[m] == 1 * isq::length[km]); // Named and derived dimensions (same units) -static_assert(10 * si::length[m] / (2 * si::time[s]) == 5 * si::speed[m / s]); -static_assert(5 * si::speed[m / s] == 10 * si::length[m] / (2 * si::time[s])); +static_assert(10 * isq::length[m] / (2 * isq::time[s]) == 5 * isq::speed[m / s]); +static_assert(5 * isq::speed[m / s] == 10 * isq::length[m] / (2 * isq::time[s])); // Same named dimension & different but equivalent unit -static_assert(10 * si::frequency[1 / s] == 10 * si::frequency[Hz]); -static_assert(10 * si::frequency[Hz] == 10 * si::frequency[1 / s]); +static_assert(10 * isq::frequency[1 / s] == 10 * isq::frequency[Hz]); +static_assert(10 * isq::frequency[Hz] == 10 * isq::frequency[1 / s]); // Named and derived dimensions (different but equivalent units) -static_assert(10 / (2 * si::time[s]) == 5 * si::frequency[Hz]); -static_assert(5 * si::frequency[Hz] == 10 / (2 * si::time[s])); -static_assert(5 * si::force[N] * (2 * si::length[m]) == 10 * si::energy[J]); -static_assert(10 * si::energy[J] == 5 * si::force[N] * (2 * si::length[m])); +static_assert(10 / (2 * isq::time[s]) == 5 * isq::frequency[Hz]); +static_assert(5 * isq::frequency[Hz] == 10 / (2 * isq::time[s])); +static_assert(5 * isq::force[N] * (2 * isq::length[m]) == 10 * isq::energy[J]); +static_assert(10 * isq::energy[J] == 5 * isq::force[N] * (2 * isq::length[m])); // Different named dimensions template concept invalid_comparison = !requires { 2 * R1 == 2 * R2; } && !requires { 2 * R2 == 2 * R1; }; -static_assert(invalid_comparison); +static_assert(invalid_comparison); // Arithmetics // Named and derived dimensions (same units) -static_assert(10 * si::length[m] / (2 * si::time[s]) + 5 * si::speed[m / s] == 10 * si::speed[m / s]); -static_assert(5 * si::speed[m / s] + 10 * si::length[m] / (2 * si::time[s]) == 10 * si::speed[m / s]); -static_assert(10 * si::length[m] / (2 * si::time[s]) - 5 * si::speed[m / s] == 0 * si::speed[m / s]); -static_assert(5 * si::speed[m / s] - 10 * si::length[m] / (2 * si::time[s]) == 0 * si::speed[m / s]); +static_assert(10 * isq::length[m] / (2 * isq::time[s]) + 5 * isq::speed[m / s] == 10 * isq::speed[m / s]); +static_assert(5 * isq::speed[m / s] + 10 * isq::length[m] / (2 * isq::time[s]) == 10 * isq::speed[m / s]); +static_assert(10 * isq::length[m] / (2 * isq::time[s]) - 5 * isq::speed[m / s] == 0 * isq::speed[m / s]); +static_assert(5 * isq::speed[m / s] - 10 * isq::length[m] / (2 * isq::time[s]) == 0 * isq::speed[m / s]); static_assert( - is_same_v>>{}, int>>); + is_same_v>>{}, int>>); static_assert( - is_same_v>>{}, int>>); + is_same_v>>{}, int>>); static_assert( - is_same_v>>{}, int>>); + is_same_v>>{}, int>>); static_assert( - is_same_v>>{}, int>>); + is_same_v>>{}, int>>); // Named and derived dimensions (different units) -static_assert(10 / (2 * si::time[s]) + 5 * si::frequency[Hz] == 10 * si::frequency[Hz]); -static_assert(5 * si::frequency[Hz] + 10 / (2 * si::time[s]) == 10 * si::frequency[Hz]); -static_assert(10 / (2 * si::time[s]) - 5 * si::frequency[Hz] == 0 * si::frequency[Hz]); -static_assert(5 * si::frequency[Hz] - 10 / (2 * si::time[s]) == 0 * si::frequency[Hz]); -static_assert(is_same_v{}, int>>); -static_assert(is_same_v{}, int>>); -static_assert(is_same_v{}, int>>); -static_assert(is_same_v{}, int>>); +static_assert(10 / (2 * isq::time[s]) + 5 * isq::frequency[Hz] == 10 * isq::frequency[Hz]); +static_assert(5 * isq::frequency[Hz] + 10 / (2 * isq::time[s]) == 10 * isq::frequency[Hz]); +static_assert(10 / (2 * isq::time[s]) - 5 * isq::frequency[Hz] == 0 * isq::frequency[Hz]); +static_assert(5 * isq::frequency[Hz] - 10 / (2 * isq::time[s]) == 0 * isq::frequency[Hz]); +static_assert(is_same_v{}, int>>); +static_assert(is_same_v{}, int>>); +static_assert(is_same_v{}, int>>); +static_assert(is_same_v{}, int>>); // Different named dimensions template @@ -132,50 +130,49 @@ consteval bool invalid_arithmetic(Ts... ts) { return !requires { (... + ts); } && !requires { (... - ts); }; } -static_assert(invalid_arithmetic(5 * activity[Bq], 5 * si::frequency[Hz])); -static_assert(invalid_arithmetic(5 * activity[Bq], 10 / (2 * si::time[s]), 5 * si::frequency[Hz])); +static_assert(invalid_arithmetic(5 * activity[Bq], 5 * isq::frequency[Hz])); +static_assert(invalid_arithmetic(5 * activity[Bq], 10 / (2 * isq::time[s]), 5 * isq::frequency[Hz])); // Implicit conversions allowed between quantities of `convertible` references -constexpr quantity speed = 120 * si::length[km] / (2 * si::time[h]); +constexpr quantity speed = 120 * isq::length[km] / (2 * isq::time[h]); // Explicit casts allow changing all or only a part of the type static_assert( - std::is_same_v< - decltype(quantity_cast(120 * si::length[km] / (2 * si::time[h]))), - quantity)>, per>>{}, - int>>); -auto q3 = quantity_cast(120 * si::length[km] / (2 * si::time[h])); -auto q4 = quantity_cast(120 * si::length[km] / (2 * si::time[h])); -auto q5 = quantity_cast(120 * si::length[km] / (2 * si::time[h])); -auto q6 = quantity_cast>(120 * si::length[km] / (2 * si::time[h])); + std::is_same_v(120 * isq::length[km] / (2 * isq::time[h]))), + quantity)>, + per>>{}, + int>>); +auto q3 = quantity_cast(120 * isq::length[km] / (2 * isq::time[h])); +auto q4 = quantity_cast(120 * isq::length[km] / (2 * isq::time[h])); +auto q5 = quantity_cast(120 * isq::length[km] / (2 * isq::time[h])); +auto q6 = quantity_cast>(120 * isq::length[km] / (2 * isq::time[h])); -// cast 1 / time_dim to use Hz +// cast 1 / time to use Hz -// static_assert(quantity_of); -// static_assert(quantity_of); -// static_assert(quantity_of); -// static_assert(!quantity_of); +// static_assert(quantity_of); +// static_assert(quantity_of); +// static_assert(quantity_of); +// static_assert(!quantity_of); -// quantity>>, int> s = 5 * speed[m / s]; -// quantity>, derived_unit>>, int> q = -// 10 * length[m] / (2 * si::time[s]); +// quantity>>, int> s = 5 * speed[m / s]; +// quantity>, derived_unit>>, int> q = +// 10 * length[m] / (2 * isq::time[s]); -// auto q1 = 10 * length[m] / (2 * si::time[s]) + 5 * speed[m / s]; // should this be allowed? -// bool b1 = (10 * length[m] / (2 * si::time[s]) == 5 * speed[m / s]); // should this be allowed? +// auto q1 = 10 * length[m] / (2 * isq::time[s]) + 5 * speed[m / s]; // should this be allowed? +// bool b1 = (10 * length[m] / (2 * isq::time[s]) == 5 * speed[m / s]); // should this be allowed? -// auto q2 = 10 / (2 * si::time[s]) + 5 * frequency[Hz]; // should this be allowed? -// bool b2 = (10 / (2 * si::time[s]) == 5 * frequency[Hz]); // should this be allowed? +// auto q2 = 10 / (2 * isq::time[s]) + 5 * frequency[Hz]; // should this be allowed? +// bool b2 = (10 / (2 * isq::time[s]) == 5 * frequency[Hz]); // should this be allowed? // auto q3 = 5 * activity[Bq] + 5 * frequency[Hz]; // should this be allowed? // auto b3 = (5 * activity[Bq] == 5 * frequency[Hz]); // should this be allowed? -// auto q4 = 5 * activity[Bq] + 10 / (2 * si::time[s]) + 5 * frequency[Hz]; // should this be allowed? +// auto q4 = 5 * activity[Bq] + 10 / (2 * isq::time[s]) + 5 * frequency[Hz]; // should this be allowed? -// auto q5 = 120 * length[km] / (2 * si::time[h]); // not speed -// auto q6 = quantity_cast(120 * length[km] / (2 * si::time[h])); -// auto q7 = quantity_cast(120 * length[km] / (2 * si::time[h])); +// auto q5 = 120 * length[km] / (2 * isq::time[h]); // not speed +// auto q6 = quantity_cast(120 * length[km] / (2 * isq::time[h])); +// auto q7 = quantity_cast(120 * length[km] / (2 * isq::time[h])); // quantity s = q5; // should this implicit conversion be allowed? } // namespace @@ -192,10 +189,12 @@ namespace units::isq::si { // quantity tests // static_assert( -// is_exactly_quantity_of>>); +// is_exactly_quantity_of>>); -// static_assert(QuantityOf>); -// static_assert(QuantityOf>); +// static_assert(QuantityOf>); static_assert(QuantityOf>); // // TODO Should this compile? } // namespace units::isq::si @@ -205,21 +204,37 @@ namespace units::isq::si { // using namespace units::si::unit_symbols; // /* Frequency */ auto freq1 = 20 * frequency[Hz]; -// // /* Frequency */ auto freq2 = 20 / (1 * si::time[s]); +// // /* Frequency */ auto freq2 = 20 / (1 * isq::time[s]); // quantity freq3(20); // quantity freq4(20); -// quantity freq5(20); +// quantity freq5(20); // /* Speed */ auto speed1 = 20 * speed[m / s]; -// /* Speed */ auto speed2 = 20 * (length[m] / si::time[s]); +// /* Speed */ auto speed2 = 20 * (length[m] / isq::time[s]); // quantity speed3(20); -// quantity speed4(20); +// quantity speed4(20); -// constexpr auto avg_speed(quantity d, quantity t) { return d / t; } +// constexpr auto avg_speed(quantity d, quantity t) { return d / t; } + +#include int main() { + using enum text_encoding; + using enum unit_symbol_denominator; + using enum unit_symbol_separator; + + std::cout << unit_symbol(si::kilogram / si::metre / square, {.denominator = always_solidus}) << "\n"; + // std::cout << unit_symbol(si::metre / si::second, {.denominator = unit_symbol_denominator::always_negative}) << + // "\n"; std::cout << unit_symbol(si::metre / si::second, {.denominator = unit_symbol_denominator::always_negative}) + // << + // "\n"; + // static_assert(unit_symbol(metre / second, {.denominator = always_negative, .separator = dot}) == "m⋅s⁻¹"); + + // std::cout << get_unit_symbol(si::minute / square).standard().c_str() << "\n"; + // std::cout << get_unit_symbol(si::joule / si::minute).standard().c_str() << "\n"; + // print(); // print(); // // print(); @@ -239,19 +254,19 @@ int main() // joule * erg??? // joule / erg??? -// auto d1 = 42 * isq::length_dim[si::kilo]; -// auto d2 = 42 * isq::length_dim[cgs::centimetre]; +// auto d1 = 42 * isq::length[si::kilo]; +// auto d2 = 42 * isq::length[cgs::centimetre]; -// auto s1 = 42 * isq::speed_dim[si::metre / si::second]; -// auto s2 = 42 * isq::speed_dim[cgs::centimetre / si::second]; -// auto e1 = 42 * isq::energy_dim[si::joule]; -// auto e2 = 42 * isq::energy_dim[cgs::erg]; -// auto e2_bad = 42 * isq::energy_dim[cgs::erg / si::second]; -// auto p1 = 42 * isq::power_dim[si::watt]; -// auto p2 = 42 * isq::power_dim[cgs::erg / si::second]; +// auto s1 = 42 * isq::speed[si::metre / si::second]; +// auto s2 = 42 * isq::speed[cgs::centimetre / si::second]; +// auto e1 = 42 * isq::energy[si::joule]; +// auto e2 = 42 * isq::energy[cgs::erg]; +// auto e2_bad = 42 * isq::energy[cgs::erg / si::second]; +// auto p1 = 42 * isq::power[si::watt]; +// auto p2 = 42 * isq::power[cgs::erg / si::second]; // type of Rep{1} * (mag * mag_power<10, -34> * energy[joule] * time[second]) // and inline constexpr auto planck_constant = Rep{1} * mag_planck * energy[joule] * time[second]; -// quantity_cast on equivalent dimensions \ No newline at end of file +// quantity_cast on equivalent dimensions diff --git a/src/core/include/units/bits/basic_concepts.h b/src/core/include/units/bits/basic_concepts.h index ac073b28..9cea3de7 100644 --- a/src/core/include/units/bits/basic_concepts.h +++ b/src/core/include/units/bits/basic_concepts.h @@ -102,7 +102,11 @@ template concept AliasUnit = requires(T* t) { detail::to_base_alias_unit(t); }; // BaseDimension -template +#ifdef __cpp_explicit_this_parameter__ +template +#else +template +#endif struct base_dimension; namespace detail { diff --git a/src/core/include/units/bits/expression_template.h b/src/core/include/units/bits/expression_template.h index b2bdee1e..63264d69 100644 --- a/src/core/include/units/bits/expression_template.h +++ b/src/core/include/units/bits/expression_template.h @@ -457,6 +457,9 @@ template typename To * * @tparam Num Exponent numerator * @tparam Den Exponent denominator + * @tparam To destination type list to put the result to + * @tparam OneType type that represents the value `1` + * @tparam Pred binary less then predicate * @tparam T Expression being the base of the operation */ template typename To, typename OneType, @@ -467,6 +470,44 @@ template typename To return expr_pow_impl(typename T::_num_{}, typename T::_den_{}); } + +// expr_map + +template typename Proj> +struct expr_type_map { + using type = Proj; +}; + +template typename Proj> +struct expr_type_map, Proj> { + using type = power, Ints...>; +}; + +template typename Proj, template typename To, typename OneType, + template typename Pred, typename... Nums, typename... Dens> +[[nodiscard]] consteval auto expr_map_impl(type_list, type_list) +{ + using nums = type_list_sort::type...>, Pred>; + using dens = type_list_sort::type...>, Pred>; + return detail::get_optimized_expression(); +} + +/** + * @brief Maps contents of one expression template to another resulting in a different type list + * + * @tparam Proj Projection to be used for mapping + * @tparam To destination type list to put the result to + * @tparam OneType type that represents the value `1` + * @tparam Pred binary less then predicate + * @tparam T expression template to map from + */ +template typename Proj, template typename To, typename OneType, + template typename Pred, typename T> +[[nodiscard]] consteval auto expr_map(T) +{ + return expr_map_impl(typename T::_num_{}, typename T::_den_{}); +} + } // namespace detail } // namespace units diff --git a/src/core/include/units/dimension.h b/src/core/include/units/dimension.h index 742148fb..63d99316 100644 --- a/src/core/include/units/dimension.h +++ b/src/core/include/units/dimension.h @@ -25,64 +25,10 @@ #include #include #include +#include namespace units { -/** - * @brief A dimension of a base quantity - * - * Base quantity is a quantity in a conventionally chosen subset of a given system of quantities, where no quantity - * in the subset can be expressed in terms of the other quantities within that subset. They are referred to as - * being mutually independent since a base quantity cannot be expressed as a product of powers of the other base - * quantities. - * - * Symbol template parameters is an unique identifier of the base dimension. The same identifiers can be multiplied - * and divided which will result with an adjustment of its factor in an exponent of a derived_dimension - * (in case of zero the dimension will be simplified and removed from further analysis of current expresion). - * - * User should derive a strong type from this class template rather than use it directly in the source code. - * For example: - * - * @code{.cpp} - * inline constexpr struct length_dim : base_dimension<"L"> {} length_dim; - * inline constexpr struct time_dim : base_dimension<"T"> {} time_dim; - * inline constexpr struct mass_dim : base_dimension<"M"> {} mass_dim; - * @endcode - * - * @note A common convention in this library is to assign the same name for a type and an object of this type. - * Besides defining them user never works with the dimension types in the source code. All operations - * are done on the objects. Contrarily, the dimension types are the only one visible in the compilation - * errors. Having them of the same names improves user experience and somehow blurs those separate domains. - * - * @tparam Symbol an unique identifier of the base dimension used to provide dimensional analysis support - */ -template -struct base_dimension { - static constexpr auto symbol = Symbol; ///< Unique base dimension identifier -}; - -namespace detail { - -template -void to_base_base_dimension(const volatile base_dimension*); - -template -inline constexpr bool is_specialization_of_base_dimension = false; - -template -inline constexpr bool is_specialization_of_base_dimension> = true; - -} // namespace detail - -/** - * @brief A concept matching all named base dimensions in the library. - * - * Satisfied by all dimension types derived from a specialization of `base_dimension`. - */ -template -concept BaseDimension = requires(T* t) { detail::to_base_base_dimension(t); } && - (!detail::is_specialization_of_base_dimension); - namespace detail { template @@ -107,6 +53,66 @@ concept DerivedDimension = detail::is_derived_dimension; template concept Dimension = BaseDimension || DerivedDimension; + +namespace detail { + +[[nodiscard]] consteval Dimension auto get_dimension_for(Unit auto); + +} + +template +struct reference; + +/** + * @brief A dimension of a base quantity + * + * Base quantity is a quantity in a conventionally chosen subset of a given system of quantities, where no quantity + * in the subset can be expressed in terms of the other quantities within that subset. They are referred to as + * being mutually independent since a base quantity cannot be expressed as a product of powers of the other base + * quantities. + * + * Symbol template parameters is an unique identifier of the base dimension. The same identifiers can be multiplied + * and divided which will result with an adjustment of its factor in an exponent of a derived_dimension + * (in case of zero the dimension will be simplified and removed from further analysis of current expresion). + * + * User should derive a strong type from this class template rather than use it directly in the source code. + * For example: + * + * @code{.cpp} + * inline constexpr struct length : base_dimension<"L"> {} length; + * inline constexpr struct time : base_dimension<"T"> {} time; + * inline constexpr struct mass : base_dimension<"M"> {} mass; + * @endcode + * + * @note A common convention in this library is to assign the same name for a type and an object of this type. + * Besides defining them user never works with the dimension types in the source code. All operations + * are done on the objects. Contrarily, the dimension types are the only one visible in the compilation + * errors. Having them of the same names improves user experience and somehow blurs those separate domains. + * + * @tparam Symbol an unique identifier of the base dimension used to provide dimensional analysis support + */ +#ifdef __cpp_explicit_this_parameter__ +template +#else +template +#endif +struct base_dimension { + static constexpr auto symbol = Symbol; ///< Unique base dimension identifier + +#ifdef __cpp_explicit_this_parameter__ + template + requires(convertible(Self{}, detail::get_dimension_for(U{}))) + [[nodiscard]] constexpr reference operator[](this const Self, U) +#else + template + requires(convertible(Self{}, detail::get_dimension_for(U{}))) + [[nodiscard]] constexpr reference operator[](U) const +#endif + { + return {}; + } +}; + namespace detail { template @@ -116,12 +122,13 @@ template using type_list_of_base_dimension_less = expr_less; template -inline constexpr bool is_one_dim = false; +inline constexpr bool is_dimensionless = false; template inline constexpr bool is_power_of_dim = requires { - requires is_specialization_of_power && (BaseDimension || is_one_dim); + requires is_specialization_of_power && + (BaseDimension || is_dimensionless); }; template @@ -129,15 +136,15 @@ inline constexpr bool is_per_of_dims = false; template inline constexpr bool is_per_of_dims> = - (... && (BaseDimension || is_one_dim || is_power_of_dim)); + (... && (BaseDimension || is_dimensionless || is_power_of_dim)); } // namespace detail template concept DerivedDimensionSpec = - BaseDimension || detail::is_one_dim || detail::is_power_of_dim || detail::is_per_of_dims; + BaseDimension || detail::is_dimensionless || detail::is_power_of_dim || detail::is_per_of_dims; -template +template struct derived_dimension; namespace detail { @@ -160,47 +167,83 @@ struct derived_dimension_impl : detail::expr_fractions, Ds.. * more digestable for the user. The positive exponents are ordered first and all negative exponents are put as a list * into the `per<...>` class template. If a power of exponent is different than `1` the dimension type is enclosed in * `power` class template. Otherwise, it is just put directly in the list without any wrapper. There - * is also one special case. In case all of the exponents are negative than the `one_dim` being a dimension of + * is also one special case. In case all of the exponents are negative than the `dimensionless` being a dimension of * a dimensionless quantity is put in the front to increase the readability. * * For example: * * @code{.cpp} - * inline constexpr struct frequency_dim : decltype(1 / time_dim) {} frequency_dim; - * inline constexpr struct speed_dim : decltype(length_dim / time_dim) {} speed_dim; - * inline constexpr struct acceleration_dim : decltype(speed_dim / time_dim) {} acceleration_dim; - * inline constexpr struct force_dim : decltype(mass_dim * acceleration_dim) {} force_dim; - * inline constexpr struct energy_dim : decltype(force_dim * length_dim) {} energy_dim; - * inline constexpr struct moment_of_force_dim : decltype(length_dim * force_dim) {} moment_of_force_dim; - * inline constexpr struct torque_dim : decltype(moment_of_force_dim) {} torque_dim; + * DERIVED_DIMENSION(frequency, 1 / time); + * DERIVED_DIMENSION(speed, length / time); + * DERIVED_DIMENSION(acceleration, speed / time); + * DERIVED_DIMENSION(force, mass * acceleration); + * DERIVED_DIMENSION(energy, force * length); + * DERIVED_DIMENSION(moment_of_force, length * force); + * DERIVED_DIMENSION(torque, moment_of_force); * @endcode * - * - `frequency_dim` will be derived from type `derived_dimension>` - * - `speed_dim` will be derived from type `derived_dimension>` - * - `acceleration_dim` will be derived from type `derived_dimension>>` - * - `force_dim` will be derived from type `derived_dimension>>` - * - `energy_dim` will be derived from type `derived_dimension, mass_dim, per>>` + * - `frequency` will be derived from type `derived_dimension>` + * - `speed` will be derived from type `derived_dimension>` + * - `acceleration` will be derived from type `derived_dimension>>` + * - `force` will be derived from type `derived_dimension>>` + * - `energy` will be derived from type `derived_dimension, mass, per>>` * * @note A common convention in this library is to assign the same name for a type and an object of this type. * Besides defining them user never works with the dimension types in the source code. All operations * are done on the objects. Contrarily, the dimension types are the only one visible in the compilation * errors. Having them of the same names improves user experience and somehow blurs those separate domains. * - * Two dimensions are deemed equal when they are of the same type. With that strong type `speed_dim` and - * `derived_dimension>` are considered not equal. They are convertible though. + * Two dimensions are deemed equal when they are of the same type. With that strong type `speed` and + * `derived_dimension>` are considered not equal. They are convertible though. * User can implicitly convert up and down the inheritance hierarchy between those two. - * `torque_dim` and `moment_of_force_dim` are convertible as well. However, `energy_dim` and `torque_dim` + * `torque` and `moment_of_force` are convertible as well. However, `energy` and `torque` * are not convertible as they do not inherit from each other. They are from two separate branches of * dimensionally equivalent quantities. * * @tparam Ds a parameter pack consisting tokens allowed in the dimension specification - * (base dimensions, `one_dim`, `power`, `per<...>`) + * (base dimensions, `dimensionless`, `power`, `per<...>`) * * @note User should not instantiate this type! It is not exported from the C++ module. The library will * instantiate this type automatically based on the dimensional arithmetic equation provided by the user. */ +#ifdef __cpp_explicit_this_parameter__ + template -struct derived_dimension : detail::derived_dimension_impl {}; +struct derived_dimension : detail::derived_dimension_impl { + template + requires(convertible(Self{}, detail::get_dimension_for(U{}))) + [[nodiscard]] constexpr reference operator[](this const Self, U) + { + return {}; + } +}; + +#else + +template +struct derived_dimension; + +template +struct derived_dimension : detail::derived_dimension_impl { + template + requires(convertible(derived_dimension{}, detail::get_dimension_for(U{}))) + [[nodiscard]] constexpr reference operator[](U) const + { + return {}; + } +}; + +template +struct derived_dimension : D { + template + requires(convertible(Self{}, detail::get_dimension_for(U{}))) + [[nodiscard]] constexpr reference operator[](U) const + { + return {}; + } +}; + +#endif namespace detail { @@ -223,13 +266,13 @@ inline constexpr bool is_derived_dimension = true; * Dimension for which all the exponents of the factors corresponding to the base * dimensions are zero. Also commonly named as "dimensionless". */ -inline constexpr struct one_dim : derived_dimension<> { -} one_dim; +inline constexpr struct dimensionless : derived_dimension<> { +} dimensionless; namespace detail { template<> -inline constexpr bool is_one_dim = true; +inline constexpr bool is_dimensionless = true; template struct dim_type_impl { @@ -252,14 +295,14 @@ using dim_type = dim_type_impl::type; template [[nodiscard]] consteval Dimension auto operator*(Lhs, Rhs) { - return detail::expr_multiply( + return detail::expr_multiply( detail::dim_type{}, detail::dim_type{}); } template [[nodiscard]] consteval Dimension auto operator/(Lhs, Rhs) { - return detail::expr_divide( + return detail::expr_divide( detail::dim_type{}, detail::dim_type{}); } @@ -267,7 +310,7 @@ template [[nodiscard]] consteval Dimension auto operator/(int value, D) { gsl_Expects(value == 1); - return detail::expr_invert(detail::dim_type{}); + return detail::expr_invert(detail::dim_type{}); } template @@ -304,9 +347,38 @@ template else return derived_dimension>{}; } else - return detail::expr_pow(d); + return detail::expr_pow(d); } +namespace detail { + +template +[[nodiscard]] consteval Dimension auto get_dimension_for_impl(U) + requires requires { U::base_dimension; } +{ + return U::base_dimension; +} + +template + requires requires { U::base_dimension; } +using to_base_dimension = std::remove_const_t; + +template +[[nodiscard]] consteval Dimension auto get_dimension_for_impl(const derived_unit& u) +{ + return detail::expr_map(u); +} + +[[nodiscard]] consteval Dimension auto get_dimension_for(Unit auto u) +{ + return get_dimension_for_impl(get_canonical_unit(u).reference_unit); +} + +} // namespace detail + + // TODO consider adding the support for text output of the dimensional equation } // namespace units @@ -327,3 +399,26 @@ struct common_type { }; } // namespace std + + +#ifdef __cpp_explicit_this_parameter__ + +#define BASE_DIMENSION(name, symbol) \ + inline constexpr struct name : base_dimension { \ + } name + +#define DERIVED_DIMENSION(name, base) \ + inline constexpr struct name : base { \ + } name + +#else + +#define BASE_DIMENSION(name, symbol) \ + inline constexpr struct name : base_dimension { \ + } name + +#define DERIVED_DIMENSION(name, base) \ + inline constexpr struct name : derived_dimension { \ + } name + +#endif diff --git a/src/core/include/units/quantity.h b/src/core/include/units/quantity.h index f48c3d7f..62eb4d6e 100644 --- a/src/core/include/units/quantity.h +++ b/src/core/include/units/quantity.h @@ -48,7 +48,7 @@ inline constexpr auto make_quantity = [](Representation auto&& v) { }; template -concept quantity_one = Quantity && (T::dimension == one_dim) && (T::unit == one); +concept quantity_one = Quantity && (T::dimension == dimensionless) && (T::unit == one); } // namespace detail @@ -506,7 +506,7 @@ template template requires(!floating_point_) && (!floating_point_) && - (std::convertible_to || quantity_of) && + (std::convertible_to || quantity_of) && (quantity_value_for_, typename Q1::rep, typename Q2::rep>) [[nodiscard]] constexpr Quantity auto operator%(const Q1& lhs, const Q2& rhs) { diff --git a/src/core/include/units/reference.h b/src/core/include/units/reference.h index eaa8c65b..d88851ef 100644 --- a/src/core/include/units/reference.h +++ b/src/core/include/units/reference.h @@ -162,9 +162,6 @@ struct system_reference { } }; -inline constexpr struct dimensionless : system_reference { -} dimensionless; - } // namespace units namespace std { diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index 31cd3827..08cfc414 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -29,19 +29,52 @@ #include #include #include +#include #include #include #include -// #include - -// IWYU pragma: begin_exports -// #include -// #include -// IWYU pragma: end_exports - namespace units { +#ifdef __cpp_explicit_this_parameter__ +template +#else +template +#endif +struct base_dimension; + +namespace detail { + +#ifdef __cpp_explicit_this_parameter__ +template +void to_base_base_dimension(const volatile base_dimension*); +#else +template +void to_base_base_dimension(const volatile base_dimension*); +#endif + +template +inline constexpr bool is_specialization_of_base_dimension = false; + +#ifdef __cpp_explicit_this_parameter__ +template +inline constexpr bool is_specialization_of_base_dimension> = true; +#else +template +inline constexpr bool is_specialization_of_base_dimension> = true; +#endif + +} // namespace detail + +/** + * @brief A concept matching all named base dimensions in the library. + * + * Satisfied by all dimension types derived from a specialization of `base_dimension`. + */ +template +concept BaseDimension = requires(T* t) { detail::to_base_base_dimension(t); } && + (!detail::is_specialization_of_base_dimension); + namespace detail { template @@ -86,14 +119,16 @@ inline constexpr bool is_specialization_of_scaled_unit> = true /** * @brief A named unit * - * Defines a unit with a special name. + * Defines a unit with a special name. It may be used to provide a base unit in the system + * of units (i.e. `metre`) or a name assigned to another scaled or derived unit + * (i.e. `hour`, `joule`). * Most of the named units may be composed with a prefix to create a `prefixed_unit`. * * For example: * * @code{.cpp} - * inline constexpr struct second : named_unit<"s"> {} second; - * inline constexpr struct metre : named_unit<"m"> {} metre; + * inline constexpr struct second : named_unit<"s", time> {} second; + * inline constexpr struct metre : named_unit<"m", length> {} metre; * inline constexpr struct hertz : named_unit<"Hz", 1 / second> {} hertz; * inline constexpr struct newton : named_unit<"N", kilogram * metre / square> {} newton; * inline constexpr struct degree_Celsius : named_unit {} degree_Celsius; @@ -111,11 +146,33 @@ template struct named_unit; /** - * @brief Specialization for base unit + * @brief Specialization for unit of a specified base dimension * - * Defines a base unit in the system of units (i.e. `metre`). - * or a name assigned to another scaled or derived unit (i.e. `hour`, `joule`). - * Most of the named units may be composed with a prefix to create a `prefixed_unit`. + * This is the preferred way to define a measurement unit for a base dimension. For example `si::metre` + * is a unit to measure `isq::length` in the SI system. + * + * @note It does not have to (or sometimes even can't) be a proper system's base unit. For example + * a base unit of mass in the SI is `si::kilogram` but here you are about to provide an `si::gram` + * and it will work just fine as those two are convertible to each other. A similar case would be + * the `cgs::centimetre` that is a base unit for `isq::length` in the CGS system. + * + * @tparam Symbol a short text representation of the unit + * @tparam BaseDimension base dimension measured with this unit + */ +template + requires(!Symbol.empty()) +struct named_unit { + static constexpr auto symbol = Symbol; ///< Unique base unit identifier + static constexpr auto base_dimension = D; +}; + +/** + * @brief Specialization for a unit that can be reused by several base dimensions + * + * This specialization is used in rare cases where more than one base dimension in a specific + * system of units uses the same unit. For example in a hypothetical system of units where + * constant for speed of light `c = 1`, length and time could be measured in seconds. In such + * cases `system_reference` has to be used to explicitly express such a binding. * * @tparam Symbol a short text representation of the unit */ @@ -319,6 +376,9 @@ struct canonical_unit { U reference_unit; }; +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T t, const named_unit&); + template [[nodiscard]] consteval auto get_canonical_unit_impl(T t, const named_unit&); @@ -338,6 +398,12 @@ template return canonical_unit{M * base.mag, base.reference_unit}; } +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T t, const named_unit&) +{ + return canonical_unit{mag<1>, t}; +} + template [[nodiscard]] consteval auto get_canonical_unit_impl(T t, const named_unit&) { diff --git a/src/systems/isq/include/units/isq/base_dimensions.h b/src/systems/isq/include/units/isq/base_dimensions.h index cabf9b61..a0e7b2ad 100644 --- a/src/systems/isq/include/units/isq/base_dimensions.h +++ b/src/systems/isq/include/units/isq/base_dimensions.h @@ -26,15 +26,13 @@ namespace units::isq { -// clang-format off -inline constexpr struct length_dim : base_dimension<"L"> {} length_dim; -inline constexpr struct mass_dim : base_dimension<"M"> {} mass_dim; -inline constexpr struct time_dim : base_dimension<"T"> {} time_dim; -inline constexpr struct electric_current_dim : base_dimension<"I"> {} electric_current_dim; +BASE_DIMENSION(length, "L"); +BASE_DIMENSION(mass, "M"); +BASE_DIMENSION(time, "T"); +BASE_DIMENSION(electric_current, "I"); // TODO Should the below use basic_symbol_text? How to name it for ASCII? -inline constexpr struct thermodynamic_temperature_dim : base_dimension<"Θ"> {} thermodynamic_temperature_dim; -inline constexpr struct amount_of_substance_dim : base_dimension<"N"> {} amount_of_substance_dim; -inline constexpr struct luminous_intensity_dim : base_dimension<"J"> {} luminous_intensity_dim; -// clang-format on +BASE_DIMENSION(thermodynamic_temperature, "Θ"); +BASE_DIMENSION(amount_of_substance, "N"); +BASE_DIMENSION(luminous_intensity, "J"); } // namespace units::isq diff --git a/src/systems/isq/include/units/isq/mechanics.h b/src/systems/isq/include/units/isq/mechanics.h index 3f4271d9..aa6d7ca8 100644 --- a/src/systems/isq/include/units/isq/mechanics.h +++ b/src/systems/isq/include/units/isq/mechanics.h @@ -28,45 +28,45 @@ namespace units::isq { -// clang-format off -// inline constexpr struct mass_dim : base_dimension<"M"> {} mass_dim; -inline constexpr struct mass_density_dim : decltype(mass_dim / volume_dim) {} mass_density_dim; -inline constexpr struct specific_volume_dim : decltype(1 / mass_density_dim) {} specific_volume_dim; -inline constexpr struct relative_mass_density_dim : decltype(mass_density_dim / mass_density_dim) {} relative_mass_density_dim; -inline constexpr struct surface_mass_density_dim : decltype(mass_dim / area_dim) {} surface_mass_density_dim; -inline constexpr struct linear_mass_density_dim : decltype(mass_dim / length_dim) {} linear_mass_density_dim; -inline constexpr struct momentum_dim : decltype(mass_dim * speed_dim) {} momentum_dim; // TODO velocity_dim? -inline constexpr struct force_dim : decltype(mass_dim * acceleration_dim) {} force_dim; // TODO what is a correct equation here? -// inline constexpr struct weight_dim : decltype(mass_dim * acceleration_dim) {} weight_dim; // TODO should we add it as a quantity or should it be a quantity_kind? -// TODO Should we add other forces as well: static_friction_force, kinematic_friction_force, rolling_resistance, drag_force -inline constexpr struct impulse_dim : decltype(force_dim / time_dim) {} impulse_dim; -inline constexpr struct angular_momentum_dim : decltype(length_dim * momentum_dim) {} angular_momentum_dim; // TODO position_vector -inline constexpr struct moment_of_inertia_dim : decltype(angular_momentum_dim * angular_velocity_dim) {} moment_of_inertia_dim; -inline constexpr struct moment_of_force_dim : decltype(length_dim * force_dim) {} moment_of_force_dim; // TODO position_vector -inline constexpr struct torque_dim : decltype(moment_of_force_dim) {} torque_dim; // TODO angle? -inline constexpr struct angular_impulse_dim : decltype(moment_of_force_dim * time_dim) {} angular_impulse_dim; -inline constexpr struct pressure_dim : decltype(force_dim / area_dim) {} pressure_dim; -inline constexpr struct stress_dim : decltype(pressure_dim) {} stress_dim; // TODO tensor? -inline constexpr struct normal_stress_dim : decltype(force_dim / area_dim) {} normal_stress_dim; -inline constexpr struct strain_dim : decltype(stress_dim / stress_dim) {} strain_dim; // TODO what is a correct equation here? -inline constexpr struct poisson_number_dim : decltype(length_dim / length_dim) {} poisson_number_dim; // TODO width? +// inline constexpr struct mass : base_dimension<"M"> {} mass; +DERIVED_DIMENSION(mass_density, decltype(mass / volume)); +DERIVED_DIMENSION(specific_volume, decltype(1 / mass_density)); +DERIVED_DIMENSION(relative_mass_density, decltype(mass_density / mass_density)); +DERIVED_DIMENSION(surface_mass_density, decltype(mass / area)); +DERIVED_DIMENSION(linear_mass_density, decltype(mass / length)); +DERIVED_DIMENSION(momentum, decltype(mass * speed)); // TODO velocity? +DERIVED_DIMENSION(force, decltype(mass * acceleration)); // TODO what is a correct equation here? +// DERIVED_DIMENSION(weight, decltype(mass * acceleration)); // TODO should we add it as a quantity or should it be a +// quantity_kind? +// TODO Should we add other forces as well: static_friction_force, kinematic_friction_force, rolling_resistance, +// drag_force +DERIVED_DIMENSION(impulse, decltype(force / time)); +DERIVED_DIMENSION(angular_momentum, decltype(length * momentum)); // TODO position_vector +DERIVED_DIMENSION(moment_of_inertia, decltype(angular_momentum * angular_velocity)); +DERIVED_DIMENSION(moment_of_force, decltype(length * force)); // TODO position_vector +DERIVED_DIMENSION(torque, decltype(moment_of_force)); // TODO angle? +DERIVED_DIMENSION(angular_impulse, decltype(moment_of_force * time)); +DERIVED_DIMENSION(pressure, decltype(force / area)); +DERIVED_DIMENSION(stress, decltype(pressure)); // TODO tensor? +DERIVED_DIMENSION(normal_stress, decltype(force / area)); +DERIVED_DIMENSION(strain, decltype(stress / stress)); // TODO what is a correct equation here? +DERIVED_DIMENSION(poisson_number, decltype(length / length)); // TODO width? // TODO modulus quantities -inline constexpr struct compressibility_dim : decltype(volume_dim / pressure_dim) {} compressibility_dim; -inline constexpr struct second_axial_moment_of_area_dim : decltype(area_dim * area_dim) {} second_axial_moment_of_area_dim; // TODO what is a correct equation here? -inline constexpr struct section_modulus_dim : decltype(second_axial_moment_of_area_dim / length_dim) {} section_modulus_dim; // TODO radial distance +DERIVED_DIMENSION(compressibility, decltype(volume / pressure)); +DERIVED_DIMENSION(second_axial_moment_of_area, decltype(area * area)); // TODO what is a correct equation here? +DERIVED_DIMENSION(section_modulus, decltype(second_axial_moment_of_area / length)); // TODO radial distance // TODO friction coefficients? -inline constexpr struct dynamic_viscosity_dim : decltype(stress_dim * length_dim / speed_dim) {} dynamic_viscosity_dim; // TODO shear stress, velocity -inline constexpr struct kinematic_viscosity_dim : decltype(dynamic_viscosity_dim / mass_density_dim) {} kinematic_viscosity_dim; -inline constexpr struct surface_tension_dim : decltype(force_dim / length_dim) {} surface_tension_dim; // TODO what is a correct equation here? -inline constexpr struct power_dim : decltype(force_dim * speed_dim) {} power_dim; -// TODO what about energy (potential and kinetic as separate quantities will prevent an equation for mechanical one, is it expected?) -inline constexpr struct efficiency_dim : decltype(power_dim / power_dim) {} efficiency_dim; -inline constexpr struct mass_flow_dim : decltype(mass_density_dim * speed_dim) {} mass_flow_dim; // TODO velocity -inline constexpr struct mass_flow_rate_dim : decltype(mass_flow_dim * area_dim) {} mass_flow_rate_dim; -inline constexpr struct mass_change_rate_dim : decltype(mass_dim / time_dim) {} mass_change_rate_dim; -inline constexpr struct volume_flow_rate_dim : decltype(speed_dim * area_dim) {} volume_flow_rate_dim; // TODO velocity -// inline constexpr struct action_dim : decltype(energy_dim * time_dim) {} action_dim; // TODO make it compile - -// clang-format on +DERIVED_DIMENSION(dynamic_viscosity, decltype(stress * length / speed)); // TODO shear stress, velocity +DERIVED_DIMENSION(kinematic_viscosity, decltype(dynamic_viscosity / mass_density)); +DERIVED_DIMENSION(surface_tension, decltype(force / length)); // TODO what is a correct equation here? +DERIVED_DIMENSION(power, decltype(force * speed)); +// TODO what about energy (potential and kinetic as separate quantities will prevent an equation for mechanical one, is +// it expected?) +DERIVED_DIMENSION(efficiency, decltype(power / power)); +DERIVED_DIMENSION(mass_flow, decltype(mass_density * speed)); // TODO velocity +DERIVED_DIMENSION(mass_flow_rate, decltype(mass_flow * area)); +DERIVED_DIMENSION(mass_change_rate, decltype(mass / time)); +DERIVED_DIMENSION(volume_flow_rate, decltype(speed * area)); // TODO velocity +// DERIVED_DIMENSION(action, decltype(energy * time)); // TODO make it compile } // namespace units::isq diff --git a/src/systems/isq/include/units/isq/space_and_time.h b/src/systems/isq/include/units/isq/space_and_time.h index 4357b630..829bf052 100644 --- a/src/systems/isq/include/units/isq/space_and_time.h +++ b/src/systems/isq/include/units/isq/space_and_time.h @@ -27,42 +27,40 @@ namespace units::isq { -// clang-format off -// inline constexpr struct length_dim : base_dimension<"L"> {} length_dim; -inline constexpr struct curvature_dim : decltype(1 / length_dim) {} curvature_dim; -inline constexpr struct area_dim : decltype(length_dim * length_dim) {} area_dim; -inline constexpr struct volume_dim : decltype(length_dim * length_dim * length_dim) {} volume_dim; -inline constexpr struct angular_measure_dim : decltype(length_dim / length_dim) {} angular_measure_dim; -inline constexpr struct angular_displacement_dim : decltype(length_dim / length_dim) {} angular_displacement_dim; -inline constexpr struct phase_angle_dim : decltype(length_dim / length_dim) {} phase_angle_dim; -inline constexpr struct solid_angular_measure_dim : decltype(area_dim / (length_dim * length_dim)) {} solid_angular_measure_dim; -// inline constexpr struct time_dim : base_dimension<"T"> {} time_dim; // TODO called duration in ISO 80000 +// inline constexpr struct length : base_dimension<"L"> {} length; +DERIVED_DIMENSION(curvature, decltype(1 / length)); +DERIVED_DIMENSION(area, decltype(length * length)); +DERIVED_DIMENSION(volume, decltype(length * length * length)); +DERIVED_DIMENSION(angular_measure, decltype(length / length)); +DERIVED_DIMENSION(angular_displacement, decltype(length / length)); +DERIVED_DIMENSION(phase_angle, decltype(length / length)); +inline constexpr struct solid_angular_measure : decltype(area / (length * length)) { +} solid_angular_measure; +// inline constexpr struct time : base_dimension<"T"> {} time; // TODO called duration in ISO 80000 // TODO there is also a velocity in ISO 80000 -inline constexpr struct speed_dim : decltype(length_dim / time_dim) {} speed_dim; -inline constexpr struct acceleration_dim : decltype(speed_dim / time_dim) {} acceleration_dim; -inline constexpr struct angular_velocity_dim : decltype(angular_displacement_dim / time_dim) {} angular_velocity_dim; -inline constexpr struct angular_acceleration_dim : decltype(angular_velocity_dim / time_dim) {} angular_acceleration_dim; -inline constexpr struct period_duration_dim : time_dim {} period_duration_dim; -inline constexpr struct time_constant_dim : time_dim {} time_constant_dim; -inline constexpr struct rotation_dim : angular_displacement_dim {} rotation_dim; -inline constexpr struct frequency_dim : decltype(1 / time_dim) {} frequency_dim; -inline constexpr struct rotational_frequency_dim : decltype(rotation_dim / time_dim) {} rotational_frequency_dim; -inline constexpr struct angular_frequency_dim : decltype(angular_measure_dim / time_dim) {} angular_frequency_dim; -inline constexpr struct wavelength_dim : length_dim {} wavelength_dim; -inline constexpr struct repetency_dim : decltype(1 / wavelength_dim) {} repetency_dim; -inline constexpr struct wave_vector_dim : decltype(1 / length_dim) {} wave_vector_dim; -inline constexpr struct angular_repetency_dim : decltype(1 / wavelength_dim) {} angular_repetency_dim; -inline constexpr struct phase_velocity_dim : decltype(angular_frequency_dim / angular_repetency_dim) {} phase_velocity_dim; -inline constexpr struct damping_coefficient_dim : decltype(1 / time_constant_dim) {} damping_coefficient_dim; -inline constexpr struct logarithmic_decrement_dim : decltype(damping_coefficient_dim * period_duration_dim) {} logarithmic_decrement_dim; -inline constexpr struct attenuation_dim : decltype(1 / length_dim) {} attenuation_dim; -inline constexpr struct phase_coefficient_dim : decltype(phase_angle_dim / length_dim) {} phase_coefficient_dim; -inline constexpr struct propagation_coefficient_dim : decltype(1 / length_dim) {} propagation_coefficient_dim; -// clang-format on +DERIVED_DIMENSION(speed, decltype(length / time)); +DERIVED_DIMENSION(acceleration, decltype(speed / time)); +DERIVED_DIMENSION(angular_velocity, decltype(angular_displacement / time)); +DERIVED_DIMENSION(angular_acceleration, decltype(angular_velocity / time)); +inline constexpr struct period_duration : time { +} period_duration; +inline constexpr struct time_constant : time { +} time_constant; +inline constexpr struct rotation : angular_displacement { +} rotation; +DERIVED_DIMENSION(frequency, decltype(1 / time)); +DERIVED_DIMENSION(rotational_frequency, decltype(rotation / time)); +DERIVED_DIMENSION(angular_frequency, decltype(angular_measure / time)); +inline constexpr struct wavelength : length { +} wavelength; +DERIVED_DIMENSION(repetency, decltype(1 / wavelength)); +DERIVED_DIMENSION(wave_vector, decltype(1 / length)); +DERIVED_DIMENSION(angular_repetency, decltype(1 / wavelength)); +DERIVED_DIMENSION(phase_velocity, decltype(angular_frequency / angular_repetency)); +DERIVED_DIMENSION(damping_coefficient, decltype(1 / time_constant)); +DERIVED_DIMENSION(logarithmic_decrement, decltype(damping_coefficient * period_duration)); +DERIVED_DIMENSION(attenuation, decltype(1 / length)); +DERIVED_DIMENSION(phase_coefficient, decltype(phase_angle / length)); +DERIVED_DIMENSION(propagation_coefficient, decltype(1 / length)); } // namespace units::isq - - -// inline constexpr struct force_dim : decltype(mass_dim * acceleration_dim) {} force_dim; -// inline constexpr struct energy_dim : decltype(force_dim * length_dim) {} energy_dim; -// inline constexpr struct power_dim : decltype(force_dim * speed_dim) {} power_dim; diff --git a/src/systems/isq/include/units/isq/thermodynamics.h b/src/systems/isq/include/units/isq/thermodynamics.h index afe0bd39..80956a3b 100644 --- a/src/systems/isq/include/units/isq/thermodynamics.h +++ b/src/systems/isq/include/units/isq/thermodynamics.h @@ -28,15 +28,12 @@ namespace units::isq { -// clang-format off -// inline constexpr struct thermodynamic_temperature_dim : base_dimension<"Θ"> {} thermodynamic_temperature_dim; +// inline constexpr struct thermodynamic_temperature : base_dimension<"Θ"> {} thermodynamic_temperature; // TODO Celsius temperature??? -// inline constexpr struct mass_density_dim : decltype(mass_dim / volume_dim) {} mass_density_dim; +// DERIVED_DIMENSION(mass_density, decltype(mass / volume)); -inline constexpr struct energy_dim : decltype(force_dim * length_dim) {} energy_dim; - -// clang-format on +DERIVED_DIMENSION(energy, decltype(force * length)); } // namespace units::isq diff --git a/src/systems/si-cgs/include/units/si/cgs/cgs.h b/src/systems/si-cgs/include/units/si/cgs/cgs.h index 4c68f3b6..4b8091f8 100644 --- a/src/systems/si-cgs/include/units/si/cgs/cgs.h +++ b/src/systems/si-cgs/include/units/si/cgs/cgs.h @@ -42,16 +42,6 @@ inline constexpr struct poise : named_unit<"P", gram / (centimetre * second)> {} inline constexpr struct stokes : named_unit<"St", square / second> {} stokes; inline constexpr struct kayser : decltype(1 / centimetre) {} kayser; -inline constexpr struct length : system_reference {} length; -inline constexpr struct mass : system_reference {} mass; -inline constexpr struct time : system_reference {} time; -inline constexpr struct speed : system_reference {} speed; -inline constexpr struct acceleration : system_reference {} acceleration; -inline constexpr struct force : system_reference {} force;inline constexpr struct energy : system_reference {} energy; -inline constexpr struct power : system_reference {} power; -inline constexpr struct dynamic_viscosity : system_reference {} dynamic_viscosity; -inline constexpr struct kinematic_viscosity : system_reference {} kinematic_viscosity; -// inline constexpr struct wavenumber : system_reference {} wavenumber; // clang-format on } // namespace units::si::cgs diff --git a/src/systems/si/CMakeLists.txt b/src/systems/si/CMakeLists.txt index eb54a1c4..4e2ed458 100644 --- a/src/systems/si/CMakeLists.txt +++ b/src/systems/si/CMakeLists.txt @@ -23,15 +23,7 @@ cmake_minimum_required(VERSION 3.19) add_units_module( - si - DEPENDENCIES mp-units::isq - HEADERS include/units/si/base_quantities.h - include/units/si/constants.h - include/units/si/mechanics.h - include/units/si/prefixes.h - include/units/si/si.h - include/units/si/space_and_time.h - include/units/si/thermodynamics.h - include/units/si/unit_symbols.h - include/units/si/units.h + si DEPENDENCIES mp-units::isq + HEADERS include/units/si/constants.h include/units/si/prefixes.h include/units/si/si.h + include/units/si/unit_symbols.h include/units/si/units.h ) diff --git a/src/systems/si/include/units/si/base_quantities.h b/src/systems/si/include/units/si/base_quantities.h deleted file mode 100644 index 91d557f5..00000000 --- a/src/systems/si/include/units/si/base_quantities.h +++ /dev/null @@ -1,43 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::si { - -// inline constexpr struct time : system_reference {} time; -// inline constexpr struct length : system_reference {} length; -// inline constexpr struct mass : system_reference {} mass; -inline constexpr struct electric_current : system_reference { -} electric_current; -inline constexpr struct thermodynamic_temperature : system_reference { -} thermodynamic_temperature; -inline constexpr struct amount_of_substance : system_reference { -} amount_of_substance; -inline constexpr struct luminous_intensity : system_reference { -} luminous_intensity; - -} // namespace units::si diff --git a/src/systems/si/include/units/si/constants.h b/src/systems/si/include/units/si/constants.h index 1027bf37..c9bda269 100644 --- a/src/systems/si/include/units/si/constants.h +++ b/src/systems/si/include/units/si/constants.h @@ -22,10 +22,10 @@ #pragma once +#include +#include +#include #include -#include -#include -#include #include namespace units::si { @@ -38,10 +38,10 @@ inline constexpr struct mag_speed_of_light : decltype(mag<299'792'458>) {} mag_s // clang-format on template -inline constexpr auto planck_constant = Rep{1} * (mag_planck * energy[joule] * time[second]); +inline constexpr auto planck_constant = Rep{1} * (mag_planck * isq::energy[joule] * isq::time[second]); template -inline constexpr auto speed_of_light = Rep{1} * speed[mag_speed_of_light * metre / second]; +inline constexpr auto speed_of_light = Rep{1} * isq::speed[mag_speed_of_light * metre / second]; // template // inline constexpr auto planck_constant = energy(6.62607015e-34) * time(1); @@ -75,6 +75,6 @@ inline constexpr struct mag_standard_gravity : decltype(mag -inline constexpr auto standard_gravity = Rep{1} * acceleration[mag_standard_gravity * metre / square]; +inline constexpr auto standard_gravity = Rep{1} * isq::acceleration[mag_standard_gravity * metre / square]; } // namespace units::si diff --git a/src/systems/si/include/units/si/mechanics.h b/src/systems/si/include/units/si/mechanics.h deleted file mode 100644 index e657aca7..00000000 --- a/src/systems/si/include/units/si/mechanics.h +++ /dev/null @@ -1,68 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include -#include - -namespace units::si { - -// clang-format off -inline constexpr struct mass : system_reference {} mass; -inline constexpr struct mass_density : system_reference> {} mass_density; -inline constexpr struct specific_volume : system_reference / kilogram> {} specific_volume; -inline constexpr struct relative_mass_density : system_reference {} relative_mass_density; -inline constexpr struct surface_mass_density : system_reference> {} surface_mass_density; -inline constexpr struct linear_mass_density : system_reference {} linear_mass_density; -inline constexpr struct momentum : system_reference {} momentum; -inline constexpr struct force : system_reference {} force; -// inline constexpr struct weight : system_reference {} weight; -inline constexpr struct impulse : system_reference {} impulse; -inline constexpr struct angular_momentum : system_reference / second> {} angular_momentum; // TODO radian? -inline constexpr struct moment_of_inertia : system_reference> {} moment_of_inertia; -inline constexpr struct moment_of_force : system_reference {} moment_of_force; -inline constexpr struct torque : system_reference {} torque; -inline constexpr struct angular_impulse : system_reference {} angular_impulse; -inline constexpr struct pressure : system_reference {} pressure; -inline constexpr struct stress : system_reference {} stress; -inline constexpr struct normal_stress : system_reference {} normal_stress; -inline constexpr struct strain : system_reference {} strain; -inline constexpr struct poisson_number : system_reference {} poisson_number; -inline constexpr struct compressibility : system_reference {} compressibility; -inline constexpr struct second_axial_moment_of_area : system_reference * square> {} second_axial_moment_of_area; -inline constexpr struct section_modulus : system_reference> {} section_modulus; -inline constexpr struct dynamic_viscosity : system_reference {} dynamic_viscosity; -inline constexpr struct kinematic_viscosity : system_reference / second> {} kinematic_viscosity; -inline constexpr struct surface_tension : system_reference {} surface_tension; -inline constexpr struct power : system_reference {} power; -inline constexpr struct efficiency : system_reference {} efficiency; -inline constexpr struct mass_flow : system_reference * second)> {} mass_flow; -inline constexpr struct mass_flow_rate : system_reference {} mass_flow_rate; -inline constexpr struct mass_change_rate : system_reference {} mass_change_rate; -inline constexpr struct volume_flow_rate : system_reference / second> {} volume_flow_rate; -// inline constexpr struct action : system_reference {} action; // TODO make it compile -// clang-format on - -} // namespace units::si diff --git a/src/systems/si/include/units/si/si.h b/src/systems/si/include/units/si/si.h index 70878f77..e97aff6d 100644 --- a/src/systems/si/include/units/si/si.h +++ b/src/systems/si/include/units/si/si.h @@ -22,11 +22,7 @@ #pragma once -#include #include -#include #include -#include -#include #include #include diff --git a/src/systems/si/include/units/si/space_and_time.h b/src/systems/si/include/units/si/space_and_time.h deleted file mode 100644 index 697429d0..00000000 --- a/src/systems/si/include/units/si/space_and_time.h +++ /dev/null @@ -1,64 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -#include -#include - -namespace units::si { - -// clang-format off -inline constexpr struct length : system_reference {} length; -inline constexpr struct curvature : system_reference {} curvature; -inline constexpr struct area : system_reference> {} area; -inline constexpr struct volume : system_reference> {} volume; -inline constexpr struct angular_measure : system_reference {} angular_measure; -inline constexpr struct angular_displacement : system_reference {} angular_displacement; -inline constexpr struct phase_angle : system_reference {} phase_angle; -inline constexpr struct solid_angular_measure : system_reference {} solid_angular_measure; -inline constexpr struct time : system_reference {} time; // TODO called duration in ISO 80000 -// TODO there is also a velocity in ISO 80000 -inline constexpr struct speed : system_reference {} speed; -inline constexpr struct acceleration : system_reference> {} acceleration; -inline constexpr struct angular_velocity : system_reference {} angular_velocity; -inline constexpr struct angular_acceleration : system_reference> {} angular_acceleration; -inline constexpr struct period_duration : system_reference {} period_duration; -inline constexpr struct time_constant : system_reference {} time_constant; -inline constexpr struct rotation : system_reference {} rotation; -inline constexpr struct frequency : system_reference {} frequency; -inline constexpr struct rotational_frequency : system_reference {} rotational_frequency; -inline constexpr struct angular_frequency : system_reference {} angular_frequency; -inline constexpr struct wavelength : system_reference {} wavelength; -inline constexpr struct repetency : system_reference {} repetency; -inline constexpr struct wave_vector : system_reference {} wave_vector; -inline constexpr struct angular_repetency : system_reference {} angular_repetency; -inline constexpr struct phase_velocity : system_reference {} phase_velocity; -inline constexpr struct damping_coefficient : system_reference {} damping_coefficient; -inline constexpr struct logarithmic_decrement : system_reference {} logarithmic_decrement; -inline constexpr struct attenuation : system_reference {} attenuation; -inline constexpr struct phase_coefficient : system_reference {} phase_coefficient; -inline constexpr struct propagation_coefficient : system_reference {} propagation_coefficient; -// clang-format on - -} // namespace units::si diff --git a/src/systems/si/include/units/si/thermodynamics.h b/src/systems/si/include/units/si/thermodynamics.h deleted file mode 100644 index 33538eb9..00000000 --- a/src/systems/si/include/units/si/thermodynamics.h +++ /dev/null @@ -1,39 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// 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. - -#pragma once - -#include -// #include -#include -#include -#include - -namespace units::si { - -// inline constexpr struct thermodynamic_temperature : system_reference {} -// thermodynamic_temperature; - -inline constexpr struct energy : system_reference { -} energy; - -} // namespace units::si diff --git a/src/systems/si/include/units/si/units.h b/src/systems/si/include/units/si/units.h index 26b46db8..05b08a4b 100644 --- a/src/systems/si/include/units/si/units.h +++ b/src/systems/si/include/units/si/units.h @@ -22,6 +22,7 @@ #pragma once +#include #include #include @@ -29,14 +30,14 @@ namespace units::si { // clang-format off // base units -inline constexpr struct second : named_unit<"s"> {} second; -inline constexpr struct metre : named_unit<"m"> {} metre; -inline constexpr struct gram : named_unit<"g"> {} gram; +inline constexpr struct second : named_unit<"s", isq::time> {} second; +inline constexpr struct metre : named_unit<"m", isq::length> {} metre; +inline constexpr struct gram : named_unit<"g", isq::mass> {} gram; inline constexpr struct kilogram : decltype(kilo) {} kilogram; -inline constexpr struct ampere : named_unit<"A"> {} ampere; -inline constexpr struct kelvin : named_unit<"K"> {} kelvin; -inline constexpr struct mole : named_unit<"mol"> {} mole; -inline constexpr struct candela : named_unit<"cd"> {} candela; +inline constexpr struct ampere : named_unit<"A", isq::electric_current> {} ampere; +inline constexpr struct kelvin : named_unit<"K", isq::thermodynamic_temperature> {} kelvin; +inline constexpr struct mole : named_unit<"mol", isq::amount_of_substance> {} mole; +inline constexpr struct candela : named_unit<"cd", isq::luminous_intensity> {} candela; // derived named units inline constexpr struct radian : named_unit<"rad", metre / metre> {} radian; @@ -90,7 +91,7 @@ inline constexpr struct electronvolt : named_unit<"eV", mag -inline constexpr bool unit_can_be_prefixed = false; +inline constexpr bool unit_can_be_prefixed = false; // TODO Is it true? template<> inline constexpr bool unit_can_be_prefixed = false; template<> diff --git a/test/unit_test/static/CMakeLists.txt b/test/unit_test/static/CMakeLists.txt index 587f824d..2dcd38bc 100644 --- a/test/unit_test/static/CMakeLists.txt +++ b/test/unit_test/static/CMakeLists.txt @@ -35,7 +35,6 @@ cmake_minimum_required(VERSION 3.2) add_library( unit_tests_static dimension_test.cpp - # angle_test.cpp # cgs_test.cpp # chrono_test.cpp @@ -49,7 +48,6 @@ add_library( # iec80000_test.cpp # kind_test.cpp magnitude_test.cpp - # math_test.cpp # point_origin_test.cpp # prime_test.cpp @@ -62,7 +60,6 @@ add_library( # symbol_text_test.cpp type_list_test.cpp unit_test.cpp - # us_test.cpp ) diff --git a/test/unit_test/static/dimension_test.cpp b/test/unit_test/static/dimension_test.cpp index 25cb5c3d..12088ab5 100644 --- a/test/unit_test/static/dimension_test.cpp +++ b/test/unit_test/static/dimension_test.cpp @@ -20,206 +20,199 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +#include "test_tools.h" #include namespace { using namespace units; -template -inline constexpr bool is_of_type = std::is_same_v, T>; - -using one_dim_ = struct one_dim; +using dimensionless_ = struct dimensionless; // clang-format off -inline constexpr struct length_dim_ : base_dimension<"L"> {} length_dim; -inline constexpr struct time_dim_ : base_dimension<"T"> {} time_dim; -inline constexpr struct mass_dim_ : base_dimension<"M"> {} mass_dim; +BASE_DIMENSION_(length, "L"); +BASE_DIMENSION_(time, "T"); +BASE_DIMENSION_(mass, "M"); -inline constexpr struct frequency_dim_ : decltype(1 / time_dim) {} frequency_dim; -inline constexpr struct action_dim_ : decltype(1 / time_dim) {} action_dim; -inline constexpr struct area_dim_ : decltype(length_dim * length_dim) {} area_dim; -inline constexpr struct volume_dim_ : decltype(area_dim * length_dim) {} volume_dim; -inline constexpr struct speed_dim_ : decltype(length_dim / time_dim) {} speed_dim; -inline constexpr struct velocity_dim_ : speed_dim_ {} velocity_dim; -inline constexpr struct acceleration_dim_ : decltype(speed_dim / time_dim) {} acceleration_dim; -inline constexpr struct force_dim_ : decltype(mass_dim * acceleration_dim) {} force_dim; -inline constexpr struct moment_of_force_dim_ : decltype(length_dim * force_dim) {} moment_of_force_dim; -inline constexpr struct torque_dim_ : decltype(moment_of_force_dim) {} torque_dim; -inline constexpr struct pressure_dim_ : decltype(force_dim / area_dim) {} pressure_dim; -inline constexpr struct stress_dim_ : decltype(pressure_dim) {} stress_dim; -inline constexpr struct strain_dim_ : decltype(stress_dim / stress_dim) {} strain_dim; -inline constexpr struct power_dim_ : decltype(force_dim * speed_dim) {} power_dim; -inline constexpr struct efficiency_dim_ : decltype(power_dim / power_dim) {} efficiency_dim; -inline constexpr struct energy_dim_ : decltype(force_dim * length_dim) {} energy_dim; +DERIVED_DIMENSION_(frequency, decltype(1 / time)); +DERIVED_DIMENSION_(action, decltype(1 / time)); +DERIVED_DIMENSION_(area, decltype(length * length)); +DERIVED_DIMENSION_(volume, decltype(area * length)); +DERIVED_DIMENSION_(speed, decltype(length / time)); +inline constexpr struct velocity_ : speed_ {} velocity; +DERIVED_DIMENSION_(acceleration, decltype(speed / time)); +DERIVED_DIMENSION_(force, decltype(mass * acceleration)); +DERIVED_DIMENSION_(moment_of_force, decltype(length * force)); +DERIVED_DIMENSION_(torque, decltype(moment_of_force)); +DERIVED_DIMENSION_(pressure, decltype(force / area)); +DERIVED_DIMENSION_(stress, decltype(pressure)); +DERIVED_DIMENSION_(strain, decltype(stress / stress)); +DERIVED_DIMENSION_(power, decltype(force * speed)); +DERIVED_DIMENSION_(efficiency, decltype(power / power)); +DERIVED_DIMENSION_(energy, decltype(force * length)); // clang-format on // concepts verification -static_assert(BaseDimension); -static_assert(!BaseDimension); -static_assert(!DerivedDimension); -static_assert(DerivedDimension); -static_assert(Dimension); -static_assert(Dimension); +static_assert(BaseDimension); +static_assert(!BaseDimension); +static_assert(!DerivedDimension); +static_assert(DerivedDimension); +static_assert(Dimension); +static_assert(Dimension); -static_assert(DerivedDimension); -static_assert(DerivedDimension); // one_dim -static_assert(BaseDimension); // length_dim +static_assert(DerivedDimension); +static_assert(DerivedDimension); // dimensionless +static_assert(BaseDimension); // length // derived dimension expression template syntax verification -static_assert(is_of_type<1 / time_dim, derived_dimension>>); -static_assert(is_of_type<1 / (1 / time_dim), time_dim_>); +static_assert(is_of_type<1 / time, derived_dimension>>); +static_assert(is_of_type<1 / (1 / time), time_>); -static_assert(is_of_type); -static_assert(is_of_type); -static_assert(is_of_type>>); -static_assert(is_of_type<1 / time_dim * one_dim, derived_dimension>>); +static_assert(is_of_type); +static_assert(is_of_type