From f98f43fada0a599f9a1d3e7219fde422286fe4e8 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Mon, 14 Nov 2022 08:20:30 +0100 Subject: [PATCH] Port `std::span` and enable if for C++11 onwards to support mdspan Notably this does not take the fairly outdated state of our libc++ fork, but upgrades it to the actually approved state that became C++20. The only missing pieces are ranges support, but we can happily do that once we support ranges. --- .../pairs/pairs.pair/default-sfinae.pass.cpp | 16 +- .../views/views.span/span.cons/array.fail.cpp | 73 ++++ .../views/views.span/span.cons/array.pass.cpp | 119 ++++++ .../views.span/span.cons/assign.pass.cpp | 263 ++++++++++++ .../views/views.span/span.cons/copy.pass.cpp | 67 +++ .../views.span/span.cons/deduct.pass.cpp | 99 +++++ .../views.span/span.cons/default.fail.cpp | 30 ++ .../views.span/span.cons/default.pass.cpp | 89 ++++ .../span.cons/initializer_list.pass.cpp | 49 +++ .../span.cons/iterator_len.pass.cpp | 76 ++++ .../span.cons/iterator_len.verify.cpp | 39 ++ .../span.cons/iterator_sentinel.pass.cpp | 65 +++ .../span.cons/iterator_sentinel.verify.cpp | 35 ++ .../views/views.span/span.cons/range.pass.cpp | 144 +++++++ .../views.span/span.cons/range.verify.cpp | 110 +++++ .../span.cons/span.dtor.compile.pass.cpp | 35 ++ .../views/views.span/span.cons/span.fail.cpp | 115 +++++ .../views/views.span/span.cons/span.pass.cpp | 120 ++++++ .../views.span/span.cons/stdarray.pass.cpp | 124 ++++++ .../views/views.span/span.elem/back.pass.cpp | 83 ++++ .../views/views.span/span.elem/data.pass.cpp | 112 +++++ .../views/views.span/span.elem/front.pass.cpp | 84 ++++ .../views.span/span.elem/op_idx.pass.cpp | 110 +++++ .../views.span/span.iterators/begin.pass.cpp | 98 +++++ .../views.span/span.iterators/end.pass.cpp | 102 +++++ .../views.span/span.iterators/rbegin.pass.cpp | 103 +++++ .../views.span/span.iterators/rend.pass.cpp | 102 +++++ .../span.objectrep/as_bytes.pass.cpp | 73 ++++ .../span.objectrep/as_writable_bytes.pass.cpp | 73 ++++ .../as_writable_bytes.verify.cpp | 47 +++ .../span.obs/empty.nodiscard.verify.cpp | 30 ++ .../views/views.span/span.obs/empty.pass.cpp | 65 +++ .../views/views.span/span.obs/size.pass.cpp | 84 ++++ .../views.span/span.obs/size_bytes.pass.cpp | 85 ++++ .../views/views.span/span.sub/first.pass.cpp | 110 +++++ .../views.span/span.sub/first.verify.cpp | 36 ++ .../views/views.span/span.sub/last.pass.cpp | 109 +++++ .../views/views.span/span.sub/last.verify.cpp | 36 ++ .../views.span/span.sub/subspan.pass.cpp | 208 +++++++++ .../views.span/span.sub/subspan.verify.cpp | 42 ++ .../trivially_copyable.compile.pass.cpp | 24 ++ .../test/std/views/views.span/types.pass.cpp | 95 +++++ .upstream-tests/test/support/test_macros.h | 17 + .../cuda/std/detail/libcxx/include/iterator | 4 +- include/cuda/std/detail/libcxx/include/span | 394 ++++++++---------- .../std/detail/libcxx/include/type_traits | 1 + .../cuda/std/detail/libcxx/include/version | 1 + include/cuda/std/span | 29 ++ 48 files changed, 3795 insertions(+), 230 deletions(-) create mode 100644 .upstream-tests/test/std/views/views.span/span.cons/array.fail.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.cons/array.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.cons/assign.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.cons/copy.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.cons/deduct.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.cons/default.fail.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.cons/default.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.cons/initializer_list.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.cons/iterator_len.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.cons/iterator_len.verify.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.cons/iterator_sentinel.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.cons/iterator_sentinel.verify.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.cons/range.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.cons/range.verify.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.cons/span.dtor.compile.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.cons/span.fail.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.cons/span.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.cons/stdarray.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.elem/back.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.elem/data.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.elem/front.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.elem/op_idx.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.iterators/begin.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.iterators/end.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.iterators/rbegin.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.iterators/rend.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.objectrep/as_bytes.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.objectrep/as_writable_bytes.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.objectrep/as_writable_bytes.verify.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.obs/empty.nodiscard.verify.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.obs/empty.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.obs/size.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.obs/size_bytes.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.sub/first.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.sub/first.verify.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.sub/last.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.sub/last.verify.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.sub/subspan.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/span.sub/subspan.verify.cpp create mode 100644 .upstream-tests/test/std/views/views.span/trivially_copyable.compile.pass.cpp create mode 100644 .upstream-tests/test/std/views/views.span/types.pass.cpp create mode 100644 include/cuda/std/span diff --git a/.upstream-tests/test/std/utilities/utility/pairs/pairs.pair/default-sfinae.pass.cpp b/.upstream-tests/test/std/utilities/utility/pairs/pairs.pair/default-sfinae.pass.cpp index a33c1b079a..13d948e919 100644 --- a/.upstream-tests/test/std/utilities/utility/pairs/pairs.pair/default-sfinae.pass.cpp +++ b/.upstream-tests/test/std/utilities/utility/pairs/pairs.pair/default-sfinae.pass.cpp @@ -22,14 +22,6 @@ #include "test_macros.h" -#if TEST_STD_VER > 11 -#define CONSTEXPR_CXX14 constexpr -#define STATIC_ASSERT_CXX14(Pred) static_assert(Pred, "") -#else -#define CONSTEXPR_CXX14 -#define STATIC_ASSERT_CXX14(Pred) assert(Pred) -#endif - struct DeletedDefault { // A class with a deleted default constructor. Used to test the SFINAE // on cuda::std::pair's default constructor. @@ -121,20 +113,20 @@ __host__ __device__ void test_illformed_default() { typedef cuda::std::pair P; static_assert((cuda::std::is_constructible::value), ""); - CONSTEXPR_CXX14 P p(IllFormedDefault(42), -5); + TEST_CONSTEXPR_CXX14 P p(IllFormedDefault(42), -5); STATIC_ASSERT_CXX14(p.first.value == 42 && p.second == -5); } { typedef cuda::std::pair P; static_assert((cuda::std::is_constructible::value), ""); - CONSTEXPR_CXX14 IllFormedDefault dd(-5); - CONSTEXPR_CXX14 P p(42, dd); + TEST_CONSTEXPR_CXX14 IllFormedDefault dd(-5); + TEST_CONSTEXPR_CXX14 P p(42, dd); STATIC_ASSERT_CXX14(p.first == 42 && p.second.value == -5); } { typedef cuda::std::pair P; static_assert((cuda::std::is_constructible::value), ""); - CONSTEXPR_CXX14 P p(IllFormedDefault(42), IllFormedDefault(-5)); + TEST_CONSTEXPR_CXX14 P p(IllFormedDefault(42), IllFormedDefault(-5)); STATIC_ASSERT_CXX14(p.first.value == 42 && p.second.value == -5); } } diff --git a/.upstream-tests/test/std/views/views.span/span.cons/array.fail.cpp b/.upstream-tests/test/std/views/views.span/span.cons/array.fail.cpp new file mode 100644 index 0000000000..eab06786b7 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.cons/array.fail.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: nvrtc + +// + +// template +// constexpr span(element_type (&arr)[N]) noexcept; +// template +// constexpr span(array& arr) noexcept; +// template +// constexpr span(const array& arr) noexcept; +// +// Remarks: These constructors shall not participate in overload resolution unless: +// — extent == dynamic_extent || N == extent is true, and +// — remove_pointer_t(*)[] is convertible to ElementType(*)[]. +// + + +#include +#include + +#include "test_macros.h" + +__device__ int arr[] = {1,2,3}; +__device__ const int carr[] = {4,5,6}; +__device__ volatile int varr[] = {7,8,9}; +__device__ const volatile int cvarr[] = {1,3,5}; + +int main(int, char**) +{ +// Size wrong + { + cuda::std::span s1(arr); // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + } + +// Type wrong + { + cuda::std::span s1(arr); // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span s2(arr); // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + } + +// CV wrong (dynamically sized) + { + cuda::std::span< int> s1{ carr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< int> s2{ varr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< int> s3{cvarr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span s4{ varr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span s5{cvarr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< volatile int> s6{ carr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< volatile int> s7{cvarr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + } + +// CV wrong (statically sized) + { + cuda::std::span< int,3> s1{ carr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< int,3> s2{ varr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< int,3> s3{cvarr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span s4{ varr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span s5{cvarr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< volatile int,3> s6{ carr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< volatile int,3> s7{cvarr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + } + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.cons/array.pass.cpp b/.upstream-tests/test/std/views/views.span/span.cons/array.pass.cpp new file mode 100644 index 0000000000..dc9d9415ff --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.cons/array.pass.cpp @@ -0,0 +1,119 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// constexpr span(element_type (&arr)[N]) noexcept; +// +// Remarks: These constructors shall not participate in overload resolution unless: +// — extent == dynamic_extent || N == extent is true, and +// — remove_pointer_t(*)[] is convertible to ElementType(*)[]. +// + + +#include +#include + +#include "test_macros.h" + +__device__ int arr[] = {1,2,3}; +__device__ const int carr[] = {4,5,6}; +__device__ volatile int varr[] = {7,8,9}; +__device__ const volatile int cvarr[] = {1,3,5}; + +__host__ __device__ void checkCV() +{ +// Types the same (dynamic sized) + { + cuda::std::span< int> s1{ arr}; // a cuda::std::span< int> pointing at int. + cuda::std::span s2{ carr}; // a cuda::std::span pointing at const int. + cuda::std::span< volatile int> s3{ varr}; // a cuda::std::span< volatile int> pointing at volatile int. + cuda::std::span s4{cvarr}; // a cuda::std::span pointing at const volatile int. + assert(s1.size() + s2.size() + s3.size() + s4.size() == 12); + } + +// Types the same (static sized) + { + cuda::std::span< int,3> s1{ arr}; // a cuda::std::span< int> pointing at int. + cuda::std::span s2{ carr}; // a cuda::std::span pointing at const int. + cuda::std::span< volatile int,3> s3{ varr}; // a cuda::std::span< volatile int> pointing at volatile int. + cuda::std::span s4{cvarr}; // a cuda::std::span pointing at const volatile int. + assert(s1.size() + s2.size() + s3.size() + s4.size() == 12); + } + + +// types different (dynamic sized) + { + cuda::std::span s1{ arr}; // a cuda::std::span pointing at int. + cuda::std::span< volatile int> s2{ arr}; // a cuda::std::span< volatile int> pointing at int. + cuda::std::span< volatile int> s3{ arr}; // a cuda::std::span< volatile int> pointing at const int. + cuda::std::span s4{ arr}; // a cuda::std::span pointing at int. + cuda::std::span s5{carr}; // a cuda::std::span pointing at const int. + cuda::std::span s6{varr}; // a cuda::std::span pointing at volatile int. + assert(s1.size() + s2.size() + s3.size() + s4.size() + s5.size() + s6.size() == 18); + } + +// types different (static sized) + { + cuda::std::span s1{ arr}; // a cuda::std::span pointing at int. + cuda::std::span< volatile int,3> s2{ arr}; // a cuda::std::span< volatile int> pointing at int. + cuda::std::span< volatile int,3> s3{ arr}; // a cuda::std::span< volatile int> pointing at const int. + cuda::std::span s4{ arr}; // a cuda::std::span pointing at int. + cuda::std::span s5{carr}; // a cuda::std::span pointing at const int. + cuda::std::span s6{varr}; // a cuda::std::span pointing at volatile int. + assert(s1.size() + s2.size() + s3.size() + s4.size() + s5.size() + s6.size() == 18); + } +} + +template +__host__ __device__ constexpr bool testSpan() +{ + T val[2] = {}; + + ASSERT_NOEXCEPT(cuda::std::span{val}); + ASSERT_NOEXCEPT(cuda::std::span{val}); + ASSERT_NOEXCEPT(cuda::std::span{val}); + ASSERT_NOEXCEPT(cuda::std::span{val}); + + cuda::std::span s1 = val; + cuda::std::span s2 = val; + cuda::std::span s3 = val; + cuda::std::span s4 = val; + assert(s1.data() == val && s1.size() == 2); + assert(s2.data() == val && s2.size() == 2); + assert(s3.data() == val && s3.size() == 2); + assert(s4.data() == val && s4.size() == 2); + + cuda::std::span s5 = {{1,2}}; + cuda::std::span s6 = {{1,2}}; + assert(s5.size() == 2); // and it dangles + assert(s6.size() == 2); // and it dangles + + return true; +} + + +struct A {}; + +int main(int, char**) +{ + testSpan(); + testSpan(); + testSpan(); + + static_assert(testSpan(), ""); + static_assert(testSpan(), ""); + static_assert(testSpan(), ""); + + checkCV(); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.cons/assign.pass.cpp b/.upstream-tests/test/std/views/views.span/span.cons/assign.pass.cpp new file mode 100644 index 0000000000..2dfb25cd8b --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.cons/assign.pass.cpp @@ -0,0 +1,263 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// constexpr span& operator=(const span& other) noexcept = default; + +#include +#include +#include +#include + +#include "test_macros.h" + +using cuda::std::span; + +template +__host__ __device__ +constexpr bool doAssign(T lhs, T rhs) +{ + ASSERT_NOEXCEPT(cuda::std::declval() = rhs); + lhs = rhs; + return lhs.data() == rhs.data() + && lhs.size() == rhs.size(); +} + +struct A{}; + +__device__ constexpr int carr1[] = {1,2,3,4}; +__device__ constexpr int carr2[] = {3,4,5}; +__device__ constexpr int carr3[] = {7,8}; +__device__ int arr[] = {5,6,7,9}; + +int main(int, char**) +{ + +// constexpr dynamically sized assignment + { +// On systems where 'ptrdiff_t' is a synonym for 'int', +// the call span(ptr, 0) selects the (pointer, size_type) constructor. +// On systems where 'ptrdiff_t' is NOT a synonym for 'int', +// it is ambiguous, because of 0 also being convertible to a null pointer +// and so the compiler can't choose between: +// span(pointer, size_type) +// and span(pointer, pointer) +// We cast zero to std::ptrdiff_t to remove that ambiguity. +// Example: +// On darwin x86_64, ptrdiff_t is the same as long int. +// On darwin i386, ptrdiff_t is the same as int. + constexpr cuda::std::span spans[] = { + {}, + {carr1, static_cast(0)}, + {carr1, 1U}, + {carr1, 2U}, + {carr1, 3U}, + {carr1, 4U}, + {carr2, static_cast(0)}, + {carr2, 1U}, + {carr2, 2U}, + {carr2, 3U}, + {carr3, static_cast(0)}, + {carr3, 1U}, + {carr3, 2U} + }; + //static_assert(cuda::std::size(spans) == 13 ); + +// No for loops in constexpr land :-( + STATIC_ASSERT_CXX14(doAssign(spans[0], spans[0])); + STATIC_ASSERT_CXX14(doAssign(spans[0], spans[1])); + STATIC_ASSERT_CXX14(doAssign(spans[0], spans[2])); + STATIC_ASSERT_CXX14(doAssign(spans[0], spans[3])); + STATIC_ASSERT_CXX14(doAssign(spans[0], spans[4])); + STATIC_ASSERT_CXX14(doAssign(spans[0], spans[5])); + STATIC_ASSERT_CXX14(doAssign(spans[0], spans[6])); + STATIC_ASSERT_CXX14(doAssign(spans[0], spans[7])); + STATIC_ASSERT_CXX14(doAssign(spans[0], spans[8])); + STATIC_ASSERT_CXX14(doAssign(spans[0], spans[9])); + STATIC_ASSERT_CXX14(doAssign(spans[0], spans[10])); + STATIC_ASSERT_CXX14(doAssign(spans[0], spans[11])); + STATIC_ASSERT_CXX14(doAssign(spans[0], spans[12])); + + STATIC_ASSERT_CXX14(doAssign(spans[1], spans[1])); + STATIC_ASSERT_CXX14(doAssign(spans[1], spans[2])); + STATIC_ASSERT_CXX14(doAssign(spans[1], spans[3])); + STATIC_ASSERT_CXX14(doAssign(spans[1], spans[4])); + STATIC_ASSERT_CXX14(doAssign(spans[1], spans[5])); + STATIC_ASSERT_CXX14(doAssign(spans[1], spans[6])); + STATIC_ASSERT_CXX14(doAssign(spans[1], spans[7])); + STATIC_ASSERT_CXX14(doAssign(spans[1], spans[8])); + STATIC_ASSERT_CXX14(doAssign(spans[1], spans[9])); + STATIC_ASSERT_CXX14(doAssign(spans[1], spans[10])); + STATIC_ASSERT_CXX14(doAssign(spans[1], spans[11])); + STATIC_ASSERT_CXX14(doAssign(spans[1], spans[12])); + + STATIC_ASSERT_CXX14(doAssign(spans[2], spans[2])); + STATIC_ASSERT_CXX14(doAssign(spans[2], spans[3])); + STATIC_ASSERT_CXX14(doAssign(spans[2], spans[4])); + STATIC_ASSERT_CXX14(doAssign(spans[2], spans[5])); + STATIC_ASSERT_CXX14(doAssign(spans[2], spans[6])); + STATIC_ASSERT_CXX14(doAssign(spans[2], spans[7])); + STATIC_ASSERT_CXX14(doAssign(spans[2], spans[8])); + STATIC_ASSERT_CXX14(doAssign(spans[2], spans[9])); + STATIC_ASSERT_CXX14(doAssign(spans[2], spans[10])); + STATIC_ASSERT_CXX14(doAssign(spans[2], spans[11])); + STATIC_ASSERT_CXX14(doAssign(spans[2], spans[12])); + + STATIC_ASSERT_CXX14(doAssign(spans[3], spans[3])); + STATIC_ASSERT_CXX14(doAssign(spans[3], spans[4])); + STATIC_ASSERT_CXX14(doAssign(spans[3], spans[4])); + STATIC_ASSERT_CXX14(doAssign(spans[3], spans[4])); + STATIC_ASSERT_CXX14(doAssign(spans[3], spans[4])); + STATIC_ASSERT_CXX14(doAssign(spans[3], spans[4])); + STATIC_ASSERT_CXX14(doAssign(spans[3], spans[4])); + STATIC_ASSERT_CXX14(doAssign(spans[3], spans[4])); + STATIC_ASSERT_CXX14(doAssign(spans[3], spans[4])); + STATIC_ASSERT_CXX14(doAssign(spans[3], spans[10])); + STATIC_ASSERT_CXX14(doAssign(spans[3], spans[11])); + STATIC_ASSERT_CXX14(doAssign(spans[3], spans[12])); + + STATIC_ASSERT_CXX14(doAssign(spans[4], spans[4])); + STATIC_ASSERT_CXX14(doAssign(spans[4], spans[5])); + STATIC_ASSERT_CXX14(doAssign(spans[4], spans[6])); + STATIC_ASSERT_CXX14(doAssign(spans[4], spans[7])); + STATIC_ASSERT_CXX14(doAssign(spans[4], spans[8])); + STATIC_ASSERT_CXX14(doAssign(spans[4], spans[9])); + STATIC_ASSERT_CXX14(doAssign(spans[4], spans[10])); + STATIC_ASSERT_CXX14(doAssign(spans[4], spans[11])); + STATIC_ASSERT_CXX14(doAssign(spans[4], spans[12])); + + STATIC_ASSERT_CXX14(doAssign(spans[5], spans[5])); + STATIC_ASSERT_CXX14(doAssign(spans[5], spans[6])); + STATIC_ASSERT_CXX14(doAssign(spans[5], spans[7])); + STATIC_ASSERT_CXX14(doAssign(spans[5], spans[8])); + STATIC_ASSERT_CXX14(doAssign(spans[5], spans[9])); + STATIC_ASSERT_CXX14(doAssign(spans[5], spans[10])); + STATIC_ASSERT_CXX14(doAssign(spans[5], spans[11])); + STATIC_ASSERT_CXX14(doAssign(spans[5], spans[12])); + + STATIC_ASSERT_CXX14(doAssign(spans[6], spans[6])); + STATIC_ASSERT_CXX14(doAssign(spans[6], spans[7])); + STATIC_ASSERT_CXX14(doAssign(spans[6], spans[8])); + STATIC_ASSERT_CXX14(doAssign(spans[6], spans[9])); + STATIC_ASSERT_CXX14(doAssign(spans[6], spans[10])); + STATIC_ASSERT_CXX14(doAssign(spans[6], spans[11])); + STATIC_ASSERT_CXX14(doAssign(spans[6], spans[12])); + + STATIC_ASSERT_CXX14(doAssign(spans[7], spans[7])); + STATIC_ASSERT_CXX14(doAssign(spans[7], spans[8])); + STATIC_ASSERT_CXX14(doAssign(spans[7], spans[9])); + STATIC_ASSERT_CXX14(doAssign(spans[7], spans[10])); + STATIC_ASSERT_CXX14(doAssign(spans[7], spans[11])); + STATIC_ASSERT_CXX14(doAssign(spans[7], spans[12])); + + STATIC_ASSERT_CXX14(doAssign(spans[8], spans[8])); + STATIC_ASSERT_CXX14(doAssign(spans[8], spans[9])); + STATIC_ASSERT_CXX14(doAssign(spans[8], spans[10])); + STATIC_ASSERT_CXX14(doAssign(spans[8], spans[11])); + STATIC_ASSERT_CXX14(doAssign(spans[8], spans[12])); + + STATIC_ASSERT_CXX14(doAssign(spans[9], spans[9])); + STATIC_ASSERT_CXX14(doAssign(spans[9], spans[10])); + STATIC_ASSERT_CXX14(doAssign(spans[9], spans[11])); + STATIC_ASSERT_CXX14(doAssign(spans[9], spans[12])); + + STATIC_ASSERT_CXX14(doAssign(spans[10], spans[10])); + STATIC_ASSERT_CXX14(doAssign(spans[10], spans[11])); + STATIC_ASSERT_CXX14(doAssign(spans[10], spans[12])); + + STATIC_ASSERT_CXX14(doAssign(spans[11], spans[11])); + STATIC_ASSERT_CXX14(doAssign(spans[11], spans[12])); + + STATIC_ASSERT_CXX14(doAssign(spans[12], spans[12])); + +// for (size_t i = 0; i < cuda::std::size(spans); ++i) +// for (size_t j = i; j < cuda::std::size(spans); ++j) +// static_assert(doAssign(spans[i], spans[j])); + } + +// constexpr statically sized assignment + { + using spanType = cuda::std::span; + + constexpr spanType spans[] = { + spanType{carr1, 2}, + spanType{carr1 + 1, 2}, + spanType{carr1 + 2, 2}, + spanType{carr2, 2}, + spanType{carr2 + 1, 2}, + spanType{carr3, 2} + }; + STATIC_ASSERT_CXX14(cuda::std::size(spans) == 6 ); + + // No for loops in constexpr land :-( + STATIC_ASSERT_CXX14(doAssign(spans[0], spans[0])); + STATIC_ASSERT_CXX14(doAssign(spans[0], spans[1])); + STATIC_ASSERT_CXX14(doAssign(spans[0], spans[2])); + STATIC_ASSERT_CXX14(doAssign(spans[0], spans[3])); + STATIC_ASSERT_CXX14(doAssign(spans[0], spans[4])); + STATIC_ASSERT_CXX14(doAssign(spans[0], spans[5])); + + STATIC_ASSERT_CXX14(doAssign(spans[1], spans[1])); + STATIC_ASSERT_CXX14(doAssign(spans[1], spans[2])); + STATIC_ASSERT_CXX14(doAssign(spans[1], spans[3])); + STATIC_ASSERT_CXX14(doAssign(spans[1], spans[4])); + STATIC_ASSERT_CXX14(doAssign(spans[1], spans[5])); + + STATIC_ASSERT_CXX14(doAssign(spans[2], spans[2])); + STATIC_ASSERT_CXX14(doAssign(spans[2], spans[3])); + STATIC_ASSERT_CXX14(doAssign(spans[2], spans[4])); + STATIC_ASSERT_CXX14(doAssign(spans[2], spans[5])); + + STATIC_ASSERT_CXX14(doAssign(spans[3], spans[3])); + STATIC_ASSERT_CXX14(doAssign(spans[3], spans[4])); + STATIC_ASSERT_CXX14(doAssign(spans[3], spans[5])); + + STATIC_ASSERT_CXX14(doAssign(spans[4], spans[4])); + STATIC_ASSERT_CXX14(doAssign(spans[4], spans[5])); + + STATIC_ASSERT_CXX14(doAssign(spans[5], spans[5])); + +// for (size_t i = 0; i < cuda::std::size(spans); ++i) +// for (size_t j = i; j < cuda::std::size(spans); ++j) +// static_assert(doAssign(spans[i], spans[j])); + } + +// dynamically sized assignment + { + cuda::std::span spans[] = { + {}, + {arr, arr + 1}, + {arr, arr + 2}, + {arr, arr + 3}, + {arr + 1, arr + 3} // same size as s2 + }; + + for (size_t i = 0; i < 5; ++i) + for (size_t j = i; j < 5; ++j) + assert((doAssign(spans[i], spans[j]))); + } + +// statically sized assignment + { + using spanType = cuda::std::span; + spanType spans[] = { + spanType{arr, arr + 2}, + spanType{arr + 1, arr + 3}, + spanType{arr + 2, arr + 4} + }; + + for (size_t i = 0; i < 3; ++i) + for (size_t j = i; j < 3; ++j) + assert((doAssign(spans[i], spans[j]))); + } + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.cons/copy.pass.cpp b/.upstream-tests/test/std/views/views.span/span.cons/copy.pass.cpp new file mode 100644 index 0000000000..748e0f3728 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.cons/copy.pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// constexpr span(const span& other) noexcept = default; + +#include +#include + +#include "test_macros.h" + +template +__host__ __device__ +constexpr bool doCopy(const T &rhs) +{ + ASSERT_NOEXCEPT(T{rhs}); + T lhs{rhs}; + return lhs.data() == rhs.data() + && lhs.size() == rhs.size(); +} + +struct A{}; + +template +__host__ __device__ +void testCV () +{ + int arr[] = {1,2,3}; + assert((doCopy(cuda::std::span () ))); + assert((doCopy(cuda::std::span() ))); + assert((doCopy(cuda::std::span (&arr[0], 1)))); + assert((doCopy(cuda::std::span(&arr[0], 1)))); + assert((doCopy(cuda::std::span (&arr[0], 2)))); + assert((doCopy(cuda::std::span(&arr[0], 2)))); +} + +__device__ constexpr int carr[] = {1,2,3}; + +int main(int, char**) +{ + + STATIC_ASSERT_CXX14(doCopy(cuda::std::span< int> ())); + STATIC_ASSERT_CXX14(doCopy(cuda::std::span< int,0>())); + STATIC_ASSERT_CXX14(doCopy(cuda::std::span (&carr[0], 1))); + STATIC_ASSERT_CXX14(doCopy(cuda::std::span(&carr[0], 1))); + STATIC_ASSERT_CXX14(doCopy(cuda::std::span (&carr[0], 2))); + STATIC_ASSERT_CXX14(doCopy(cuda::std::span(&carr[0], 2))); + + STATIC_ASSERT_CXX14(doCopy(cuda::std::span())); + STATIC_ASSERT_CXX14(doCopy(cuda::std::span())); + STATIC_ASSERT_CXX14(doCopy(cuda::std::span())); + + testCV< int>(); + testCV(); + testCV< volatile int>(); + testCV(); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.cons/deduct.pass.cpp b/.upstream-tests/test/std/views/views.span/span.cons/deduct.pass.cpp new file mode 100644 index 0000000000..c7ea5fe3e6 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.cons/deduct.pass.cpp @@ -0,0 +1,99 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++14 + +// + +// template +// span(It, EndOrSize) -> span>>; +// +// template +// span(T (&)[N]) -> span; +// +// template +// span(array&) -> span; +// +// template +// span(const array&) -> span; +// +// template +// span(R&&) -> span>>; + + +#include +#include +#include +#include + +#include "test_macros.h" + + +__host__ __device__ +void test_iterator_sentinel() { + int arr[] = {1, 2, 3}; + { + cuda::std::span s{cuda::std::begin(arr), cuda::std::end(arr)}; + ASSERT_SAME_TYPE(decltype(s), cuda::std::span); + assert(s.size() == cuda::std::size(arr)); + assert(s.data() == cuda::std::data(arr)); + } + { + cuda::std::span s{cuda::std::begin(arr), 3}; + ASSERT_SAME_TYPE(decltype(s), cuda::std::span); + assert(s.size() == cuda::std::size(arr)); + assert(s.data() == cuda::std::data(arr)); + } +} + +__host__ __device__ +void test_c_array() { + { + int arr[] = {1, 2, 3}; + cuda::std::span s{arr}; + ASSERT_SAME_TYPE(decltype(s), cuda::std::span); + assert(s.size() == cuda::std::size(arr)); + assert(s.data() == cuda::std::data(arr)); + } + + { + const int arr[] = {1,2,3}; + cuda::std::span s{arr}; + ASSERT_SAME_TYPE(decltype(s), cuda::std::span); + assert(s.size() == cuda::std::size(arr)); + assert(s.data() == cuda::std::data(arr)); + } +} + +__host__ __device__ +void test_std_array() { + { + cuda::std::array arr = {1.0, 2.0, 3.0, 4.0}; + cuda::std::span s{arr}; + ASSERT_SAME_TYPE(decltype(s), cuda::std::span); + assert(s.size() == arr.size()); + assert(s.data() == arr.data()); + } + + { + const cuda::std::array arr = {4, 5, 6, 7, 8}; + cuda::std::span s{arr}; + ASSERT_SAME_TYPE(decltype(s), cuda::std::span); + assert(s.size() == arr.size()); + assert(s.data() == arr.data()); + } +} + +int main(int, char**) +{ + test_iterator_sentinel(); + test_c_array(); + test_std_array(); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.cons/default.fail.cpp b/.upstream-tests/test/std/views/views.span/span.cons/default.fail.cpp new file mode 100644 index 0000000000..6532c7c8c5 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.cons/default.fail.cpp @@ -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) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: nvrtc + +// + +// constexpr span() noexcept; +// +// Remarks: This constructor shall not participate in overload resolution +// unless Extent == 0 || Extent == dynamic_extent is true. + + +#include +#include + +#include "test_macros.h" + +int main(int, char**) +{ + cuda::std::span s; // expected-error {{no matching constructor for initialization of 'std::span'}} + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.cons/default.pass.cpp b/.upstream-tests/test/std/views/views.span/span.cons/default.pass.cpp new file mode 100644 index 0000000000..fcb4039431 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.cons/default.pass.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// constexpr span() noexcept; + +#include +#include +#include + +#include "test_macros.h" + +__host__ __device__ +void checkCV() +{ +// Types the same (dynamic sized) + { + cuda::std::span< int> s1; + cuda::std::span s2; + cuda::std::span< volatile int> s3; + cuda::std::span s4; + assert(s1.size() + s2.size() + s3.size() + s4.size() == 0); + } + +// Types the same (static sized) + { + cuda::std::span< int,0> s1; + cuda::std::span s2; + cuda::std::span< volatile int,0> s3; + cuda::std::span s4; + assert(s1.size() + s2.size() + s3.size() + s4.size() == 0); + } +} + + +template +__host__ __device__ +constexpr bool testConstexprSpan() +{ + cuda::std::span s1; + cuda::std::span s2; + return + s1.data() == nullptr && s1.size() == 0 + && s2.data() == nullptr && s2.size() == 0; +} + + +template +__host__ __device__ +void testRuntimeSpan() +{ + ASSERT_NOEXCEPT(T{}); + cuda::std::span s1; + cuda::std::span s2; + assert(s1.data() == nullptr && s1.size() == 0); + assert(s2.data() == nullptr && s2.size() == 0); +} + + +struct A{}; + +int main(int, char**) +{ + STATIC_ASSERT_CXX14(testConstexprSpan()); + STATIC_ASSERT_CXX14(testConstexprSpan()); + STATIC_ASSERT_CXX14(testConstexprSpan()); + STATIC_ASSERT_CXX14(testConstexprSpan()); + + testRuntimeSpan(); + testRuntimeSpan(); + testRuntimeSpan(); + testRuntimeSpan(); + + checkCV(); + + static_assert( cuda::std::is_default_constructible>::value, ""); + static_assert( cuda::std::is_default_constructible>::value, ""); + static_assert(!cuda::std::is_default_constructible>::value, ""); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.cons/initializer_list.pass.cpp b/.upstream-tests/test/std/views/views.span/span.cons/initializer_list.pass.cpp new file mode 100644 index 0000000000..3d25243326 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.cons/initializer_list.pass.cpp @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +#include +#include +#include + +#include "test_macros.h" +struct Sink { + constexpr Sink() = default; + __host__ __device__ + constexpr Sink(Sink*) {} +}; + +__host__ __device__ +constexpr cuda::std::size_t count(cuda::std::span sp) { + return sp.size(); +} + +template +__host__ __device__ +constexpr cuda::std::size_t countn(cuda::std::span sp) { + return sp.size(); +} + +__host__ __device__ +constexpr bool test() { + Sink a[10] = {}; + assert(count({a}) == 10); + assert(count({a, a+10}) == 10); + assert(countn<10>({a}) == 10); + return true; +} + +int main(int, char**) { + test(); + static_assert(test(), ""); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.cons/iterator_len.pass.cpp b/.upstream-tests/test/std/views/views.span/span.cons/iterator_len.pass.cpp new file mode 100644 index 0000000000..d975429dd5 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.cons/iterator_len.pass.cpp @@ -0,0 +1,76 @@ +//===---------------------------------------------------------------------===// +// +// 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 + +// + +// template +// constexpr explicit(Extent != dynamic_extent) span(It first, size_type count); +// If Extent is not equal to dynamic_extent, then count shall be equal to Extent. +// + + +#include +#include +#include +#include + +#include "test_macros.h" + +template +__host__ __device__ +constexpr bool test_constructibility() { + struct Other {}; + static_assert(cuda::std::is_constructible, int*, size_t>::value, ""); + static_assert(!cuda::std::is_constructible, const int*, size_t>::value, ""); + static_assert(cuda::std::is_constructible, int*, size_t>::value, ""); + static_assert(cuda::std::is_constructible, const int*, size_t>::value, ""); + static_assert(!cuda::std::is_constructible, volatile int*, size_t>::value, ""); + static_assert(!cuda::std::is_constructible, const volatile int*, size_t>::value, ""); + static_assert(!cuda::std::is_constructible, volatile int*, size_t>::value, ""); + static_assert(!cuda::std::is_constructible, const volatile int*, size_t>::value, ""); + static_assert(!cuda::std::is_constructible, const int*, size_t>::value, ""); + static_assert(!cuda::std::is_constructible, const volatile int*, size_t>::value, ""); + static_assert( + !cuda::std::is_constructible, double*, size_t>::value, ""); // iterator type differs from span type + static_assert(!cuda::std::is_constructible, size_t, size_t>::value, ""); + static_assert(!cuda::std::is_constructible, Other*, size_t>::value, ""); // unrelated iterator type + + return true; +} + +template +__host__ __device__ +constexpr bool test_ctor() { + T val[2] = {}; + auto s1 = cuda::std::span(val, 2); + auto s2 = cuda::std::span(val, 2); + assert(s1.data() == val && s1.size() == 2); + assert(s2.data() == val && s2.size() == 2); + return true; +} + +__host__ __device__ +constexpr bool test() { + test_constructibility(); + test_constructibility<3>(); + + struct A {}; + test_ctor(); + test_ctor(); + + return true; +} + +int main(int, char**) { + test(); + static_assert(test(), ""); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.cons/iterator_len.verify.cpp b/.upstream-tests/test/std/views/views.span/span.cons/iterator_len.verify.cpp new file mode 100644 index 0000000000..3136891097 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.cons/iterator_len.verify.cpp @@ -0,0 +1,39 @@ +//===---------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: nvrtc + +// + +// template +// constexpr explicit(Extent != dynamic_extent) span(It first, size_type count); +// If Extent is not equal to dynamic_extent, then count shall be equal to Extent. +// + +#include +#include + +template +__host__ __device__ +cuda::std::span createImplicitSpan(T* ptr, size_t len) { + return {ptr, len}; // expected-error {{chosen constructor is explicit in copy-initialization}} +} + +int main(int, char**) { + // explicit constructor necessary + int arr[] = {1, 2, 3}; + createImplicitSpan(arr, 3); + + cuda::std::span sp = {0, 0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span sp2 = {0, 0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span csp = {0, 0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span csp2 = {0, 0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.cons/iterator_sentinel.pass.cpp b/.upstream-tests/test/std/views/views.span/span.cons/iterator_sentinel.pass.cpp new file mode 100644 index 0000000000..fead7b1758 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.cons/iterator_sentinel.pass.cpp @@ -0,0 +1,65 @@ +//===---------------------------------------------------------------------===// +// +// 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 + +// + +// template +// constexpr explicit(Extent != dynamic_extent) span(It first, End last); +// Requires: [first, last) shall be a valid range. +// If Extent is not equal to dynamic_extent, then last - first shall be equal to Extent. +// + +#include +#include + +#include "test_macros.h" +#include "test_iterators.h" + +template +__host__ __device__ constexpr bool test_ctor() { + T val[2] = {}; + auto s1 = cuda::std::span(cuda::std::begin(val), Sentinel(cuda::std::end(val))); + auto s2 = cuda::std::span(cuda::std::begin(val), Sentinel(cuda::std::end(val))); + assert(s1.data() == cuda::std::data(val) && s1.size() == cuda::std::size(val)); + assert(s2.data() == cuda::std::data(val) && s2.size() == cuda::std::size(val)); + return true; +} + +template +__host__ __device__ constexpr void test_constructibility() { + static_assert(cuda::std::is_constructible_v, int*, int*>, ""); + static_assert(!cuda::std::is_constructible_v, const int*, const int*>, ""); + static_assert(!cuda::std::is_constructible_v, volatile int*, volatile int*>, ""); + static_assert(cuda::std::is_constructible_v, int*, int*>, ""); + static_assert(cuda::std::is_constructible_v, const int*, const int*>, ""); + static_assert(!cuda::std::is_constructible_v, volatile int*, volatile int*>, ""); + static_assert(cuda::std::is_constructible_v, int*, int*>, ""); + static_assert(!cuda::std::is_constructible_v, const int*, const int*>, ""); + static_assert(cuda::std::is_constructible_v, volatile int*, volatile int*>, ""); + static_assert(!cuda::std::is_constructible_v, int*, float*>, ""); // types wrong +} + +__host__ __device__ constexpr bool test() { + test_constructibility(); + test_constructibility<3>(); + struct A {}; + assert((test_ctor())); + //assert((test_ctor>())); + assert((test_ctor())); + //assert((test_ctor>())); + return true; +} + +int main(int, char**) { + test(); + static_assert(test(), ""); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.cons/iterator_sentinel.verify.cpp b/.upstream-tests/test/std/views/views.span/span.cons/iterator_sentinel.verify.cpp new file mode 100644 index 0000000000..fd7e003cf2 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.cons/iterator_sentinel.verify.cpp @@ -0,0 +1,35 @@ +//===---------------------------------------------------------------------===// +// +// 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, c++14, c++17 + +// + +// template +// constexpr explicit(Extent != dynamic_extent) span(It first, End last); +// Requires: [first, last) shall be a valid range. +// If Extent is not equal to dynamic_extent, then last - first shall be equal to Extent. +// + +#include +#include + +#include "test_macros.h" + +template +cuda::std::span createImplicitSpan(T* first, T* last) { + return {first, last}; // expected-error {{chosen constructor is explicit in copy-initialization}} +} + +int main(int, char**) { + // explicit constructor necessary + int arr[] = {1, 2, 3}; + createImplicitSpan(cuda::std::begin(arr), cuda::std::end(arr)); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.cons/range.pass.cpp b/.upstream-tests/test/std/views/views.span/span.cons/range.pass.cpp new file mode 100644 index 0000000000..96c420053d --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.cons/range.pass.cpp @@ -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 + +// + +// template +// constexpr explicit(Extent != dynamic_extent) span(Container&); +// template +// 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 , and we can +// remove it once we get rid of _LIBCUDACXX_HAS_NO_INCOMPLETE_RANGES. + +#include +#include + +#include "test_macros.h" + +// Look ma - I'm a container! +template +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 +__host__ __device__ +constexpr bool unused(T &&) {return true;} + +__host__ __device__ void checkCV() +{ + IsAContainer v{}; + +// Types the same + { + cuda::std::span< int> s1{v}; // a span< int> pointing at int. + unused(s1); + } + +// types different + { + cuda::std::span s1{v}; // a span 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 s4{v}; // a span pointing at int. + unused(s1); + unused(s2); + unused(s3); + unused(s4); + } + +// Constructing a const view from a temporary + { + cuda::std::span s1{IsAContainer()}; + unused(s1); + } +} + + +template +__host__ __device__ constexpr bool testConstexprSpan() +{ + constexpr IsAContainer val{}; + cuda::std::span s1{val}; + return s1.data() == val.getV() && s1.size() == 1; +} + +template +__host__ __device__ constexpr bool testConstexprSpanStatic() +{ + constexpr IsAContainer val{}; + cuda::std::span s1{val}; + return s1.data() == val.getV() && s1.size() == 1; +} + +template +__host__ __device__ void testRuntimeSpan() +{ + IsAContainer val{}; + const IsAContainer cVal; + cuda::std::span s1{val}; + cuda::std::span s2{cVal}; + assert(s1.data() == val.getV() && s1.size() == 1); + assert(s2.data() == cVal.getV() && s2.size() == 1); +} + +template +__host__ __device__ void testRuntimeSpanStatic() +{ + IsAContainer val{}; + const IsAContainer cVal; + cuda::std::span s1{val}; + cuda::std::span 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(), ""); + static_assert(testConstexprSpan(), ""); + static_assert(testConstexprSpan(), ""); + static_assert(testConstexprSpan(), ""); + + static_assert(testConstexprSpanStatic(), ""); + static_assert(testConstexprSpanStatic(), ""); + static_assert(testConstexprSpanStatic(), ""); + static_assert(testConstexprSpanStatic(), ""); + + testRuntimeSpan(); + testRuntimeSpan(); + testRuntimeSpan(); + testRuntimeSpan(); + + testRuntimeSpanStatic(); + testRuntimeSpanStatic(); + testRuntimeSpanStatic(); + testRuntimeSpanStatic(); + + checkCV(); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.cons/range.verify.cpp b/.upstream-tests/test/std/views/views.span/span.cons/range.verify.cpp new file mode 100644 index 0000000000..3a93971393 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.cons/range.verify.cpp @@ -0,0 +1,110 @@ +//===---------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: nvrtc + +// + +// template +// constexpr explicit(Extent != dynamic_extent) span(Container&); +// template +// 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 , and we can +// remove it once we get rid of _LIBCUDACXX_HAS_NO_INCOMPLETE_RANGES. + +#include +#include + +#include "test_macros.h" + +// Look ma - I'm a container! +template +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 +struct NotAContainerNoData { + __host__ __device__ size_t size() const {return 0;} +}; + +template +struct NotAContainerNoSize { + __host__ __device__ const T *data() const {return nullptr;} +}; + +template +struct NotAContainerPrivate { +private: + __host__ __device__ size_t size() const {return 0;} + __host__ __device__ const T *data() const {return nullptr;} +}; + +template +__host__ __device__ cuda::std::span 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 s1{IsAContainer()}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + } + +// Missing size and/or data + { + cuda::std::span s1{NotAContainerNoData()}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span s3{NotAContainerNoSize()}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span s5{NotAContainerPrivate()}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + } + +// Not the same type + { + IsAContainer c; + cuda::std::span s1{c}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + } + +// CV wrong + { + IsAContainer c; + IsAContainer cv; + IsAContainer< volatile int> v; + + cuda::std::span< int> s1{c}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< int> s2{v}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< int> s3{cv}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span s4{v}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span s5{cv}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< volatile int> s6{c}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< volatile int> s7{cv}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + } + +// explicit constructor necessary + { + IsAContainer c; + const IsAContainer cc; + + createImplicitSpan(c); + createImplicitSpan(cc); + } + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.cons/span.dtor.compile.pass.cpp b/.upstream-tests/test/std/views/views.span/span.cons/span.dtor.compile.pass.cpp new file mode 100644 index 0000000000..524313b194 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.cons/span.dtor.compile.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// ~span() = default; + +#include +#include + +template +__host__ __device__ +constexpr bool testDestructor() { + static_assert(cuda::std::is_nothrow_destructible::value, ""); + static_assert(cuda::std::is_trivially_destructible::value, ""); + return true; +} + +__host__ __device__ +void test() { + testDestructor>(); + testDestructor>(); +} + +int main(int, char**) +{ + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.cons/span.fail.cpp b/.upstream-tests/test/std/views/views.span/span.cons/span.fail.cpp new file mode 100644 index 0000000000..4ab16a10b4 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.cons/span.fail.cpp @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: nvrtc + +// + +// template +// constexpr span(const span& s) noexcept; +// +// Remarks: This constructor shall not participate in overload resolution unless: +// Extent == dynamic_extent || Extent == OtherExtent is true, and +// OtherElementType(*)[] is convertible to ElementType(*)[]. + + +#include +#include + +#include "test_macros.h" + +template +cuda::std::span createImplicitSpan(cuda::std::span s) { + return {s}; // expected-error {{chosen constructor is explicit in copy-initialization}} +} + +void checkCV () +{ +// cuda::std::span< int> sp; + cuda::std::span csp; + cuda::std::span< volatile int> vsp; + cuda::std::span cvsp; + +// cuda::std::span< int, 0> sp0; + cuda::std::span csp0; + cuda::std::span< volatile int, 0> vsp0; + cuda::std::span cvsp0; + +// Try to remove const and/or volatile (dynamic -> dynamic) + { + cuda::std::span< int> s1{ csp}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< int> s2{ vsp}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< int> s3{cvsp}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + + cuda::std::span s4{ vsp}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span s5{cvsp}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + + cuda::std::span< volatile int> s6{ csp}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< volatile int> s7{cvsp}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + } + +// Try to remove const and/or volatile (static -> static) + { + cuda::std::span< int, 0> s1{ csp0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< int, 0> s2{ vsp0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< int, 0> s3{cvsp0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + + cuda::std::span s4{ vsp0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span s5{cvsp0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + + cuda::std::span< volatile int, 0> s6{ csp0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< volatile int, 0> s7{cvsp0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + } + +// Try to remove const and/or volatile (static -> dynamic) + { + cuda::std::span< int> s1{ csp0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< int> s2{ vsp0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< int> s3{cvsp0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + + cuda::std::span s4{ vsp0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span s5{cvsp0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + + cuda::std::span< volatile int> s6{ csp0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< volatile int> s7{cvsp0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + } + +// Try to remove const and/or volatile (static -> static) + { + cuda::std::span< int, 0> s1{ csp}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< int, 0> s2{ vsp}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< int, 0> s3{cvsp}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + + cuda::std::span s4{ vsp}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span s5{cvsp}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + + cuda::std::span< volatile int, 0> s6{ csp}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span< volatile int, 0> s7{cvsp}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + } +} + +int main(int, char**) +{ + cuda::std::span sp; + cuda::std::span sp0; + + cuda::std::span s1{sp}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span s2{sp0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span s3{sp}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + cuda::std::span s4{sp0}; // expected-error {{no matching constructor for initialization of 'cuda::std::span'}} + + checkCV(); + + // explicit constructor necessary + { + createImplicitSpan(sp); + } + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.cons/span.pass.cpp b/.upstream-tests/test/std/views/views.span/span.cons/span.pass.cpp new file mode 100644 index 0000000000..4f8886bb9b --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.cons/span.pass.cpp @@ -0,0 +1,120 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// constexpr span(const span& s) noexcept; +// +// Remarks: This constructor shall not participate in overload resolution unless: +// Extent == dynamic_extent || Extent == OtherExtent is true, and +// OtherElementType(*)[] is convertible to ElementType(*)[]. + + +#include +#include + +#include "test_macros.h" + +__host__ __device__ +void checkCV() +{ + cuda::std::span< int> sp; +// cuda::std::span csp; + cuda::std::span< volatile int> vsp; +// cuda::std::span cvsp; + + cuda::std::span< int, 0> sp0; +// cuda::std::span csp0; + cuda::std::span< volatile int, 0> vsp0; +// cuda::std::span cvsp0; + +// dynamic -> dynamic + { + cuda::std::span s1{ sp}; // a cuda::std::span pointing at int. + cuda::std::span< volatile int> s2{ sp}; // a cuda::std::span< volatile int> pointing at int. + cuda::std::span s3{ sp}; // a cuda::std::span pointing at int. + cuda::std::span s4{ vsp}; // a cuda::std::span pointing at volatile int. + assert(s1.size() + s2.size() + s3.size() + s4.size() == 0); + } + +// static -> static + { + cuda::std::span s1{ sp0}; // a cuda::std::span pointing at int. + cuda::std::span< volatile int, 0> s2{ sp0}; // a cuda::std::span< volatile int> pointing at int. + cuda::std::span s3{ sp0}; // a cuda::std::span pointing at int. + cuda::std::span s4{ vsp0}; // a cuda::std::span pointing at volatile int. + assert(s1.size() + s2.size() + s3.size() + s4.size() == 0); + } + +// static -> dynamic + { + cuda::std::span s1{ sp0}; // a cuda::std::span pointing at int. + cuda::std::span< volatile int> s2{ sp0}; // a cuda::std::span< volatile int> pointing at int. + cuda::std::span s3{ sp0}; // a cuda::std::span pointing at int. + cuda::std::span s4{ vsp0}; // a cuda::std::span pointing at volatile int. + assert(s1.size() + s2.size() + s3.size() + s4.size() == 0); + } + +// dynamic -> static (not allowed) +} + + +template +__host__ __device__ +constexpr bool testConstexprSpan() +{ + cuda::std::span s0{}; + cuda::std::span s1{}; + cuda::std::span s2(s1); // static -> dynamic + ASSERT_NOEXCEPT(cuda::std::span {s0}); + ASSERT_NOEXCEPT(cuda::std::span{s1}); + ASSERT_NOEXCEPT(cuda::std::span {s1}); + + return + s1.data() == nullptr && s1.size() == 0 + && s2.data() == nullptr && s2.size() == 0; +} + + +template +__host__ __device__ +void testRuntimeSpan() +{ + cuda::std::span s0{}; + cuda::std::span s1{}; + cuda::std::span s2(s1); // static -> dynamic + ASSERT_NOEXCEPT(cuda::std::span {s0}); + ASSERT_NOEXCEPT(cuda::std::span{s1}); + ASSERT_NOEXCEPT(cuda::std::span {s1}); + + assert(s1.data() == nullptr && s1.size() == 0); + assert(s2.data() == nullptr && s2.size() == 0); +} + + +struct A{}; + +int main(int, char**) +{ + STATIC_ASSERT_CXX14(testConstexprSpan()); + STATIC_ASSERT_CXX14(testConstexprSpan()); + STATIC_ASSERT_CXX14(testConstexprSpan()); + STATIC_ASSERT_CXX14(testConstexprSpan()); + + testRuntimeSpan(); + testRuntimeSpan(); + testRuntimeSpan(); + testRuntimeSpan(); + + checkCV(); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.cons/stdarray.pass.cpp b/.upstream-tests/test/std/views/views.span/span.cons/stdarray.pass.cpp new file mode 100644 index 0000000000..18ad569007 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.cons/stdarray.pass.cpp @@ -0,0 +1,124 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// constexpr span(array& arr) noexcept; +// template +// constexpr span(const array& arr) noexcept; +// +// Remarks: These constructors shall not participate in overload resolution unless: +// — extent == dynamic_extent || N == extent is true, and +// — remove_pointer_t(*)[] is convertible to ElementType(*)[]. +// + + +#include +#include +#include + +#include "test_macros.h" + +__host__ __device__ +void checkCV() +{ + cuda::std::array arr = {1,2,3}; +// STL says these are not cromulent +// std::array carr = {4,5,6}; +// std::array varr = {7,8,9}; +// std::array cvarr = {1,3,5}; + +// Types the same (dynamic sized) + { + cuda::std::span< int> s1{ arr}; // a cuda::std::span< int> pointing at int. + } + +// Types the same (static sized) + { + cuda::std::span< int,3> s1{ arr}; // a cuda::std::span< int> pointing at int. + } + + +// types different (dynamic sized) + { + cuda::std::span s1{ arr}; // a cuda::std::span pointing at int. + cuda::std::span< volatile int> s2{ arr}; // a cuda::std::span< volatile int> pointing at int. + cuda::std::span< volatile int> s3{ arr}; // a cuda::std::span< volatile int> pointing at const int. + cuda::std::span s4{ arr}; // a cuda::std::span pointing at int. + } + +// types different (static sized) + { + cuda::std::span s1{ arr}; // a cuda::std::span pointing at int. + cuda::std::span< volatile int,3> s2{ arr}; // a cuda::std::span< volatile int> pointing at int. + cuda::std::span< volatile int,3> s3{ arr}; // a cuda::std::span< volatile int> pointing at const int. + cuda::std::span s4{ arr}; // a cuda::std::span pointing at int. + } +} + +template +__host__ __device__ +TEST_CONSTEXPR_CXX17 bool testConstructorArray() { + cuda::std::array val = {U(), U()}; + ASSERT_NOEXCEPT(cuda::std::span{val}); + ASSERT_NOEXCEPT(cuda::std::span{val}); + cuda::std::span s1{val}; + cuda::std::span s2{val}; + return s1.data() == &val[0] && s1.size() == 2 && s2.data() == &val[0] && + s2.size() == 2; +} + +template +__host__ __device__ +TEST_CONSTEXPR_CXX17 bool testConstructorConstArray() { + const cuda::std::array val = {U(), U()}; + ASSERT_NOEXCEPT(cuda::std::span{val}); + ASSERT_NOEXCEPT(cuda::std::span{val}); + cuda::std::span s1{val}; + cuda::std::span s2{val}; + return s1.data() == &val[0] && s1.size() == 2 && s2.data() == &val[0] && + s2.size() == 2; +} + +template +__host__ __device__ +TEST_CONSTEXPR_CXX17 bool testConstructors() { + STATIC_ASSERT_CXX17((testConstructorArray())); + STATIC_ASSERT_CXX17((testConstructorArray())); + STATIC_ASSERT_CXX17((testConstructorArray())); + STATIC_ASSERT_CXX17((testConstructorConstArray())); + STATIC_ASSERT_CXX17((testConstructorConstArray())); + STATIC_ASSERT_CXX17((testConstructorConstArray())); + + return testConstructorArray() && + testConstructorArray() && + testConstructorArray() && + testConstructorConstArray() && + testConstructorConstArray() && + testConstructorConstArray(); +} + +struct A{}; + +int main(int, char**) +{ + assert(testConstructors()); + assert(testConstructors()); + assert(testConstructors()); + assert(testConstructors()); + + assert(testConstructors()); + assert(testConstructors()); + + checkCV(); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.elem/back.pass.cpp b/.upstream-tests/test/std/views/views.span/span.elem/back.pass.cpp new file mode 100644 index 0000000000..a59249df7e --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.elem/back.pass.cpp @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// constexpr reference back() const noexcept; +// Expects: empty() is false. +// Effects: Equivalent to: return *(data() + (size() - 1)); +// + + +#include +#include + +#include "test_macros.h" + +template +__host__ __device__ +constexpr bool unused(T &&) {return true;} + +template +__host__ __device__ +constexpr bool testConstexprSpan(Span sp) +{ + ASSERT_NOEXCEPT(sp.back()); + return &sp.back() == sp.data() + (sp.size() - 1); +} + +template +__host__ __device__ +void testRuntimeSpan(Span sp) +{ + ASSERT_NOEXCEPT(sp.back()); + assert(&sp.back() == sp.data() + (sp.size() - 1)); +} + +template +__host__ __device__ +void testEmptySpan(Span sp) +{ + if (!sp.empty()) + unused(sp.back()); +} + +struct A{}; +__device__ constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +__device__ int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; + +int main(int, char**) +{ + STATIC_ASSERT_CXX14(testConstexprSpan(cuda::std::span(iArr1, 1))); + STATIC_ASSERT_CXX14(testConstexprSpan(cuda::std::span(iArr1, 2))); + STATIC_ASSERT_CXX14(testConstexprSpan(cuda::std::span(iArr1, 3))); + STATIC_ASSERT_CXX14(testConstexprSpan(cuda::std::span(iArr1, 4))); + + STATIC_ASSERT_CXX14(testConstexprSpan(cuda::std::span(iArr1, 1))); + STATIC_ASSERT_CXX14(testConstexprSpan(cuda::std::span(iArr1, 2))); + STATIC_ASSERT_CXX14(testConstexprSpan(cuda::std::span(iArr1, 3))); + STATIC_ASSERT_CXX14(testConstexprSpan(cuda::std::span(iArr1, 4))); + + testRuntimeSpan(cuda::std::span(iArr2, 1)); + testRuntimeSpan(cuda::std::span(iArr2, 2)); + testRuntimeSpan(cuda::std::span(iArr2, 3)); + testRuntimeSpan(cuda::std::span(iArr2, 4)); + + + testRuntimeSpan(cuda::std::span(iArr2, 1)); + testRuntimeSpan(cuda::std::span(iArr2, 2)); + testRuntimeSpan(cuda::std::span(iArr2, 3)); + testRuntimeSpan(cuda::std::span(iArr2, 4)); + + cuda::std::span sp; + testEmptySpan(sp); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.elem/data.pass.cpp b/.upstream-tests/test/std/views/views.span/span.elem/data.pass.cpp new file mode 100644 index 0000000000..c31e63519f --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.elem/data.pass.cpp @@ -0,0 +1,112 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// constexpr pointer data() const noexcept; +// + + +#include +#include + +#include "test_macros.h" + +template +__host__ __device__ +constexpr bool testConstexprSpan(Span sp, typename Span::pointer ptr) +{ + ASSERT_NOEXCEPT(sp.data()); + return sp.data() == ptr; +} + + +template +__host__ __device__ +void testRuntimeSpan(Span sp, typename Span::pointer ptr) +{ + ASSERT_NOEXCEPT(sp.data()); + assert(sp.data() == ptr); +} + +struct A{}; +__device__ constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +__device__ int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; + +int main(int, char**) +{ + +// dynamic size + static_assert(testConstexprSpan(cuda::std::span(), nullptr), ""); + static_assert(testConstexprSpan(cuda::std::span(), nullptr), ""); + static_assert(testConstexprSpan(cuda::std::span(), nullptr), ""); + static_assert(testConstexprSpan(cuda::std::span(), nullptr), ""); + + static_assert(testConstexprSpan(cuda::std::span(iArr1, 1), iArr1), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 2), iArr1), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 3), iArr1), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 4), iArr1), ""); + + static_assert(testConstexprSpan(cuda::std::span(iArr1 + 1, 1), iArr1 + 1), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1 + 2, 2), iArr1 + 2), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1 + 3, 3), iArr1 + 3), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1 + 4, 4), iArr1 + 4), ""); + +// static size + static_assert(testConstexprSpan(cuda::std::span(), nullptr), ""); + static_assert(testConstexprSpan(cuda::std::span(), nullptr), ""); + static_assert(testConstexprSpan(cuda::std::span(), nullptr), ""); + static_assert(testConstexprSpan(cuda::std::span(), nullptr), ""); + + static_assert(testConstexprSpan(cuda::std::span(iArr1, 1), iArr1), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 2), iArr1), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 3), iArr1), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 4), iArr1), ""); + + static_assert(testConstexprSpan(cuda::std::span(iArr1 + 1, 1), iArr1 + 1), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1 + 2, 2), iArr1 + 2), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1 + 3, 3), iArr1 + 3), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1 + 4, 4), iArr1 + 4), ""); + + +// dynamic size + testRuntimeSpan(cuda::std::span(), nullptr); + testRuntimeSpan(cuda::std::span(), nullptr); + testRuntimeSpan(cuda::std::span(), nullptr); + testRuntimeSpan(cuda::std::span(), nullptr); + + testRuntimeSpan(cuda::std::span(iArr2, 1), iArr2); + testRuntimeSpan(cuda::std::span(iArr2, 2), iArr2); + testRuntimeSpan(cuda::std::span(iArr2, 3), iArr2); + testRuntimeSpan(cuda::std::span(iArr2, 4), iArr2); + + testRuntimeSpan(cuda::std::span(iArr2 + 1, 1), iArr2 + 1); + testRuntimeSpan(cuda::std::span(iArr2 + 2, 2), iArr2 + 2); + testRuntimeSpan(cuda::std::span(iArr2 + 3, 3), iArr2 + 3); + testRuntimeSpan(cuda::std::span(iArr2 + 4, 4), iArr2 + 4); + +// static size + testRuntimeSpan(cuda::std::span(), nullptr); + testRuntimeSpan(cuda::std::span(), nullptr); + testRuntimeSpan(cuda::std::span(), nullptr); + testRuntimeSpan(cuda::std::span(), nullptr); + + testRuntimeSpan(cuda::std::span(iArr2, 1), iArr2); + testRuntimeSpan(cuda::std::span(iArr2, 2), iArr2); + testRuntimeSpan(cuda::std::span(iArr2, 3), iArr2); + testRuntimeSpan(cuda::std::span(iArr2, 4), iArr2); + + testRuntimeSpan(cuda::std::span(iArr2 + 1, 1), iArr2 + 1); + testRuntimeSpan(cuda::std::span(iArr2 + 2, 2), iArr2 + 2); + testRuntimeSpan(cuda::std::span(iArr2 + 3, 3), iArr2 + 3); + testRuntimeSpan(cuda::std::span(iArr2 + 4, 4), iArr2 + 4); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.elem/front.pass.cpp b/.upstream-tests/test/std/views/views.span/span.elem/front.pass.cpp new file mode 100644 index 0000000000..82db22d17e --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.elem/front.pass.cpp @@ -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) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11 + +// + +// constexpr reference front() const noexcept; +// Expects: empty() is false. +// Effects: Equivalent to: return *data(); +// + + +#include +#include + +#include "test_macros.h" + +template +__host__ __device__ +constexpr bool unused(T &&) {return true;} + +template +__host__ __device__ +constexpr bool testConstexprSpan(Span sp) +{ + ASSERT_NOEXCEPT(sp.front()); + return &sp.front() == sp.data(); +} + + +template +__host__ __device__ +void testRuntimeSpan(Span sp) +{ + ASSERT_NOEXCEPT(sp.front()); + assert(&sp.front() == sp.data()); +} + +template +__host__ __device__ +void testEmptySpan(Span sp) +{ + if (!sp.empty()) + unused(sp.front()); +} + +struct A{}; +__device__ constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +__device__ int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; + +int main(int, char**) +{ + static_assert(testConstexprSpan(cuda::std::span(iArr1, 1)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 2)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 3)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 4)), ""); + + static_assert(testConstexprSpan(cuda::std::span(iArr1, 1)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 2)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 3)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 4)), ""); + + testRuntimeSpan(cuda::std::span(iArr2, 1)); + testRuntimeSpan(cuda::std::span(iArr2, 2)); + testRuntimeSpan(cuda::std::span(iArr2, 3)); + testRuntimeSpan(cuda::std::span(iArr2, 4)); + + + testRuntimeSpan(cuda::std::span(iArr2, 1)); + testRuntimeSpan(cuda::std::span(iArr2, 2)); + testRuntimeSpan(cuda::std::span(iArr2, 3)); + testRuntimeSpan(cuda::std::span(iArr2, 4)); + + cuda::std::span sp; + testEmptySpan(sp); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.elem/op_idx.pass.cpp b/.upstream-tests/test/std/views/views.span/span.elem/op_idx.pass.cpp new file mode 100644 index 0000000000..13aff0a8b9 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.elem/op_idx.pass.cpp @@ -0,0 +1,110 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// constexpr reference operator[](size_type idx) const; +// + + +#include +#include + +#include "test_macros.h" + +template +__host__ __device__ +constexpr bool testConstexprSpan(Span sp, size_t idx) +{ + ASSERT_NOEXCEPT(sp[idx]); + + typename Span::reference r1 = sp[idx]; + typename Span::reference r2 = *(sp.data() + idx); + return r1 == r2; +} + + +template +__host__ __device__ +void testRuntimeSpan(Span sp, size_t idx) +{ + ASSERT_NOEXCEPT(sp[idx]); + + typename Span::reference r1 = sp[idx]; + typename Span::reference r2 = *(sp.data() + idx); + assert(r1 == r2); +} + +struct A{}; +__device__ constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +__device__ int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; + +int main(int, char**) +{ + static_assert(testConstexprSpan(cuda::std::span(iArr1, 1), 0), ""); + + static_assert(testConstexprSpan(cuda::std::span(iArr1, 2), 0), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 2), 1), ""); + + static_assert(testConstexprSpan(cuda::std::span(iArr1, 3), 0), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 3), 1), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 3), 2), ""); + + static_assert(testConstexprSpan(cuda::std::span(iArr1, 4), 0), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 4), 1), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 4), 2), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 4), 3), ""); + + + static_assert(testConstexprSpan(cuda::std::span(iArr1, 1), 0), ""); + + static_assert(testConstexprSpan(cuda::std::span(iArr1, 2), 0), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 2), 1), ""); + + static_assert(testConstexprSpan(cuda::std::span(iArr1, 3), 0), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 3), 1), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 3), 2), ""); + + static_assert(testConstexprSpan(cuda::std::span(iArr1, 4), 0), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 4), 1), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 4), 2), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 4), 3), ""); + + testRuntimeSpan(cuda::std::span(iArr2, 1), 0); + + testRuntimeSpan(cuda::std::span(iArr2, 2), 0); + testRuntimeSpan(cuda::std::span(iArr2, 2), 1); + + testRuntimeSpan(cuda::std::span(iArr2, 3), 0); + testRuntimeSpan(cuda::std::span(iArr2, 3), 1); + testRuntimeSpan(cuda::std::span(iArr2, 3), 2); + + testRuntimeSpan(cuda::std::span(iArr2, 4), 0); + testRuntimeSpan(cuda::std::span(iArr2, 4), 1); + testRuntimeSpan(cuda::std::span(iArr2, 4), 2); + testRuntimeSpan(cuda::std::span(iArr2, 4), 3); + + + testRuntimeSpan(cuda::std::span(iArr2, 1), 0); + + testRuntimeSpan(cuda::std::span(iArr2, 2), 0); + testRuntimeSpan(cuda::std::span(iArr2, 2), 1); + + testRuntimeSpan(cuda::std::span(iArr2, 3), 0); + testRuntimeSpan(cuda::std::span(iArr2, 3), 1); + testRuntimeSpan(cuda::std::span(iArr2, 3), 2); + + testRuntimeSpan(cuda::std::span(iArr2, 4), 0); + testRuntimeSpan(cuda::std::span(iArr2, 4), 1); + testRuntimeSpan(cuda::std::span(iArr2, 4), 2); + testRuntimeSpan(cuda::std::span(iArr2, 4), 3); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.iterators/begin.pass.cpp b/.upstream-tests/test/std/views/views.span/span.iterators/begin.pass.cpp new file mode 100644 index 0000000000..785616ccdf --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.iterators/begin.pass.cpp @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// constexpr iterator begin() const noexcept; + +#include +#include + +#include "test_macros.h" + +template +__host__ __device__ +constexpr bool testConstexprSpan(Span s) +{ + bool ret = true; + typename Span::iterator b = s.begin(); + + if (s.empty()) + { + ret = ret && (b == s.end()); + } + else + { + ret = ret && ( *b == s[0]); + ret = ret && (&*b == &s[0]); + } + return ret; +} + + +template +__host__ __device__ +void testRuntimeSpan(Span s) +{ + typename Span::iterator b = s.begin(); + + if (s.empty()) + { + assert(b == s.end()); + } + else + { + assert( *b == s[0]); + assert(&*b == &s[0]); + } +} + +struct A{}; +__host__ __device__ bool operator==(A, A) {return true;} + +__device__ constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +__device__ int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; + +int main(int, char**) +{ + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + + static_assert(testConstexprSpan(cuda::std::span(iArr1, 1)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 2)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 3)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 4)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 5)), ""); + + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + + testRuntimeSpan(cuda::std::span(iArr2, 1)); + testRuntimeSpan(cuda::std::span(iArr2, 2)); + testRuntimeSpan(cuda::std::span(iArr2, 3)); + testRuntimeSpan(cuda::std::span(iArr2, 4)); + testRuntimeSpan(cuda::std::span(iArr2, 5)); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.iterators/end.pass.cpp b/.upstream-tests/test/std/views/views.span/span.iterators/end.pass.cpp new file mode 100644 index 0000000000..b10c7e7e22 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.iterators/end.pass.cpp @@ -0,0 +1,102 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// constexpr iterator end() const noexcept; + +#include +#include + +#include "test_macros.h" + +template +__host__ __device__ +constexpr bool testConstexprSpan(Span s) +{ + bool ret = true; + typename Span::iterator e = s.end(); + if (s.empty()) + { + ret = ret && (e == s.begin()); + } + else + { + typename Span::const_pointer last = &*(s.begin() + s.size() - 1); + ret = ret && (e != s.begin()); + ret = ret && (&*( e-1) == last); + } + + ret = ret && (static_cast(e - s.begin()) == s.size()); + return ret; +} + +template +__host__ __device__ +void testRuntimeSpan(Span s) +{ + typename Span::iterator e = s.end(); + if (s.empty()) + { + assert(e == s.begin()); + } + else + { + typename Span::const_pointer last = &*(s.begin() + s.size() - 1); + assert(e != s.begin()); + assert(&*( e-1) == last); + } + + assert(static_cast(e - s.begin()) == s.size()); +} + + +struct A{}; +__host__ __device__ bool operator==(A, A) {return true;} + +__device__ constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +__device__ int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; + +int main(int, char**) +{ + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + + static_assert(testConstexprSpan(cuda::std::span(iArr1, 1)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 2)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 3)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 4)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 5)), ""); + + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + + testRuntimeSpan(cuda::std::span(iArr2, 1)); + testRuntimeSpan(cuda::std::span(iArr2, 2)); + testRuntimeSpan(cuda::std::span(iArr2, 3)); + testRuntimeSpan(cuda::std::span(iArr2, 4)); + testRuntimeSpan(cuda::std::span(iArr2, 5)); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.iterators/rbegin.pass.cpp b/.upstream-tests/test/std/views/views.span/span.iterators/rbegin.pass.cpp new file mode 100644 index 0000000000..b8a934dd2d --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.iterators/rbegin.pass.cpp @@ -0,0 +1,103 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// constexpr reverse_iterator rbegin() const noexcept; + +#include +#include + +#include "test_macros.h" + +template +__host__ __device__ +TEST_CONSTEXPR_CXX17 bool testConstexprSpan(Span s) +{ + bool ret = true; + typename Span::reverse_iterator b = s.rbegin(); + if (s.empty()) + { + ret = ret && ( b == s.rend()); + } + else + { + const typename Span::size_type last = s.size() - 1; + ret = ret && ( *b == s[last]); + ret = ret && (&*b == &s[last]); + } + return ret; +} + + +template +__host__ __device__ +void testRuntimeSpan(Span s) +{ + typename Span::reverse_iterator b = s.rbegin(); + if (s.empty()) + { + assert(b == s.rend()); + } + else + { + const typename Span::size_type last = s.size() - 1; + assert( *b == s[last]); + assert(&*b == &s[last]); + } +} + + +struct A{}; +__host__ __device__ bool operator==(A, A) {return true;} + +#if TEST_STD_VER > 14 +__device__ constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +#endif +__device__ int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; + +int main(int, char**) +{ +#if TEST_STD_VER > 14 + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + + static_assert(testConstexprSpan(cuda::std::span(iArr1, 1)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 2)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 3)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 4)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 5)), ""); +#endif // TEST_STD_VER > 14 + + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + + testRuntimeSpan(cuda::std::span(iArr2, 1)); + testRuntimeSpan(cuda::std::span(iArr2, 2)); + testRuntimeSpan(cuda::std::span(iArr2, 3)); + testRuntimeSpan(cuda::std::span(iArr2, 4)); + testRuntimeSpan(cuda::std::span(iArr2, 5)); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.iterators/rend.pass.cpp b/.upstream-tests/test/std/views/views.span/span.iterators/rend.pass.cpp new file mode 100644 index 0000000000..a749bc29f3 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.iterators/rend.pass.cpp @@ -0,0 +1,102 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// constexpr reverse_iterator rend() const noexcept; + +#include +#include + +#include "test_macros.h" + +template +__host__ __device__ +constexpr bool testConstexprSpan(Span s) +{ + bool ret = true; + typename Span::reverse_iterator e = s.rend(); + if (s.empty()) + { + ret = ret && (e == s.rbegin()); + } + else + { + ret = ret && (e != s.rbegin()); + } + + ret = ret && (static_cast(e - s.rbegin()) == s.size()); + return ret; +} + +template +__host__ __device__ +void testRuntimeSpan(Span s) +{ + typename Span::reverse_iterator e = s.rend(); + if (s.empty()) + { + assert(e == s.rbegin()); + } + else + { + assert(e != s.rbegin()); + } + + assert(static_cast(e - s.rbegin()) == s.size()); +} + + +struct A{}; +__host__ __device__ bool operator==(A, A) {return true;} + +#if TEST_STD_VER > 14 +__device__ constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +#endif +__device__ int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; + +int main(int, char**) +{ +#if TEST_STD_VER > 14 + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + static_assert(testConstexprSpan(cuda::std::span()), ""); + + static_assert(testConstexprSpan(cuda::std::span(iArr1, 1)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 2)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 3)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 4)), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 5)), ""); +#endif // TEST_STD_VER > 14 + + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + + testRuntimeSpan(cuda::std::span(iArr2, 1)); + testRuntimeSpan(cuda::std::span(iArr2, 2)); + testRuntimeSpan(cuda::std::span(iArr2, 3)); + testRuntimeSpan(cuda::std::span(iArr2, 4)); + testRuntimeSpan(cuda::std::span(iArr2, 5)); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.objectrep/as_bytes.pass.cpp b/.upstream-tests/test/std/views/views.span/span.objectrep/as_bytes.pass.cpp new file mode 100644 index 0000000000..5b7d1a9ac1 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.objectrep/as_bytes.pass.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// span +// as_bytes(span s) noexcept; + + +#include +#include + +#include "test_macros.h" + +template +__host__ __device__ +void testRuntimeSpan(Span sp) +{ + ASSERT_NOEXCEPT(cuda::std::as_bytes(sp)); + + auto spBytes = cuda::std::as_bytes(sp); + using SB = decltype(spBytes); + ASSERT_SAME_TYPE(const cuda::std::byte, typename SB::element_type); + + if (sp.extent == cuda::std::dynamic_extent) + assert(spBytes.extent == cuda::std::dynamic_extent); + else + assert(spBytes.extent == sizeof(typename Span::element_type) * sp.extent); + + assert((void *) spBytes.data() == (void *) sp.data()); + assert(spBytes.size() == sp.size_bytes()); +} + +struct A{}; +__device__ int iArr2[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + +int main(int, char**) +{ + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + + testRuntimeSpan(cuda::std::span(iArr2, 1)); + testRuntimeSpan(cuda::std::span(iArr2, 2)); + testRuntimeSpan(cuda::std::span(iArr2, 3)); + testRuntimeSpan(cuda::std::span(iArr2, 4)); + testRuntimeSpan(cuda::std::span(iArr2, 5)); + + testRuntimeSpan(cuda::std::span(iArr2 + 5, 1)); + testRuntimeSpan(cuda::std::span(iArr2 + 4, 2)); + testRuntimeSpan(cuda::std::span(iArr2 + 3, 3)); + testRuntimeSpan(cuda::std::span(iArr2 + 2, 4)); + testRuntimeSpan(cuda::std::span(iArr2 + 1, 5)); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.objectrep/as_writable_bytes.pass.cpp b/.upstream-tests/test/std/views/views.span/span.objectrep/as_writable_bytes.pass.cpp new file mode 100644 index 0000000000..9e61ffe3f7 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.objectrep/as_writable_bytes.pass.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// span +// as_writable_bytes(span s) noexcept; + + +#include +#include + +#include "test_macros.h" + +template +__host__ __device__ +void testRuntimeSpan(Span sp) +{ + ASSERT_NOEXCEPT(cuda::std::as_writable_bytes(sp)); + + auto spBytes = cuda::std::as_writable_bytes(sp); + using SB = decltype(spBytes); + ASSERT_SAME_TYPE(cuda::std::byte, typename SB::element_type); + + if (sp.extent == cuda::std::dynamic_extent) + assert(spBytes.extent == cuda::std::dynamic_extent); + else + assert(spBytes.extent == sizeof(typename Span::element_type) * sp.extent); + + assert(static_cast(spBytes.data()) == static_cast(sp.data())); + assert(spBytes.size() == sp.size_bytes()); +} + +struct A{}; +__device__ int iArr2[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + +int main(int, char**) +{ + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + testRuntimeSpan(cuda::std::span ()); + + testRuntimeSpan(cuda::std::span(iArr2, 1)); + testRuntimeSpan(cuda::std::span(iArr2, 2)); + testRuntimeSpan(cuda::std::span(iArr2, 3)); + testRuntimeSpan(cuda::std::span(iArr2, 4)); + testRuntimeSpan(cuda::std::span(iArr2, 5)); + + testRuntimeSpan(cuda::std::span(iArr2 + 5, 1)); + testRuntimeSpan(cuda::std::span(iArr2 + 4, 2)); + testRuntimeSpan(cuda::std::span(iArr2 + 3, 3)); + testRuntimeSpan(cuda::std::span(iArr2 + 2, 4)); + testRuntimeSpan(cuda::std::span(iArr2 + 1, 5)); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.objectrep/as_writable_bytes.verify.cpp b/.upstream-tests/test/std/views/views.span/span.objectrep/as_writable_bytes.verify.cpp new file mode 100644 index 0000000000..bc205208b9 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.objectrep/as_writable_bytes.verify.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: nvrtc + +// + +// template +// span +// as_writable_bytes(span s) noexcept; + +#include + +#include "test_macros.h" + +__device__ constexpr int iArr2[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + +struct A {}; + +__host__ __device__ void f() { + cuda::std::as_writable_bytes(cuda::std::span()); // expected-error {{no matching function for call to 'as_writable_bytes'}} + cuda::std::as_writable_bytes(cuda::std::span()); // expected-error {{no matching function for call to 'as_writable_bytes'}} + cuda::std::as_writable_bytes(cuda::std::span()); // expected-error {{no matching function for call to 'as_writable_bytes'}} + cuda::std::as_writable_bytes(cuda::std::span()); // expected-error {{no matching function for call to 'as_writable_bytes'}} + + cuda::std::as_writable_bytes(cuda::std::span()); // expected-error {{no matching function for call to 'as_writable_bytes'}} + cuda::std::as_writable_bytes(cuda::std::span()); // expected-error {{no matching function for call to 'as_writable_bytes'}} + cuda::std::as_writable_bytes(cuda::std::span()); // expected-error {{no matching function for call to 'as_writable_bytes'}} + cuda::std::as_writable_bytes(cuda::std::span()); // expected-error {{no matching function for call to 'as_writable_bytes'}} + + cuda::std::as_writable_bytes(cuda::std::span (iArr2, 1)); // expected-error {{no matching function for call to 'as_writable_bytes'}} + cuda::std::as_writable_bytes(cuda::std::span(iArr2 + 5, 1)); // expected-error {{no matching function for call to 'as_writable_bytes'}} +} + +int main(int, char**) +{ + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.obs/empty.nodiscard.verify.cpp b/.upstream-tests/test/std/views/views.span/span.obs/empty.nodiscard.verify.cpp new file mode 100644 index 0000000000..1f5b68c14e --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.obs/empty.nodiscard.verify.cpp @@ -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) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: nvrtc + +// + +// [[nodiscard]] constexpr bool empty() const noexcept; + +#include + +void test() { + cuda::std::span s1; + s1.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + int arr[] = {1, 2, 3}; + cuda::std::span s2{arr}; + s2.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +} + +int main(int, char**) +{ + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.obs/empty.pass.cpp b/.upstream-tests/test/std/views/views.span/span.obs/empty.pass.cpp new file mode 100644 index 0000000000..b1a6ee2764 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.obs/empty.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// [[nodiscard]] constexpr bool empty() const noexcept; +// + + +#include +#include + +#include "test_macros.h" + +struct A{}; +__device__ constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +__device__ int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; + +int main(int, char**) +{ + static_assert( noexcept(cuda::std::span ().empty()), ""); + static_assert( noexcept(cuda::std::span().empty()), ""); + + + static_assert( cuda::std::span().empty(), ""); + static_assert( cuda::std::span().empty(), ""); + static_assert( cuda::std::span().empty(), ""); + static_assert( cuda::std::span().empty(), ""); + + static_assert( cuda::std::span().empty(), ""); + static_assert( cuda::std::span().empty(), ""); + static_assert( cuda::std::span().empty(), ""); + static_assert( cuda::std::span().empty(), ""); + + static_assert(!cuda::std::span(iArr1, 1).empty(), ""); + static_assert(!cuda::std::span(iArr1, 2).empty(), ""); + static_assert(!cuda::std::span(iArr1, 3).empty(), ""); + static_assert(!cuda::std::span(iArr1, 4).empty(), ""); + static_assert(!cuda::std::span(iArr1, 5).empty(), ""); + + assert( (cuda::std::span().empty() )); + assert( (cuda::std::span().empty() )); + assert( (cuda::std::span().empty() )); + assert( (cuda::std::span().empty() )); + + assert( (cuda::std::span().empty() )); + assert( (cuda::std::span().empty() )); + assert( (cuda::std::span().empty() )); + assert( (cuda::std::span().empty() )); + + assert(!(cuda::std::span(iArr2, 1).empty())); + assert(!(cuda::std::span(iArr2, 2).empty())); + assert(!(cuda::std::span(iArr2, 3).empty())); + assert(!(cuda::std::span(iArr2, 4).empty())); + assert(!(cuda::std::span(iArr2, 5).empty())); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.obs/size.pass.cpp b/.upstream-tests/test/std/views/views.span/span.obs/size.pass.cpp new file mode 100644 index 0000000000..1cb6e78db7 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.obs/size.pass.cpp @@ -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) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11 + +// + +// constexpr size_type size() const noexcept; +// + + +#include +#include + +#include "test_macros.h" + +template +__host__ __device__ +constexpr bool testConstexprSpan(Span sp, size_t sz) +{ + ASSERT_NOEXCEPT(sp.size()); + return sp.size() == sz; +} + + +template +__host__ __device__ +void testRuntimeSpan(Span sp, size_t sz) +{ + ASSERT_NOEXCEPT(sp.size()); + assert(sp.size() == sz); +} + +struct A{}; +__device__ constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +__device__ int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; + +int main(int, char**) +{ + static_assert(testConstexprSpan(cuda::std::span(), 0), ""); + static_assert(testConstexprSpan(cuda::std::span(), 0), ""); + static_assert(testConstexprSpan(cuda::std::span(), 0), ""); + static_assert(testConstexprSpan(cuda::std::span(), 0), ""); + + static_assert(testConstexprSpan(cuda::std::span(), 0), ""); + static_assert(testConstexprSpan(cuda::std::span(), 0), ""); + static_assert(testConstexprSpan(cuda::std::span(), 0), ""); + static_assert(testConstexprSpan(cuda::std::span(), 0), ""); + + static_assert(testConstexprSpan(cuda::std::span(iArr1, 1), 1), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 2), 2), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 3), 3), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 4), 4), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 5), 5), ""); + + testRuntimeSpan(cuda::std::span (), 0); + testRuntimeSpan(cuda::std::span (), 0); + testRuntimeSpan(cuda::std::span (), 0); + testRuntimeSpan(cuda::std::span (), 0); + + testRuntimeSpan(cuda::std::span (), 0); + testRuntimeSpan(cuda::std::span (), 0); + testRuntimeSpan(cuda::std::span (), 0); + testRuntimeSpan(cuda::std::span (), 0); + + testRuntimeSpan(cuda::std::span(iArr2, 1), 1); + testRuntimeSpan(cuda::std::span(iArr2, 2), 2); + testRuntimeSpan(cuda::std::span(iArr2, 3), 3); + testRuntimeSpan(cuda::std::span(iArr2, 4), 4); + testRuntimeSpan(cuda::std::span(iArr2, 5), 5); + + testRuntimeSpan(cuda::std::span(iArr2 + 5, 1), 1); + testRuntimeSpan(cuda::std::span(iArr2 + 4, 2), 2); + testRuntimeSpan(cuda::std::span(iArr2 + 3, 3), 3); + testRuntimeSpan(cuda::std::span(iArr2 + 2, 4), 4); + testRuntimeSpan(cuda::std::span(iArr2 + 1, 5), 5); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.obs/size_bytes.pass.cpp b/.upstream-tests/test/std/views/views.span/span.obs/size_bytes.pass.cpp new file mode 100644 index 0000000000..d736a1ecc8 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.obs/size_bytes.pass.cpp @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// constexpr size_type size_bytes() const noexcept; +// +// Effects: Equivalent to: return size() * sizeof(element_type); + + +#include +#include + +#include "test_macros.h" + +template +__host__ __device__ +constexpr bool testConstexprSpan(Span sp, size_t sz) +{ + ASSERT_NOEXCEPT(sp.size_bytes()); + return (size_t) sp.size_bytes() == sz * sizeof(typename Span::element_type); +} + + +template +__host__ __device__ +void testRuntimeSpan(Span sp, size_t sz) +{ + ASSERT_NOEXCEPT(sp.size_bytes()); + assert((size_t) sp.size_bytes() == sz * sizeof(typename Span::element_type)); +} + +struct A{}; +__device__ constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +__device__ int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; + +int main(int, char**) +{ + static_assert(testConstexprSpan(cuda::std::span(), 0), ""); + static_assert(testConstexprSpan(cuda::std::span(), 0), ""); + static_assert(testConstexprSpan(cuda::std::span(), 0), ""); + static_assert(testConstexprSpan(cuda::std::span(), 0), ""); + + static_assert(testConstexprSpan(cuda::std::span(), 0), ""); + static_assert(testConstexprSpan(cuda::std::span(), 0), ""); + static_assert(testConstexprSpan(cuda::std::span(), 0), ""); + static_assert(testConstexprSpan(cuda::std::span(), 0), ""); + + static_assert(testConstexprSpan(cuda::std::span(iArr1, 1), 1), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 2), 2), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 3), 3), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 4), 4), ""); + static_assert(testConstexprSpan(cuda::std::span(iArr1, 5), 5), ""); + + testRuntimeSpan(cuda::std::span (), 0); + testRuntimeSpan(cuda::std::span (), 0); + testRuntimeSpan(cuda::std::span (), 0); + testRuntimeSpan(cuda::std::span (), 0); + + testRuntimeSpan(cuda::std::span (), 0); + testRuntimeSpan(cuda::std::span (), 0); + testRuntimeSpan(cuda::std::span (), 0); + testRuntimeSpan(cuda::std::span (), 0); + + testRuntimeSpan(cuda::std::span(iArr2, 1), 1); + testRuntimeSpan(cuda::std::span(iArr2, 2), 2); + testRuntimeSpan(cuda::std::span(iArr2, 3), 3); + testRuntimeSpan(cuda::std::span(iArr2, 4), 4); + testRuntimeSpan(cuda::std::span(iArr2, 5), 5); + + testRuntimeSpan(cuda::std::span(iArr2 + 5, 1), 1); + testRuntimeSpan(cuda::std::span(iArr2 + 4, 2), 2); + testRuntimeSpan(cuda::std::span(iArr2 + 3, 3), 3); + testRuntimeSpan(cuda::std::span(iArr2 + 2, 4), 4); + testRuntimeSpan(cuda::std::span(iArr2 + 1, 5), 5); + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.sub/first.pass.cpp b/.upstream-tests/test/std/views/views.span/span.sub/first.pass.cpp new file mode 100644 index 0000000000..fcd4019958 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.sub/first.pass.cpp @@ -0,0 +1,110 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// constexpr span first() const; +// +// constexpr span first(size_type count) const; +// +// Requires: Count <= size(). + + +#include +#include + +#include "test_macros.h" + +template +__host__ __device__ +constexpr bool testConstexprSpan(Span sp) +{ + ASSERT_NOEXCEPT(sp.template first()); + ASSERT_NOEXCEPT(sp.first(Count)); + auto s1 = sp.template first(); + auto s2 = sp.first(Count); + using S1 = decltype(s1); + using S2 = decltype(s2); + ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type); + ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type); + static_assert(S1::extent == Count, ""); + static_assert(S2::extent == cuda::std::dynamic_extent, ""); + return + s1.data() == s2.data() + && s1.size() == s2.size(); +} + + +template +__host__ __device__ +void testRuntimeSpan(Span sp) +{ + ASSERT_NOEXCEPT(sp.template first()); + ASSERT_NOEXCEPT(sp.first(Count)); + auto s1 = sp.template first(); + auto s2 = sp.first(Count); + using S1 = decltype(s1); + using S2 = decltype(s2); + ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type); + ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type); + static_assert(S1::extent == Count, ""); + static_assert(S2::extent == cuda::std::dynamic_extent, ""); + assert(s1.data() == s2.data()); + assert(s1.size() == s2.size()); +} + +__device__ constexpr int carr1[] = {1,2,3,4}; +__device__ int arr[] = {5,6,7}; + +int main(int, char**) +{ + { + using Sp = cuda::std::span; + static_assert(testConstexprSpan(Sp{}), ""); + + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + } + + { + using Sp = cuda::std::span; + + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + } + + { + using Sp = cuda::std::span; + testRuntimeSpan(Sp{}); + + testRuntimeSpan(Sp{arr}); + testRuntimeSpan(Sp{arr}); + testRuntimeSpan(Sp{arr}); + testRuntimeSpan(Sp{arr}); + } + + { + using Sp = cuda::std::span; + + testRuntimeSpan(Sp{arr}); + testRuntimeSpan(Sp{arr}); + testRuntimeSpan(Sp{arr}); + testRuntimeSpan(Sp{arr}); + } + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.sub/first.verify.cpp b/.upstream-tests/test/std/views/views.span/span.sub/first.verify.cpp new file mode 100644 index 0000000000..a500d74062 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.sub/first.verify.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: nvrtc + +// + +// template +// constexpr span first() const; +// +// Requires: Count <= size(). + +#include +#include + +void f() { + int array[] = {1, 2, 3, 4}; + cuda::std::span sp(array); + + // Count too large + [[maybe_unused]] auto s1 = sp.first<5>(); // expected-error@span:* {{span::first(): Count out of range}} + + // Count numeric_limits + [[maybe_unused]] auto s2 = sp.first(); // expected-error@span:* {{span::first(): Count out of range}} +} + +int main(int, char**) +{ + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.sub/last.pass.cpp b/.upstream-tests/test/std/views/views.span/span.sub/last.pass.cpp new file mode 100644 index 0000000000..c10afc0b91 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.sub/last.pass.cpp @@ -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 + +// + +// template +// constexpr span last() const; +// +// constexpr span last(size_type count) const; +// +// Requires: Count <= size(). + + +#include +#include + +#include "test_macros.h" + +template +__host__ __device__ +constexpr bool testConstexprSpan(Span sp) +{ + assert((noexcept(sp.template last()))); + assert((noexcept(sp.last(Count)))); + auto s1 = sp.template last(); + auto s2 = sp.last(Count); + using S1 = decltype(s1); + using S2 = decltype(s2); + ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type); + ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type); + static_assert(S1::extent == Count, ""); + static_assert(S2::extent == cuda::std::dynamic_extent, ""); + return + s1.data() == s2.data() + && s1.size() == s2.size(); +} + +template +__host__ __device__ +void testRuntimeSpan(Span sp) +{ + assert((noexcept(sp.template last()))); + assert((noexcept(sp.last(Count)))); + auto s1 = sp.template last(); + auto s2 = sp.last(Count); + using S1 = decltype(s1); + using S2 = decltype(s2); + ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type); + ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type); + static_assert(S1::extent == Count, ""); + static_assert(S2::extent == cuda::std::dynamic_extent, ""); + assert(s1.data() == s2.data()); + assert(s1.size() == s2.size()); +} + +__device__ constexpr int carr1[] = {1,2,3,4}; +__device__ int arr[] = {5,6,7}; + +int main(int, char**) +{ + { + using Sp = cuda::std::span; + static_assert(testConstexprSpan(Sp{}), ""); + + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + } + + { + using Sp = cuda::std::span; + + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + } + + { + using Sp = cuda::std::span; + testRuntimeSpan(Sp{}); + + testRuntimeSpan(Sp{arr}); + testRuntimeSpan(Sp{arr}); + testRuntimeSpan(Sp{arr}); + testRuntimeSpan(Sp{arr}); + } + + { + using Sp = cuda::std::span; + + testRuntimeSpan(Sp{arr}); + testRuntimeSpan(Sp{arr}); + testRuntimeSpan(Sp{arr}); + testRuntimeSpan(Sp{arr}); + } + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.sub/last.verify.cpp b/.upstream-tests/test/std/views/views.span/span.sub/last.verify.cpp new file mode 100644 index 0000000000..5deb1e7fc9 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.sub/last.verify.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: nvrtc + +// + +// template +// constexpr span last() const; +// +// Requires: Count <= size(). + +#include +#include + +void f() { + int array[] = {1, 2, 3, 4}; + cuda::std::span sp(array); + + // Count too large + [[maybe_unused]] auto s1 = sp.last<5>(); // expected-error@span:* {{span::last(): Count out of range}} + + // Count numeric_limits + [[maybe_unused]] auto s2 = sp.last(); // expected-error@span:* {{span::last(): Count out of range}} +} + +int main(int, char**) +{ + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.sub/subspan.pass.cpp b/.upstream-tests/test/std/views/views.span/span.sub/subspan.pass.cpp new file mode 100644 index 0000000000..09247c83e0 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.sub/subspan.pass.cpp @@ -0,0 +1,208 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// constexpr span subspan() const; +// +// constexpr span subspan( +// size_type offset, size_type count = dynamic_extent) const; +// +// Requires: (0 <= Offset && Offset <= size()) +// && (Count == dynamic_extent || Count >= 0 && Offset + Count <= size()) + +#include +#include + +#include "test_macros.h" + +template +__host__ __device__ +constexpr bool testConstexprSpan(Span sp) +{ + ASSERT_NOEXCEPT(sp.template subspan()); + ASSERT_NOEXCEPT(sp.subspan(Offset, Count)); + auto s1 = sp.template subspan(); + auto s2 = sp.subspan(Offset, Count); + using S1 = decltype(s1); + using S2 = decltype(s2); + ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type); + ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type); + static_assert(S1::extent == Count, ""); + static_assert(S2::extent == cuda::std::dynamic_extent, ""); + return + s1.data() == s2.data() + && s1.size() == s2.size(); +} + +template +__host__ __device__ +constexpr bool testConstexprSpan(Span sp) +{ + ASSERT_NOEXCEPT(sp.template subspan()); + ASSERT_NOEXCEPT(sp.subspan(Offset)); + auto s1 = sp.template subspan(); + auto s2 = sp.subspan(Offset); + using S1 = decltype(s1); + using S2 = decltype(s2); + ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type); + ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type); + static_assert(S1::extent == (Span::extent == cuda::std::dynamic_extent ? cuda::std::dynamic_extent : Span::extent - Offset), ""); + static_assert(S2::extent == cuda::std::dynamic_extent, ""); + return + s1.data() == s2.data() + && s1.size() == s2.size(); +} + + +template +__host__ __device__ +void testRuntimeSpan(Span sp) +{ + ASSERT_NOEXCEPT(sp.template subspan()); + ASSERT_NOEXCEPT(sp.subspan(Offset, Count)); + auto s1 = sp.template subspan(); + auto s2 = sp.subspan(Offset, Count); + using S1 = decltype(s1); + using S2 = decltype(s2); + ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type); + ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type); + static_assert(S1::extent == Count, ""); + static_assert(S2::extent == cuda::std::dynamic_extent, ""); + assert(s1.data() == s2.data()); + assert(s1.size() == s2.size()); +} + + +template +__host__ __device__ +void testRuntimeSpan(Span sp) +{ + ASSERT_NOEXCEPT(sp.template subspan()); + ASSERT_NOEXCEPT(sp.subspan(Offset)); + auto s1 = sp.template subspan(); + auto s2 = sp.subspan(Offset); + using S1 = decltype(s1); + using S2 = decltype(s2); + ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type); + ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type); + static_assert(S1::extent == (Span::extent == cuda::std::dynamic_extent ? cuda::std::dynamic_extent : Span::extent - Offset), ""); + static_assert(S2::extent == cuda::std::dynamic_extent, ""); + assert(s1.data() == s2.data()); + assert(s1.size() == s2.size()); +} + +__device__ constexpr int carr1[] = {1,2,3,4}; +__device__ int arr1[] = {5,6,7}; + +int main(int, char**) +{ + { + using Sp = cuda::std::span; + static_assert(testConstexprSpan(Sp{}), ""); + + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + } + + { + using Sp = cuda::std::span; + + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + } + + { + using Sp = cuda::std::span; + static_assert(testConstexprSpan(Sp{}), ""); + + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + } + + { + using Sp = cuda::std::span; + + static_assert(testConstexprSpan(Sp{carr1}), ""); + + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + static_assert(testConstexprSpan(Sp{carr1}), ""); + } + + { + using Sp = cuda::std::span; + testRuntimeSpan(Sp{}); + + testRuntimeSpan(Sp{arr1}); + testRuntimeSpan(Sp{arr1}); + testRuntimeSpan(Sp{arr1}); + testRuntimeSpan(Sp{arr1}); + + testRuntimeSpan(Sp{arr1}); + testRuntimeSpan(Sp{arr1}); + testRuntimeSpan(Sp{arr1}); + } + + { + using Sp = cuda::std::span; + + testRuntimeSpan(Sp{arr1}); + testRuntimeSpan(Sp{arr1}); + testRuntimeSpan(Sp{arr1}); + testRuntimeSpan(Sp{arr1}); + + testRuntimeSpan(Sp{arr1}); + testRuntimeSpan(Sp{arr1}); + testRuntimeSpan(Sp{arr1}); + } + + { + using Sp = cuda::std::span; + testRuntimeSpan(Sp{}); + + testRuntimeSpan(Sp{arr1}); + testRuntimeSpan(Sp{arr1}); + testRuntimeSpan(Sp{arr1}); + testRuntimeSpan(Sp{arr1}); + } + + { + using Sp = cuda::std::span; + + testRuntimeSpan(Sp{arr1}); + testRuntimeSpan(Sp{arr1}); + testRuntimeSpan(Sp{arr1}); + testRuntimeSpan(Sp{arr1}); + } + + return 0; +} diff --git a/.upstream-tests/test/std/views/views.span/span.sub/subspan.verify.cpp b/.upstream-tests/test/std/views/views.span/span.sub/subspan.verify.cpp new file mode 100644 index 0000000000..9cf47fffe4 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/span.sub/subspan.verify.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: nvrtc + +// This test also generates spurious warnings when instantiating std::span +// with a very large extent (like size_t(-2)) -- silence those. +// ADDITIONAL_COMPILE_FLAGS: -Xclang -verify-ignore-unexpected=warning + +// + +// template +// constexpr span subspan() const; +// +// Requires: offset <= size() && +// (count == dynamic_extent || count <= size() - offset) + +#include +#include + +void f() { + int array[] = {1, 2, 3, 4}; + cuda::std::span sp(array); + + // Offset too large templatized + [[maybe_unused]] auto s1 = sp.subspan<5>(); // expected-error@span:* {{span::subspan(): Offset out of range}} + + // Count too large templatized + [[maybe_unused]] auto s2 = sp.subspan<0, 5>(); // expected-error@span:* {{span::subspan(): Offset + Count out of range}} + + // Offset + Count too large templatized + [[maybe_unused]] auto s3 = sp.subspan<2, 3>(); // expected-error@span:* {{span::subspan(): Offset + Count out of range}} + + // Offset + Count overflow templatized + [[maybe_unused]] auto s4 = sp.subspan<3, cuda::std::size_t(-2)>(); // expected-error@span:* {{span::subspan(): Offset + Count out of range}}, expected-error-re@span:* {{array is too large{{(.* elements)}}}} +} diff --git a/.upstream-tests/test/std/views/views.span/trivially_copyable.compile.pass.cpp b/.upstream-tests/test/std/views/views.span/trivially_copyable.compile.pass.cpp new file mode 100644 index 0000000000..aea36c7730 --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/trivially_copyable.compile.pass.cpp @@ -0,0 +1,24 @@ +// +// 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 + +// P2251 was voted into C++23, but is supported even in C++20 mode by all vendors. + +// + +#include +#include + +static_assert(cuda::std::is_trivially_copyable>::value, ""); +static_assert(cuda::std::is_trivially_copyable>::value, ""); + +int main(int, char**) +{ + return 0; +} \ No newline at end of file diff --git a/.upstream-tests/test/std/views/views.span/types.pass.cpp b/.upstream-tests/test/std/views/views.span/types.pass.cpp new file mode 100644 index 0000000000..691de311dd --- /dev/null +++ b/.upstream-tests/test/std/views/views.span/types.pass.cpp @@ -0,0 +1,95 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// template +// class span { +// public: +// // constants and types +// using element_type = ElementType; +// using value_type = remove_cv_t; +// using size_type = size_t; +// using difference_type = ptrdiff_t; +// using pointer = element_type *; +// using reference = element_type &; +// using const_pointe = const element_type *; +// using const_reference = const element_type &; +// using iterator = implementation-defined; +// using reverse_iterator = std::reverse_iterator; +// +// static constexpr size_type extent = Extent; +// + +#include +#include +#include + +#include "test_macros.h" + +template +__host__ __device__ +void testIterator() +{ + typedef cuda::std::iterator_traits ItT; + + ASSERT_SAME_TYPE(typename ItT::iterator_category, cuda::std::random_access_iterator_tag); + ASSERT_SAME_TYPE(typename ItT::value_type, typename S::value_type); + ASSERT_SAME_TYPE(typename ItT::reference, typename S::reference); + ASSERT_SAME_TYPE(typename ItT::pointer, typename S::pointer); + ASSERT_SAME_TYPE(typename ItT::difference_type, typename S::difference_type); +} + +template +__host__ __device__ +void testSpan() +{ + ASSERT_SAME_TYPE(typename S::element_type, ElementType); + ASSERT_SAME_TYPE(typename S::value_type, typename cuda::std::remove_cv::type); + ASSERT_SAME_TYPE(typename S::size_type, cuda::std::size_t); + ASSERT_SAME_TYPE(typename S::difference_type, cuda::std::ptrdiff_t); + ASSERT_SAME_TYPE(typename S::pointer, ElementType *); + ASSERT_SAME_TYPE(typename S::const_pointer, const ElementType *); + ASSERT_SAME_TYPE(typename S::reference, ElementType &); + ASSERT_SAME_TYPE(typename S::const_reference, const ElementType &); + + static_assert(S::extent == Size, ""); // check that it exists + + testIterator(); + testIterator(); +} + + +template +__host__ __device__ +void test() +{ + testSpan, T, cuda::std::dynamic_extent>(); + testSpan, const T, cuda::std::dynamic_extent>(); + testSpan, volatile T, cuda::std::dynamic_extent>(); + testSpan, const volatile T, cuda::std::dynamic_extent>(); + + testSpan, T, 5>(); + testSpan, const T, 5>(); + testSpan, volatile T, 5>(); + testSpan, const volatile T, 5>(); +} + +struct A{}; + +int main(int, char**) +{ + test(); + test(); + test(); + test(); + + return 0; +} diff --git a/.upstream-tests/test/support/test_macros.h b/.upstream-tests/test/support/test_macros.h index ed7306f2c5..74f3bc54d7 100644 --- a/.upstream-tests/test/support/test_macros.h +++ b/.upstream-tests/test/support/test_macros.h @@ -149,6 +149,11 @@ # else # define TEST_CONSTEXPR_CXX14 # endif +# if TEST_STD_VER >= 17 +# define TEST_CONSTEXPR_CXX17 constexpr +# else +# define TEST_CONSTEXPR_CXX17 +# endif # if TEST_STD_VER > 14 # define TEST_THROW_SPEC(...) # else @@ -268,6 +273,18 @@ static_assert(!noexcept(__VA_ARGS__), "Operation must NOT be noexcept") #endif +#if TEST_STD_VER > 11 +#define STATIC_ASSERT_CXX14(Pred) static_assert(Pred, "") +#else +#define STATIC_ASSERT_CXX14(Pred) assert(Pred) +#endif + +#if TEST_STD_VER > 14 +#define STATIC_ASSERT_CXX17(Pred) static_assert(Pred, "") +#else +#define STATIC_ASSERT_CXX17(Pred) assert(Pred) +#endif + /* Macros for testing libc++ specific behavior and extensions */ #if defined(_LIBCUDACXX_VERSION) #define LIBCPP_ASSERT(...) assert(__VA_ARGS__) diff --git a/include/cuda/std/detail/libcxx/include/iterator b/include/cuda/std/detail/libcxx/include/iterator index 95f9fe4314..e91e76df1d 100644 --- a/include/cuda/std/detail/libcxx/include/iterator +++ b/include/cuda/std/detail/libcxx/include/iterator @@ -1856,7 +1856,7 @@ end(const _Cp& __c) #endif // !defined(_LIBCUDACXX_CXX03_LANG) -#if _LIBCUDACXX_STD_VER > 14 +#if _LIBCUDACXX_STD_VER > 11 // #if _LIBCUDACXX_STD_VER > 11 // template <> @@ -1932,7 +1932,7 @@ constexpr _Tp* data(_Tp (&__array)[_Sz]) noexcept { return __array; } template _LIBCUDACXX_INLINE_VISIBILITY constexpr const _Ep* data(::std::initializer_list<_Ep> __il) noexcept { return __il.begin(); } -#endif +#endif // _LIBCUDACXX_STD_VER > 11 _LIBCUDACXX_END_NAMESPACE_STD diff --git a/include/cuda/std/detail/libcxx/include/span b/include/cuda/std/detail/libcxx/include/span index c1d2f9357f..595e835eaf 100644 --- a/include/cuda/std/detail/libcxx/include/span +++ b/include/cuda/std/detail/libcxx/include/span @@ -4,6 +4,7 @@ // 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. // //===---------------------------------------------------------------------===// @@ -22,6 +23,12 @@ inline constexpr size_t dynamic_extent = numeric_limits::max(); template class span; +template + inline constexpr bool ranges::enable_view> = true; + +template + inline constexpr bool ranges::enable_borrowed_range> = true; + // [span.objectrep], views of object representation template span (sizeof(ElementType) * Extent))> as_writable_bytes(span s) noexcept; -namespace std { template class span { public: // constants and types using element_type = ElementType; using value_type = remove_cv_t; - using index_type = size_t; + using size_type = size_t; using difference_type = ptrdiff_t; using pointer = element_type*; using const_pointer = const element_type*; using reference = element_type&; using const_reference = const element_type&; using iterator = implementation-defined; - using const_iterator = implementation-defined; using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; - static constexpr index_type extent = Extent; + static constexpr size_type extent = Extent; // [span.cons], span constructors, copy, assignment, and destructor constexpr span() noexcept; - constexpr span(pointer ptr, index_type count); - constexpr span(pointer firstElem, pointer lastElem); + template + constexpr explicit(Extent != dynamic_extent) span(It first, size_type count); + template + constexpr explicit(Extent != dynamic_extent) span(It first, End last); template - constexpr span(element_type (&arr)[N]) noexcept; + constexpr span(type_identity_t (&arr)[N]) noexcept; template constexpr span(array& arr) noexcept; template constexpr span(const array& arr) noexcept; - template - constexpr span(Container& cont); - template - constexpr span(const Container& cont); + template + constexpr explicit(Extent != dynamic_extent) span(R&& r); constexpr span(const span& other) noexcept = default; template - constexpr span(const span& s) noexcept; + constexpr explicit(Extent != dynamic_extent) span(const span& s) noexcept; ~span() noexcept = default; constexpr span& operator=(const span& other) noexcept = default; @@ -79,17 +83,17 @@ public: template constexpr span subspan() const; - constexpr span first(index_type count) const; - constexpr span last(index_type count) const; - constexpr span subspan(index_type offset, index_type count = dynamic_extent) const; + constexpr span first(size_type count) const; + constexpr span last(size_type count) const; + constexpr span subspan(size_type offset, size_type count = dynamic_extent) const; // [span.obs], span observers - constexpr index_type size() const noexcept; - constexpr index_type size_bytes() const noexcept; - constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type size_bytes() const noexcept; + [[nodiscard]] constexpr bool empty() const noexcept; // [span.elem], span element access - constexpr reference operator[](index_type idx) const; + constexpr reference operator[](size_type idx) const; constexpr reference front() const; constexpr reference back() const; constexpr pointer data() const noexcept; @@ -97,18 +101,17 @@ public: // [span.iterators], span iterator support constexpr iterator begin() const noexcept; constexpr iterator end() const noexcept; - constexpr const_iterator cbegin() const noexcept; - constexpr const_iterator cend() const noexcept; constexpr reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() const noexcept; - constexpr const_reverse_iterator crbegin() const noexcept; - constexpr const_reverse_iterator crend() const noexcept; private: - pointer data_; // exposition only - index_type size_; // exposition only + pointer data_; // exposition only + size_type size_; // exposition only }; +template + span(It, EndOrSize) -> span>>; + template span(T (&)[N]) -> span; @@ -118,22 +121,21 @@ template template span(const array&) -> span; -template - span(Container&) -> span; - -template - span(const Container&) -> span; +template + span(R&&) -> span>>; } // namespace std */ +#ifndef __cuda_std__ #include <__config> #include // for ptrdiff_t #include // for iterators #include // for array #include // for remove_cv, etc #include // for byte +#endif // __cuda_std__ #if defined(_LIBCUDACXX_USE_PRAGMA_GCC_SYSTEM_HEADER) #pragma GCC system_header @@ -141,9 +143,9 @@ template _LIBCUDACXX_BEGIN_NAMESPACE_STD -#if _LIBCUDACXX_STD_VER > 17 +#if _LIBCUDACXX_STD_VER > 11 -inline constexpr size_t dynamic_extent = numeric_limits::max(); +_LIBCUDACXX_INLINE_VAR constexpr size_t dynamic_extent = numeric_limits::max(); template class span; @@ -172,74 +174,88 @@ template struct __is_span_compatible_container<_Tp, _ElementType, void_t< // is not a specialization of span - typename enable_if::value, nullptr_t>::type, + enable_if_t::value, nullptr_t>, // is not a specialization of array - typename enable_if::value, nullptr_t>::type, + enable_if_t::value, nullptr_t>, // is_array_v is false, - typename enable_if, nullptr_t>::type, + enable_if_t, nullptr_t>, // data(cont) and size(cont) are well formed decltype(data(declval<_Tp>())), decltype(size(declval<_Tp>())), // remove_pointer_t(*)[] is convertible to ElementType(*)[] - typename enable_if< - is_convertible_v()))>(*)[], - _ElementType(*)[]>, - nullptr_t>::type + enable_if_t< + is_convertible()))>(*)[], + _ElementType(*)[]>::value, + nullptr_t> >> : public true_type {}; - template class _LIBCUDACXX_TEMPLATE_VIS span { public: // constants and types using element_type = _Tp; using value_type = remove_cv_t<_Tp>; - using index_type = size_t; + using size_type = size_t; using difference_type = ptrdiff_t; using pointer = _Tp *; using const_pointer = const _Tp *; using reference = _Tp &; using const_reference = const _Tp &; using iterator = __wrap_iter; - using const_iterator = __wrap_iter; using reverse_iterator = _CUDA_VSTD::reverse_iterator; - using const_reverse_iterator = _CUDA_VSTD::reverse_iterator; - static constexpr index_type extent = _Extent; + static constexpr size_type extent = _Extent; // [span.cons], span constructors, copy, assignment, and destructor - _LIBCUDACXX_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} - { static_assert(_Extent == 0, "Can't default construct a statically sized span with size > 0"); } + template = nullptr> + _LIBCUDACXX_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} {} - constexpr span (const span&) noexcept = default; - constexpr span& operator=(const span&) noexcept = default; + span (const span&) noexcept = default; + span& operator=(const span&) noexcept = default; - _LIBCUDACXX_INLINE_VISIBILITY constexpr span(pointer __ptr, index_type __count) : __data{__ptr} + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 span(pointer __ptr, size_type __count) : __data{__ptr} { (void)__count; _LIBCUDACXX_ASSERT(_Extent == __count, "size mismatch in span's constructor (ptr, len)"); } - _LIBCUDACXX_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f} + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 span(pointer __f, pointer __l) : __data{__f} { (void)__l; _LIBCUDACXX_ASSERT(_Extent == distance(__f, __l), "size mismatch in span's constructor (ptr, ptr)"); } - - _LIBCUDACXX_INLINE_VISIBILITY constexpr span(element_type (&__arr)[_Extent]) noexcept : __data{__arr} {} - _LIBCUDACXX_INLINE_VISIBILITY constexpr span( array& __arr) noexcept : __data{__arr.data()} {} - _LIBCUDACXX_INLINE_VISIBILITY constexpr span(const array& __arr) noexcept : __data{__arr.data()} {} - - template +#ifdef _LIBCUDACXX_COMPILER_NVRTC + template = nullptr> + _LIBCUDACXX_INLINE_VISIBILITY constexpr span(type_identity_t (&__arr)[_Sz]) noexcept : __data{__arr} {} +#else + _LIBCUDACXX_INLINE_VISIBILITY constexpr span(type_identity_t (&__arr)[_Extent]) noexcept : __data{__arr} {} +#endif + template ::value, nullptr_t> = nullptr> + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX14 + span( array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {} + template ::value, nullptr_t> = nullptr> + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX14 + span(const array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {} + + template ::value, nullptr_t> = nullptr> _LIBCUDACXX_INLINE_VISIBILITY - constexpr span(const span<_OtherElementType, _Extent>& __other, - enable_if_t< - is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, - nullptr_t> = nullptr) + constexpr span(const span<_OtherElementType, _Extent>& __other) noexcept : __data{__other.data()} {} - template + template ::value, nullptr_t> = nullptr> _LIBCUDACXX_INLINE_VISIBILITY - constexpr span(const span<_OtherElementType, dynamic_extent>& __other, - enable_if_t< - is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, - nullptr_t> = nullptr) noexcept + _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 span(const span<_OtherElementType, dynamic_extent>& __other) noexcept : __data{__other.data()} { _LIBCUDACXX_ASSERT(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); } + template ::value, nullptr_t> = nullptr> + _LIBCUDACXX_INLINE_VISIBILITY + constexpr span( _Container& __c) noexcept(noexcept(_CUDA_VSTD::data(__c))) + : __data{_CUDA_VSTD::data(__c)} { _LIBCUDACXX_ASSERT(_Extent == _CUDA::VSTD::size(__c), "size mismatch in span's constructor (other span)"); } + + template ::value, nullptr_t> = nullptr> + _LIBCUDACXX_INLINE_VISIBILITY + constexpr span(const _Container& __c) noexcept(noexcept(_CUDA_VSTD::data(__c))) + : __data{_CUDA_VSTD::data(__c)} { _LIBCUDACXX_ASSERT(_Extent == _CUDA::VSTD::size(__c), "size mismatch in span's constructor (other span)"); } // ~span() noexcept = default; @@ -247,7 +263,7 @@ public: _LIBCUDACXX_INLINE_VISIBILITY constexpr span first() const noexcept { - static_assert(_Count <= _Extent, "Count out of range in span::first()"); + static_assert(_Count <= _Extent, "span::first(): Count out of range"); return {data(), _Count}; } @@ -255,21 +271,21 @@ public: _LIBCUDACXX_INLINE_VISIBILITY constexpr span last() const noexcept { - static_assert(_Count <= _Extent, "Count out of range in span::last()"); + static_assert(_Count <= _Extent, "span::last(): Count out of range"); return {data() + size() - _Count, _Count}; } _LIBCUDACXX_INLINE_VISIBILITY - constexpr span first(index_type __count) const noexcept + _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 span first(size_type __count) const noexcept { - _LIBCUDACXX_ASSERT(__count <= size(), "Count out of range in span::first(count)"); + _LIBCUDACXX_ASSERT(__count <= size(), "span::first(count): count out of range"); return {data(), __count}; } _LIBCUDACXX_INLINE_VISIBILITY - constexpr span last(index_type __count) const noexcept + _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 span last(size_type __count) const noexcept { - _LIBCUDACXX_ASSERT(__count <= size(), "Count out of range in span::last(count)"); + _LIBCUDACXX_ASSERT(__count <= size(), "span::last(count): count out of range"); return {data() + size() - __count, __count}; } @@ -278,238 +294,214 @@ public: constexpr auto subspan() const noexcept -> span { - static_assert(_Offset <= _Extent, "Offset out of range in span::subspan()"); - return {data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; + static_assert(_Offset <= _Extent, "span::subspan(): Offset out of range"); + static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, "span::subspan(): Offset + Count out of range"); + + using _ReturnType = span; + return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; } _LIBCUDACXX_INLINE_VISIBILITY - constexpr span - subspan(index_type __offset, index_type __count = dynamic_extent) const noexcept + _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 span + subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { - _LIBCUDACXX_ASSERT(__offset <= size(), "Offset out of range in span::subspan(offset, count)"); - _LIBCUDACXX_ASSERT(__count <= size() || __count == dynamic_extent, "Count out of range in span::subspan(offset, count)"); + _LIBCUDACXX_ASSERT(__offset <= size(), "span::subspan(offset, count): offset out of range"); + _LIBCUDACXX_ASSERT(__count <= size() || __count == dynamic_extent, "span::subspan(offset, count): count out of range"); if (__count == dynamic_extent) return {data() + __offset, size() - __offset}; - _LIBCUDACXX_ASSERT(__offset <= size() - __count, "count + offset out of range in span::subspan(offset, count)"); + _LIBCUDACXX_ASSERT(__count <= size() - __offset, "span::subspan(offset, count): offset + count out of range"); return {data() + __offset, __count}; } - _LIBCUDACXX_INLINE_VISIBILITY constexpr index_type size() const noexcept { return _Extent; } - _LIBCUDACXX_INLINE_VISIBILITY constexpr index_type size_bytes() const noexcept { return _Extent * sizeof(element_type); } + _LIBCUDACXX_INLINE_VISIBILITY constexpr size_type size() const noexcept { return _Extent; } + _LIBCUDACXX_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { return _Extent * sizeof(element_type); } _LIBCUDACXX_INLINE_VISIBILITY constexpr bool empty() const noexcept { return _Extent == 0; } - _LIBCUDACXX_INLINE_VISIBILITY constexpr reference operator[](index_type __idx) const noexcept + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 reference operator[](size_type __idx) const noexcept { - _LIBCUDACXX_ASSERT(__idx >= 0 && __idx < size(), "span[] index out of bounds"); + _LIBCUDACXX_ASSERT(__idx < size(), "span::operator[](index): index out of range"); return __data[__idx]; } - _LIBCUDACXX_INLINE_VISIBILITY constexpr reference front() const noexcept + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 reference front() const noexcept { - static_assert(_Extent > 0, "span[].front() on empty span"); + _LIBCUDACXX_ASSERT(!empty(), "span::front() on empty span"); return __data[0]; } - _LIBCUDACXX_INLINE_VISIBILITY constexpr reference back() const noexcept + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 reference back() const noexcept { - static_assert(_Extent > 0, "span[].back() on empty span"); + _LIBCUDACXX_ASSERT(!empty(), "span::back() on empty span"); return __data[size()-1]; } _LIBCUDACXX_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; } // [span.iter], span iterator support - _LIBCUDACXX_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); } - _LIBCUDACXX_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); } - _LIBCUDACXX_INLINE_VISIBILITY constexpr const_iterator cbegin() const noexcept { return const_iterator(data()); } - _LIBCUDACXX_INLINE_VISIBILITY constexpr const_iterator cend() const noexcept { return const_iterator(data() + size()); } - _LIBCUDACXX_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } - _LIBCUDACXX_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } - _LIBCUDACXX_INLINE_VISIBILITY constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); } - _LIBCUDACXX_INLINE_VISIBILITY constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); } - - _LIBCUDACXX_INLINE_VISIBILITY constexpr void swap(span &__other) noexcept - { - pointer __p = __data; - __data = __other.__data; - __other.__data = __p; - } + _LIBCUDACXX_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); } + _LIBCUDACXX_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); } + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX14 reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX14 reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } _LIBCUDACXX_INLINE_VISIBILITY span __as_bytes() const noexcept - { return {reinterpret_cast(data()), size_bytes()}; } + { return span{reinterpret_cast(data()), size_bytes()}; } _LIBCUDACXX_INLINE_VISIBILITY span __as_writable_bytes() const noexcept - { return {reinterpret_cast(data()), size_bytes()}; } + { return span{reinterpret_cast(data()), size_bytes()}; } private: pointer __data; - }; template class _LIBCUDACXX_TEMPLATE_VIS span<_Tp, dynamic_extent> { -private: - public: // constants and types using element_type = _Tp; using value_type = remove_cv_t<_Tp>; - using index_type = size_t; + using size_type = size_t; using difference_type = ptrdiff_t; using pointer = _Tp *; using const_pointer = const _Tp *; using reference = _Tp &; using const_reference = const _Tp &; using iterator = __wrap_iter; - using const_iterator = __wrap_iter; using reverse_iterator = _CUDA_VSTD::reverse_iterator; - using const_reverse_iterator = _CUDA_VSTD::reverse_iterator; - static constexpr index_type extent = dynamic_extent; + static constexpr size_type extent = dynamic_extent; // [span.cons], span constructors, copy, assignment, and destructor _LIBCUDACXX_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}, __size{0} {} - constexpr span (const span&) noexcept = default; - constexpr span& operator=(const span&) noexcept = default; + span (const span&) noexcept = default; + span& operator=(const span&) noexcept = default; - _LIBCUDACXX_INLINE_VISIBILITY constexpr span(pointer __ptr, index_type __count) : __data{__ptr}, __size{__count} {} + _LIBCUDACXX_INLINE_VISIBILITY constexpr span(pointer __ptr, size_type __count) : __data{__ptr}, __size{__count} {} +#if _LIBCUDACXX_STD_VER > 14 _LIBCUDACXX_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f}, __size{static_cast(distance(__f, __l))} {} +#else + _LIBCUDACXX_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f}, __size{static_cast(__l - __f)} {} +#endif template _LIBCUDACXX_INLINE_VISIBILITY - constexpr span(element_type (&__arr)[_Sz]) noexcept : __data{__arr}, __size{_Sz} {} + constexpr span(type_identity_t (&__arr)[_Sz]) noexcept : __data{__arr}, __size{_Sz} {} - template + template ::value, nullptr_t> = nullptr> _LIBCUDACXX_INLINE_VISIBILITY - constexpr span(array& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} + _LIBCUDACXX_CONSTEXPR_AFTER_CXX14 span(array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} - template + template ::value, nullptr_t> = nullptr> _LIBCUDACXX_INLINE_VISIBILITY - constexpr span(const array& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} + _LIBCUDACXX_CONSTEXPR_AFTER_CXX14 span(const array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} - template + template ::value, nullptr_t> = nullptr> _LIBCUDACXX_INLINE_VISIBILITY - constexpr span( _Container& __c, - enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr) - : __data{_CUDA_VSTD::data(__c)}, __size{(index_type) _CUDA_VSTD::size(__c)} {} + constexpr span( _Container& __c) + : __data{_CUDA_VSTD::data(__c)}, __size{(size_type) _CUDA_VSTD::size(__c)} {} - template + template ::value, nullptr_t> = nullptr> _LIBCUDACXX_INLINE_VISIBILITY - constexpr span(const _Container& __c, - enable_if_t<__is_span_compatible_container::value, nullptr_t> = nullptr) - : __data{_CUDA_VSTD::data(__c)}, __size{(index_type) _CUDA_VSTD::size(__c)} {} + constexpr span(const _Container& __c) + : __data{_CUDA_VSTD::data(__c)}, __size{(size_type) _CUDA_VSTD::size(__c)} {} - template + template ::value, nullptr_t> = nullptr> _LIBCUDACXX_INLINE_VISIBILITY - constexpr span(const span<_OtherElementType, _OtherExtent>& __other, - enable_if_t< - is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, - nullptr_t> = nullptr) noexcept + constexpr span(const span<_OtherElementType, _OtherExtent>& __other) noexcept : __data{__other.data()}, __size{__other.size()} {} // ~span() noexcept = default; template _LIBCUDACXX_INLINE_VISIBILITY - constexpr span first() const noexcept + _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 span first() const noexcept { - _LIBCUDACXX_ASSERT(_Count <= size(), "Count out of range in span::first()"); - return {data(), _Count}; + _LIBCUDACXX_ASSERT(_Count <= size(), "span::first(): Count out of range"); + return span{data(), _Count}; } template _LIBCUDACXX_INLINE_VISIBILITY - constexpr span last() const noexcept + _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 span last() const noexcept { - _LIBCUDACXX_ASSERT(_Count <= size(), "Count out of range in span::last()"); - return {data() + size() - _Count, _Count}; + _LIBCUDACXX_ASSERT(_Count <= size(), "span::last(): Count out of range"); + return span{data() + size() - _Count, _Count}; } _LIBCUDACXX_INLINE_VISIBILITY - constexpr span first(index_type __count) const noexcept + _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 span first(size_type __count) const noexcept { - _LIBCUDACXX_ASSERT(__count <= size(), "Count out of range in span::first(count)"); + _LIBCUDACXX_ASSERT(__count <= size(), "span::first(count): count out of range"); return {data(), __count}; } _LIBCUDACXX_INLINE_VISIBILITY - constexpr span last (index_type __count) const noexcept + _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 span last (size_type __count) const noexcept { - _LIBCUDACXX_ASSERT(__count <= size(), "Count out of range in span::last(count)"); + _LIBCUDACXX_ASSERT(__count <= size(), "span::last(count): count out of range"); return {data() + size() - __count, __count}; } template _LIBCUDACXX_INLINE_VISIBILITY - constexpr span<_Tp, dynamic_extent> subspan() const noexcept + _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 span subspan() const noexcept { - _LIBCUDACXX_ASSERT(_Offset <= size(), "Offset out of range in span::subspan()"); - _LIBCUDACXX_ASSERT(_Count == dynamic_extent || _Offset + _Count <= size(), "Count out of range in span::subspan()"); - return {data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; + _LIBCUDACXX_ASSERT(_Offset <= size(), "span::subspan(): Offset out of range"); + _LIBCUDACXX_ASSERT(_Count == dynamic_extent || _Count <= size() - _Offset, "span::subspan(): Offset + Count out of range"); + return span{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; } - constexpr span + _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 span _LIBCUDACXX_INLINE_VISIBILITY - subspan(index_type __offset, index_type __count = dynamic_extent) const noexcept + subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { - _LIBCUDACXX_ASSERT(__offset <= size(), "Offset out of range in span::subspan(offset, count)"); - _LIBCUDACXX_ASSERT(__count <= size() || __count == dynamic_extent, "count out of range in span::subspan(offset, count)"); + _LIBCUDACXX_ASSERT(__offset <= size(), "span::subspan(offset, count): offset out of range"); + _LIBCUDACXX_ASSERT(__count <= size() || __count == dynamic_extent, "span::subspan(offset, count): count out of range"); if (__count == dynamic_extent) return {data() + __offset, size() - __offset}; - _LIBCUDACXX_ASSERT(__offset <= size() - __count, "Offset + count out of range in span::subspan(offset, count)"); + _LIBCUDACXX_ASSERT(__count <= size() - __offset, "span::subspan(offset, count): offset + count out of range"); return {data() + __offset, __count}; } - _LIBCUDACXX_INLINE_VISIBILITY constexpr index_type size() const noexcept { return __size; } - _LIBCUDACXX_INLINE_VISIBILITY constexpr index_type size_bytes() const noexcept { return __size * sizeof(element_type); } - _LIBCUDACXX_INLINE_VISIBILITY constexpr bool empty() const noexcept { return __size == 0; } + _LIBCUDACXX_INLINE_VISIBILITY constexpr size_type size() const noexcept { return __size; } + _LIBCUDACXX_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { return __size * sizeof(element_type); } + _LIBCUDACXX_INLINE_VISIBILITY constexpr bool empty() const noexcept { return __size == 0; } - _LIBCUDACXX_INLINE_VISIBILITY constexpr reference operator[](index_type __idx) const noexcept + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 reference operator[](size_type __idx) const noexcept { - _LIBCUDACXX_ASSERT(__idx >= 0 && __idx < size(), "span[] index out of bounds"); + _LIBCUDACXX_ASSERT(__idx < size(), "span::operator[](index): index out of range"); return __data[__idx]; } - _LIBCUDACXX_INLINE_VISIBILITY constexpr reference front() const noexcept + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 reference front() const noexcept { - _LIBCUDACXX_ASSERT(!empty(), "span[].front() on empty span"); + _LIBCUDACXX_ASSERT(!empty(), "span::front() on empty span"); return __data[0]; } - _LIBCUDACXX_INLINE_VISIBILITY constexpr reference back() const noexcept + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 reference back() const noexcept { - _LIBCUDACXX_ASSERT(!empty(), "span[].back() on empty span"); + _LIBCUDACXX_ASSERT(!empty(), "span::back() on empty span"); return __data[size()-1]; } - _LIBCUDACXX_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; } + _LIBCUDACXX_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; } // [span.iter], span iterator support - _LIBCUDACXX_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); } - _LIBCUDACXX_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); } - _LIBCUDACXX_INLINE_VISIBILITY constexpr const_iterator cbegin() const noexcept { return const_iterator(data()); } - _LIBCUDACXX_INLINE_VISIBILITY constexpr const_iterator cend() const noexcept { return const_iterator(data() + size()); } - _LIBCUDACXX_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } - _LIBCUDACXX_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } - _LIBCUDACXX_INLINE_VISIBILITY constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); } - _LIBCUDACXX_INLINE_VISIBILITY constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); } - - _LIBCUDACXX_INLINE_VISIBILITY constexpr void swap(span &__other) noexcept - { - pointer __p = __data; - __data = __other.__data; - __other.__data = __p; - - index_type __sz = __size; - __size = __other.__size; - __other.__size = __sz; - } - + _LIBCUDACXX_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); } + _LIBCUDACXX_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); } + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX14 reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX14 reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } + _LIBCUDACXX_INLINE_VISIBILITY span __as_bytes() const noexcept { return {reinterpret_cast(data()), size_bytes()}; } @@ -518,37 +510,9 @@ public: private: pointer __data; - index_type __size; + size_type __size; }; -// tuple interface -template -struct _LIBCUDACXX_TEMPLATE_VIS tuple_size> - : public integral_constant {}; - -template -struct _LIBCUDACXX_TEMPLATE_VIS tuple_size>; // declared but not defined - - -template -struct _LIBCUDACXX_TEMPLATE_VIS tuple_element<_Ip, span<_Tp, _Size>> -{ - static_assert( dynamic_extent != _Size, "std::tuple_element<> not supported for std::span"); - static_assert(_Ip < _Size, "Index out of bounds in std::tuple_element<> (std::span)"); - typedef _Tp type; -}; - -template -_LIBCUDACXX_INLINE_VISIBILITY constexpr -_Tp& -get(span<_Tp, _Size> __s) noexcept -{ - static_assert( dynamic_extent != _Size, "std::get<> not supported for std::span"); - static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::span)"); - return __s[_Ip]; -} - - // as_bytes & as_writable_bytes template _LIBCUDACXX_INLINE_VISIBILITY @@ -559,14 +523,12 @@ auto as_bytes(span<_Tp, _Extent> __s) noexcept template _LIBCUDACXX_INLINE_VISIBILITY auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept --> enable_if_t, decltype(__s.__as_writable_bytes())> +-> enable_if_t::value, decltype(__s.__as_writable_bytes())> { return __s.__as_writable_bytes(); } -template -_LIBCUDACXX_INLINE_VISIBILITY -constexpr void swap(span<_Tp, _Extent> &__lhs, span<_Tp, _Extent> &__rhs) noexcept -{ __lhs.swap(__rhs); } +#endif // _LIBCUDACXX_STD_VER > 11 +#if _LIBCUDACXX_STD_VER > 14 // Deduction guides template @@ -584,7 +546,7 @@ template template span(const _Container&) -> span; -#endif // _LIBCUDACXX_STD_VER > 17 +#endif // _LIBCUDACXX_STD_VER > 14 _LIBCUDACXX_END_NAMESPACE_STD diff --git a/include/cuda/std/detail/libcxx/include/type_traits b/include/cuda/std/detail/libcxx/include/type_traits index 44f7c654a7..52217b830b 100644 --- a/include/cuda/std/detail/libcxx/include/type_traits +++ b/include/cuda/std/detail/libcxx/include/type_traits @@ -4,6 +4,7 @@ // 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. // //===----------------------------------------------------------------------===// diff --git a/include/cuda/std/detail/libcxx/include/version b/include/cuda/std/detail/libcxx/include/version index 736c4343f5..0871d45a9e 100644 --- a/include/cuda/std/detail/libcxx/include/version +++ b/include/cuda/std/detail/libcxx/include/version @@ -140,6 +140,7 @@ __cpp_lib_void_t 201411L # if !defined(_LIBCUDACXX_HAS_NO_THREADS) # define __cpp_lib_shared_timed_mutex 201402L # endif +# define __cpp_lib_span 201902L # define __cpp_lib_string_udls 201304L # define __cpp_lib_transformation_trait_aliases 201304L # define __cpp_lib_transparent_operators 201210L diff --git a/include/cuda/std/span b/include/cuda/std/span new file mode 100644 index 0000000000..12ec1e4721 --- /dev/null +++ b/include/cuda/std/span @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// Part of libcu++, the C++ Standard Library for your entire system, +// 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. +// +//===----------------------------------------------------------------------===// + +#ifndef _CUDA_SPAN +#define _CUDA_SPAN + +#include "array" +#include "cstddef" +#include "type_traits" +#include "version" +#include "iterator" +#include "utility" + +#include "detail/__config" + +#include "detail/__pragma_push" + +#include "detail/libcxx/include/span" + +#include "detail/__pragma_pop" + +#endif //_CUDA_SPAN