diff options
author | Abseil Team <absl-team@google.com> | 2020-12-07 09:56:14 -0800 |
---|---|---|
committer | Andy Getz <durandal@google.com> | 2020-12-07 16:03:42 -0500 |
commit | fbdff6f3ae0ba977a69f172e85ecaede535e70f6 (patch) | |
tree | 33b150f23f618fa9709819e37cc3e029800572f7 /absl/strings | |
parent | acf3390ca28edf1438fa896602ffede2a7dff103 (diff) | |
download | abseil-fbdff6f3ae0ba977a69f172e85ecaede535e70f6.tar.gz abseil-fbdff6f3ae0ba977a69f172e85ecaede535e70f6.tar.bz2 abseil-fbdff6f3ae0ba977a69f172e85ecaede535e70f6.zip |
Export of internal Abseil changes
--
ff793052bd01e1e4fcf639f94d7c30c4855a9372 by Evan Brown <ezb@google.com>:
Roll forward of btree_iterator refactoring.
PiperOrigin-RevId: 346116047
--
17984679f16e3e2139b0f14fa76f4a6ca16a3ef9 by Chris Kennelly <ckennelly@google.com>:
Extend absl::StrContains to accept single character needles.
Single characters are more efficient to search for. Extending this API allows
the abseil-string-find-str-contains Clang Tidy to include this pattern.
The C++ committee has adopted http://wg21.link/P1679 for inclusion in C++23.
PiperOrigin-RevId: 346095060
--
ef20b31c501b1dcaa25e244fd8f8aa43dec09bd6 by Jorg Brown <jorg@google.com>:
Internal change for cord ring
PiperOrigin-RevId: 346087545
--
b70f2c1cb77fc9e733a126e790967d45c5fd1dc7 by Derek Mauro <dmauro@google.com>:
Release layout_benchmark
PiperOrigin-RevId: 345968909
--
3a0eda337ee43622f92cfe14c2aa06f72dc71ee5 by Derek Mauro <dmauro@google.com>:
Release raw_hash_set_probe_benchmark
PiperOrigin-RevId: 345965969
--
abffdb4bb241a2264cb4e73a6262b660bb10447d by Derek Mauro <dmauro@google.com>:
Internal change
PiperOrigin-RevId: 345733599
--
7c9e24a71188df945be17fe98f700bdb51f81b16 by Derek Mauro <dmauro@google.com>:
Release hash_benchmark
PiperOrigin-RevId: 345721635
--
d68f33f17f9a8cd3f6da8eee3870bdb46402cdc8 by Derek Mauro <dmauro@google.com>:
Release raw_hash_set_benchmark
PiperOrigin-RevId: 345708384
--
6e6c547d4d1327b226c0ffe8ff34d0aa103ce24b by Abseil Team <absl-team@google.com>:
Updates the implementation of InlinedVector to accurately express the value-initialization semantics of the default constructor
PiperOrigin-RevId: 345548260
--
1532424deda97d468444c217cc0fa4614099c7c1 by Evan Brown <ezb@google.com>:
Rollback btree_iterator refactoring.
PiperOrigin-RevId: 345543900
GitOrigin-RevId: ff793052bd01e1e4fcf639f94d7c30c4855a9372
Change-Id: I719831981fd056de41939f9addfee3d85e3b49b2
Diffstat (limited to 'absl/strings')
-rw-r--r-- | absl/strings/cord.cc | 22 | ||||
-rw-r--r-- | absl/strings/internal/cord_internal.h | 2 | ||||
-rw-r--r-- | absl/strings/internal/cord_rep_flat.h | 14 | ||||
-rw-r--r-- | absl/strings/match.h | 4 | ||||
-rw-r--r-- | absl/strings/match_test.cc | 17 |
5 files changed, 45 insertions, 14 deletions
diff --git a/absl/strings/cord.cc b/absl/strings/cord.cc index 7c4f6c92..badeb610 100644 --- a/absl/strings/cord.cc +++ b/absl/strings/cord.cc @@ -58,7 +58,6 @@ using ::absl::cord_internal::kMaxFlatLength; using ::absl::cord_internal::CONCAT; using ::absl::cord_internal::EXTERNAL; using ::absl::cord_internal::FLAT; -using ::absl::cord_internal::MAX_FLAT_TAG; using ::absl::cord_internal::SUBSTRING; namespace cord_internal { @@ -93,6 +92,15 @@ inline const CordRepExternal* CordRep::external() const { return static_cast<const CordRepExternal*>(this); } +inline CordRepFlat* CordRep::flat() { + assert(tag >= FLAT); + return static_cast<CordRepFlat*>(this); +} +inline const CordRepFlat* CordRep::flat() const { + assert(tag >= FLAT); + return static_cast<const CordRepFlat*>(this); +} + } // namespace cord_internal // Prefer copying blocks of at most this size, otherwise reference count. @@ -457,7 +465,7 @@ static inline bool PrepareAppendRegion(CordRep* root, char** region, } const size_t in_use = dst->length; - const size_t capacity = static_cast<CordRepFlat*>(dst)->Capacity(); + const size_t capacity = dst->flat()->Capacity(); if (in_use == capacity) { *region = nullptr; *size = 0; @@ -539,7 +547,7 @@ void Cord::InlineRep::GetAppendRegion(char** region, size_t* size) { // will return true. static bool RepMemoryUsageLeaf(const CordRep* rep, size_t* total_mem_usage) { if (rep->tag >= FLAT) { - *total_mem_usage += static_cast<const CordRepFlat*>(rep)->AllocatedSize(); + *total_mem_usage += rep->flat()->AllocatedSize(); return true; } if (rep->tag == EXTERNAL) { @@ -637,7 +645,7 @@ Cord& Cord::operator=(absl::string_view src) { return *this; } if (tree != nullptr && tree->tag >= FLAT && - static_cast<CordRepFlat*>(tree)->Capacity() >= length && + tree->flat()->Capacity() >= length && tree->refcount.IsOne()) { // Copy in place if the existing FLAT node is reusable. memmove(tree->data, data, length); @@ -694,7 +702,7 @@ void Cord::InlineRep::AppendArray(const char* src_data, size_t src_size) { const size_t size2 = inline_length + src_size / 10; root = CordRepFlat::New(std::max<size_t>(size1, size2)); appended = std::min( - src_size, static_cast<CordRepFlat*>(root)->Capacity() - inline_length); + src_size, root->flat()->Capacity() - inline_length); memcpy(root->data, data_.as_chars, inline_length); memcpy(root->data + inline_length, src_data, appended); root->length = inline_length + appended; @@ -1785,7 +1793,7 @@ static void DumpNode(CordRep* rep, bool include_data, std::ostream* os) { *os << absl::CEscape(std::string(rep->external()->base, rep->length)); *os << "]\n"; } else { - *os << "FLAT cap=" << static_cast<CordRepFlat*>(rep)->Capacity() + *os << "FLAT cap=" << rep->flat()->Capacity() << " ["; if (include_data) *os << absl::CEscape(std::string(rep->data, rep->length)); @@ -1835,7 +1843,7 @@ static bool VerifyNode(CordRep* root, CordRep* start_node, } } else if (node->tag >= FLAT) { ABSL_INTERNAL_CHECK( - node->length <= static_cast<CordRepFlat*>(node)->Capacity(), + node->length <= node->flat()->Capacity(), ReportError(root, node)); } else if (node->tag == EXTERNAL) { ABSL_INTERNAL_CHECK(node->external()->base != nullptr, diff --git a/absl/strings/internal/cord_internal.h b/absl/strings/internal/cord_internal.h index ec2c767b..6fb75c4f 100644 --- a/absl/strings/internal/cord_internal.h +++ b/absl/strings/internal/cord_internal.h @@ -149,6 +149,8 @@ struct CordRep { inline const CordRepSubstring* substring() const; inline CordRepExternal* external(); inline const CordRepExternal* external() const; + inline CordRepFlat* flat(); + inline const CordRepFlat* flat() const; }; struct CordRepConcat : public CordRep { diff --git a/absl/strings/internal/cord_rep_flat.h b/absl/strings/internal/cord_rep_flat.h index 3e2cd33c..80391a5e 100644 --- a/absl/strings/internal/cord_rep_flat.h +++ b/absl/strings/internal/cord_rep_flat.h @@ -43,7 +43,7 @@ static constexpr size_t kMaxFlatSize = 4096; static constexpr size_t kMaxFlatLength = kMaxFlatSize - kFlatOverhead; static constexpr size_t kMinFlatLength = kMinFlatSize - kFlatOverhead; -static constexpr size_t AllocatedSizeToTagUnchecked(size_t size) { +constexpr size_t AllocatedSizeToTagUnchecked(size_t size) { return (size <= 1024) ? size / 8 : 128 + size / 32 - 1024 / 32; } @@ -51,12 +51,12 @@ static_assert(kMinFlatSize / 8 >= FLAT, ""); static_assert(AllocatedSizeToTagUnchecked(kMaxFlatSize) <= MAX_FLAT_TAG, ""); // Helper functions for rounded div, and rounding to exact sizes. -static size_t DivUp(size_t n, size_t m) { return (n + m - 1) / m; } -static size_t RoundUp(size_t n, size_t m) { return DivUp(n, m) * m; } +constexpr size_t DivUp(size_t n, size_t m) { return (n + m - 1) / m; } +constexpr size_t RoundUp(size_t n, size_t m) { return DivUp(n, m) * m; } // Returns the size to the nearest equal or larger value that can be // expressed exactly as a tag value. -static size_t RoundUpForTag(size_t size) { +inline size_t RoundUpForTag(size_t size) { return RoundUp(size, (size <= 1024) ? 8 : 32); } @@ -64,19 +64,19 @@ static size_t RoundUpForTag(size_t size) { // does not exactly match a 'tag expressible' size value. The result is // undefined if the size exceeds the maximum size that can be encoded in // a tag, i.e., if size is larger than TagToAllocatedSize(<max tag>). -static uint8_t AllocatedSizeToTag(size_t size) { +inline uint8_t AllocatedSizeToTag(size_t size) { const size_t tag = AllocatedSizeToTagUnchecked(size); assert(tag <= MAX_FLAT_TAG); return tag; } // Converts the provided tag to the corresponding allocated size -static constexpr size_t TagToAllocatedSize(uint8_t tag) { +constexpr size_t TagToAllocatedSize(uint8_t tag) { return (tag <= 128) ? (tag * 8) : (1024 + (tag - 128) * 32); } // Converts the provided tag to the corresponding available data length -static constexpr size_t TagToLength(uint8_t tag) { +constexpr size_t TagToLength(uint8_t tag) { return TagToAllocatedSize(tag) - kFlatOverhead; } diff --git a/absl/strings/match.h b/absl/strings/match.h index 6c822c26..038cbb3f 100644 --- a/absl/strings/match.h +++ b/absl/strings/match.h @@ -48,6 +48,10 @@ inline bool StrContains(absl::string_view haystack, return haystack.find(needle, 0) != haystack.npos; } +inline bool StrContains(absl::string_view haystack, char needle) noexcept { + return haystack.find(needle) != haystack.npos; +} + // StartsWith() // // Returns whether a given string `text` begins with `prefix`. diff --git a/absl/strings/match_test.cc b/absl/strings/match_test.cc index 4c313dda..5841bc1b 100644 --- a/absl/strings/match_test.cc +++ b/absl/strings/match_test.cc @@ -66,6 +66,23 @@ TEST(MatchTest, Contains) { EXPECT_FALSE(absl::StrContains("", "a")); } +TEST(MatchTest, ContainsChar) { + absl::string_view a("abcdefg"); + absl::string_view b("abcd"); + EXPECT_TRUE(absl::StrContains(a, 'a')); + EXPECT_TRUE(absl::StrContains(a, 'b')); + EXPECT_TRUE(absl::StrContains(a, 'e')); + EXPECT_FALSE(absl::StrContains(a, 'h')); + + EXPECT_TRUE(absl::StrContains(b, 'a')); + EXPECT_TRUE(absl::StrContains(b, 'b')); + EXPECT_FALSE(absl::StrContains(b, 'e')); + EXPECT_FALSE(absl::StrContains(b, 'h')); + + EXPECT_FALSE(absl::StrContains("", 'a')); + EXPECT_FALSE(absl::StrContains("", 'a')); +} + TEST(MatchTest, ContainsNull) { const std::string s = "foo"; const char* cs = "foo"; |