1a8cf78c7SLouis Dionne //===----------------------------------------------------------------------===// 2a8cf78c7SLouis Dionne // 3a8cf78c7SLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4a8cf78c7SLouis Dionne // See https://llvm.org/LICENSE.txt for license information. 5a8cf78c7SLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a8cf78c7SLouis Dionne // 7a8cf78c7SLouis Dionne //===----------------------------------------------------------------------===// 8*99696b35SLouis Dionne 9a8cf78c7SLouis Dionne // UNSUPPORTED: c++03, c++11, c++14, c++17 10a8cf78c7SLouis Dionne 11a8cf78c7SLouis Dionne // <span> 12a8cf78c7SLouis Dionne 13a8cf78c7SLouis Dionne // constexpr span(const span& other) noexcept = default; 14a8cf78c7SLouis Dionne 15a8cf78c7SLouis Dionne #include <span> 16a8cf78c7SLouis Dionne #include <cassert> 17a8cf78c7SLouis Dionne #include <string> 18*99696b35SLouis Dionne #include <utility> 19a8cf78c7SLouis Dionne 20a8cf78c7SLouis Dionne #include "test_macros.h" 21a8cf78c7SLouis Dionne 22*99696b35SLouis Dionne template <class T> 23*99696b35SLouis Dionne constexpr void test() { 24*99696b35SLouis Dionne ASSERT_NOEXCEPT(std::span<T>(std::declval<std::span<T> const&>())); 25*99696b35SLouis Dionne ASSERT_NOEXCEPT(std::span<T>{std::declval<std::span<T> const&>()}); 26*99696b35SLouis Dionne 27*99696b35SLouis Dionne // dynamic_extent 28a8cf78c7SLouis Dionne { 29*99696b35SLouis Dionne std::span<T> x; 30*99696b35SLouis Dionne std::span<T> copy(x); 31*99696b35SLouis Dionne assert(copy.data() == x.data()); 32*99696b35SLouis Dionne assert(copy.size() == x.size()); 33*99696b35SLouis Dionne } 34*99696b35SLouis Dionne { 35*99696b35SLouis Dionne T array[3] = {}; 36*99696b35SLouis Dionne std::span<T> x(array, 3); 37*99696b35SLouis Dionne std::span<T> copy(x); 38*99696b35SLouis Dionne assert(copy.data() == array); 39*99696b35SLouis Dionne assert(copy.size() == 3); 40*99696b35SLouis Dionne } 41*99696b35SLouis Dionne { 42*99696b35SLouis Dionne T array[3] = {}; 43*99696b35SLouis Dionne std::span<T> x(array, 2); 44*99696b35SLouis Dionne std::span<T> copy(x); 45*99696b35SLouis Dionne assert(copy.data() == array); 46*99696b35SLouis Dionne assert(copy.size() == 2); 47a8cf78c7SLouis Dionne } 48a8cf78c7SLouis Dionne 49*99696b35SLouis Dionne // static extent 50a8cf78c7SLouis Dionne { 51*99696b35SLouis Dionne std::span<T, 0> x; 52*99696b35SLouis Dionne std::span<T, 0> copy(x); 53*99696b35SLouis Dionne assert(copy.data() == x.data()); 54*99696b35SLouis Dionne assert(copy.size() == x.size()); 55*99696b35SLouis Dionne } 56*99696b35SLouis Dionne { 57*99696b35SLouis Dionne T array[3] = {}; 58*99696b35SLouis Dionne std::span<T, 3> x(array); 59*99696b35SLouis Dionne std::span<T, 3> copy(x); 60*99696b35SLouis Dionne assert(copy.data() == array); 61*99696b35SLouis Dionne assert(copy.size() == 3); 62*99696b35SLouis Dionne } 63*99696b35SLouis Dionne { 64*99696b35SLouis Dionne T array[2] = {}; 65*99696b35SLouis Dionne std::span<T, 2> x(array); 66*99696b35SLouis Dionne std::span<T, 2> copy(x); 67*99696b35SLouis Dionne assert(copy.data() == array); 68*99696b35SLouis Dionne assert(copy.size() == 2); 69*99696b35SLouis Dionne } 70a8cf78c7SLouis Dionne } 71a8cf78c7SLouis Dionne 72*99696b35SLouis Dionne struct Foo {}; 73a8cf78c7SLouis Dionne 74*99696b35SLouis Dionne constexpr bool test_all() { 75*99696b35SLouis Dionne test<int>(); 76*99696b35SLouis Dionne test<const int>(); 77*99696b35SLouis Dionne test<volatile int>(); 78*99696b35SLouis Dionne test<const volatile int>(); 79*99696b35SLouis Dionne 80*99696b35SLouis Dionne test<long>(); 81*99696b35SLouis Dionne test<const long>(); 82*99696b35SLouis Dionne test<volatile long>(); 83*99696b35SLouis Dionne test<const volatile long>(); 84*99696b35SLouis Dionne 85*99696b35SLouis Dionne test<double>(); 86*99696b35SLouis Dionne test<const double>(); 87*99696b35SLouis Dionne test<volatile double>(); 88*99696b35SLouis Dionne test<const volatile double>(); 89*99696b35SLouis Dionne 90*99696b35SLouis Dionne // Note: Can't test non-fundamental types with volatile because we require `T*` to be indirectly_readable, 91*99696b35SLouis Dionne // which isn't the case when T is volatile. 92*99696b35SLouis Dionne test<Foo>(); 93*99696b35SLouis Dionne test<const Foo>(); 94*99696b35SLouis Dionne 95*99696b35SLouis Dionne test<std::string>(); 96*99696b35SLouis Dionne test<const std::string>(); 97*99696b35SLouis Dionne 98*99696b35SLouis Dionne // Regression test for https://github.com/llvm/llvm-project/issues/104496 99a8cf78c7SLouis Dionne { 100*99696b35SLouis Dionne struct Incomplete; 101*99696b35SLouis Dionne std::span<Incomplete> x; 102*99696b35SLouis Dionne std::span<Incomplete> copy(x); 103*99696b35SLouis Dionne assert(copy.data() == x.data()); 104*99696b35SLouis Dionne assert(copy.size() == x.size()); 105*99696b35SLouis Dionne } 106a8cf78c7SLouis Dionne 107*99696b35SLouis Dionne return true; 108*99696b35SLouis Dionne } 109a8cf78c7SLouis Dionne 110*99696b35SLouis Dionne int main(int, char**) { 111*99696b35SLouis Dionne test_all(); 112*99696b35SLouis Dionne static_assert(test_all()); 113a8cf78c7SLouis Dionne 114a8cf78c7SLouis Dionne return 0; 115a8cf78c7SLouis Dionne } 116