Warning, /include/gsl/span_ext is written in an unsupported language. File is not indexed.
0001 ///////////////////////////////////////////////////////////////////////////////
0002 //
0003 // Copyright (c) 2015 Microsoft Corporation. All rights reserved.
0004 //
0005 // This code is licensed under the MIT License (MIT).
0006 //
0007 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0008 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0009 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0010 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0011 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0012 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
0013 // THE SOFTWARE.
0014 //
0015 ///////////////////////////////////////////////////////////////////////////////
0016
0017 #ifndef GSL_SPAN_EXT_H
0018 #define GSL_SPAN_EXT_H
0019
0020 ///////////////////////////////////////////////////////////////////////////////
0021 //
0022 // File: span_ext
0023 // Purpose: continue offering features that have been cut from the official
0024 // implementation of span.
0025 // While modernizing gsl::span a number of features needed to be removed to
0026 // be compliant with the design of std::span
0027 //
0028 ///////////////////////////////////////////////////////////////////////////////
0029
0030 #include <gsl/assert> // GSL_KERNEL_MODE
0031 #include <gsl/util> // for narrow_cast, narrow
0032
0033 #include <cstddef> // for ptrdiff_t, size_t
0034 #include <utility>
0035
0036 #ifndef GSL_KERNEL_MODE
0037 #include <algorithm> // for lexicographical_compare
0038 #endif // GSL_KERNEL_MODE
0039
0040 namespace gsl
0041 {
0042
0043 // [span.views.constants], constants
0044 constexpr const std::size_t dynamic_extent = narrow_cast<std::size_t>(-1);
0045
0046 template <class ElementType, std::size_t Extent = dynamic_extent>
0047 class span;
0048
0049 // std::equal and std::lexicographical_compare are not /kernel compatible
0050 // so all comparison operators must be removed for kernel mode.
0051 #ifndef GSL_KERNEL_MODE
0052
0053 // [span.comparison], span comparison operators
0054 template <class ElementType, std::size_t FirstExtent, std::size_t SecondExtent>
0055 constexpr bool operator==(span<ElementType, FirstExtent> l, span<ElementType, SecondExtent> r)
0056 {
0057 return std::equal(l.begin(), l.end(), r.begin(), r.end());
0058 }
0059
0060 template <class ElementType, std::size_t Extent>
0061 constexpr bool operator!=(span<ElementType, Extent> l, span<ElementType, Extent> r)
0062 {
0063 return !(l == r);
0064 }
0065
0066 template <class ElementType, std::size_t Extent>
0067 constexpr bool operator<(span<ElementType, Extent> l, span<ElementType, Extent> r)
0068 {
0069 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
0070 }
0071
0072 template <class ElementType, std::size_t Extent>
0073 constexpr bool operator<=(span<ElementType, Extent> l, span<ElementType, Extent> r)
0074 {
0075 return !(l > r);
0076 }
0077
0078 template <class ElementType, std::size_t Extent>
0079 constexpr bool operator>(span<ElementType, Extent> l, span<ElementType, Extent> r)
0080 {
0081 return r < l;
0082 }
0083
0084 template <class ElementType, std::size_t Extent>
0085 constexpr bool operator>=(span<ElementType, Extent> l, span<ElementType, Extent> r)
0086 {
0087 return !(l < r);
0088 }
0089
0090 #endif // GSL_KERNEL_MODE
0091
0092 //
0093 // make_span() - Utility functions for creating spans
0094 //
0095 template <class ElementType>
0096 constexpr span<ElementType> make_span(ElementType* ptr, typename span<ElementType>::size_type count)
0097 {
0098 return span<ElementType>(ptr, count);
0099 }
0100
0101 template <class ElementType>
0102 constexpr span<ElementType> make_span(ElementType* firstElem, ElementType* lastElem)
0103 {
0104 return span<ElementType>(firstElem, lastElem);
0105 }
0106
0107 template <class ElementType, std::size_t N>
0108 constexpr span<ElementType, N> make_span(ElementType (&arr)[N]) noexcept
0109 {
0110 return span<ElementType, N>(arr);
0111 }
0112
0113 template <class Container>
0114 constexpr span<typename Container::value_type> make_span(Container& cont)
0115 {
0116 return span<typename Container::value_type>(cont);
0117 }
0118
0119 template <class Container>
0120 constexpr span<const typename Container::value_type> make_span(const Container& cont)
0121 {
0122 return span<const typename Container::value_type>(cont);
0123 }
0124
0125 template <class Ptr>
0126 constexpr span<typename Ptr::element_type> make_span(Ptr& cont, std::size_t count)
0127 {
0128 return span<typename Ptr::element_type>(cont, count);
0129 }
0130
0131 template <class Ptr>
0132 constexpr span<typename Ptr::element_type> make_span(Ptr& cont)
0133 {
0134 return span<typename Ptr::element_type>(cont);
0135 }
0136
0137 // Specialization of gsl::at for span
0138 template <class ElementType, std::size_t Extent>
0139 constexpr ElementType& at(span<ElementType, Extent> s, index i)
0140 {
0141 // No bounds checking here because it is done in span::operator[] called below
0142 Ensures(i >= 0);
0143 return s[narrow_cast<std::size_t>(i)];
0144 }
0145
0146 // [span.obs] Free observer functions
0147 template <class ElementType, std::size_t Extent>
0148 constexpr std::ptrdiff_t ssize(const span<ElementType, Extent>& s) noexcept
0149 {
0150 return static_cast<std::ptrdiff_t>(s.size());
0151 }
0152
0153 // [span.iter] Free functions for begin/end functions
0154 template <class ElementType, std::size_t Extent>
0155 constexpr typename span<ElementType, Extent>::iterator
0156 begin(const span<ElementType, Extent>& s) noexcept
0157 {
0158 return s.begin();
0159 }
0160
0161 template <class ElementType, std::size_t Extent = dynamic_extent>
0162 constexpr typename span<ElementType, Extent>::iterator
0163 end(const span<ElementType, Extent>& s) noexcept
0164 {
0165 return s.end();
0166 }
0167
0168 template <class ElementType, std::size_t Extent>
0169 constexpr typename span<ElementType, Extent>::reverse_iterator
0170 rbegin(const span<ElementType, Extent>& s) noexcept
0171 {
0172 return s.rbegin();
0173 }
0174
0175 template <class ElementType, std::size_t Extent>
0176 constexpr typename span<ElementType, Extent>::reverse_iterator
0177 rend(const span<ElementType, Extent>& s) noexcept
0178 {
0179 return s.rend();
0180 }
0181
0182 template <class ElementType, std::size_t Extent>
0183 constexpr typename span<ElementType, Extent>::iterator
0184 cbegin(const span<ElementType, Extent>& s) noexcept
0185 {
0186 return s.begin();
0187 }
0188
0189 template <class ElementType, std::size_t Extent = dynamic_extent>
0190 constexpr typename span<ElementType, Extent>::iterator
0191 cend(const span<ElementType, Extent>& s) noexcept
0192 {
0193 return s.end();
0194 }
0195
0196 template <class ElementType, std::size_t Extent>
0197 constexpr typename span<ElementType, Extent>::reverse_iterator
0198 crbegin(const span<ElementType, Extent>& s) noexcept
0199 {
0200 return s.rbegin();
0201 }
0202
0203 template <class ElementType, std::size_t Extent>
0204 constexpr typename span<ElementType, Extent>::reverse_iterator
0205 crend(const span<ElementType, Extent>& s) noexcept
0206 {
0207 return s.rend();
0208 }
0209
0210 } // namespace gsl
0211
0212 #endif // GSL_SPAN_EXT_H