blob: a0b37fe8e64b9d6fa5512959f8df30084fc1fd0d [file] [log] [blame]
Marshall Clow8a0794b2018-07-24 03:01:02 +00001// -*- C++ -*-
2//===------------------------------ span ---------------------------------===//
3//
Chandler Carruth57b08b02019-01-19 10:56:40 +00004// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Marshall Clow8a0794b2018-07-24 03:01:02 +00007//
8//===---------------------------------------------------------------------===//
Stephan T. Lavavejdec89052018-11-14 03:06:06 +00009// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
Marshall Clow8a0794b2018-07-24 03:01:02 +000010
11// <span>
12
13// template<size_t N>
14// constexpr span(array<value_type, N>& arr) noexcept;
15// template<size_t N>
Stephan T. Lavavejdec89052018-11-14 03:06:06 +000016// constexpr span(const array<value_type, N>& arr) noexcept;
Marshall Clow8a0794b2018-07-24 03:01:02 +000017//
18// Remarks: These constructors shall not participate in overload resolution unless:
19// — extent == dynamic_extent || N == extent is true, and
20// — remove_pointer_t<decltype(data(arr))>(*)[] is convertible to ElementType(*)[].
21//
22
23
24#include <span>
25#include <cassert>
26#include <string>
27
28#include "test_macros.h"
Marshall Clow8bbf22e2018-07-24 03:41:36 +000029// std::array is explicitly allowed to be initialized with A a = { init-list };.
30// Disable the missing braces warning for this reason.
31#include "disable_missing_braces_warning.h"
Marshall Clow8a0794b2018-07-24 03:01:02 +000032
33
34void checkCV()
35{
36 std::array<int, 3> arr = {1,2,3};
37// STL says these are not cromulent
38// std::array<const int,3> carr = {4,5,6};
39// std::array<volatile int, 3> varr = {7,8,9};
40// std::array<const volatile int, 3> cvarr = {1,3,5};
41
42// Types the same (dynamic sized)
43 {
44 std::span< int> s1{ arr}; // a span< int> pointing at int.
45 }
46
47// Types the same (static sized)
48 {
49 std::span< int,3> s1{ arr}; // a span< int> pointing at int.
50 }
51
52
53// types different (dynamic sized)
54 {
55 std::span<const int> s1{ arr}; // a span<const int> pointing at int.
56 std::span< volatile int> s2{ arr}; // a span< volatile int> pointing at int.
57 std::span< volatile int> s3{ arr}; // a span< volatile int> pointing at const int.
58 std::span<const volatile int> s4{ arr}; // a span<const volatile int> pointing at int.
59 }
60
61// types different (static sized)
62 {
63 std::span<const int,3> s1{ arr}; // a span<const int> pointing at int.
64 std::span< volatile int,3> s2{ arr}; // a span< volatile int> pointing at int.
65 std::span< volatile int,3> s3{ arr}; // a span< volatile int> pointing at const int.
66 std::span<const volatile int,3> s4{ arr}; // a span<const volatile int> pointing at int.
67 }
68}
69
70
71template <typename T>
72constexpr bool testConstexprSpan()
73{
74 constexpr std::array<T,2> val = { T(), T() };
75 ASSERT_NOEXCEPT(std::span<const T> {val});
76 ASSERT_NOEXCEPT(std::span<const T, 2>{val});
77 std::span<const T> s1{val};
78 std::span<const T, 2> s2{val};
79 return
80 s1.data() == &val[0] && s1.size() == 2
81 && s2.data() == &val[0] && s2.size() == 2;
82}
83
84
85template <typename T>
86void testRuntimeSpan()
87{
88 std::array<T,2> val;
89 ASSERT_NOEXCEPT(std::span<T> {val});
90 ASSERT_NOEXCEPT(std::span<T, 2>{val});
91 std::span<T> s1{val};
92 std::span<T, 2> s2{val};
93 assert(s1.data() == &val[0] && s1.size() == 2);
94 assert(s2.data() == &val[0] && s2.size() == 2);
95}
96
97struct A{};
98
99int main ()
100{
101 static_assert(testConstexprSpan<int>(), "");
102 static_assert(testConstexprSpan<long>(), "");
103 static_assert(testConstexprSpan<double>(), "");
104 static_assert(testConstexprSpan<A>(), "");
105
106 testRuntimeSpan<int>();
107 testRuntimeSpan<long>();
108 testRuntimeSpan<double>();
109 testRuntimeSpan<std::string>();
110 testRuntimeSpan<A>();
111
112 checkCV();
113}