Home | History | Annotate | Download | only in span.sub
      1 // -*- C++ -*-
      2 //===------------------------------ span ---------------------------------===//
      3 //
      4 //                     The LLVM Compiler Infrastructure
      5 //
      6 // This file is dual licensed under the MIT and the University of Illinois Open
      7 // Source Licenses. See LICENSE.TXT for details.
      8 //
      9 //===---------------------------------------------------------------------===//
     10 // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
     11 
     12 // <span>
     13 
     14 // template<ptrdiff_t Offset, ptrdiff_t Count = dynamic_extent>
     15 //   constexpr span<element_type, see below> subspan() const;
     16 //
     17 // constexpr span<element_type, dynamic_extent> subspan(
     18 //   index_type offset, index_type count = dynamic_extent) const;
     19 //
     20 //  Requires: (0 <= Offset && Offset <= size())
     21 //      && (Count == dynamic_extent || Count >= 0 && Offset + Count <= size())
     22 
     23 #include <span>
     24 #include <cassert>
     25 #include <algorithm>
     26 #include <string>
     27 
     28 #include "test_macros.h"
     29 
     30 template <typename Span, ptrdiff_t Offset, ptrdiff_t Count>
     31 constexpr bool testConstexprSpan(Span sp)
     32 {
     33     LIBCPP_ASSERT((noexcept(sp.template subspan<Offset, Count>())));
     34     LIBCPP_ASSERT((noexcept(sp.subspan(Offset, Count))));
     35     auto s1 = sp.template subspan<Offset, Count>();
     36     auto s2 = sp.subspan(Offset, Count);
     37     using S1 = decltype(s1);
     38     using S2 = decltype(s2);
     39     ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
     40     ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
     41     static_assert(S1::extent == (Span::extent == std::dynamic_extent ? std::dynamic_extent : Count), "");
     42     static_assert(S2::extent == std::dynamic_extent, "");
     43     return
     44         s1.data() == s2.data()
     45      && s1.size() == s2.size()
     46      && std::equal(s1.begin(), s1.end(), sp.begin() + Offset);
     47 }
     48 
     49 template <typename Span, ptrdiff_t Offset>
     50 constexpr bool testConstexprSpan(Span sp)
     51 {
     52     LIBCPP_ASSERT((noexcept(sp.template subspan<Offset>())));
     53     LIBCPP_ASSERT((noexcept(sp.subspan(Offset))));
     54     auto s1 = sp.template subspan<Offset>();
     55     auto s2 = sp.subspan(Offset);
     56     using S1 = decltype(s1);
     57     using S2 = decltype(s2);
     58     ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
     59     ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
     60     static_assert(S1::extent == (Span::extent == std::dynamic_extent ? std::dynamic_extent : Span::extent - Offset), "");
     61     static_assert(S2::extent == std::dynamic_extent, "");
     62     return
     63         s1.data() == s2.data()
     64      && s1.size() == s2.size()
     65      && std::equal(s1.begin(), s1.end(), sp.begin() + Offset, sp.end());
     66 }
     67 
     68 
     69 template <typename Span, ptrdiff_t Offset, ptrdiff_t Count>
     70 void testRuntimeSpan(Span sp)
     71 {
     72     LIBCPP_ASSERT((noexcept(sp.template subspan<Offset, Count>())));
     73     LIBCPP_ASSERT((noexcept(sp.subspan(Offset, Count))));
     74     auto s1 = sp.template subspan<Offset, Count>();
     75     auto s2 = sp.subspan(Offset, Count);
     76     using S1 = decltype(s1);
     77     using S2 = decltype(s2);
     78     ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
     79     ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
     80     static_assert(S1::extent == (Span::extent == std::dynamic_extent ? std::dynamic_extent : Count), "");
     81     static_assert(S2::extent == std::dynamic_extent, "");
     82     assert(s1.data() == s2.data());
     83     assert(s1.size() == s2.size());
     84     assert(std::equal(s1.begin(), s1.end(), sp.begin() + Offset));
     85 }
     86 
     87 
     88 template <typename Span, ptrdiff_t Offset>
     89 void testRuntimeSpan(Span sp)
     90 {
     91     LIBCPP_ASSERT((noexcept(sp.template subspan<Offset>())));
     92     LIBCPP_ASSERT((noexcept(sp.subspan(Offset))));
     93     auto s1 = sp.template subspan<Offset>();
     94     auto s2 = sp.subspan(Offset);
     95     using S1 = decltype(s1);
     96     using S2 = decltype(s2);
     97     ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
     98     ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
     99     static_assert(S1::extent == (Span::extent == std::dynamic_extent ? std::dynamic_extent : Span::extent - Offset), "");
    100     static_assert(S2::extent == std::dynamic_extent, "");
    101     assert(s1.data() == s2.data());
    102     assert(s1.size() == s2.size());
    103     assert(std::equal(s1.begin(), s1.end(), sp.begin() + Offset, sp.end()));
    104 }
    105 
    106 
    107 constexpr int carr1[] = {1,2,3,4};
    108           int  arr1[] = {5,6,7};
    109 
    110 int main ()
    111 {
    112     {
    113     using Sp = std::span<const int>;
    114     static_assert(testConstexprSpan<Sp, 0>(Sp{}), "");
    115 
    116     static_assert(testConstexprSpan<Sp, 0, 4>(Sp{carr1}), "");
    117     static_assert(testConstexprSpan<Sp, 0, 3>(Sp{carr1}), "");
    118     static_assert(testConstexprSpan<Sp, 0, 2>(Sp{carr1}), "");
    119     static_assert(testConstexprSpan<Sp, 0, 1>(Sp{carr1}), "");
    120     static_assert(testConstexprSpan<Sp, 0, 0>(Sp{carr1}), "");
    121 
    122     static_assert(testConstexprSpan<Sp, 1, 3>(Sp{carr1}), "");
    123     static_assert(testConstexprSpan<Sp, 2, 2>(Sp{carr1}), "");
    124     static_assert(testConstexprSpan<Sp, 3, 1>(Sp{carr1}), "");
    125     static_assert(testConstexprSpan<Sp, 4, 0>(Sp{carr1}), "");
    126     }
    127 
    128     {
    129     using Sp = std::span<const int, 4>;
    130 
    131     static_assert(testConstexprSpan<Sp, 0, 4>(Sp{carr1}), "");
    132     static_assert(testConstexprSpan<Sp, 0, 3>(Sp{carr1}), "");
    133     static_assert(testConstexprSpan<Sp, 0, 2>(Sp{carr1}), "");
    134     static_assert(testConstexprSpan<Sp, 0, 1>(Sp{carr1}), "");
    135     static_assert(testConstexprSpan<Sp, 0, 0>(Sp{carr1}), "");
    136 
    137     static_assert(testConstexprSpan<Sp, 1, 3>(Sp{carr1}), "");
    138     static_assert(testConstexprSpan<Sp, 2, 2>(Sp{carr1}), "");
    139     static_assert(testConstexprSpan<Sp, 3, 1>(Sp{carr1}), "");
    140     static_assert(testConstexprSpan<Sp, 4, 0>(Sp{carr1}), "");
    141     }
    142 
    143     {
    144     using Sp = std::span<const int>;
    145     static_assert(testConstexprSpan<Sp, 0>(Sp{}), "");
    146 
    147     static_assert(testConstexprSpan<Sp, 0>(Sp{carr1}), "");
    148     static_assert(testConstexprSpan<Sp, 1>(Sp{carr1}), "");
    149     static_assert(testConstexprSpan<Sp, 2>(Sp{carr1}), "");
    150     static_assert(testConstexprSpan<Sp, 3>(Sp{carr1}), "");
    151     static_assert(testConstexprSpan<Sp, 4>(Sp{carr1}), "");
    152     }
    153 
    154     {
    155     using Sp = std::span<const int, 4>;
    156 
    157     static_assert(testConstexprSpan<Sp, 0>(Sp{carr1}), "");
    158 
    159     static_assert(testConstexprSpan<Sp, 1>(Sp{carr1}), "");
    160     static_assert(testConstexprSpan<Sp, 2>(Sp{carr1}), "");
    161     static_assert(testConstexprSpan<Sp, 3>(Sp{carr1}), "");
    162     static_assert(testConstexprSpan<Sp, 4>(Sp{carr1}), "");
    163     }
    164 
    165     {
    166     using Sp = std::span<int>;
    167     testRuntimeSpan<Sp, 0>(Sp{});
    168 
    169     testRuntimeSpan<Sp, 0, 3>(Sp{arr1});
    170     testRuntimeSpan<Sp, 0, 2>(Sp{arr1});
    171     testRuntimeSpan<Sp, 0, 1>(Sp{arr1});
    172     testRuntimeSpan<Sp, 0, 0>(Sp{arr1});
    173 
    174     testRuntimeSpan<Sp, 1, 2>(Sp{arr1});
    175     testRuntimeSpan<Sp, 2, 1>(Sp{arr1});
    176     testRuntimeSpan<Sp, 3, 0>(Sp{arr1});
    177     }
    178 
    179     {
    180     using Sp = std::span<int, 3>;
    181 
    182     testRuntimeSpan<Sp, 0, 3>(Sp{arr1});
    183     testRuntimeSpan<Sp, 0, 2>(Sp{arr1});
    184     testRuntimeSpan<Sp, 0, 1>(Sp{arr1});
    185     testRuntimeSpan<Sp, 0, 0>(Sp{arr1});
    186 
    187     testRuntimeSpan<Sp, 1, 2>(Sp{arr1});
    188     testRuntimeSpan<Sp, 2, 1>(Sp{arr1});
    189     testRuntimeSpan<Sp, 3, 0>(Sp{arr1});
    190     }
    191 
    192     {
    193     using Sp = std::span<int>;
    194     testRuntimeSpan<Sp, 0>(Sp{});
    195 
    196     testRuntimeSpan<Sp, 0>(Sp{arr1});
    197     testRuntimeSpan<Sp, 1>(Sp{arr1});
    198     testRuntimeSpan<Sp, 2>(Sp{arr1});
    199     testRuntimeSpan<Sp, 3>(Sp{arr1});
    200     }
    201 
    202     {
    203     using Sp = std::span<int, 3>;
    204 
    205     testRuntimeSpan<Sp, 0>(Sp{arr1});
    206     testRuntimeSpan<Sp, 1>(Sp{arr1});
    207     testRuntimeSpan<Sp, 2>(Sp{arr1});
    208     testRuntimeSpan<Sp, 3>(Sp{arr1});
    209     }
    210 }
    211