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