Skip to content

A few small suggestions #3

Closed
Closed
@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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions