Fix gsl::at()'s use of size_t

gsl::at should use std::ptrdiff_t instead of size_t. This patch
fixes that, and adds missing unit tests
This commit is contained in:
Rian Quinn 2016-10-28 12:46:14 -06:00 committed by Neil MacIntosh
parent f4486389b8
commit fb1a89fb14
3 changed files with 16 additions and 12 deletions

View File

@ -135,30 +135,30 @@ inline T narrow(U u)
// at() - Bounds-checked way of accessing static arrays, std::array, std::vector // at() - Bounds-checked way of accessing static arrays, std::array, std::vector
// //
template <class T, size_t N> template <class T, size_t N>
constexpr T& at(T (&arr)[N], size_t index) constexpr T& at(T (&arr)[N], std::ptrdiff_t index)
{ {
Expects(index < N); Expects(index >= 0 && index < narrow_cast<std::ptrdiff_t>(N));
return arr[index]; return arr[static_cast<size_t>(index)];
} }
template <class T, size_t N> template <class T, size_t N>
constexpr T& at(std::array<T, N>& arr, size_t index) constexpr T& at(std::array<T, N>& arr, std::ptrdiff_t index)
{ {
Expects(index < N); Expects(index >= 0 && index < narrow_cast<std::ptrdiff_t>(N));
return arr[index]; return arr[static_cast<size_t>(index)];
} }
template <class Cont> template <class Cont>
constexpr typename Cont::value_type& at(Cont& cont, size_t index) constexpr typename Cont::value_type& at(Cont& cont, std::ptrdiff_t index)
{ {
Expects(index < cont.size()); Expects(index >= 0 && index < narrow_cast<std::ptrdiff_t>(cont.size()));
return cont[index]; return cont[static_cast<typename Cont::size_type>(index)];
} }
template <class T> template <class T>
constexpr const T& at(std::initializer_list<T> cont, size_t index) constexpr const T& at(std::initializer_list<T> cont, std::ptrdiff_t index)
{ {
Expects(index < cont.size()); Expects(index >= 0 && index < narrow_cast<std::ptrdiff_t>(cont.size()));
return *(cont.begin() + index); return *(cont.begin() + index);
} }

View File

@ -627,7 +627,7 @@ as_writeable_bytes(span<ElementType, Extent> s) noexcept
// 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, size_t index) constexpr ElementType& at(const span<ElementType, Extent>& s, std::ptrdiff_t index)
{ {
// No bounds checking here because it is done in span::operator[] called below // No bounds checking here because it is done in span::operator[] called below
return s[index]; return s[index];

View File

@ -31,6 +31,7 @@ SUITE(at_tests)
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
CHECK(at(a, i) == i+1); CHECK(at(a, i) == i+1);
CHECK_THROW(at(a, -1), fail_fast);
CHECK_THROW(at(a, 4), fail_fast); CHECK_THROW(at(a, 4), fail_fast);
} }
@ -41,6 +42,7 @@ SUITE(at_tests)
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
CHECK(at(a, i) == i+1); CHECK(at(a, i) == i+1);
CHECK_THROW(at(a, -1), fail_fast);
CHECK_THROW(at(a, 4), fail_fast); CHECK_THROW(at(a, 4), fail_fast);
} }
@ -51,6 +53,7 @@ SUITE(at_tests)
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
CHECK(at(a, i) == i+1); CHECK(at(a, i) == i+1);
CHECK_THROW(at(a, -1), fail_fast);
CHECK_THROW(at(a, 4), fail_fast); CHECK_THROW(at(a, 4), fail_fast);
} }
@ -61,6 +64,7 @@ SUITE(at_tests)
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
CHECK(at(a, i) == i+1); CHECK(at(a, i) == i+1);
CHECK_THROW(at(a, -1), fail_fast);
CHECK_THROW(at(a, 4), fail_fast); CHECK_THROW(at(a, 4), fail_fast);
} }
} }