1// -*- C++ -*- 2//===------------------------ string_view ---------------------------------===// 3// 4// The LLVM Compiler Infrastructure 5// 6// This file is distributed under the University of Illinois Open Source 7// License. See LICENSE.TXT for details. 8// 9//===----------------------------------------------------------------------===// 10 11#ifndef _LIBCPP_STRING_VIEW 12#define _LIBCPP_STRING_VIEW 13 14/* 15string_view synopsis 16 17namespace std { 18 19 // 7.2, Class template basic_string_view 20 template<class charT, class traits = char_traits<charT>> 21 class basic_string_view; 22 23 // 7.9, basic_string_view non-member comparison functions 24 template<class charT, class traits> 25 constexpr bool operator==(basic_string_view<charT, traits> x, 26 basic_string_view<charT, traits> y) noexcept; 27 template<class charT, class traits> 28 constexpr bool operator!=(basic_string_view<charT, traits> x, 29 basic_string_view<charT, traits> y) noexcept; 30 template<class charT, class traits> 31 constexpr bool operator< (basic_string_view<charT, traits> x, 32 basic_string_view<charT, traits> y) noexcept; 33 template<class charT, class traits> 34 constexpr bool operator> (basic_string_view<charT, traits> x, 35 basic_string_view<charT, traits> y) noexcept; 36 template<class charT, class traits> 37 constexpr bool operator<=(basic_string_view<charT, traits> x, 38 basic_string_view<charT, traits> y) noexcept; 39 template<class charT, class traits> 40 constexpr bool operator>=(basic_string_view<charT, traits> x, 41 basic_string_view<charT, traits> y) noexcept; 42 // see below, sufficient additional overloads of comparison functions 43 44 // 7.10, Inserters and extractors 45 template<class charT, class traits> 46 basic_ostream<charT, traits>& 47 operator<<(basic_ostream<charT, traits>& os, 48 basic_string_view<charT, traits> str); 49 50 // basic_string_view typedef names 51 typedef basic_string_view<char> string_view; 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; 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; 124 constexpr size_type find(const charT* s, size_type pos = 0) const; 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; 128 constexpr size_type rfind(const charT* s, size_type pos = npos) const; 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; 132 constexpr size_type find_first_of(const charT* s, size_type pos = 0) const; 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; 136 constexpr size_type find_last_of(const charT* s, size_type pos = npos) const; 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; 140 constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const; 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; 144 constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const; 145 146 constexpr bool starts_with(basic_string_view s) const noexcept; // C++2a 147 constexpr bool starts_with(charT c) const noexcept; // C++2a 148 constexpr bool starts_with(const charT* s) const; // C++2a 149 constexpr bool ends_with(basic_string_view s) const noexcept; // C++2a 150 constexpr bool ends_with(charT c) const noexcept; // C++2a 151 constexpr bool ends_with(const charT* s) const; // C++2a 152 153 private: 154 const_pointer data_; // exposition only 155 size_type size_; // exposition only 156 }; 157 158 // 7.11, Hash support 159 template <class T> struct hash; 160 template <> struct hash<string_view>; 161 template <> struct hash<u16string_view>; 162 template <> struct hash<u32string_view>; 163 template <> struct hash<wstring_view>; 164 165 constexpr basic_string_view<char> operator "" sv( const char *str, size_t len ) noexcept; 166 constexpr basic_string_view<wchar_t> operator "" sv( const wchar_t *str, size_t len ) noexcept; 167 constexpr basic_string_view<char16_t> operator "" sv( const char16_t *str, size_t len ) noexcept; 168 constexpr basic_string_view<char32_t> operator "" sv( const char32_t *str, size_t len ) noexcept; 169 170} // namespace std 171 172 173*/ 174 175#include <__config> 176#include <__string> 177#include <algorithm> 178#include <iterator> 179#include <limits> 180#include <stdexcept> 181#include <__debug> 182 183#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 184#pragma GCC system_header 185#endif 186 187_LIBCPP_PUSH_MACROS 188#include <__undef_macros> 189 190 191_LIBCPP_BEGIN_NAMESPACE_STD 192 193template<class _CharT, class _Traits = char_traits<_CharT> > 194class _LIBCPP_TEMPLATE_VIS basic_string_view { 195public: 196 // types 197 typedef _Traits traits_type; 198 typedef _CharT value_type; 199 typedef _CharT* pointer; 200 typedef const _CharT* const_pointer; 201 typedef _CharT& reference; 202 typedef const _CharT& const_reference; 203 typedef const_pointer const_iterator; // See [string.view.iterators] 204 typedef const_iterator iterator; 205 typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; 206 typedef const_reverse_iterator reverse_iterator; 207 typedef size_t size_type; 208 typedef ptrdiff_t difference_type; 209 static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1); 210 211 static_assert(is_trivial<value_type>::value, "Character type of basic_string_view must be trivial"); 212 static_assert((is_same<_CharT, typename traits_type::char_type>::value), 213 "traits_type::char_type must be the same type as CharT"); 214 215 // [string.view.cons], construct/copy 216 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 217 basic_string_view() _NOEXCEPT : __data (nullptr), __size(0) {} 218 219 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 220 basic_string_view(const basic_string_view&) _NOEXCEPT = default; 221 222 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 223 basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default; 224 225 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 226 basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT 227 : __data(__s), __size(__len) 228 { 229// #if _LIBCPP_STD_VER > 11 230// _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr"); 231// #endif 232 } 233 234 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 235 basic_string_view(const _CharT* __s) 236 : __data(__s), __size(_Traits::length(__s)) {} 237 238 // [string.view.iterators], iterators 239 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 240 const_iterator begin() const _NOEXCEPT { return cbegin(); } 241 242 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 243 const_iterator end() const _NOEXCEPT { return cend(); } 244 245 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 246 const_iterator cbegin() const _NOEXCEPT { return __data; } 247 248 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 249 const_iterator cend() const _NOEXCEPT { return __data + __size; } 250 251 _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY 252 const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); } 253 254 _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY 255 const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); } 256 257 _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY 258 const_reverse_iterator crbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); } 259 260 _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY 261 const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); } 262 263 // [string.view.capacity], capacity 264 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 265 size_type size() const _NOEXCEPT { return __size; } 266 267 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 268 size_type length() const _NOEXCEPT { return __size; } 269 270 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 271 size_type max_size() const _NOEXCEPT { return numeric_limits<size_type>::max(); } 272 273 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 274 bool empty() const _NOEXCEPT { return __size == 0; } 275 276 // [string.view.access], element access 277 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 278 const_reference operator[](size_type __pos) const _NOEXCEPT { return __data[__pos]; } 279 280 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 281 const_reference at(size_type __pos) const 282 { 283 return __pos >= size() 284 ? (__throw_out_of_range("string_view::at"), __data[0]) 285 : __data[__pos]; 286 } 287 288 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 289 const_reference front() const 290 { 291 return _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty"), __data[0]; 292 } 293 294 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 295 const_reference back() const 296 { 297 return _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty"), __data[__size-1]; 298 } 299 300 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 301 const_pointer data() const _NOEXCEPT { return __data; } 302 303 // [string.view.modifiers], modifiers: 304 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 305 void remove_prefix(size_type __n) _NOEXCEPT 306 { 307 _LIBCPP_ASSERT(__n <= size(), "remove_prefix() can't remove more than size()"); 308 __data += __n; 309 __size -= __n; 310 } 311 312 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 313 void remove_suffix(size_type __n) _NOEXCEPT 314 { 315 _LIBCPP_ASSERT(__n <= size(), "remove_suffix() can't remove more than size()"); 316 __size -= __n; 317 } 318 319 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 320 void swap(basic_string_view& __other) _NOEXCEPT 321 { 322 const value_type *__p = __data; 323 __data = __other.__data; 324 __other.__data = __p; 325 326 size_type __sz = __size; 327 __size = __other.__size; 328 __other.__size = __sz; 329 } 330 331 _LIBCPP_INLINE_VISIBILITY 332 size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const 333 { 334 if (__pos > size()) 335 __throw_out_of_range("string_view::copy"); 336 size_type __rlen = _VSTD::min(__n, size() - __pos); 337 _Traits::copy(__s, data() + __pos, __rlen); 338 return __rlen; 339 } 340 341 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 342 basic_string_view substr(size_type __pos = 0, size_type __n = npos) const 343 { 344 return __pos > size() 345 ? (__throw_out_of_range("string_view::substr"), basic_string_view()) 346 : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos)); 347 } 348 349 _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT 350 { 351 size_type __rlen = _VSTD::min( size(), __sv.size()); 352 int __retval = _Traits::compare(data(), __sv.data(), __rlen); 353 if ( __retval == 0 ) // first __rlen chars matched 354 __retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 ); 355 return __retval; 356 } 357 358 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 359 int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const 360 { 361 return substr(__pos1, __n1).compare(__sv); 362 } 363 364 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 365 int compare( size_type __pos1, size_type __n1, 366 basic_string_view __sv, size_type __pos2, size_type __n2) const 367 { 368 return substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2)); 369 } 370 371 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 372 int compare(const _CharT* __s) const _NOEXCEPT 373 { 374 return compare(basic_string_view(__s)); 375 } 376 377 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 378 int compare(size_type __pos1, size_type __n1, const _CharT* __s) const 379 { 380 return substr(__pos1, __n1).compare(basic_string_view(__s)); 381 } 382 383 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 384 int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const 385 { 386 return substr(__pos1, __n1).compare(basic_string_view(__s, __n2)); 387 } 388 389 // find 390 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 391 size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT 392 { 393 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); 394 return __str_find<value_type, size_type, traits_type, npos> 395 (data(), size(), __s.data(), __pos, __s.size()); 396 } 397 398 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 399 size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT 400 { 401 return __str_find<value_type, size_type, traits_type, npos> 402 (data(), size(), __c, __pos); 403 } 404 405 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 406 size_type find(const _CharT* __s, size_type __pos, size_type __n) const 407 { 408 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr"); 409 return __str_find<value_type, size_type, traits_type, npos> 410 (data(), size(), __s, __pos, __n); 411 } 412 413 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 414 size_type find(const _CharT* __s, size_type __pos = 0) const 415 { 416 _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr"); 417 return __str_find<value_type, size_type, traits_type, npos> 418 (data(), size(), __s, __pos, traits_type::length(__s)); 419 } 420 421 // rfind 422 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 423 size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT 424 { 425 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); 426 return __str_rfind<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 rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT 432 { 433 return __str_rfind<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 rfind(const _CharT* __s, size_type __pos, size_type __n) const 439 { 440 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr"); 441 return __str_rfind<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 rfind(const _CharT* __s, size_type __pos=npos) const 447 { 448 _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr"); 449 return __str_rfind<value_type, size_type, traits_type, npos> 450 (data(), size(), __s, __pos, traits_type::length(__s)); 451 } 452 453 // find_first_of 454 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 455 size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT 456 { 457 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr"); 458 return __str_find_first_of<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 find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT 464 { return find(__c, __pos); } 465 466 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 467 size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const 468 { 469 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr"); 470 return __str_find_first_of<value_type, size_type, traits_type, npos> 471 (data(), size(), __s, __pos, __n); 472 } 473 474 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 475 size_type find_first_of(const _CharT* __s, size_type __pos=0) const 476 { 477 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr"); 478 return __str_find_first_of<value_type, size_type, traits_type, npos> 479 (data(), size(), __s, __pos, traits_type::length(__s)); 480 } 481 482 // find_last_of 483 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 484 size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT 485 { 486 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr"); 487 return __str_find_last_of<value_type, size_type, traits_type, npos> 488 (data(), size(), __s.data(), __pos, __s.size()); 489 } 490 491 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 492 size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT 493 { return rfind(__c, __pos); } 494 495 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 496 size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const 497 { 498 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr"); 499 return __str_find_last_of<value_type, size_type, traits_type, npos> 500 (data(), size(), __s, __pos, __n); 501 } 502 503 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 504 size_type find_last_of(const _CharT* __s, size_type __pos=npos) const 505 { 506 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr"); 507 return __str_find_last_of<value_type, size_type, traits_type, npos> 508 (data(), size(), __s, __pos, traits_type::length(__s)); 509 } 510 511 // find_first_not_of 512 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 513 size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT 514 { 515 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr"); 516 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 517 (data(), size(), __s.data(), __pos, __s.size()); 518 } 519 520 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 521 size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT 522 { 523 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 524 (data(), size(), __c, __pos); 525 } 526 527 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 528 size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const 529 { 530 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr"); 531 return __str_find_first_not_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_first_not_of(const _CharT* __s, size_type __pos=0) const 537 { 538 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr"); 539 return __str_find_first_not_of<value_type, size_type, traits_type, npos> 540 (data(), size(), __s, __pos, traits_type::length(__s)); 541 } 542 543 // find_last_not_of 544 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 545 size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT 546 { 547 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr"); 548 return __str_find_last_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_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT 554 { 555 return __str_find_last_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_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const 561 { 562 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr"); 563 return __str_find_last_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_last_not_of(const _CharT* __s, size_type __pos=npos) const 569 { 570 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr"); 571 return __str_find_last_not_of<value_type, size_type, traits_type, npos> 572 (data(), size(), __s, __pos, traits_type::length(__s)); 573 } 574 575#if _LIBCPP_STD_VER > 17 576 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 577 bool starts_with(basic_string_view __s) const _NOEXCEPT 578 { return size() >= __s.size() && compare(0, __s.size(), __s) == 0; } 579 580 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 581 bool starts_with(value_type __c) const _NOEXCEPT 582 { return !empty() && _Traits::eq(front(), __c); } 583 584 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 585 bool starts_with(const value_type* __s) const _NOEXCEPT 586 { return starts_with(basic_string_view(__s)); } 587 588 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 589 bool ends_with(basic_string_view __s) const _NOEXCEPT 590 { return size() >= __s.size() && compare(size() - __s.size(), npos, __s) == 0; } 591 592 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 593 bool ends_with(value_type __c) const _NOEXCEPT 594 { return !empty() && _Traits::eq(back(), __c); } 595 596 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 597 bool ends_with(const value_type* __s) const _NOEXCEPT 598 { return ends_with(basic_string_view(__s)); } 599#endif 600 601private: 602 const value_type* __data; 603 size_type __size; 604}; 605 606 607// [string.view.comparison] 608// operator == 609template<class _CharT, class _Traits> 610_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 611bool operator==(basic_string_view<_CharT, _Traits> __lhs, 612 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 613{ 614 if ( __lhs.size() != __rhs.size()) return false; 615 return __lhs.compare(__rhs) == 0; 616} 617 618template<class _CharT, class _Traits> 619_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 620bool operator==(basic_string_view<_CharT, _Traits> __lhs, 621 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT 622{ 623 if ( __lhs.size() != __rhs.size()) return false; 624 return __lhs.compare(__rhs) == 0; 625} 626 627template<class _CharT, class _Traits> 628_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 629bool operator==(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 630 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 631{ 632 if ( __lhs.size() != __rhs.size()) return false; 633 return __lhs.compare(__rhs) == 0; 634} 635 636 637// operator != 638template<class _CharT, class _Traits> 639_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 640bool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 641{ 642 if ( __lhs.size() != __rhs.size()) 643 return true; 644 return __lhs.compare(__rhs) != 0; 645} 646 647template<class _CharT, class _Traits> 648_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 649bool operator!=(basic_string_view<_CharT, _Traits> __lhs, 650 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT 651{ 652 if ( __lhs.size() != __rhs.size()) 653 return true; 654 return __lhs.compare(__rhs) != 0; 655} 656 657template<class _CharT, class _Traits> 658_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 659bool operator!=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 660 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 661{ 662 if ( __lhs.size() != __rhs.size()) 663 return true; 664 return __lhs.compare(__rhs) != 0; 665} 666 667 668// operator < 669template<class _CharT, class _Traits> 670_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 671bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 672{ 673 return __lhs.compare(__rhs) < 0; 674} 675 676template<class _CharT, class _Traits> 677_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 678bool operator<(basic_string_view<_CharT, _Traits> __lhs, 679 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT 680{ 681 return __lhs.compare(__rhs) < 0; 682} 683 684template<class _CharT, class _Traits> 685_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 686bool operator<(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 687 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 688{ 689 return __lhs.compare(__rhs) < 0; 690} 691 692 693// operator > 694template<class _CharT, class _Traits> 695_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 696bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 697{ 698 return __lhs.compare(__rhs) > 0; 699} 700 701template<class _CharT, class _Traits> 702_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 703bool operator>(basic_string_view<_CharT, _Traits> __lhs, 704 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT 705{ 706 return __lhs.compare(__rhs) > 0; 707} 708 709template<class _CharT, class _Traits> 710_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 711bool operator>(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 712 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 713{ 714 return __lhs.compare(__rhs) > 0; 715} 716 717 718// operator <= 719template<class _CharT, class _Traits> 720_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 721bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 722{ 723 return __lhs.compare(__rhs) <= 0; 724} 725 726template<class _CharT, class _Traits> 727_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 728bool operator<=(basic_string_view<_CharT, _Traits> __lhs, 729 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT 730{ 731 return __lhs.compare(__rhs) <= 0; 732} 733 734template<class _CharT, class _Traits> 735_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 736bool operator<=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 737 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 738{ 739 return __lhs.compare(__rhs) <= 0; 740} 741 742 743// operator >= 744template<class _CharT, class _Traits> 745_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 746bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 747{ 748 return __lhs.compare(__rhs) >= 0; 749} 750 751 752template<class _CharT, class _Traits> 753_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 754bool operator>=(basic_string_view<_CharT, _Traits> __lhs, 755 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT 756{ 757 return __lhs.compare(__rhs) >= 0; 758} 759 760template<class _CharT, class _Traits> 761_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 762bool operator>=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 763 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT 764{ 765 return __lhs.compare(__rhs) >= 0; 766} 767 768typedef basic_string_view<char> string_view; 769typedef basic_string_view<char16_t> u16string_view; 770typedef basic_string_view<char32_t> u32string_view; 771typedef basic_string_view<wchar_t> wstring_view; 772 773// [string.view.hash] 774template<class _CharT, class _Traits> 775struct _LIBCPP_TEMPLATE_VIS hash<basic_string_view<_CharT, _Traits> > 776 : public unary_function<basic_string_view<_CharT, _Traits>, size_t> 777{ 778 size_t operator()(const basic_string_view<_CharT, _Traits> __val) const _NOEXCEPT; 779}; 780 781template<class _CharT, class _Traits> 782size_t 783hash<basic_string_view<_CharT, _Traits> >::operator()( 784 const basic_string_view<_CharT, _Traits> __val) const _NOEXCEPT 785{ 786 return __do_string_hash(__val.data(), __val.data() + __val.size()); 787} 788 789 790#if _LIBCPP_STD_VER > 11 791inline namespace literals 792{ 793 inline namespace string_view_literals 794 { 795 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 796 basic_string_view<char> operator "" sv(const char *__str, size_t __len) _NOEXCEPT 797 { 798 return basic_string_view<char> (__str, __len); 799 } 800 801 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 802 basic_string_view<wchar_t> operator "" sv(const wchar_t *__str, size_t __len) _NOEXCEPT 803 { 804 return basic_string_view<wchar_t> (__str, __len); 805 } 806 807 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 808 basic_string_view<char16_t> operator "" sv(const char16_t *__str, size_t __len) _NOEXCEPT 809 { 810 return basic_string_view<char16_t> (__str, __len); 811 } 812 813 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 814 basic_string_view<char32_t> operator "" sv(const char32_t *__str, size_t __len) _NOEXCEPT 815 { 816 return basic_string_view<char32_t> (__str, __len); 817 } 818 } 819} 820#endif 821_LIBCPP_END_NAMESPACE_STD 822 823_LIBCPP_POP_MACROS 824 825#endif // _LIBCPP_STRING_VIEW 826