Changeset View
Changeset View
Standalone View
Standalone View
src/span.h
Show All 19 Lines | |||||
public: | public: | ||||
constexpr Span() noexcept : m_data(nullptr), m_size(0) {} | constexpr Span() noexcept : m_data(nullptr), m_size(0) {} | ||||
constexpr Span(C *data, std::ptrdiff_t size) noexcept | constexpr Span(C *data, std::ptrdiff_t size) noexcept | ||||
: m_data(data), m_size(size) {} | : m_data(data), m_size(size) {} | ||||
constexpr Span(C *data, C *end) noexcept | constexpr Span(C *data, C *end) noexcept | ||||
: m_data(data), m_size(end - data) {} | : m_data(data), m_size(end - data) {} | ||||
/** Implicit conversion of spans between compatible types. | |||||
* | |||||
* Specifically, if a pointer to an array of type O can be implicitly | |||||
* converted to a pointer to an array of type C, then permit implicit | |||||
* conversion of Span<O> to Span<C>. This matches the behavior of the | |||||
* corresponding C++20 std::span constructor. | |||||
* | |||||
* For example this means that a Span<T> can be converted into a Span<const | |||||
* T>. | |||||
*/ | |||||
template <typename O, | |||||
typename std::enable_if< | |||||
std::is_convertible<O (*)[], C (*)[]>::value, int>::type = 0> | |||||
constexpr Span(const Span<O> &other) noexcept | |||||
: m_data(other.m_data), m_size(other.m_size) {} | |||||
/** Default copy constructor. */ | |||||
constexpr Span(const Span &) noexcept = default; | |||||
/** Default assignment operator. */ | |||||
Span &operator=(const Span &other) noexcept = default; | |||||
constexpr C *data() const noexcept { return m_data; } | constexpr C *data() const noexcept { return m_data; } | ||||
constexpr C *begin() const noexcept { return m_data; } | constexpr C *begin() const noexcept { return m_data; } | ||||
constexpr C *end() const noexcept { return m_data + m_size; } | constexpr C *end() const noexcept { return m_data + m_size; } | ||||
constexpr C &front() const noexcept { return m_data[0]; } | constexpr C &front() const noexcept { return m_data[0]; } | ||||
constexpr C &back() const noexcept { return m_data[m_size - 1]; } | constexpr C &back() const noexcept { return m_data[m_size - 1]; } | ||||
constexpr std::ptrdiff_t size() const noexcept { return m_size; } | constexpr std::ptrdiff_t size() const noexcept { return m_size; } | ||||
constexpr C &operator[](std::ptrdiff_t pos) const noexcept { | constexpr C &operator[](std::ptrdiff_t pos) const noexcept { | ||||
return m_data[pos]; | return m_data[pos]; | ||||
Show All 28 Lines | friend constexpr bool operator<=(const Span &a, const Span &b) noexcept { | ||||
return !(b < a); | return !(b < a); | ||||
} | } | ||||
friend constexpr bool operator>(const Span &a, const Span &b) noexcept { | friend constexpr bool operator>(const Span &a, const Span &b) noexcept { | ||||
return (b < a); | return (b < a); | ||||
} | } | ||||
friend constexpr bool operator>=(const Span &a, const Span &b) noexcept { | friend constexpr bool operator>=(const Span &a, const Span &b) noexcept { | ||||
return !(a < b); | return !(a < b); | ||||
} | } | ||||
template <typename O> friend class Span; | |||||
}; | }; | ||||
/** Create a span to a container exposing data() and size(). | /** Create a span to a container exposing data() and size(). | ||||
* | * | ||||
* This correctly deals with constness: the returned Span's element type will be | * This correctly deals with constness: the returned Span's element type will be | ||||
* whatever data() returns a pointer to. If either the passed container is | * whatever data() returns a pointer to. If either the passed container is | ||||
* const, or its element type is const, the resulting span will have a const | * const, or its element type is const, the resulting span will have a const | ||||
* element type. | * element type. | ||||
Show All 27 Lines |