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