136 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			136 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								#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];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |