Skip to content

Commit

Permalink
more test
Browse files Browse the repository at this point in the history
  • Loading branch information
changkhothuychung committed Nov 22, 2024
1 parent 19c3e4d commit bc705f1
Show file tree
Hide file tree
Showing 3 changed files with 303 additions and 0 deletions.
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 libcxx/test/std/ranges/range.adaptors/range.concat/end.pass.cpp
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 libcxx/test/std/ranges/range.adaptors/range.concat/types.h
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

0 comments on commit bc705f1

Please sign in to comment.