1/////////////////////////////////////////////////////////////////////////////// 2// 3// Copyright (c) 2015 Microsoft Corporation. All rights reserved. 4// 5// This code is licensed under the MIT License (MIT). 6// 7// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 8// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 9// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 10// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 11// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 12// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 13// THE SOFTWARE. 14// 15/////////////////////////////////////////////////////////////////////////////// 16 17#include <catch/catch.hpp> 18 19#include <gsl/span> 20 21#include <iostream> 22#include <list> 23#include <map> 24#include <memory> 25#include <regex> 26#include <string> 27#include <vector> 28 29using namespace std; 30using namespace gsl; 31 32namespace 33{ 34struct BaseClass 35{ 36}; 37struct DerivedClass : BaseClass 38{ 39}; 40} 41 42TEST_CASE("default_constructor") 43{ 44 { 45 span<int> s; 46 CHECK((s.length() == 0 && s.data() == nullptr)); 47 48 span<const int> cs; 49 CHECK((cs.length() == 0 && cs.data() == nullptr)); 50 } 51 52 { 53 span<int, 0> s; 54 CHECK((s.length() == 0 && s.data() == nullptr)); 55 56 span<const int, 0> cs; 57 CHECK((cs.length() == 0 && cs.data() == nullptr)); 58 } 59 60 { 61#ifdef CONFIRM_COMPILATION_ERRORS 62 span<int, 1> s; 63 CHECK((s.length() == 1 && s.data() == nullptr)); // explains why it can't compile 64#endif 65 } 66 67 { 68 span<int> s{}; 69 CHECK((s.length() == 0 && s.data() == nullptr)); 70 71 span<const int> cs{}; 72 CHECK((cs.length() == 0 && cs.data() == nullptr)); 73 } 74} 75 76TEST_CASE("size_optimization") 77{ 78 { 79 span<int> s; 80 CHECK(sizeof(s) == sizeof(int*) + sizeof(ptrdiff_t)); 81 } 82 83 { 84 span<int, 0> s; 85 CHECK(sizeof(s) == sizeof(int*)); 86 } 87} 88 89TEST_CASE("from_nullptr_constructor") 90{ 91 { 92 span<int> s = nullptr; 93 CHECK((s.length() == 0 && s.data() == nullptr)); 94 95 span<const int> cs = nullptr; 96 CHECK((cs.length() == 0 && cs.data() == nullptr)); 97 } 98 99 { 100 span<int, 0> s = nullptr; 101 CHECK((s.length() == 0 && s.data() == nullptr)); 102 103 span<const int, 0> cs = nullptr; 104 CHECK((cs.length() == 0 && cs.data() == nullptr)); 105 } 106 107 { 108#ifdef CONFIRM_COMPILATION_ERRORS 109 span<int, 1> s = nullptr; 110 CHECK((s.length() == 1 && s.data() == nullptr)); // explains why it can't compile 111#endif 112 } 113 114 { 115 span<int> s{nullptr}; 116 CHECK((s.length() == 0 && s.data() == nullptr)); 117 118 span<const int> cs{nullptr}; 119 CHECK((cs.length() == 0 && cs.data() == nullptr)); 120 } 121 122 { 123 span<int*> s{nullptr}; 124 CHECK((s.length() == 0 && s.data() == nullptr)); 125 126 span<const int*> cs{nullptr}; 127 CHECK((cs.length() == 0 && cs.data() == nullptr)); 128 } 129} 130 131TEST_CASE("from_nullptr_length_constructor") 132{ 133 { 134 span<int> s{nullptr, static_cast<span<int>::index_type>(0)}; 135 CHECK((s.length() == 0 && s.data() == nullptr)); 136 137 span<const int> cs{nullptr, static_cast<span<int>::index_type>(0)}; 138 CHECK((cs.length() == 0 && cs.data() == nullptr)); 139 } 140 141 { 142 span<int, 0> s{nullptr, static_cast<span<int>::index_type>(0)}; 143 CHECK((s.length() == 0 && s.data() == nullptr)); 144 145 span<const int, 0> cs{nullptr, static_cast<span<int>::index_type>(0)}; 146 CHECK((cs.length() == 0 && cs.data() == nullptr)); 147 } 148 149 { 150 auto workaround_macro = []() { 151 span<int, 1> s{nullptr, static_cast<span<int>::index_type>(0)}; 152 }; 153 CHECK_THROWS_AS(workaround_macro(), fail_fast); 154 } 155 156 { 157 auto workaround_macro = []() { span<int> s{nullptr, 1}; }; 158 CHECK_THROWS_AS(workaround_macro(), fail_fast); 159 160 auto const_workaround_macro = []() { span<const int> cs{nullptr, 1}; }; 161 CHECK_THROWS_AS(const_workaround_macro(), fail_fast); 162 } 163 164 { 165 auto workaround_macro = []() { span<int, 0> s{nullptr, 1}; }; 166 CHECK_THROWS_AS(workaround_macro(), fail_fast); 167 168 auto const_workaround_macro = []() { span<const int, 0> s{nullptr, 1}; }; 169 CHECK_THROWS_AS(const_workaround_macro(), fail_fast); 170 } 171 172 { 173 span<int*> s{nullptr, static_cast<span<int>::index_type>(0)}; 174 CHECK((s.length() == 0 && s.data() == nullptr)); 175 176 span<const int*> cs{nullptr, static_cast<span<int>::index_type>(0)}; 177 CHECK((cs.length() == 0 && cs.data() == nullptr)); 178 } 179} 180 181TEST_CASE("from_pointer_length_constructor") 182{ 183 int arr[4] = {1, 2, 3, 4}; 184 185 { 186 span<int> s{&arr[0], 2}; 187 CHECK((s.length() == 2 && s.data() == &arr[0])); 188 CHECK((s[0] == 1 && s[1] == 2)); 189 } 190 191 { 192 span<int, 2> s{&arr[0], 2}; 193 CHECK((s.length() == 2 && s.data() == &arr[0])); 194 CHECK((s[0] == 1 && s[1] == 2)); 195 } 196 197 { 198 int* p = nullptr; 199 span<int> s{p, static_cast<span<int>::index_type>(0)}; 200 CHECK((s.length() == 0 && s.data() == nullptr)); 201 } 202 203 { 204 int* p = nullptr; 205 auto workaround_macro = [=]() { span<int> s{p, 2}; }; 206 CHECK_THROWS_AS(workaround_macro(), fail_fast); 207 } 208 209 { 210 auto s = make_span(&arr[0], 2); 211 CHECK((s.length() == 2 && s.data() == &arr[0])); 212 CHECK((s[0] == 1 && s[1] == 2)); 213 } 214 215 { 216 int* p = nullptr; 217 auto s = make_span(p, static_cast<span<int>::index_type>(0)); 218 CHECK((s.length() == 0 && s.data() == nullptr)); 219 } 220 221 { 222 int* p = nullptr; 223 auto workaround_macro = [=]() { make_span(p, 2); }; 224 CHECK_THROWS_AS(workaround_macro(), fail_fast); 225 } 226} 227 228TEST_CASE("from_pointer_pointer_constructor") 229{ 230 int arr[4] = {1, 2, 3, 4}; 231 232 { 233 span<int> s{&arr[0], &arr[2]}; 234 CHECK((s.length() == 2 && s.data() == &arr[0])); 235 CHECK((s[0] == 1 && s[1] == 2)); 236 } 237 238 { 239 span<int, 2> s{&arr[0], &arr[2]}; 240 CHECK((s.length() == 2 && s.data() == &arr[0])); 241 CHECK((s[0] == 1 && s[1] == 2)); 242 } 243 244 { 245 span<int> s{&arr[0], &arr[0]}; 246 CHECK((s.length() == 0 && s.data() == &arr[0])); 247 } 248 249 { 250 span<int, 0> s{&arr[0], &arr[0]}; 251 CHECK((s.length() == 0 && s.data() == &arr[0])); 252 } 253 254 // this will fail the std::distance() precondition, which asserts on MSVC debug builds 255 //{ 256 // auto workaround_macro = [&]() { span<int> s{&arr[1], &arr[0]}; }; 257 // CHECK_THROWS_AS(workaround_macro(), fail_fast); 258 //} 259 260 // this will fail the std::distance() precondition, which asserts on MSVC debug builds 261 //{ 262 // int* p = nullptr; 263 // auto workaround_macro = [&]() { span<int> s{&arr[0], p}; }; 264 // CHECK_THROWS_AS(workaround_macro(), fail_fast); 265 //} 266 267 { 268 int* p = nullptr; 269 span<int> s{p, p}; 270 CHECK((s.length() == 0 && s.data() == nullptr)); 271 } 272 273 { 274 int* p = nullptr; 275 span<int, 0> s{p, p}; 276 CHECK((s.length() == 0 && s.data() == nullptr)); 277 } 278 279 // this will fail the std::distance() precondition, which asserts on MSVC debug builds 280 //{ 281 // int* p = nullptr; 282 // auto workaround_macro = [&]() { span<int> s{&arr[0], p}; }; 283 // CHECK_THROWS_AS(workaround_macro(), fail_fast); 284 //} 285 286 { 287 auto s = make_span(&arr[0], &arr[2]); 288 CHECK((s.length() == 2 && s.data() == &arr[0])); 289 CHECK((s[0] == 1 && s[1] == 2)); 290 } 291 292 { 293 auto s = make_span(&arr[0], &arr[0]); 294 CHECK((s.length() == 0 && s.data() == &arr[0])); 295 } 296 297 { 298 int* p = nullptr; 299 auto s = make_span(p, p); 300 CHECK((s.length() == 0 && s.data() == nullptr)); 301 } 302} 303 304TEST_CASE("from_array_constructor") 305{ 306 int arr[5] = {1, 2, 3, 4, 5}; 307 308 { 309 span<int> s{arr}; 310 CHECK((s.length() == 5 && s.data() == &arr[0])); 311 } 312 313 { 314 span<int, 5> s{arr}; 315 CHECK((s.length() == 5 && s.data() == &arr[0])); 316 } 317 318 int arr2d[2][3] = {1, 2, 3, 4, 5, 6}; 319 320#ifdef CONFIRM_COMPILATION_ERRORS 321 { 322 span<int, 6> s{arr}; 323 } 324 325 { 326 span<int, 0> s{arr}; 327 CHECK((s.length() == 0 && s.data() == &arr[0])); 328 } 329 330 { 331 span<int> s{arr2d}; 332 CHECK((s.length() == 6 && s.data() == &arr2d[0][0])); 333 CHECK((s[0] == 1 && s[5] == 6)); 334 } 335 336 { 337 span<int, 0> s{arr2d}; 338 CHECK((s.length() == 0 && s.data() == &arr2d[0][0])); 339 } 340 341 { 342 span<int, 6> s{arr2d}; 343 } 344#endif 345 { 346 span<int[3]> s{&(arr2d[0]), 1}; 347 CHECK((s.length() == 1 && s.data() == &arr2d[0])); 348 } 349 350 int arr3d[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; 351 352#ifdef CONFIRM_COMPILATION_ERRORS 353 { 354 span<int> s{arr3d}; 355 CHECK((s.length() == 12 && s.data() == &arr3d[0][0][0])); 356 CHECK((s[0] == 1 && s[11] == 12)); 357 } 358 359 { 360 span<int, 0> s{arr3d}; 361 CHECK((s.length() == 0 && s.data() == &arr3d[0][0][0])); 362 } 363 364 { 365 span<int, 11> s{arr3d}; 366 } 367 368 { 369 span<int, 12> s{arr3d}; 370 CHECK((s.length() == 12 && s.data() == &arr3d[0][0][0])); 371 CHECK((s[0] == 1 && s[5] == 6)); 372 } 373#endif 374 { 375 span<int[3][2]> s{&arr3d[0], 1}; 376 CHECK((s.length() == 1 && s.data() == &arr3d[0])); 377 } 378 379 { 380 auto s = make_span(arr); 381 CHECK((s.length() == 5 && s.data() == &arr[0])); 382 } 383 384 { 385 auto s = make_span(&(arr2d[0]), 1); 386 CHECK((s.length() == 1 && s.data() == &arr2d[0])); 387 } 388 389 { 390 auto s = make_span(&arr3d[0], 1); 391 CHECK((s.length() == 1 && s.data() == &arr3d[0])); 392 } 393} 394 395TEST_CASE("from_dynamic_array_constructor") 396{ 397 double(*arr)[3][4] = new double[100][3][4]; 398 399 { 400 span<double> s(&arr[0][0][0], 10); 401 CHECK((s.length() == 10 && s.data() == &arr[0][0][0])); 402 } 403 404 { 405 auto s = make_span(&arr[0][0][0], 10); 406 CHECK((s.length() == 10 && s.data() == &arr[0][0][0])); 407 } 408 409 delete[] arr; 410} 411 412TEST_CASE("from_std_array_constructor") 413{ 414 std::array<int, 4> arr = {1, 2, 3, 4}; 415 416 { 417 span<int> s{arr}; 418 CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); 419 420 span<const int> cs{arr}; 421 CHECK((cs.size() == narrow_cast<ptrdiff_t>(arr.size()) && cs.data() == arr.data())); 422 } 423 424 { 425 span<int, 4> s{arr}; 426 CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); 427 428 span<const int, 4> cs{arr}; 429 CHECK((cs.size() == narrow_cast<ptrdiff_t>(arr.size()) && cs.data() == arr.data())); 430 } 431 432#ifdef CONFIRM_COMPILATION_ERRORS 433 { 434 span<int, 2> s{arr}; 435 CHECK((s.size() == 2 && s.data() == arr.data())); 436 437 span<const int, 2> cs{arr}; 438 CHECK((cs.size() == 2 && cs.data() == arr.data())); 439 } 440 441 { 442 span<int, 0> s{arr}; 443 CHECK((s.size() == 0 && s.data() == arr.data())); 444 445 span<const int, 0> cs{arr}; 446 CHECK((cs.size() == 0 && cs.data() == arr.data())); 447 } 448 449 { 450 span<int, 5> s{arr}; 451 } 452 453 { 454 auto get_an_array = []() -> std::array<int, 4> { return {1, 2, 3, 4}; }; 455 auto take_a_span = [](span<int> s) { static_cast<void>(s); }; 456 // try to take a temporary std::array 457 take_a_span(get_an_array()); 458 } 459#endif 460 461 { 462 auto get_an_array = []() -> std::array<int, 4> { return {1, 2, 3, 4}; }; 463 auto take_a_span = [](span<const int> s) { static_cast<void>(s); }; 464 // try to take a temporary std::array 465 take_a_span(get_an_array()); 466 } 467 468 { 469 auto s = make_span(arr); 470 CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); 471 } 472} 473 474TEST_CASE("from_const_std_array_constructor") 475{ 476 const std::array<int, 4> arr = {1, 2, 3, 4}; 477 478 { 479 span<const int> s{arr}; 480 CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); 481 } 482 483 { 484 span<const int, 4> s{arr}; 485 CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); 486 } 487 488#ifdef CONFIRM_COMPILATION_ERRORS 489 { 490 span<const int, 2> s{arr}; 491 CHECK((s.size() == 2 && s.data() == arr.data())); 492 } 493 494 { 495 span<const int, 0> s{arr}; 496 CHECK((s.size() == 0 && s.data() == arr.data())); 497 } 498 499 { 500 span<const int, 5> s{arr}; 501 } 502#endif 503 504 { 505 auto get_an_array = []() -> const std::array<int, 4> { return {1, 2, 3, 4}; }; 506 auto take_a_span = [](span<const int> s) { static_cast<void>(s); }; 507 // try to take a temporary std::array 508 take_a_span(get_an_array()); 509 } 510 511 { 512 auto s = make_span(arr); 513 CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); 514 } 515} 516 517TEST_CASE("from_std_array_const_constructor") 518{ 519 std::array<const int, 4> arr = {1, 2, 3, 4}; 520 521 { 522 span<const int> s{arr}; 523 CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); 524 } 525 526 { 527 span<const int, 4> s{arr}; 528 CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); 529 } 530 531#ifdef CONFIRM_COMPILATION_ERRORS 532 { 533 span<const int, 2> s{arr}; 534 CHECK((s.size() == 2 && s.data() == arr.data())); 535 } 536 537 { 538 span<const int, 0> s{arr}; 539 CHECK((s.size() == 0 && s.data() == arr.data())); 540 } 541 542 { 543 span<const int, 5> s{arr}; 544 } 545 546 { 547 span<int, 4> s{arr}; 548 } 549#endif 550 551 { 552 auto s = make_span(arr); 553 CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); 554 } 555} 556 557TEST_CASE("from_unique_pointer_construction") 558{ 559 { 560 auto ptr = std::make_unique<int>(4); 561 562 { 563 span<int> s{ptr}; 564 CHECK((s.length() == 1 && s.data() == ptr.get())); 565 CHECK(s[0] == 4); 566 } 567 568 { 569 auto s = make_span(ptr); 570 CHECK((s.length() == 1 && s.data() == ptr.get())); 571 CHECK(s[0] == 4); 572 } 573 } 574 575 { 576 auto ptr = std::unique_ptr<int>{nullptr}; 577 578 { 579 span<int> s{ptr}; 580 CHECK((s.length() == 0 && s.data() == nullptr)); 581 } 582 583 { 584 auto s = make_span(ptr); 585 CHECK((s.length() == 0 && s.data() == nullptr)); 586 } 587 } 588 589 { 590 auto arr = std::make_unique<int[]>(4); 591 592 for (auto i = 0U; i < 4; i++) arr[i] = gsl::narrow_cast<int>(i + 1); 593 594 { 595 span<int> s{arr, 4}; 596 CHECK((s.length() == 4 && s.data() == arr.get())); 597 CHECK((s[0] == 1 && s[1] == 2)); 598 } 599 600 { 601 auto s = make_span(arr, 4); 602 CHECK((s.length() == 4 && s.data() == arr.get())); 603 CHECK((s[0] == 1 && s[1] == 2)); 604 } 605 } 606 607 { 608 auto arr = std::unique_ptr<int[]>{nullptr}; 609 610 { 611 span<int> s{arr, 0}; 612 CHECK((s.length() == 0 && s.data() == nullptr)); 613 } 614 615 { 616 auto s = make_span(arr, 0); 617 CHECK((s.length() == 0 && s.data() == nullptr)); 618 } 619 } 620} 621 622TEST_CASE("from_shared_pointer_construction") 623{ 624 { 625 auto ptr = std::make_shared<int>(4); 626 627 { 628 span<int> s{ptr}; 629 CHECK((s.length() == 1 && s.data() == ptr.get())); 630 CHECK((s[0] == 4)); 631 } 632 633 { 634 auto s = make_span(ptr); 635 CHECK((s.length() == 1 && s.data() == ptr.get())); 636 CHECK((s[0] == 4)); 637 } 638 } 639 640 { 641 auto ptr = std::shared_ptr<int>{nullptr}; 642 643 { 644 span<int> s{ptr}; 645 CHECK((s.length() == 0 && s.data() == nullptr)); 646 } 647 648 { 649 auto s = make_span(ptr); 650 CHECK((s.length() == 0 && s.data() == nullptr)); 651 } 652 } 653} 654 655TEST_CASE("from_container_constructor") 656{ 657 std::vector<int> v = {1, 2, 3}; 658 const std::vector<int> cv = v; 659 660 { 661 span<int> s{v}; 662 CHECK((s.size() == narrow_cast<std::ptrdiff_t>(v.size()) && s.data() == v.data())); 663 664 span<const int> cs{v}; 665 CHECK((cs.size() == narrow_cast<std::ptrdiff_t>(v.size()) && cs.data() == v.data())); 666 } 667 668 std::string str = "hello"; 669 const std::string cstr = "hello"; 670 671 { 672#ifdef CONFIRM_COMPILATION_ERRORS 673 span<char> s{str}; 674 CHECK((s.size() == narrow_cast<std::ptrdiff_t>(str.size()) && s.data() == str.data())); 675#endif 676 span<const char> cs{str}; 677 CHECK((cs.size() == narrow_cast<std::ptrdiff_t>(str.size()) && cs.data() == str.data())); 678 } 679 680 { 681#ifdef CONFIRM_COMPILATION_ERRORS 682 span<char> s{cstr}; 683#endif 684 span<const char> cs{cstr}; 685 CHECK((cs.size() == narrow_cast<std::ptrdiff_t>(cstr.size()) && 686 cs.data() == cstr.data())); 687 } 688 689 { 690#ifdef CONFIRM_COMPILATION_ERRORS 691 auto get_temp_vector = []() -> std::vector<int> { return {}; }; 692 auto use_span = [](span<int> s) { static_cast<void>(s); }; 693 use_span(get_temp_vector()); 694#endif 695 } 696 697 { 698 auto get_temp_vector = []() -> std::vector<int> { return {}; }; 699 auto use_span = [](span<const int> s) { static_cast<void>(s); }; 700 use_span(get_temp_vector()); 701 } 702 703 { 704#ifdef CONFIRM_COMPILATION_ERRORS 705 auto get_temp_string = []() -> std::string { return {}; }; 706 auto use_span = [](span<char> s) { static_cast<void>(s); }; 707 use_span(get_temp_string()); 708#endif 709 } 710 711 { 712 auto get_temp_string = []() -> std::string { return {}; }; 713 auto use_span = [](span<const char> s) { static_cast<void>(s); }; 714 use_span(get_temp_string()); 715 } 716 717 { 718#ifdef CONFIRM_COMPILATION_ERRORS 719 auto get_temp_vector = []() -> const std::vector<int> { return {}; }; 720 auto use_span = [](span<const char> s) { static_cast<void>(s); }; 721 use_span(get_temp_vector()); 722#endif 723 } 724 725 { 726 auto get_temp_string = []() -> const std::string { return {}; }; 727 auto use_span = [](span<const char> s) { static_cast<void>(s); }; 728 use_span(get_temp_string()); 729 } 730 731 { 732#ifdef CONFIRM_COMPILATION_ERRORS 733 std::map<int, int> m; 734 span<int> s{m}; 735#endif 736 } 737 738 { 739 auto s = make_span(v); 740 CHECK((s.size() == narrow_cast<std::ptrdiff_t>(v.size()) && s.data() == v.data())); 741 742 auto cs = make_span(cv); 743 CHECK((cs.size() == narrow_cast<std::ptrdiff_t>(cv.size()) && cs.data() == cv.data())); 744 } 745} 746 747TEST_CASE("from_convertible_span_constructor") 748{ 749 { 750 span<DerivedClass> avd; 751 span<const DerivedClass> avcd = avd; 752 static_cast<void>(avcd); 753 } 754 755 { 756 #ifdef CONFIRM_COMPILATION_ERRORS 757 span<DerivedClass> avd; 758 span<BaseClass> avb = avd; 759 static_cast<void>(avb); 760 #endif 761 } 762 763 #ifdef CONFIRM_COMPILATION_ERRORS 764 { 765 span<int> s; 766 span<unsigned int> s2 = s; 767 static_cast<void>(s2); 768 } 769 770 { 771 span<int> s; 772 span<const unsigned int> s2 = s; 773 static_cast<void>(s2); 774 } 775 776 { 777 span<int> s; 778 span<short> s2 = s; 779 static_cast<void>(s2); 780 } 781 #endif 782} 783 784TEST_CASE("copy_move_and_assignment") 785{ 786 span<int> s1; 787 CHECK(s1.empty()); 788 789 int arr[] = {3, 4, 5}; 790 791 span<const int> s2 = arr; 792 CHECK((s2.length() == 3 && s2.data() == &arr[0])); 793 794 s2 = s1; 795 CHECK(s2.empty()); 796 797 auto get_temp_span = [&]() -> span<int> { return {&arr[1], 2}; }; 798 auto use_span = [&](span<const int> s) { CHECK((s.length() == 2 && s.data() == &arr[1])); }; 799 use_span(get_temp_span()); 800 801 s1 = get_temp_span(); 802 CHECK((s1.length() == 2 && s1.data() == &arr[1])); 803} 804 805TEST_CASE("first") 806{ 807 int arr[5] = {1, 2, 3, 4, 5}; 808 809 { 810 span<int, 5> av = arr; 811 CHECK(av.first<2>().length() == 2); 812 CHECK(av.first(2).length() == 2); 813 } 814 815 { 816 span<int, 5> av = arr; 817 CHECK(av.first<0>().length() == 0); 818 CHECK(av.first(0).length() == 0); 819 } 820 821 { 822 span<int, 5> av = arr; 823 CHECK(av.first<5>().length() == 5); 824 CHECK(av.first(5).length() == 5); 825 } 826 827 { 828 span<int, 5> av = arr; 829#ifdef CONFIRM_COMPILATION_ERRORS 830 CHECK(av.first<6>().length() == 6); 831 CHECK(av.first<-1>().length() == -1); 832#endif 833 CHECK_THROWS_AS(av.first(6).length(), fail_fast); 834 } 835 836 { 837 span<int> av; 838 CHECK(av.first<0>().length() == 0); 839 CHECK(av.first(0).length() == 0); 840 } 841} 842 843TEST_CASE("last") 844{ 845 int arr[5] = {1, 2, 3, 4, 5}; 846 847 { 848 span<int, 5> av = arr; 849 CHECK(av.last<2>().length() == 2); 850 CHECK(av.last(2).length() == 2); 851 } 852 853 { 854 span<int, 5> av = arr; 855 CHECK(av.last<0>().length() == 0); 856 CHECK(av.last(0).length() == 0); 857 } 858 859 { 860 span<int, 5> av = arr; 861 CHECK(av.last<5>().length() == 5); 862 CHECK(av.last(5).length() == 5); 863 } 864 865 { 866 span<int, 5> av = arr; 867#ifdef CONFIRM_COMPILATION_ERRORS 868 CHECK(av.last<6>().length() == 6); 869#endif 870 CHECK_THROWS_AS(av.last(6).length(), fail_fast); 871 } 872 873 { 874 span<int> av; 875 CHECK(av.last<0>().length() == 0); 876 CHECK(av.last(0).length() == 0); 877 } 878} 879 880TEST_CASE("subspan") 881{ 882 int arr[5] = {1, 2, 3, 4, 5}; 883 884 { 885 span<int, 5> av = arr; 886 CHECK((av.subspan<2, 2>().length() == 2)); 887 CHECK(av.subspan(2, 2).length() == 2); 888 CHECK(av.subspan(2, 3).length() == 3); 889 } 890 891 { 892 span<int, 5> av = arr; 893 CHECK((av.subspan<0, 0>().length() == 0)); 894 CHECK(av.subspan(0, 0).length() == 0); 895 } 896 897 { 898 span<int, 5> av = arr; 899 CHECK((av.subspan<0, 5>().length() == 5)); 900 CHECK(av.subspan(0, 5).length() == 5); 901 CHECK_THROWS_AS(av.subspan(0, 6).length(), fail_fast); 902 CHECK_THROWS_AS(av.subspan(1, 5).length(), fail_fast); 903 } 904 905 { 906 span<int, 5> av = arr; 907 CHECK((av.subspan<4, 0>().length() == 0)); 908 CHECK(av.subspan(4, 0).length() == 0); 909 CHECK(av.subspan(5, 0).length() == 0); 910 CHECK_THROWS_AS(av.subspan(6, 0).length(), fail_fast); 911 } 912 913 { 914 span<int> av; 915 CHECK((av.subspan<0, 0>().length() == 0)); 916 CHECK(av.subspan(0, 0).length() == 0); 917 CHECK_THROWS_AS((av.subspan<1, 0>().length()), fail_fast); 918 } 919 920 { 921 span<int> av; 922 CHECK(av.subspan(0).length() == 0); 923 CHECK_THROWS_AS(av.subspan(1).length(), fail_fast); 924 } 925 926 { 927 span<int> av = arr; 928 CHECK(av.subspan(0).length() == 5); 929 CHECK(av.subspan(1).length() == 4); 930 CHECK(av.subspan(4).length() == 1); 931 CHECK(av.subspan(5).length() == 0); 932 CHECK_THROWS_AS(av.subspan(6).length(), fail_fast); 933 const auto av2 = av.subspan(1); 934 for (int i = 0; i < 4; ++i) CHECK(av2[i] == i + 2); 935 } 936 937 { 938 span<int, 5> av = arr; 939 CHECK(av.subspan(0).length() == 5); 940 CHECK(av.subspan(1).length() == 4); 941 CHECK(av.subspan(4).length() == 1); 942 CHECK(av.subspan(5).length() == 0); 943 CHECK_THROWS_AS(av.subspan(6).length(), fail_fast); 944 const auto av2 = av.subspan(1); 945 for (int i = 0; i < 4; ++i) CHECK(av2[i] == i + 2); 946 } 947} 948 949TEST_CASE("at_call") 950{ 951 int arr[4] = {1, 2, 3, 4}; 952 953 { 954 span<int> s = arr; 955 CHECK(s.at(0) == 1); 956 CHECK_THROWS_AS(s.at(5), fail_fast); 957 } 958 959 { 960 int arr2d[2] = {1, 6}; 961 span<int, 2> s = arr2d; 962 CHECK(s.at(0) == 1); 963 CHECK(s.at(1) == 6); 964 CHECK_THROWS_AS(s.at(2), fail_fast); 965 } 966} 967 968TEST_CASE("operator_function_call") 969{ 970 int arr[4] = {1, 2, 3, 4}; 971 972 { 973 span<int> s = arr; 974 CHECK(s(0) == 1); 975 CHECK_THROWS_AS(s(5), fail_fast); 976 } 977 978 { 979 int arr2d[2] = {1, 6}; 980 span<int, 2> s = arr2d; 981 CHECK(s(0) == 1); 982 CHECK(s(1) == 6); 983 CHECK_THROWS_AS(s(2), fail_fast); 984 } 985} 986 987TEST_CASE("iterator_default_init") 988{ 989 span<int>::iterator it1; 990 span<int>::iterator it2; 991 CHECK(it1 == it2); 992} 993 994TEST_CASE("const_iterator_default_init") 995{ 996 span<int>::const_iterator it1; 997 span<int>::const_iterator it2; 998 CHECK(it1 == it2); 999} 1000 1001TEST_CASE("iterator_conversions") 1002{ 1003 span<int>::iterator badIt; 1004 span<int>::const_iterator badConstIt; 1005 CHECK(badIt == badConstIt); 1006 1007 int a[] = {1, 2, 3, 4}; 1008 span<int> s = a; 1009 1010 auto it = s.begin(); 1011 auto cit = s.cbegin(); 1012 1013 CHECK(it == cit); 1014 CHECK(cit == it); 1015 1016 span<int>::const_iterator cit2 = it; 1017 CHECK(cit2 == cit); 1018 1019 span<int>::const_iterator cit3 = it + 4; 1020 CHECK(cit3 == s.cend()); 1021} 1022 1023TEST_CASE("iterator_comparisons") 1024{ 1025 int a[] = {1, 2, 3, 4}; 1026 { 1027 span<int> s = a; 1028 span<int>::iterator it = s.begin(); 1029 auto it2 = it + 1; 1030 span<int>::const_iterator cit = s.cbegin(); 1031 1032 CHECK(it == cit); 1033 CHECK(cit == it); 1034 CHECK(it == it); 1035 CHECK(cit == cit); 1036 CHECK(cit == s.begin()); 1037 CHECK(s.begin() == cit); 1038 CHECK(s.cbegin() == cit); 1039 CHECK(it == s.begin()); 1040 CHECK(s.begin() == it); 1041 1042 CHECK(it != it2); 1043 CHECK(it2 != it); 1044 CHECK(it != s.end()); 1045 CHECK(it2 != s.end()); 1046 CHECK(s.end() != it); 1047 CHECK(it2 != cit); 1048 CHECK(cit != it2); 1049 1050 CHECK(it < it2); 1051 CHECK(it <= it2); 1052 CHECK(it2 <= s.end()); 1053 CHECK(it < s.end()); 1054 CHECK(it <= cit); 1055 CHECK(cit <= it); 1056 CHECK(cit < it2); 1057 CHECK(cit <= it2); 1058 CHECK(cit < s.end()); 1059 CHECK(cit <= s.end()); 1060 1061 CHECK(it2 > it); 1062 CHECK(it2 >= it); 1063 CHECK(s.end() > it2); 1064 CHECK(s.end() >= it2); 1065 CHECK(it2 > cit); 1066 CHECK(it2 >= cit); 1067 } 1068} 1069 1070TEST_CASE("begin_end") 1071{ 1072 { 1073 int a[] = {1, 2, 3, 4}; 1074 span<int> s = a; 1075 1076 span<int>::iterator it = s.begin(); 1077 span<int>::iterator it2 = std::begin(s); 1078 CHECK(it == it2); 1079 1080 it = s.end(); 1081 it2 = std::end(s); 1082 CHECK(it == it2); 1083 } 1084 1085 { 1086 int a[] = {1, 2, 3, 4}; 1087 span<int> s = a; 1088 1089 auto it = s.begin(); 1090 auto first = it; 1091 CHECK(it == first); 1092 CHECK(*it == 1); 1093 1094 auto beyond = s.end(); 1095 CHECK(it != beyond); 1096 CHECK_THROWS_AS(*beyond, fail_fast); 1097 1098 CHECK(beyond - first == 4); 1099 CHECK(first - first == 0); 1100 CHECK(beyond - beyond == 0); 1101 1102 ++it; 1103 CHECK(it - first == 1); 1104 CHECK(*it == 2); 1105 *it = 22; 1106 CHECK(*it == 22); 1107 CHECK(beyond - it == 3); 1108 1109 it = first; 1110 CHECK(it == first); 1111 while (it != s.end()) { 1112 *it = 5; 1113 ++it; 1114 } 1115 1116 CHECK(it == beyond); 1117 CHECK(it - beyond == 0); 1118 1119 for (const auto& n : s) { 1120 CHECK(n == 5); 1121 } 1122 } 1123} 1124 1125TEST_CASE("cbegin_cend") 1126{ 1127 { 1128 int a[] = {1, 2, 3, 4}; 1129 span<int> s = a; 1130 1131 span<int>::const_iterator cit = s.cbegin(); 1132 span<int>::const_iterator cit2 = std::cbegin(s); 1133 CHECK(cit == cit2); 1134 1135 cit = s.cend(); 1136 cit2 = std::cend(s); 1137 CHECK(cit == cit2); 1138 } 1139 1140 { 1141 int a[] = {1, 2, 3, 4}; 1142 span<int> s = a; 1143 1144 auto it = s.cbegin(); 1145 auto first = it; 1146 CHECK(it == first); 1147 CHECK(*it == 1); 1148 1149 auto beyond = s.cend(); 1150 CHECK(it != beyond); 1151 CHECK_THROWS_AS(*beyond, fail_fast); 1152 1153 CHECK(beyond - first == 4); 1154 CHECK(first - first == 0); 1155 CHECK(beyond - beyond == 0); 1156 1157 ++it; 1158 CHECK(it - first == 1); 1159 CHECK(*it == 2); 1160 CHECK(beyond - it == 3); 1161 1162 int last = 0; 1163 it = first; 1164 CHECK(it == first); 1165 while (it != s.cend()) { 1166 CHECK(*it == last + 1); 1167 1168 last = *it; 1169 ++it; 1170 } 1171 1172 CHECK(it == beyond); 1173 CHECK(it - beyond == 0); 1174 } 1175} 1176 1177TEST_CASE("rbegin_rend") 1178{ 1179 { 1180 int a[] = {1, 2, 3, 4}; 1181 span<int> s = a; 1182 1183 auto it = s.rbegin(); 1184 auto first = it; 1185 CHECK(it == first); 1186 CHECK(*it == 4); 1187 1188 auto beyond = s.rend(); 1189 CHECK(it != beyond); 1190 CHECK_THROWS_AS(*beyond, fail_fast); 1191 1192 CHECK(beyond - first == 4); 1193 CHECK(first - first == 0); 1194 CHECK(beyond - beyond == 0); 1195 1196 ++it; 1197 CHECK(it - first == 1); 1198 CHECK(*it == 3); 1199 *it = 22; 1200 CHECK(*it == 22); 1201 CHECK(beyond - it == 3); 1202 1203 it = first; 1204 CHECK(it == first); 1205 while (it != s.rend()) { 1206 *it = 5; 1207 ++it; 1208 } 1209 1210 CHECK(it == beyond); 1211 CHECK(it - beyond == 0); 1212 1213 for (const auto& n : s) { 1214 CHECK(n == 5); 1215 } 1216 } 1217} 1218 1219TEST_CASE("crbegin_crend") 1220{ 1221 { 1222 int a[] = {1, 2, 3, 4}; 1223 span<int> s = a; 1224 1225 auto it = s.crbegin(); 1226 auto first = it; 1227 CHECK(it == first); 1228 CHECK(*it == 4); 1229 1230 auto beyond = s.crend(); 1231 CHECK(it != beyond); 1232 CHECK_THROWS_AS(*beyond, fail_fast); 1233 1234 CHECK(beyond - first == 4); 1235 CHECK(first - first == 0); 1236 CHECK(beyond - beyond == 0); 1237 1238 ++it; 1239 CHECK(it - first == 1); 1240 CHECK(*it == 3); 1241 CHECK(beyond - it == 3); 1242 1243 it = first; 1244 CHECK(it == first); 1245 int last = 5; 1246 while (it != s.crend()) { 1247 CHECK(*it == last - 1); 1248 last = *it; 1249 1250 ++it; 1251 } 1252 1253 CHECK(it == beyond); 1254 CHECK(it - beyond == 0); 1255 } 1256} 1257 1258TEST_CASE("comparison_operators") 1259{ 1260 { 1261 span<int> s1 = nullptr; 1262 span<int> s2 = nullptr; 1263 CHECK(s1 == s2); 1264 CHECK(!(s1 != s2)); 1265 CHECK(!(s1 < s2)); 1266 CHECK(s1 <= s2); 1267 CHECK(!(s1 > s2)); 1268 CHECK(s1 >= s2); 1269 CHECK(s2 == s1); 1270 CHECK(!(s2 != s1)); 1271 CHECK(!(s2 < s1)); 1272 CHECK(s2 <= s1); 1273 CHECK(!(s2 > s1)); 1274 CHECK(s2 >= s1); 1275 } 1276 1277 { 1278 int arr[] = {2, 1}; 1279 span<int> s1 = arr; 1280 span<int> s2 = arr; 1281 1282 CHECK(s1 == s2); 1283 CHECK(!(s1 != s2)); 1284 CHECK(!(s1 < s2)); 1285 CHECK(s1 <= s2); 1286 CHECK(!(s1 > s2)); 1287 CHECK(s1 >= s2); 1288 CHECK(s2 == s1); 1289 CHECK(!(s2 != s1)); 1290 CHECK(!(s2 < s1)); 1291 CHECK(s2 <= s1); 1292 CHECK(!(s2 > s1)); 1293 CHECK(s2 >= s1); 1294 } 1295 1296 { 1297 int arr[] = {2, 1}; // bigger 1298 1299 span<int> s1 = nullptr; 1300 span<int> s2 = arr; 1301 1302 CHECK(s1 != s2); 1303 CHECK(s2 != s1); 1304 CHECK(!(s1 == s2)); 1305 CHECK(!(s2 == s1)); 1306 CHECK(s1 < s2); 1307 CHECK(!(s2 < s1)); 1308 CHECK(s1 <= s2); 1309 CHECK(!(s2 <= s1)); 1310 CHECK(s2 > s1); 1311 CHECK(!(s1 > s2)); 1312 CHECK(s2 >= s1); 1313 CHECK(!(s1 >= s2)); 1314 } 1315 1316 { 1317 int arr1[] = {1, 2}; 1318 int arr2[] = {1, 2}; 1319 span<int> s1 = arr1; 1320 span<int> s2 = arr2; 1321 1322 CHECK(s1 == s2); 1323 CHECK(!(s1 != s2)); 1324 CHECK(!(s1 < s2)); 1325 CHECK(s1 <= s2); 1326 CHECK(!(s1 > s2)); 1327 CHECK(s1 >= s2); 1328 CHECK(s2 == s1); 1329 CHECK(!(s2 != s1)); 1330 CHECK(!(s2 < s1)); 1331 CHECK(s2 <= s1); 1332 CHECK(!(s2 > s1)); 1333 CHECK(s2 >= s1); 1334 } 1335 1336 { 1337 int arr[] = {1, 2, 3}; 1338 1339 span<int> s1 = {&arr[0], 2}; // shorter 1340 span<int> s2 = arr; // longer 1341 1342 CHECK(s1 != s2); 1343 CHECK(s2 != s1); 1344 CHECK(!(s1 == s2)); 1345 CHECK(!(s2 == s1)); 1346 CHECK(s1 < s2); 1347 CHECK(!(s2 < s1)); 1348 CHECK(s1 <= s2); 1349 CHECK(!(s2 <= s1)); 1350 CHECK(s2 > s1); 1351 CHECK(!(s1 > s2)); 1352 CHECK(s2 >= s1); 1353 CHECK(!(s1 >= s2)); 1354 } 1355 1356 { 1357 int arr1[] = {1, 2}; // smaller 1358 int arr2[] = {2, 1}; // bigger 1359 1360 span<int> s1 = arr1; 1361 span<int> s2 = arr2; 1362 1363 CHECK(s1 != s2); 1364 CHECK(s2 != s1); 1365 CHECK(!(s1 == s2)); 1366 CHECK(!(s2 == s1)); 1367 CHECK(s1 < s2); 1368 CHECK(!(s2 < s1)); 1369 CHECK(s1 <= s2); 1370 CHECK(!(s2 <= s1)); 1371 CHECK(s2 > s1); 1372 CHECK(!(s1 > s2)); 1373 CHECK(s2 >= s1); 1374 CHECK(!(s1 >= s2)); 1375 } 1376} 1377 1378TEST_CASE("as_bytes") 1379{ 1380 int a[] = {1, 2, 3, 4}; 1381 1382 { 1383 const span<const int> s = a; 1384 CHECK(s.length() == 4); 1385 const span<const byte> bs = as_bytes(s); 1386 CHECK(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data())); 1387 CHECK(bs.length() == s.length_bytes()); 1388 } 1389 1390 { 1391 span<int> s; 1392 const auto bs = as_bytes(s); 1393 CHECK(bs.length() == s.length()); 1394 CHECK(bs.length() == 0); 1395 CHECK(bs.size_bytes() == 0); 1396 CHECK(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data())); 1397 CHECK(bs.data() == nullptr); 1398 } 1399 1400 { 1401 span<int> s = a; 1402 const auto bs = as_bytes(s); 1403 CHECK(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data())); 1404 CHECK(bs.length() == s.length_bytes()); 1405 } 1406} 1407 1408TEST_CASE("as_writeable_bytes") 1409{ 1410 int a[] = {1, 2, 3, 4}; 1411 1412 { 1413#ifdef CONFIRM_COMPILATION_ERRORS 1414 // you should not be able to get writeable bytes for const objects 1415 span<const int> s = a; 1416 CHECK(s.length() == 4); 1417 span<const byte> bs = as_writeable_bytes(s); 1418 CHECK(static_cast<void*>(bs.data()) == static_cast<void*>(s.data())); 1419 CHECK(bs.length() == s.length_bytes()); 1420#endif 1421 } 1422 1423 { 1424 span<int> s; 1425 const auto bs = as_writeable_bytes(s); 1426 CHECK(bs.length() == s.length()); 1427 CHECK(bs.length() == 0); 1428 CHECK(bs.size_bytes() == 0); 1429 CHECK(static_cast<void*>(bs.data()) == static_cast<void*>(s.data())); 1430 CHECK(bs.data() == nullptr); 1431 } 1432 1433 { 1434 span<int> s = a; 1435 const auto bs = as_writeable_bytes(s); 1436 CHECK(static_cast<void*>(bs.data()) == static_cast<void*>(s.data())); 1437 CHECK(bs.length() == s.length_bytes()); 1438 } 1439} 1440 1441TEST_CASE("fixed_size_conversions") 1442{ 1443 int arr[] = {1, 2, 3, 4}; 1444 1445 // converting to an span from an equal size array is ok 1446 span<int, 4> s4 = arr; 1447 CHECK(s4.length() == 4); 1448 1449 // converting to dynamic_range is always ok 1450 { 1451 span<int> s = s4; 1452 CHECK(s.length() == s4.length()); 1453 static_cast<void>(s); 1454 } 1455 1456// initialization or assignment to static span that REDUCES size is NOT ok 1457#ifdef CONFIRM_COMPILATION_ERRORS 1458 { 1459 span<int, 2> s = arr; 1460 } 1461 { 1462 span<int, 2> s2 = s4; 1463 static_cast<void>(s2); 1464 } 1465#endif 1466 1467 // even when done dynamically 1468 { 1469 span<int> s = arr; 1470 auto f = [&]() { 1471 span<int, 2> s2 = s; 1472 static_cast<void>(s2); 1473 }; 1474 CHECK_THROWS_AS(f(), fail_fast); 1475 } 1476 1477 // but doing so explicitly is ok 1478 1479 // you can convert statically 1480 { 1481 const span<int, 2> s2 = {arr, 2}; 1482 static_cast<void>(s2); 1483 } 1484 { 1485 const span<int, 1> s1 = s4.first<1>(); 1486 static_cast<void>(s1); 1487 } 1488 1489 // ...or dynamically 1490 { 1491 // NB: implicit conversion to span<int,1> from span<int> 1492 span<int, 1> s1 = s4.first(1); 1493 static_cast<void>(s1); 1494 } 1495 1496 // initialization or assignment to static span that requires size INCREASE is not ok. 1497 int arr2[2] = {1, 2}; 1498 1499#ifdef CONFIRM_COMPILATION_ERRORS 1500 { 1501 span<int, 4> s3 = arr2; 1502 } 1503 { 1504 span<int, 2> s2 = arr2; 1505 span<int, 4> s4a = s2; 1506 } 1507#endif 1508 { 1509 auto f = [&]() { 1510 span<int, 4> _s4 = {arr2, 2}; 1511 static_cast<void>(_s4); 1512 }; 1513 CHECK_THROWS_AS(f(), fail_fast); 1514 } 1515 1516 // this should fail - we are trying to assign a small dynamic span to a fixed_size larger one 1517 span<int> av = arr2; 1518 auto f = [&]() { 1519 span<int, 4> _s4 = av; 1520 static_cast<void>(_s4); 1521 }; 1522 CHECK_THROWS_AS(f(), fail_fast); 1523} 1524 1525TEST_CASE("interop_with_std_regex") 1526{ 1527 char lat[] = {'1', '2', '3', '4', '5', '6', 'E', 'F', 'G'}; 1528 span<char> s = lat; 1529 const auto f_it = s.begin() + 7; 1530 1531 std::match_results<span<char>::iterator> match; 1532 1533 std::regex_match(s.begin(), s.end(), match, std::regex(".*")); 1534 CHECK(match.ready()); 1535 CHECK(!match.empty()); 1536 CHECK(match[0].matched); 1537 CHECK(match[0].first == s.begin()); 1538 CHECK(match[0].second == s.end()); 1539 1540 std::regex_search(s.begin(), s.end(), match, std::regex("F")); 1541 CHECK(match.ready()); 1542 CHECK(!match.empty()); 1543 CHECK(match[0].matched); 1544 CHECK(match[0].first == f_it); 1545 CHECK(match[0].second == (f_it + 1)); 1546} 1547 1548TEST_CASE("interop_with_gsl_at") 1549{ 1550 int arr[5] = {1, 2, 3, 4, 5}; 1551 span<int> s{arr}; 1552 CHECK((at(s, 0) == 1 && at(s, 1) == 2)); 1553} 1554 1555TEST_CASE("default_constructible") 1556{ 1557 CHECK((std::is_default_constructible<span<int>>::value)); 1558 CHECK((std::is_default_constructible<span<int, 0>>::value)); 1559 CHECK((!std::is_default_constructible<span<int, 42>>::value)); 1560} 1561