Home | History | Annotate | Download | only in tests
      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 
     29 using namespace std;
     30 using namespace gsl;
     31 
     32 namespace
     33 {
     34 struct BaseClass
     35 {
     36 };
     37 struct DerivedClass : BaseClass
     38 {
     39 };
     40 }
     41 
     42 TEST_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 
     76 TEST_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 
     89 TEST_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 
    131 TEST_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 
    181 TEST_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 
    228 TEST_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 
    304 TEST_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 
    395 TEST_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 
    412 TEST_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 
    474 TEST_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 
    517 TEST_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 
    557 TEST_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 
    622 TEST_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 
    655 TEST_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 
    747 TEST_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 
    784 TEST_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 
    805 TEST_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 
    843 TEST_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 
    880 TEST_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 
    949 TEST_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 
    968 TEST_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 
    987 TEST_CASE("iterator_default_init")
    988 {
    989     span<int>::iterator it1;
    990     span<int>::iterator it2;
    991     CHECK(it1 == it2);
    992 }
    993 
    994 TEST_CASE("const_iterator_default_init")
    995 {
    996     span<int>::const_iterator it1;
    997     span<int>::const_iterator it2;
    998     CHECK(it1 == it2);
    999 }
   1000 
   1001 TEST_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 
   1023 TEST_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 
   1070 TEST_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 
   1125 TEST_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 
   1177 TEST_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 
   1219 TEST_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 
   1258 TEST_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 
   1378 TEST_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 
   1408 TEST_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 
   1441 TEST_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 
   1525 TEST_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 
   1548 TEST_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 
   1555 TEST_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