[1166] | 1 | // Components for manipulating non-owning sequences of characters -*- C++ -*-
|
---|
| 2 |
|
---|
| 3 | // Copyright (C) 2013-2021 Free Software Foundation, Inc.
|
---|
| 4 | //
|
---|
| 5 | // This file is part of the GNU ISO C++ Library. This library is free
|
---|
| 6 | // software; you can redistribute it and/or modify it under the
|
---|
| 7 | // terms of the GNU General Public License as published by the
|
---|
| 8 | // Free Software Foundation; either version 3, or (at your option)
|
---|
| 9 | // any later version.
|
---|
| 10 |
|
---|
| 11 | // This library is distributed in the hope that it will be useful,
|
---|
| 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
| 14 | // GNU General Public License for more details.
|
---|
| 15 |
|
---|
| 16 | // Under Section 7 of GPL version 3, you are granted additional
|
---|
| 17 | // permissions described in the GCC Runtime Library Exception, version
|
---|
| 18 | // 3.1, as published by the Free Software Foundation.
|
---|
| 19 |
|
---|
| 20 | // You should have received a copy of the GNU General Public License and
|
---|
| 21 | // a copy of the GCC Runtime Library Exception along with this program;
|
---|
| 22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
---|
| 23 | // <http://www.gnu.org/licenses/>.
|
---|
| 24 |
|
---|
| 25 | /** @file include/string_view
|
---|
| 26 | * This is a Standard C++ Library header.
|
---|
| 27 | */
|
---|
| 28 |
|
---|
| 29 | //
|
---|
| 30 | // N3762 basic_string_view library
|
---|
| 31 | //
|
---|
| 32 |
|
---|
| 33 | #ifndef _GLIBCXX_STRING_VIEW
|
---|
| 34 | #define _GLIBCXX_STRING_VIEW 1
|
---|
| 35 |
|
---|
| 36 | #pragma GCC system_header
|
---|
| 37 |
|
---|
| 38 | #if __cplusplus >= 201703L
|
---|
| 39 |
|
---|
| 40 | #include <iosfwd>
|
---|
| 41 | #include <bits/char_traits.h>
|
---|
| 42 | #include <bits/functional_hash.h>
|
---|
| 43 | #include <bits/range_access.h>
|
---|
| 44 | #include <bits/ostream_insert.h>
|
---|
| 45 | #include <ext/numeric_traits.h>
|
---|
| 46 |
|
---|
| 47 | #if __cplusplus >= 202002L
|
---|
| 48 | # include <bits/ranges_base.h>
|
---|
| 49 | #endif
|
---|
| 50 |
|
---|
| 51 | namespace std _GLIBCXX_VISIBILITY(default)
|
---|
| 52 | {
|
---|
| 53 | _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
---|
| 54 |
|
---|
| 55 | # define __cpp_lib_string_view 201803L
|
---|
| 56 | #if __cplusplus > 201703L
|
---|
| 57 | # define __cpp_lib_constexpr_string_view 201811L
|
---|
| 58 | #endif
|
---|
| 59 |
|
---|
| 60 | // Helper for basic_string and basic_string_view members.
|
---|
| 61 | constexpr size_t
|
---|
| 62 | __sv_check(size_t __size, size_t __pos, const char* __s)
|
---|
| 63 | {
|
---|
| 64 | if (__pos > __size)
|
---|
| 65 | __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > __size "
|
---|
| 66 | "(which is %zu)"), __s, __pos, __size);
|
---|
| 67 | return __pos;
|
---|
| 68 | }
|
---|
| 69 |
|
---|
| 70 | // Helper for basic_string members.
|
---|
| 71 | // NB: __sv_limit doesn't check for a bad __pos value.
|
---|
| 72 | constexpr size_t
|
---|
| 73 | __sv_limit(size_t __size, size_t __pos, size_t __off) noexcept
|
---|
| 74 | {
|
---|
| 75 | const bool __testoff = __off < __size - __pos;
|
---|
| 76 | return __testoff ? __off : __size - __pos;
|
---|
| 77 | }
|
---|
| 78 |
|
---|
| 79 | /**
|
---|
| 80 | * @class basic_string_view <string_view>
|
---|
| 81 | * @brief A non-owning reference to a string.
|
---|
| 82 | *
|
---|
| 83 | * @ingroup strings
|
---|
| 84 | * @ingroup sequences
|
---|
| 85 | *
|
---|
| 86 | * @tparam _CharT Type of character
|
---|
| 87 | * @tparam _Traits Traits for character type, defaults to
|
---|
| 88 | * char_traits<_CharT>.
|
---|
| 89 | *
|
---|
| 90 | * A basic_string_view looks like this:
|
---|
| 91 | *
|
---|
| 92 | * @code
|
---|
| 93 | * _CharT* _M_str
|
---|
| 94 | * size_t _M_len
|
---|
| 95 | * @endcode
|
---|
| 96 | */
|
---|
| 97 | template<typename _CharT, typename _Traits = std::char_traits<_CharT>>
|
---|
| 98 | class basic_string_view
|
---|
| 99 | {
|
---|
| 100 | static_assert(!is_array_v<_CharT>);
|
---|
| 101 | static_assert(is_trivial_v<_CharT> && is_standard_layout_v<_CharT>);
|
---|
| 102 | static_assert(is_same_v<_CharT, typename _Traits::char_type>);
|
---|
| 103 |
|
---|
| 104 | public:
|
---|
| 105 |
|
---|
| 106 | // types
|
---|
| 107 | using traits_type = _Traits;
|
---|
| 108 | using value_type = _CharT;
|
---|
| 109 | using pointer = value_type*;
|
---|
| 110 | using const_pointer = const value_type*;
|
---|
| 111 | using reference = value_type&;
|
---|
| 112 | using const_reference = const value_type&;
|
---|
| 113 | using const_iterator = const value_type*;
|
---|
| 114 | using iterator = const_iterator;
|
---|
| 115 | using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
---|
| 116 | using reverse_iterator = const_reverse_iterator;
|
---|
| 117 | using size_type = size_t;
|
---|
| 118 | using difference_type = ptrdiff_t;
|
---|
| 119 | static constexpr size_type npos = size_type(-1);
|
---|
| 120 |
|
---|
| 121 | // [string.view.cons], construction and assignment
|
---|
| 122 |
|
---|
| 123 | constexpr
|
---|
| 124 | basic_string_view() noexcept
|
---|
| 125 | : _M_len{0}, _M_str{nullptr}
|
---|
| 126 | { }
|
---|
| 127 |
|
---|
| 128 | constexpr basic_string_view(const basic_string_view&) noexcept = default;
|
---|
| 129 |
|
---|
| 130 | __attribute__((__nonnull__)) constexpr
|
---|
| 131 | basic_string_view(const _CharT* __str) noexcept
|
---|
| 132 | : _M_len{traits_type::length(__str)},
|
---|
| 133 | _M_str{__str}
|
---|
| 134 | { }
|
---|
| 135 |
|
---|
| 136 | constexpr
|
---|
| 137 | basic_string_view(const _CharT* __str, size_type __len) noexcept
|
---|
| 138 | : _M_len{__len}, _M_str{__str}
|
---|
| 139 | { }
|
---|
| 140 |
|
---|
| 141 | #if __cplusplus >= 202002L && __cpp_lib_concepts
|
---|
| 142 | template<contiguous_iterator _It, sized_sentinel_for<_It> _End>
|
---|
| 143 | requires same_as<iter_value_t<_It>, _CharT>
|
---|
| 144 | && (!convertible_to<_End, size_type>)
|
---|
| 145 | constexpr
|
---|
| 146 | basic_string_view(_It __first, _End __last)
|
---|
| 147 | : _M_len(__last - __first), _M_str(std::to_address(__first))
|
---|
| 148 | { }
|
---|
| 149 |
|
---|
| 150 | #if __cplusplus > 202002L
|
---|
| 151 | template<typename _Range, typename _DRange = remove_cvref_t<_Range>>
|
---|
| 152 | requires (!is_same_v<_DRange, basic_string_view>)
|
---|
| 153 | && ranges::contiguous_range<_Range>
|
---|
| 154 | && ranges::sized_range<_Range>
|
---|
| 155 | && is_same_v<ranges::range_value_t<_Range>, _CharT>
|
---|
| 156 | && (!is_convertible_v<_Range, const _CharT*>)
|
---|
| 157 | && (!requires (_DRange& __d) {
|
---|
| 158 | __d.operator ::std::basic_string_view<_CharT, _Traits>();
|
---|
| 159 | })
|
---|
| 160 | && (!requires { typename _DRange::traits_type; }
|
---|
| 161 | || is_same_v<typename _DRange::traits_type, _Traits>)
|
---|
| 162 | constexpr
|
---|
| 163 | basic_string_view(_Range&& __r)
|
---|
| 164 | noexcept(noexcept(ranges::size(__r)) && noexcept(ranges::data(__r)))
|
---|
| 165 | : _M_len(ranges::size(__r)), _M_str(ranges::data(__r))
|
---|
| 166 | { }
|
---|
| 167 | #endif // C++23
|
---|
| 168 | #endif // C++20
|
---|
| 169 |
|
---|
| 170 | constexpr basic_string_view&
|
---|
| 171 | operator=(const basic_string_view&) noexcept = default;
|
---|
| 172 |
|
---|
| 173 | // [string.view.iterators], iterator support
|
---|
| 174 |
|
---|
| 175 | constexpr const_iterator
|
---|
| 176 | begin() const noexcept
|
---|
| 177 | { return this->_M_str; }
|
---|
| 178 |
|
---|
| 179 | constexpr const_iterator
|
---|
| 180 | end() const noexcept
|
---|
| 181 | { return this->_M_str + this->_M_len; }
|
---|
| 182 |
|
---|
| 183 | constexpr const_iterator
|
---|
| 184 | cbegin() const noexcept
|
---|
| 185 | { return this->_M_str; }
|
---|
| 186 |
|
---|
| 187 | constexpr const_iterator
|
---|
| 188 | cend() const noexcept
|
---|
| 189 | { return this->_M_str + this->_M_len; }
|
---|
| 190 |
|
---|
| 191 | constexpr const_reverse_iterator
|
---|
| 192 | rbegin() const noexcept
|
---|
| 193 | { return const_reverse_iterator(this->end()); }
|
---|
| 194 |
|
---|
| 195 | constexpr const_reverse_iterator
|
---|
| 196 | rend() const noexcept
|
---|
| 197 | { return const_reverse_iterator(this->begin()); }
|
---|
| 198 |
|
---|
| 199 | constexpr const_reverse_iterator
|
---|
| 200 | crbegin() const noexcept
|
---|
| 201 | { return const_reverse_iterator(this->end()); }
|
---|
| 202 |
|
---|
| 203 | constexpr const_reverse_iterator
|
---|
| 204 | crend() const noexcept
|
---|
| 205 | { return const_reverse_iterator(this->begin()); }
|
---|
| 206 |
|
---|
| 207 | // [string.view.capacity], capacity
|
---|
| 208 |
|
---|
| 209 | constexpr size_type
|
---|
| 210 | size() const noexcept
|
---|
| 211 | { return this->_M_len; }
|
---|
| 212 |
|
---|
| 213 | constexpr size_type
|
---|
| 214 | length() const noexcept
|
---|
| 215 | { return _M_len; }
|
---|
| 216 |
|
---|
| 217 | constexpr size_type
|
---|
| 218 | max_size() const noexcept
|
---|
| 219 | {
|
---|
| 220 | return (npos - sizeof(size_type) - sizeof(void*))
|
---|
| 221 | / sizeof(value_type) / 4;
|
---|
| 222 | }
|
---|
| 223 |
|
---|
| 224 | [[nodiscard]] constexpr bool
|
---|
| 225 | empty() const noexcept
|
---|
| 226 | { return this->_M_len == 0; }
|
---|
| 227 |
|
---|
| 228 | // [string.view.access], element access
|
---|
| 229 |
|
---|
| 230 | constexpr const_reference
|
---|
| 231 | operator[](size_type __pos) const noexcept
|
---|
| 232 | {
|
---|
| 233 | __glibcxx_assert(__pos < this->_M_len);
|
---|
| 234 | return *(this->_M_str + __pos);
|
---|
| 235 | }
|
---|
| 236 |
|
---|
| 237 | constexpr const_reference
|
---|
| 238 | at(size_type __pos) const
|
---|
| 239 | {
|
---|
| 240 | if (__pos >= _M_len)
|
---|
| 241 | __throw_out_of_range_fmt(__N("basic_string_view::at: __pos "
|
---|
| 242 | "(which is %zu) >= this->size() "
|
---|
| 243 | "(which is %zu)"), __pos, this->size());
|
---|
| 244 | return *(this->_M_str + __pos);
|
---|
| 245 | }
|
---|
| 246 |
|
---|
| 247 | constexpr const_reference
|
---|
| 248 | front() const noexcept
|
---|
| 249 | {
|
---|
| 250 | __glibcxx_assert(this->_M_len > 0);
|
---|
| 251 | return *this->_M_str;
|
---|
| 252 | }
|
---|
| 253 |
|
---|
| 254 | constexpr const_reference
|
---|
| 255 | back() const noexcept
|
---|
| 256 | {
|
---|
| 257 | __glibcxx_assert(this->_M_len > 0);
|
---|
| 258 | return *(this->_M_str + this->_M_len - 1);
|
---|
| 259 | }
|
---|
| 260 |
|
---|
| 261 | constexpr const_pointer
|
---|
| 262 | data() const noexcept
|
---|
| 263 | { return this->_M_str; }
|
---|
| 264 |
|
---|
| 265 | // [string.view.modifiers], modifiers:
|
---|
| 266 |
|
---|
| 267 | constexpr void
|
---|
| 268 | remove_prefix(size_type __n) noexcept
|
---|
| 269 | {
|
---|
| 270 | __glibcxx_assert(this->_M_len >= __n);
|
---|
| 271 | this->_M_str += __n;
|
---|
| 272 | this->_M_len -= __n;
|
---|
| 273 | }
|
---|
| 274 |
|
---|
| 275 | constexpr void
|
---|
| 276 | remove_suffix(size_type __n) noexcept
|
---|
| 277 | { this->_M_len -= __n; }
|
---|
| 278 |
|
---|
| 279 | constexpr void
|
---|
| 280 | swap(basic_string_view& __sv) noexcept
|
---|
| 281 | {
|
---|
| 282 | auto __tmp = *this;
|
---|
| 283 | *this = __sv;
|
---|
| 284 | __sv = __tmp;
|
---|
| 285 | }
|
---|
| 286 |
|
---|
| 287 | // [string.view.ops], string operations:
|
---|
| 288 |
|
---|
| 289 | _GLIBCXX20_CONSTEXPR
|
---|
| 290 | size_type
|
---|
| 291 | copy(_CharT* __str, size_type __n, size_type __pos = 0) const
|
---|
| 292 | {
|
---|
| 293 | __glibcxx_requires_string_len(__str, __n);
|
---|
| 294 | __pos = std::__sv_check(size(), __pos, "basic_string_view::copy");
|
---|
| 295 | const size_type __rlen = std::min(__n, _M_len - __pos);
|
---|
| 296 | // _GLIBCXX_RESOLVE_LIB_DEFECTS
|
---|
| 297 | // 2777. basic_string_view::copy should use char_traits::copy
|
---|
| 298 | traits_type::copy(__str, data() + __pos, __rlen);
|
---|
| 299 | return __rlen;
|
---|
| 300 | }
|
---|
| 301 |
|
---|
| 302 | constexpr basic_string_view
|
---|
| 303 | substr(size_type __pos = 0, size_type __n = npos) const noexcept(false)
|
---|
| 304 | {
|
---|
| 305 | __pos = std::__sv_check(size(), __pos, "basic_string_view::substr");
|
---|
| 306 | const size_type __rlen = std::min(__n, _M_len - __pos);
|
---|
| 307 | return basic_string_view{_M_str + __pos, __rlen};
|
---|
| 308 | }
|
---|
| 309 |
|
---|
| 310 | constexpr int
|
---|
| 311 | compare(basic_string_view __str) const noexcept
|
---|
| 312 | {
|
---|
| 313 | const size_type __rlen = std::min(this->_M_len, __str._M_len);
|
---|
| 314 | int __ret = traits_type::compare(this->_M_str, __str._M_str, __rlen);
|
---|
| 315 | if (__ret == 0)
|
---|
| 316 | __ret = _S_compare(this->_M_len, __str._M_len);
|
---|
| 317 | return __ret;
|
---|
| 318 | }
|
---|
| 319 |
|
---|
| 320 | constexpr int
|
---|
| 321 | compare(size_type __pos1, size_type __n1, basic_string_view __str) const
|
---|
| 322 | { return this->substr(__pos1, __n1).compare(__str); }
|
---|
| 323 |
|
---|
| 324 | constexpr int
|
---|
| 325 | compare(size_type __pos1, size_type __n1,
|
---|
| 326 | basic_string_view __str, size_type __pos2, size_type __n2) const
|
---|
| 327 | {
|
---|
| 328 | return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2));
|
---|
| 329 | }
|
---|
| 330 |
|
---|
| 331 | __attribute__((__nonnull__)) constexpr int
|
---|
| 332 | compare(const _CharT* __str) const noexcept
|
---|
| 333 | { return this->compare(basic_string_view{__str}); }
|
---|
| 334 |
|
---|
| 335 | __attribute__((__nonnull__)) constexpr int
|
---|
| 336 | compare(size_type __pos1, size_type __n1, const _CharT* __str) const
|
---|
| 337 | { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); }
|
---|
| 338 |
|
---|
| 339 | constexpr int
|
---|
| 340 | compare(size_type __pos1, size_type __n1,
|
---|
| 341 | const _CharT* __str, size_type __n2) const noexcept(false)
|
---|
| 342 | {
|
---|
| 343 | return this->substr(__pos1, __n1)
|
---|
| 344 | .compare(basic_string_view(__str, __n2));
|
---|
| 345 | }
|
---|
| 346 |
|
---|
| 347 | #if __cplusplus > 201703L
|
---|
| 348 | #define __cpp_lib_starts_ends_with 201711L
|
---|
| 349 | constexpr bool
|
---|
| 350 | starts_with(basic_string_view __x) const noexcept
|
---|
| 351 | { return this->substr(0, __x.size()) == __x; }
|
---|
| 352 |
|
---|
| 353 | constexpr bool
|
---|
| 354 | starts_with(_CharT __x) const noexcept
|
---|
| 355 | { return !this->empty() && traits_type::eq(this->front(), __x); }
|
---|
| 356 |
|
---|
| 357 | constexpr bool
|
---|
| 358 | starts_with(const _CharT* __x) const noexcept
|
---|
| 359 | { return this->starts_with(basic_string_view(__x)); }
|
---|
| 360 |
|
---|
| 361 | constexpr bool
|
---|
| 362 | ends_with(basic_string_view __x) const noexcept
|
---|
| 363 | {
|
---|
| 364 | const auto __len = this->size();
|
---|
| 365 | const auto __xlen = __x.size();
|
---|
| 366 | return __len >= __xlen
|
---|
| 367 | && traits_type::compare(end() - __xlen, __x.data(), __xlen) == 0;
|
---|
| 368 | }
|
---|
| 369 |
|
---|
| 370 | constexpr bool
|
---|
| 371 | ends_with(_CharT __x) const noexcept
|
---|
| 372 | { return !this->empty() && traits_type::eq(this->back(), __x); }
|
---|
| 373 |
|
---|
| 374 | constexpr bool
|
---|
| 375 | ends_with(const _CharT* __x) const noexcept
|
---|
| 376 | { return this->ends_with(basic_string_view(__x)); }
|
---|
| 377 | #endif // C++20
|
---|
| 378 |
|
---|
| 379 | #if __cplusplus > 202002L
|
---|
| 380 | #define __cpp_lib_string_contains 202011L
|
---|
| 381 | constexpr bool
|
---|
| 382 | contains(basic_string_view __x) const noexcept
|
---|
| 383 | { return this->find(__x) != npos; }
|
---|
| 384 |
|
---|
| 385 | constexpr bool
|
---|
| 386 | contains(_CharT __x) const noexcept
|
---|
| 387 | { return this->find(__x) != npos; }
|
---|
| 388 |
|
---|
| 389 | constexpr bool
|
---|
| 390 | contains(const _CharT* __x) const noexcept
|
---|
| 391 | { return this->find(__x) != npos; }
|
---|
| 392 | #endif // C++23
|
---|
| 393 |
|
---|
| 394 | // [string.view.find], searching
|
---|
| 395 |
|
---|
| 396 | constexpr size_type
|
---|
| 397 | find(basic_string_view __str, size_type __pos = 0) const noexcept
|
---|
| 398 | { return this->find(__str._M_str, __pos, __str._M_len); }
|
---|
| 399 |
|
---|
| 400 | constexpr size_type
|
---|
| 401 | find(_CharT __c, size_type __pos = 0) const noexcept;
|
---|
| 402 |
|
---|
| 403 | constexpr size_type
|
---|
| 404 | find(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
|
---|
| 405 |
|
---|
| 406 | __attribute__((__nonnull__)) constexpr size_type
|
---|
| 407 | find(const _CharT* __str, size_type __pos = 0) const noexcept
|
---|
| 408 | { return this->find(__str, __pos, traits_type::length(__str)); }
|
---|
| 409 |
|
---|
| 410 | constexpr size_type
|
---|
| 411 | rfind(basic_string_view __str, size_type __pos = npos) const noexcept
|
---|
| 412 | { return this->rfind(__str._M_str, __pos, __str._M_len); }
|
---|
| 413 |
|
---|
| 414 | constexpr size_type
|
---|
| 415 | rfind(_CharT __c, size_type __pos = npos) const noexcept;
|
---|
| 416 |
|
---|
| 417 | constexpr size_type
|
---|
| 418 | rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
|
---|
| 419 |
|
---|
| 420 | __attribute__((__nonnull__)) constexpr size_type
|
---|
| 421 | rfind(const _CharT* __str, size_type __pos = npos) const noexcept
|
---|
| 422 | { return this->rfind(__str, __pos, traits_type::length(__str)); }
|
---|
| 423 |
|
---|
| 424 | constexpr size_type
|
---|
| 425 | find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept
|
---|
| 426 | { return this->find_first_of(__str._M_str, __pos, __str._M_len); }
|
---|
| 427 |
|
---|
| 428 | constexpr size_type
|
---|
| 429 | find_first_of(_CharT __c, size_type __pos = 0) const noexcept
|
---|
| 430 | { return this->find(__c, __pos); }
|
---|
| 431 |
|
---|
| 432 | constexpr size_type
|
---|
| 433 | find_first_of(const _CharT* __str, size_type __pos,
|
---|
| 434 | size_type __n) const noexcept;
|
---|
| 435 |
|
---|
| 436 | __attribute__((__nonnull__)) constexpr size_type
|
---|
| 437 | find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept
|
---|
| 438 | { return this->find_first_of(__str, __pos, traits_type::length(__str)); }
|
---|
| 439 |
|
---|
| 440 | constexpr size_type
|
---|
| 441 | find_last_of(basic_string_view __str,
|
---|
| 442 | size_type __pos = npos) const noexcept
|
---|
| 443 | { return this->find_last_of(__str._M_str, __pos, __str._M_len); }
|
---|
| 444 |
|
---|
| 445 | constexpr size_type
|
---|
| 446 | find_last_of(_CharT __c, size_type __pos=npos) const noexcept
|
---|
| 447 | { return this->rfind(__c, __pos); }
|
---|
| 448 |
|
---|
| 449 | constexpr size_type
|
---|
| 450 | find_last_of(const _CharT* __str, size_type __pos,
|
---|
| 451 | size_type __n) const noexcept;
|
---|
| 452 |
|
---|
| 453 | __attribute__((__nonnull__)) constexpr size_type
|
---|
| 454 | find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept
|
---|
| 455 | { return this->find_last_of(__str, __pos, traits_type::length(__str)); }
|
---|
| 456 |
|
---|
| 457 | constexpr size_type
|
---|
| 458 | find_first_not_of(basic_string_view __str,
|
---|
| 459 | size_type __pos = 0) const noexcept
|
---|
| 460 | { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); }
|
---|
| 461 |
|
---|
| 462 | constexpr size_type
|
---|
| 463 | find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept;
|
---|
| 464 |
|
---|
| 465 | constexpr size_type
|
---|
| 466 | find_first_not_of(const _CharT* __str,
|
---|
| 467 | size_type __pos, size_type __n) const noexcept;
|
---|
| 468 |
|
---|
| 469 | __attribute__((__nonnull__)) constexpr size_type
|
---|
| 470 | find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept
|
---|
| 471 | {
|
---|
| 472 | return this->find_first_not_of(__str, __pos,
|
---|
| 473 | traits_type::length(__str));
|
---|
| 474 | }
|
---|
| 475 |
|
---|
| 476 | constexpr size_type
|
---|
| 477 | find_last_not_of(basic_string_view __str,
|
---|
| 478 | size_type __pos = npos) const noexcept
|
---|
| 479 | { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); }
|
---|
| 480 |
|
---|
| 481 | constexpr size_type
|
---|
| 482 | find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept;
|
---|
| 483 |
|
---|
| 484 | constexpr size_type
|
---|
| 485 | find_last_not_of(const _CharT* __str,
|
---|
| 486 | size_type __pos, size_type __n) const noexcept;
|
---|
| 487 |
|
---|
| 488 | __attribute__((__nonnull__)) constexpr size_type
|
---|
| 489 | find_last_not_of(const _CharT* __str,
|
---|
| 490 | size_type __pos = npos) const noexcept
|
---|
| 491 | {
|
---|
| 492 | return this->find_last_not_of(__str, __pos,
|
---|
| 493 | traits_type::length(__str));
|
---|
| 494 | }
|
---|
| 495 |
|
---|
| 496 | private:
|
---|
| 497 |
|
---|
| 498 | static constexpr int
|
---|
| 499 | _S_compare(size_type __n1, size_type __n2) noexcept
|
---|
| 500 | {
|
---|
| 501 | using __limits = __gnu_cxx::__int_traits<int>;
|
---|
| 502 | const difference_type __diff = __n1 - __n2;
|
---|
| 503 | if (__diff > __limits::__max)
|
---|
| 504 | return __limits::__max;
|
---|
| 505 | if (__diff < __limits::__min)
|
---|
| 506 | return __limits::__min;
|
---|
| 507 | return static_cast<int>(__diff);
|
---|
| 508 | }
|
---|
| 509 |
|
---|
| 510 | size_t _M_len;
|
---|
| 511 | const _CharT* _M_str;
|
---|
| 512 | };
|
---|
| 513 |
|
---|
| 514 | #if __cplusplus > 201703L && __cpp_lib_concepts && __cpp_deduction_guides
|
---|
| 515 | template<contiguous_iterator _It, sized_sentinel_for<_It> _End>
|
---|
| 516 | basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>;
|
---|
| 517 |
|
---|
| 518 | #if __cplusplus > 202002L
|
---|
| 519 | template<ranges::contiguous_range _Range>
|
---|
| 520 | basic_string_view(_Range&&)
|
---|
| 521 | -> basic_string_view<ranges::range_value_t<_Range>>;
|
---|
| 522 | #endif
|
---|
| 523 | #endif
|
---|
| 524 |
|
---|
| 525 | // [string.view.comparison], non-member basic_string_view comparison function
|
---|
| 526 |
|
---|
| 527 | // Several of these functions use type_identity_t to create a non-deduced
|
---|
| 528 | // context, so that only one argument participates in template argument
|
---|
| 529 | // deduction and the other argument gets implicitly converted to the deduced
|
---|
| 530 | // type (see N3766).
|
---|
| 531 |
|
---|
| 532 | template<typename _CharT, typename _Traits>
|
---|
| 533 | constexpr bool
|
---|
| 534 | operator==(basic_string_view<_CharT, _Traits> __x,
|
---|
| 535 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
| 536 | { return __x.size() == __y.size() && __x.compare(__y) == 0; }
|
---|
| 537 |
|
---|
| 538 | template<typename _CharT, typename _Traits>
|
---|
| 539 | constexpr bool
|
---|
| 540 | operator==(basic_string_view<_CharT, _Traits> __x,
|
---|
| 541 | __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
|
---|
| 542 | noexcept
|
---|
| 543 | { return __x.size() == __y.size() && __x.compare(__y) == 0; }
|
---|
| 544 |
|
---|
| 545 | #if __cpp_lib_three_way_comparison
|
---|
| 546 | template<typename _CharT, typename _Traits>
|
---|
| 547 | constexpr auto
|
---|
| 548 | operator<=>(basic_string_view<_CharT, _Traits> __x,
|
---|
| 549 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
| 550 | -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
|
---|
| 551 | { return __detail::__char_traits_cmp_cat<_Traits>(__x.compare(__y)); }
|
---|
| 552 |
|
---|
| 553 | template<typename _CharT, typename _Traits>
|
---|
| 554 | constexpr auto
|
---|
| 555 | operator<=>(basic_string_view<_CharT, _Traits> __x,
|
---|
| 556 | __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
|
---|
| 557 | noexcept
|
---|
| 558 | -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
|
---|
| 559 | { return __detail::__char_traits_cmp_cat<_Traits>(__x.compare(__y)); }
|
---|
| 560 | #else
|
---|
| 561 | template<typename _CharT, typename _Traits>
|
---|
| 562 | constexpr bool
|
---|
| 563 | operator==(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
|
---|
| 564 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
| 565 | { return __x.size() == __y.size() && __x.compare(__y) == 0; }
|
---|
| 566 |
|
---|
| 567 | template<typename _CharT, typename _Traits>
|
---|
| 568 | constexpr bool
|
---|
| 569 | operator!=(basic_string_view<_CharT, _Traits> __x,
|
---|
| 570 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
| 571 | { return !(__x == __y); }
|
---|
| 572 |
|
---|
| 573 | template<typename _CharT, typename _Traits>
|
---|
| 574 | constexpr bool
|
---|
| 575 | operator!=(basic_string_view<_CharT, _Traits> __x,
|
---|
| 576 | __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
|
---|
| 577 | noexcept
|
---|
| 578 | { return !(__x == __y); }
|
---|
| 579 |
|
---|
| 580 | template<typename _CharT, typename _Traits>
|
---|
| 581 | constexpr bool
|
---|
| 582 | operator!=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
|
---|
| 583 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
| 584 | { return !(__x == __y); }
|
---|
| 585 |
|
---|
| 586 | template<typename _CharT, typename _Traits>
|
---|
| 587 | constexpr bool
|
---|
| 588 | operator< (basic_string_view<_CharT, _Traits> __x,
|
---|
| 589 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
| 590 | { return __x.compare(__y) < 0; }
|
---|
| 591 |
|
---|
| 592 | template<typename _CharT, typename _Traits>
|
---|
| 593 | constexpr bool
|
---|
| 594 | operator< (basic_string_view<_CharT, _Traits> __x,
|
---|
| 595 | __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
|
---|
| 596 | noexcept
|
---|
| 597 | { return __x.compare(__y) < 0; }
|
---|
| 598 |
|
---|
| 599 | template<typename _CharT, typename _Traits>
|
---|
| 600 | constexpr bool
|
---|
| 601 | operator< (__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
|
---|
| 602 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
| 603 | { return __x.compare(__y) < 0; }
|
---|
| 604 |
|
---|
| 605 | template<typename _CharT, typename _Traits>
|
---|
| 606 | constexpr bool
|
---|
| 607 | operator> (basic_string_view<_CharT, _Traits> __x,
|
---|
| 608 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
| 609 | { return __x.compare(__y) > 0; }
|
---|
| 610 |
|
---|
| 611 | template<typename _CharT, typename _Traits>
|
---|
| 612 | constexpr bool
|
---|
| 613 | operator> (basic_string_view<_CharT, _Traits> __x,
|
---|
| 614 | __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
|
---|
| 615 | noexcept
|
---|
| 616 | { return __x.compare(__y) > 0; }
|
---|
| 617 |
|
---|
| 618 | template<typename _CharT, typename _Traits>
|
---|
| 619 | constexpr bool
|
---|
| 620 | operator> (__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
|
---|
| 621 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
| 622 | { return __x.compare(__y) > 0; }
|
---|
| 623 |
|
---|
| 624 | template<typename _CharT, typename _Traits>
|
---|
| 625 | constexpr bool
|
---|
| 626 | operator<=(basic_string_view<_CharT, _Traits> __x,
|
---|
| 627 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
| 628 | { return __x.compare(__y) <= 0; }
|
---|
| 629 |
|
---|
| 630 | template<typename _CharT, typename _Traits>
|
---|
| 631 | constexpr bool
|
---|
| 632 | operator<=(basic_string_view<_CharT, _Traits> __x,
|
---|
| 633 | __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
|
---|
| 634 | noexcept
|
---|
| 635 | { return __x.compare(__y) <= 0; }
|
---|
| 636 |
|
---|
| 637 | template<typename _CharT, typename _Traits>
|
---|
| 638 | constexpr bool
|
---|
| 639 | operator<=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
|
---|
| 640 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
| 641 | { return __x.compare(__y) <= 0; }
|
---|
| 642 |
|
---|
| 643 | template<typename _CharT, typename _Traits>
|
---|
| 644 | constexpr bool
|
---|
| 645 | operator>=(basic_string_view<_CharT, _Traits> __x,
|
---|
| 646 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
| 647 | { return __x.compare(__y) >= 0; }
|
---|
| 648 |
|
---|
| 649 | template<typename _CharT, typename _Traits>
|
---|
| 650 | constexpr bool
|
---|
| 651 | operator>=(basic_string_view<_CharT, _Traits> __x,
|
---|
| 652 | __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
|
---|
| 653 | noexcept
|
---|
| 654 | { return __x.compare(__y) >= 0; }
|
---|
| 655 |
|
---|
| 656 | template<typename _CharT, typename _Traits>
|
---|
| 657 | constexpr bool
|
---|
| 658 | operator>=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
|
---|
| 659 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
| 660 | { return __x.compare(__y) >= 0; }
|
---|
| 661 | #endif // three-way comparison
|
---|
| 662 |
|
---|
| 663 | // [string.view.io], Inserters and extractors
|
---|
| 664 | template<typename _CharT, typename _Traits>
|
---|
| 665 | inline basic_ostream<_CharT, _Traits>&
|
---|
| 666 | operator<<(basic_ostream<_CharT, _Traits>& __os,
|
---|
| 667 | basic_string_view<_CharT,_Traits> __str)
|
---|
| 668 | { return __ostream_insert(__os, __str.data(), __str.size()); }
|
---|
| 669 |
|
---|
| 670 |
|
---|
| 671 | // basic_string_view typedef names
|
---|
| 672 |
|
---|
| 673 | using string_view = basic_string_view<char>;
|
---|
| 674 | #ifdef _GLIBCXX_USE_WCHAR_T
|
---|
| 675 | using wstring_view = basic_string_view<wchar_t>;
|
---|
| 676 | #endif
|
---|
| 677 | #ifdef _GLIBCXX_USE_CHAR8_T
|
---|
| 678 | using u8string_view = basic_string_view<char8_t>;
|
---|
| 679 | #endif
|
---|
| 680 | using u16string_view = basic_string_view<char16_t>;
|
---|
| 681 | using u32string_view = basic_string_view<char32_t>;
|
---|
| 682 |
|
---|
| 683 | // [string.view.hash], hash support:
|
---|
| 684 |
|
---|
| 685 | template<typename _Tp>
|
---|
| 686 | struct hash;
|
---|
| 687 |
|
---|
| 688 | template<>
|
---|
| 689 | struct hash<string_view>
|
---|
| 690 | : public __hash_base<size_t, string_view>
|
---|
| 691 | {
|
---|
| 692 | size_t
|
---|
| 693 | operator()(const string_view& __str) const noexcept
|
---|
| 694 | { return std::_Hash_impl::hash(__str.data(), __str.length()); }
|
---|
| 695 | };
|
---|
| 696 |
|
---|
| 697 | template<>
|
---|
| 698 | struct __is_fast_hash<hash<string_view>> : std::false_type
|
---|
| 699 | { };
|
---|
| 700 |
|
---|
| 701 | #ifdef _GLIBCXX_USE_WCHAR_T
|
---|
| 702 | template<>
|
---|
| 703 | struct hash<wstring_view>
|
---|
| 704 | : public __hash_base<size_t, wstring_view>
|
---|
| 705 | {
|
---|
| 706 | size_t
|
---|
| 707 | operator()(const wstring_view& __s) const noexcept
|
---|
| 708 | { return std::_Hash_impl::hash(__s.data(),
|
---|
| 709 | __s.length() * sizeof(wchar_t)); }
|
---|
| 710 | };
|
---|
| 711 |
|
---|
| 712 | template<>
|
---|
| 713 | struct __is_fast_hash<hash<wstring_view>> : std::false_type
|
---|
| 714 | { };
|
---|
| 715 | #endif
|
---|
| 716 |
|
---|
| 717 | #ifdef _GLIBCXX_USE_CHAR8_T
|
---|
| 718 | template<>
|
---|
| 719 | struct hash<u8string_view>
|
---|
| 720 | : public __hash_base<size_t, u8string_view>
|
---|
| 721 | {
|
---|
| 722 | size_t
|
---|
| 723 | operator()(const u8string_view& __str) const noexcept
|
---|
| 724 | { return std::_Hash_impl::hash(__str.data(), __str.length()); }
|
---|
| 725 | };
|
---|
| 726 |
|
---|
| 727 | template<>
|
---|
| 728 | struct __is_fast_hash<hash<u8string_view>> : std::false_type
|
---|
| 729 | { };
|
---|
| 730 | #endif
|
---|
| 731 |
|
---|
| 732 | template<>
|
---|
| 733 | struct hash<u16string_view>
|
---|
| 734 | : public __hash_base<size_t, u16string_view>
|
---|
| 735 | {
|
---|
| 736 | size_t
|
---|
| 737 | operator()(const u16string_view& __s) const noexcept
|
---|
| 738 | { return std::_Hash_impl::hash(__s.data(),
|
---|
| 739 | __s.length() * sizeof(char16_t)); }
|
---|
| 740 | };
|
---|
| 741 |
|
---|
| 742 | template<>
|
---|
| 743 | struct __is_fast_hash<hash<u16string_view>> : std::false_type
|
---|
| 744 | { };
|
---|
| 745 |
|
---|
| 746 | template<>
|
---|
| 747 | struct hash<u32string_view>
|
---|
| 748 | : public __hash_base<size_t, u32string_view>
|
---|
| 749 | {
|
---|
| 750 | size_t
|
---|
| 751 | operator()(const u32string_view& __s) const noexcept
|
---|
| 752 | { return std::_Hash_impl::hash(__s.data(),
|
---|
| 753 | __s.length() * sizeof(char32_t)); }
|
---|
| 754 | };
|
---|
| 755 |
|
---|
| 756 | template<>
|
---|
| 757 | struct __is_fast_hash<hash<u32string_view>> : std::false_type
|
---|
| 758 | { };
|
---|
| 759 |
|
---|
| 760 | inline namespace literals
|
---|
| 761 | {
|
---|
| 762 | inline namespace string_view_literals
|
---|
| 763 | {
|
---|
| 764 | #pragma GCC diagnostic push
|
---|
| 765 | #pragma GCC diagnostic ignored "-Wliteral-suffix"
|
---|
| 766 | inline constexpr basic_string_view<char>
|
---|
| 767 | operator""sv(const char* __str, size_t __len) noexcept
|
---|
| 768 | { return basic_string_view<char>{__str, __len}; }
|
---|
| 769 |
|
---|
| 770 | #ifdef _GLIBCXX_USE_WCHAR_T
|
---|
| 771 | inline constexpr basic_string_view<wchar_t>
|
---|
| 772 | operator""sv(const wchar_t* __str, size_t __len) noexcept
|
---|
| 773 | { return basic_string_view<wchar_t>{__str, __len}; }
|
---|
| 774 | #endif
|
---|
| 775 |
|
---|
| 776 | #ifdef _GLIBCXX_USE_CHAR8_T
|
---|
| 777 | inline constexpr basic_string_view<char8_t>
|
---|
| 778 | operator""sv(const char8_t* __str, size_t __len) noexcept
|
---|
| 779 | { return basic_string_view<char8_t>{__str, __len}; }
|
---|
| 780 | #endif
|
---|
| 781 |
|
---|
| 782 | inline constexpr basic_string_view<char16_t>
|
---|
| 783 | operator""sv(const char16_t* __str, size_t __len) noexcept
|
---|
| 784 | { return basic_string_view<char16_t>{__str, __len}; }
|
---|
| 785 |
|
---|
| 786 | inline constexpr basic_string_view<char32_t>
|
---|
| 787 | operator""sv(const char32_t* __str, size_t __len) noexcept
|
---|
| 788 | { return basic_string_view<char32_t>{__str, __len}; }
|
---|
| 789 |
|
---|
| 790 | #pragma GCC diagnostic pop
|
---|
| 791 | } // namespace string_literals
|
---|
| 792 | } // namespace literals
|
---|
| 793 |
|
---|
| 794 | #if __cpp_lib_concepts
|
---|
| 795 | namespace ranges
|
---|
| 796 | {
|
---|
| 797 | // Opt-in to borrowed_range concept
|
---|
| 798 | template<typename _CharT, typename _Traits>
|
---|
| 799 | inline constexpr bool
|
---|
| 800 | enable_borrowed_range<basic_string_view<_CharT, _Traits>> = true;
|
---|
| 801 |
|
---|
| 802 | // Opt-in to view concept
|
---|
| 803 | template<typename _CharT, typename _Traits>
|
---|
| 804 | inline constexpr bool
|
---|
| 805 | enable_view<basic_string_view<_CharT, _Traits>> = true;
|
---|
| 806 | }
|
---|
| 807 | #endif
|
---|
| 808 | _GLIBCXX_END_NAMESPACE_VERSION
|
---|
| 809 | } // namespace std
|
---|
| 810 |
|
---|
| 811 | #include <bits/string_view.tcc>
|
---|
| 812 |
|
---|
| 813 | #endif // __cplusplus <= 201402L
|
---|
| 814 |
|
---|
| 815 | #endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW
|
---|