// // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // Official repository: https://github.com/boostorg/beast // #ifndef MYX_BACKPORTS_CPP_SPAN_HPP_ #define MYX_BACKPORTS_CPP_SPAN_HPP_ #pragma once #if ( __cplusplus >= 201103L ) && ( __cplusplus < 201703L ) #include #include #include #include #include namespace std { template< class T, class E, class = void > struct is_contiguous_container : std::false_type {}; // NOLINT template< class T, class E > struct is_contiguous_container< T, E, void_t< decltype( std::declval< std::size_t& >() = std::declval< T const& >().size(), std::declval< E*& >() = std::declval< T& >().data() ), typename std::enable_if< std::is_same< typename std::remove_cv< E >::type, typename std::remove_cv< typename std::remove_pointer< decltype( std::declval< T& >().data() ) >::type >::type >::value >::type > > : std::true_type {}; /** A range of bytes expressed as a ContiguousContainer This class implements a non-owning reference to a storage area of a certain size and having an underlying integral type with size of 1. @tparam T The type pointed to by span iterators */ template< class T > class span // NOLINT { T* m_data = nullptr; std::size_t m_size = 0; public: /// The type of value, including cv qualifiers using ElementType = T; /// The type of value of each span element using ValueType = typename std::remove_const< T >::type; /// The type of integer used to index the span using IndexType = std::ptrdiff_t; /// A pointer to a span element using Pointer = T*; /// A reference to a span element using Reference = T&; /// The iterator used by the container using Iterator = Pointer; /// The const pointer used by the container using ConstPointer = T const*; /// The const reference used by the container using ConstReference = T const&; /// The const iterator used by the container using ConstIterator = ConstPointer; /// Constructor span() = default; /// Constructor span( span const& ) = default; /// Assignment span& operator=( span const& ) = default; /** Constructor * @param data A pointer to the beginning of the range of elements * @param size The number of elements pointed to by `data` */ span( T* data, std::size_t size ) : m_data( data ), m_size( size ) { } /** Constructor * @param container The container to construct from */ template< class ContiguousContainer, class = typename std::enable_if< is_contiguous_container< ContiguousContainer, T >::value >::type > explicit span( ContiguousContainer&& container ) : m_data( container.data() ), m_size( container.size() ) { } template< class CharT, class Traits, class Allocator > explicit span( std::basic_string< CharT, Traits, Allocator >& s ) : m_data( &s[0] ), m_size( s.size() ) { } template< class CharT, class Traits, class Allocator > explicit span( std::basic_string< CharT, Traits, Allocator > const& s ) : m_data( s.data() ), m_size( s.size() ) { } /** Assignment * @param container The container to assign from */ template< class ContiguousContainer > typename std::enable_if< is_contiguous_container< //NOLINT ContiguousContainer, T >::value, span& >::type operator=( ContiguousContainer&& container ) { m_data = container.data(); m_size = container.size(); return( *this ); } template< class CharT, class Traits, class Allocator > span& operator=( std::basic_string< CharT, Traits, Allocator >& s ) { m_data = &s[0]; m_size = s.size(); return( *this ); } template< class CharT, class Traits, class Allocator > span& operator=( std::basic_string< CharT, Traits, Allocator > const& s ) { m_data = s.data(); m_size = s.size(); return( *this ); } /// Returns `true` if the span is empty bool empty() const { return( m_size == 0 ); } /// Returns a pointer to the beginning of the span T* data() const { return( m_data ); } /// Returns the number of elements in the span std::size_t size() const { return( m_size ); } /// Returns an iterator to the beginning of the span Iterator begin() const { return( m_data ); } /// Returns an iterator to the beginning of the span ConstIterator cbegin() const { return( m_data ); } /// Returns an iterator to one past the end of the span Iterator end() const { return( m_data + m_size ); } /// Returns an iterator to one past the end of the span ConstIterator cend() const { return( m_data + m_size ); } }; // class span } // namespace std #endif // if ( __cplusplus >= 201103L ) && ( __cplusplus < 201703L ) #endif // ifndef MYX_BACKPORTS_CPP_SPAN_HPP_