Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add tests
  • Loading branch information
huixie90 committed Jul 19, 2025
commit db14a593596c2e0cbe2a6d9eab03a28358551eae
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@

#include <cassert>
#include <concepts>
#include <tuple>
#include <utility>

#include "types.h"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@

#include <ranges>

#include <array>
#include <algorithm>
#include <array>
#include <cassert>
#include <tuple>
#include <type_traits>
#include <utility>

struct NotMoveConstructible {
NotMoveConstructible() = default;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

#include <cassert>
#include <ranges>
#include <utility>

#include "types.h"
struct Container {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

#include <cassert>
#include <type_traits>
#include <utility>

constexpr int buff[] = {1, 2, 3};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
// constexpr explicit zip_transform_view(F, Views...)

#include <ranges>
#include <tuple>

#include "types.h"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
// regular_invocable<const F&, range_reference_t<const Views>...>;

#include <ranges>
#include <tuple>

#include "types.h"

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
//===----------------------------------------------------------------------===//
//
// 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, c++20

// constexpr iterator& operator+=(difference_type x) requires random_access_range<Base>;
// constexpr iterator& operator-=(difference_type x) requires random_access_range<Base>;
// friend constexpr iterator operator+(const iterator& i, difference_type n)
// requires random_access_range<Base>;
// friend constexpr iterator operator+(difference_type n, const iterator& i)
// requires random_access_range<Base>;
// friend constexpr iterator operator-(const iterator& i, difference_type n)
// requires random_access_range<Base>;
// friend constexpr difference_type operator-(const iterator& x, const iterator& y)
// requires sized_sentinel_for<ziperator<Const>, ziperator<Const>>;

#include <ranges>

#include <array>
#include <concepts>
#include <functional>

#include "../types.h"

template <class T, class U>
concept canPlusEqual = requires(T& t, U& u) { t += u; };

template <class T, class U>
concept canPlus = requires(T& t, U& u) { t + u; };

template <class T, class U>
concept canMinusEqual = requires(T& t, U& u) { t -= u; };

template <class T, class U>
concept canMinus = requires(T& t, U& u) { t - u; };

constexpr bool test() {
int buffer1[5] = {1, 2, 3, 4, 5};
SizedRandomAccessView a{buffer1};
static_assert(std::ranges::random_access_range<decltype(a)>);

std::array b{4.1, 3.2, 4.3, 0.1, 0.2};
static_assert(std::ranges::contiguous_range<decltype(b)>);

{
// operator+(x, n) and operator+=
std::ranges::zip_transform_view v(MakeTuple{}, a, b);
auto it1 = v.begin();
using Iter = decltype(it1);

std::same_as<Iter> decltype(auto) it2 = it1 + 3;
assert(*it2 == std::tuple(4, 0.1));

std::same_as<Iter> decltype(auto) it3 = 3 + it1;
assert(*it3 == std::tuple(4, 0.1));

std::same_as<Iter&> decltype(auto) it1_ref = it1 += 3;
assert(&it1_ref == &it1);
assert(*it1_ref == std::tuple(4, 0.1));
assert(*it1 == std::tuple(4, 0.1));

static_assert(canPlus<Iter, std::intptr_t>);
static_assert(canPlusEqual<Iter, std::intptr_t>);
}

{
// operator-(x, n) and operator-=
std::ranges::zip_transform_view v(MakeTuple{}, a, b);
auto it1 = v.end();
using Iter = decltype(it1);

std::same_as<Iter> decltype(auto) it2 = it1 - 3;
assert(*it2 == std::tuple(3, 4.3));

std::same_as<Iter&> decltype(auto) it1_ref = it1 -= 3;
assert(&it1_ref == &it1);
assert(*it1_ref == std::tuple(3, 4.3));
assert(*it1 == std::tuple(3, 4.3));

static_assert(canMinusEqual<Iter, std::intptr_t>);
static_assert(canMinus<Iter, std::intptr_t>);
}

{
// operator-(x, y)
std::ranges::zip_transform_view v(MakeTuple{}, a, b);
assert((v.end() - v.begin()) == 5);

auto it1 = v.begin() + 2;
auto it2 = v.end() - 1;

using Iter = decltype(it1);

std::same_as<std::iter_difference_t<Iter>> decltype(auto) n = it1 - it2;
assert(n == -2);
}

{
// One of the ranges is not random access
std::ranges::zip_transform_view v(MakeTuple{}, a, b, ForwardSizedView{buffer1});
auto it1 = v.begin();
using Iter = decltype(it1);
static_assert(!canPlus<Iter, std::intptr_t>);
static_assert(!canPlus<std::intptr_t, Iter>);
static_assert(!canPlusEqual<Iter, std::intptr_t>);
static_assert(!canMinus<Iter, std::intptr_t>);
static_assert(canMinus<Iter, Iter>);
static_assert(!canMinusEqual<Iter, std::intptr_t>);

auto it2 = ++v.begin();
assert((it2 - it1) == 1);
}

{
// One of the ranges does not have sized sentinel
std::ranges::zip_transform_view v(MakeTuple{}, a, b, InputCommonView{buffer1});
using Iter = decltype(v.begin());
static_assert(!canPlus<Iter, std::intptr_t>);
static_assert(!canPlus<std::intptr_t, Iter>);
static_assert(!canPlusEqual<Iter, std::intptr_t>);
static_assert(!canMinus<Iter, std::intptr_t>);
static_assert(!canMinus<Iter, Iter>);
static_assert(!canMinusEqual<Iter, std::intptr_t>);
}

return true;
}

int main(int, char**) {
test();
static_assert(test());

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
//===----------------------------------------------------------------------===//
//
// 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, c++20

// friend constexpr bool operator==(const iterator& x, const iterator& y)
// requires equality_comparable<ziperator<Const>>;

// friend constexpr auto operator<=>(const iterator& x, const iterator& y)
// requires random_access_range<Base>;

#include <ranges>

#include <compare>

#include "test_iterators.h"
#include "../types.h"

constexpr void compareOperatorTest(auto&& iter1, auto&& iter2) {
assert(!(iter1 < iter1));
assert(iter1 < iter2);
assert(!(iter2 < iter1));
assert(iter1 <= iter1);
assert(iter1 <= iter2);
assert(!(iter2 <= iter1));
assert(!(iter1 > iter1));
assert(!(iter1 > iter2));
assert(iter2 > iter1);
assert(iter1 >= iter1);
assert(!(iter1 >= iter2));
assert(iter2 >= iter1);
assert(iter1 == iter1);
assert(!(iter1 == iter2));
assert(iter2 == iter2);
assert(!(iter1 != iter1));
assert(iter1 != iter2);
assert(!(iter2 != iter2));
}

constexpr void inequalityOperatorsDoNotExistTest(auto&& iter1, auto&& iter2) {
using Iter1 = decltype(iter1);
using Iter2 = decltype(iter2);
static_assert(!std::is_invocable_v<std::less<>, Iter1, Iter2>);
static_assert(!std::is_invocable_v<std::less_equal<>, Iter1, Iter2>);
static_assert(!std::is_invocable_v<std::greater<>, Iter1, Iter2>);
static_assert(!std::is_invocable_v<std::greater_equal<>, Iter1, Iter2>);
}

constexpr bool test() {
{
// Test a new-school iterator with operator<=>; the iterator should also have operator<=>.
using It = three_way_contiguous_iterator<int*>;
using SubRange = std::ranges::subrange<It>;
static_assert(std::three_way_comparable<It>);

int a[] = {1, 2, 3, 4};
int b[] = {5, 6, 7, 8, 9};
auto r = std::views::zip_transform(MakeTuple{}, SubRange(It(a), It(a + 4)), SubRange(It(b), It(b + 5)));
auto iter1 = r.begin();
auto iter2 = iter1 + 1;
using Iter = decltype(iter1);
static_assert(std::three_way_comparable<Iter>);
compareOperatorTest(iter1, iter2);

assert((iter1 <=> iter2) == std::strong_ordering::less);
assert((iter1 <=> iter1) == std::strong_ordering::equal);
assert((iter2 <=> iter1) == std::strong_ordering::greater);
}

{
// Test an old-school iterator with no operator<=>; the transform iterator shouldn't have
// operator<=> either.
using It = random_access_iterator<int*>;
using Subrange = std::ranges::subrange<It>;
static_assert(!std::three_way_comparable<It>);

int a[] = {1, 2, 3, 4};
int b[] = {5, 6, 7, 8, 9};
auto r = std::views::zip_transform(MakeTuple{}, Subrange(It(a), It(a + 4)), Subrange(It(b), It(b + 5)));
auto iter1 = r.begin();
using Iter = decltype(iter1);
#ifndef _LIBCPP_VERSION
// libc++ hasn't implemented LWG-3692 "zip_transform_view::iterator's operator<=> is overconstrained"
auto iter2 = iter1 + 1;

compareOperatorTest(iter1, iter2);
static_assert(std::three_way_comparable<Iter>);
assert((iter1 <=> iter2) == std::strong_ordering::less);
assert((iter1 <=> iter1) == std::strong_ordering::equal);
assert((iter2 <=> iter1) == std::strong_ordering::greater);
#endif
}

{
// non random_access_range
int buffer1[1] = {1};
int buffer2[2] = {1, 2};

std::ranges::zip_transform_view v{MakeTuple{}, InputCommonView(buffer1), InputCommonView(buffer2)};
using View = decltype(v);
static_assert(!std::ranges::forward_range<View>);
static_assert(std::ranges::input_range<View>);
static_assert(std::ranges::common_range<View>);

auto it1 = v.begin();
auto it2 = v.end();
assert(it1 != it2);

++it1;
assert(it1 == it2);

inequalityOperatorsDoNotExistTest(it1, it2);
}

{
// in this case sentinel is computed by getting each of the underlying sentinel, so only one
// underlying iterator is comparing equal
int buffer1[1] = {1};
int buffer2[2] = {1, 2};
std::ranges::zip_transform_view v{MakeTuple{}, ForwardSizedView(buffer1), ForwardSizedView(buffer2)};
using View = decltype(v);
static_assert(std::ranges::common_range<View>);
static_assert(!std::ranges::bidirectional_range<View>);

auto it1 = v.begin();
auto it2 = v.end();
assert(it1 != it2);

++it1;
// it1: <buffer1 + 1, buffer2 + 1>
// it2: <buffer1 + 1, buffer2 + 2>
assert(it1 == it2);

inequalityOperatorsDoNotExistTest(it1, it2);
}

{
// underlying iterator does not support ==
using IterNoEqualView = BasicView<cpp20_input_iterator<int*>, sentinel_wrapper<cpp20_input_iterator<int*>>>;
int buffer[] = {1};
std::ranges::zip_transform_view r(MakeTuple{}, IterNoEqualView{buffer});
auto it = r.begin();
using Iter = decltype(it);
static_assert(!std::invocable<std::equal_to<>, Iter, Iter>);
inequalityOperatorsDoNotExistTest(it, it);
}
return true;
}

int main(int, char**) {
test();
//static_assert(test());

return 0;
}
Loading