diff options
Diffstat (limited to 'absl/strings/string_view.h')
-rw-r--r-- | absl/strings/string_view.h | 71 |
1 files changed, 45 insertions, 26 deletions
diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h index df6f1ae4..3a0a4609 100644 --- a/absl/strings/string_view.h +++ b/absl/strings/string_view.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -32,12 +32,12 @@ #ifdef ABSL_HAVE_STD_STRING_VIEW -#include <string_view> +#include <string_view> // IWYU pragma: export namespace absl { -inline namespace lts_2018_12_18 { +inline namespace lts_2019_08_08 { using std::string_view; -} // inline namespace lts_2018_12_18 +} // inline namespace lts_2019_08_08 } // namespace absl #else // ABSL_HAVE_STD_STRING_VIEW @@ -52,10 +52,11 @@ using std::string_view; #include "absl/base/internal/throw_delegate.h" #include "absl/base/macros.h" +#include "absl/base/optimization.h" #include "absl/base/port.h" namespace absl { -inline namespace lts_2018_12_18 { +inline namespace lts_2019_08_08 { // absl::string_view // @@ -104,7 +105,6 @@ inline namespace lts_2018_12_18 { // example, when splitting a string, `std::vector<absl::string_view>` is a // natural data type for the output. // -// // When constructed from a source which is nul-terminated, the `string_view` // itself will not include the nul-terminator unless a specific size (including // the nul) is passed to the constructor. As a result, common idioms that work @@ -176,19 +176,9 @@ class string_view { // Implicit constructor of a `string_view` from nul-terminated `str`. When // accepting possibly null strings, use `absl::NullSafeStringView(str)` // instead (see below). -#if ABSL_HAVE_BUILTIN(__builtin_strlen) || \ - (defined(__GNUC__) && !defined(__clang__)) - // GCC has __builtin_strlen according to - // https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Other-Builtins.html, but - // ABSL_HAVE_BUILTIN doesn't detect that, so we use the extra checks above. - // __builtin_strlen is constexpr. constexpr string_view(const char* str) // NOLINT(runtime/explicit) : ptr_(str), - length_(CheckLengthInternal(str ? __builtin_strlen(str) : 0)) {} -#else - constexpr string_view(const char* str) // NOLINT(runtime/explicit) - : ptr_(str), length_(CheckLengthInternal(str ? strlen(str) : 0)) {} -#endif + length_(str ? CheckLengthInternal(StrlenInternal(str)) : 0) {} // Implicit constructor of a `string_view` from a `const char*` and length. constexpr string_view(const char* data, size_type len) @@ -280,7 +270,7 @@ class string_view { // Checks if the `string_view` is empty (refers to no characters). constexpr bool empty() const noexcept { return length_ == 0; } - // std::string:view::operator[] + // string_view::operator[] // // Returns the ith element of an `string_view` using the array operator. // Note that this operator does not perform any bounds checking. @@ -348,7 +338,17 @@ class string_view { // // Copies the contents of the `string_view` at offset `pos` and length `n` // into `buf`. - size_type copy(char* buf, size_type n, size_type pos = 0) const; + size_type copy(char* buf, size_type n, size_type pos = 0) const { + if (ABSL_PREDICT_FALSE(pos > length_)) { + base_internal::ThrowStdOutOfRange("absl::string_view::copy"); + } + size_type rlen = (std::min)(length_ - pos, n); + if (rlen > 0) { + const char* start = ptr_ + pos; + std::copy(start, start + rlen, buf); + } + return rlen; + } // string_view::substr() // @@ -358,7 +358,7 @@ class string_view { string_view substr(size_type pos, size_type n = npos) const { if (ABSL_PREDICT_FALSE(pos > length_)) base_internal::ThrowStdOutOfRange("absl::string_view::substr"); - n = std::min(n, length_ - pos); + n = (std::min)(n, length_ - pos); return string_view(ptr_ + pos, n); } @@ -371,7 +371,7 @@ class string_view { // on the respective sizes of the two `string_view`s to determine which is // smaller, equal, or greater. int compare(string_view x) const noexcept { - auto min_length = std::min(length_, x.length_); + auto min_length = (std::min)(length_, x.length_); if (min_length > 0) { int r = memcmp(ptr_, x.ptr_, min_length); if (r < 0) return -1; @@ -499,6 +499,24 @@ class string_view { return ABSL_ASSERT(len <= kMaxSize), len; } + static constexpr size_type StrlenInternal(const char* str) { +#if defined(_MSC_VER) && _MSC_VER >= 1910 && !defined(__clang__) + // MSVC 2017+ can evaluate this at compile-time. + const char* begin = str; + while (*str != '\0') ++str; + return str - begin; +#elif ABSL_HAVE_BUILTIN(__builtin_strlen) || \ + (defined(__GNUC__) && !defined(__clang__)) + // GCC has __builtin_strlen according to + // https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Other-Builtins.html, but + // ABSL_HAVE_BUILTIN doesn't detect that, so we use the extra checks above. + // __builtin_strlen is constexpr. + return __builtin_strlen(str); +#else + return str ? strlen(str) : 0; +#endif + } + const char* ptr_; size_type length_; }; @@ -511,6 +529,7 @@ inline bool operator==(string_view x, string_view y) noexcept { if (len != y.size()) { return false; } + return x.data() == y.data() || len <= 0 || memcmp(x.data(), y.data(), len) == 0; } @@ -520,7 +539,7 @@ inline bool operator!=(string_view x, string_view y) noexcept { } inline bool operator<(string_view x, string_view y) noexcept { - auto min_size = std::min(x.size(), y.size()); + auto min_size = (std::min)(x.size(), y.size()); const int r = min_size == 0 ? 0 : memcmp(x.data(), y.data(), min_size); return (r < 0) || (r == 0 && x.size() < y.size()); } @@ -538,13 +557,13 @@ inline bool operator>=(string_view x, string_view y) noexcept { // IO Insertion Operator std::ostream& operator<<(std::ostream& o, string_view piece); -} // inline namespace lts_2018_12_18 +} // inline namespace lts_2019_08_08 } // namespace absl #endif // ABSL_HAVE_STD_STRING_VIEW namespace absl { -inline namespace lts_2018_12_18 { +inline namespace lts_2019_08_08 { // ClippedSubstr() // @@ -552,7 +571,7 @@ inline namespace lts_2018_12_18 { // Provided because std::string_view::substr throws if `pos > size()` inline string_view ClippedSubstr(string_view s, size_t pos, size_t n = string_view::npos) { - pos = std::min(pos, static_cast<size_t>(s.size())); + pos = (std::min)(pos, static_cast<size_t>(s.size())); return s.substr(pos, n); } @@ -565,7 +584,7 @@ inline string_view NullSafeStringView(const char* p) { return p ? string_view(p) : string_view(); } -} // inline namespace lts_2018_12_18 +} // inline namespace lts_2019_08_08 } // namespace absl #endif // ABSL_STRINGS_STRING_VIEW_H_ |