diff options
Diffstat (limited to 'Firestore/third_party/abseil-cpp/absl/strings')
10 files changed, 295 insertions, 96 deletions
diff --git a/Firestore/third_party/abseil-cpp/absl/strings/escaping_test.cc b/Firestore/third_party/abseil-cpp/absl/strings/escaping_test.cc index e87f101..982989b 100644 --- a/Firestore/third_party/abseil-cpp/absl/strings/escaping_test.cc +++ b/Firestore/third_party/abseil-cpp/absl/strings/escaping_test.cc @@ -22,6 +22,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "absl/container/fixed_array.h" #include "absl/strings/str_cat.h" #include "absl/strings/internal/escaping_test_common.inc" diff --git a/Firestore/third_party/abseil-cpp/absl/strings/internal/stl_type_traits.h b/Firestore/third_party/abseil-cpp/absl/strings/internal/stl_type_traits.h index 8c3d877..04c4a53 100644 --- a/Firestore/third_party/abseil-cpp/absl/strings/internal/stl_type_traits.h +++ b/Firestore/third_party/abseil-cpp/absl/strings/internal/stl_type_traits.h @@ -79,31 +79,48 @@ struct IsSTLContainer template <typename C, template <typename...> class T, typename = void> struct IsBaseOfSpecializationImpl : std::false_type {}; -// IsBaseOfSpecializationImpl must have three partial specializations, -// because we must only compare templates that take the same number of -// arguments. Otherwise, for example, std::vector can be compared with std::map, -// and fail to compile because of too few or too many template arguments. -// -// We must also SFINAE on the existence of an allocator_type. Otherwise, we may -// try to compare, for example, a std::pair<std::string, std::string> with a -// std::vector<std::string, std:std::string>. This would fail to compile, because -// of expected properties of the type passed in as the allocator. -template <template <typename, typename> class U, - template <typename, typename> class T, typename... Args> +// IsBaseOfSpecializationImpl needs multiple partial specializations to SFINAE +// on the existence of container dependent types and plug them into the STL +// template. +template <typename C, template <typename, typename> class T> +struct IsBaseOfSpecializationImpl< + C, T, absl::void_t<typename C::value_type, typename C::allocator_type>> + : std::is_base_of<C, + T<typename C::value_type, typename C::allocator_type>> {}; +template <typename C, template <typename, typename, typename> class T> struct IsBaseOfSpecializationImpl< - U<Args...>, T, absl::void_t<typename U<Args...>::allocator_type>> - : std::is_base_of<U<Args...>, T<Args...>> {}; -template <template <typename, typename, typename> class U, - template <typename, typename, typename> class T, typename... Args> + C, T, + absl::void_t<typename C::key_type, typename C::key_compare, + typename C::allocator_type>> + : std::is_base_of<C, T<typename C::key_type, typename C::key_compare, + typename C::allocator_type>> {}; +template <typename C, template <typename, typename, typename, typename> class T> +struct IsBaseOfSpecializationImpl< + C, T, + absl::void_t<typename C::key_type, typename C::mapped_type, + typename C::key_compare, typename C::allocator_type>> + : std::is_base_of<C, + T<typename C::key_type, typename C::mapped_type, + typename C::key_compare, typename C::allocator_type>> { +}; +template <typename C, template <typename, typename, typename, typename> class T> struct IsBaseOfSpecializationImpl< - U<Args...>, T, absl::void_t<typename U<Args...>::allocator_type>> - : std::is_base_of<U<Args...>, T<Args...>> {}; -template <template <typename, typename, typename, typename> class U, - template <typename, typename, typename, typename> class T, - typename... Args> + C, T, + absl::void_t<typename C::key_type, typename C::hasher, + typename C::key_equal, typename C::allocator_type>> + : std::is_base_of<C, T<typename C::key_type, typename C::hasher, + typename C::key_equal, typename C::allocator_type>> { +}; +template <typename C, + template <typename, typename, typename, typename, typename> class T> struct IsBaseOfSpecializationImpl< - U<Args...>, T, absl::void_t<typename U<Args...>::allocator_type>> - : std::is_base_of<U<Args...>, T<Args...>> {}; + C, T, + absl::void_t<typename C::key_type, typename C::mapped_type, + typename C::hasher, typename C::key_equal, + typename C::allocator_type>> + : std::is_base_of<C, T<typename C::key_type, typename C::mapped_type, + typename C::hasher, typename C::key_equal, + typename C::allocator_type>> {}; template <typename C, template <typename...> class T> using IsBaseOfSpecialization = IsBaseOfSpecializationImpl<absl::decay_t<C>, T>; @@ -140,31 +157,47 @@ struct IsBaseOfSTLContainer template <typename C, template <typename...> class T, typename = void> struct IsConvertibleToSpecializationImpl : std::false_type {}; -// IsConvertibleToSpecializationImpl must have three partial specializations, -// because we must only compare templates that take the same number of -// arguments. Otherwise, for example, std::vector can be compared with std::map, -// and fail to compile because of too few or too many template arguments. -// -// We must also SFINAE on the existence of an allocator_type. Otherwise, we may -// try to compare, for example, a std::pair<std::string, std::string> with a -// std::vector<std::string, std:std::string>. This would fail to compile, because -// of expected properties of the type passed in as the allocator. -template <template <typename, typename> class U, - template <typename, typename> class T, typename... Args> +// IsConvertibleToSpecializationImpl needs multiple partial specializations to +// SFINAE on the existence of container dependent types and plug them into the +// STL template. +template <typename C, template <typename, typename> class T> +struct IsConvertibleToSpecializationImpl< + C, T, absl::void_t<typename C::value_type, typename C::allocator_type>> + : std::is_convertible< + C, T<typename C::value_type, typename C::allocator_type>> {}; +template <typename C, template <typename, typename, typename> class T> +struct IsConvertibleToSpecializationImpl< + C, T, + absl::void_t<typename C::key_type, typename C::key_compare, + typename C::allocator_type>> + : std::is_convertible<C, T<typename C::key_type, typename C::key_compare, + typename C::allocator_type>> {}; +template <typename C, template <typename, typename, typename, typename> class T> struct IsConvertibleToSpecializationImpl< - U<Args...>, T, absl::void_t<typename U<Args...>::allocator_type>> - : std::is_convertible<U<Args...>, T<Args...>> {}; -template <template <typename, typename, typename> class U, - template <typename, typename, typename> class T, typename... Args> + C, T, + absl::void_t<typename C::key_type, typename C::mapped_type, + typename C::key_compare, typename C::allocator_type>> + : std::is_convertible< + C, T<typename C::key_type, typename C::mapped_type, + typename C::key_compare, typename C::allocator_type>> {}; +template <typename C, template <typename, typename, typename, typename> class T> struct IsConvertibleToSpecializationImpl< - U<Args...>, T, absl::void_t<typename U<Args...>::allocator_type>> - : std::is_convertible<U<Args...>, T<Args...>> {}; -template <template <typename, typename, typename, typename> class U, - template <typename, typename, typename, typename> class T, - typename... Args> + C, T, + absl::void_t<typename C::key_type, typename C::hasher, + typename C::key_equal, typename C::allocator_type>> + : std::is_convertible< + C, T<typename C::key_type, typename C::hasher, typename C::key_equal, + typename C::allocator_type>> {}; +template <typename C, + template <typename, typename, typename, typename, typename> class T> struct IsConvertibleToSpecializationImpl< - U<Args...>, T, absl::void_t<typename U<Args...>::allocator_type>> - : std::is_convertible<U<Args...>, T<Args...>> {}; + C, T, + absl::void_t<typename C::key_type, typename C::mapped_type, + typename C::hasher, typename C::key_equal, + typename C::allocator_type>> + : std::is_convertible<C, T<typename C::key_type, typename C::mapped_type, + typename C::hasher, typename C::key_equal, + typename C::allocator_type>> {}; template <typename C, template <typename...> class T> using IsConvertibleToSpecialization = IsConvertibleToSpecializationImpl<absl::decay_t<C>, T>; diff --git a/Firestore/third_party/abseil-cpp/absl/strings/internal/utf8.h b/Firestore/third_party/abseil-cpp/absl/strings/internal/utf8.h index 5bd82e8..d2c3c0b 100644 --- a/Firestore/third_party/abseil-cpp/absl/strings/internal/utf8.h +++ b/Firestore/third_party/abseil-cpp/absl/strings/internal/utf8.h @@ -14,10 +14,6 @@ // // UTF8 utilities, implemented to reduce dependencies. // -// If you need Unicode specific processing (for example being aware of -// Unicode character boundaries, or knowledge of Unicode casing rules, -// or various forms of equivalence and normalization), take a look at -// files in i18n/utf8. #ifndef ABSL_STRINGS_INTERNAL_UTF8_H_ #define ABSL_STRINGS_INTERNAL_UTF8_H_ diff --git a/Firestore/third_party/abseil-cpp/absl/strings/str_cat.cc b/Firestore/third_party/abseil-cpp/absl/strings/str_cat.cc index 99eb289..3fe8c95 100644 --- a/Firestore/third_party/abseil-cpp/absl/strings/str_cat.cc +++ b/Firestore/third_party/abseil-cpp/absl/strings/str_cat.cc @@ -45,6 +45,37 @@ AlphaNum::AlphaNum(Hex hex) { piece_ = absl::string_view(beg, end - beg); } +AlphaNum::AlphaNum(Dec dec) { + assert(dec.width <= numbers_internal::kFastToBufferSize); + char* const end = &digits_[numbers_internal::kFastToBufferSize]; + char* const minfill = end - dec.width; + char* writer = end; + uint64_t value = dec.value; + bool neg = dec.neg; + while (value > 9) { + *--writer = '0' + (value % 10); + value /= 10; + } + *--writer = '0' + value; + if (neg) *--writer = '-'; + + ptrdiff_t fillers = writer - minfill; + if (fillers > 0) { + // Tricky: if the fill character is ' ', then it's <fill><+/-><digits> + // But...: if the fill character is '0', then it's <+/-><fill><digits> + bool add_sign_again = false; + if (neg && dec.fill == '0') { // If filling with '0', + ++writer; // ignore the sign we just added + add_sign_again = true; // and re-add the sign later. + } + writer -= fillers; + std::fill_n(writer, fillers, dec.fill); + if (add_sign_again) *--writer = '-'; + } + + piece_ = absl::string_view(writer, end - writer); +} + // ---------------------------------------------------------------------- // StrCat() // This merges the given strings or integers, with no delimiter. This diff --git a/Firestore/third_party/abseil-cpp/absl/strings/str_cat.h b/Firestore/third_party/abseil-cpp/absl/strings/str_cat.h index 1cf7b11..e38369c 100644 --- a/Firestore/third_party/abseil-cpp/absl/strings/str_cat.h +++ b/Firestore/third_party/abseil-cpp/absl/strings/str_cat.h @@ -76,10 +76,10 @@ struct AlphaNumBuffer { } // namespace strings_internal -// Enum that specifies the number of significant digits to return in a `Hex` -// conversion and fill character to use. A `kZeroPad2` value, for example, would -// produce hexadecimal strings such as "0A","0F" and 'kSpacePad5' value would -// produce hexadecimal strings such as " A"," F". +// Enum that specifies the number of significant digits to return in a `Hex` or +// `Dec` conversion and fill character to use. A `kZeroPad2` value, for example, +// would produce hexadecimal strings such as "0A","0F" and a 'kSpacePad5' value +// would produce hexadecimal strings such as " A"," F". enum PadSpec { kNoPad = 1, kZeroPad2, @@ -127,21 +127,32 @@ struct Hex { char fill; template <typename Int> - explicit Hex(Int v, PadSpec spec = absl::kNoPad, - typename std::enable_if<sizeof(Int) == 1>::type* = nullptr) + explicit Hex( + Int v, PadSpec spec = absl::kNoPad, + typename std::enable_if<sizeof(Int) == 1 && + !std::is_pointer<Int>::value>::type* = nullptr) : Hex(spec, static_cast<uint8_t>(v)) {} template <typename Int> - explicit Hex(Int v, PadSpec spec = absl::kNoPad, - typename std::enable_if<sizeof(Int) == 2>::type* = nullptr) + explicit Hex( + Int v, PadSpec spec = absl::kNoPad, + typename std::enable_if<sizeof(Int) == 2 && + !std::is_pointer<Int>::value>::type* = nullptr) : Hex(spec, static_cast<uint16_t>(v)) {} template <typename Int> - explicit Hex(Int v, PadSpec spec = absl::kNoPad, - typename std::enable_if<sizeof(Int) == 4>::type* = nullptr) + explicit Hex( + Int v, PadSpec spec = absl::kNoPad, + typename std::enable_if<sizeof(Int) == 4 && + !std::is_pointer<Int>::value>::type* = nullptr) : Hex(spec, static_cast<uint32_t>(v)) {} template <typename Int> - explicit Hex(Int v, PadSpec spec = absl::kNoPad, - typename std::enable_if<sizeof(Int) == 8>::type* = nullptr) + explicit Hex( + Int v, PadSpec spec = absl::kNoPad, + typename std::enable_if<sizeof(Int) == 8 && + !std::is_pointer<Int>::value>::type* = nullptr) : Hex(spec, static_cast<uint64_t>(v)) {} + template <typename Pointee> + explicit Hex(Pointee* v, PadSpec spec = absl::kNoPad) + : Hex(spec, reinterpret_cast<uintptr_t>(v)) {} private: Hex(PadSpec spec, uint64_t v) @@ -154,6 +165,32 @@ struct Hex { }; // ----------------------------------------------------------------------------- +// Dec +// ----------------------------------------------------------------------------- +// +// `Dec` stores a set of decimal std::string conversion parameters for use +// within `AlphaNum` std::string conversions. Dec is slower than the default +// integer conversion, so use it only if you need padding. +struct Dec { + uint64_t value; + uint8_t width; + char fill; + bool neg; + + template <typename Int> + explicit Dec(Int v, PadSpec spec = absl::kNoPad, + typename std::enable_if<(sizeof(Int) <= 8)>::type* = nullptr) + : value(v >= 0 ? static_cast<uint64_t>(v) + : uint64_t{0} - static_cast<uint64_t>(v)), + width(spec == absl::kNoPad + ? 1 + : spec >= absl::kSpacePad2 ? spec - absl::kSpacePad2 + 2 + : spec - absl::kZeroPad2 + 2), + fill(spec >= absl::kSpacePad2 ? ' ' : '0'), + neg(v < 0) {} +}; + +// ----------------------------------------------------------------------------- // AlphaNum // ----------------------------------------------------------------------------- // @@ -191,6 +228,7 @@ class AlphaNum { : piece_(digits_, numbers_internal::SixDigitsToBuffer(f, digits_)) {} AlphaNum(Hex hex); // NOLINT(runtime/explicit) + AlphaNum(Dec dec); // NOLINT(runtime/explicit) template <size_t size> AlphaNum( // NOLINT(runtime/explicit) diff --git a/Firestore/third_party/abseil-cpp/absl/strings/str_cat_test.cc b/Firestore/third_party/abseil-cpp/absl/strings/str_cat_test.cc index dd063b0..58ab743 100644 --- a/Firestore/third_party/abseil-cpp/absl/strings/str_cat_test.cc +++ b/Firestore/third_party/abseil-cpp/absl/strings/str_cat_test.cc @@ -234,7 +234,7 @@ TEST(StrCat, CustomAllocator) { TEST(StrCat, MaxArgs) { std::string result; - // Test 10 up to 26 arguments, the current maximum + // Test 10 up to 26 arguments, the old maximum result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a"); EXPECT_EQ(result, "123456789a"); result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b"); @@ -431,28 +431,97 @@ void CheckHex(IntType v, const char* nopad_format, const char* zeropad_format, } } -void CheckHex64(uint64_t v) { - unsigned long long llv = v; // NOLINT(runtime/int) +template <typename IntType> +void CheckDec(IntType v, const char* nopad_format, const char* zeropad_format, + const char* spacepad_format) { + char expected[256]; + + std::string actual = absl::StrCat(absl::Dec(v, absl::kNoPad)); + snprintf(expected, sizeof(expected), nopad_format, v); + EXPECT_EQ(expected, actual) << " decimal value " << v; + + for (int spec = absl::kZeroPad2; spec <= absl::kZeroPad16; ++spec) { + std::string actual = + absl::StrCat(absl::Dec(v, static_cast<absl::PadSpec>(spec))); + snprintf(expected, sizeof(expected), zeropad_format, + spec - absl::kZeroPad2 + 2, v); + EXPECT_EQ(expected, actual) + << " decimal value " << v << " format '" << zeropad_format + << "' digits " << (spec - absl::kZeroPad2 + 2); + } - CheckHex(llv, "%llx", "%0*llx", "%*llx"); + for (int spec = absl::kSpacePad2; spec <= absl::kSpacePad16; ++spec) { + std::string actual = + absl::StrCat(absl::Dec(v, static_cast<absl::PadSpec>(spec))); + snprintf(expected, sizeof(expected), spacepad_format, + spec - absl::kSpacePad2 + 2, v); + EXPECT_EQ(expected, actual) + << " decimal value " << v << " format '" << spacepad_format + << "' digits " << (spec - absl::kSpacePad2 + 2); + } +} + +void CheckHexDec64(uint64_t v) { + unsigned long long ullv = v; // NOLINT(runtime/int) + + CheckHex(ullv, "%llx", "%0*llx", "%*llx"); + CheckDec(ullv, "%llu", "%0*llu", "%*llu"); + + long long llv = static_cast<long long>(ullv); // NOLINT(runtime/int) + CheckDec(llv, "%lld", "%0*lld", "%*lld"); + + if (sizeof(v) == sizeof(&v)) { + auto uintptr = static_cast<uintptr_t>(v); + void* ptr = reinterpret_cast<void*>(uintptr); + CheckHex(ptr, "%llx", "%0*llx", "%*llx"); + } +} + +void CheckHexDec32(uint32_t uv) { + CheckHex(uv, "%x", "%0*x", "%*x"); + CheckDec(uv, "%u", "%0*u", "%*u"); + int32_t v = static_cast<int32_t>(uv); + CheckDec(v, "%d", "%0*d", "%*d"); + + if (sizeof(v) == sizeof(&v)) { + auto uintptr = static_cast<uintptr_t>(v); + void* ptr = reinterpret_cast<void*>(uintptr); + CheckHex(ptr, "%x", "%0*x", "%*x"); + } } -template <typename Int32Type> -void CheckHex32(Int32Type v) { - CheckHex(v, "%x", "%0*x", "%*x"); +void CheckAll(uint64_t v) { + CheckHexDec64(v); + CheckHexDec32(static_cast<uint32_t>(v)); } void TestFastPrints() { - // Test min int to make sure that works + // Test all small ints; there aren't many and they're common. for (int i = 0; i < 10000; i++) { - CheckHex64(i); - CheckHex32(static_cast<uint32_t>(i)); - CheckHex32(i); - CheckHex32(-i); + CheckAll(i); } - CheckHex64(uint64_t{0x123456789abcdef0}); - CheckHex32(0x12345678U); + CheckAll(std::numeric_limits<uint64_t>::max()); + CheckAll(std::numeric_limits<uint64_t>::max() - 1); + CheckAll(std::numeric_limits<int64_t>::min()); + CheckAll(std::numeric_limits<int64_t>::min() + 1); + CheckAll(std::numeric_limits<uint32_t>::max()); + CheckAll(std::numeric_limits<uint32_t>::max() - 1); + CheckAll(std::numeric_limits<int32_t>::min()); + CheckAll(std::numeric_limits<int32_t>::min() + 1); + CheckAll(999999999); // fits in 32 bits + CheckAll(1000000000); // fits in 32 bits + CheckAll(9999999999); // doesn't fit in 32 bits + CheckAll(10000000000); // doesn't fit in 32 bits + CheckAll(999999999999999999); // fits in signed 64-bit + CheckAll(9999999999999999999u); // fits in unsigned 64-bit, but not signed. + CheckAll(1000000000000000000); // fits in signed 64-bit + CheckAll(10000000000000000000u); // fits in unsigned 64-bit, but not signed. + + CheckAll(999999999876543210); // check all decimal digits, signed + CheckAll(9999999999876543210u); // check all decimal digits, unsigned. + CheckAll(0x123456789abcdef0); // check all hex digits + CheckAll(0x12345678); int8_t minus_one_8bit = -1; EXPECT_EQ("ff", absl::StrCat(absl::Hex(minus_one_8bit))); diff --git a/Firestore/third_party/abseil-cpp/absl/strings/str_split.h b/Firestore/third_party/abseil-cpp/absl/strings/str_split.h index 5b3d6a8..1f089b9 100644 --- a/Firestore/third_party/abseil-cpp/absl/strings/str_split.h +++ b/Firestore/third_party/abseil-cpp/absl/strings/str_split.h @@ -208,7 +208,7 @@ class ByAnyChar { // using absl::ByLength; // std::vector<std::string> v = absl::StrSplit("12345", ByLength(2)); // -// // v[0] == "12", v[1] == "35", v[2] == "5" +// // v[0] == "12", v[1] == "34", v[2] == "5" class ByLength { public: explicit ByLength(ptrdiff_t length); @@ -402,7 +402,7 @@ struct SkipWhitespace { // // std::vector<std::string> v = absl::StrSplit(" a , ,,b,", // ',', SkipWhitespace()); -// // v[0] == "a", v[1] == "b" +// // v[0] == " a ", v[1] == "b" // // See above for more information on predicates. // diff --git a/Firestore/third_party/abseil-cpp/absl/strings/str_split_test.cc b/Firestore/third_party/abseil-cpp/absl/strings/str_split_test.cc index 500f3cb..c172a76 100644 --- a/Firestore/third_party/abseil-cpp/absl/strings/str_split_test.cc +++ b/Firestore/third_party/abseil-cpp/absl/strings/str_split_test.cc @@ -154,8 +154,8 @@ TEST(Split, APIExamples) { { // Uses the SkipWhitespace predicate. using absl::SkipWhitespace; - std::vector<std::string> v = absl::StrSplit("a, ,,b,", ',', SkipWhitespace()); - EXPECT_THAT(v, ElementsAre("a", "b")); + std::vector<std::string> v = absl::StrSplit(" a , ,,b,", ',', SkipWhitespace()); + EXPECT_THAT(v, ElementsAre(" a ", "b")); } { @@ -241,10 +241,10 @@ TEST(SplitIterator, Basics) { EXPECT_NE(it, end); EXPECT_EQ("a", *it); // tests dereference - ++it; // tests preincrement + ++it; // tests preincrement EXPECT_NE(it, end); EXPECT_EQ("b", std::string(it->data(), it->size())); // tests dereference as ptr - it++; // tests postincrement + it++; // tests postincrement EXPECT_EQ(it, end); } @@ -265,10 +265,10 @@ TEST(SplitIterator, Predicate) { EXPECT_NE(it, end); EXPECT_EQ("a", *it); // tests dereference - ++it; // tests preincrement -- "b" should be skipped here. + ++it; // tests preincrement -- "b" should be skipped here. EXPECT_NE(it, end); EXPECT_EQ("c", std::string(it->data(), it->size())); // tests dereference as ptr - it++; // tests postincrement + it++; // tests postincrement EXPECT_EQ(it, end); } @@ -278,13 +278,13 @@ TEST(SplitIterator, EdgeCases) { std::string in; std::vector<std::string> expect; } specs[] = { - {"", {""}}, - {"foo", {"foo"}}, - {",", {"", ""}}, - {",foo", {"", "foo"}}, - {"foo,", {"foo", ""}}, - {",foo,", {"", "foo", ""}}, - {"foo,bar", {"foo", "bar"}}, + {"", {""}}, + {"foo", {"foo"}}, + {",", {"", ""}}, + {",foo", {"", "foo"}}, + {"foo,", {"foo", ""}}, + {",foo,", {"", "foo", ""}}, + {"foo,bar", {"foo", "bar"}}, }; for (const auto& spec : specs) { @@ -621,23 +621,28 @@ TEST(Split, StringDelimiter) { TEST(Split, UTF8) { // Tests splitting utf8 strings and utf8 delimiters. + std::string utf8_string = u8"\u03BA\u1F79\u03C3\u03BC\u03B5"; { // A utf8 input std::string with an ascii delimiter. - std::vector<absl::string_view> v = absl::StrSplit("a,κόσμε", ','); - EXPECT_THAT(v, ElementsAre("a", "κόσμε")); + std::string to_split = "a," + utf8_string; + std::vector<absl::string_view> v = absl::StrSplit(to_split, ','); + EXPECT_THAT(v, ElementsAre("a", utf8_string)); } { // A utf8 input std::string and a utf8 delimiter. - std::vector<absl::string_view> v = absl::StrSplit("a,κόσμε,b", ",κόσμε,"); + std::string to_split = "a," + utf8_string + ",b"; + std::string unicode_delimiter = "," + utf8_string + ","; + std::vector<absl::string_view> v = + absl::StrSplit(to_split, unicode_delimiter); EXPECT_THAT(v, ElementsAre("a", "b")); } { // A utf8 input std::string and ByAnyChar with ascii chars. std::vector<absl::string_view> v = - absl::StrSplit("Foo hällo th丞re", absl::ByAnyChar(" \t")); - EXPECT_THAT(v, ElementsAre("Foo", "hällo", "th丞re")); + absl::StrSplit(u8"Foo h\u00E4llo th\u4E1Ere", absl::ByAnyChar(" \t")); + EXPECT_THAT(v, ElementsAre("Foo", u8"h\u00E4llo", u8"th\u4E1Ere")); } } diff --git a/Firestore/third_party/abseil-cpp/absl/strings/strip_test.cc b/Firestore/third_party/abseil-cpp/absl/strings/strip_test.cc index ff0e7f1..205c160 100644 --- a/Firestore/third_party/abseil-cpp/absl/strings/strip_test.cc +++ b/Firestore/third_party/abseil-cpp/absl/strings/strip_test.cc @@ -178,4 +178,24 @@ TEST(String, StripLeadingAsciiWhitespace) { EXPECT_EQ(absl::string_view(), absl::StripLeadingAsciiWhitespace(orig)); } +TEST(Strip, StripAsciiWhitespace) { + std::string test2 = "\t \f\r\n\vfoo \t\f\r\v\n"; + absl::StripAsciiWhitespace(&test2); + EXPECT_EQ(test2, "foo"); + std::string test3 = "bar"; + absl::StripAsciiWhitespace(&test3); + EXPECT_EQ(test3, "bar"); + std::string test4 = "\t \f\r\n\vfoo"; + absl::StripAsciiWhitespace(&test4); + EXPECT_EQ(test4, "foo"); + std::string test5 = "foo \t\f\r\v\n"; + absl::StripAsciiWhitespace(&test5); + EXPECT_EQ(test5, "foo"); + absl::string_view test6("\t \f\r\n\vfoo \t\f\r\v\n"); + test6 = absl::StripAsciiWhitespace(test6); + EXPECT_EQ(test6, "foo"); + test6 = absl::StripAsciiWhitespace(test6); + EXPECT_EQ(test6, "foo"); // already stripped +} + } // namespace diff --git a/Firestore/third_party/abseil-cpp/absl/strings/substitute_test.cc b/Firestore/third_party/abseil-cpp/absl/strings/substitute_test.cc index a6d7d7b..7c9af6b 100644 --- a/Firestore/third_party/abseil-cpp/absl/strings/substitute_test.cc +++ b/Firestore/third_party/abseil-cpp/absl/strings/substitute_test.cc @@ -46,8 +46,14 @@ TEST(SubstituteTest, Substitute) { // Pointer. const int* int_p = reinterpret_cast<const int*>(0x12345); std::string str = absl::Substitute("$0", int_p); - EXPECT_EQ(absl::StrCat("0x", absl::Hex(reinterpret_cast<intptr_t>(int_p))), - str); + EXPECT_EQ(absl::StrCat("0x", absl::Hex(int_p)), str); + + // Volatile Pointer. + // Like C++ streamed I/O, such pointers implicitly become bool + volatile int vol = 237; + volatile int *volatile volptr = &vol; + str = absl::Substitute("$0", volptr); + EXPECT_EQ("true", str); // null is special. StrCat prints 0x0. Substitute prints NULL. const uint64_t* null_p = nullptr; |