void test_case_from_pointer_pointer_constructor() { int arr[4] = {1, 2, 3, 4}; { span<int> s{&arr[0], &arr[2]}; CHECK((s.size() == 2 && s.data() == &arr[0])); CHECK((s[0] == 1 && s[1] == 2)); } { span<int, 2> s{&arr[0], &arr[2]}; CHECK((s.size() == 2 && s.data() == &arr[0])); CHECK((s[0] == 1 && s[1] == 2)); } { span<int> s{&arr[0], &arr[0]}; CHECK((s.size() == 0 && s.data() == &arr[0])); } { span<int, 0> s{&arr[0], &arr[0]}; CHECK((s.size() == 0 && s.data() == &arr[0])); } { int* p = nullptr; span<int> s{p, p}; CHECK((s.size() == 0 && s.data() == nullptr)); } { int* p = nullptr; span<int, 0> s{p, p}; CHECK((s.size() == 0 && s.data() == nullptr)); } { auto s = make_span(&arr[0], &arr[2]); CHECK((s.size() == 2 && s.data() == &arr[0])); CHECK((s[0] == 1 && s[1] == 2)); } { auto s = make_span(&arr[0], &arr[0]); CHECK((s.size() == 0 && s.data() == &arr[0])); } { int* p = nullptr; auto s = make_span(p, p); CHECK((s.size() == 0 && s.data() == nullptr)); } }
void test_case_from_array_constructor() { int arr[5] = {1, 2, 3, 4, 5}; { span<int> s{arr}; CHECK((s.size() == 5 && s.data() == &arr[0])); } { span<int, 5> s{arr}; CHECK((s.size() == 5 && s.data() == &arr[0])); } int arr2d[2][3] = {1, 2, 3, 4, 5, 6}; CONCEPT_ASSERT(!std::is_constructible<span<int, 6>, int(&)[5]>::value); CONCEPT_ASSERT(!std::is_constructible<span<int, 0>, int(&)[5]>::value); CONCEPT_ASSERT(!std::is_constructible<span<int>, decltype((arr2d))>::value); CONCEPT_ASSERT(!std::is_constructible<span<int, 0>, decltype((arr2d))>::value); CONCEPT_ASSERT(!std::is_constructible<span<int, 6>, decltype((arr2d))>::value); { span<int[3]> s{&(arr2d[0]), 1}; CHECK((s.size() == 1 && s.data() == &arr2d[0])); } int arr3d[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; CONCEPT_ASSERT(!std::is_constructible<span<int>, decltype((arr3d))>::value); CONCEPT_ASSERT(!std::is_constructible<span<int, 0>, decltype((arr3d))>::value); CONCEPT_ASSERT(!std::is_constructible<span<int, 11>, decltype((arr3d))>::value); CONCEPT_ASSERT(!std::is_constructible<span<int, 12>, decltype((arr3d))>::value); { span<int[3][2]> s{&arr3d[0], 1}; CHECK((s.size() == 1 && s.data() == &arr3d[0])); } { auto s = make_span(arr); CHECK((s.size() == 5 && s.data() == &arr[0])); } { auto s = make_span(&(arr2d[0]), 1); CHECK((s.size() == 1 && s.data() == &arr2d[0])); } { auto s = make_span(&arr3d[0], 1); CHECK((s.size() == 1 && s.data() == &arr3d[0])); } }
void test_case_from_const_std_array_constructor() { const std::array<int, 4> arr = {1, 2, 3, 4}; { span<const int> s{arr}; CHECK((s.size() == narrow_cast<std::ptrdiff_t>(arr.size()) && s.data() == arr.data())); } { span<const int, 4> s{arr}; CHECK((s.size() == narrow_cast<std::ptrdiff_t>(arr.size()) && s.data() == arr.data())); } CONCEPT_ASSERT(!std::is_constructible<span<const int, 2>, decltype((arr))>::value); CONCEPT_ASSERT(!std::is_constructible<span<const int, 0>, decltype((arr))>::value); CONCEPT_ASSERT(!std::is_constructible<span<const int, 5>, decltype((arr))>::value); { auto get_an_array = []() -> const std::array<int, 4> { return {1, 2, 3, 4}; }; auto take_a_span = [](span<const int>) {}; take_a_span(get_an_array()); } { auto s = make_span(arr); CHECK((s.size() == narrow_cast<std::ptrdiff_t>(arr.size()) && s.data() == arr.data())); } }
void test_case_from_pointer_size_constructor() { int arr[4] = {1, 2, 3, 4}; { span<int> s{&arr[0], 2}; CHECK((s.size() == 2 && s.data() == &arr[0])); CHECK((s[0] == 1 && s[1] == 2)); } { span<int, 2> s{&arr[0], 2}; CHECK((s.size() == 2 && s.data() == &arr[0])); CHECK((s[0] == 1 && s[1] == 2)); } { int* p = nullptr; span<int> s{p, static_cast<span<int>::index_type>(0)}; CHECK((s.size() == 0 && s.data() == nullptr)); } { auto s = make_span(&arr[0], 2); CHECK((s.size() == 2 && s.data() == &arr[0])); CHECK((s[0] == 1 && s[1] == 2)); } { int* p = nullptr; auto s = make_span(p, static_cast<span<int>::index_type>(0)); CHECK((s.size() == 0 && s.data() == nullptr)); } { int i = 42; span<int> s{&i, 0}; CHECK((s.size() == 0 && s.data() == &i)); span<const int> cs{&i, 0}; CHECK((s.size() == 0 && s.data() == &i)); } }
void test_case_from_std_array_const_constructor() { std::array<const int, 4> arr = {1, 2, 3, 4}; { span<const int> s{arr}; CHECK((s.size() == narrow_cast<std::ptrdiff_t>(arr.size()) && s.data() == arr.data())); } { span<const int, 4> s{arr}; CHECK((s.size() == narrow_cast<std::ptrdiff_t>(arr.size()) && s.data() == arr.data())); } CONCEPT_ASSERT(!std::is_constructible<span<const int, 2>, decltype((arr))>::value); CONCEPT_ASSERT(!std::is_constructible<span<const int, 0>, decltype((arr))>::value); CONCEPT_ASSERT(!std::is_constructible<span<const int, 5>, decltype((arr))>::value); CONCEPT_ASSERT(!std::is_constructible<span<int, 4>, decltype((arr))>::value); { auto s = make_span(arr); CHECK((s.size() == narrow_cast<std::ptrdiff_t>(arr.size()) && s.data() == arr.data())); } }
void test_case_from_container_constructor() { std::vector<int> v = {1, 2, 3}; const std::vector<int> cv = v; { span<int> s{v}; CHECK((s.size() == narrow_cast<std::ptrdiff_t>(v.size()) && s.data() == v.data())); span<const int> cs{v}; CHECK((cs.size() == narrow_cast<std::ptrdiff_t>(v.size()) && cs.data() == v.data())); } std::string str = "hello"; const std::string cstr = "hello"; { span<char> s{str}; CHECK((s.size() == narrow_cast<std::ptrdiff_t>(str.size()) && s.data() == str.data())); } { auto get_temp_string = []() -> std::string { return {}; }; auto use_span = [](span<char>) {}; use_span(get_temp_string()); } { span<const char> cs{str}; CHECK((cs.size() == narrow_cast<std::ptrdiff_t>(str.size()) && cs.data() == str.data())); } { auto get_temp_string = []() -> std::string { return {}; }; auto use_span = [](span<const char>) {}; use_span(get_temp_string()); } { CONCEPT_ASSERT(!std::is_constructible<span<char>, decltype((cstr))>::value); span<const char> cs{cstr}; CHECK((cs.size() == narrow_cast<std::ptrdiff_t>(cstr.size()) && cs.data() == cstr.data())); } { auto get_temp_vector = []() -> std::vector<int> { return {}; }; auto use_span = [](span<int>) {}; use_span(get_temp_vector()); } { auto get_temp_vector = []() -> std::vector<int> { return {}; }; auto use_span = [](span<const int>) {}; use_span(get_temp_vector()); } CONCEPT_ASSERT(!std::is_convertible<const std::vector<int>, span<const char>>::value); { auto get_temp_string = []() -> const std::string { return {}; }; auto use_span = [](span<const char> s) { static_cast<void>(s); }; use_span(get_temp_string()); } CONCEPT_ASSERT(!std::is_constructible<span<int>, std::map<int, int>&>::value); { auto s = make_span(v); CHECK((s.size() == narrow_cast<std::ptrdiff_t>(v.size()) && s.data() == v.data())); auto cs = make_span(cv); CHECK((cs.size() == narrow_cast<std::ptrdiff_t>(cv.size()) && cs.data() == cv.data())); } }