forked from OSchip/llvm-project
[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
This commit is contained in:
parent
11f75e0a2d
commit
ae2ae84ffe
|
@ -16,13 +16,8 @@
|
|||
#include <cassert>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#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`.
|
||||
{
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
#include <ranges>
|
||||
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include "small_string.h"
|
||||
#include "types.h"
|
||||
|
||||
struct ElementWithCounting {
|
||||
|
@ -72,24 +72,15 @@ struct RangeWithCounting {
|
|||
static_assert( std::ranges::forward_range<RangeWithCounting>);
|
||||
static_assert(!std::ranges::view<RangeWithCounting>);
|
||||
|
||||
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<StrRange>);
|
||||
static_assert(!std::ranges::view<StrRange>);
|
||||
static_assert( std::is_copy_constructible_v<StrRange>);
|
||||
|
||||
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 <std::ranges::range R>
|
||||
constexpr StrView(R&& r) : buffer_(std::forward<R>(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<StrView, StrView>;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
|
|
@ -25,9 +25,33 @@
|
|||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#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 Char>
|
||||
class BasicSmallString {
|
||||
std::basic_string<Char> buffer_{};
|
||||
|
||||
public:
|
||||
constexpr BasicSmallString(std::basic_string_view<Char> v) : buffer_(v) {}
|
||||
|
||||
template <class I, class S>
|
||||
constexpr BasicSmallString(I b, const S& e) {
|
||||
for (; b != e; ++b) {
|
||||
buffer_ += *b;
|
||||
}
|
||||
}
|
||||
|
||||
template <std::ranges::range R>
|
||||
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 <std::ranges::view View, std::ranges::range Expected>
|
||||
constexpr bool is_equal(View& view, const Expected& expected) {
|
||||
using Char = std::ranges::range_value_t<std::ranges::range_value_t<View>>;
|
||||
|
@ -55,7 +79,7 @@ constexpr bool test_with_piping(T&& input, Separator&& separator, std::array<U,
|
|||
for (auto e : input | std::ranges::views::lazy_split(separator)) {
|
||||
if (expected_it == expected.end())
|
||||
return false;
|
||||
if (SmallString(e) != *expected_it)
|
||||
if (!std::ranges::equal(e, *expected_it))
|
||||
return false;
|
||||
|
||||
++expected_it;
|
||||
|
|
|
@ -13,14 +13,16 @@
|
|||
|
||||
#include <ranges>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include "../small_string.h"
|
||||
#include "../types.h"
|
||||
|
||||
template <class View, class Separator>
|
||||
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<decltype(*i)>);
|
||||
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<decltype(*ci)>);
|
||||
assert(SmallString(*ci) == "abc"_str);
|
||||
assert(std::ranges::equal(*ci, "abc"s));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,11 +17,12 @@
|
|||
#include <ranges>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string_view>
|
||||
#include "../small_string.h"
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#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<decltype(i2)>);
|
||||
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<decltype(i2)>);
|
||||
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<decltype(i2)>);
|
||||
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<decltype(i++)>);
|
||||
i++;
|
||||
assert(*i == "def"_str);
|
||||
assert(std::ranges::equal(*i, "def"s));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 <algorithm>
|
||||
#include <cassert>
|
||||
#include <ranges>
|
||||
#include <string_view>
|
||||
|
||||
// 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 Char>
|
||||
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<Char> v) : size_(v.size()) {
|
||||
assert(size_ < N);
|
||||
if (size_ == 0) return;
|
||||
|
||||
std::copy(v.begin(), v.end(), buffer_);
|
||||
}
|
||||
|
||||
template <class I, class S>
|
||||
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<Char>(ptr, size)) {
|
||||
}
|
||||
|
||||
template <std::ranges::range R>
|
||||
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<char>;
|
||||
|
||||
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
|
|
@ -11,9 +11,9 @@
|
|||
|
||||
#include <concepts>
|
||||
#include <ranges>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include "small_string.h"
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
|
@ -55,18 +55,21 @@ static_assert( std::is_move_constructible_v<ForwardView>);
|
|||
|
||||
// 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<char*> begin() { return forward_iterator<char*>(buffer_.begin()); }
|
||||
constexpr forward_iterator<char*> end() { return forward_iterator<char*>(buffer_.end()); }
|
||||
constexpr forward_iterator<const char*> begin() const { return forward_iterator<const char*>(buffer_.begin()); }
|
||||
constexpr forward_iterator<const char*> end() const { return forward_iterator<const char*>(buffer_.end()); }
|
||||
constexpr forward_iterator<char*> begin() { return forward_iterator<char*>(buffer_.begin().base()); }
|
||||
constexpr forward_iterator<char*> end() { return forward_iterator<char*>(buffer_.end().base()); }
|
||||
constexpr forward_iterator<const char*> begin() const { return forward_iterator<const char*>(buffer_.begin().base()); }
|
||||
constexpr forward_iterator<const char*> end() const { return forward_iterator<const char*>(buffer_.end().base()); }
|
||||
};
|
||||
static_assert( std::ranges::forward_range<ForwardView>);
|
||||
static_assert( std::ranges::forward_range<const ForwardView>);
|
||||
|
@ -135,21 +138,27 @@ static_assert( std::ranges::view<ForwardOnlyIfNonConstView>);
|
|||
// 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<char*> begin() { return cpp20_input_iterator<char*>(buffer_.begin()); }
|
||||
constexpr cpp20_input_iterator<char*> begin() { return cpp20_input_iterator<char*>(buffer_.begin().base()); }
|
||||
constexpr sentinel_wrapper<cpp20_input_iterator<char*>> end() {
|
||||
return sentinel_wrapper(cpp20_input_iterator<char*>(buffer_.end()));
|
||||
return sentinel_wrapper(cpp20_input_iterator<char*>(buffer_.end().base()));
|
||||
}
|
||||
constexpr cpp20_input_iterator<const char*> begin() const {
|
||||
return cpp20_input_iterator<const char*>(buffer_.begin());
|
||||
return cpp20_input_iterator<const char*>(buffer_.begin().base());
|
||||
}
|
||||
constexpr sentinel_wrapper<cpp20_input_iterator<const char*>> end() const {
|
||||
return sentinel_wrapper(cpp20_input_iterator<const char*>(buffer_.end()));
|
||||
return sentinel_wrapper(cpp20_input_iterator<const char*>(buffer_.end().base()));
|
||||
}
|
||||
friend constexpr bool operator==(const InputView& lhs, const InputView& rhs) {
|
||||
return lhs.buffer_ == rhs.buffer_;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue