199 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			199 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| ///////////////////////////////////////////////////////////////////////////////
 | |
| //
 | |
| // Copyright (c) 2015 Microsoft Corporation. All rights reserved.
 | |
| //
 | |
| // This code is licensed under the MIT License (MIT).
 | |
| //
 | |
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | |
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | |
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | |
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | |
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | |
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | |
| // THE SOFTWARE.
 | |
| //
 | |
| ///////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| #ifndef GSL_SPAN_EXT_H
 | |
| #define GSL_SPAN_EXT_H
 | |
| 
 | |
| ///////////////////////////////////////////////////////////////////////////////
 | |
| //
 | |
| // File: span_ext
 | |
| // Purpose: continue offering features that have been cut from the official
 | |
| //   implementation of span.
 | |
| //   While modernizing gsl::span a number of features needed to be removed to
 | |
| //   be compliant with the design of std::span
 | |
| //
 | |
| ///////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| 
 | |
| #include <gsl/gsl_util> // for narrow_cast, narrow
 | |
| #include <gsl/span>     // for span
 | |
| 
 | |
| #include <algorithm> // for lexicographical_compare
 | |
| #include <cstddef>   // for ptrdiff_t, size_t
 | |
| #include <utility>
 | |
| 
 | |
| namespace gsl
 | |
