From 7cad312b55ddbfd317a26040f9035be0034e4ac6 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Mon, 23 Dec 2019 13:21:48 +0100 Subject: [PATCH] fixed_string refactored --- .../units/bits/external/fixed_string.h | 166 +++++++++++------- 1 file changed, 102 insertions(+), 64 deletions(-) diff --git a/src/include/units/bits/external/fixed_string.h b/src/include/units/bits/external/fixed_string.h index 48e27e44..0fe86f97 100644 --- a/src/include/units/bits/external/fixed_string.h +++ b/src/include/units/bits/external/fixed_string.h @@ -27,85 +27,123 @@ namespace units { - template - struct basic_fixed_string { - CharT data_[N + 1] = {}; +template +struct basic_fixed_string { + CharT data_[N + 1] = {}; - constexpr basic_fixed_string(CharT ch) noexcept - { - data_[0] = ch; - } + constexpr basic_fixed_string(CharT ch) noexcept { data_[0] = ch; } - constexpr basic_fixed_string(const CharT (&txt)[N + 1]) noexcept - { - for(std::size_t i = 0; i < N; ++i) - data_[i] = txt[i]; - } + constexpr basic_fixed_string(const CharT (&txt)[N + 1]) noexcept + { + for (std::size_t i = 0; i < N; ++i) data_[i] = txt[i]; + } - [[nodiscard]] constexpr std::size_t size() const noexcept { return N; } - [[nodiscard]] constexpr const CharT* c_str() const noexcept { return data_; } - [[nodiscard]] constexpr const CharT& operator[](std::size_t index) const noexcept { return data_[index]; } - [[nodiscard]] constexpr CharT operator[](std::size_t index) noexcept { return data_[index]; } + [[nodiscard]] constexpr std::size_t size() const noexcept { return N; } + [[nodiscard]] constexpr const CharT* c_str() const noexcept { return data_; } + [[nodiscard]] constexpr const CharT& operator[](std::size_t index) const noexcept { return data_[index]; } + [[nodiscard]] constexpr CharT operator[](std::size_t index) noexcept { return data_[index]; } - // auto operator==(const basic_fixed_string &) = default; + template + [[nodiscard]] constexpr friend basic_fixed_string operator+( + const basic_fixed_string& lhs, const basic_fixed_string& rhs) noexcept + { + CharT txt[N + N2 + 1] = {}; - [[nodiscard]] constexpr friend bool operator==(const basic_fixed_string& lhs, const basic_fixed_string& rhs) noexcept - { - for(size_t i = 0; i != lhs.size(); ++i) - if(lhs.data_[i] != rhs.data_[i]) - return false; - return true; - } + for (size_t i = 0; i != N; ++i) txt[i] = lhs[i]; + for (size_t i = 0; i != N2; ++i) txt[N + i] = rhs[i]; - template - [[nodiscard]] constexpr friend bool operator==(const basic_fixed_string&, const basic_fixed_string&) noexcept - { - return false; - } + return units::basic_fixed_string(txt); + } - template - [[nodiscard]] constexpr friend bool operator<(const basic_fixed_string& lhs, const basic_fixed_string& rhs) noexcept - { - using std::begin, std::end; - auto first1 = begin(lhs.data_); - auto first2 = begin(rhs.data_); - const auto last1 = std::prev(end(lhs.data_)); // do not waste time for '\0' - const auto last2 = std::prev(end(rhs.data_)); +#if __GNUC__ >= 10 - for(; (first1 != last1) && (first2 != last2); ++first1, (void)++first2 ) { - if(*first1 < *first2) return true; - if(*first2 < *first1) return false; + [[nodiscard]] friend constexpr bool operator==(const basic_fixed_string& lhs, const basic_fixed_string& rhs) + { + for (size_t i = 0; i != lhs.size(); ++i) + if (lhs[i] != rhs[i]) return false; + return true; + } + + [[nodiscard]] friend constexpr bool operator!=(const basic_fixed_string&, const basic_fixed_string&) = default; + + template + [[nodiscard]] friend constexpr bool operator==(const basic_fixed_string&, const basic_fixed_string&) + { + return false; + } + + template + // TODO gcc-10 error: a template cannot be defaulted + // [[nodiscard]] friend constexpr bool operator!=(const basic_fixed_string&, + // const basic_fixed_string&) = default; + [[nodiscard]] friend constexpr bool operator!=(const basic_fixed_string&, const basic_fixed_string&) + { + return true; + } + + template + [[nodiscard]] friend constexpr auto operator<=>(const basic_fixed_string& lhs, + const basic_fixed_string& rhs) + { + size_t min_size = std::min(lhs.size(), rhs.size()); + for (size_t i = 0; i != min_size; ++i) { + if (auto const cmp = lhs[i] <=> rhs[i]; cmp != 0) { + return cmp; } - return first1 == last1 && first2 != last2; } + return lhs.size() <=> rhs.size(); + } - template - friend std::basic_ostream& operator<<(std::basic_ostream& os, const basic_fixed_string& txt) - { - return os << txt.c_str(); +#else + + [[nodiscard]] constexpr friend bool operator==(const basic_fixed_string& lhs, const basic_fixed_string& rhs) noexcept + { + for (size_t i = 0; i != lhs.size(); ++i) + if (lhs.data_[i] != rhs.data_[i]) return false; + return true; + } + + template + [[nodiscard]] constexpr friend bool operator==(const basic_fixed_string&, + const basic_fixed_string&) noexcept + { + return false; + } + + template + [[nodiscard]] constexpr friend bool operator<(const basic_fixed_string& lhs, + const basic_fixed_string& rhs) noexcept + { + using std::begin, std::end; + auto first1 = begin(lhs.data_); + auto first2 = begin(rhs.data_); + const auto last1 = std::prev(end(lhs.data_)); // do not waste time for '\0' + const auto last2 = std::prev(end(rhs.data_)); + + for (; (first1 != last1) && (first2 != last2); ++first1, (void)++first2) { + if (*first1 < *first2) return true; + if (*first2 < *first1) return false; } + return first1 == last1 && first2 != last2; + } - template - [[nodiscard]] constexpr friend basic_fixed_string operator+(const basic_fixed_string& lhs, const basic_fixed_string& rhs) noexcept - { - CharT txt[N + N2 + 1] = {}; +#endif - for(size_t i = 0; i != N; ++i) - txt[i] = lhs[i]; - for(size_t i = 0; i != N2; ++i) - txt[N + i] = rhs[i]; + template + friend std::basic_ostream& operator<<(std::basic_ostream& os, + const basic_fixed_string& txt) + { + return os << txt.c_str(); + } +}; - return units::basic_fixed_string(txt); - } - }; +template +basic_fixed_string(const CharT (&str)[N]) -> basic_fixed_string; - template - basic_fixed_string(const CharT (&str)[N]) -> basic_fixed_string; +template +basic_fixed_string(CharT) -> basic_fixed_string; - template - basic_fixed_string(CharT) -> basic_fixed_string; +template +using fixed_string = basic_fixed_string; - template - using fixed_string = basic_fixed_string; - -} +} // namespace units