This repository has been archived by the owner on Mar 21, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 187
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add range constructors for static span and add tests
- Loading branch information
Showing
5 changed files
with
272 additions
and
7 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
144 changes: 144 additions & 0 deletions
144
.upstream-tests/test/std/views/views.span/span.cons/range.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,144 @@ | ||
//===---------------------------------------------------------------------===// | ||
// | ||
// 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) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
// | ||
//===---------------------------------------------------------------------===// | ||
// UNSUPPORTED: c++03, c++11 | ||
|
||
// <cuda/std/span> | ||
|
||
// template<class Container> | ||
// constexpr explicit(Extent != dynamic_extent) span(Container&); | ||
// template<class Container> | ||
// constexpr explicit(Extent != dynamic_extent) span(Container const&); | ||
|
||
// This test checks for libc++'s non-conforming temporary extension to cuda::std::span | ||
// to support construction from containers that look like contiguous ranges. | ||
// | ||
// This extension is only supported when we don't ship <ranges>, and we can | ||
// remove it once we get rid of _LIBCUDACXX_HAS_NO_INCOMPLETE_RANGES. | ||
|
||
#include <cuda/std/span> | ||
#include <cuda/std/cassert> | ||
|
||
#include "test_macros.h" | ||
|
||
// Look ma - I'm a container! | ||
template <typename T> | ||
struct IsAContainer { | ||
__host__ __device__ constexpr IsAContainer() : v_{} {} | ||
__host__ __device__ constexpr size_t size() const {return 1;} | ||
__host__ __device__ constexpr T *data() {return &v_;} | ||
__host__ __device__ constexpr const T *data() const {return &v_;} | ||
__host__ __device__ constexpr T *begin() {return &v_;} | ||
__host__ __device__ constexpr const T *begin() const {return &v_;} | ||
__host__ __device__ constexpr T *end() {return &v_ + 1;} | ||
__host__ __device__ constexpr const T *end() const {return &v_ + 1;} | ||
|
||
__host__ __device__ constexpr T const *getV() const {return &v_;} // for checking | ||
T v_; | ||
}; | ||
|
||
template <typename T> | ||
__host__ __device__ | ||
constexpr bool unused(T &&) {return true;} | ||
|
||
__host__ __device__ void checkCV() | ||
{ | ||
IsAContainer<int> v{}; | ||
|
||
// Types the same | ||
{ | ||
cuda::std::span< int> s1{v}; // a span< int> pointing at int. | ||
unused(s1); | ||
} | ||
|
||
// types different | ||
{ | ||
cuda::std::span<const int> s1{v}; // a span<const int> pointing at int. | ||
cuda::std::span< volatile int> s2{v}; // a span< volatile int> pointing at int. | ||
cuda::std::span< volatile int> s3{v}; // a span< volatile int> pointing at const int. | ||
cuda::std::span<const volatile int> s4{v}; // a span<const volatile int> pointing at int. | ||
unused(s1); | ||
unused(s2); | ||
unused(s3); | ||
unused(s4); | ||
} | ||
|
||
// Constructing a const view from a temporary | ||
{ | ||
cuda::std::span<const int> s1{IsAContainer<int>()}; | ||
unused(s1); | ||
} | ||
} | ||
|
||
|
||
template <typename T> | ||
__host__ __device__ constexpr bool testConstexprSpan() | ||
{ | ||
constexpr IsAContainer<const T> val{}; | ||
cuda::std::span<const T> s1{val}; | ||
return s1.data() == val.getV() && s1.size() == 1; | ||
} | ||
|
||
template <typename T> | ||
__host__ __device__ constexpr bool testConstexprSpanStatic() | ||
{ | ||
constexpr IsAContainer<const T> val{}; | ||
cuda::std::span<const T, 1> s1{val}; | ||
return s1.data() == val.getV() && s1.size() == 1; | ||
} | ||
|
||
template <typename T> | ||
__host__ __device__ void testRuntimeSpan() | ||
{ | ||
IsAContainer<T> val{}; | ||
const IsAContainer<T> cVal; | ||
cuda::std::span<T> s1{val}; | ||
cuda::std::span<const T> s2{cVal}; | ||
assert(s1.data() == val.getV() && s1.size() == 1); | ||
assert(s2.data() == cVal.getV() && s2.size() == 1); | ||
} | ||
|
||
template <typename T> | ||
__host__ __device__ void testRuntimeSpanStatic() | ||
{ | ||
IsAContainer<T> val{}; | ||
const IsAContainer<T> cVal; | ||
cuda::std::span<T, 1> s1{val}; | ||
cuda::std::span<const T, 1> s2{cVal}; | ||
assert(s1.data() == val.getV() && s1.size() == 1); | ||
assert(s2.data() == cVal.getV() && s2.size() == 1); | ||
} | ||
|
||
struct A{}; | ||
|
||
int main(int, char**) | ||
{ | ||
static_assert(testConstexprSpan<int>(), ""); | ||
static_assert(testConstexprSpan<long>(), ""); | ||
static_assert(testConstexprSpan<double>(), ""); | ||
static_assert(testConstexprSpan<A>(), ""); | ||
|
||
static_assert(testConstexprSpanStatic<int>(), ""); | ||
static_assert(testConstexprSpanStatic<long>(), ""); | ||
static_assert(testConstexprSpanStatic<double>(), ""); | ||
static_assert(testConstexprSpanStatic<A>(), ""); | ||
|
||
testRuntimeSpan<int>(); | ||
testRuntimeSpan<long>(); | ||
testRuntimeSpan<double>(); | ||
testRuntimeSpan<A>(); | ||
|
||
testRuntimeSpanStatic<int>(); | ||
testRuntimeSpanStatic<long>(); | ||
testRuntimeSpanStatic<double>(); | ||
testRuntimeSpanStatic<A>(); | ||
|
||
checkCV(); | ||
|
||
return 0; | ||
} |
109 changes: 109 additions & 0 deletions
109
.upstream-tests/test/std/views/views.span/span.cons/range.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,109 @@ | ||
//===---------------------------------------------------------------------===// | ||
// | ||
// 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) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
// | ||
//===---------------------------------------------------------------------===// | ||
// UNSUPPORTED: c++03, c++11 | ||
|
||
// <cuda/std/span> | ||
|
||
// template<class Container> | ||
// constexpr explicit(Extent != dynamic_extent) span(Container&); | ||
// template<class Container> | ||
// constexpr explicit(Extent != dynamic_extent) span(Container const&); | ||
|
||
// This test checks for libc++'s non-conforming temporary extension to cuda::std::span | ||
// to support construction from containers that look like contiguous ranges. | ||
// | ||
// This extension is only supported when we don't ship <ranges>, and we can | ||
// remove it once we get rid of _LIBCUDACXX_HAS_NO_INCOMPLETE_RANGES. | ||
|
||
#include <cuda/std/span> | ||
#include <cuda/std/cassert> | ||
|
||
#include "test_macros.h" | ||
|
||
// Look ma - I'm a container! | ||
template <typename T> | ||
struct IsAContainer { | ||
__host__ __device__ constexpr IsAContainer() : v_{} {} | ||
__host__ __device__ constexpr size_t size() const {return 1;} | ||
__host__ __device__ constexpr T *data() {return &v_;} | ||
__host__ __device__ constexpr const T *data() const {return &v_;} | ||
|
||
__host__ __device__ constexpr const T *getV() const {return &v_;} // for checking | ||
T v_; | ||
}; | ||
|
||
template <typename T> | ||
struct NotAContainerNoData { | ||
__host__ __device__ size_t size() const {return 0;} | ||
}; | ||
|
||
template <typename T> | ||
struct NotAContainerNoSize { | ||
__host__ __device__ const T *data() const {return nullptr;} | ||
}; | ||
|
||
template <typename T> | ||
struct NotAContainerPrivate { | ||
private: | ||
__host__ __device__ size_t size() const {return 0;} | ||
__host__ __device__ const T *data() const {return nullptr;} | ||
}; | ||
|
||
template<class T, size_t extent, class container> | ||
__host__ __device__ cuda::std::span<T, extent> createImplicitSpan(container c) { | ||
return {c}; // expected-error-re {{no matching constructor for initialization of 'cuda::std::span<{{.+}}>'}} | ||
} | ||
|
||
int main(int, char**) | ||
{ | ||
|
||
// Making non-const spans from const sources (a temporary binds to `const &`) | ||
{ | ||
cuda::std::span<int> s1{IsAContainer<int>()}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<int>'}} | ||
} | ||
|
||
// Missing size and/or data | ||
{ | ||
cuda::std::span<const int> s1{NotAContainerNoData<int>()}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<const int>'}} | ||
cuda::std::span<const int> s3{NotAContainerNoSize<int>()}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<const int>'}} | ||
cuda::std::span<const int> s5{NotAContainerPrivate<int>()}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<const int>'}} | ||
} | ||
|
||
// Not the same type | ||
{ | ||
IsAContainer<int> c; | ||
cuda::std::span<float> s1{c}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<float>'}} | ||
} | ||
|
||
// CV wrong | ||
{ | ||
IsAContainer<const int> c; | ||
IsAContainer<const volatile int> cv; | ||
IsAContainer< volatile int> v; | ||
|
||
cuda::std::span< int> s1{c}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<int>'}} | ||
cuda::std::span< int> s2{v}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<int>'}} | ||
cuda::std::span< int> s3{cv}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<int>'}} | ||
cuda::std::span<const int> s4{v}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<const int>'}} | ||
cuda::std::span<const int> s5{cv}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<const int>'}} | ||
cuda::std::span< volatile int> s6{c}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<volatile int>'}} | ||
cuda::std::span< volatile int> s7{cv}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<volatile int>'}} | ||
} | ||
|
||
// explicit constructor necessary | ||
{ | ||
IsAContainer<int> c; | ||
const IsAContainer<int> cc; | ||
|
||
createImplicitSpan<int, 1>(c); | ||
createImplicitSpan<int, 1>(cc); | ||
} | ||
|
||
return 0; | ||
} |
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
Submodule llvm-project
added at
377a95