From e1f7266b517c04644b666af6aef3e65216b28c56 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Sat, 19 Mar 2022 20:07:55 +0100 Subject: [PATCH] refactor: `` header added Should be replaced with `` when C++20 modules will be used. Right now this header is too expensive to compile. --- .../include/units/bits/external/algorithm.h | 76 +++++++++++++++++++ .../units/bits/external/fixed_string.h | 24 ++---- 2 files changed, 81 insertions(+), 19 deletions(-) create mode 100644 src/core/include/units/bits/external/algorithm.h diff --git a/src/core/include/units/bits/external/algorithm.h b/src/core/include/units/bits/external/algorithm.h new file mode 100644 index 00000000..830f8cc5 --- /dev/null +++ b/src/core/include/units/bits/external/algorithm.h @@ -0,0 +1,76 @@ +// 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 // IWYU pragma: keep +#include + +namespace units::detail { + +template +constexpr bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2) +{ + for (; first1 != last1; ++first1, ++first2) { + if (!(*first1 == *first2)) { + return false; + } + } + return true; +} + +template +constexpr InputIt find_if(InputIt first, InputIt last, UnaryPredicate p) +{ + for (; first != last; ++first) { + if (p(*first)) { + return first; + } + } + return last; +} + +template +constexpr auto lexicographical_compare_three_way(I1 f1, I1 l1, I2 f2, I2 l2, Cmp comp) -> decltype(comp(*f1, *f2)) +{ + using ret_t = decltype(comp(*f1, *f2)); + static_assert(std::disjunction_v, std::is_same, + std::is_same>, + "The return type must be a comparison category type."); + + bool exhaust1 = (f1 == l1); + bool exhaust2 = (f2 == l2); + for (; !exhaust1 && !exhaust2; exhaust1 = (++f1 == l1), exhaust2 = (++f2 == l2)) + if (auto c = comp(*f1, *f2); c != 0) return c; + + return !exhaust1 ? std::strong_ordering::greater + : !exhaust2 ? std::strong_ordering::less + : std::strong_ordering::equal; +} + +template +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()); +} + +} // namespace units::detail diff --git a/src/core/include/units/bits/external/fixed_string.h b/src/core/include/units/bits/external/fixed_string.h index 136b1279..732a30c7 100644 --- a/src/core/include/units/bits/external/fixed_string.h +++ b/src/core/include/units/bits/external/fixed_string.h @@ -23,6 +23,8 @@ #pragma once #include // IWYU pragma: keep +// TODO use when moved to C++20 modules (parsing takes too long for each translation unit) +#include // IWYU pragma: begin_exports #include @@ -31,7 +33,6 @@ #include -// TODO use when moved to C++20 modules (parsing takes too long for each translation unit) namespace units { @@ -83,11 +84,7 @@ struct basic_fixed_string { [[nodiscard]] constexpr bool operator==(const basic_fixed_string& other) const { if (size() != other.size()) return false; - for (size_t i = 0; i != size(); ++i) { - if ((*this)[i] != other[i]) return false; - } - return true; - // return std::ranges::equal(*this, other); + return detail::equal(begin(), end(), other.begin()); // TODO std::ranges::equal(*this, other) } template @@ -100,19 +97,8 @@ struct basic_fixed_string { [[nodiscard]] friend constexpr auto operator<=>(const basic_fixed_string& lhs, const basic_fixed_string& rhs) { - auto first1 = lhs.begin(); - const auto last1 = lhs.end(); - auto first2 = rhs.begin(); - const auto last2 = rhs.end(); - auto comp = std::compare_three_way(); - - for (; first1 != last1 && first2 != last2; ++first1, ++first2) - if (auto cmp = comp(*first1, *first2); cmp != 0) return cmp; - - return first1 != last1 ? std::strong_ordering::greater - : first2 != last2 ? std::strong_ordering::less - : std::strong_ordering::equal; - // return std::lexicographical_compare_three_way(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); + // TODO std::lexicographical_compare_three_way(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); + return detail::lexicographical_compare_three_way(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); } };