1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // UNSUPPORTED: c++03, c++11, c++14, c++17 9 10 // <span> 11 12 // constexpr span& operator=(const span& other) noexcept = default; 13 14 #include <span> 15 #include <cassert> 16 #include <iterator> 17 #include <string> 18 #include <utility> 19 20 #include "test_macros.h" 21 22 template <typename T> 23 constexpr bool doAssign(T lhs, T rhs) 24 { 25 ASSERT_NOEXCEPT(std::declval<T&>() = rhs); 26 lhs = rhs; 27 return lhs.data() == rhs.data() 28 && lhs.size() == rhs.size(); 29 } 30 31 struct A{}; 32 33 constexpr int carr1[] = {1,2,3,4}; 34 constexpr int carr2[] = {3,4,5}; 35 constexpr int carr3[] = {7,8}; 36 int arr[] = {5,6,7,9}; 37 std::string strs[] = {"ABC", "DEF", "GHI"}; 38 39 40 int main(int, char**) 41 { 42 43 // constexpr dynamically sized assignment 44 { 45 // On systems where 'ptrdiff_t' is a synonym for 'int', 46 // the call span(ptr, 0) selects the (pointer, size_type) constructor. 47 // On systems where 'ptrdiff_t' is NOT a synonym for 'int', 48 // it is ambiguous, because of 0 also being convertible to a null pointer 49 // and so the compiler can't choose between: 50 // span(pointer, size_type) 51 // and span(pointer, pointer) 52 // We cast zero to std::ptrdiff_t to remove that ambiguity. 53 // Example: 54 // On darwin x86_64, ptrdiff_t is the same as long int. 55 // On darwin i386, ptrdiff_t is the same as int. 56 constexpr std::span<const int> spans[] = { 57 {}, 58 {carr1, static_cast<std::size_t>(0)}, 59 {carr1, 1U}, 60 {carr1, 2U}, 61 {carr1, 3U}, 62 {carr1, 4U}, 63 {carr2, static_cast<std::size_t>(0)}, 64 {carr2, 1U}, 65 {carr2, 2U}, 66 {carr2, 3U}, 67 {carr3, static_cast<std::size_t>(0)}, 68 {carr3, 1U}, 69 {carr3, 2U} 70 }; 71 72 static_assert(std::size(spans) == 13, "" ); 73 74 // No for loops in constexpr land :-( 75 static_assert(doAssign(spans[0], spans[0]), ""); 76 static_assert(doAssign(spans[0], spans[1]), ""); 77 static_assert(doAssign(spans[0], spans[2]), ""); 78 static_assert(doAssign(spans[0], spans[3]), ""); 79 static_assert(doAssign(spans[0], spans[4]), ""); 80 static_assert(doAssign(spans[0], spans[5]), ""); 81 static_assert(doAssign(spans[0], spans[6]), ""); 82 static_assert(doAssign(spans[0], spans[7]), ""); 83 static_assert(doAssign(spans[0], spans[8]), ""); 84 static_assert(doAssign(spans[0], spans[9]), ""); 85 static_assert(doAssign(spans[0], spans[10]), ""); 86 static_assert(doAssign(spans[0], spans[11]), ""); 87 static_assert(doAssign(spans[0], spans[12]), ""); 88 89 static_assert(doAssign(spans[1], spans[1]), ""); 90 static_assert(doAssign(spans[1], spans[2]), ""); 91 static_assert(doAssign(spans[1], spans[3]), ""); 92 static_assert(doAssign(spans[1], spans[4]), ""); 93 static_assert(doAssign(spans[1], spans[5]), ""); 94 static_assert(doAssign(spans[1], spans[6]), ""); 95 static_assert(doAssign(spans[1], spans[7]), ""); 96 static_assert(doAssign(spans[1], spans[8]), ""); 97 static_assert(doAssign(spans[1], spans[9]), ""); 98 static_assert(doAssign(spans[1], spans[10]), ""); 99 static_assert(doAssign(spans[1], spans[11]), ""); 100 static_assert(doAssign(spans[1], spans[12]), ""); 101 102 static_assert(doAssign(spans[2], spans[2]), ""); 103 static_assert(doAssign(spans[2], spans[3]), ""); 104 static_assert(doAssign(spans[2], spans[4]), ""); 105 static_assert(doAssign(spans[2], spans[5]), ""); 106 static_assert(doAssign(spans[2], spans[6]), ""); 107 static_assert(doAssign(spans[2], spans[7]), ""); 108 static_assert(doAssign(spans[2], spans[8]), ""); 109 static_assert(doAssign(spans[2], spans[9]), ""); 110 static_assert(doAssign(spans[2], spans[10]), ""); 111 static_assert(doAssign(spans[2], spans[11]), ""); 112 static_assert(doAssign(spans[2], spans[12]), ""); 113 114 static_assert(doAssign(spans[3], spans[3]), ""); 115 static_assert(doAssign(spans[3], spans[4]), ""); 116 static_assert(doAssign(spans[3], spans[4]), ""); 117 static_assert(doAssign(spans[3], spans[4]), ""); 118 static_assert(doAssign(spans[3], spans[4]), ""); 119 static_assert(doAssign(spans[3], spans[4]), ""); 120 static_assert(doAssign(spans[3], spans[4]), ""); 121 static_assert(doAssign(spans[3], spans[4]), ""); 122 static_assert(doAssign(spans[3], spans[4]), ""); 123 static_assert(doAssign(spans[3], spans[10]), ""); 124 static_assert(doAssign(spans[3], spans[11]), ""); 125 static_assert(doAssign(spans[3], spans[12]), ""); 126 127 static_assert(doAssign(spans[4], spans[4]), ""); 128 static_assert(doAssign(spans[4], spans[5]), ""); 129 static_assert(doAssign(spans[4], spans[6]), ""); 130 static_assert(doAssign(spans[4], spans[7]), ""); 131 static_assert(doAssign(spans[4], spans[8]), ""); 132 static_assert(doAssign(spans[4], spans[9]), ""); 133 static_assert(doAssign(spans[4], spans[10]), ""); 134 static_assert(doAssign(spans[4], spans[11]), ""); 135 static_assert(doAssign(spans[4], spans[12]), ""); 136 137 static_assert(doAssign(spans[5], spans[5]), ""); 138 static_assert(doAssign(spans[5], spans[6]), ""); 139 static_assert(doAssign(spans[5], spans[7]), ""); 140 static_assert(doAssign(spans[5], spans[8]), ""); 141 static_assert(doAssign(spans[5], spans[9]), ""); 142 static_assert(doAssign(spans[5], spans[10]), ""); 143 static_assert(doAssign(spans[5], spans[11]), ""); 144 static_assert(doAssign(spans[5], spans[12]), ""); 145 146 static_assert(doAssign(spans[6], spans[6]), ""); 147 static_assert(doAssign(spans[6], spans[7]), ""); 148 static_assert(doAssign(spans[6], spans[8]), ""); 149 static_assert(doAssign(spans[6], spans[9]), ""); 150 static_assert(doAssign(spans[6], spans[10]), ""); 151 static_assert(doAssign(spans[6], spans[11]), ""); 152 static_assert(doAssign(spans[6], spans[12]), ""); 153 154 static_assert(doAssign(spans[7], spans[7]), ""); 155 static_assert(doAssign(spans[7], spans[8]), ""); 156 static_assert(doAssign(spans[7], spans[9]), ""); 157 static_assert(doAssign(spans[7], spans[10]), ""); 158 static_assert(doAssign(spans[7], spans[11]), ""); 159 static_assert(doAssign(spans[7], spans[12]), ""); 160 161 static_assert(doAssign(spans[8], spans[8]), ""); 162 static_assert(doAssign(spans[8], spans[9]), ""); 163 static_assert(doAssign(spans[8], spans[10]), ""); 164 static_assert(doAssign(spans[8], spans[11]), ""); 165 static_assert(doAssign(spans[8], spans[12]), ""); 166 167 static_assert(doAssign(spans[9], spans[9]), ""); 168 static_assert(doAssign(spans[9], spans[10]), ""); 169 static_assert(doAssign(spans[9], spans[11]), ""); 170 static_assert(doAssign(spans[9], spans[12]), ""); 171 172 static_assert(doAssign(spans[10], spans[10]), ""); 173 static_assert(doAssign(spans[10], spans[11]), ""); 174 static_assert(doAssign(spans[10], spans[12]), ""); 175 176 static_assert(doAssign(spans[11], spans[11]), ""); 177 static_assert(doAssign(spans[11], spans[12]), ""); 178 179 static_assert(doAssign(spans[12], spans[12]), ""); 180 181 // for (size_t i = 0; i < std::size(spans); ++i) 182 // for (size_t j = i; j < std::size(spans); ++j) 183 // static_assert(doAssign(spans[i], spans[j]), ""); 184 } 185 186 // constexpr statically sized assignment 187 { 188 using spanType = std::span<const int,2>; 189 constexpr spanType spans[] = { 190 spanType{carr1, 2}, 191 spanType{carr1 + 1, 2}, 192 spanType{carr1 + 2, 2}, 193 spanType{carr2, 2}, 194 spanType{carr2 + 1, 2}, 195 spanType{carr3, 2} 196 }; 197 198 static_assert(std::size(spans) == 6, "" ); 199 200 // No for loops in constexpr land :-( 201 static_assert(doAssign(spans[0], spans[0]), ""); 202 static_assert(doAssign(spans[0], spans[1]), ""); 203 static_assert(doAssign(spans[0], spans[2]), ""); 204 static_assert(doAssign(spans[0], spans[3]), ""); 205 static_assert(doAssign(spans[0], spans[4]), ""); 206 static_assert(doAssign(spans[0], spans[5]), ""); 207 208 static_assert(doAssign(spans[1], spans[1]), ""); 209 static_assert(doAssign(spans[1], spans[2]), ""); 210 static_assert(doAssign(spans[1], spans[3]), ""); 211 static_assert(doAssign(spans[1], spans[4]), ""); 212 static_assert(doAssign(spans[1], spans[5]), ""); 213 214 static_assert(doAssign(spans[2], spans[2]), ""); 215 static_assert(doAssign(spans[2], spans[3]), ""); 216 static_assert(doAssign(spans[2], spans[4]), ""); 217 static_assert(doAssign(spans[2], spans[5]), ""); 218 219 static_assert(doAssign(spans[3], spans[3]), ""); 220 static_assert(doAssign(spans[3], spans[4]), ""); 221 static_assert(doAssign(spans[3], spans[5]), ""); 222 223 static_assert(doAssign(spans[4], spans[4]), ""); 224 static_assert(doAssign(spans[4], spans[5]), ""); 225 226 static_assert(doAssign(spans[5], spans[5]), ""); 227 228 // for (size_t i = 0; i < std::size(spans); ++i) 229 // for (size_t j = i; j < std::size(spans); ++j) 230 // static_assert(doAssign(spans[i], spans[j]), ""); 231 } 232 233 234 // dynamically sized assignment 235 { 236 std::span<int> spans[] = { 237 {}, 238 {arr, arr + 1}, 239 {arr, arr + 2}, 240 {arr, arr + 3}, 241 {arr + 1, arr + 3} // same size as s2 242 }; 243 244 for (size_t i = 0; i < std::size(spans); ++i) 245 for (size_t j = i; j < std::size(spans); ++j) 246 assert((doAssign(spans[i], spans[j]))); 247 } 248 249 // statically sized assignment 250 { 251 using spanType = std::span<int,2>; 252 spanType spans[] = { 253 spanType{arr, arr + 2}, 254 spanType{arr + 1, arr + 3}, 255 spanType{arr + 2, arr + 4} 256 }; 257 258 for (size_t i = 0; i < std::size(spans); ++i) 259 for (size_t j = i; j < std::size(spans); ++j) 260 assert((doAssign(spans[i], spans[j]))); 261 } 262 263 // dynamically sized assignment 264 { 265 std::span<std::string> spans[] = { 266 {strs, strs}, 267 {strs, strs + 1}, 268 {strs, strs + 2}, 269 {strs, strs + 3}, 270 {strs + 1, strs + 1}, 271 {strs + 1, strs + 2}, 272 {strs + 1, strs + 3}, 273 {strs + 2, strs + 2}, 274 {strs + 2, strs + 3}, 275 {strs + 3, strs + 3} 276 }; 277 278 for (size_t i = 0; i < std::size(spans); ++i) 279 for (size_t j = i; j < std::size(spans); ++j) 280 assert((doAssign(spans[i], spans[j]))); 281 } 282 283 { 284 using spanType = std::span<std::string, 1>; 285 spanType spans[] = { 286 spanType{strs, strs + 1}, 287 spanType{strs + 1, strs + 2}, 288 spanType{strs + 2, strs + 3} 289 }; 290 291 for (size_t i = 0; i < std::size(spans); ++i) 292 for (size_t j = i; j < std::size(spans); ++j) 293 assert((doAssign(spans[i], spans[j]))); 294 } 295 296 return 0; 297 } 298