microsoft / GSL

Guidelines Support Library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

move gsl::at for gsl::span

JordanMaples opened this issue · comments

The version of gsl::at that is invoked when calling it with a gsl::span changes depending on which headers are included.

<gsl/span_ext> has a specialization for gsl::span that takes the span by copy:

// Specialization of gsl::at for span
template <class ElementType, std::size_t Extent>
constexpr ElementType& at(span<ElementType, Extent> s, index i)
{
    // No bounds checking here because it is done in span::operator[] called below
    Ensures(i >= 0);
    return s[narrow_cast<std::size_t>(i)];
}

However, unless you include <gsl/span_ext>, <gsl/string_view>, or <gsl/gsl> the version of at that is compiled is the one from <gsl/util>.

template <class Cont>
// clang-format off
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
// clang-format on
    constexpr auto at(Cont& cont, const index i) -> decltype(cont[cont.size()])
{
    Expects(i >= 0 && i < narrow_cast<index>(cont.size()));
    using size_type = decltype(cont.size());
    return cont[narrow_cast<size_type>(i)];
}

If we intend to continue offering this specialization, it should be moved into <gsl/span>.