Created
January 20, 2022 15:38
-
-
Save Naios/dd523d3361ea2f3836697e32e860a92a to your computer and use it in GitHub Desktop.
A simple span polyfill
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template <typename T> | |
class Span { | |
public: | |
using size_type = std::size_t; | |
using value_type = std::remove_const_t<T>; | |
using pointer = std::add_pointer_t<T>; | |
using const_pointer = std::add_pointer_t<std::add_const_t<T>>; | |
using reference = std::add_lvalue_reference_t<T>; | |
using const_reference = std::add_lvalue_reference_t<std::add_const_t<T>>; | |
using difference_type = std::ptrdiff_t; | |
constexpr Span() noexcept | |
: Span(nullptr, 0) { | |
// Also a clang compiler bug workaround for empty default constructors | |
// https://stackoverflow.com/questions/43819314/default-member-initializer-needed-within-definition-of-enclosing-class-outside | |
} | |
template <std::size_t Size> | |
/* implicit */ constexpr Span(T (&data)[Size]) noexcept | |
: Span(data, Size) {} | |
constexpr Span(pointer data, size_type size) noexcept | |
: data_(data) | |
, size_(size) {} | |
template <typename C, | |
decltype(const_pointer(std::declval<C>().data()))* = nullptr, | |
decltype(size_type(std::declval<C>().size()))* = nullptr> | |
/* implicit */ constexpr Span(C&& src) noexcept( | |
noexcept(std::declval<C>().data()) && noexcept(std::declval<C>().size())) | |
: Span(src.data(), src.size()) {} | |
T* begin() const noexcept { | |
return data(); | |
} | |
T* end() const noexcept { | |
return data() + size(); | |
} | |
T* data() const noexcept { | |
return data_; | |
} | |
std::size_t size() const noexcept { | |
return size_; | |
} | |
private: | |
T* data_{}; | |
std::size_t size_{}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment