Coverage Report

Created: 2023-06-07 07:09

/src/LPM/external.protobuf/include/absl/strings/string_view.h
Line
Count
Source (jump to first uncovered line)
1
//
2
// Copyright 2017 The Abseil Authors.
3
//
4
// Licensed under the Apache License, Version 2.0 (the "License");
5
// you may not use this file except in compliance with the License.
6
// You may obtain a copy of the License at
7
//
8
//      https://www.apache.org/licenses/LICENSE-2.0
9
//
10
// Unless required by applicable law or agreed to in writing, software
11
// distributed under the License is distributed on an "AS IS" BASIS,
12
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
// See the License for the specific language governing permissions and
14
// limitations under the License.
15
//
16
// -----------------------------------------------------------------------------
17
// File: string_view.h
18
// -----------------------------------------------------------------------------
19
//
20
// This file contains the definition of the `absl::string_view` class. A
21
// `string_view` points to a contiguous span of characters, often part or all of
22
// another `std::string`, double-quoted string literal, character array, or even
23
// another `string_view`.
24
//
25
// This `absl::string_view` abstraction is designed to be a drop-in
26
// replacement for the C++17 `std::string_view` abstraction.
27
#ifndef ABSL_STRINGS_STRING_VIEW_H_
28
#define ABSL_STRINGS_STRING_VIEW_H_
29
30
#include <algorithm>
31
#include <cassert>
32
#include <cstddef>
33
#include <cstring>
34
#include <iosfwd>
35
#include <iterator>
36
#include <limits>
37
#include <string>
38
39
#include "absl/base/attributes.h"
40
#include "absl/base/config.h"
41
#include "absl/base/internal/throw_delegate.h"
42
#include "absl/base/macros.h"
43
#include "absl/base/optimization.h"
44
#include "absl/base/port.h"
45
46
#ifdef ABSL_USES_STD_STRING_VIEW
47
48
#include <string_view>  // IWYU pragma: export
49
50
namespace absl {
51
ABSL_NAMESPACE_BEGIN
52
using string_view = std::string_view;
53
ABSL_NAMESPACE_END
54
}  // namespace absl
55
56
#else  // ABSL_USES_STD_STRING_VIEW
57
58
#if ABSL_HAVE_BUILTIN(__builtin_memcmp) ||        \
59
    (defined(__GNUC__) && !defined(__clang__)) || \
60
    (defined(_MSC_VER) && _MSC_VER >= 1928)
61
#define ABSL_INTERNAL_STRING_VIEW_MEMCMP __builtin_memcmp
62
#else  // ABSL_HAVE_BUILTIN(__builtin_memcmp)
63
#define ABSL_INTERNAL_STRING_VIEW_MEMCMP memcmp
64
#endif  // ABSL_HAVE_BUILTIN(__builtin_memcmp)
65
66
namespace absl {
67
ABSL_NAMESPACE_BEGIN
68
69
// absl::string_view
70
//
71
// A `string_view` provides a lightweight view into the string data provided by
72
// a `std::string`, double-quoted string literal, character array, or even
73
// another `string_view`. A `string_view` does *not* own the string to which it
74
// points, and that data cannot be modified through the view.
75
//
76
// You can use `string_view` as a function or method parameter anywhere a
77
// parameter can receive a double-quoted string literal, `const char*`,
78
// `std::string`, or another `absl::string_view` argument with no need to copy
79
// the string data. Systematic use of `string_view` within function arguments
80
// reduces data copies and `strlen()` calls.
81
//
82
// Because of its small size, prefer passing `string_view` by value:
83
//
84
//   void MyFunction(absl::string_view arg);
85
//
86
// If circumstances require, you may also pass one by const reference:
87
//
88
//   void MyFunction(const absl::string_view& arg);  // not preferred
89
//
90
// Passing by value generates slightly smaller code for many architectures.
91
//
92
// In either case, the source data of the `string_view` must outlive the
93
// `string_view` itself.
94
//
95
// A `string_view` is also suitable for local variables if you know that the
96
// lifetime of the underlying object is longer than the lifetime of your
97
// `string_view` variable. However, beware of binding a `string_view` to a
98
// temporary value:
99
//
100
//   // BAD use of string_view: lifetime problem
101
//   absl::string_view sv = obj.ReturnAString();
102
//
103
//   // GOOD use of string_view: str outlives sv
104
//   std::string str = obj.ReturnAString();
105
//   absl::string_view sv = str;
106
//
107
// Due to lifetime issues, a `string_view` is sometimes a poor choice for a
108
// return value and usually a poor choice for a data member. If you do use a
109
// `string_view` this way, it is your responsibility to ensure that the object
110
// pointed to by the `string_view` outlives the `string_view`.
111
//
112
// A `string_view` may represent a whole string or just part of a string. For
113
// example, when splitting a string, `std::vector<absl::string_view>` is a
114
// natural data type for the output.
115
//
116
// For another example, a Cord is a non-contiguous, potentially very
117
// long string-like object.  The Cord class has an interface that iteratively
118
// provides string_view objects that point to the successive pieces of a Cord
119
// object.
120
//
121
// When constructed from a source which is NUL-terminated, the `string_view`
122
// itself will not include the NUL-terminator unless a specific size (including
123
// the NUL) is passed to the constructor. As a result, common idioms that work
124
// on NUL-terminated strings do not work on `string_view` objects. If you write
125
// code that scans a `string_view`, you must check its length rather than test
126
// for nul, for example. Note, however, that nuls may still be embedded within
127
// a `string_view` explicitly.
128
//
129
// You may create a null `string_view` in two ways:
130
//
131
//   absl::string_view sv;
132
//   absl::string_view sv(nullptr, 0);
133
//
134
// For the above, `sv.data() == nullptr`, `sv.length() == 0`, and
135
// `sv.empty() == true`. Also, if you create a `string_view` with a non-null
136
// pointer then `sv.data() != nullptr`. Thus, you can use `string_view()` to
137
// signal an undefined value that is different from other `string_view` values
138
// in a similar fashion to how `const char* p1 = nullptr;` is different from
139
// `const char* p2 = "";`. However, in practice, it is not recommended to rely
140
// on this behavior.
141
//
142
// Be careful not to confuse a null `string_view` with an empty one. A null
143
// `string_view` is an empty `string_view`, but some empty `string_view`s are
144
// not null. Prefer checking for emptiness over checking for null.
145
//
146
// There are many ways to create an empty string_view:
147
//
148
//   const char* nullcp = nullptr;
149
//   // string_view.size() will return 0 in all cases.
150
//   absl::string_view();
151
//   absl::string_view(nullcp, 0);
152
//   absl::string_view("");
153
//   absl::string_view("", 0);
154
//   absl::string_view("abcdef", 0);
155
//   absl::string_view("abcdef" + 6, 0);
156
//
157
// All empty `string_view` objects whether null or not, are equal:
158
//
159
//   absl::string_view() == absl::string_view("", 0)
160
//   absl::string_view(nullptr, 0) == absl::string_view("abcdef"+6, 0)
161
class string_view {
162
 public:
163
  using traits_type = std::char_traits<char>;
164
  using value_type = char;
165
  using pointer = char*;
166
  using const_pointer = const char*;
167
  using reference = char&;
168
  using const_reference = const char&;
169
  using const_iterator = const char*;
170
  using iterator = const_iterator;
171
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
172
  using reverse_iterator = const_reverse_iterator;
173
  using size_type = size_t;
174
  using difference_type = std::ptrdiff_t;
175
176
  static constexpr size_type npos = static_cast<size_type>(-1);
177
178
  // Null `string_view` constructor
179
0
  constexpr string_view() noexcept : ptr_(nullptr), length_(0) {}
180
181
  // Implicit constructors
182
183
  template <typename Allocator>
184
  string_view(  // NOLINT(runtime/explicit)
185
      const std::basic_string<char, std::char_traits<char>, Allocator>& str
186
          ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept
187
      // This is implemented in terms of `string_view(p, n)` so `str.size()`
188
      // doesn't need to be reevaluated after `ptr_` is set.
189
      // The length check is also skipped since it is unnecessary and causes
190
      // code bloat.
191
      : string_view(str.data(), str.size(), SkipCheckLengthTag{}) {}
192
193
  // Implicit constructor of a `string_view` from NUL-terminated `str`. When
194
  // accepting possibly null strings, use `absl::NullSafeStringView(str)`
195
  // instead (see below).
196
  // The length check is skipped since it is unnecessary and causes code bloat.
197
  constexpr string_view(const char* str)  // NOLINT(runtime/explicit)
198
0
      : ptr_(str), length_(str ? StrlenInternal(str) : 0) {}
199
200
  // Implicit constructor of a `string_view` from a `const char*` and length.
201
  constexpr string_view(const char* data, size_type len)
202
0
      : ptr_(data), length_(CheckLengthInternal(len)) {}
203
204
  // NOTE: Harmlessly omitted to work around gdb bug.
205
  //   constexpr string_view(const string_view&) noexcept = default;
206
  //   string_view& operator=(const string_view&) noexcept = default;
207
208
  // Iterators
209
210
  // string_view::begin()
211
  //
212
  // Returns an iterator pointing to the first character at the beginning of the
213
  // `string_view`, or `end()` if the `string_view` is empty.
214
0
  constexpr const_iterator begin() const noexcept { return ptr_; }
215
216
  // string_view::end()
217
  //
218
  // Returns an iterator pointing just beyond the last character at the end of
219
  // the `string_view`. This iterator acts as a placeholder; attempting to
220
  // access it results in undefined behavior.
221
0
  constexpr const_iterator end() const noexcept { return ptr_ + length_; }
222
223
  // string_view::cbegin()
224
  //
225
  // Returns a const iterator pointing to the first character at the beginning
226
  // of the `string_view`, or `end()` if the `string_view` is empty.
227
0
  constexpr const_iterator cbegin() const noexcept { return begin(); }
228
229
  // string_view::cend()
230
  //
231
  // Returns a const iterator pointing just beyond the last character at the end
232
  // of the `string_view`. This pointer acts as a placeholder; attempting to
233
  // access its element results in undefined behavior.
234
0
  constexpr const_iterator cend() const noexcept { return end(); }
235
236
  // string_view::rbegin()
237
  //
238
  // Returns a reverse iterator pointing to the last character at the end of the
239
  // `string_view`, or `rend()` if the `string_view` is empty.
240
0
  const_reverse_iterator rbegin() const noexcept {
241
0
    return const_reverse_iterator(end());
242
0
  }
243
244
  // string_view::rend()
245
  //
246
  // Returns a reverse iterator pointing just before the first character at the
247
  // beginning of the `string_view`. This pointer acts as a placeholder;
248
  // attempting to access its element results in undefined behavior.
249
0
  const_reverse_iterator rend() const noexcept {
250
0
    return const_reverse_iterator(begin());
251
0
  }
252
253
  // string_view::crbegin()
254
  //
255
  // Returns a const reverse iterator pointing to the last character at the end
256
  // of the `string_view`, or `crend()` if the `string_view` is empty.
257
0
  const_reverse_iterator crbegin() const noexcept { return rbegin(); }
258
259
  // string_view::crend()
260
  //
261
  // Returns a const reverse iterator pointing just before the first character
262
  // at the beginning of the `string_view`. This pointer acts as a placeholder;
263
  // attempting to access its element results in undefined behavior.
264
0
  const_reverse_iterator crend() const noexcept { return rend(); }
265
266
  // Capacity Utilities
267
268
  // string_view::size()
269
  //
270
  // Returns the number of characters in the `string_view`.
271
0
  constexpr size_type size() const noexcept { return length_; }
272
273
  // string_view::length()
274
  //
275
  // Returns the number of characters in the `string_view`. Alias for `size()`.
276
0
  constexpr size_type length() const noexcept { return size(); }
277
278
  // string_view::max_size()
279
  //
280
  // Returns the maximum number of characters the `string_view` can hold.
281
0
  constexpr size_type max_size() const noexcept { return kMaxSize; }
282
283
  // string_view::empty()
284
  //
285
  // Checks if the `string_view` is empty (refers to no characters).
286
0
  constexpr bool empty() const noexcept { return length_ == 0; }
287
288
  // string_view::operator[]
289
  //
290
  // Returns the ith element of the `string_view` using the array operator.
291
  // Note that this operator does not perform any bounds checking.
292
0
  constexpr const_reference operator[](size_type i) const {
293
0
    return ABSL_HARDENING_ASSERT(i < size()), ptr_[i];
294
0
  }
295
296
  // string_view::at()
297
  //
298
  // Returns the ith element of the `string_view`. Bounds checking is performed,
299
  // and an exception of type `std::out_of_range` will be thrown on invalid
300
  // access.
301
0
  constexpr const_reference at(size_type i) const {
302
0
    return ABSL_PREDICT_TRUE(i < size())
303
0
               ? ptr_[i]
304
0
               : ((void)base_internal::ThrowStdOutOfRange(
305
0
                      "absl::string_view::at"),
306
0
                  ptr_[i]);
307
0
  }
308
309
  // string_view::front()
310
  //
311
  // Returns the first element of a `string_view`.
312
0
  constexpr const_reference front() const {
313
0
    return ABSL_HARDENING_ASSERT(!empty()), ptr_[0];
314
0
  }
315
316
  // string_view::back()
317
  //
318
  // Returns the last element of a `string_view`.
319
0
  constexpr const_reference back() const {
320
0
    return ABSL_HARDENING_ASSERT(!empty()), ptr_[size() - 1];
321
0
  }
322
323
  // string_view::data()
324
  //
325
  // Returns a pointer to the underlying character array (which is of course
326
  // stored elsewhere). Note that `string_view::data()` may contain embedded nul
327
  // characters, but the returned buffer may or may not be NUL-terminated;
328
  // therefore, do not pass `data()` to a routine that expects a NUL-terminated
329
  // string.
330
0
  constexpr const_pointer data() const noexcept { return ptr_; }
331
332
  // Modifiers
333
334
  // string_view::remove_prefix()
335
  //
336
  // Removes the first `n` characters from the `string_view`. Note that the
337
  // underlying string is not changed, only the view.
338
0
  constexpr void remove_prefix(size_type n) {
339
0
    ABSL_HARDENING_ASSERT(n <= length_);
340
0
    ptr_ += n;
341
0
    length_ -= n;
342
0
  }
343
344
  // string_view::remove_suffix()
345
  //
346
  // Removes the last `n` characters from the `string_view`. Note that the
347
  // underlying string is not changed, only the view.
348
0
  constexpr void remove_suffix(size_type n) {
349
0
    ABSL_HARDENING_ASSERT(n <= length_);
350
0
    length_ -= n;
351
0
  }
352
353
  // string_view::swap()
354
  //
355
  // Swaps this `string_view` with another `string_view`.
356
0
  constexpr void swap(string_view& s) noexcept {
357
0
    auto t = *this;
358
0
    *this = s;
359
0
    s = t;
360
0
  }
361
362
  // Explicit conversion operators
363
364
  // Converts to `std::basic_string`.
365
  template <typename A>
366
0
  explicit operator std::basic_string<char, traits_type, A>() const {
367
0
    if (!data()) return {};
368
0
    return std::basic_string<char, traits_type, A>(data(), size());
369
0
  }
370
371
  // string_view::copy()
372
  //
373
  // Copies the contents of the `string_view` at offset `pos` and length `n`
374
  // into `buf`.
375
0
  size_type copy(char* buf, size_type n, size_type pos = 0) const {
376
0
    if (ABSL_PREDICT_FALSE(pos > length_)) {
377
0
      base_internal::ThrowStdOutOfRange("absl::string_view::copy");
378
0
    }
379
0
    size_type rlen = (std::min)(length_ - pos, n);
380
0
    if (rlen > 0) {
381
0
      const char* start = ptr_ + pos;
382
0
      traits_type::copy(buf, start, rlen);
383
0
    }
384
0
    return rlen;
385
0
  }
386
387
  // string_view::substr()
388
  //
389
  // Returns a "substring" of the `string_view` (at offset `pos` and length
390
  // `n`) as another string_view. This function throws `std::out_of_bounds` if
391
  // `pos > size`.
392
  // Use absl::ClippedSubstr if you need a truncating substr operation.
393
0
  constexpr string_view substr(size_type pos = 0, size_type n = npos) const {
394
0
    return ABSL_PREDICT_FALSE(pos > length_)
395
0
               ? (base_internal::ThrowStdOutOfRange(
396
0
                      "absl::string_view::substr"),
397
0
                  string_view())
398
0
               : string_view(ptr_ + pos, Min(n, length_ - pos));
399
0
  }
400
401
  // string_view::compare()
402
  //
403
  // Performs a lexicographical comparison between this `string_view` and
404
  // another `string_view` `x`, returning a negative value if `*this` is less
405
  // than `x`, 0 if `*this` is equal to `x`, and a positive value if `*this`
406
  // is greater than `x`.
407
0
  constexpr int compare(string_view x) const noexcept {
408
0
    return CompareImpl(length_, x.length_,
409
0
                       Min(length_, x.length_) == 0
410
0
                           ? 0
411
0
                           : ABSL_INTERNAL_STRING_VIEW_MEMCMP(
412
0
                                 ptr_, x.ptr_, Min(length_, x.length_)));
413
0
  }
414
415
  // Overload of `string_view::compare()` for comparing a substring of the
416
  // 'string_view` and another `absl::string_view`.
417
0
  constexpr int compare(size_type pos1, size_type count1, string_view v) const {
418
0
    return substr(pos1, count1).compare(v);
419
0
  }
420
421
  // Overload of `string_view::compare()` for comparing a substring of the
422
  // `string_view` and a substring of another `absl::string_view`.
423
  constexpr int compare(size_type pos1, size_type count1, string_view v,
424
0
                        size_type pos2, size_type count2) const {
425
0
    return substr(pos1, count1).compare(v.substr(pos2, count2));
426
0
  }
427
428
  // Overload of `string_view::compare()` for comparing a `string_view` and a
429
  // a different C-style string `s`.
430
0
  constexpr int compare(const char* s) const { return compare(string_view(s)); }
431
432
  // Overload of `string_view::compare()` for comparing a substring of the
433
  // `string_view` and a different string C-style string `s`.
434
0
  constexpr int compare(size_type pos1, size_type count1, const char* s) const {
435
0
    return substr(pos1, count1).compare(string_view(s));
436
0
  }
437
438
  // Overload of `string_view::compare()` for comparing a substring of the
439
  // `string_view` and a substring of a different C-style string `s`.
440
  constexpr int compare(size_type pos1, size_type count1, const char* s,
441
0
                        size_type count2) const {
442
0
    return substr(pos1, count1).compare(string_view(s, count2));
443
0
  }
444
445
  // Find Utilities
446
447
  // string_view::find()
448
  //
449
  // Finds the first occurrence of the substring `s` within the `string_view`,
450
  // returning the position of the first character's match, or `npos` if no
451
  // match was found.
452
  size_type find(string_view s, size_type pos = 0) const noexcept;
453
454
  // Overload of `string_view::find()` for finding the given character `c`
455
  // within the `string_view`.
456
  size_type find(char c, size_type pos = 0) const noexcept;
457
458
  // Overload of `string_view::find()` for finding a substring of a different
459
  // C-style string `s` within the `string_view`.
460
0
  size_type find(const char* s, size_type pos, size_type count) const {
461
0
    return find(string_view(s, count), pos);
462
0
  }
463
464
  // Overload of `string_view::find()` for finding a different C-style string
465
  // `s` within the `string_view`.
466
0
  size_type find(const char* s, size_type pos = 0) const {
467
0
    return find(string_view(s), pos);
468
0
  }
469
470
  // string_view::rfind()
471
  //
472
  // Finds the last occurrence of a substring `s` within the `string_view`,
473
  // returning the position of the first character's match, or `npos` if no
474
  // match was found.
475
  size_type rfind(string_view s, size_type pos = npos) const noexcept;
476
477
  // Overload of `string_view::rfind()` for finding the last given character `c`
478
  // within the `string_view`.
479
  size_type rfind(char c, size_type pos = npos) const noexcept;
480
481
  // Overload of `string_view::rfind()` for finding a substring of a different
482
  // C-style string `s` within the `string_view`.
483
0
  size_type rfind(const char* s, size_type pos, size_type count) const {
484
0
    return rfind(string_view(s, count), pos);
485
0
  }
486
487
  // Overload of `string_view::rfind()` for finding a different C-style string
488
  // `s` within the `string_view`.
489
0
  size_type rfind(const char* s, size_type pos = npos) const {
490
0
    return rfind(string_view(s), pos);
491
0
  }
492
493
  // string_view::find_first_of()
494
  //
495
  // Finds the first occurrence of any of the characters in `s` within the
496
  // `string_view`, returning the start position of the match, or `npos` if no
497
  // match was found.
498
  size_type find_first_of(string_view s, size_type pos = 0) const noexcept;
499
500
  // Overload of `string_view::find_first_of()` for finding a character `c`
501
  // within the `string_view`.
502
0
  size_type find_first_of(char c, size_type pos = 0) const noexcept {
503
0
    return find(c, pos);
504
0
  }
505
506
  // Overload of `string_view::find_first_of()` for finding a substring of a
507
  // different C-style string `s` within the `string_view`.
508
  size_type find_first_of(const char* s, size_type pos,
509
0
                                    size_type count) const {
510
0
    return find_first_of(string_view(s, count), pos);
511
0
  }
512
513
  // Overload of `string_view::find_first_of()` for finding a different C-style
514
  // string `s` within the `string_view`.
515
0
  size_type find_first_of(const char* s, size_type pos = 0) const {
516
0
    return find_first_of(string_view(s), pos);
517
0
  }
518
519
  // string_view::find_last_of()
520
  //
521
  // Finds the last occurrence of any of the characters in `s` within the
522
  // `string_view`, returning the start position of the match, or `npos` if no
523
  // match was found.
524
  size_type find_last_of(string_view s, size_type pos = npos) const noexcept;
525
526
  // Overload of `string_view::find_last_of()` for finding a character `c`
527
  // within the `string_view`.
528
0
  size_type find_last_of(char c, size_type pos = npos) const noexcept {
529
0
    return rfind(c, pos);
530
0
  }
531
532
  // Overload of `string_view::find_last_of()` for finding a substring of a
533
  // different C-style string `s` within the `string_view`.
534
0
  size_type find_last_of(const char* s, size_type pos, size_type count) const {
535
0
    return find_last_of(string_view(s, count), pos);
536
0
  }
537
538
  // Overload of `string_view::find_last_of()` for finding a different C-style
539
  // string `s` within the `string_view`.
540
0
  size_type find_last_of(const char* s, size_type pos = npos) const {
541
0
    return find_last_of(string_view(s), pos);
542
0
  }
543
544
  // string_view::find_first_not_of()
545
  //
546
  // Finds the first occurrence of any of the characters not in `s` within the
547
  // `string_view`, returning the start position of the first non-match, or
548
  // `npos` if no non-match was found.
549
  size_type find_first_not_of(string_view s, size_type pos = 0) const noexcept;
550
551
  // Overload of `string_view::find_first_not_of()` for finding a character
552
  // that is not `c` within the `string_view`.
553
  size_type find_first_not_of(char c, size_type pos = 0) const noexcept;
554
555
  // Overload of `string_view::find_first_not_of()` for finding a substring of a
556
  // different C-style string `s` within the `string_view`.
557
  size_type find_first_not_of(const char* s, size_type pos,
558
0
                              size_type count) const {
559
0
    return find_first_not_of(string_view(s, count), pos);
560
0
  }
561
562
  // Overload of `string_view::find_first_not_of()` for finding a different
563
  // C-style string `s` within the `string_view`.
564
0
  size_type find_first_not_of(const char* s, size_type pos = 0) const {
565
0
    return find_first_not_of(string_view(s), pos);
566
0
  }
567
568
  // string_view::find_last_not_of()
569
  //
570
  // Finds the last occurrence of any of the characters not in `s` within the
571
  // `string_view`, returning the start position of the last non-match, or
572
  // `npos` if no non-match was found.
573
  size_type find_last_not_of(string_view s,
574
                             size_type pos = npos) const noexcept;
575
576
  // Overload of `string_view::find_last_not_of()` for finding a character
577
  // that is not `c` within the `string_view`.
578
  size_type find_last_not_of(char c, size_type pos = npos) const noexcept;
579
580
  // Overload of `string_view::find_last_not_of()` for finding a substring of a
581
  // different C-style string `s` within the `string_view`.
582
  size_type find_last_not_of(const char* s, size_type pos,
583
0
                             size_type count) const {
584
0
    return find_last_not_of(string_view(s, count), pos);
585
0
  }
586
587
  // Overload of `string_view::find_last_not_of()` for finding a different
588
  // C-style string `s` within the `string_view`.
589
0
  size_type find_last_not_of(const char* s, size_type pos = npos) const {
590
0
    return find_last_not_of(string_view(s), pos);
591
0
  }
592
593
 private:
594
  // The constructor from std::string delegates to this constructor.
595
  // See the comment on that constructor for the rationale.
596
  struct SkipCheckLengthTag {};
597
  string_view(const char* data, size_type len, SkipCheckLengthTag) noexcept
598
0
      : ptr_(data), length_(len) {}
599
600
  static constexpr size_type kMaxSize =
601
      (std::numeric_limits<difference_type>::max)();
602
603
0
  static constexpr size_type CheckLengthInternal(size_type len) {
604
0
    return ABSL_HARDENING_ASSERT(len <= kMaxSize), len;
605
0
  }
606
607
0
  static constexpr size_type StrlenInternal(const char* str) {
608
0
#if defined(_MSC_VER) && _MSC_VER >= 1910 && !defined(__clang__)
609
0
    // MSVC 2017+ can evaluate this at compile-time.
610
0
    const char* begin = str;
611
0
    while (*str != '\0') ++str;
612
0
    return str - begin;
613
0
#elif ABSL_HAVE_BUILTIN(__builtin_strlen) || \
614
0
    (defined(__GNUC__) && !defined(__clang__))
615
0
    // GCC has __builtin_strlen according to
616
0
    // https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Other-Builtins.html, but
617
0
    // ABSL_HAVE_BUILTIN doesn't detect that, so we use the extra checks above.
618
0
    // __builtin_strlen is constexpr.
619
0
    return __builtin_strlen(str);
620
0
#else
621
0
    return str ? strlen(str) : 0;
622
0
#endif
623
0
  }
624
625
0
  static constexpr size_t Min(size_type length_a, size_type length_b) {
626
0
    return length_a < length_b ? length_a : length_b;
627
0
  }
628
629
  static constexpr int CompareImpl(size_type length_a, size_type length_b,
630
0
                                   int compare_result) {
631
0
    return compare_result == 0 ? static_cast<int>(length_a > length_b) -
632
0
                                     static_cast<int>(length_a < length_b)
633
0
                               : (compare_result < 0 ? -1 : 1);
634
0
  }
635
636
  const char* ptr_;
637
  size_type length_;
638
};
639
640
// This large function is defined inline so that in a fairly common case where
641
// one of the arguments is a literal, the compiler can elide a lot of the
642
// following comparisons.
643
0
constexpr bool operator==(string_view x, string_view y) noexcept {
644
0
  return x.size() == y.size() &&
645
0
         (x.empty() ||
646
0
          ABSL_INTERNAL_STRING_VIEW_MEMCMP(x.data(), y.data(), x.size()) == 0);
647
0
}
648
649
0
constexpr bool operator!=(string_view x, string_view y) noexcept {
650
0
  return !(x == y);
651
0
}
652
653
0
constexpr bool operator<(string_view x, string_view y) noexcept {
654
0
  return x.compare(y) < 0;
655
0
}
656
657
0
constexpr bool operator>(string_view x, string_view y) noexcept {
658
0
  return y < x;
659
0
}
660
661
0
constexpr bool operator<=(string_view x, string_view y) noexcept {
662
0
  return !(y < x);
663
0
}
664
665
0
constexpr bool operator>=(string_view x, string_view y) noexcept {
666
0
  return !(x < y);
667
0
}
668
669
// IO Insertion Operator
670
std::ostream& operator<<(std::ostream& o, string_view piece);
671
672
ABSL_NAMESPACE_END
673
}  // namespace absl
674
675
#undef ABSL_INTERNAL_STRING_VIEW_MEMCMP
676
677
#endif  // ABSL_USES_STD_STRING_VIEW
678
679
namespace absl {
680
ABSL_NAMESPACE_BEGIN
681
682
// ClippedSubstr()
683
//
684
// Like `s.substr(pos, n)`, but clips `pos` to an upper bound of `s.size()`.
685
// Provided because std::string_view::substr throws if `pos > size()`
686
inline string_view ClippedSubstr(string_view s, size_t pos,
687
0
                                 size_t n = string_view::npos) {
688
0
  pos = (std::min)(pos, static_cast<size_t>(s.size()));
689
0
  return s.substr(pos, n);
690
0
}
691
692
// NullSafeStringView()
693
//
694
// Creates an `absl::string_view` from a pointer `p` even if it's null-valued.
695
// This function should be used where an `absl::string_view` can be created from
696
// a possibly-null pointer.
697
0
constexpr string_view NullSafeStringView(const char* p) {
698
0
  return p ? string_view(p) : string_view();
699
0
}
700
701
ABSL_NAMESPACE_END
702
}  // namespace absl
703
704
#endif  // ABSL_STRINGS_STRING_VIEW_H_