Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/gsl/string_span 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_STRING_SPAN_H
0018 #define GSL_STRING_SPAN_H
0019 
0020 #include <gsl/assert>   // for Ensures, Expects
0021 #include <gsl/span_ext> // for operator!=, operator==, dynamic_extent
0022 #include <gsl/util>     // for narrow_cast
0023 
0024 #include <algorithm> // for equal, lexicographical_compare
0025 #include <array>     // for array
0026 #include <cstddef>   // for size_t, nullptr_t
0027 #include <cstdint>   // for PTRDIFF_MAX
0028 #include <cstring>
0029 #include <string>      // for basic_string, allocator, char_traits
0030 #include <type_traits> // for declval, is_convertible, enable_if_t, add_...
0031 
0032 #if defined(_MSC_VER) && !defined(__clang__)
0033 #pragma warning(push)
0034 
0035 // Turn MSVC /analyze rules that generate too much noise. TODO: fix in the tool.
0036 #pragma warning(disable : 26446) // TODO: bug in parser - attributes and templates
0037 #pragma warning(disable : 26481) // TODO: suppress does not work inside templates sometimes
0038 #pragma warning(disable : 4996)  // use of functions & classes marked [[deprecated]]
0039 #endif                           // _MSC_VER
0040 
0041 #if defined(__GNUC__) || defined(__clang__)
0042 #pragma GCC diagnostic push
0043 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
0044 #endif
0045 
0046 namespace gsl
0047 {
0048 //
0049 // czstring and wzstring
0050 //
0051 // These are "tag" typedefs for C-style strings (i.e. null-terminated character arrays)
0052 // that allow static analysis to help find bugs.
0053 //
0054 // There are no additional features/semantics that we can find a way to add inside the
0055 // type system for these types that will not either incur significant runtime costs or
0056 // (sometimes needlessly) break existing programs when introduced.
0057 //
0058 
0059 template <typename CharT, std::size_t Extent = dynamic_extent>
0060 using basic_zstring = CharT*;
0061 
0062 using czstring = basic_zstring<const char, dynamic_extent>;
0063 
0064 using cwzstring = basic_zstring<const wchar_t, dynamic_extent>;
0065 
0066 using cu16zstring = basic_zstring<const char16_t, dynamic_extent>;
0067 
0068 using cu32zstring = basic_zstring<const char32_t, dynamic_extent>;
0069 
0070 using zstring = basic_zstring<char, dynamic_extent>;
0071 
0072 using wzstring = basic_zstring<wchar_t, dynamic_extent>;
0073 
0074 using u16zstring = basic_zstring<char16_t, dynamic_extent>;
0075 
0076 using u32zstring = basic_zstring<char32_t, dynamic_extent>;
0077 
0078 namespace details
0079 {
0080     template <class CharT>
0081     [[deprecated("string_span was removed from the C++ Core Guidelines. For more information, see "
0082                  "isocpp/CppCoreGuidelines PR#1680")]] constexpr std::size_t
0083     string_length(const CharT* str, std::size_t n)
0084     {
0085         if (str == nullptr || n == dynamic_extent) return 0;
0086 
0087         const span<const CharT> str_span{str, n};
0088 
0089         std::size_t len = 0;
0090         while (len < n && str_span[len]) len++;
0091 
0092         return len;
0093     }
0094 } // namespace details
0095 
0096 //
0097 // ensure_sentinel()
0098 //
0099 // Provides a way to obtain an span from a contiguous sequence
0100 // that ends with a (non-inclusive) sentinel value.
0101 //
0102 // Will fail-fast if sentinel cannot be found before max elements are examined.
0103 //
0104 template <typename T, const T Sentinel>
0105 [[deprecated("string_span was removed from the C++ Core Guidelines. For more information, see "
0106              "isocpp/CppCoreGuidelines PR#1680")]] constexpr span<T, dynamic_extent>
0107 ensure_sentinel(T* seq, std::size_t max = static_cast<std::size_t>(-1))
0108 {
0109     Ensures(seq != nullptr);
0110 
0111     // clang-format off
0112     GSL_SUPPRESS(f.23) // TODO: false positive // TODO: suppress does not work
0113     // clang-format on
0114     auto cur = seq;
0115     Ensures(cur != nullptr); // workaround for removing the warning
0116 
0117     // clang-format off
0118     GSL_SUPPRESS(bounds.1) // TODO: suppress does not work
0119     // clang-format on
0120     while (static_cast<std::size_t>(cur - seq) < max && *cur != Sentinel) ++cur;
0121     Ensures(*cur == Sentinel);
0122     return {seq, static_cast<std::size_t>(cur - seq)};
0123 }
0124 
0125 //
0126 // ensure_z - creates a span for a zero terminated strings. The span will not contain the zero
0127 // termination. Will fail fast if a null-terminator cannot be found before the limit of size_type.
0128 //
0129 template <typename CharT>
0130 [[deprecated("string_span was removed from the C++ Core Guidelines. For more information, see "
0131              "isocpp/CppCoreGuidelines PR#1680")]] constexpr span<CharT, dynamic_extent>
0132 ensure_z(CharT* const& sz, std::size_t max = static_cast<std::size_t>(-1))
0133 {
0134     return ensure_sentinel<CharT, CharT(0)>(sz, max);
0135 }
0136 
0137 template <typename CharT, std::size_t N>
0138 constexpr span<CharT, dynamic_extent> ensure_z(CharT (&sz)[N])
0139 {
0140     return ensure_z(&sz[0], N);
0141 }
0142 
0143 template <class Cont>
0144 [[deprecated(
0145     "string_span was removed from the C++ Core Guidelines. For more information, see "
0146     "isocpp/CppCoreGuidelines PR#1680")]] constexpr span<typename std::
0147                                                              remove_pointer<
0148                                                                  typename Cont::pointer>::type,
0149                                                          dynamic_extent>
0150 ensure_z(Cont& cont)
0151 {
0152     return ensure_z(cont.data(), cont.size());
0153 }
0154 
0155 template <typename CharT, std::size_t>
0156 class [[deprecated("string_span was removed from the C++ Core Guidelines. For more information, "
0157                    "see isocpp/CppCoreGuidelines PR#1680")]] basic_string_span;
0158 
0159 namespace details
0160 {
0161     template <typename T>
0162     struct [[deprecated(
0163         "string_span was removed from the C++ Core Guidelines. For more information, "
0164         "see isocpp/CppCoreGuidelines PR#1680")]] is_basic_string_span_oracle : std::false_type{};
0165 
0166     template <typename CharT, std::size_t Extent>
0167     struct [[deprecated(
0168         "string_span was removed from the C++ Core Guidelines. For more information, see "
0169         "isocpp/CppCoreGuidelines PR#1680")]] is_basic_string_span_oracle<basic_string_span<CharT,
0170                                                                                             Extent>>
0171         : std::true_type{};
0172 
0173     template <typename T>
0174     struct [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
0175                         "information, see isocpp/CppCoreGuidelines PR#1680")]] is_basic_string_span
0176         : is_basic_string_span_oracle<std::remove_cv_t<T>>{};
0177 } // namespace details
0178 
0179 //
0180 // string_span and relatives
0181 //
0182 template <typename CharT, std::size_t Extent = dynamic_extent>
0183 class [[deprecated("string_span was removed from the C++ Core Guidelines. For more information, "
0184                    "see isocpp/CppCoreGuidelines PR#1680")]] basic_string_span
0185 {
0186 public:
0187     using element_type = CharT;
0188     using value_type = std::remove_cv_t<element_type>;
0189     using pointer = std::add_pointer_t<element_type>;
0190     using reference = std::add_lvalue_reference_t<element_type>;
0191     using const_reference = std::add_lvalue_reference_t<std::add_const_t<element_type>>;
0192     using impl_type = span<element_type, Extent>;
0193 
0194     using size_type = typename impl_type::size_type;
0195     using iterator = typename impl_type::iterator;
0196     using reverse_iterator = typename impl_type::reverse_iterator;
0197 
0198     // default (empty)
0199     constexpr basic_string_span() noexcept = default;
0200 
0201     // copy
0202     constexpr basic_string_span(const basic_string_span& other) noexcept = default;
0203 
0204     // assign
0205     constexpr basic_string_span& operator=(const basic_string_span& other) noexcept = default;
0206 
0207     constexpr basic_string_span(pointer ptr, size_type length) : span_(ptr, length) {}
0208     constexpr basic_string_span(pointer firstElem, pointer lastElem) : span_(firstElem, lastElem) {}
0209 
0210     // From static arrays - if 0-terminated, remove 0 from the view
0211     // All other containers allow 0s within the length, so we do not remove them
0212     template <std::size_t N>
0213     constexpr basic_string_span(element_type(&arr)[N]) : span_(remove_z(arr))
0214     {}
0215 
0216     template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>>
0217     constexpr basic_string_span(std::array<ArrayElementType, N> & arr) noexcept : span_(arr)
0218     {}
0219 
0220     template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>>
0221     constexpr basic_string_span(const std::array<ArrayElementType, N>& arr) noexcept : span_(arr)
0222     {}
0223 
0224     // Container signature should work for basic_string after C++17 version exists
0225     template <class Traits, class Allocator>
0226     // GSL_SUPPRESS(bounds.4) // TODO: parser bug
0227     constexpr basic_string_span(std::basic_string<element_type, Traits, Allocator> & str)
0228         : span_(&str[0], str.length())
0229     {}
0230 
0231     template <class Traits, class Allocator>
0232     constexpr basic_string_span(const std::basic_string<element_type, Traits, Allocator>& str)
0233         : span_(&str[0], str.length())
0234     {}
0235 
0236     // from containers. Containers must have a pointer type and data() function signatures
0237     template <class Container,
0238               class = std::enable_if_t<
0239                   !details::is_basic_string_span<Container>::value &&
0240                   std::is_convertible<typename Container::pointer, pointer>::value &&
0241                   std::is_convertible<typename Container::pointer,
0242                                       decltype(std::declval<Container>().data())>::value>>
0243     constexpr basic_string_span(Container & cont) : span_(cont)
0244     {}
0245 
0246     template <class Container,
0247               class = std::enable_if_t<
0248                   !details::is_basic_string_span<Container>::value &&
0249                   std::is_convertible<typename Container::pointer, pointer>::value &&
0250                   std::is_convertible<typename Container::pointer,
0251                                       decltype(std::declval<Container>().data())>::value>>
0252     constexpr basic_string_span(const Container& cont) : span_(cont)
0253     {}
0254 
0255     // from string_span
0256     template <
0257         class OtherValueType, std::size_t OtherExtent,
0258         class = std::enable_if_t<std::is_convertible<
0259             typename basic_string_span<OtherValueType, OtherExtent>::impl_type, impl_type>::value>>
0260     constexpr basic_string_span(basic_string_span<OtherValueType, OtherExtent> other)
0261         : span_(other.data(), other.length())
0262     {}
0263 
0264     template <size_type Count>
0265     constexpr basic_string_span<element_type, Count> first() const
0266     {
0267         return {span_.template first<Count>()};
0268     }
0269 
0270     constexpr basic_string_span<element_type, dynamic_extent> first(size_type count) const
0271     {
0272         return {span_.first(count)};
0273     }
0274 
0275     template <size_type Count>
0276     constexpr basic_string_span<element_type, Count> last() const
0277     {
0278         return {span_.template last<Count>()};
0279     }
0280 
0281     constexpr basic_string_span<element_type, dynamic_extent> last(size_type count) const
0282     {
0283         return {span_.last(count)};
0284     }
0285 
0286     template <size_type Offset, size_type Count>
0287     constexpr basic_string_span<element_type, Count> subspan() const
0288     {
0289         return {span_.template subspan<Offset, Count>()};
0290     }
0291 
0292     constexpr basic_string_span<element_type, dynamic_extent> subspan(
0293         size_type offset, size_type count = dynamic_extent) const
0294     {
0295         return {span_.subspan(offset, count)};
0296     }
0297 
0298     constexpr reference operator[](size_type idx) const { return span_[idx]; }
0299     constexpr reference operator()(size_type idx) const { return span_[idx]; }
0300 
0301     constexpr pointer data() const { return span_.data(); }
0302 
0303     constexpr size_type length() const noexcept { return span_.size(); }
0304     constexpr size_type size() const noexcept { return span_.size(); }
0305     constexpr size_type size_bytes() const noexcept { return span_.size_bytes(); }
0306     constexpr size_type length_bytes() const noexcept { return span_.length_bytes(); }
0307     constexpr bool empty() const noexcept { return size() == 0; }
0308 
0309     constexpr iterator begin() const noexcept { return span_.begin(); }
0310     constexpr iterator end() const noexcept { return span_.end(); }
0311 
0312     constexpr reverse_iterator rbegin() const noexcept { return span_.rbegin(); }
0313     constexpr reverse_iterator rend() const noexcept { return span_.rend(); }
0314 
0315 private:
0316     static constexpr impl_type remove_z(pointer const& sz, std::size_t max)
0317     {
0318         return impl_type(sz, details::string_length(sz, max));
0319     }
0320 
0321     template <std::size_t N>
0322     static constexpr impl_type remove_z(element_type(&sz)[N])
0323     {
0324         return remove_z(&sz[0], N);
0325     }
0326 
0327     impl_type span_;
0328 };
0329 
0330 template <std::size_t Extent = dynamic_extent>
0331 using string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
0332                                "information, see isocpp/CppCoreGuidelines PR#1680")]] =
0333     basic_string_span<char, Extent>;
0334 
0335 template <std::size_t Extent = dynamic_extent>
0336 using cstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
0337                                 "information, see isocpp/CppCoreGuidelines PR#1680")]] =
0338     basic_string_span<const char, Extent>;
0339 
0340 template <std::size_t Extent = dynamic_extent>
0341 using wstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
0342                                 "information, see isocpp/CppCoreGuidelines PR#1680")]] =
0343     basic_string_span<wchar_t, Extent>;
0344 
0345 template <std::size_t Extent = dynamic_extent>
0346 using cwstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
0347                                  "information, see isocpp/CppCoreGuidelines PR#1680")]] =
0348     basic_string_span<const wchar_t, Extent>;
0349 
0350 template <std::size_t Extent = dynamic_extent>
0351 using u16string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
0352                                   "information, see isocpp/CppCoreGuidelines PR#1680")]] =
0353     basic_string_span<char16_t, Extent>;
0354 
0355 template <std::size_t Extent = dynamic_extent>
0356 using cu16string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
0357                                    "information, see isocpp/CppCoreGuidelines PR#1680")]] =
0358     basic_string_span<const char16_t, Extent>;
0359 
0360 template <std::size_t Extent = dynamic_extent>
0361 using u32string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
0362                                   "information, see isocpp/CppCoreGuidelines PR#1680")]] =
0363     basic_string_span<char32_t, Extent>;
0364 
0365 template <std::size_t Extent = dynamic_extent>
0366 using cu32string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
0367                                    "information, see isocpp/CppCoreGuidelines PR#1680")]] =
0368     basic_string_span<const char32_t, Extent>;
0369 
0370 //
0371 // to_string() allow (explicit) conversions from string_span to string
0372 //
0373 
0374 template <typename CharT, std::size_t Extent>
0375 constexpr std::basic_string<typename std::remove_const<CharT>::type>
0376 to_string(basic_string_span<CharT, Extent> view)
0377 {
0378     return {view.data(), narrow_cast<std::size_t>(view.length())};
0379 }
0380 
0381 template <typename CharT, typename Traits = typename std::char_traits<CharT>,
0382           typename Allocator = std::allocator<CharT>, typename gCharT, std::size_t Extent>
0383 constexpr std::basic_string<CharT, Traits, Allocator>
0384 to_basic_string(basic_string_span<gCharT, Extent> view)
0385 {
0386     return {view.data(), narrow_cast<std::size_t>(view.length())};
0387 }
0388 
0389 template <class ElementType, std::size_t Extent>
0390 constexpr basic_string_span<const byte, details::calculate_byte_size<ElementType, Extent>::value>
0391 as_bytes(basic_string_span<ElementType, Extent> s) noexcept
0392 {
0393     // clang-format off
0394     GSL_SUPPRESS(type.1)
0395     // clang-format on
0396     return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()};
0397 }
0398 
0399 template <class ElementType, std::size_t Extent,
0400           class = std::enable_if_t<!std::is_const<ElementType>::value>>
0401 constexpr basic_string_span<byte, details::calculate_byte_size<ElementType, Extent>::value>
0402 as_writable_bytes(basic_string_span<ElementType, Extent> s) noexcept
0403 {
0404     // clang-format off
0405     GSL_SUPPRESS(type.1)
0406     // clang-format on
0407     return {reinterpret_cast<byte*>(s.data()), s.size_bytes()};
0408 }
0409 
0410 // zero-terminated string span, used to convert
0411 // zero-terminated spans to legacy strings
0412 template <typename CharT, std::size_t Extent = dynamic_extent>
0413 class [[deprecated("string_span was removed from the C++ Core Guidelines. For more information, "
0414                    "see isocpp/CppCoreGuidelines PR#1680")]] basic_zstring_span
0415 {
0416 public:
0417     using value_type = CharT;
0418     using const_value_type = std::add_const_t<CharT>;
0419 
0420     using pointer = std::add_pointer_t<value_type>;
0421     using const_pointer = std::add_pointer_t<const_value_type>;
0422 
0423     using zstring_type = basic_zstring<value_type, Extent>;
0424     using const_zstring_type = basic_zstring<const_value_type, Extent>;
0425 
0426     using impl_type = span<value_type, Extent>;
0427     using string_span_type = basic_string_span<value_type, Extent>;
0428 
0429     constexpr basic_zstring_span(impl_type s) : span_(s)
0430     {
0431         // expects a zero-terminated span
0432         Expects(s.size() > 0);
0433         Expects(s[s.size() - 1] == value_type{});
0434     }
0435 
0436     // copy
0437     constexpr basic_zstring_span(const basic_zstring_span& other) = default;
0438 
0439     // move
0440     constexpr basic_zstring_span(basic_zstring_span && other) = default;
0441 
0442     // assign
0443     constexpr basic_zstring_span& operator=(const basic_zstring_span& other) = default;
0444 
0445     // move assign
0446     constexpr basic_zstring_span& operator=(basic_zstring_span&& other) = default;
0447 
0448     constexpr bool empty() const noexcept { return false; }
0449 
0450     constexpr string_span_type as_string_span() const noexcept
0451     {
0452         return {span_.data(), span_.size() - 1};
0453     }
0454     constexpr string_span_type ensure_z() const { return gsl::ensure_z(span_); }
0455 
0456     constexpr const_zstring_type assume_z() const noexcept { return span_.data(); }
0457 
0458 private:
0459     impl_type span_;
0460 };
0461 
0462 template <std::size_t Max = dynamic_extent>
0463 using zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
0464                                 "information, see isocpp/CppCoreGuidelines PR#1680")]] =
0465     basic_zstring_span<char, Max>;
0466 
0467 template <std::size_t Max = dynamic_extent>
0468 using wzstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
0469                                  "information, see isocpp/CppCoreGuidelines PR#1680")]] =
0470     basic_zstring_span<wchar_t, Max>;
0471 
0472 template <std::size_t Max = dynamic_extent>
0473 using u16zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
0474                                    "information, see isocpp/CppCoreGuidelines PR#1680")]] =
0475     basic_zstring_span<char16_t, Max>;
0476 
0477 template <std::size_t Max = dynamic_extent>
0478 using u32zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
0479                                    "information, see isocpp/CppCoreGuidelines PR#1680")]] =
0480     basic_zstring_span<char32_t, Max>;
0481 
0482 template <std::size_t Max = dynamic_extent>
0483 using czstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
0484                                  "information, see isocpp/CppCoreGuidelines PR#1680")]] =
0485     basic_zstring_span<const char, Max>;
0486 
0487 template <std::size_t Max = dynamic_extent>
0488 using cwzstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
0489                                   "information, see isocpp/CppCoreGuidelines PR#1680")]] =
0490     basic_zstring_span<const wchar_t, Max>;
0491 
0492 template <std::size_t Max = dynamic_extent>
0493 using cu16zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For "
0494                                     "more information, see isocpp/CppCoreGuidelines PR#1680")]] =
0495     basic_zstring_span<const char16_t, Max>;
0496 
0497 template <std::size_t Max = dynamic_extent>
0498 using cu32zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For "
0499                                     "more information, see isocpp/CppCoreGuidelines PR#1680")]] =
0500     basic_zstring_span<const char32_t, Max>;
0501 
0502 // operator ==
0503 template <class CharT, std::size_t Extent, class T,
0504           class = std::enable_if_t<
0505               details::is_basic_string_span<T>::value ||
0506               std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>>>::value>>
0507 bool operator==(const gsl::basic_string_span<CharT, Extent>& one, const T& other)
0508 {
0509     const gsl::basic_string_span<std::add_const_t<CharT>> tmp(other);
0510     return std::equal(one.begin(), one.end(), tmp.begin(), tmp.end());
0511 }
0512 
0513 template <class CharT, std::size_t Extent, class T,
0514           class = std::enable_if_t<
0515               !details::is_basic_string_span<T>::value &&
0516               std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>>>::value>>
0517 bool operator==(const T& one, const gsl::basic_string_span<CharT, Extent>& other)
0518 {
0519     const gsl::basic_string_span<std::add_const_t<CharT>> tmp(one);
0520     return std::equal(tmp.begin(), tmp.end(), other.begin(), other.end());
0521 }
0522 
0523 // operator !=
0524 template <typename CharT, std::size_t Extent = dynamic_extent, typename T,
0525           typename = std::enable_if_t<std::is_convertible<
0526               T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
0527 bool operator!=(gsl::basic_string_span<CharT, Extent> one, const T& other)
0528 {
0529     return !(one == other);
0530 }
0531 
0532 template <
0533     typename CharT, std::size_t Extent = dynamic_extent, typename T,
0534     typename = std::enable_if_t<
0535         std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
0536         !gsl::details::is_basic_string_span<T>::value>>
0537 bool operator!=(const T& one, gsl::basic_string_span<CharT, Extent> other)
0538 {
0539     return !(one == other);
0540 }
0541 
0542 // operator<
0543 template <typename CharT, std::size_t Extent = dynamic_extent, typename T,
0544           typename = std::enable_if_t<std::is_convertible<
0545               T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
0546 bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other)
0547 {
0548     const gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(other);
0549     return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end());
0550 }
0551 
0552 template <
0553     typename CharT, std::size_t Extent = dynamic_extent, typename T,
0554     typename = std::enable_if_t<
0555         std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
0556         !gsl::details::is_basic_string_span<T>::value>>
0557 bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other)
0558 {
0559     gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(one);
0560     return std::lexicographical_compare(tmp.begin(), tmp.end(), other.begin(), other.end());
0561 }
0562 
0563 #ifndef _MSC_VER
0564 
0565 // VS treats temp and const containers as convertible to basic_string_span,
0566 // so the cases below are already covered by the previous operators
0567 
0568 template <
0569     typename CharT, std::size_t Extent = dynamic_extent, typename T,
0570     typename DataType = typename T::value_type,
0571     typename = std::enable_if_t<
0572         !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
0573         std::is_convertible<DataType*, CharT*>::value &&
0574         std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
0575                      DataType>::value>>
0576 bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other)
0577 {
0578     gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(other);
0579     return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end());
0580 }
0581 
0582 template <
0583     typename CharT, std::size_t Extent = dynamic_extent, typename T,
0584     typename DataType = typename T::value_type,
0585     typename = std::enable_if_t<
0586         !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
0587         std::is_convertible<DataType*, CharT*>::value &&
0588         std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
0589                      DataType>::value>>
0590 bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other)
0591 {
0592     gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(one);
0593     return std::lexicographical_compare(tmp.begin(), tmp.end(), other.begin(), other.end());
0594 }
0595 #endif
0596 
0597 // operator <=
0598 template <typename CharT, std::size_t Extent = dynamic_extent, typename T,
0599           typename = std::enable_if_t<std::is_convertible<
0600               T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
0601 bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other)
0602 {
0603     return !(other < one);
0604 }
0605 
0606 template <
0607     typename CharT, std::size_t Extent = dynamic_extent, typename T,
0608     typename = std::enable_if_t<
0609         std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
0610         !gsl::details::is_basic_string_span<T>::value>>
0611 bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other)
0612 {
0613     return !(other < one);
0614 }
0615 
0616 #ifndef _MSC_VER
0617 
0618 // VS treats temp and const containers as convertible to basic_string_span,
0619 // so the cases below are already covered by the previous operators
0620 
0621 template <
0622     typename CharT, std::size_t Extent = dynamic_extent, typename T,
0623     typename DataType = typename T::value_type,
0624     typename = std::enable_if_t<
0625         !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
0626         std::is_convertible<DataType*, CharT*>::value &&
0627         std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
0628                      DataType>::value>>
0629 bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other)
0630 {
0631     return !(other < one);
0632 }
0633 
0634 template <
0635     typename CharT, std::size_t Extent = dynamic_extent, typename T,
0636     typename DataType = typename T::value_type,
0637     typename = std::enable_if_t<
0638         !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
0639         std::is_convertible<DataType*, CharT*>::value &&
0640         std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
0641                      DataType>::value>>
0642 bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other)
0643 {
0644     return !(other < one);
0645 }
0646 #endif
0647 
0648 // operator>
0649 template <typename CharT, std::size_t Extent = dynamic_extent, typename T,
0650           typename = std::enable_if_t<std::is_convertible<
0651               T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
0652 bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other)
0653 {
0654     return other < one;
0655 }
0656 
0657 template <
0658     typename CharT, std::size_t Extent = dynamic_extent, typename T,
0659     typename = std::enable_if_t<
0660         std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
0661         !gsl::details::is_basic_string_span<T>::value>>
0662 bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other)
0663 {
0664     return other < one;
0665 }
0666 
0667 #ifndef _MSC_VER
0668 
0669 // VS treats temp and const containers as convertible to basic_string_span,
0670 // so the cases below are already covered by the previous operators
0671 
0672 template <
0673     typename CharT, std::size_t Extent = dynamic_extent, typename T,
0674     typename DataType = typename T::value_type,
0675     typename = std::enable_if_t<
0676         !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
0677         std::is_convertible<DataType*, CharT*>::value &&
0678         std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
0679                      DataType>::value>>
0680 bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other)
0681 {
0682     return other < one;
0683 }
0684 
0685 template <
0686     typename CharT, std::size_t Extent = dynamic_extent, typename T,
0687     typename DataType = typename T::value_type,
0688     typename = std::enable_if_t<
0689         !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
0690         std::is_convertible<DataType*, CharT*>::value &&
0691         std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
0692                      DataType>::value>>
0693 bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other)
0694 {
0695     return other < one;
0696 }
0697 #endif
0698 
0699 // operator >=
0700 template <typename CharT, std::size_t Extent = dynamic_extent, typename T,
0701           typename = std::enable_if_t<std::is_convertible<
0702               T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
0703 bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other)
0704 {
0705     return !(one < other);
0706 }
0707 
0708 template <
0709     typename CharT, std::size_t Extent = dynamic_extent, typename T,
0710     typename = std::enable_if_t<
0711         std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
0712         !gsl::details::is_basic_string_span<T>::value>>
0713 bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other)
0714 {
0715     return !(one < other);
0716 }
0717 
0718 #ifndef _MSC_VER
0719 
0720 // VS treats temp and const containers as convertible to basic_string_span,
0721 // so the cases below are already covered by the previous operators
0722 
0723 template <
0724     typename CharT, std::size_t Extent = dynamic_extent, typename T,
0725     typename DataType = typename T::value_type,
0726     typename = std::enable_if_t<
0727         !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
0728         std::is_convertible<DataType*, CharT*>::value &&
0729         std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
0730                      DataType>::value>>
0731 bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other)
0732 {
0733     return !(one < other);
0734 }
0735 
0736 template <
0737     typename CharT, std::size_t Extent = dynamic_extent, typename T,
0738     typename DataType = typename T::value_type,
0739     typename = std::enable_if_t<
0740         !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
0741         std::is_convertible<DataType*, CharT*>::value &&
0742         std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
0743                      DataType>::value>>
0744 bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other)
0745 {
0746     return !(one < other);
0747 }
0748 #endif
0749 } // namespace gsl
0750 
0751 #if defined(_MSC_VER) && !defined(__clang__)
0752 #pragma warning(pop)
0753 
0754 #endif // _MSC_VER
0755 
0756 #if defined(__GNUC__) || defined(__clang__)
0757 #pragma GCC diagnostic pop
0758 #endif
0759 #endif // GSL_STRING_SPAN_H