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(_VSTD::__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 { 282 return _LIBCPP_ASSERT(__pos < size(), "string_view[] index out of bounds"), __data[__pos]; 283 } 284 285 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 286 const_reference at(size_type __pos) const 287 { 288 return __pos >= size() 289 ? (__throw_out_of_range("string_view::at"), __data[0]) 290 : __data[__pos]; 291 } 292 293 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 294 const_reference front() const _NOEXCEPT 295 { 296 return _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty"), __data[0]; 297 } 298 299 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 300 const_reference back() const _NOEXCEPT 301 { 302 return _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty"), __data[__size-1]; 303 } 304 305 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 306 const_pointer data() const _NOEXCEPT { return __data; } 307 308 // [string.view.modifiers], modifiers: 309 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 310 void remove_prefix(size_type __n) _NOEXCEPT 311 { 312 _LIBCPP_ASSERT(__n <= size(), "remove_prefix() can't remove more than size()"); 313 __data += __n; 314 __size -= __n; 315 } 316 317 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 318 void remove_suffix(size_type __n) _NOEXCEPT 319 { 320 _LIBCPP_ASSERT(__n <= size(), "remove_suffix() can't remove more than size()"); 321 __size -= __n; 322 } 323 324 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 325 void swap(basic_string_view& __other) _NOEXCEPT 326 { 327 const value_type *__p = __data; 328 __data = __other.__data; 329 __other.__data = __p; 330 331 size_type __sz = __size; 332 __size = __other.__size; 333 __other.__size = __sz; 334 } 335 336 _LIBCPP_INLINE_VISIBILITY 337 size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const 338 { 339 if (__pos > size()) 340 __throw_out_of_range("string_view::copy"); 341 size_type __rlen = _VSTD::min(__n, size() - __pos); 342 _Traits::copy(__s, data() + __pos, __rlen); 343 return __rlen; 344 } 345 346 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 347 basic_string_view substr(size_type __pos = 0, size_type __n = npos) const 348 { 349 return __pos > size() 350 ? (__throw_out_of_range("string_view::substr"), basic_string_view()) 351 : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos)); 352 } 353 354 _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT 355 { 356 size_type __rlen = _VSTD::min( size(), __sv.size()); 357 int __retval = _Traits::compare(data(), __sv.data(), __rlen); 358 if ( __retval == 0 ) // first __rlen chars matched 359 __retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 ); 360 return __retval; 361 } 362 363 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 364 int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const 365 { 366 return substr(__pos1, __n1).compare(__sv); 367 } 368 369 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 370 int compare( size_type __pos1, size_type __n1, 371 basic_string_view __sv, size_type __pos2, size_type __n2) const 372 { 373 return substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2)); 374 } 375 376 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 377 int compare(const _CharT* __s) const _NOEXCEPT 378 { 379 return compare(basic_string_view(__s)); 380 } 381 382 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 383 int compare(size_type __pos1, size_type __n1, const _CharT* __s) const 384 { 385 return substr(__pos1, __n1).compare(basic_string_view(__s)); 386 } 387 388 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 389 int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const 390 { 391 return substr(__pos1, __n1).compare(basic_string_view(__s, __n2)); 392 } 393 394 // find 395 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 396 size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT 397 { 398 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); 399 return __str_find<value_type, size_type, traits_type, npos> 400 (data(), size(), __s.data(), __pos, __s.size()); 401 } 402 403 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 404 size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT 405 { 406 return __str_find<value_type, size_type, traits_type, npos> 407 (data(), size(), __c, __pos); 408 } 409 410 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 411 size_type find(const _CharT* __s, size_type __pos, size_type __n) const 412 { 413 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr"); 414 return __str_find<value_type, size_type, traits_type, npos> 415 (data(), size(), __s, __pos, __n); 416 } 417 418 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 419 size_type find(const _CharT* __s, size_type __pos = 0) const 420 { 421 _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr"); 422 return __str_find<value_type, size_type, traits_type, npos> 423 (data(), size(), __s, __pos, traits_type::length(__s)); 424 } 425 426 // rfind 427 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 428 size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT 429 { 430 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); 431 return __str_rfind<value_type, size_type, traits_type, npos> 432 (data(), size(), __s.data(), __pos, __s.size()); 433 } 434 435 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 436 size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT 437 { 438 return __str_rfind<value_type, size_type, traits_type, npos> 439 (data(), size(), __c, __pos); 440 } 441 442 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 443 size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const 444 { 445 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr"); 446 return __str_rfind<value_type, size_type, traits_type, npos> 447 (data(), size(), __s, __pos, __n); 448 } 449 450 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 451 size_type rfind(const _CharT* __s, size_type __pos=npos) const 452 { 453 _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr"); 454 return __str_rfind<value_type, size_type, traits_type, npos> 455 (data(), size(), __s, __pos, traits_type::length(__s)); 456 } 457 458 // find_first_of 459 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 460 size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT 461 { 462 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr"); 463 return __str_find_first_of<value_type, size_type, traits_type, npos> 464 (data(), size(), __s.data(), __pos, __s.size()); 465 } 466 467 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 468 size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT 469 { return find(__c, __pos); } 470 471 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 472 size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const 473 { 474 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr"); 475 return __str_find_first_of<value_type, size_type, traits_type, npos> 476 (data(), size(), __s, __pos, __n); 477 } 478 479 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 480 size_type find_first_of(const _CharT* __s, size_type __pos=0) const 481 { 482 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr"); 483 return __str_find_first_of<value_type, size_type, traits_type, npos> 484 (data(), size(), __s, __pos, traits_type::length(__s)); 485 } 486 487 // find_last_of 488 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 489 size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT 490 { 491 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr"); 492 return __str_find_last_of<value_type, size_type, traits_type, npos> 493 (data(), size(), __s.data(), __pos, __s.size()); 494 } 495 496 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 497 size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT 498 { return rfind(__c, __pos); } 499 500 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 501 size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const 502 { 503 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr"); 504 return __str_find_last_of<value_type, size_type, traits_type, npos> 505 (data(), size(), __s, __pos, __n); 506 } 507 508 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 509 size_type find_last_of(const _CharT* __s, size_type __pos=npos) const 510 { 511 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr"); 512 return __str_find_last_of<value_type, size_type, traits_type, npos> 513 (data(), size(), __s, __pos, traits_type::length(__s)); 514 } 515 516 // find_first_not_of 517 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 518 size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT 519 { 520 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr"); 521 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 522 (data(), size(), __s.data(), __pos, __s.size()); 523 } 524 525 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 526 size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT 527 { 528 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 529 (data(), size(), __c, __pos); 530 } 531 532 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 533 size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const 534 { 535 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr"); 536 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 537 (data(), size(), __s, __pos, __n); 538 } 539 540 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 541 size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const 542 { 543 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr"); 544 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 545 (data(), size(), __s, __pos, traits_type::length(__s)); 546 } 547 548 // find_last_not_of 549 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 550 size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT 551 { 552 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr"); 553 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 554 (data(), size(), __s.data(), __pos, __s.size()); 555 } 556 557 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 558 size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT 559 { 560 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 561 (data(), size(), __c, __pos); 562 } 563 564 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 565 size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const 566 { 567 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr"); 568 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 569 (data(), size(), __s, __pos, __n); 570 } 571 572 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 573 size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const 574 { 575 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr"); 576 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 577 (data(), size(), __s, __pos, traits_type::length(__s)); 578 } 579 580#if _LIBCPP_STD_VER > 17 581 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 582 bool starts_with(basic_string_view __s) const _NOEXCEPT 583 { return size() >= __s.size() && compare(0, __s.size(), __s) == 0; } 584 585 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 586 bool starts_with(value_type __c) const _NOEXCEPT 587 { return !empty() && _Traits::eq(front(), __c); } 588 589 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 590 bool starts_with(const value_type* __s) const _NOEXCEPT 591 { return starts_with(basic_string_view(__s)); } 592 593 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 594 bool ends_with(basic_string_view __s) const _NOEXCEPT 595 { return size() >= __s.size() && compare(size() - __s.size(), npos, __s) == 0; } 596 597 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 598 bool ends_with(value_type __c) const _NOEXCEPT 599 { return !empty() && _Traits::eq(back(), __c); } 600 601 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 602 bool ends_with(const value_type* __s) const _NOEXCEPT 603 { return ends_with(basic_string_view(__s)); } 604#endif 605 606private: 607 const value_type* __data; 608 size_type __size; 609}; 610 611 612// [string.view.comparison] 613// operator == 614template<class _CharT, class _Traits> 615_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 616bool operator==(basic_string_view<_CharT, _Traits> __lhs, 617 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 618{ 619 if ( __lhs.size() != __rhs.size()) return false; 620 return __lhs.compare(__rhs) == 0; 621} 622 623template<class _CharT, class _Traits> 624_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 625bool operator==(basic_string_view<_CharT, _Traits> __lhs, 626 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT 627{ 628 if ( __lhs.size() != __rhs.size()) return false; 629 return __lhs.compare(__rhs) == 0; 630} 631 632template<class _CharT, class _Traits> 633_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 634bool operator==(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 635 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 636{ 637 if ( __lhs.size() != __rhs.size()) return false; 638 return __lhs.compare(__rhs) == 0; 639} 640 641 642// operator != 643template<class _CharT, class _Traits> 644_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 645bool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 646{ 647 if ( __lhs.size() != __rhs.size()) 648 return true; 649 return __lhs.compare(__rhs) != 0; 650} 651 652template<class _CharT, class _Traits> 653_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 654bool operator!=(basic_string_view<_CharT, _Traits> __lhs, 655 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT 656{ 657 if ( __lhs.size() != __rhs.size()) 658 return true; 659 return __lhs.compare(__rhs) != 0; 660} 661 662template<class _CharT, class _Traits> 663_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 664bool operator!=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 665 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 666{ 667 if ( __lhs.size() != __rhs.size()) 668 return true; 669 return __lhs.compare(__rhs) != 0; 670} 671 672 673// operator < 674template<class _CharT, class _Traits> 675_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 676bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 677{ 678 return __lhs.compare(__rhs) < 0; 679} 680 681template<class _CharT, class _Traits> 682_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 683bool operator<(basic_string_view<_CharT, _Traits> __lhs, 684 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT 685{ 686 return __lhs.compare(__rhs) < 0; 687} 688 689template<class _CharT, class _Traits> 690_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 691bool operator<(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 692 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 693{ 694 return __lhs.compare(__rhs) < 0; 695} 696 697 698// operator > 699template<class _CharT, class _Traits> 700_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 701bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 702{ 703 return __lhs.compare(__rhs) > 0; 704} 705 706template<class _CharT, class _Traits> 707_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 708bool operator>(basic_string_view<_CharT, _Traits> __lhs, 709 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT 710{ 711 return __lhs.compare(__rhs) > 0; 712} 713 714template<class _CharT, class _Traits> 715_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 716bool operator>(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 717 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 718{ 719 return __lhs.compare(__rhs) > 0; 720} 721 722 723// operator <= 724template<class _CharT, class _Traits> 725_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 726bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 727{ 728 return __lhs.compare(__rhs) <= 0; 729} 730 731template<class _CharT, class _Traits> 732_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 733bool operator<=(basic_string_view<_CharT, _Traits> __lhs, 734 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT 735{ 736 return __lhs.compare(__rhs) <= 0; 737} 738 739template<class _CharT, class _Traits> 740_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 741bool operator<=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 742 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 743{ 744 return __lhs.compare(__rhs) <= 0; 745} 746 747 748// operator >= 749template<class _CharT, class _Traits> 750_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 751bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 752{ 753 return __lhs.compare(__rhs) >= 0; 754} 755 756 757template<class _CharT, class _Traits> 758_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 759bool operator>=(basic_string_view<_CharT, _Traits> __lhs, 760 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT 761{ 762 return __lhs.compare(__rhs) >= 0; 763} 764 765template<class _CharT, class _Traits> 766_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 767bool operator>=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 768 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 769{ 770 return __lhs.compare(__rhs) >= 0; 771} 772 773 774template<class _CharT, class _Traits> 775basic_ostream<_CharT, _Traits>& 776operator<<(basic_ostream<_CharT, _Traits>& __os, 777 basic_string_view<_CharT, _Traits> __str); 778 779typedef basic_string_view<char> string_view; 780#ifndef _LIBCPP_NO_HAS_CHAR8_T 781typedef basic_string_view<char8_t> u8string_view; 782#endif 783typedef basic_string_view<char16_t> u16string_view; 784typedef basic_string_view<char32_t> u32string_view; 785typedef basic_string_view<wchar_t> wstring_view; 786 787// [string.view.hash] 788template<class _CharT> 789struct _LIBCPP_TEMPLATE_VIS hash<basic_string_view<_CharT, char_traits<_CharT> > > 790 : public unary_function<basic_string_view<_CharT, char_traits<_CharT> >, size_t> 791{ 792 _LIBCPP_INLINE_VISIBILITY 793 size_t operator()(const basic_string_view<_CharT, char_traits<_CharT> > __val) const _NOEXCEPT { 794 return __do_string_hash(__val.data(), __val.data() + __val.size()); 795 } 796}; 797 798 799#if _LIBCPP_STD_VER > 11 800inline namespace literals 801{ 802 inline namespace string_view_literals 803 { 804 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 805 basic_string_view<char> operator "" sv(const char *__str, size_t __len) _NOEXCEPT 806 { 807 return basic_string_view<char> (__str, __len); 808 } 809 810 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 811 basic_string_view<wchar_t> operator "" sv(const wchar_t *__str, size_t __len) _NOEXCEPT 812 { 813 return basic_string_view<wchar_t> (__str, __len); 814 } 815 816#ifndef _LIBCPP_NO_HAS_CHAR8_T 817 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 818 basic_string_view<char8_t> operator "" sv(const char8_t *__str, size_t __len) _NOEXCEPT 819 { 820 return basic_string_view<char8_t> (__str, __len); 821 } 822#endif 823 824 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 825 basic_string_view<char16_t> operator "" sv(const char16_t *__str, size_t __len) _NOEXCEPT 826 { 827 return basic_string_view<char16_t> (__str, __len); 828 } 829 830 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 831 basic_string_view<char32_t> operator "" sv(const char32_t *__str, size_t __len) _NOEXCEPT 832 { 833 return basic_string_view<char32_t> (__str, __len); 834 } 835 } 836} 837#endif 838_LIBCPP_END_NAMESPACE_STD 839 840_LIBCPP_POP_MACROS 841 842#endif // _LIBCPP_STRING_VIEW 843