Skip to content
This repository has been archived by the owner on Mar 21, 2024. It is now read-only.

Commit

Permalink
Port std::span and enable if for C++11 onwards to support mdspan
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
miscco committed Nov 14, 2022
1 parent a982592 commit f98f43f
Show file tree
Hide file tree
Showing 48 changed files with 3,795 additions and 230 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -121,20 +113,20 @@ __host__ __device__ void test_illformed_default()
{
typedef cuda::std::pair<IllFormedDefault, int> P;
static_assert((cuda::std::is_constructible<P, IllFormedDefault, int>::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<int, IllFormedDefault> P;
static_assert((cuda::std::is_constructible<P, int, IllFormedDefault>::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<IllFormedDefault, IllFormedDefault> P;
static_assert((cuda::std::is_constructible<P, IllFormedDefault, IllFormedDefault>::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);
}
}
Expand Down
73 changes: 73 additions & 0 deletions .upstream-tests/test/std/views/views.span/span.cons/array.fail.cpp
Original file line number Diff line number Diff line change
@@ -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

// <span>

// template<size_t N>
// constexpr span(element_type (&arr)[N]) noexcept;
// template<size_t N>
// constexpr span(array<value_type, N>& arr) noexcept;
// template<size_t N>
// constexpr span(const array<value_type, N>& arr) noexcept;
//
// Remarks: These constructors shall not participate in overload resolution unless:
// — extent == dynamic_extent || N == extent is true, and
// — remove_pointer_t<decltype(data(arr))>(*)[] is convertible to ElementType(*)[].
//


#include <cuda/std/span>
#include <cuda/std/cassert>

#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<int, 2> s1(arr); // expected-error {{no matching constructor for initialization of 'cuda::std::span<int, 2>'}}
}

// Type wrong
{
cuda::std::span<float> s1(arr); // expected-error {{no matching constructor for initialization of 'cuda::std::span<float>'}}
cuda::std::span<float, 3> s2(arr); // expected-error {{no matching constructor for initialization of 'cuda::std::span<float, 3>'}}
}

// CV wrong (dynamically sized)
{
cuda::std::span< int> s1{ carr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<int>'}}
cuda::std::span< int> s2{ varr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<int>'}}
cuda::std::span< int> s3{cvarr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<int>'}}
cuda::std::span<const int> s4{ varr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<const int>'}}
cuda::std::span<const int> s5{cvarr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<const int>'}}
cuda::std::span< volatile int> s6{ carr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<volatile int>'}}
cuda::std::span< volatile int> s7{cvarr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<volatile int>'}}
}

// CV wrong (statically sized)
{
cuda::std::span< int,3> s1{ carr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<int, 3>'}}
cuda::std::span< int,3> s2{ varr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<int, 3>'}}
cuda::std::span< int,3> s3{cvarr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<int, 3>'}}
cuda::std::span<const int,3> s4{ varr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<const int, 3>'}}
cuda::std::span<const int,3> s5{cvarr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<const int, 3>'}}
cuda::std::span< volatile int,3> s6{ carr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<volatile int, 3>'}}
cuda::std::span< volatile int,3> s7{cvarr}; // expected-error {{no matching constructor for initialization of 'cuda::std::span<volatile int, 3>'}}
}

return 0;
}
119 changes: 119 additions & 0 deletions .upstream-tests/test/std/views/views.span/span.cons/array.pass.cpp
Original file line number Diff line number Diff line change
@@ -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

// <span>

// template<size_t N>
// 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<decltype(data(arr))>(*)[] is convertible to ElementType(*)[].
//


#include <cuda/std/span>
#include <cuda/std/cassert>

#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<const int> s2{ carr}; // a cuda::std::span<const int> pointing at const int.
cuda::std::span< volatile int> s3{ varr}; // a cuda::std::span< volatile int> pointing at volatile int.
cuda::std::span<const volatile int> s4{cvarr}; // a cuda::std::span<const volatile int> 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<const int,3> s2{ carr}; // a cuda::std::span<const int> 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<const volatile int,3> s4{cvarr}; // a cuda::std::span<const volatile int> pointing at const volatile int.
assert(s1.size() + s2.size() + s3.size() + s4.size() == 12);
}


// types different (dynamic sized)
{
cuda::std::span<const int> s1{ arr}; // a cuda::std::span<const int> 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<const volatile int> s4{ arr}; // a cuda::std::span<const volatile int> pointing at int.
cuda::std::span<const volatile int> s5{carr}; // a cuda::std::span<const volatile int> pointing at const int.
cuda::std::span<const volatile int> s6{varr}; // a cuda::std::span<const volatile int> 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<const int,3> s1{ arr}; // a cuda::std::span<const int> 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<const volatile int,3> s4{ arr}; // a cuda::std::span<const volatile int> pointing at int.
cuda::std::span<const volatile int,3> s5{carr}; // a cuda::std::span<const volatile int> pointing at const int.
cuda::std::span<const volatile int,3> s6{varr}; // a cuda::std::span<const volatile int> pointing at volatile int.
assert(s1.size() + s2.size() + s3.size() + s4.size() + s5.size() + s6.size() == 18);
}
}

template<class T>
__host__ __device__ constexpr bool testSpan()
{
T val[2] = {};

ASSERT_NOEXCEPT(cuda::std::span<T>{val});
ASSERT_NOEXCEPT(cuda::std::span<T, 2>{val});
ASSERT_NOEXCEPT(cuda::std::span<const T>{val});
ASSERT_NOEXCEPT(cuda::std::span<const T, 2>{val});

cuda::std::span<T> s1 = val;
cuda::std::span<T, 2> s2 = val;
cuda::std::span<const T> s3 = val;
cuda::std::span<const T, 2> 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<const int> s5 = {{1,2}};
cuda::std::span<const int, 2> 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<int>();
testSpan<double>();
testSpan<A>();

static_assert(testSpan<int>(), "");
static_assert(testSpan<double>(), "");
static_assert(testSpan<A>(), "");

checkCV();

return 0;
}
Loading

0 comments on commit f98f43f

Please sign in to comment.