From 77625d63cb105d7f7b50e058cff07411054db1d8 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 22 Aug 2024 08:06:00 +0200 Subject: [PATCH] feat: :boom: `unit_can_be_prefixed` removed - from now on all named units can be prefixed Resolves #604 --- docs/users_guide/framework_basics/concepts.md | 16 ++--------- .../framework_basics/systems_of_units.md | 18 ------------- .../mp-units/framework/unit_concepts.h | 27 +------------------ .../include/mp-units/systems/si/units.h | 9 ------- test/static/concepts_test.cpp | 25 ----------------- test/static/si_test.cpp | 4 --- test/static/unit_test.cpp | 24 ++++++++--------- 7 files changed, 15 insertions(+), 108 deletions(-) diff --git a/docs/users_guide/framework_basics/concepts.md b/docs/users_guide/framework_basics/concepts.md index efeb847aa..dd09e6737 100644 --- a/docs/users_guide/framework_basics/concepts.md +++ b/docs/users_guide/framework_basics/concepts.md @@ -117,20 +117,8 @@ and is satisfied by: ### `PrefixableUnit` { #PrefixableUnit } -`PrefixableUnit` concept is satisfied by all units derived from a `named_unit` class template for -which a customization point `unit_can_be_prefixed` was not explicitly set to `false`. Such -units can be passed as an argument to a `prefixed_unit` class template. - -??? abstract "Examples" - - All units in the [SI](../../appendix/glossary.md#si) can be prefixed with SI-defined prefixes. - - Some [off-system units](../../appendix/glossary.md#off-system-unit) like `non_si::day` - can't be prefixed. To enforce that, the following has to be provided: - - ```cpp - template<> inline constexpr bool unit_can_be_prefixed = false; - ``` +`PrefixableUnit` concept is satisfied by all units derived from a `named_unit` class template. +Such units can be passed as an argument to a `prefixed_unit` class template. ### `UnitOf` { #UnitOf } diff --git a/docs/users_guide/framework_basics/systems_of_units.md b/docs/users_guide/framework_basics/systems_of_units.md index 307fd2152..df37b6bf4 100644 --- a/docs/users_guide/framework_basics/systems_of_units.md +++ b/docs/users_guide/framework_basics/systems_of_units.md @@ -190,21 +190,3 @@ inline constexpr struct mag_pi final : magnitude ```cpp inline constexpr struct degree final : named_unit<{u8"°", "deg"}, mag_pi / mag<180> * si::radian> {} degree; ``` - -!!! tip - - The ISO 8000 and [SI](../../appendix/glossary.md#si) standards explicitly forbid using prefixes - with some units (e.g., day, minute, hour, degree Celsius). This is why the library disallows - this as well by providing specializations of the `unit_can_be_prefixed` variable template for - such units. Thanks to it trying to create a prefixed version for them will result in - a compile-time error. - - However, some projects are not aware of those limitations and use prefixed version of such units - (e.g., [linux kernel uses millidegrees Celsius](https://github.com/search?q=repo%3Atorvalds%2Flinux+millidegree&type=code)). - To enable compatibility with those projects we can workaround the limitation in **mp-units** - by providing a scaled version of the unit explicitly: - - ```cpp - inline constexpr struct milli_degree_celsius final : named_unit * si::degree_Celsius> {} milli_degree_celsius; - inline constexpr auto mdeg_C = milli_degree_celsius; - ``` diff --git a/src/core/include/mp-units/framework/unit_concepts.h b/src/core/include/mp-units/framework/unit_concepts.h index 5f7088cdf..56e15c65b 100644 --- a/src/core/include/mp-units/framework/unit_concepts.h +++ b/src/core/include/mp-units/framework/unit_concepts.h @@ -62,38 +62,13 @@ template inline constexpr bool is_derived_from_specialization_of_named_unit = requires(T* t) { to_base_specialization_of_named_unit(t); }; -template -inline constexpr bool is_specialization_of_named_unit = false; - -template -inline constexpr bool is_specialization_of_named_unit> = true; - -/** - * @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 && detail::is_derived_from_specialization_of_named_unit && (!detail::is_specialization_of_named_unit); - } // namespace detail -/** - * @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. - */ -MP_UNITS_EXPORT template -inline constexpr bool unit_can_be_prefixed = true; - /** * @brief A concept to be used to define prefixes for a unit */ MP_UNITS_EXPORT template -concept PrefixableUnit = detail::NamedUnit && unit_can_be_prefixed; +concept PrefixableUnit = Unit && detail::is_derived_from_specialization_of_named_unit; namespace detail { diff --git a/src/systems/include/mp-units/systems/si/units.h b/src/systems/include/mp-units/systems/si/units.h index d69668a0a..4f5efe523 100644 --- a/src/systems/include/mp-units/systems/si/units.h +++ b/src/systems/include/mp-units/systems/si/units.h @@ -125,15 +125,6 @@ using namespace non_si; } // namespace si -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; -template<> -inline constexpr bool unit_can_be_prefixed = false; - template<> inline constexpr bool space_before_unit_symbol = false; template<> diff --git a/test/static/concepts_test.cpp b/test/static/concepts_test.cpp index 17cf6d814..06b20699c 100644 --- a/test/static/concepts_test.cpp +++ b/test/static/concepts_test.cpp @@ -155,31 +155,6 @@ static_assert(!Unit); static_assert(!Unit); #endif -// NamedUnit -static_assert(detail::NamedUnit); -static_assert(detail::NamedUnit); -static_assert(!detail::NamedUnit); -static_assert(!detail::NamedUnit)>); -static_assert(!detail::NamedUnit); -static_assert(!detail::NamedUnit); -static_assert(!detail::NamedUnit * si::second)>); -static_assert(!detail::NamedUnit); -static_assert(!detail::NamedUnit(si::metre))>); -static_assert(detail::NamedUnit); -static_assert(!detail::NamedUnit, struct si::second>>); -static_assert(!detail::NamedUnit>>); -static_assert(!detail::NamedUnit); -static_assert(!detail::NamedUnit>>); -static_assert(!detail::NamedUnit>); -static_assert(!detail::NamedUnit>); -static_assert(!detail::NamedUnit>>); -static_assert(!detail::NamedUnit, si::second>>); -static_assert(!detail::NamedUnit); -static_assert(!detail::NamedUnit); -#if MP_UNITS_HOSTED -static_assert(!detail::NamedUnit); -#endif - // PrefixableUnit static_assert(PrefixableUnit); static_assert(PrefixableUnit); diff --git a/test/static/si_test.cpp b/test/static/si_test.cpp index 0b06630aa..4f306fd25 100644 --- a/test/static/si_test.cpp +++ b/test/static/si_test.cpp @@ -63,10 +63,6 @@ static_assert(1 * Qm == 1'000'000'000'000'000'000 * Tm); template typename prefix, auto V1> concept can_not_be_prefixed = Unit && !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>); diff --git a/test/static/unit_test.cpp b/test/static/unit_test.cpp index 8250962f7..ba7ecb4c7 100644 --- a/test/static/unit_test.cpp +++ b/test/static/unit_test.cpp @@ -106,18 +106,18 @@ static_assert(Unit); static_assert(Unit); static_assert(Unit); -static_assert(detail::NamedUnit); -static_assert(detail::NamedUnit); -static_assert(detail::NamedUnit); -static_assert(detail::NamedUnit); -static_assert(detail::NamedUnit); -static_assert(!detail::NamedUnit); -static_assert(!detail::NamedUnit); -static_assert(!detail::NamedUnit)>); -static_assert(!detail::NamedUnit); -static_assert(!detail::NamedUnit); -static_assert(!detail::NamedUnit * second)>); -static_assert(!detail::NamedUnit); +static_assert(PrefixableUnit); +static_assert(PrefixableUnit); +static_assert(PrefixableUnit); +static_assert(PrefixableUnit); +static_assert(PrefixableUnit); +static_assert(!PrefixableUnit); +static_assert(!PrefixableUnit); +static_assert(!PrefixableUnit)>); +static_assert(!PrefixableUnit); +static_assert(!PrefixableUnit); +static_assert(!PrefixableUnit * second)>); +static_assert(!PrefixableUnit); // named unit static_assert(is_of_type);