Closed
Description
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
addusing span_lite::as_bytes;
andusing 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
Labels
No labels