Add a span class to act as a view to contiguous data
This commit is contained in:
parent
e3d6f3d988
commit
a4af617532
@ -646,6 +646,7 @@ SET(COMMON_OBJS
|
|||||||
common/almalloc.cpp
|
common/almalloc.cpp
|
||||||
common/almalloc.h
|
common/almalloc.h
|
||||||
common/alnumeric.h
|
common/alnumeric.h
|
||||||
|
common/alspan.h
|
||||||
common/atomic.h
|
common/atomic.h
|
||||||
common/math_defs.h
|
common/math_defs.h
|
||||||
common/opthelpers.h
|
common/opthelpers.h
|
||||||
|
105
common/alspan.h
Normal file
105
common/alspan.h
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
#ifndef AL_SPAN_H
|
||||||
|
#define AL_SPAN_H
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <initializer_list>
|
||||||
|
|
||||||
|
namespace al {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr auto size(T &cont) -> decltype(cont.size())
|
||||||
|
{ return cont.size(); }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr auto size(const T &cont) -> decltype(cont.size())
|
||||||
|
{ return cont.size(); }
|
||||||
|
|
||||||
|
template<typename T, size_t N>
|
||||||
|
constexpr size_t size(T (&)[N]) noexcept
|
||||||
|
{ return N; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr size_t size(std::initializer_list<T> list) noexcept
|
||||||
|
{ return list.size(); }
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr auto data(T &cont) -> decltype(cont.data())
|
||||||
|
{ return cont.data(); }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr auto data(const T &cont) -> decltype(cont.data())
|
||||||
|
{ return cont.data(); }
|
||||||
|
|
||||||
|
template<typename T, size_t N>
|
||||||
|
constexpr T* data(T (&arr)[N]) noexcept
|
||||||
|
{ return arr; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr const T* data(std::initializer_list<T> list) noexcept
|
||||||
|
{ return list.begin(); }
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class span {
|
||||||
|
public:
|
||||||
|
using element_type = T;
|
||||||
|
using value_type = typename std::remove_cv<T>::type;
|
||||||
|
using index_type = size_t;
|
||||||
|
using difference_type = ptrdiff_t;
|
||||||
|
|
||||||
|
using pointer = T*;
|
||||||
|
using const_pointer = const T*;
|
||||||
|
using reference = T&;
|
||||||
|
using const_reference = const T&;
|
||||||
|
|
||||||
|
using iterator = pointer;
|
||||||
|
using const_iterator = const_pointer;
|
||||||
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||||
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
|
|
||||||
|
constexpr span() noexcept = default;
|
||||||
|
constexpr span(pointer ptr, index_type count) : mData{ptr}, mCount{count} { }
|
||||||
|
constexpr span(pointer first, pointer last) : mData{first}, mCount{std::distance(first, last)} { }
|
||||||
|
template<size_t N>
|
||||||
|
constexpr span(element_type (&arr)[N]) noexcept : span{al::data(arr), al::size(arr)} { }
|
||||||
|
template<size_t N>
|
||||||
|
constexpr span(std::array<value_type,N> &arr) noexcept : span{al::data(arr), al::size(arr)} { }
|
||||||
|
template<size_t N>
|
||||||
|
constexpr span(const std::array<value_type,N> &arr) noexcept : span{al::data(arr), al::size(arr)} { }
|
||||||
|
template<typename U>
|
||||||
|
constexpr span(U &cont) : span{al::data(cont), al::size(cont)} { }
|
||||||
|
template<typename U>
|
||||||
|
constexpr span(const U &cont) : span{al::data(cont), al::size(cont)} { }
|
||||||
|
constexpr span(const span&) noexcept = default;
|
||||||
|
|
||||||
|
span& operator=(const span &rhs) noexcept = default;
|
||||||
|
|
||||||
|
constexpr reference front() const { return mData[0]; }
|
||||||
|
constexpr reference back() const { return mData[mCount-1]; }
|
||||||
|
constexpr reference operator[](index_type idx) const { return mData[idx]; }
|
||||||
|
constexpr pointer data() const noexcept { return mData; }
|
||||||
|
|
||||||
|
constexpr index_type size() const noexcept { return mCount; }
|
||||||
|
constexpr index_type size_bytes() const noexcept { return mCount * sizeof(value_type); }
|
||||||
|
constexpr bool empty() const noexcept { return mCount == 0; }
|
||||||
|
|
||||||
|
constexpr iterator begin() const noexcept { return mData; }
|
||||||
|
constexpr iterator end() const noexcept { return mData + mCount; }
|
||||||
|
constexpr const_iterator cbegin() const noexcept { return mData; }
|
||||||
|
constexpr const_iterator cend() const noexcept { return mData + mCount; }
|
||||||
|
|
||||||
|
constexpr reverse_iterator rbegin() const noexcept { return end(); }
|
||||||
|
constexpr reverse_iterator rend() const noexcept { return begin(); }
|
||||||
|
constexpr const_reverse_iterator crbegin() const noexcept { return cend(); }
|
||||||
|
constexpr const_reverse_iterator crend() const noexcept { return cbegin(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
pointer mData{nullptr};
|
||||||
|
index_type mCount{0u};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace al
|
||||||
|
|
||||||
|
#endif /* AL_SPAN_H */
|
Loading…
x
Reference in New Issue
Block a user