mirror of
https://github.com/microsoft/GSL.git
synced 2024-11-03 17:56:43 -05:00
Add make_span()
This patch provides a make_span function to simplify the creation of spans until C++17 is available. In addition this patch updates the unit tests to includes tests that verify this new functionality.
This commit is contained in:
parent
9523c1842e
commit
2df9f85385
39
gsl/span
39
gsl/span
@ -632,6 +632,45 @@ as_writeable_bytes(span<ElementType, Extent> s) noexcept
|
|||||||
return {reinterpret_cast<byte*>(s.data()), s.size_bytes()};
|
return {reinterpret_cast<byte*>(s.data()), s.size_bytes()};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// make_span() - Utility functions for creating spans
|
||||||
|
//
|
||||||
|
template <class ElementType>
|
||||||
|
span<ElementType>
|
||||||
|
make_span(ElementType* ptr, typename span<ElementType>::index_type count)
|
||||||
|
{ return span<ElementType>(ptr, count); }
|
||||||
|
|
||||||
|
template <class ElementType>
|
||||||
|
span<ElementType>
|
||||||
|
make_span(ElementType* firstElem, ElementType* lastElem)
|
||||||
|
{ return span<ElementType>(firstElem, lastElem); }
|
||||||
|
|
||||||
|
template <class ElementType, size_t N>
|
||||||
|
span<ElementType>
|
||||||
|
make_span(ElementType (&arr)[N])
|
||||||
|
{ return span<ElementType>(arr); }
|
||||||
|
|
||||||
|
template <class Container>
|
||||||
|
span<typename Container::value_type>
|
||||||
|
make_span(Container &cont)
|
||||||
|
{ return span<typename Container::value_type>(cont); }
|
||||||
|
|
||||||
|
template <class Container>
|
||||||
|
span<const typename Container::value_type>
|
||||||
|
make_span(const Container &cont)
|
||||||
|
{ return span<const typename Container::value_type>(cont); }
|
||||||
|
|
||||||
|
template <class Ptr>
|
||||||
|
span<typename Ptr::element_type>
|
||||||
|
make_span(Ptr& cont, std::ptrdiff_t count)
|
||||||
|
{ return span<typename Ptr::element_type>(cont, count); }
|
||||||
|
|
||||||
|
template <class Ptr>
|
||||||
|
span<typename Ptr::element_type>
|
||||||
|
make_span(Ptr& cont)
|
||||||
|
{ return span<typename Ptr::element_type>(cont); }
|
||||||
|
|
||||||
|
|
||||||
// Specialization of gsl::at for span
|
// Specialization of gsl::at for span
|
||||||
template <class ElementType, std::ptrdiff_t Extent>
|
template <class ElementType, std::ptrdiff_t Extent>
|
||||||
constexpr ElementType& at(const span<ElementType, Extent>& s, std::ptrdiff_t index)
|
constexpr ElementType& at(const span<ElementType, Extent>& s, std::ptrdiff_t index)
|
||||||
|
@ -204,6 +204,24 @@ SUITE(span_tests)
|
|||||||
auto workaround_macro = [=]() { span<int> s{p, 2}; };
|
auto workaround_macro = [=]() { span<int> s{p, 2}; };
|
||||||
CHECK_THROW(workaround_macro(), fail_fast);
|
CHECK_THROW(workaround_macro(), fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s = make_span(&arr[0], 2);
|
||||||
|
CHECK(s.length() == 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.length() == 0 && s.data() == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int* p = nullptr;
|
||||||
|
auto workaround_macro = [=]() { make_span(p, 2); };
|
||||||
|
CHECK_THROW(workaround_macro(), fail_fast);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(from_pointer_pointer_constructor)
|
TEST(from_pointer_pointer_constructor)
|
||||||
@ -263,6 +281,23 @@ SUITE(span_tests)
|
|||||||
// auto workaround_macro = [&]() { span<int> s{&arr[0], p}; };
|
// auto workaround_macro = [&]() { span<int> s{&arr[0], p}; };
|
||||||
// CHECK_THROW(workaround_macro(), fail_fast);
|
// CHECK_THROW(workaround_macro(), fail_fast);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s = make_span(&arr[0], &arr[2]);
|
||||||
|
CHECK(s.length() == 2 && s.data() == &arr[0]);
|
||||||
|
CHECK(s[0] == 1 && s[1] == 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s = make_span(&arr[0], &arr[0]);
|
||||||
|
CHECK(s.length() == 0 && s.data() == &arr[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int* p = nullptr;
|
||||||
|
auto s = make_span(p, p);
|
||||||
|
CHECK(s.length() == 0 && s.data() == nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(from_array_constructor)
|
TEST(from_array_constructor)
|
||||||
@ -339,6 +374,21 @@ SUITE(span_tests)
|
|||||||
span<int[3][2]> s{&arr3d[0], 1};
|
span<int[3][2]> s{&arr3d[0], 1};
|
||||||
CHECK(s.length() == 1 && s.data() == &arr3d[0]);
|
CHECK(s.length() == 1 && s.data() == &arr3d[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s = make_span(arr);
|
||||||
|
CHECK(s.length() == 5 && s.data() == &arr[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s = make_span(&(arr2d[0]), 1);
|
||||||
|
CHECK(s.length() == 1 && s.data() == &arr2d[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s = make_span(&arr3d[0], 1);
|
||||||
|
CHECK(s.length() == 1 && s.data() == &arr3d[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(from_dynamic_array_constructor)
|
TEST(from_dynamic_array_constructor)
|
||||||
@ -350,6 +400,11 @@ SUITE(span_tests)
|
|||||||
CHECK(s.length() == 10 && s.data() == &arr[0][0][0]);
|
CHECK(s.length() == 10 && s.data() == &arr[0][0][0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s = make_span(&arr[0][0][0], 10);
|
||||||
|
CHECK(s.length() == 10 && s.data() == &arr[0][0][0]);
|
||||||
|
}
|
||||||
|
|
||||||
delete[] arr;
|
delete[] arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,6 +463,11 @@ SUITE(span_tests)
|
|||||||
// try to take a temporary std::array
|
// try to take a temporary std::array
|
||||||
take_a_span(get_an_array());
|
take_a_span(get_an_array());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s = make_span(arr);
|
||||||
|
CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(from_const_std_array_constructor)
|
TEST(from_const_std_array_constructor)
|
||||||
@ -446,6 +506,11 @@ SUITE(span_tests)
|
|||||||
// try to take a temporary std::array
|
// try to take a temporary std::array
|
||||||
take_a_span(get_an_array());
|
take_a_span(get_an_array());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s = make_span(arr);
|
||||||
|
CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(from_std_array_const_constructor)
|
TEST(from_std_array_const_constructor)
|
||||||
@ -481,6 +546,11 @@ SUITE(span_tests)
|
|||||||
span<int, 4> s{arr};
|
span<int, 4> s{arr};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s = make_span(arr);
|
||||||
|
CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(from_unique_pointer_construction)
|
TEST(from_unique_pointer_construction)
|
||||||
@ -493,6 +563,12 @@ SUITE(span_tests)
|
|||||||
CHECK(s.length() == 1 && s.data() == ptr.get());
|
CHECK(s.length() == 1 && s.data() == ptr.get());
|
||||||
CHECK(s[0] == 4);
|
CHECK(s[0] == 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s = make_span(ptr);
|
||||||
|
CHECK(s.length() == 1 && s.data() == ptr.get());
|
||||||
|
CHECK(s[0] == 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -502,6 +578,11 @@ SUITE(span_tests)
|
|||||||
span<int> s{ptr};
|
span<int> s{ptr};
|
||||||
CHECK(s.length() == 0 && s.data() == nullptr);
|
CHECK(s.length() == 0 && s.data() == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s = make_span(ptr);
|
||||||
|
CHECK(s.length() == 0 && s.data() == nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -515,13 +596,24 @@ SUITE(span_tests)
|
|||||||
CHECK(s.length() == 4 && s.data() == arr.get());
|
CHECK(s.length() == 4 && s.data() == arr.get());
|
||||||
CHECK(s[0] == 1 && s[1] == 2);
|
CHECK(s[0] == 1 && s[1] == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s = make_span(arr, 4);
|
||||||
|
CHECK(s.length() == 4 && s.data() == arr.get());
|
||||||
|
CHECK(s[0] == 1 && s[1] == 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto ptr = std::unique_ptr<int[]>{nullptr};
|
auto arr = std::unique_ptr<int[]>{nullptr};
|
||||||
|
|
||||||
{
|
{
|
||||||
span<int> s{ptr, 0};
|
span<int> s{arr, 0};
|
||||||
|
CHECK(s.length() == 0 && s.data() == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s = make_span(arr, 0);
|
||||||
CHECK(s.length() == 0 && s.data() == nullptr);
|
CHECK(s.length() == 0 && s.data() == nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -537,6 +629,12 @@ SUITE(span_tests)
|
|||||||
CHECK(s.length() == 1 && s.data() == ptr.get());
|
CHECK(s.length() == 1 && s.data() == ptr.get());
|
||||||
CHECK(s[0] == 4);
|
CHECK(s[0] == 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s = make_span(ptr);
|
||||||
|
CHECK(s.length() == 1 && s.data() == ptr.get());
|
||||||
|
CHECK(s[0] == 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -546,6 +644,11 @@ SUITE(span_tests)
|
|||||||
span<int> s{ptr};
|
span<int> s{ptr};
|
||||||
CHECK(s.length() == 0 && s.data() == nullptr);
|
CHECK(s.length() == 0 && s.data() == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s = make_span(ptr);
|
||||||
|
CHECK(s.length() == 0 && s.data() == nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -631,6 +734,14 @@ SUITE(span_tests)
|
|||||||
span<int> s{m};
|
span<int> s{m};
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(from_convertible_span_constructor)
|
TEST(from_convertible_span_constructor)
|
||||||
|
Loading…
Reference in New Issue
Block a user