| {
 | |
| 
 | |
| // [span.comparison], span comparison operators
 | |
| template <class ElementType, std::size_t FirstExtent, std::size_t SecondExtent>
 | |
| constexpr bool operator==(span<ElementType, FirstExtent> l, span<ElementType, SecondExtent> r)
 | |
| {
 | |
|     return std::equal(l.begin(), l.end(), r.begin(), r.end());
 | |
| }
 | |
| 
 | |
| template <class ElementType, std::size_t Extent>
 | |
| constexpr bool operator!=(span<ElementType, Extent> l, span<ElementType, Extent> r)
 | |
| {
 | |
|     return !(l == r);
 | |
| }
 | |
| 
 | |
| template <class ElementType, std::size_t Extent>
 | |
| constexpr bool operator<(span<ElementType, Extent> l, span<ElementType, Extent> r)
 | |
| {
 | |
|     return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
 | |
| }
 | |
| 
 | |
| template <class ElementType, std::size_t Extent>
 | |
| constexpr bool operator<=(span<ElementType, Extent> l, span<ElementType, Extent> r)
 | |
| {
 | |
|     return !(l > r);
 | |
| }
 | |
| 
 | |
| template <class ElementType, std::size_t Extent>
 | |
| constexpr bool operator>(span<ElementType, Extent> l, span<ElementType, Extent> r)
 | |
| {
 | |
|     return r < l;
 | |
| }
 | |
| 
 | |
| template <class ElementType, std::size_t Extent>
 | |
| constexpr bool operator>=(span<ElementType, Extent> l, span<ElementType, Extent> r)
 | |
| {
 | |
|     return !(l < r);
 | |
| }
 | |
| 
 | |
| //
 | |
| // make_span() - Utility functions for creating spans
 | |
| //
 | |
| template <class ElementType>
 | |
| constexpr span<ElementType> make_span(ElementType* ptr, typename span<ElementType>::size_type count)
 | |
| {
 | |
|     return span<ElementType>(ptr, count);
 | |
| }
 | |
| 
 | |
| template <class ElementType>
 | |
| constexpr span<ElementType> make_span(ElementType* firstElem, ElementType* lastElem)
 | |
| {
 | |
|     return span<ElementType>(firstElem, lastElem);
 | |
| }
 | |
| 
 | |
| template <class ElementType, std::size_t N>
 | |
| constexpr span<ElementType, N> make_span(ElementType (&arr)[N]) noexcept
 | |
| {
 | |
|     return span<ElementType, N>(arr);
 | |
| }
 | |
| 
 | |
| template <class Container>
 | |
| constexpr span<typename Container::value_type> make_span(Container& cont)
 | |
| {
 | |
|     return span<typename Container::value_type>(cont);
 | |
| }
 | |
| 
 | |
| template <class Container>
 | |
| constexpr span<const typename Container::value_type> make_span(const Container& cont)
 | |
| {
 | |
|     return span<const typename Container::value_type>(cont);
 | |
| }
 | |
| 
 | |
| template <class Ptr>
 | |
| constexpr span<typename Ptr::element_type> make_span(Ptr& cont, std::size_t count)
 | |
| {
 | |
|     return span<typename Ptr::element_type>(cont, count);
 | |
| }
 | |
| 
 | |
| template <class Ptr>
 | |
| constexpr span<typename Ptr::element_type> make_span(Ptr& cont)
 | |
| {
 | |
|     return span<typename Ptr::element_type>(cont);
 | |
| }
 | |
| 
 | |
| // Specialization of gsl::at for span
 | |
| template <class ElementType, std::size_t Extent>
 | |
| constexpr ElementType& at(span<ElementType, Extent> s, index i)
 | |
| {
 | |
|     // No bounds checking here because it is done in span::operator[] called below
 | |
|     Ensures(i >= 0);
 | |
|     return s[narrow_cast<std::size_t>(i)];
 | |
| }
 | |
| 
 | |
| // [span.obs] Free observer functions
 | |
| template <class ElementType, std::size_t Extent>
 | |
| constexpr std::ptrdiff_t ssize(const span<ElementType, Extent>& s) noexcept
 | |
| {
 | |
|     return static_cast<std::ptrdiff_t>(s.size());
 | |
| }
 | |
| 
 | |
| // [span.iter] Free functions for begin/end functions
 | |
| template <class ElementType, std::size_t Extent>
 | |
| constexpr typename span<ElementType, Extent>::iterator
 | |
| begin(const span<ElementType, Extent>& s) noexcept
 | |
| {
 | |
|     return s.begin();
 | |
| }
 | |
| 
 | |
| template <class ElementType, std::size_t Extent = dynamic_extent>
 | |
| constexpr typename span<ElementType, Extent>::iterator
 | |
| end(const span<ElementType, Extent>& s) noexcept
 | |
| {
 | |
|     return s.end();
 | |
| }
 | |
| 
 | |
| template <class ElementType, std::size_t Extent>
 | |
| constexpr typename span<ElementType, Extent>::reverse_iterator
 | |
| rbegin(const span<ElementType, Extent>& s) noexcept
 | |
| {
 | |
|     return s.rbegin();
 | |
| }
 | |
| 
 | |
| template <class ElementType, std::size_t Extent>
 | |
| constexpr typename span<ElementType, Extent>::reverse_iterator
 | |
| rend(const span<ElementType, Extent>& s) noexcept
 | |
| {
 | |
|     return s.rend();
 | |
| }
 | |
| 
 | |
| template <class ElementType, std::size_t Extent>
 | |
| constexpr typename span<ElementType, Extent>::iterator
 | |
| cbegin(const span<ElementType, Extent>& s) noexcept
 | |
| {
 | |
|     return s.begin();
 | |
| }
 | |
| 
 | |
| template <class ElementType, std::size_t Extent = dynamic_extent>
 | |
| constexpr typename span<ElementType, Extent>::iterator
 | |
| cend(const span<ElementType, Extent>& s) noexcept
 | |
| {
 | |
|     return s.end();
 | |
| }
 | |
| 
 | |
| template <class ElementType, std::size_t Extent>
 | |
| constexpr typename span<ElementType, Extent>::reverse_iterator
 | |
| crbegin(const span<ElementType, Extent>& s) noexcept
 | |
| {
 | |
|     return s.rbegin();
 | |
| }
 | |
| 
 | |
| template <class ElementType, std::size_t Extent>
 | |
| constexpr typename span<ElementType, Extent>::reverse_iterator
 | |
| crend(const span<ElementType, Extent>& s) noexcept
 | |
| {
 | |
|     return s.rend();
 | |
| }
 | |
| 
 | |
| } // namespace gsl
 | |
| 
 | |
| #endif // GSL_SPAN_EXT_H
 |