From 4eb63227e2012b7371bbb33268eb07a5db2fbe99 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 10 Oct 2024 00:02:08 +0200 Subject: [PATCH] refactor: :boom: `ascii` -> `portable`, `unicode` -> `utf8`, 'A' -> 'P' --- docs/getting_started/faq.md | 6 +- .../framework_basics/systems_of_units.md | 8 +- .../framework_basics/text_output.md | 38 +++--- example/currency.cpp | 2 +- src/core/include/mp-units/bits/text_tools.h | 12 +- src/core/include/mp-units/format.h | 20 +-- .../include/mp-units/framework/magnitude.h | 4 +- .../include/mp-units/framework/symbol_text.h | 50 +++---- .../framework/unit_symbol_formatting.h | 2 +- test/runtime/fmt_test.cpp | 12 +- test/static/dimension_symbol_test.cpp | 6 +- test/static/symbol_text_test.cpp | 22 +-- test/static/unit_symbol_test.cpp | 126 +++++++++--------- 13 files changed, 158 insertions(+), 150 deletions(-) diff --git a/docs/getting_started/faq.md b/docs/getting_started/faq.md index efc919770..fa9c29c73 100644 --- a/docs/getting_started/faq.md +++ b/docs/getting_started/faq.md @@ -164,11 +164,11 @@ code. please let us know in the associated [GitHub Issue](https://github.com/mpusz/mp-units/issues/93). -## Why Unicode quantity symbols are used by default instead of ASCII-only characters? +## Why UTF-8 quantity symbols are used by default instead of portable characters? Both C++ and [ISO 80000](../appendix/references.md#ISO80000) are standardized by the ISO. [ISO 80000](../appendix/references.md#ISO80000) and the [SI](../appendix/references.md#SIBrochure) -standards specify Unicode symbols as the official unit names for some quantities +standards specify UTF-8 symbols as the official unit names for some quantities (e.g. `Ω` symbol for the resistance quantity). As the **mp-units** library will be proposed for standardization as a part of the C++ Standard Library we have to obey the rules and be consistent with ISO specifications. @@ -176,7 +176,7 @@ we have to obey the rules and be consistent with ISO specifications. !!! note We do understand engineering reality and the constraints of some environments. This is why the library - has the option of [ASCII-only Quantity Symbols](../users_guide/framework_basics/text_output.md#unit_symbol_formatting). + has the option of [Portable Quantity Symbols](../users_guide/framework_basics/text_output.md#unit_symbol_formatting). ## Why don't we have CMake options to disable the building of tests and examples? diff --git a/docs/users_guide/framework_basics/systems_of_units.md b/docs/users_guide/framework_basics/systems_of_units.md index 667b21cd5..18266d4b3 100644 --- a/docs/users_guide/framework_basics/systems_of_units.md +++ b/docs/users_guide/framework_basics/systems_of_units.md @@ -240,18 +240,18 @@ are opt-in. A user has to explicitly "import" them from a dedicated `unit_symbol quantity q2 = 42 * km / h; ``` -We also provide alternative object identifiers using Unicode characters in their names for most -unit symbols. The code using Unicode looks nicer, but it is harder to type on the keyboard. +We also provide alternative object identifiers using UTF-8 characters in their names for most +unit symbols. The code using UTF-8 looks nicer, but it is harder to type on the keyboard. This is why we provide both versions of identifiers for such units. -=== "ASCII only" +=== "Portable" ```cpp quantity resistance = 60 * kohm; quantity capacitance = 100 * uF; ``` -=== "With Unicode glyphs" +=== "With UTF-8 glyphs" ```cpp quantity resistance = 60 * kΩ; diff --git a/docs/users_guide/framework_basics/text_output.md b/docs/users_guide/framework_basics/text_output.md index 4d676fdcc..58ad13a78 100644 --- a/docs/users_guide/framework_basics/text_output.md +++ b/docs/users_guide/framework_basics/text_output.md @@ -114,18 +114,18 @@ and units of derived quantities. ### `text_encoding` [ISQ](../../appendix/glossary.md#isq) and [SI](../../appendix/glossary.md#si) standards always -specify symbols using Unicode encoding. This is why it is a default and primary target for -text output. However, in some applications or environments, a standard ASCII-like text output +specify symbols using UTF-8 encoding. This is why it is a default and primary target for +text output. However, in some applications or environments, a standard portable text output using only the characters from the [basic literal character set](https://en.cppreference.com/w/cpp/language/charset) can be preferred by users. -This is why the library provides an option to change the default encoding to the ASCII one with: +This is why the library provides an option to change the default encoding to the portable one with: ```cpp enum class text_encoding : std::int8_t { - unicode, // µs; m³; L²MT⁻³ - ascii, // us; m^3; L^2MT^-3 - default_encoding = unicode + utf8, // µs; m³; L²MT⁻³ + portable, // us; m^3; L^2MT^-3 + default_encoding = utf8 }; ``` @@ -154,7 +154,7 @@ template(isq::power.dimension) == "L^2MT^-3"); +static_assert(dimension_symbol<{.encoding = text_encoding::portable}>(isq::power.dimension) == "L^2MT^-3"); ``` !!! note @@ -175,7 +175,7 @@ For example: ```cpp std::string txt; -dimension_symbol_to(std::back_inserter(txt), isq::power.dimension, {.encoding = text_encoding::ascii}); +dimension_symbol_to(std::back_inserter(txt), isq::power.dimension, {.encoding = text_encoding::portable}); std::cout << txt << "\n"; ``` @@ -203,7 +203,7 @@ enum class unit_symbol_solidus : std::int8_t { enum class unit_symbol_separator : std::int8_t { space, // kg m²/s² - half_high_dot, // kg⋅m²/s² (valid only for unicode encoding) + half_high_dot, // kg⋅m²/s² (valid only for utf8 encoding) default_separator = space }; @@ -455,7 +455,7 @@ as text and, thus, are aligned to the left by default. ```ebnf dimension-format-spec = [fill-and-align], [width], [dimension-spec]; dimension-spec = [text-encoding]; -text-encoding = 'U' | 'A'; +text-encoding = 'U' | 'P'; ``` In the above grammar: @@ -463,8 +463,8 @@ In the above grammar: - `fill-and-align` and `width` tokens are defined in the [format.string.std](https://wg21.link/format.string.std) chapter of the C++ standard specification, - `text-encoding` token specifies the symbol text encoding: - - `U` (default) uses the **Unicode** symbols defined by [@ISO80000] (e.g., `LT⁻²`), - - `A` forces non-standard **ASCII**-only output (e.g., `LT^-2`). + - `U` (default) uses the **UTF-8** symbols defined by [@ISO80000] (e.g., `LT⁻²`), + - `P` forces non-standard **portable** output (e.g., `LT^-2`). Dimension symbols of some quantities are specified to use Unicode signs by the [ISQ](../../appendix/glossary.md#isq) (e.g., `Θ` symbol for the _thermodynamic temperature_ @@ -475,9 +475,9 @@ symbol can be forced to be printed using such characters thanks to `text-encodin ```cpp std::println("{}", isq::dim_thermodynamic_temperature); // Θ -std::println("{:A}", isq::dim_thermodynamic_temperature); // O +std::println("{:P}", isq::dim_thermodynamic_temperature); // O std::println("{}", isq::power.dimension); // L²MT⁻³ -std::println("{:A}", isq::power.dimension); // L^2MT^-3 +std::println("{:P}", isq::power.dimension); // L^2MT^-3 ``` ### Unit formatting @@ -506,7 +506,7 @@ In the above grammar: (e.g., `m s⁻¹`, `kg m⁻¹ s⁻¹`) - `unit-symbol-separator` token specifies how multiplied unit symbols should be separated: - 's' (default) uses **space** as a separator (e.g., `kg m²/s²`) - - 'd' uses half-high **dot** (`⋅`) as a separator (e.g., `kg⋅m²/s²`) (requires the Unicode encoding) + - 'd' uses half-high **dot** (`⋅`) as a separator (e.g., `kg⋅m²/s²`) (requires the UTF-8 encoding) - 'L' is reserved for possible future localization use in case the C++ standard library gets access to the ICU-like database. @@ -525,11 +525,11 @@ In such a case, the unit symbol can be forced to be printed using such character ```cpp std::println("{}", si::ohm); // Ω -std::println("{:A}", si::ohm); // ohm +std::println("{:P}", si::ohm); // ohm std::println("{}", us); // µs -std::println("{:A}", us); // us +std::println("{:P}", us); // us std::println("{}", m / s2); // m/s² -std::println("{:A}", m / s2); // m/s^2 +std::println("{:P}", m / s2); // m/s^2 ``` Additionally, both ISO 80000 and [SI](../../appendix/glossary.md#si) leave some freedom on how to @@ -576,7 +576,7 @@ std::println("{:d}", kg * m2 / s2); // kg⋅m²/s² !!! note - 'd' requires the Unicode encoding to be set. + 'd' requires the UTF-8 encoding to be set. ### Quantity formatting diff --git a/example/currency.cpp b/example/currency.cpp index f6699376e..fbcfb9152 100644 --- a/example/currency.cpp +++ b/example/currency.cpp @@ -77,7 +77,7 @@ template #else -[[nodiscard]] std::string_view to_string_view(Unit auto u) { return u.symbol.ascii().c_str(); } +[[nodiscard]] std::string_view to_string_view(Unit auto u) { return u.symbol.portable().c_str(); } template [[nodiscard]] double exchange_rate(std::chrono::sys_seconds timestamp) diff --git a/src/core/include/mp-units/bits/text_tools.h b/src/core/include/mp-units/bits/text_tools.h index 46e5fa9c5..45203d273 100644 --- a/src/core/include/mp-units/bits/text_tools.h +++ b/src/core/include/mp-units/bits/text_tools.h @@ -98,19 +98,19 @@ template template Out> constexpr Out copy(const symbol_text& txt, text_encoding encoding, Out out) { - if (encoding == text_encoding::unicode) { + if (encoding == text_encoding::utf8) { if constexpr (is_same_v) - return ::mp_units::detail::copy(txt.unicode().begin(), txt.unicode().end(), out); + return ::mp_units::detail::copy(txt.utf8().begin(), txt.utf8().end(), out); else if constexpr (is_same_v) { - for (const char8_t ch : txt.unicode()) *out++ = static_cast(ch); + for (const char8_t ch : txt.utf8()) *out++ = static_cast(ch); return out; } else - MP_UNITS_THROW(std::invalid_argument("Unicode text can't be copied to CharT output")); + MP_UNITS_THROW(std::invalid_argument("UTF-8 text can't be copied to CharT output")); } else { if constexpr (is_same_v) - return ::mp_units::detail::copy(txt.ascii().begin(), txt.ascii().end(), out); + return ::mp_units::detail::copy(txt.portable().begin(), txt.portable().end(), out); else - MP_UNITS_THROW(std::invalid_argument("ASCII text can't be copied to CharT output")); + MP_UNITS_THROW(std::invalid_argument("Portable text can't be copied to CharT output")); } } diff --git a/src/core/include/mp-units/format.h b/src/core/include/mp-units/format.h index aeaa5201c..fe19a07e5 100644 --- a/src/core/include/mp-units/format.h +++ b/src/core/include/mp-units/format.h @@ -112,7 +112,7 @@ MP_UNITS_EXPORT_END // // dimension-format-spec = [fill-and-align], [width], [dimension-spec]; // dimension-spec = [text-encoding]; -// text-encoding = 'U' | 'A'; +// text-encoding = 'U' | 'P'; // template class MP_UNITS_STD_FMT::formatter { @@ -126,15 +126,16 @@ class MP_UNITS_STD_FMT::formatter { auto it = begin; if (it == end || *it == '}') return begin; - constexpr auto valid_modifiers = std::string_view{"UA"}; + constexpr auto valid_modifiers = std::string_view{"UP"}; for (; it != end && *it != '}'; ++it) { if (valid_modifiers.find(*it) == std::string_view::npos) throw MP_UNITS_STD_FMT::format_error("invalid dimension modifier specified"); } end = it; - if (it = mp_units::detail::at_most_one_of(begin, end, "UA"); it != end) - specs_.encoding = (*it == 'U') ? mp_units::text_encoding::unicode : mp_units::text_encoding::ascii; + if (it = mp_units::detail::at_most_one_of(begin, end, "UAP"); it != end) + // TODO 'A' stands for an old and deprecated ASCII encoding + specs_.encoding = (*it == 'U') ? mp_units::text_encoding::utf8 : mp_units::text_encoding::portable; return end; } @@ -198,15 +199,16 @@ class MP_UNITS_STD_FMT::formatter { auto it = begin; if (it == end || *it == '}') return begin; - constexpr auto valid_modifiers = std::string_view{"UA1ansd"}; + constexpr auto valid_modifiers = std::string_view{"UAP1ansd"}; for (; it != end && *it != '}'; ++it) { if (valid_modifiers.find(*it) == std::string_view::npos) throw MP_UNITS_STD_FMT::format_error("invalid unit modifier specified"); } end = it; - if (it = mp_units::detail::at_most_one_of(begin, end, "UA"); it != end) - specs_.encoding = (*it == 'U') ? mp_units::text_encoding::unicode : mp_units::text_encoding::ascii; + if (it = mp_units::detail::at_most_one_of(begin, end, "UAP"); it != end) + // TODO 'A' stands for an old and deprecated ASCII encoding + specs_.encoding = (*it == 'U') ? mp_units::text_encoding::utf8 : mp_units::text_encoding::portable; if (it = mp_units::detail::at_most_one_of(begin, end, "1an"); it != end) { switch (*it) { case '1': @@ -221,8 +223,8 @@ class MP_UNITS_STD_FMT::formatter { } } if (it = mp_units::detail::at_most_one_of(begin, end, "sd"); it != end) { - if (*it == 'd' && specs_.encoding == mp_units::text_encoding::ascii) - throw MP_UNITS_STD_FMT::format_error("half_high_dot unit separator allowed only for Unicode encoding"); + if (*it == 'd' && specs_.encoding == mp_units::text_encoding::portable) + throw MP_UNITS_STD_FMT::format_error("half_high_dot unit separator allowed only for UTF-8 encoding"); specs_.separator = (*it == 's') ? mp_units::unit_symbol_separator::space : mp_units::unit_symbol_separator::half_high_dot; } diff --git a/src/core/include/mp-units/framework/magnitude.h b/src/core/include/mp-units/framework/magnitude.h index 87b46758c..fb80a72a2 100644 --- a/src/core/include/mp-units/framework/magnitude.h +++ b/src/core/include/mp-units/framework/magnitude.h @@ -310,9 +310,9 @@ template Out> constexpr Out print_separator(Out out, const unit_symbol_formatting& fmt) { if (fmt.separator == unit_symbol_separator::half_high_dot) { - if (fmt.encoding != text_encoding::unicode) + if (fmt.encoding != text_encoding::utf8) MP_UNITS_THROW( - std::invalid_argument("'unit_symbol_separator::half_high_dot' can be only used with 'text_encoding::unicode'")); + std::invalid_argument("'unit_symbol_separator::half_high_dot' can be only used with 'text_encoding::utf8'")); const std::string_view dot = "⋅"; out = detail::copy(dot.begin(), dot.end(), out); } else { diff --git a/src/core/include/mp-units/framework/symbol_text.h b/src/core/include/mp-units/framework/symbol_text.h index a08a68444..a627fc9da 100644 --- a/src/core/include/mp-units/framework/symbol_text.h +++ b/src/core/include/mp-units/framework/symbol_text.h @@ -56,9 +56,11 @@ namespace mp_units { // NOLINTNEXTLINE(readability-enum-initial-value) MP_UNITS_EXPORT enum class text_encoding : std::int8_t { - unicode, // µs; m³; L²MT⁻³ - ascii, // us; m^3; L^2MT^-3 - default_encoding = unicode + utf8, // µs; m³; L²MT⁻³ + unicode [[deprecated("Use `utf8` instead")]] = utf8, + portable, // us; m^3; L^2MT^-3 + ascii [[deprecated("Use `portable` instead")]] = portable, + default_encoding = utf8 }; namespace detail { @@ -89,65 +91,67 @@ constexpr fixed_u8string to_u8string(fixed_string txt) * * This class template is responsible for definition and handling of a symbol text * representation. In the libary it is used to define symbols of units and prefixes. - * Each symbol can have two versions: Unicode and ASCI-only. + * Each symbol can have two versions: UTF-8 and portable. * - * @tparam N The size of a Unicode symbol - * @tparam M The size of the ASCII-only symbol + * @tparam N The size of a UTF-8 symbol + * @tparam M The size of the portable symbol */ MP_UNITS_EXPORT template class symbol_text { public: - fixed_u8string unicode_; - fixed_string ascii_; + fixed_u8string utf8_; + fixed_string portable_; // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) - constexpr explicit(false) symbol_text(char ch) : unicode_(static_cast(ch)), ascii_(ch) + constexpr explicit(false) symbol_text(char ch) : utf8_(static_cast(ch)), portable_(ch) { MP_UNITS_EXPECTS(detail::is_basic_literal_character_set_char(ch)); } // NOLINTNEXTLINE(*-avoid-c-arrays, google-explicit-constructor, hicpp-explicit-conversions) consteval explicit(false) symbol_text(const char (&txt)[N + 1]) : - unicode_(detail::to_u8string(basic_fixed_string{txt})), ascii_(txt) + utf8_(detail::to_u8string(basic_fixed_string{txt})), portable_(txt) { MP_UNITS_EXPECTS(txt[N] == char{}); MP_UNITS_EXPECTS(detail::is_basic_literal_character_set(txt)); } // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) - constexpr explicit(false) symbol_text(const fixed_string& txt) : unicode_(detail::to_u8string(txt)), ascii_(txt) + constexpr explicit(false) symbol_text(const fixed_string& txt) : utf8_(detail::to_u8string(txt)), portable_(txt) { MP_UNITS_EXPECTS(detail::is_basic_literal_character_set(txt.data_)); } // NOLINTNEXTLINE(*-avoid-c-arrays) - consteval symbol_text(const char8_t (&u)[N + 1], const char (&a)[M + 1]) : unicode_(u), ascii_(a) + consteval symbol_text(const char8_t (&u)[N + 1], const char (&a)[M + 1]) : utf8_(u), portable_(a) { MP_UNITS_EXPECTS(u[N] == char8_t{}); MP_UNITS_EXPECTS(a[M] == char{}); MP_UNITS_EXPECTS(detail::is_basic_literal_character_set(a)); } - constexpr symbol_text(const fixed_u8string& unicode, const fixed_string& ascii) : - unicode_(unicode), ascii_(ascii) + constexpr symbol_text(const fixed_u8string& utf8, const fixed_string& portable) : + utf8_(utf8), portable_(portable) { - MP_UNITS_EXPECTS(detail::is_basic_literal_character_set(ascii.data_)); + MP_UNITS_EXPECTS(detail::is_basic_literal_character_set(portable.data_)); } - [[nodiscard]] constexpr const auto& unicode() const { return unicode_; } - [[nodiscard]] constexpr const auto& ascii() const { return ascii_; } + [[nodiscard]] constexpr const auto& utf8() const { return utf8_; } + [[nodiscard]] constexpr const auto& portable() const { return portable_; } + [[deprecated("Use `utf8()` instead")]] constexpr const auto& unicode() const { return utf8(); } + [[deprecated("Use `portable()` instead")]] constexpr const auto& ascii() const { return portable(); } [[nodiscard]] constexpr bool empty() const { - MP_UNITS_ASSERT_DEBUG(unicode().empty() == ascii().empty()); - return unicode().empty(); + MP_UNITS_ASSERT_DEBUG(utf8().empty() == portable().empty()); + return utf8().empty(); } template [[nodiscard]] constexpr friend symbol_text operator+(const symbol_text& lhs, const symbol_text& rhs) { - return symbol_text(lhs.unicode() + rhs.unicode(), lhs.ascii() + rhs.ascii()); + return symbol_text(lhs.utf8() + rhs.utf8(), lhs.portable() + rhs.portable()); } template @@ -155,15 +159,15 @@ class symbol_text { { MP_UNITS_DIAGNOSTIC_PUSH MP_UNITS_DIAGNOSTIC_IGNORE_ZERO_AS_NULLPOINTER_CONSTANT - if (const auto cmp = lhs.unicode() <=> rhs.unicode(); cmp != 0) return cmp; + if (const auto cmp = lhs.utf8() <=> rhs.utf8(); cmp != 0) return cmp; MP_UNITS_DIAGNOSTIC_POP - return lhs.ascii() <=> rhs.ascii(); + return lhs.portable() <=> rhs.portable(); } template [[nodiscard]] friend constexpr bool operator==(const symbol_text& lhs, const symbol_text& rhs) noexcept { - return lhs.unicode() == rhs.unicode() && lhs.ascii() == rhs.ascii(); + return lhs.utf8() == rhs.utf8() && lhs.portable() == rhs.portable(); } }; diff --git a/src/core/include/mp-units/framework/unit_symbol_formatting.h b/src/core/include/mp-units/framework/unit_symbol_formatting.h index 422d512f0..c62fc7f73 100644 --- a/src/core/include/mp-units/framework/unit_symbol_formatting.h +++ b/src/core/include/mp-units/framework/unit_symbol_formatting.h @@ -48,7 +48,7 @@ enum class unit_symbol_solidus : std::int8_t { // NOLINTNEXTLINE(readability-enum-initial-value) enum class unit_symbol_separator : std::int8_t { space, // kg m²/s² - half_high_dot, // kg⋅m²/s² (valid only for unicode encoding) + half_high_dot, // kg⋅m²/s² (valid only for utf8 encoding) default_separator = space }; diff --git a/test/runtime/fmt_test.cpp b/test/runtime/fmt_test.cpp index a299d14a7..60a951df4 100644 --- a/test/runtime/fmt_test.cpp +++ b/test/runtime/fmt_test.cpp @@ -443,7 +443,7 @@ TEST_CASE("Unit formatting should use proper text encoding") CHECK(MP_UNITS_STD_FMT::format("{}", m / s2) == "m/s²"); } - SECTION("ASCII text output") + SECTION("Portable text output") { CHECK(MP_UNITS_STD_FMT::format("{:A}", km / h) == "km/h"); CHECK(MP_UNITS_STD_FMT::format("{:A}", si::kilo) == "kohm"); @@ -618,7 +618,7 @@ TEST_CASE("more then one modifier of the same kind should throw", "[text][fmt][e } } -TEST_CASE("half_high_dot separator requested for ASCII encoding should throw", "[text][fmt][exception]") +TEST_CASE("half_high_dot separator requested for portable encoding should throw", "[text][fmt][exception]") { REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:dAa}", MP_UNITS_STD_FMT::make_format_args(m)), MP_UNITS_STD_FMT::format_error, @@ -1037,9 +1037,9 @@ TEST_CASE("unit_symbol", "[text]") CHECK(os.str() == "m/s²"); } - SECTION("ASCII mode") + SECTION("Portable mode") { - os << unit_symbol(m / s2); + os << unit_symbol(m / s2); CHECK(os.str() == "m/s^2"); } @@ -1068,9 +1068,9 @@ TEST_CASE("dimension_symbol", "[text]") CHECK(os.str() == "L²MT⁻³"); } - SECTION("ASCII mode") + SECTION("Portable mode") { - os << dimension_symbol(isq::power.dimension); + os << dimension_symbol(isq::power.dimension); CHECK(os.str() == "L^2MT^-3"); } } diff --git a/test/static/dimension_symbol_test.cpp b/test/static/dimension_symbol_test.cpp index 9f0dbf1d6..40fa1f31a 100644 --- a/test/static/dimension_symbol_test.cpp +++ b/test/static/dimension_symbol_test.cpp @@ -39,14 +39,14 @@ static_assert(dimension_symbol(dimension_one) == "1"); // base dimensions static_assert(dimension_symbol(isq::dim_length) == "L"); static_assert(dimension_symbol(isq::dim_thermodynamic_temperature) == "Θ"); -static_assert(dimension_symbol(isq::dim_thermodynamic_temperature) == +static_assert(dimension_symbol(isq::dim_thermodynamic_temperature) == "O"); // derived dimensions static_assert(dimension_symbol(isq::speed.dimension) == "LT⁻¹"); -static_assert(dimension_symbol(isq::speed.dimension) == "LT^-1"); +static_assert(dimension_symbol(isq::speed.dimension) == "LT^-1"); static_assert(dimension_symbol(isq::power.dimension) == "L²MT⁻³"); -static_assert(dimension_symbol(isq::power.dimension) == "L^2MT^-3"); +static_assert(dimension_symbol(isq::power.dimension) == "L^2MT^-3"); static_assert(dimension_symbol(pow<123>(isq::dim_length)) == "L¹²³"); static_assert(dimension_symbol(pow<1, 2>(isq::dim_length)) == "L^(1/2)"); diff --git a/test/static/symbol_text_test.cpp b/test/static/symbol_text_test.cpp index 10de7f925..96c3402a1 100644 --- a/test/static/symbol_text_test.cpp +++ b/test/static/symbol_text_test.cpp @@ -37,26 +37,26 @@ static_assert(sym1 <= 'b'); static_assert(sym1 <= 'c'); static_assert(sym1 >= 'b'); static_assert(sym1 >= 'a'); -static_assert(sym1.unicode() == u8"b"); -static_assert(sym1.ascii() == "b"); +static_assert(sym1.utf8() == u8"b"); +static_assert(sym1.portable() == "b"); constexpr symbol_text sym3("ab"); -static_assert(sym3.unicode() == u8"ab"); -static_assert(sym3.ascii() == "ab"); +static_assert(sym3.utf8() == u8"ab"); +static_assert(sym3.portable() == "ab"); constexpr basic_fixed_string txt1("bc"); constexpr symbol_text sym4(txt1); -static_assert(sym4.unicode() == u8"bc"); -static_assert(sym4.ascii() == "bc"); +static_assert(sym4.utf8() == u8"bc"); +static_assert(sym4.portable() == "bc"); constexpr symbol_text sym5(u8"bc", "de"); -static_assert(sym5.unicode() == u8"bc"); -static_assert(sym5.ascii() == "de"); +static_assert(sym5.utf8() == u8"bc"); +static_assert(sym5.portable() == "de"); constexpr basic_fixed_string txt2("de"); -constexpr symbol_text sym6(sym4.unicode(), txt2); -static_assert(sym6.unicode() == u8"bc"); -static_assert(sym6.ascii() == "de"); +constexpr symbol_text sym6(sym4.utf8(), txt2); +static_assert(sym6.utf8() == u8"bc"); +static_assert(sym6.portable() == "de"); static_assert(sym6 == symbol_text(u8"bc", "de")); static_assert(sym6 != symbol_text(u8"fg", "hi")); diff --git a/test/static/unit_symbol_test.cpp b/test/static/unit_symbol_test.cpp index 9e9b5376f..1e4b2d60e 100644 --- a/test/static/unit_symbol_test.cpp +++ b/test/static/unit_symbol_test.cpp @@ -48,59 +48,59 @@ static_assert(unit_symbol(metre) == "m"); static_assert(unit_symbol(second) == "s"); static_assert(unit_symbol(joule) == "J"); static_assert(unit_symbol(degree_Celsius) == "\u2103"); -static_assert(unit_symbol(degree_Celsius) == "`C"); +static_assert(unit_symbol(degree_Celsius) == "`C"); static_assert(unit_symbol(kilogram) == "kg"); static_assert(unit_symbol(hour) == "h"); // prefixed units static_assert(unit_symbol(quecto) == "qΩ"); -static_assert(unit_symbol(quecto) == "qohm"); +static_assert(unit_symbol(quecto) == "qohm"); static_assert(unit_symbol(ronto) == "rΩ"); -static_assert(unit_symbol(ronto) == "rohm"); +static_assert(unit_symbol(ronto) == "rohm"); static_assert(unit_symbol(yocto) == "yΩ"); -static_assert(unit_symbol(yocto) == "yohm"); +static_assert(unit_symbol(yocto) == "yohm"); static_assert(unit_symbol(zepto) == "zΩ"); -static_assert(unit_symbol(zepto) == "zohm"); +static_assert(unit_symbol(zepto) == "zohm"); static_assert(unit_symbol(atto) == "aΩ"); -static_assert(unit_symbol(atto) == "aohm"); +static_assert(unit_symbol(atto) == "aohm"); static_assert(unit_symbol(femto) == "fΩ"); -static_assert(unit_symbol(femto) == "fohm"); +static_assert(unit_symbol(femto) == "fohm"); static_assert(unit_symbol(pico) == "pΩ"); -static_assert(unit_symbol(pico) == "pohm"); +static_assert(unit_symbol(pico) == "pohm"); static_assert(unit_symbol(nano) == "nΩ"); -static_assert(unit_symbol(nano) == "nohm"); +static_assert(unit_symbol(nano) == "nohm"); static_assert(unit_symbol(micro) == "µΩ"); -static_assert(unit_symbol(micro) == "uohm"); +static_assert(unit_symbol(micro) == "uohm"); static_assert(unit_symbol(milli) == "mΩ"); -static_assert(unit_symbol(milli) == "mohm"); +static_assert(unit_symbol(milli) == "mohm"); static_assert(unit_symbol(centi) == "cΩ"); -static_assert(unit_symbol(centi) == "cohm"); +static_assert(unit_symbol(centi) == "cohm"); static_assert(unit_symbol(deci) == "dΩ"); -static_assert(unit_symbol(deci) == "dohm"); +static_assert(unit_symbol(deci) == "dohm"); static_assert(unit_symbol(deca) == "daΩ"); -static_assert(unit_symbol(deca) == "daohm"); +static_assert(unit_symbol(deca) == "daohm"); static_assert(unit_symbol(hecto) == "hΩ"); -static_assert(unit_symbol(hecto) == "hohm"); +static_assert(unit_symbol(hecto) == "hohm"); static_assert(unit_symbol(kilo) == "kΩ"); -static_assert(unit_symbol(kilo) == "kohm"); +static_assert(unit_symbol(kilo) == "kohm"); static_assert(unit_symbol(mega) == "MΩ"); -static_assert(unit_symbol(mega) == "Mohm"); +static_assert(unit_symbol(mega) == "Mohm"); static_assert(unit_symbol(giga) == "GΩ"); -static_assert(unit_symbol(giga) == "Gohm"); +static_assert(unit_symbol(giga) == "Gohm"); static_assert(unit_symbol(tera) == "TΩ"); -static_assert(unit_symbol(tera) == "Tohm"); +static_assert(unit_symbol(tera) == "Tohm"); static_assert(unit_symbol(peta) == "PΩ"); -static_assert(unit_symbol(peta) == "Pohm"); +static_assert(unit_symbol(peta) == "Pohm"); static_assert(unit_symbol(exa) == "EΩ"); -static_assert(unit_symbol(exa) == "Eohm"); +static_assert(unit_symbol(exa) == "Eohm"); static_assert(unit_symbol(zetta) == "ZΩ"); -static_assert(unit_symbol(zetta) == "Zohm"); +static_assert(unit_symbol(zetta) == "Zohm"); static_assert(unit_symbol(yotta) == "YΩ"); -static_assert(unit_symbol(yotta) == "Yohm"); +static_assert(unit_symbol(yotta) == "Yohm"); static_assert(unit_symbol(ronna) == "RΩ"); -static_assert(unit_symbol(ronna) == "Rohm"); +static_assert(unit_symbol(ronna) == "Rohm"); static_assert(unit_symbol(quetta) == "QΩ"); -static_assert(unit_symbol(quetta) == "Qohm"); +static_assert(unit_symbol(quetta) == "Qohm"); static_assert(unit_symbol(kibi) == "Kibit"); static_assert(unit_symbol(mebi) == "Mibit"); @@ -113,13 +113,13 @@ static_assert(unit_symbol(yobi) == "Yibit"); // scaled units static_assert(unit_symbol(mag<100> * metre) == "[100 m]"); -static_assert(unit_symbol(mag<100> * metre) == "[100 m]"); +static_assert(unit_symbol(mag<100> * metre) == "[100 m]"); static_assert(unit_symbol(mag<1000> * metre) == "[10³ m]"); static_assert(unit_symbol(mag_power<10, 3> * metre) == "[10³ m]"); -static_assert(unit_symbol(mag<1000> * metre) == "[10^3 m]"); +static_assert(unit_symbol(mag<1000> * metre) == "[10^3 m]"); static_assert(unit_symbol(mag<6000> * metre) == "[6 × 10³ m]"); static_assert(unit_symbol(mag<6> * mag_power<10, 3> * metre) == "[6 × 10³ m]"); -static_assert(unit_symbol(mag<6000> * metre) == "[6 x 10^3 m]"); +static_assert(unit_symbol(mag<6000> * metre) == "[6 x 10^3 m]"); static_assert(unit_symbol(mag<10600> * metre) == "[10600 m]"); static_assert(unit_symbol(mag<60> * second) == "[60 s]"); static_assert(unit_symbol(mag_ratio<1, 18> * metre / second) == "[1/18 m]/s"); @@ -128,18 +128,18 @@ static_assert(unit_symbol(mag_ratio<1, 1800> * metre / second) == "[1/1800 m]/s" static_assert(unit_symbol(mag_ratio<1, 1800> * (metre / second)) == "[1/1800 m/s]"); static_assert(unit_symbol(mag_ratio<1, 18000> * metre / second) == "[1/18 × 10⁻³ m]/s"); static_assert(unit_symbol(mag_ratio<1, 18000> * (metre / second)) == "[1/18 × 10⁻³ m/s]"); -static_assert(unit_symbol(mag_ratio<1, 18000> * metre / second) == "[1/18 x 10^-3 m]/s"); -static_assert(unit_symbol(mag_ratio<1, 18000> * (metre / second)) == "[1/18 x 10^-3 m/s]"); +static_assert(unit_symbol(mag_ratio<1, 18000> * metre / second) == "[1/18 x 10^-3 m]/s"); +static_assert(unit_symbol(mag_ratio<1, 18000> * (metre / second)) == "[1/18 x 10^-3 m/s]"); // TODO implement all the below // static_assert(unit_symbol(mag_power<2, 1, 2> * one) == "[2^(1/2)]"); -// static_assert(unit_symbol(mag_power<2, 1, 2> * one) == "[2^(1/2)]"); +// static_assert(unit_symbol(mag_power<2, 1, 2> * one) == "[2^(1/2)]"); // static_assert(unit_symbol(mag_power<2, 1, 2> * m) == "[2^(1/2) m]"); -// static_assert(unit_symbol(mag_power<2, 1, 2> * m) == "[2^(1/2) m]"); +// static_assert(unit_symbol(mag_power<2, 1, 2> * m) == "[2^(1/2) m]"); // static_assert(unit_symbol(mag<1> / mag_power<2, 1, 2> * one) == "[1/2^(1/2)]"); -// static_assert(unit_symbol(mag<1> / mag_power<2, 1, 2> * one) == "[1/2^(1/2)]"); +// static_assert(unit_symbol(mag<1> / mag_power<2, 1, 2> * one) == "[1/2^(1/2)]"); // static_assert(unit_symbol(mag<1> / mag_power<2, 1, 2> * m) == "[1/2^(1/2) m]"); -// static_assert(unit_symbol(mag<1> / mag_power<2, 1, 2> * m) == "[1/2^(1/2) m]"); +// static_assert(unit_symbol(mag<1> / mag_power<2, 1, 2> * m) == "[1/2^(1/2) m]"); // magnitude constants #if defined MP_UNITS_COMP_CLANG || MP_UNITS_COMP_CLANG < 18 @@ -151,47 +151,47 @@ inline constexpr struct e final : mag_constant<"e", std::numbers::e_v * one) == "[𝜋]"); -static_assert(unit_symbol(mag * one) == "[pi]"); +static_assert(unit_symbol(mag * one) == "[pi]"); static_assert(unit_symbol(mag * metre) == "[𝜋 m]"); -static_assert(unit_symbol(mag * metre) == "[pi m]"); +static_assert(unit_symbol(mag * metre) == "[pi m]"); static_assert(unit_symbol(mag<2> * mag * metre) == "[2 𝜋 m]"); -static_assert(unit_symbol(mag<2> * mag * metre) == "[2 pi m]"); +static_assert(unit_symbol(mag<2> * mag * metre) == "[2 pi m]"); static_assert(unit_symbol(mag<2> * mag * metre) == "[2⋅𝜋 m]"); static_assert(unit_symbol(mag<1> / mag * one) == "[1/𝜋]"); -static_assert(unit_symbol(mag<1> / mag * one) == "[1/pi]"); +static_assert(unit_symbol(mag<1> / mag * one) == "[1/pi]"); static_assert(unit_symbol(mag<1> / mag * one) == "[𝜋⁻¹]"); -static_assert(unit_symbol(mag<1> / mag * one) == "[pi^-1]"); +static_assert(unit_symbol(mag<1> / mag * one) == "[pi^-1]"); static_assert(unit_symbol(mag<1> / mag * metre) == "[1/𝜋 m]"); -static_assert(unit_symbol(mag<1> / mag * metre) == "[1/pi m]"); +static_assert(unit_symbol(mag<1> / mag * metre) == "[1/pi m]"); static_assert(unit_symbol(mag<1> / mag * metre) == "[𝜋⁻¹ m]"); -static_assert(unit_symbol(mag<1> / mag * metre) == "[pi^-1 m]"); +static_assert(unit_symbol(mag<1> / mag * metre) == "[pi^-1 m]"); static_assert(unit_symbol(mag<2> / mag * metre) == "[2/𝜋 m]"); -static_assert(unit_symbol(mag<2> / mag * metre) == "[2/pi m]"); +static_assert(unit_symbol(mag<2> / mag * metre) == "[2/pi m]"); static_assert(unit_symbol(mag<2> / mag * metre) == "[2 𝜋⁻¹ m]"); -static_assert(unit_symbol(mag<2> / mag * metre) == "[2 pi^-1 m]"); +static_assert(unit_symbol(mag<2> / mag * metre) == "[2 pi^-1 m]"); static_assert(unit_symbol(mag<2> / mag * metre) == "[2⋅𝜋⁻¹ m]"); static_assert(unit_symbol(mag<1> / (mag<2> * mag)*metre) == "[2⁻¹ 𝜋⁻¹ m]"); static_assert(unit_symbol(mag<1> / (mag<2> * mag)*metre) == "[1/(2 𝜋) m]"); -static_assert(unit_symbol(mag<1> / (mag<2> * mag)*metre) == +static_assert(unit_symbol(mag<1> / (mag<2> * mag)*metre) == "[1/(2 pi) m]"); static_assert(unit_symbol(mag_ratio<1, 2> / mag * metre) == "[2⁻¹ 𝜋⁻¹ m]"); static_assert(unit_symbol(mag_ratio<1, 2> / mag * metre) == "[1/(2 𝜋) m]"); -static_assert(unit_symbol(mag_ratio<1, 2> / mag * metre) == +static_assert(unit_symbol(mag_ratio<1, 2> / mag * metre) == "[1/(2 pi) m]"); static_assert(unit_symbol(mag_ratio<1, 2> * mag * metre) == "[𝜋/2 m]"); static_assert(unit_symbol(mag_power * one) == "[𝜋²]"); -static_assert(unit_symbol(mag_power * one) == "[pi^2]"); +static_assert(unit_symbol(mag_power * one) == "[pi^2]"); static_assert(unit_symbol(mag_power * metre) == "[𝜋^(1/2) m]"); -static_assert(unit_symbol(mag_power * metre) == "[pi^(1/2) m]"); +static_assert(unit_symbol(mag_power * metre) == "[pi^(1/2) m]"); static_assert(unit_symbol(mag * mag * one) == "[e 𝜋]"); static_assert(unit_symbol(mag * mag * one) == "[e 𝜋]"); -static_assert(unit_symbol(mag * mag * one) == "[e pi]"); +static_assert(unit_symbol(mag * mag * one) == "[e pi]"); static_assert(unit_symbol(mag / mag * one) == "[𝜋/e]"); static_assert(unit_symbol(mag<1> / mag * mag * one) == "[𝜋/e]"); static_assert(unit_symbol(mag / mag * one) == "[𝜋 e⁻¹]"); @@ -216,49 +216,51 @@ static_assert(unit_symbol(get_common_unit(radian, degree)) == "EQUIV{[1/𝜋°], static_assert(unit_symbol(one) == ""); // NOLINT(readability-container-size-empty) static_assert(unit_symbol(percent) == "%"); static_assert(unit_symbol(per_mille) == "‰"); -static_assert(unit_symbol(per_mille) == "%o"); +static_assert(unit_symbol(per_mille) == "%o"); static_assert(unit_symbol(parts_per_million) == "ppm"); static_assert(unit_symbol(square(metre)) == "m²"); -static_assert(unit_symbol(square(metre)) == "m^2"); +static_assert(unit_symbol(square(metre)) == "m^2"); static_assert(unit_symbol(cubic(metre)) == "m³"); -static_assert(unit_symbol(cubic(metre)) == "m^3"); +static_assert(unit_symbol(cubic(metre)) == "m^3"); static_assert(unit_symbol(kilo * metre) == "km m"); static_assert(unit_symbol(kilo * metre) == "km⋅m"); static_assert(unit_symbol(metre / metre) == ""); // NOLINT(readability-container-size-empty) static_assert(unit_symbol(kilo / metre) == "km/m"); static_assert(unit_symbol(kilo / metre) == "km m⁻¹"); -static_assert(unit_symbol(kilo / metre) == "km m^-1"); +static_assert(unit_symbol(kilo / metre) == "km m^-1"); static_assert(unit_symbol(metre / second) == "m/s"); static_assert(unit_symbol(metre / second) == "m/s"); static_assert(unit_symbol(metre / second) == "m s⁻¹"); -static_assert(unit_symbol(metre / second) == "m s^-1"); +static_assert(unit_symbol(metre / second) == "m s^-1"); static_assert(unit_symbol(metre / second) == "m⋅s⁻¹"); static_assert(unit_symbol(metre / square(second)) == "m/s²"); -static_assert(unit_symbol(metre / square(second)) == "m/s^2"); +static_assert(unit_symbol(metre / square(second)) == "m/s^2"); static_assert(unit_symbol(metre / square(second)) == "m/s²"); -static_assert(unit_symbol(metre / square(second)) == "m/s^2"); +static_assert(unit_symbol(metre / square(second)) == "m/s^2"); static_assert(unit_symbol(metre / square(second)) == "m s⁻²"); -static_assert(unit_symbol(metre / square(second)) == "m s^-2"); +static_assert(unit_symbol(metre / square(second)) == "m s^-2"); static_assert(unit_symbol(metre / square(second)) == "m⋅s⁻²"); static_assert(unit_symbol(kilogram * metre / square(second)) == "kg m/s²"); static_assert(unit_symbol(kilogram * metre / square(second)) == "kg⋅m/s²"); -static_assert(unit_symbol(kilogram * metre / square(second)) == "kg m/s^2"); +static_assert(unit_symbol(kilogram * metre / square(second)) == "kg m/s^2"); static_assert(unit_symbol(kilogram * metre / square(second)) == "kg m/s²"); -static_assert(unit_symbol(kilogram * metre / square(second)) == "kg m/s^2"); +static_assert(unit_symbol(kilogram * metre / square(second)) == + "kg m/s^2"); static_assert(unit_symbol(kilogram * metre / square(second)) == "kg m s⁻²"); -static_assert(unit_symbol(kilogram * metre / square(second)) == "kg m s^-2"); +static_assert(unit_symbol(kilogram * metre / square(second)) == + "kg m s^-2"); static_assert(unit_symbol(kilogram * metre / square(second)) == "kg⋅m⋅s⁻²"); static_assert(unit_symbol(one / metre / square(second)) == "m⁻¹ s⁻²"); static_assert(unit_symbol(one / metre / square(second)) == "1/(m s²)"); static_assert(unit_symbol(kilogram / metre / square(second)) == "kg m⁻¹ s⁻²"); static_assert(unit_symbol(kilogram / metre / square(second)) == "kg⋅m⁻¹⋅s⁻²"); -static_assert(unit_symbol(kilogram / metre / square(second)) == "kg m^-1 s^-2"); +static_assert(unit_symbol(kilogram / metre / square(second)) == "kg m^-1 s^-2"); static_assert(unit_symbol(kilogram / metre / square(second)) == "kg/(m s²)"); -static_assert(unit_symbol(kilogram / metre / square(second)) == +static_assert(unit_symbol(kilogram / metre / square(second)) == "kg/(m s^2)"); static_assert(unit_symbol(kilogram / metre / square(second)) == "kg m⁻¹ s⁻²"); -static_assert(unit_symbol(kilogram / metre / square(second)) == +static_assert(unit_symbol(kilogram / metre / square(second)) == "kg m^-1 s^-2"); static_assert(unit_symbol(kilogram / metre / square(second)) == "kg⋅m⁻¹⋅s⁻²");