#pragma once #include #include namespace zstd { namespace detail { template struct is_contiguous_container : std::false_type {}; template struct is_contiguous_container()), std::size(std::declval()) )>> : std::true_type {}; template constexpr auto is_contiguous_container_v = is_contiguous_container::value; } template struct span { static constexpr auto npos = static_cast(-1); using element_type = T; using value_type = std::remove_cv_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; using const_reverse_iterator = std::reverse_iterator; T* _begin = nullptr; T* _end = nullptr; constexpr span() noexcept = default; constexpr span(T* begin, T* end) noexcept; template && std::is_convertible_v())), T*> && !std::is_same_v, 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 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 span(Container&&) -> span < std::remove_reference_t().data())>>; template constexpr span::span(T* begin, T* end) noexcept : _begin{ begin }, _end{ end } {} template template constexpr span::span(Container&& c) noexcept : _begin{ std::data(c) }, _end{ std::data(c) + std::size(c) } { } template constexpr T* span::begin() const noexcept { return _begin; } template constexpr T* span::end() const noexcept { return _end; } template inline constexpr span span::subspan(size_t offset, size_t count) const noexcept { return span{_begin + offset, count != npos ? _begin + offset + count : _end}; } template inline constexpr T* span::data() const noexcept { return _begin; } template constexpr size_t span::size() const noexcept { return _end - _begin; } template inline constexpr size_t span::size_bytes() const noexcept { return size() * sizeof(T); } template inline constexpr bool span::empty() const noexcept { return _begin == _end; } template constexpr T& span::operator[](size_t index) const noexcept { return _begin[index]; } template inline constexpr T& span::front() const noexcept { return *_begin; } template inline constexpr T& span::back() const noexcept { return _end[-1]; } }