From ae2ae84ffed3662fda4c516f6e9d62a7f780b169 Mon Sep 17 00:00:00 2001 From: Joe Loser Date: Sat, 28 May 2022 19:08:25 -0600 Subject: [PATCH] [libc++][test] Refactor SmallBasicString uses in range.lazy.split tests The tests for `std::ranges::lazy_split_view` heavily use a wrapper class around `std::string` because `std::string` was not `constexpr` until recently. Where possible, remove the wrapper class and extra functionality no longer needed. Remove `libcxx/test/std/ranges/range.adaptors/range.lazy.split/small_string.h` and inline its one use remaining in `libcxx/test/std/ranges/range.adaptors/range.lazy.split/general.pass.cpp`. Differential Revision: https://reviews.llvm.org/D126663 --- .../range.lazy.split/ctor.copy_move.pass.cpp | 5 -- .../range.lazy.split/ctor.range.pass.cpp | 25 +++---- .../range.lazy.split/general.pass.cpp | 28 +++++++- .../range.lazy.split.outer/deref.pass.cpp | 12 ++-- .../range.lazy.split.outer/increment.pass.cpp | 23 ++++--- .../range.adaptors/range.lazy.split/small_string.h | 79 ---------------------- .../ranges/range.adaptors/range.lazy.split/types.h | 35 ++++++---- 7 files changed, 75 insertions(+), 132 deletions(-) delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.lazy.split/small_string.h diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/ctor.copy_move.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/ctor.copy_move.pass.cpp index 97e172c..8cf19ef 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/ctor.copy_move.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/ctor.copy_move.pass.cpp @@ -16,13 +16,8 @@ #include #include #include -#include "small_string.h" #include "types.h" -constexpr bool operator==(const InputView& lhs, const InputView& rhs) { - return SmallString(lhs) == SmallString(rhs); -} - constexpr bool test() { // Can copy `lazy_split_view`. { diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/ctor.range.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/ctor.range.pass.cpp index bde1cb6..fa083bf 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/ctor.range.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/ctor.range.pass.cpp @@ -17,10 +17,10 @@ #include #include +#include #include #include #include -#include "small_string.h" #include "types.h" struct ElementWithCounting { @@ -72,24 +72,15 @@ struct RangeWithCounting { static_assert( std::ranges::forward_range); static_assert(!std::ranges::view); -struct StrRange { - SmallString buffer_; - constexpr explicit StrRange() = default; - constexpr StrRange(const char* ptr) : buffer_(ptr) {} - constexpr const char* begin() const { return buffer_.begin(); } - constexpr const char* end() const { return buffer_.end(); } - constexpr bool operator==(const StrRange& rhs) const { return buffer_ == rhs.buffer_; } -}; -static_assert( std::ranges::random_access_range); -static_assert(!std::ranges::view); -static_assert( std::is_copy_constructible_v); - struct StrView : std::ranges::view_base { - SmallString buffer_; + std::string_view buffer_; constexpr explicit StrView() = default; constexpr StrView(const char* ptr) : buffer_(ptr) {} + // Intentionally don't forward to range constructor for std::string_view since + // this test needs to work on C++20 as well and the range constructor is only for + // C++23 and later. template - constexpr StrView(R&& r) : buffer_(std::forward(r)) {} + constexpr StrView(R&& r) : buffer_(r.begin(), r.end()) {} constexpr const char* begin() const { return buffer_.begin(); } constexpr const char* end() const { return buffer_.end(); } constexpr bool operator==(const StrView& rhs) const { return buffer_ == rhs.buffer_; } @@ -102,9 +93,9 @@ constexpr bool test() { { using V = std::ranges::lazy_split_view; - // Calling the constructor with `(StrRange, range_value_t)`. + // Calling the constructor with `(std::string, range_value_t)`. { - StrRange input; + std::string input; V v(input, ' '); assert(v.base() == input); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/general.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/general.pass.cpp index 52793ab..440fca8 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/general.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/general.pass.cpp @@ -25,9 +25,33 @@ #include #include #include -#include "small_string.h" #include "types.h" +// A constexpr-friendly lightweight string, primarily useful for comparisons. +// Unlike `std::string_view`, it copies the given string into an +// internal buffer and can work with non-contiguous inputs. +template +class BasicSmallString { + std::basic_string buffer_{}; + +public: + constexpr BasicSmallString(std::basic_string_view v) : buffer_(v) {} + + template + constexpr BasicSmallString(I b, const S& e) { + for (; b != e; ++b) { + buffer_ += *b; + } + } + + template + constexpr BasicSmallString(R&& from) : BasicSmallString(from.begin(), from.end()) {} + + friend constexpr bool operator==(const BasicSmallString& lhs, const BasicSmallString& rhs) { + return lhs.buffer_ == rhs.buffer_; + } +}; + template constexpr bool is_equal(View& view, const Expected& expected) { using Char = std::ranges::range_value_t>; @@ -55,7 +79,7 @@ constexpr bool test_with_piping(T&& input, Separator&& separator, std::array +#include #include +#include #include #include -#include "../small_string.h" #include "../types.h" template constexpr void test_one(Separator sep) { + using namespace std::string_literals; using namespace std::string_view_literals; View v("abc def ghi"sv, sep); @@ -29,16 +31,16 @@ constexpr void test_one(Separator sep) { { auto i = v.begin(); static_assert(!std::is_reference_v); - assert(SmallString(*i) == "abc"_str); - assert(SmallString(*(++i)) == "def"_str); - assert(SmallString(*(++i)) == "ghi"_str); + assert(std::ranges::equal(*i, "abc"s)); + assert(std::ranges::equal(*(++i), "def"s)); + assert(std::ranges::equal(*(++i), "ghi"s)); } // Const iterator. { const auto ci = v.begin(); static_assert(!std::is_reference_v); - assert(SmallString(*ci) == "abc"_str); + assert(std::ranges::equal(*ci, "abc"s)); } } diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/increment.pass.cpp index 1e234e4..e2c023e 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/increment.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/increment.pass.cpp @@ -17,11 +17,12 @@ #include #include -#include -#include "../small_string.h" +#include +#include #include "../types.h" constexpr bool test() { + using namespace std::string_literals; // Can call `outer-iterator::operator++`; `View` is a forward range. { SplitViewForward v("abc def ghi", " "); @@ -29,23 +30,23 @@ constexpr bool test() { // ++i { auto i = v.begin(); - assert(*i == "abc"_str); + assert(std::ranges::equal(*i, "abc"s)); decltype(auto) i2 = ++i; static_assert(std::is_lvalue_reference_v); assert(&i2 == &i); - assert(*i2 == "def"_str); + assert(std::ranges::equal(*i2, "def"s)); } // i++ { auto i = v.begin(); - assert(*i == "abc"_str); + assert(std::ranges::equal(*i, "abc"s)); decltype(auto) i2 = i++; static_assert(!std::is_reference_v); - assert(*i2 == "abc"_str); - assert(*i == "def"_str); + assert(std::ranges::equal(*i2, "abc"s)); + assert(std::ranges::equal(*i, "def"s)); } } @@ -56,22 +57,22 @@ constexpr bool test() { // ++i { auto i = v.begin(); - assert(*i == "abc"_str); + assert(std::ranges::equal(*i, "abc"s)); decltype(auto) i2 = ++i; static_assert(std::is_lvalue_reference_v); assert(&i2 == &i); - assert(*i2 == "def"_str); + assert(std::ranges::equal(*i2, "def"s)); } // i++ { auto i = v.begin(); - assert(*i == "abc"_str); + assert(std::ranges::equal(*i, "abc"s)); static_assert(std::is_void_v); i++; - assert(*i == "def"_str); + assert(std::ranges::equal(*i, "def"s)); } } diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/small_string.h b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/small_string.h deleted file mode 100644 index 362d080..0000000 --- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/small_string.h +++ /dev/null @@ -1,79 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_LAZY_SPLIT_SMALL_STRING_H -#define TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_LAZY_SPLIT_SMALL_STRING_H - -#include -#include -#include -#include - -// A constexpr-friendly lightweight string, primarily useful for comparisons. -// Unlike `std::string`, all functions are `constexpr`. Unlike `std::string_view`, it copies the given string into an -// internal buffer and can work with non-contiguous inputs. -// -// TODO(var-const): remove once https://reviews.llvm.org/D110598 lands and `std::string` can be used instead of this -// class. -template -class BasicSmallString { - constexpr static int N = 32; - Char buffer_[N] = {}; - size_t size_ = 0; - -public: - // Main constructors. - - constexpr BasicSmallString() = default; - - constexpr BasicSmallString(std::basic_string_view v) : size_(v.size()) { - assert(size_ < N); - if (size_ == 0) return; - - std::copy(v.begin(), v.end(), buffer_); - } - - template - constexpr BasicSmallString(I b, const S& e) { - for (; b != e; ++b) { - buffer_[size_++] = *b; - assert(size_ < N); - } - } - - // Delegating constructors. - - constexpr BasicSmallString(const Char* ptr, size_t size) : BasicSmallString(std::basic_string_view(ptr, size)) { - } - - template - constexpr BasicSmallString(R&& from) : BasicSmallString(from.begin(), from.end()) { - } - - // Iterators. - - constexpr Char* begin() { return buffer_; } - constexpr Char* end() { return buffer_ + size_; } - constexpr const Char* begin() const { return buffer_; } - constexpr const Char* end() const { return buffer_ + size_; } - - friend constexpr bool operator==(const BasicSmallString& lhs, const BasicSmallString& rhs) { - return lhs.size_ == rhs.size_ && std::equal(lhs.buffer_, lhs.buffer_ + lhs.size_, rhs.buffer_); - } - friend constexpr bool operator==(const BasicSmallString& lhs, std::string_view rhs) { - return lhs == BasicSmallString(rhs); - } -}; - -using SmallString = BasicSmallString; - -inline constexpr SmallString operator "" _str(const char* ptr, size_t size) { - return SmallString(ptr, size); -} - -#endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_LAZY_SPLIT_SMALL_STRING_H diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/types.h b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/types.h index 3cb4a0d..a606e91 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/types.h @@ -11,9 +11,9 @@ #include #include +#include #include #include -#include "small_string.h" #include "test_macros.h" #include "test_iterators.h" @@ -55,18 +55,21 @@ static_assert( std::is_move_constructible_v); // Iterator types differ based on constness of this class. struct ForwardDiffView : std::ranges::view_base { - SmallString buffer_; + std::string buffer_; constexpr explicit ForwardDiffView() = default; constexpr ForwardDiffView(const char* ptr) : ForwardDiffView(std::string_view(ptr)) {} - constexpr ForwardDiffView(std::string_view v) : buffer_(v) {} + constexpr ForwardDiffView(std::string_view v) { + // Workaround https://github.com/llvm/llvm-project/issues/55867 + buffer_ = v; + } constexpr ForwardDiffView(ForwardDiffView&&) = default; constexpr ForwardDiffView& operator=(ForwardDiffView&&) = default; constexpr ForwardDiffView(const ForwardDiffView&) = default; constexpr ForwardDiffView& operator=(const ForwardDiffView&) = default; - constexpr forward_iterator begin() { return forward_iterator(buffer_.begin()); } - constexpr forward_iterator end() { return forward_iterator(buffer_.end()); } - constexpr forward_iterator begin() const { return forward_iterator(buffer_.begin()); } - constexpr forward_iterator end() const { return forward_iterator(buffer_.end()); } + constexpr forward_iterator begin() { return forward_iterator(buffer_.begin().base()); } + constexpr forward_iterator end() { return forward_iterator(buffer_.end().base()); } + constexpr forward_iterator begin() const { return forward_iterator(buffer_.begin().base()); } + constexpr forward_iterator end() const { return forward_iterator(buffer_.end().base()); } }; static_assert( std::ranges::forward_range); static_assert( std::ranges::forward_range); @@ -135,21 +138,27 @@ static_assert( std::ranges::view); // InputView struct InputView : std::ranges::view_base { - SmallString buffer_; + std::string buffer_; constexpr InputView() = default; constexpr InputView(const char* s) : InputView(std::string_view(s)) {} - constexpr InputView(std::string_view v) : buffer_(v) {} + constexpr InputView(std::string_view v) { + // Workaround https://github.com/llvm/llvm-project/issues/55867 + buffer_ = v; + } - constexpr cpp20_input_iterator begin() { return cpp20_input_iterator(buffer_.begin()); } + constexpr cpp20_input_iterator begin() { return cpp20_input_iterator(buffer_.begin().base()); } constexpr sentinel_wrapper> end() { - return sentinel_wrapper(cpp20_input_iterator(buffer_.end())); + return sentinel_wrapper(cpp20_input_iterator(buffer_.end().base())); } constexpr cpp20_input_iterator begin() const { - return cpp20_input_iterator(buffer_.begin()); + return cpp20_input_iterator(buffer_.begin().base()); } constexpr sentinel_wrapper> end() const { - return sentinel_wrapper(cpp20_input_iterator(buffer_.end())); + return sentinel_wrapper(cpp20_input_iterator(buffer_.end().base())); + } + friend constexpr bool operator==(const InputView& lhs, const InputView& rhs) { + return lhs.buffer_ == rhs.buffer_; } }; -- 2.7.4