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