-
Notifications
You must be signed in to change notification settings - Fork 180
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Implement `ranges::advance` * [skip-tests] Address review feedback
- Loading branch information
Showing
15 changed files
with
1,385 additions
and
109 deletions.
There are no files selected for viewing
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
30 changes: 30 additions & 0 deletions
30
...terators/iterator.primitives/range.iter.ops/range.iter.ops.advance/constraints.verify.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,30 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// 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 | ||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
// UNSUPPORTED: c++03, c++11, c++14 | ||
// UNSUPPORTED: nvrtc | ||
// UNSUPPORTED: msvc-19.16 | ||
|
||
// ranges::advance | ||
// Make sure we're SFINAE-friendly when the template argument constraints are not met. | ||
|
||
#include <cuda/std/iterator> | ||
|
||
class not_incrementable{}; | ||
|
||
__host__ __device__ void proper_constraints() { | ||
not_incrementable p{}; | ||
cuda::std::ranges::advance(p, 5); // expected-error {{no matching function for call}} | ||
cuda::std::ranges::advance(p, p); // expected-error {{no matching function for call}} | ||
cuda::std::ranges::advance(p, 5, p); // expected-error {{no matching function for call}} | ||
} | ||
|
||
int main(int, char**) { | ||
return 0; | ||
} |
84 changes: 84 additions & 0 deletions
84
...erators/iterator.primitives/range.iter.ops/range.iter.ops.advance/iterator_count.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,84 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// 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 | ||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
// UNSUPPORTED: c++03, c++11, c++14 | ||
// UNSUPPORTED: msvc-19.16 | ||
|
||
// ranges::advance(it, n) | ||
|
||
#include <cuda/std/iterator> | ||
|
||
#include <cuda/std/cassert> | ||
|
||
#include "test_iterators.h" | ||
#include "test_macros.h" | ||
|
||
struct Abs { | ||
template<class T> | ||
__host__ __device__ constexpr T operator()(T x) const noexcept { return x < 0 ? -x : x; }; | ||
}; | ||
|
||
template <bool Count, typename It> | ||
__host__ __device__ constexpr void check(int* first, cuda::std::iter_difference_t<It> n, int* expected) { | ||
using Difference = cuda::std::iter_difference_t<It>; | ||
Difference const M = (expected - first); // expected travel distance (which may be negative) | ||
Abs abs{}; | ||
unused(abs); | ||
unused(M); | ||
|
||
{ | ||
It it(first); | ||
cuda::std::ranges::advance(it, n); | ||
assert(base(it) == expected); | ||
ASSERT_SAME_TYPE(decltype(cuda::std::ranges::advance(it, n)), void); | ||
} | ||
|
||
// Count operations | ||
if constexpr (Count) { | ||
auto it = stride_counting_iterator(It(first)); | ||
cuda::std::ranges::advance(it, n); | ||
if constexpr (cuda::std::random_access_iterator<It>) { | ||
assert(it.stride_count() <= 1); | ||
} else { | ||
assert(it.stride_count() == abs(M)); | ||
} | ||
} | ||
} | ||
|
||
__host__ __device__ constexpr bool test() { | ||
int range[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; | ||
|
||
// Check advancing forward | ||
for (int n = 0; n != 10; ++n) { | ||
check<false, cpp17_input_iterator<int*>>( range, n, range+n); | ||
check<false, cpp20_input_iterator<int*>>( range, n, range+n); | ||
check<true, forward_iterator<int*>>( range, n, range+n); | ||
check<true, bidirectional_iterator<int*>>(range, n, range+n); | ||
check<true, random_access_iterator<int*>>(range, n, range+n); | ||
check<true, contiguous_iterator<int*>>( range, n, range+n); | ||
check<true, int*>( range, n, range+n); | ||
check<true, cpp17_output_iterator<int*> >(range, n, range+n); | ||
} | ||
|
||
// Check advancing backward | ||
for (int n = 0; n != 10; ++n) { | ||
check<true, bidirectional_iterator<int*>>(range+9, -n, range+9 - n); | ||
check<true, random_access_iterator<int*>>(range+9, -n, range+9 - n); | ||
check<true, contiguous_iterator<int*>>( range+9, -n, range+9 - n); | ||
check<true, int*>( range+9, -n, range+9 - n); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
int main(int, char**) { | ||
assert(test()); | ||
static_assert(test()); | ||
return 0; | ||
} |
Oops, something went wrong.