zengine-old/engine/3rdparty/zlib/include/zstd/span.h

136 lines
3.5 KiB
C
Raw Permalink Normal View History

2024-06-16 22:52:45 +08:00
#pragma once
#include <utility>
#include <iterator>
namespace zstd
{
namespace detail
{
template<typename T, typename = void>
struct is_contiguous_container : std::false_type {};
template<typename T>
struct is_contiguous_container<T, std::void_t<decltype(
std::data(std::declval<T&>()),
std::size(std::declval<T&>())
)>> : std::true_type {};
template<typename T> constexpr auto is_contiguous_container_v = is_contiguous_container<T>::value;
}
template <typename T>
struct span
{
static constexpr auto npos = static_cast<size_t>(-1);
using element_type = T;
using value_type = std::remove_cv_t<T>;
using size_t = std::size_t;
using difference_type = std::ptrdiff_t;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
using iterator = T*;
using const_iterator = const T*;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
T* _begin = nullptr;
T* _end = nullptr;
constexpr span() noexcept = default;
constexpr span(T* begin, T* end) noexcept;
template <typename Container, typename = std::enable_if_t<detail::is_contiguous_container_v<Container>
&& std::is_convertible_v<decltype(std::data(std::declval<Container&>())), T*>
&& !std::is_same_v<std::decay_t<Container>, span>>>
constexpr span(Container&& c) noexcept;
constexpr span(const span&) noexcept = default;
// element access
constexpr T& operator[](size_t index) const noexcept;
constexpr T& front() const noexcept;
constexpr T& back() const noexcept;
constexpr T* data() const noexcept;
// iterators
constexpr T* begin() const noexcept;
constexpr T* end() const noexcept;
// subviews
constexpr span<T> subspan(size_t offset, size_t count = npos) const noexcept;
// capacity
constexpr size_t size() const noexcept;
constexpr size_t size_bytes() const noexcept;
constexpr bool empty() const noexcept;
};
//User defined deduction guide (C++17 onwards)
template<typename Container>
span(Container&&) -> span < std::remove_reference_t<decltype(*std::declval<Container>().data())>>;
template<typename T>
constexpr span<T>::span(T* begin, T* end) noexcept
: _begin{ begin }, _end{ end }
{}
template<typename T>
template<typename Container, typename>
constexpr span<T>::span(Container&& c) noexcept
: _begin{ std::data(c) }, _end{ std::data(c) + std::size(c) }
{
}
template<typename T>
constexpr T* span<T>::begin() const noexcept
{
return _begin;
}
template<typename T>
constexpr T* span<T>::end() const noexcept
{
return _end;
}
template<typename T>
inline constexpr span<T> span<T>::subspan(size_t offset, size_t count) const noexcept
{
return span<T>{_begin + offset, count != npos ? _begin + offset + count : _end};
}
template<typename T>
inline constexpr T* span<T>::data() const noexcept
{
return _begin;
}
template<typename T>
constexpr size_t span<T>::size() const noexcept
{
return _end - _begin;
}
template<typename T>
inline constexpr size_t span<T>::size_bytes() const noexcept
{
return size() * sizeof(T);
}
template<typename T>
inline constexpr bool span<T>::empty() const noexcept
{
return _begin == _end;
}
template<typename T>
constexpr T& span<T>::operator[](size_t index) const noexcept
{
return _begin[index];
}
template<typename T>
inline constexpr T& span<T>::front() const noexcept
{
return *_begin;
}
template<typename T>
inline constexpr T& span<T>::back() const noexcept
{
return _end[-1];
}
}