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