Skip to content

A few small suggestions #3

@chris0e3

Description

@chris0e3

Great job. Thanks for creating & releasing this.
Have you considered offering it for use in libc++/clang?
It would be good if you could add the static size optimisation (at some point).

I have been experimenting with it & testing it with Clang 6.0 & C++17.

Here’s my feedback & suggestions:

  • Add #include <algorithm> (for lexicographical_compare).
  • The with_container_t stuff appears redundant (with Clang 6.0 & C++17).
  • In namespace nonstd add using span_lite::as_bytes; and using span_lite::as_writeable_bytes; (after line 932).
  • The operator== fails to compile with:
    static const uint8_t data[] = { 0,1,2,3,4,5,6,7,8,9,10 };
    span<uint8_t const> span_data(data);
    assert(make_span(data) == span_data);	// Compile error

I fixed it by adding template<class T> struct is_span_oracle<span<T>> : std::true_type {}; (by the current is_span_oracle) and changed operator==, != etc. to something like:

template<class T1, index_t L1, class T2, index_t L2> inline constexpr bool
operator==(span<T1, L1> l, span<T2, L2> r)
    { return (l.cbegin() == r.cbegin() && l.size() == r.size()) ||
             equal(l.cbegin(), l.cend(), r.cbegin(), r.cend()); }

template<class T1, index_t L1, class T2, index_t L2> inline constexpr bool
operator<(span<T1, L1> l, span<T2, L2> r)
    { return lexicographical_compare(l.cbegin(), l.cend(), r.cbegin(), r.cend()); }

template<class T1, index_t L1, class T2, index_t L2> inline constexpr bool
operator!=(span<T1, L1> l, span<T2, L2> r)	{ return !(l == r); }

template<class T1, index_t L1, class T2, index_t L2> inline constexpr bool
operator<=(span<T1, L1> l, span<T2, L2> r)	{ return !(r < l); }

template<class T1, index_t L1, class T2, index_t L2> inline constexpr bool
operator>(span<T1, L1> l, span<T2, L2> r)	{ return (r < l); }

template<class T1, index_t L1, class T2, index_t L2> inline constexpr bool
operator>=(span<T1, L1> l, span<T2, L2> r)	{ return !(l < r); }
  • The as_bytes & as_writeable_bytes have a mistake in their disabled lines (closing paren in wrong plac)e:
    return { reinterpret_cast< std::byte const * >( spn.data(), spn.size_bytes() ) };
    should be:
    return { reinterpret_cast<std::byte const*>(spn.data()), spn.size_bytes() };
                                                          ^
    And
    return { reinterpret_cast< std::byte * >( spn.data(), spn.size_bytes() ) };
    should be:
    return { reinterpret_cast<std::byte*>(spn.data()), spn.size_bytes() };
                                                    ^
  • I added the following helpers along with the make_span functions:
template<class T> inline constexpr auto
byte_span(T& t) noexcept
    { return span<byte, sizeof(t)>(reinterpret_cast<byte*>(&t), sizeof(t)); }

template<class T> inline constexpr auto
byte_span(T const& t) noexcept
    { return span<byte const, sizeof(t)>(reinterpret_cast<byte const*>(&t), sizeof(t)); }
  • I also added cdata, front & back member functions (with the obvious impls).
  • Additionally I added the following (as C++ has no operator===):
    template<class Span2 = span<T, Extent>>
    constexpr bool same(Span2 s) const noexcept
    {
        return static_cast<void const*>(data()) == s.data() && size() == s.size();
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions