forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
19c3e4d
commit bc705f1
Showing
3 changed files
with
303 additions
and
0 deletions.
There are no files selected for viewing
70 changes: 70 additions & 0 deletions
70
libcxx/test/std/ranges/range.adaptors/range.concat/ctor.view.pass.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// 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 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
// UNSUPPORTED: c++03, c++11, c++14, c++17 | ||
|
||
// constexpr filter_view(View, Pred); // explicit since C++23 | ||
|
||
#include <cassert> | ||
#include <ranges> | ||
#include <utility> | ||
|
||
#include "test_convertible.h" | ||
#include "test_macros.h" | ||
#include "types.h" | ||
|
||
struct Range : std::ranges::view_base { | ||
constexpr explicit Range(int* b, int* e) : begin_(b), end_(e) { } | ||
constexpr int* begin() const { return begin_; } | ||
constexpr int* end() const { return end_; } | ||
|
||
private: | ||
int* begin_; | ||
int* end_; | ||
}; | ||
|
||
struct TrackingRange : TrackInitialization, std::ranges::view_base { | ||
using TrackInitialization::TrackInitialization; | ||
int* begin() const; | ||
int* end() const; | ||
}; | ||
|
||
constexpr bool test() { | ||
int buff[] = {1, 2, 3, 4}; | ||
|
||
// Test explicit syntax | ||
{ | ||
Range range(buff, buff + 4); | ||
std::ranges::concat_view<Range> view(range); | ||
auto it = view.begin(); | ||
auto end = view.end(); | ||
assert(*it++ == 1); | ||
assert(*it++ == 2); | ||
assert(*it++ == 3); | ||
assert(*it++ == 4); | ||
assert(it == end); | ||
} | ||
|
||
// Make sure we move the view | ||
{ | ||
bool moved = false, copied = false; | ||
TrackingRange range(&moved, &copied); | ||
[[maybe_unused]] std::ranges::concat_view<TrackingRange> view(std::move(range)); | ||
assert(moved); | ||
assert(!copied); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
int main(int, char**) { | ||
test(); | ||
static_assert(test()); | ||
|
||
return 0; | ||
} |
129 changes: 129 additions & 0 deletions
129
libcxx/test/std/ranges/range.adaptors/range.concat/end.pass.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// 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 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
// UNSUPPORTED: c++03, c++11, c++14, c++17 | ||
|
||
// constexpr auto end(); | ||
|
||
#include <ranges> | ||
|
||
#include <cassert> | ||
#include <concepts> | ||
#include <type_traits> | ||
#include <iterator> | ||
#include "test_iterators.h" | ||
|
||
struct Range : std::ranges::view_base { | ||
using Iterator = forward_iterator<int*>; | ||
using Sentinel = sentinel_wrapper<Iterator>; | ||
constexpr explicit Range(int* b, int* e) : begin_(b), end_(e) { } | ||
constexpr Iterator begin() const { return Iterator(begin_); } | ||
constexpr Sentinel end() const { return Sentinel(Iterator(end_)); } | ||
|
||
private: | ||
int* begin_; | ||
int* end_; | ||
}; | ||
|
||
struct CommonRange : std::ranges::view_base { | ||
using Iterator = forward_iterator<int*>; | ||
constexpr explicit CommonRange(int* b, int* e) : begin_(b), end_(e) { } | ||
constexpr Iterator begin() const { return Iterator(begin_); } | ||
constexpr Iterator end() const { return Iterator(end_); } | ||
|
||
private: | ||
int* begin_; | ||
int* end_; | ||
}; | ||
|
||
struct NotCommonRange : std::ranges::view_base | ||
{ | ||
constexpr explicit NotCommonRange(){} | ||
char* begin(); | ||
bool end(); | ||
}; | ||
|
||
constexpr bool test() { | ||
int buff[] = {1, 2, 3, 4, 5, 6, 7, 8}; | ||
|
||
// Check the return type of `.end()` | ||
{ | ||
Range range(buff, buff + 1); | ||
std::ranges::concat_view view(range); | ||
using FilterSentinel = std::ranges::sentinel_t<decltype(view)>; | ||
ASSERT_SAME_TYPE(FilterSentinel, decltype(view.end())); | ||
} | ||
|
||
// Check a not a common range | ||
{ | ||
Range range(buff, buff + 1); | ||
std::ranges::concat_view view(range); | ||
using FilterSentinel = std::default_sentinel_t; | ||
ASSERT_SAME_TYPE(FilterSentinel, decltype(view.end())); | ||
} | ||
|
||
// // end() on an empty range | ||
// { | ||
// Range range(buff, buff); | ||
// auto pred = [](int) { return true; }; | ||
// std::ranges::filter_view view(range, pred); | ||
// auto end = view.end(); | ||
// assert(base(base(end.base())) == buff); | ||
// } | ||
|
||
// // end() on a 1-element range | ||
// { | ||
// Range range(buff, buff + 1); | ||
// auto pred = [](int) { return true; }; | ||
// std::ranges::filter_view view(range, pred); | ||
// auto end = view.end(); | ||
// assert(base(base(end.base())) == buff + 1); | ||
// static_assert(!std::is_same_v<decltype(end), decltype(view.begin())>); | ||
// } | ||
|
||
// // end() on a 2-element range | ||
// { | ||
// Range range(buff, buff + 2); | ||
// auto pred = [](int) { return true; }; | ||
// std::ranges::filter_view view(range, pred); | ||
// auto end = view.end(); | ||
// assert(base(base(end.base())) == buff + 2); | ||
// static_assert(!std::is_same_v<decltype(end), decltype(view.begin())>); | ||
// } | ||
|
||
// // end() on a N-element range | ||
// { | ||
// for (int k = 1; k != 8; ++k) { | ||
// Range range(buff, buff + 8); | ||
// auto pred = [=](int i) { return i == k; }; | ||
// std::ranges::filter_view view(range, pred); | ||
// auto end = view.end(); | ||
// assert(base(base(end.base())) == buff + 8); | ||
// static_assert(!std::is_same_v<decltype(end), decltype(view.begin())>); | ||
// } | ||
// } | ||
|
||
// // end() on a common_range | ||
// { | ||
// CommonRange range(buff, buff + 8); | ||
// auto pred = [](int i) { return i % 2 == 0; }; | ||
// std::ranges::filter_view view(range, pred); | ||
// auto end = view.end(); | ||
// assert(base(end.base()) == buff + 8); | ||
// static_assert(std::is_same_v<decltype(end), decltype(view.begin())>); | ||
// } | ||
|
||
return true; | ||
} | ||
|
||
int main(int, char**) { | ||
test(); | ||
static_assert(test()); | ||
|
||
return 0; | ||
} |
104 changes: 104 additions & 0 deletions
104
libcxx/test/std/ranges/range.adaptors/range.concat/types.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// 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_CONCAT_TYPES_H | ||
#define TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_CONCAT_TYPES_H | ||
|
||
#include <ranges> | ||
#include <utility> | ||
|
||
struct TrackInitialization { | ||
constexpr explicit TrackInitialization(bool* moved, bool* copied) : moved_(moved), copied_(copied) { } | ||
constexpr TrackInitialization(TrackInitialization const& other) : moved_(other.moved_), copied_(other.copied_) { | ||
*copied_ = true; | ||
} | ||
constexpr TrackInitialization(TrackInitialization&& other) : moved_(other.moved_), copied_(other.copied_) { | ||
*moved_ = true; | ||
} | ||
TrackInitialization& operator=(TrackInitialization const&) = default; | ||
TrackInitialization& operator=(TrackInitialization&&) = default; | ||
bool* moved_; | ||
bool* copied_; | ||
}; | ||
|
||
struct AlwaysTrue { | ||
template <typename T> | ||
constexpr bool operator()(T const&) const { return true; } | ||
}; | ||
|
||
template <class Iter, class Sent> | ||
struct minimal_view : std::ranges::view_base { | ||
constexpr explicit minimal_view(Iter it, Sent sent) | ||
: it_(base(std::move(it))) | ||
, sent_(base(std::move(sent))) | ||
{ } | ||
|
||
minimal_view(minimal_view&&) = default; | ||
minimal_view& operator=(minimal_view&&) = default; | ||
|
||
constexpr Iter begin() const { return Iter(it_); } | ||
constexpr Sent end() const { return Sent(sent_); } | ||
|
||
private: | ||
decltype(base(std::declval<Iter>())) it_; | ||
decltype(base(std::declval<Sent>())) sent_; | ||
}; | ||
|
||
template <bool IsNoexcept> | ||
class NoexceptIterMoveInputIterator { | ||
int *it_; | ||
|
||
public: | ||
using iterator_category = std::input_iterator_tag; | ||
using value_type = int; | ||
using difference_type = typename std::iterator_traits<int *>::difference_type; | ||
using pointer = int*; | ||
using reference = int&; | ||
|
||
NoexceptIterMoveInputIterator() = default; | ||
explicit constexpr NoexceptIterMoveInputIterator(int *it) : it_(it) {} | ||
|
||
friend constexpr decltype(auto) iter_move(const NoexceptIterMoveInputIterator& it) noexcept(IsNoexcept) { | ||
return std::ranges::iter_move(it.it_); | ||
} | ||
|
||
friend constexpr int* base(const NoexceptIterMoveInputIterator& i) { return i.it_; } | ||
|
||
constexpr reference operator*() const { return *it_; } | ||
constexpr NoexceptIterMoveInputIterator& operator++() {++it_; return *this;} | ||
constexpr NoexceptIterMoveInputIterator operator++(int) | ||
{ NoexceptIterMoveInputIterator tmp(*this); ++(*this); return tmp; } | ||
}; | ||
|
||
template <bool IsNoexcept> | ||
class NoexceptIterSwapInputIterator { | ||
int *it_; | ||
|
||
public: | ||
using iterator_category = std::input_iterator_tag; | ||
using value_type = int; | ||
using difference_type = typename std::iterator_traits<int *>::difference_type; | ||
using pointer = int*; | ||
using reference = int&; | ||
|
||
NoexceptIterSwapInputIterator() = default; | ||
explicit constexpr NoexceptIterSwapInputIterator(int *it) : it_(it) {} | ||
|
||
friend constexpr void iter_swap(const NoexceptIterSwapInputIterator& a, const NoexceptIterSwapInputIterator& b) noexcept(IsNoexcept) { | ||
return std::ranges::iter_swap(a.it_, b.it_); | ||
} | ||
|
||
friend constexpr int* base(const NoexceptIterSwapInputIterator& i) { return i.it_; } | ||
|
||
constexpr reference operator*() const { return *it_; } | ||
constexpr NoexceptIterSwapInputIterator& operator++() {++it_; return *this;} | ||
constexpr NoexceptIterSwapInputIterator operator++(int) | ||
{ NoexceptIterSwapInputIterator tmp(*this); ++(*this); return tmp; } | ||
}; | ||
|
||
#endif // TEST_STD_RANGES_RANGE_ADAPTORS_CONCAT_FILTER_TYPES_H |