1// -*- C++ -*- 2//===------------------------ string_view ---------------------------------===// 3// 4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5// See https://llvm.org/LICENSE.txt for license information. 6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef _LIBCPP_STRING_VIEW 11#define _LIBCPP_STRING_VIEW 12 13/* 14string_view synopsis 15 16namespace std { 17 18 // 7.2, Class template basic_string_view 19 template<class charT, class traits = char_traits<charT>> 20 class basic_string_view; 21 22 template<class charT, class traits> 23 inline constexpr bool ranges::enable_borrowed_range<basic_string_view<charT, traits>> = true; // C++20 24 25 // 7.9, basic_string_view non-member comparison functions 26 template<class charT, class traits> 27 constexpr bool operator==(basic_string_view<charT, traits> x, 28 basic_string_view<charT, traits> y) noexcept; 29 template<class charT, class traits> 30 constexpr bool operator!=(basic_string_view<charT, traits> x, 31 basic_string_view<charT, traits> y) noexcept; 32 template<class charT, class traits> 33 constexpr bool operator< (basic_string_view<charT, traits> x, 34 basic_string_view<charT, traits> y) noexcept; 35 template<class charT, class traits> 36 constexpr bool operator> (basic_string_view<charT, traits> x, 37 basic_string_view<charT, traits> y) noexcept; 38 template<class charT, class traits> 39 constexpr bool operator<=(basic_string_view<charT, traits> x, 40 basic_string_view<charT, traits> y) noexcept; 41 template<class charT, class traits> 42 constexpr bool operator>=(basic_string_view<charT, traits> x, 43 basic_string_view<charT, traits> y) noexcept; 44 // see below, sufficient additional overloads of comparison functions 45 46 // 7.10, Inserters and extractors 47 template<class charT, class traits> 48 basic_ostream<charT, traits>& 49 operator<<(basic_ostream<charT, traits>& os, 50 basic_string_view<charT, traits> str); 51 52 // basic_string_view typedef names 53 typedef basic_string_view<char> string_view; 54 typedef basic_string_view<char8_t> u8string_view; // C++20 55 typedef basic_string_view<char16_t> u16string_view; 56 typedef basic_string_view<char32_t> u32string_view; 57 typedef basic_string_view<wchar_t> wstring_view; 58 59 template<class charT, class traits = char_traits<charT>> 60 class basic_string_view { 61 public: 62 // types 63 typedef traits traits_type; 64 typedef charT value_type; 65 typedef charT* pointer; 66 typedef const charT* const_pointer; 67 typedef charT& reference; 68 typedef const charT& const_reference; 69 typedef implementation-defined const_iterator; 70 typedef const_iterator iterator; 71 typedef reverse_iterator<const_iterator> const_reverse_iterator; 72 typedef const_reverse_iterator reverse_iterator; 73 typedef size_t size_type; 74 typedef ptrdiff_t difference_type; 75 static constexpr size_type npos = size_type(-1); 76 77 // 7.3, basic_string_view constructors and assignment operators 78 constexpr basic_string_view() noexcept; 79 constexpr basic_string_view(const basic_string_view&) noexcept = default; 80 basic_string_view& operator=(const basic_string_view&) noexcept = default; 81 template<class Allocator> 82 constexpr basic_string_view(const charT* str); 83 constexpr basic_string_view(const charT* str, size_type len); 84 85 // 7.4, basic_string_view iterator support 86 constexpr const_iterator begin() const noexcept; 87 constexpr const_iterator end() const noexcept; 88 constexpr const_iterator cbegin() const noexcept; 89 constexpr const_iterator cend() const noexcept; 90 const_reverse_iterator rbegin() const noexcept; 91 const_reverse_iterator rend() const noexcept; 92 const_reverse_iterator crbegin() const noexcept; 93 const_reverse_iterator crend() const noexcept; 94 95 // 7.5, basic_string_view capacity 96 constexpr size_type size() const noexcept; 97 constexpr size_type length() const noexcept; 98 constexpr size_type max_size() const noexcept; 99 constexpr bool empty() const noexcept; 100 101 // 7.6, basic_string_view element access 102 constexpr const_reference operator[](size_type pos) const; 103 constexpr const_reference at(size_type pos) const; 104 constexpr const_reference front() const; 105 constexpr const_reference back() const; 106 constexpr const_pointer data() const noexcept; 107 108 // 7.7, basic_string_view modifiers 109 constexpr void remove_prefix(size_type n); 110 constexpr void remove_suffix(size_type n); 111 constexpr void swap(basic_string_view& s) noexcept; 112 113 size_type copy(charT* s, size_type n, size_type pos = 0) const; // constexpr in C++20 114 115 constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const; 116 constexpr int compare(basic_string_view s) const noexcept; 117 constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const; 118 constexpr int compare(size_type pos1, size_type n1, 119 basic_string_view s, size_type pos2, size_type n2) const; 120 constexpr int compare(const charT* s) const; 121 constexpr int compare(size_type pos1, size_type n1, const charT* s) const; 122 constexpr int compare(size_type pos1, size_type n1, 123 const charT* s, size_type n2) const; 124 constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept; 125 constexpr size_type find(charT c, size_type pos = 0) const noexcept; 126 constexpr size_type find(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension 127 constexpr size_type find(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension 128 constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept; 129 constexpr size_type rfind(charT c, size_type pos = npos) const noexcept; 130 constexpr size_type rfind(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension 131 constexpr size_type rfind(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension 132 constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept; 133 constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept; 134 constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension 135 constexpr size_type find_first_of(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension 136 constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept; 137 constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept; 138 constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension 139 constexpr size_type find_last_of(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension 140 constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept; 141 constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept; 142 constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension 143 constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension 144 constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept; 145 constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept; 146 constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension 147 constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension 148 149 constexpr bool starts_with(basic_string_view s) const noexcept; // C++20 150 constexpr bool starts_with(charT c) const noexcept; // C++20 151 constexpr bool starts_with(const charT* s) const; // C++20 152 constexpr bool ends_with(basic_string_view s) const noexcept; // C++20 153 constexpr bool ends_with(charT c) const noexcept; // C++20 154 constexpr bool ends_with(const charT* s) const; // C++20 155 156 constexpr bool contains(basic_string_view s) const noexcept; // C++2b 157 constexpr bool contains(charT c) const noexcept; // C++2b 158 constexpr bool contains(const charT* s) const; // C++2b 159 160 private: 161 const_pointer data_; // exposition only 162 size_type size_; // exposition only 163 }; 164 165 // 7.11, Hash support 166 template <class T> struct hash; 167 template <> struct hash<string_view>; 168 template <> struct hash<u8string_view>; // C++20 169 template <> struct hash<u16string_view>; 170 template <> struct hash<u32string_view>; 171 template <> struct hash<wstring_view>; 172 173 constexpr basic_string_view<char> operator "" sv( const char *str, size_t len ) noexcept; 174 constexpr basic_string_view<wchar_t> operator "" sv( const wchar_t *str, size_t len ) noexcept; 175 constexpr basic_string_view<char8_t> operator "" sv( const char8_t *str, size_t len ) noexcept; // C++20 176 constexpr basic_string_view<char16_t> operator "" sv( const char16_t *str, size_t len ) noexcept; 177 constexpr basic_string_view<char32_t> operator "" sv( const char32_t *str, size_t len ) noexcept; 178 179} // namespace std 180 181 182*/ 183 184#include <__config> 185#include <__ranges/enable_borrowed_range.h> 186#include <__string> 187#include <iosfwd> 188#include <algorithm> 189#include <compare> 190#include <iterator> 191#include <limits> 192#include <stdexcept> 193#include <version> 194#include <__debug> 195 196#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 197#pragma GCC system_header 198#endif 199 200_LIBCPP_PUSH_MACROS 201#include <__undef_macros> 202 203 204_LIBCPP_BEGIN_NAMESPACE_STD 205 206template<class _CharT, class _Traits = char_traits<_CharT> > 207 class _LIBCPP_TEMPLATE_VIS basic_string_view; 208 209typedef basic_string_view<char> string_view; 210#ifndef _LIBCPP_HAS_NO_CHAR8_T 211typedef basic_string_view<char8_t> u8string_view; 212#endif 213typedef basic_string_view<char16_t> u16string_view; 214typedef basic_string_view<char32_t> u32string_view; 215typedef basic_string_view<wchar_t> wstring_view; 216 217template<class _CharT, class _Traits> 218class 219 _LIBCPP_PREFERRED_NAME(string_view) 220#ifndef _LIBCPP_HAS_NO_CHAR8_T 221 _LIBCPP_PREFERRED_NAME(u8string_view) 222#endif 223 _LIBCPP_PREFERRED_NAME(u16string_view) 224 _LIBCPP_PREFERRED_NAME(u32string_view) 225 _LIBCPP_PREFERRED_NAME(wstring_view) 226 basic_string_view { 227public: 228 // types 229 typedef _Traits traits_type; 230 typedef _CharT value_type; 231 typedef _CharT* pointer; 232 typedef const _CharT* const_pointer; 233 typedef _CharT& reference; 234 typedef const _CharT& const_reference; 235 typedef const_pointer const_iterator; // See [string.view.iterators] 236 typedef const_iterator iterator; 237 typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; 238 typedef const_reverse_iterator reverse_iterator; 239 typedef size_t size_type; 240 typedef ptrdiff_t difference_type; 241 static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1); 242 243 static_assert((!is_array<value_type>::value), "Character type of basic_string_view must not be an array"); 244 static_assert(( is_standard_layout<value_type>::value), "Character type of basic_string_view must be standard-layout"); 245 static_assert(( is_trivial<value_type>::value), "Character type of basic_string_view must be trivial"); 246 static_assert((is_same<_CharT, typename traits_type::char_type>::value), 247 "traits_type::char_type must be the same type as CharT"); 248 249 // [string.view.cons], construct/copy 250 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 251 basic_string_view() _NOEXCEPT : __data (nullptr), __size(0) {} 252 253 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 254 basic_string_view(const basic_string_view&) _NOEXCEPT = default; 255 256 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 257 basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default; 258 259 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 260 basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT 261 : __data(__s), __size(__len) 262 { 263#if _LIBCPP_STD_VER > 11 264 _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr"); 265#endif 266 } 267 268 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 269 basic_string_view(const _CharT* __s) 270 : __data(__s), __size(_VSTD::__char_traits_length_checked<_Traits>(__s)) {} 271 272 // [string.view.iterators], iterators 273 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 274 const_iterator begin() const _NOEXCEPT { return cbegin(); } 275 276 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 277 const_iterator end() const _NOEXCEPT { return cend(); } 278 279 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 280 const_iterator cbegin() const _NOEXCEPT { return __data; } 281 282 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 283 const_iterator cend() const _NOEXCEPT { return __data + __size; } 284 285 _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY 286 const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); } 287 288 _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY 289 const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); } 290 291 _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY 292 const_reverse_iterator crbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); } 293 294 _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY 295 const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); } 296 297 // [string.view.capacity], capacity 298 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 299 size_type size() const _NOEXCEPT { return __size; } 300 301 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 302 size_type length() const _NOEXCEPT { return __size; } 303 304 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 305 size_type max_size() const _NOEXCEPT { return numeric_limits<size_type>::max(); } 306 307 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 308 bool empty() const _NOEXCEPT { return __size == 0; } 309 310 // [string.view.access], element access 311 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 312 const_reference operator[](size_type __pos) const _NOEXCEPT { 313 return _LIBCPP_ASSERT(__pos < size(), "string_view[] index out of bounds"), __data[__pos]; 314 } 315 316 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 317 const_reference at(size_type __pos) const 318 { 319 return __pos >= size() 320 ? (__throw_out_of_range("string_view::at"), __data[0]) 321 : __data[__pos]; 322 } 323 324 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 325 const_reference front() const _NOEXCEPT 326 { 327 return _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty"), __data[0]; 328 } 329 330 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 331 const_reference back() const _NOEXCEPT 332 { 333 return _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty"), __data[__size-1]; 334 } 335 336 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 337 const_pointer data() const _NOEXCEPT { return __data; } 338 339 // [string.view.modifiers], modifiers: 340 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 341 void remove_prefix(size_type __n) _NOEXCEPT 342 { 343 _LIBCPP_ASSERT(__n <= size(), "remove_prefix() can't remove more than size()"); 344 __data += __n; 345 __size -= __n; 346 } 347 348 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 349 void remove_suffix(size_type __n) _NOEXCEPT 350 { 351 _LIBCPP_ASSERT(__n <= size(), "remove_suffix() can't remove more than size()"); 352 __size -= __n; 353 } 354 355 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 356 void swap(basic_string_view& __other) _NOEXCEPT 357 { 358 const value_type *__p = __data; 359 __data = __other.__data; 360 __other.__data = __p; 361 362 size_type __sz = __size; 363 __size = __other.__size; 364 __other.__size = __sz; 365 } 366 367 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 368 size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const 369 { 370 if (__pos > size()) 371 __throw_out_of_range("string_view::copy"); 372 size_type __rlen = _VSTD::min(__n, size() - __pos); 373 _Traits::copy(__s, data() + __pos, __rlen); 374 return __rlen; 375 } 376 377 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 378 basic_string_view substr(size_type __pos = 0, size_type __n = npos) const 379 { 380 return __pos > size() 381 ? (__throw_out_of_range("string_view::substr"), basic_string_view()) 382 : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos)); 383 } 384 385 _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT 386 { 387 size_type __rlen = _VSTD::min( size(), __sv.size()); 388 int __retval = _Traits::compare(data(), __sv.data(), __rlen); 389 if ( __retval == 0 ) // first __rlen chars matched 390 __retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 ); 391 return __retval; 392 } 393 394 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 395 int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const 396 { 397 return substr(__pos1, __n1).compare(__sv); 398 } 399 400 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 401 int compare( size_type __pos1, size_type __n1, 402 basic_string_view __sv, size_type __pos2, size_type __n2) const 403 { 404 return substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2)); 405 } 406 407 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 408 int compare(const _CharT* __s) const _NOEXCEPT 409 { 410 return compare(basic_string_view(__s)); 411 } 412 413 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 414 int compare(size_type __pos1, size_type __n1, const _CharT* __s) const 415 { 416 return substr(__pos1, __n1).compare(basic_string_view(__s)); 417 } 418 419 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 420 int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const 421 { 422 return substr(__pos1, __n1).compare(basic_string_view(__s, __n2)); 423 } 424 425 // find 426 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 427 size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT 428 { 429 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); 430 return __str_find<value_type, size_type, traits_type, npos> 431 (data(), size(), __s.data(), __pos, __s.size()); 432 } 433 434 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 435 size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT 436 { 437 return __str_find<value_type, size_type, traits_type, npos> 438 (data(), size(), __c, __pos); 439 } 440 441 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 442 size_type find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT 443 { 444 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr"); 445 return __str_find<value_type, size_type, traits_type, npos> 446 (data(), size(), __s, __pos, __n); 447 } 448 449 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 450 size_type find(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT 451 { 452 _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr"); 453 return __str_find<value_type, size_type, traits_type, npos> 454 (data(), size(), __s, __pos, traits_type::length(__s)); 455 } 456 457 // rfind 458 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 459 size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT 460 { 461 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); 462 return __str_rfind<value_type, size_type, traits_type, npos> 463 (data(), size(), __s.data(), __pos, __s.size()); 464 } 465 466 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 467 size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT 468 { 469 return __str_rfind<value_type, size_type, traits_type, npos> 470 (data(), size(), __c, __pos); 471 } 472 473 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 474 size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT 475 { 476 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr"); 477 return __str_rfind<value_type, size_type, traits_type, npos> 478 (data(), size(), __s, __pos, __n); 479 } 480 481 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 482 size_type rfind(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT 483 { 484 _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr"); 485 return __str_rfind<value_type, size_type, traits_type, npos> 486 (data(), size(), __s, __pos, traits_type::length(__s)); 487 } 488 489 // find_first_of 490 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 491 size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT 492 { 493 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr"); 494 return __str_find_first_of<value_type, size_type, traits_type, npos> 495 (data(), size(), __s.data(), __pos, __s.size()); 496 } 497 498 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 499 size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT 500 { return find(__c, __pos); } 501 502 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 503 size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT 504 { 505 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr"); 506 return __str_find_first_of<value_type, size_type, traits_type, npos> 507 (data(), size(), __s, __pos, __n); 508 } 509 510 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 511 size_type find_first_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT 512 { 513 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr"); 514 return __str_find_first_of<value_type, size_type, traits_type, npos> 515 (data(), size(), __s, __pos, traits_type::length(__s)); 516 } 517 518 // find_last_of 519 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 520 size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT 521 { 522 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr"); 523 return __str_find_last_of<value_type, size_type, traits_type, npos> 524 (data(), size(), __s.data(), __pos, __s.size()); 525 } 526 527 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 528 size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT 529 { return rfind(__c, __pos); } 530 531 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 532 size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT 533 { 534 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr"); 535 return __str_find_last_of<value_type, size_type, traits_type, npos> 536 (data(), size(), __s, __pos, __n); 537 } 538 539 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 540 size_type find_last_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT 541 { 542 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr"); 543 return __str_find_last_of<value_type, size_type, traits_type, npos> 544 (data(), size(), __s, __pos, traits_type::length(__s)); 545 } 546 547 // find_first_not_of 548 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 549 size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT 550 { 551 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr"); 552 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 553 (data(), size(), __s.data(), __pos, __s.size()); 554 } 555 556 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 557 size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT 558 { 559 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 560 (data(), size(), __c, __pos); 561 } 562 563 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 564 size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT 565 { 566 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr"); 567 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 568 (data(), size(), __s, __pos, __n); 569 } 570 571 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 572 size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT 573 { 574 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr"); 575 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 576 (data(), size(), __s, __pos, traits_type::length(__s)); 577 } 578 579 // find_last_not_of 580 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 581 size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT 582 { 583 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr"); 584 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 585 (data(), size(), __s.data(), __pos, __s.size()); 586 } 587 588 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 589 size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT 590 { 591 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 592 (data(), size(), __c, __pos); 593 } 594 595 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 596 size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT 597 { 598 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr"); 599 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 600 (data(), size(), __s, __pos, __n); 601 } 602 603 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 604 size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT 605 { 606 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr"); 607 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 608 (data(), size(), __s, __pos, traits_type::length(__s)); 609 } 610 611#if _LIBCPP_STD_VER > 17 612 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 613 bool starts_with(basic_string_view __s) const _NOEXCEPT 614 { return size() >= __s.size() && compare(0, __s.size(), __s) == 0; } 615 616 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 617 bool starts_with(value_type __c) const _NOEXCEPT 618 { return !empty() && _Traits::eq(front(), __c); } 619 620 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 621 bool starts_with(const value_type* __s) const _NOEXCEPT 622 { return starts_with(basic_string_view(__s)); } 623 624 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 625 bool ends_with(basic_string_view __s) const _NOEXCEPT 626 { return size() >= __s.size() && compare(size() - __s.size(), npos, __s) == 0; } 627 628 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 629 bool ends_with(value_type __c) const _NOEXCEPT 630 { return !empty() && _Traits::eq(back(), __c); } 631 632 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 633 bool ends_with(const value_type* __s) const _NOEXCEPT 634 { return ends_with(basic_string_view(__s)); } 635#endif 636 637#if _LIBCPP_STD_VER > 20 638 constexpr _LIBCPP_INLINE_VISIBILITY 639 bool contains(basic_string_view __sv) const noexcept 640 { return find(__sv) != npos; } 641 642 constexpr _LIBCPP_INLINE_VISIBILITY 643 bool contains(value_type __c) const noexcept 644 { return find(__c) != npos; } 645 646 constexpr _LIBCPP_INLINE_VISIBILITY 647 bool contains(const value_type* __s) const 648 { return find(__s) != npos; } 649#endif 650 651private: 652 const value_type* __data; 653 size_type __size; 654}; 655 656#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES) 657template <class _CharT, class _Traits> 658inline constexpr bool ranges::enable_borrowed_range<basic_string_view<_CharT, _Traits> > = true; 659#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES) 660 661// [string.view.comparison] 662// operator == 663template<class _CharT, class _Traits> 664_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 665bool operator==(basic_string_view<_CharT, _Traits> __lhs, 666 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 667{ 668 if ( __lhs.size() != __rhs.size()) return false; 669 return __lhs.compare(__rhs) == 0; 670} 671 672template<class _CharT, class _Traits> 673_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 674bool operator==(basic_string_view<_CharT, _Traits> __lhs, 675 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT 676{ 677 if ( __lhs.size() != __rhs.size()) return false; 678 return __lhs.compare(__rhs) == 0; 679} 680 681template<class _CharT, class _Traits> 682_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 683bool operator==(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 684 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 685{ 686 if ( __lhs.size() != __rhs.size()) return false; 687 return __lhs.compare(__rhs) == 0; 688} 689 690 691// operator != 692template<class _CharT, class _Traits> 693_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 694bool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 695{ 696 if ( __lhs.size() != __rhs.size()) 697 return true; 698 return __lhs.compare(__rhs) != 0; 699} 700 701template<class _CharT, class _Traits> 702_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 703bool operator!=(basic_string_view<_CharT, _Traits> __lhs, 704 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT 705{ 706 if ( __lhs.size() != __rhs.size()) 707 return true; 708 return __lhs.compare(__rhs) != 0; 709} 710 711template<class _CharT, class _Traits> 712_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 713bool operator!=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 714 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 715{ 716 if ( __lhs.size() != __rhs.size()) 717 return true; 718 return __lhs.compare(__rhs) != 0; 719} 720 721 722// operator < 723template<class _CharT, class _Traits> 724_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 725bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 726{ 727 return __lhs.compare(__rhs) < 0; 728} 729 730template<class _CharT, class _Traits> 731_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 732bool operator<(basic_string_view<_CharT, _Traits> __lhs, 733 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT 734{ 735 return __lhs.compare(__rhs) < 0; 736} 737 738template<class _CharT, class _Traits> 739_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 740bool operator<(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 741 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 742{ 743 return __lhs.compare(__rhs) < 0; 744} 745 746 747// operator > 748template<class _CharT, class _Traits> 749_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 750bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 751{ 752 return __lhs.compare(__rhs) > 0; 753} 754 755template<class _CharT, class _Traits> 756_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 757bool operator>(basic_string_view<_CharT, _Traits> __lhs, 758 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT 759{ 760 return __lhs.compare(__rhs) > 0; 761} 762 763template<class _CharT, class _Traits> 764_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 765bool operator>(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 766 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 767{ 768 return __lhs.compare(__rhs) > 0; 769} 770 771 772// operator <= 773template<class _CharT, class _Traits> 774_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 775bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 776{ 777 return __lhs.compare(__rhs) <= 0; 778} 779 780template<class _CharT, class _Traits> 781_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 782bool operator<=(basic_string_view<_CharT, _Traits> __lhs, 783 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT 784{ 785 return __lhs.compare(__rhs) <= 0; 786} 787 788template<class _CharT, class _Traits> 789_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 790bool operator<=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 791 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 792{ 793 return __lhs.compare(__rhs) <= 0; 794} 795 796 797// operator >= 798template<class _CharT, class _Traits> 799_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 800bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 801{ 802 return __lhs.compare(__rhs) >= 0; 803} 804 805 806template<class _CharT, class _Traits> 807_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 808bool operator>=(basic_string_view<_CharT, _Traits> __lhs, 809 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT 810{ 811 return __lhs.compare(__rhs) >= 0; 812} 813 814template<class _CharT, class _Traits> 815_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 816bool operator>=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 817 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 818{ 819 return __lhs.compare(__rhs) >= 0; 820} 821 822 823template<class _CharT, class _Traits> 824basic_ostream<_CharT, _Traits>& 825operator<<(basic_ostream<_CharT, _Traits>& __os, 826 basic_string_view<_CharT, _Traits> __str); 827 828// [string.view.hash] 829template<class _CharT> 830struct _LIBCPP_TEMPLATE_VIS hash<basic_string_view<_CharT, char_traits<_CharT> > > 831 : public unary_function<basic_string_view<_CharT, char_traits<_CharT> >, size_t> 832{ 833 _LIBCPP_INLINE_VISIBILITY 834 size_t operator()(const basic_string_view<_CharT, char_traits<_CharT> > __val) const _NOEXCEPT { 835 return __do_string_hash(__val.data(), __val.data() + __val.size()); 836 } 837}; 838 839 840#if _LIBCPP_STD_VER > 11 841inline namespace literals 842{ 843 inline namespace string_view_literals 844 { 845 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 846 basic_string_view<char> operator "" sv(const char *__str, size_t __len) _NOEXCEPT 847 { 848 return basic_string_view<char> (__str, __len); 849 } 850 851 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 852 basic_string_view<wchar_t> operator "" sv(const wchar_t *__str, size_t __len) _NOEXCEPT 853 { 854 return basic_string_view<wchar_t> (__str, __len); 855 } 856 857#ifndef _LIBCPP_HAS_NO_CHAR8_T 858 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 859 basic_string_view<char8_t> operator "" sv(const char8_t *__str, size_t __len) _NOEXCEPT 860 { 861 return basic_string_view<char8_t> (__str, __len); 862 } 863#endif 864 865 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 866 basic_string_view<char16_t> operator "" sv(const char16_t *__str, size_t __len) _NOEXCEPT 867 { 868 return basic_string_view<char16_t> (__str, __len); 869 } 870 871 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 872 basic_string_view<char32_t> operator "" sv(const char32_t *__str, size_t __len) _NOEXCEPT 873 { 874 return basic_string_view<char32_t> (__str, __len); 875 } 876 } 877} 878#endif 879_LIBCPP_END_NAMESPACE_STD 880 881_LIBCPP_POP_MACROS 882 883#endif // _LIBCPP_STRING_VIEW 884