ContiguousSpan Closure(const Span &s) { ContiguousSpan result(-1,-1); if (!s.empty()) { result.first = *(s.begin()); result.second = *(s.rbegin()); } return result; }
bool SpansIntersect(const Span &a, const ContiguousSpan &b) { for (Span::const_iterator p = a.begin(); p != a.end(); ++p) { if (*p >= b.first && *p <= b.second) { return true; } } return false; }
void testRuntimeSpan(Span sp) { LIBCPP_ASSERT((noexcept(sp.template first<Count>()))); LIBCPP_ASSERT((noexcept(sp.first(Count)))); auto s1 = sp.template first<Count>(); auto s2 = sp.first(Count); using S1 = decltype(s1); using S2 = decltype(s2); ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type); ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type); static_assert(S1::extent == Count, ""); static_assert(S2::extent == std::dynamic_extent, ""); assert(s1.data() == s2.data()); assert(s1.size() == s2.size()); assert(std::equal(s1.begin(), s1.end(), sp.begin())); }
constexpr bool testConstexprSpan(Span sp) { LIBCPP_ASSERT((noexcept(sp.template subspan<Offset>()))); LIBCPP_ASSERT((noexcept(sp.subspan(Offset)))); auto s1 = sp.template subspan<Offset>(); auto s2 = sp.subspan(Offset); using S1 = decltype(s1); using S2 = decltype(s2); ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type); ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type); static_assert(S1::extent == (Span::extent == std::dynamic_extent ? std::dynamic_extent : Span::extent - Offset), ""); static_assert(S2::extent == std::dynamic_extent, ""); return s1.data() == s2.data() && s1.size() == s2.size() && std::equal(s1.begin(), s1.end(), sp.begin() + Offset, sp.end()); }
Iterator begin(Span<Iterator> range) { return range.begin(); }
Span<std::reverse_iterator<Iterator>> makeReverseSpan(Span<Iterator> range) { return makeSpan(std::reverse_iterator<Iterator>(range.end()), std::reverse_iterator<Iterator>(range.begin())); }