From f5df68253ea89954f684c308db52f1840947981a Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Fri, 27 Mar 2020 15:21:05 +0100 Subject: [PATCH] symbol_text refactored --- src/include/units/symbol_text.h | 133 ++++++------------ test/unit_test/static/CMakeLists.txt | 2 +- test/unit_test/static/cgs_test.cpp | 2 +- test/unit_test/static/si_test.cpp | 8 +- ...d_symbol_test.cpp => symbol_text_test.cpp} | 56 ++++---- 5 files changed, 80 insertions(+), 121 deletions(-) rename test/unit_test/static/{fixed_symbol_test.cpp => symbol_text_test.cpp} (58%) diff --git a/src/include/units/symbol_text.h b/src/include/units/symbol_text.h index ddbb2720..3aca1c45 100644 --- a/src/include/units/symbol_text.h +++ b/src/include/units/symbol_text.h @@ -1,30 +1,36 @@ #pragma once -#include #include +#include namespace units { +namespace detail { + +constexpr void validate_ascii_char([[maybe_unused]] char c) noexcept { Expects((c & 0x80) == 0); } + +template +constexpr void validate_ascii_string([[maybe_unused]] const char (&s)[P + 1]) noexcept +{ +#ifndef NDEBUG + for (size_t i = 0; i < P; ++i) + validate_ascii_char(s[i]); +#endif +} + +} + template struct basic_symbol_text { basic_fixed_string standard_; basic_fixed_string ascii_; - constexpr void validate_ascii_char([[maybe_unused]] char c) noexcept { assert((c & 0x80) == 0); } - - template - constexpr void validate_ascii_string(const char (&s)[P + 1]) noexcept - { - for (size_t i = 0; i < P; ++i) - validate_ascii_char(s[i]); - } - - constexpr basic_symbol_text(StandardCharT s) noexcept: standard_(s), ascii_(s) { validate_ascii_char(s); } - constexpr basic_symbol_text(StandardCharT s, char a) noexcept: standard_(s), ascii_(a) { validate_ascii_char(a); } - constexpr basic_symbol_text(const StandardCharT (&s)[N + 1]) noexcept: standard_(s), ascii_(s) { validate_ascii_string(s); } - constexpr basic_symbol_text(const basic_fixed_string& s) noexcept: standard_(s), ascii_(s) { validate_ascii_string(s.data_); } - constexpr basic_symbol_text(const StandardCharT (&s)[N + 1], const char (&a)[M + 1]) noexcept: standard_(s), ascii_(a) { validate_ascii_string(a); } - constexpr basic_symbol_text(const basic_fixed_string& s, const basic_fixed_string& a) noexcept: standard_(s), ascii_(a) { validate_ascii_string(a.data_); } + constexpr basic_symbol_text(StandardCharT s) noexcept: standard_(s), ascii_(s) { detail::validate_ascii_char(s); } + constexpr basic_symbol_text(StandardCharT s, char a) noexcept: standard_(s), ascii_(a) { detail::validate_ascii_char(a); } + constexpr basic_symbol_text(const StandardCharT (&s)[N + 1]) noexcept: standard_(s), ascii_(s) { detail::validate_ascii_string(s); } + constexpr basic_symbol_text(const basic_fixed_string& s) noexcept: standard_(s), ascii_(s) { detail::validate_ascii_string(s.data_); } + constexpr basic_symbol_text(const StandardCharT (&s)[N + 1], const char (&a)[M + 1]) noexcept: standard_(s), ascii_(a) { detail::validate_ascii_string(a); } + constexpr basic_symbol_text(const basic_fixed_string& s, const basic_fixed_string& a) noexcept: standard_(s), ascii_(a) { detail::validate_ascii_string(a.data_); } [[nodiscard]] constexpr auto& standard() { return standard_; } [[nodiscard]] constexpr const auto& standard() const { return standard_; } @@ -83,73 +89,28 @@ struct basic_symbol_text { template [[nodiscard]] friend constexpr auto operator<=>(const basic_symbol_text& lhs, - const basic_symbol_text& rhs) + const basic_symbol_text& rhs) noexcept { - auto comparison = std::lexicographical_compare_three_way(lhs.standard_.begin(), lhs.standard_.end(), rhs.standard_.begin(), rhs.standard_.end()); - assert(std::lexicographical_compare_three_way(lhs.ascii_.begin(), lhs.ascii_.end(), rhs.ascii_.begin(), rhs.ascii_.end()) == comparison); - return comparison; - } - - template - [[nodiscard]] friend constexpr auto operator<=>(const basic_symbol_text& lhs, - const basic_fixed_string& rhs) - { - return std::lexicographical_compare_three_way(lhs.standard_.begin(), lhs.standard_.end(), rhs.begin(), rhs.end()); - } - - template - [[nodiscard]] friend constexpr auto operator<=>(const basic_symbol_text& lhs, - const StandardCharT2 (&rhs)[N2]) - { - return lhs <=> basic_fixed_string(rhs); - } - - template - [[nodiscard]] friend constexpr auto operator<=>(const basic_symbol_text& lhs, - StandardCharT2 rhs) - { - return lhs <=> basic_fixed_string(rhs); + if (const auto cmp = lhs.standard_ <=> rhs.standard_; cmp != 0) return cmp; + return lhs.ascii_ <=> rhs.ascii_; } template [[nodiscard]] friend constexpr bool operator==(const basic_symbol_text& lhs, - const basic_symbol_text& rhs) + const basic_symbol_text& rhs) noexcept { - bool comparison = std::equal(lhs.standard_.begin(), lhs.standard_.end(), rhs.standard_.begin(), rhs.standard_.end()); - assert(std::equal(lhs.ascii_.begin(), lhs.ascii_.end(), rhs.ascii_.begin(), rhs.ascii_.end()) == comparison); - return comparison; - } - - template - [[nodiscard]] friend constexpr bool operator==(const basic_symbol_text& lhs, - const basic_fixed_string& rhs) - { - return std::equal(lhs.standard_.begin(), lhs.standard_.end(), rhs.begin(), rhs.end()); - } - - template - [[nodiscard]] friend constexpr bool operator==(const basic_symbol_text& lhs, - const StandardCharT2 (&rhs)[N2]) - { - return lhs == basic_fixed_string(rhs); - } - - template - [[nodiscard]] friend constexpr bool operator==(const basic_symbol_text& lhs, - StandardCharT2 rhs) - { - return lhs == basic_fixed_string(rhs); + return lhs.standard_ == rhs.standard_ && lhs.ascii_ == rhs.ascii_; } #else + // I did not update the below operators with comparing ASCII as this code is going to be deleted soon anyway... + template [[nodiscard]] constexpr friend bool operator==(const basic_symbol_text& lhs, const basic_symbol_text& rhs) noexcept { - bool comparison = (lhs.standard_ == rhs.standard_); - assert((lhs.ascii_ == rhs.ascii_) == comparison); - return comparison; + return lhs.standard_ == rhs.standard_; } template @@ -241,9 +202,7 @@ struct basic_symbol_text { [[nodiscard]] constexpr friend bool operator<(const basic_symbol_text& lhs, const basic_symbol_text& rhs) noexcept { - bool comparison = lhs.standard_ < rhs.standard_; - assert((lhs.ascii_ < rhs.ascii_) == comparison); - return comparison; + return lhs.standard_ < rhs.standard_; } template @@ -271,90 +230,84 @@ struct basic_symbol_text { [[nodiscard]] constexpr friend bool operator>(const basic_symbol_text& lhs, const basic_symbol_text& rhs) noexcept { - bool comparison = lhs.standard_ > rhs.standard_; - assert((lhs.ascii_ > rhs.ascii_) == comparison); - return comparison; + return rhs < lhs; } template [[nodiscard]] constexpr friend bool operator>(const basic_symbol_text& lhs, const basic_fixed_string& rhs) noexcept { - return lhs.standard_ > rhs; + return rhs < lhs; } template [[nodiscard]] constexpr friend bool operator>(const basic_symbol_text& lhs, const StandardCharT2 (&rhs)[N2]) noexcept { - return lhs.standard_ > basic_fixed_string(rhs); + return rhs < lhs; } template [[nodiscard]] constexpr friend bool operator>(const basic_symbol_text& lhs, StandardCharT2 rhs) noexcept { - return lhs.standard_ > basic_fixed_string(rhs); + return rhs < lhs; } template [[nodiscard]] constexpr friend bool operator<=(const basic_symbol_text& lhs, const basic_symbol_text& rhs) noexcept { - bool comparison = lhs.standard_ <= rhs.standard_; - assert((lhs.ascii_ <= rhs.ascii_) == comparison); - return comparison; + return !(rhs < lhs); } template [[nodiscard]] constexpr friend bool operator<=(const basic_symbol_text& lhs, const basic_fixed_string& rhs) noexcept { - return lhs.standard_ <= rhs; + return !(rhs < lhs); } template [[nodiscard]] constexpr friend bool operator<=(const basic_symbol_text& lhs, const StandardCharT2 (&rhs)[N2]) noexcept { - return lhs.standard_ <= basic_fixed_string(rhs); + return !(rhs < lhs); } template [[nodiscard]] constexpr friend bool operator<=(const basic_symbol_text& lhs, StandardCharT2 rhs) noexcept { - return lhs.standard_ <= basic_fixed_string(rhs); + return !(rhs < lhs); } template [[nodiscard]] constexpr friend bool operator>=(const basic_symbol_text& lhs, const basic_symbol_text& rhs) noexcept { - bool comparison = lhs.standard_ >= rhs.standard_; - assert((lhs.ascii_ >= rhs.ascii_) == comparison); - return comparison; + return !(lhs < rhs); } template [[nodiscard]] constexpr friend bool operator>=(const basic_symbol_text& lhs, const basic_fixed_string& rhs) noexcept { - return lhs.standard_ >= rhs; + return !(lhs < rhs); } template [[nodiscard]] constexpr friend bool operator>=(const basic_symbol_text& lhs, const StandardCharT2 (&rhs)[N2]) noexcept { - return lhs.standard_ >= basic_fixed_string(rhs); + return !(lhs < rhs); } template [[nodiscard]] constexpr friend bool operator>=(const basic_symbol_text& lhs, StandardCharT2 rhs) noexcept { - return lhs.standard_ >= basic_fixed_string(rhs); + return !(lhs < rhs); } #endif diff --git a/test/unit_test/static/CMakeLists.txt b/test/unit_test/static/CMakeLists.txt index c5516336..8c4610b0 100644 --- a/test/unit_test/static/CMakeLists.txt +++ b/test/unit_test/static/CMakeLists.txt @@ -28,12 +28,12 @@ add_library(unit_tests_static dimension_op_test.cpp dimensions_concepts_test.cpp fixed_string_test.cpp - fixed_symbol_test.cpp math_test.cpp quantity_test.cpp ratio_test.cpp si_test.cpp si_cgs_test.cpp + symbol_text_test.cpp type_list_test.cpp unit_test.cpp us_test.cpp diff --git a/test/unit_test/static/cgs_test.cpp b/test/unit_test/static/cgs_test.cpp index 294bb54e..ac33c0f3 100644 --- a/test/unit_test/static/cgs_test.cpp +++ b/test/unit_test/static/cgs_test.cpp @@ -62,7 +62,7 @@ static_assert(std::is_same_v() == "cm²"); +static_assert(detail::unit_text() == basic_symbol_text("cm²", "cm^2")); /* ************** DERIVED DIMENSIONS WITH NAMED UNITS **************** */ diff --git a/test/unit_test/static/si_test.cpp b/test/unit_test/static/si_test.cpp index 320665dd..bc49edfe 100644 --- a/test/unit_test/static/si_test.cpp +++ b/test/unit_test/static/si_test.cpp @@ -86,7 +86,7 @@ static_assert(1q_d == 24q_h); static_assert(1q_d == 86'400q_s); static_assert(nanosecond::symbol == "ns"); -static_assert(microsecond::symbol == "µs"); +static_assert(microsecond::symbol == basic_symbol_text("µs", "us")); static_assert(millisecond::symbol == "ms"); // current @@ -219,7 +219,7 @@ static_assert(10q_m_per_s / 10q_s == 1q_m_per_s2); static_assert(10q_m_per_s / 1q_m_per_s2 == 10q_s); static_assert(1q_m_per_s2 * 10q_s == 10q_m_per_s); -static_assert(detail::unit_text() == "m/s²"); +static_assert(detail::unit_text() == basic_symbol_text("m/s²", "m/s^2")); // area @@ -229,7 +229,7 @@ static_assert(10q_km * 10q_km == 100q_km2); static_assert(1q_m2 == 10'000q_cm2); static_assert(1q_ha == 10'000q_m2); -static_assert(detail::unit_text() == "m²"); +static_assert(detail::unit_text() == basic_symbol_text("m²", "m^2")); // volume @@ -240,7 +240,7 @@ static_assert(1q_m3 == 1'000'000q_cm3); static_assert(1q_dm * 1q_dm * 1q_dm == 1q_l); static_assert(1000q_l == 1q_m3); -static_assert(detail::unit_text() == "m³"); +static_assert(detail::unit_text() == basic_symbol_text("m³", "m^3")); /* ************** DERIVED DIMENSIONS IN TERMS OF OTHER UNITS **************** */ diff --git a/test/unit_test/static/fixed_symbol_test.cpp b/test/unit_test/static/symbol_text_test.cpp similarity index 58% rename from test/unit_test/static/fixed_symbol_test.cpp rename to test/unit_test/static/symbol_text_test.cpp index c9bcea18..e50f7443 100644 --- a/test/unit_test/static/fixed_symbol_test.cpp +++ b/test/unit_test/static/symbol_text_test.cpp @@ -1,3 +1,25 @@ +// 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 "units/symbol_text.h" using namespace units; @@ -7,7 +29,7 @@ namespace { constexpr basic_symbol_text sym1('b'); static_assert(sym1 == 'b'); static_assert(sym1 != 'a'); -static_assert(sym1 != "ab"); +static_assert(sym1 != basic_symbol_text("ab")); static_assert(sym1 < 'c'); static_assert(sym1 > 'a'); static_assert(sym1 <= 'b'); @@ -18,7 +40,7 @@ static_assert(sym1.standard() == 'b'); static_assert(sym1.ascii() == 'b'); constexpr basic_symbol_text sym2('a', 'b'); -static_assert(sym2 == 'a'); +static_assert(sym2 == basic_symbol_text('a', 'b')); static_assert(sym2 != 'b'); static_assert(sym2.standard() == 'a'); static_assert(sym2.ascii() == 'b'); @@ -45,29 +67,12 @@ static_assert(sym6 == basic_symbol_text("bc", "de")); static_assert(sym6 != basic_symbol_text("fg", "hi")); static_assert(sym6 != basic_symbol_text("bcd", "ef")); -static_assert(sym6 == basic_fixed_string("bc")); -static_assert(sym6 != basic_fixed_string("de")); -static_assert(sym6 != basic_fixed_string("fg")); -static_assert(sym6 != basic_fixed_string("bcd")); - -static_assert(sym6 == "bc"); -static_assert(sym6 != "de"); -static_assert(sym6 != "fg"); -static_assert(sym6 != "bcd"); - -static_assert(sym6 < basic_fixed_string("c")); -static_assert(sym6 > basic_fixed_string("a")); -static_assert(sym6 <= basic_fixed_string("c")); -static_assert(sym6 <= basic_fixed_string("bcd")); -static_assert(sym6 >= basic_fixed_string("a")); -static_assert(sym6 >= basic_fixed_string("bc")); - -static_assert(sym6 < "c"); -static_assert(sym6 > "a"); -static_assert(sym6 <= "c"); -static_assert(sym6 <= "bcd"); -static_assert(sym6 >= "a"); -static_assert(sym6 >= "bc"); +static_assert(sym6 < basic_symbol_text("c")); +static_assert(sym6 > basic_symbol_text("a")); +static_assert(sym6 <= basic_symbol_text("c")); +static_assert(sym6 <= basic_symbol_text("bcd")); +static_assert(sym6 >= basic_symbol_text("a")); +static_assert(sym6 >= basic_symbol_text("bc")); static_assert(basic_symbol_text("a") + sym4 == basic_symbol_text("abc")); static_assert(sym4 + basic_symbol_text("f") == basic_symbol_text("bcf")); @@ -86,4 +91,5 @@ static_assert(sym6 + basic_fixed_string("f") == basic_symbol_text("bcf", "def")) static_assert("a" + sym6 == basic_symbol_text("abc", "ade")); static_assert(sym6 + "f" == basic_symbol_text("bcf", "def")); + }