summaryrefslogtreecommitdiff
path: root/absl/strings
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings')
-rw-r--r--absl/strings/BUILD.bazel41
-rw-r--r--absl/strings/escaping_benchmark.cc6
-rw-r--r--absl/strings/escaping_test.cc4
-rw-r--r--absl/strings/internal/char_map_benchmark.cc61
-rw-r--r--absl/strings/internal/escaping_test_common.h131
-rw-r--r--absl/strings/internal/escaping_test_common.inc113
-rw-r--r--absl/strings/internal/numbers_test_common.h178
-rw-r--r--absl/strings/internal/numbers_test_common.inc156
-rw-r--r--absl/strings/internal/ostringstream_benchmark.cc106
-rw-r--r--absl/strings/numbers.h4
-rw-r--r--absl/strings/numbers_test.cc21
-rw-r--r--absl/strings/str_cat_benchmark.cc2
-rw-r--r--absl/strings/str_join_benchmark.cc2
-rw-r--r--absl/strings/str_replace_benchmark.cc2
-rw-r--r--absl/strings/str_split_benchmark.cc2
-rw-r--r--absl/strings/string_view_benchmark.cc2
-rw-r--r--absl/strings/substitute.h5
17 files changed, 532 insertions, 304 deletions
diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel
index e6bb7ff5..d1c6878c 100644
--- a/absl/strings/BUILD.bazel
+++ b/absl/strings/BUILD.bazel
@@ -111,7 +111,7 @@ cc_test(
size = "small",
srcs = [
"escaping_test.cc",
- "internal/escaping_test_common.inc",
+ "internal/escaping_test_common.h",
],
copts = ABSL_TEST_COPTS,
visibility = ["//visibility:private"],
@@ -127,7 +127,7 @@ cc_test(
name = "escaping_benchmark",
srcs = [
"escaping_benchmark.cc",
- "internal/escaping_test_common.inc",
+ "internal/escaping_test_common.h",
],
copts = ABSL_TEST_COPTS,
tags = ["benchmark"],
@@ -135,7 +135,7 @@ cc_test(
deps = [
":strings",
"//absl/base",
- "@com_github_google_benchmark//:benchmark",
+ "@com_github_google_benchmark//:benchmark_main",
],
)
@@ -199,7 +199,7 @@ cc_test(
":strings",
"//absl/base",
"//absl/base:core_headers",
- "@com_github_google_benchmark//:benchmark",
+ "@com_github_google_benchmark//:benchmark_main",
],
)
@@ -240,7 +240,7 @@ cc_test(
deps = [
":strings",
"//absl/base",
- "@com_github_google_benchmark//:benchmark",
+ "@com_github_google_benchmark//:benchmark_main",
],
)
@@ -278,7 +278,7 @@ cc_test(
deps = [
":strings",
"//absl/base",
- "@com_github_google_benchmark//:benchmark",
+ "@com_github_google_benchmark//:benchmark_main",
],
)
@@ -295,6 +295,18 @@ cc_test(
)
cc_test(
+ name = "ostringstream_benchmark",
+ srcs = ["internal/ostringstream_benchmark.cc"],
+ copts = ABSL_TEST_COPTS,
+ tags = ["benchmark"],
+ visibility = ["//visibility:private"],
+ deps = [
+ ":internal",
+ "@com_github_google_benchmark//:benchmark_main",
+ ],
+)
+
+cc_test(
name = "resize_uninitialized_test",
size = "small",
srcs = [
@@ -333,7 +345,7 @@ cc_test(
deps = [
":strings",
"//absl/memory",
- "@com_github_google_benchmark//:benchmark",
+ "@com_github_google_benchmark//:benchmark_main",
],
)
@@ -358,7 +370,7 @@ cc_test(
visibility = ["//visibility:private"],
deps = [
":strings",
- "@com_github_google_benchmark//:benchmark",
+ "@com_github_google_benchmark//:benchmark_main",
],
)
@@ -366,7 +378,7 @@ cc_test(
name = "numbers_test",
size = "small",
srcs = [
- "internal/numbers_test_common.inc",
+ "internal/numbers_test_common.h",
"numbers_test.cc",
],
copts = ABSL_TEST_COPTS,
@@ -411,3 +423,14 @@ cc_test(
"@com_google_googletest//:gtest_main",
],
)
+
+cc_test(
+ name = "char_map_benchmark",
+ srcs = ["internal/char_map_benchmark.cc"],
+ copts = ABSL_TEST_COPTS,
+ tags = ["benchmark"],
+ deps = [
+ ":internal",
+ "@com_github_google_benchmark//:benchmark_main",
+ ],
+)
diff --git a/absl/strings/escaping_benchmark.cc b/absl/strings/escaping_benchmark.cc
index 26ddc2d5..0f791f4e 100644
--- a/absl/strings/escaping_benchmark.cc
+++ b/absl/strings/escaping_benchmark.cc
@@ -20,7 +20,7 @@
#include "benchmark/benchmark.h"
#include "absl/base/internal/raw_logging.h"
-#include "absl/strings/internal/escaping_test_common.inc"
+#include "absl/strings/internal/escaping_test_common.h"
namespace {
@@ -39,7 +39,7 @@ BENCHMARK(BM_CUnescapeHexString);
void BM_WebSafeBase64Escape_string(benchmark::State& state) {
std::string raw;
for (int i = 0; i < 10; ++i) {
- for (const auto& test_set : base64_strings) {
+ for (const auto& test_set : absl::strings_internal::base64_strings()) {
raw += std::string(test_set.plaintext);
}
}
@@ -92,5 +92,3 @@ void BM_CEscape_MostEscaped(benchmark::State& state) {
BENCHMARK(BM_CEscape_MostEscaped)->Range(1, 1 << 14);
} // namespace
-
-BENCHMARK_MAIN();
diff --git a/absl/strings/escaping_test.cc b/absl/strings/escaping_test.cc
index 982989b8..3f65ec10 100644
--- a/absl/strings/escaping_test.cc
+++ b/absl/strings/escaping_test.cc
@@ -25,7 +25,7 @@
#include "absl/container/fixed_array.h"
#include "absl/strings/str_cat.h"
-#include "absl/strings/internal/escaping_test_common.inc"
+#include "absl/strings/internal/escaping_test_common.h"
namespace {
@@ -575,7 +575,7 @@ TEST(Base64, EscapeAndUnescape) {
}
// Now try the long strings, this tests the streaming
- for (const auto& tc : base64_strings) {
+ for (const auto& tc : absl::strings_internal::base64_strings()) {
std::string buffer;
absl::WebSafeBase64Escape(tc.plaintext, &buffer);
EXPECT_EQ(tc.cyphertext, buffer);
diff --git a/absl/strings/internal/char_map_benchmark.cc b/absl/strings/internal/char_map_benchmark.cc
new file mode 100644
index 00000000..c45f3157
--- /dev/null
+++ b/absl/strings/internal/char_map_benchmark.cc
@@ -0,0 +1,61 @@
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// 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
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/strings/internal/char_map.h"
+
+#include <cstdint>
+
+#include "benchmark/benchmark.h"
+
+namespace {
+
+absl::strings_internal::Charmap MakeBenchmarkMap() {
+ absl::strings_internal::Charmap m;
+ uint32_t x[] = {0x0, 0x1, 0x2, 0x3, 0xf, 0xe, 0xd, 0xc};
+ for (uint32_t& t : x) t *= static_cast<uint32_t>(0x11111111UL);
+ for (uint32_t i = 0; i < 256; ++i) {
+ if ((x[i / 32] >> (i % 32)) & 1)
+ m = m | absl::strings_internal::Charmap::Char(i);
+ }
+ return m;
+}
+
+// Micro-benchmark for Charmap::contains.
+void BM_Contains(benchmark::State& state) {
+ // Loop-body replicated 10 times to increase time per iteration.
+ // Argument continuously changed to avoid generating common subexpressions.
+ const absl::strings_internal::Charmap benchmark_map = MakeBenchmarkMap();
+ unsigned char c = 0;
+ int ops = 0;
+ for (auto _ : state) {
+ ops += benchmark_map.contains(c++);
+ ops += benchmark_map.contains(c++);
+ ops += benchmark_map.contains(c++);
+ ops += benchmark_map.contains(c++);
+ ops += benchmark_map.contains(c++);
+ ops += benchmark_map.contains(c++);
+ ops += benchmark_map.contains(c++);
+ ops += benchmark_map.contains(c++);
+ ops += benchmark_map.contains(c++);
+ ops += benchmark_map.contains(c++);
+ }
+ benchmark::DoNotOptimize(ops);
+}
+BENCHMARK(BM_Contains);
+
+// We don't bother benchmarking Charmap::IsZero or Charmap::IntersectsWith;
+// their running time is data-dependent and it is not worth characterizing
+// "typical" data.
+
+} // namespace
diff --git a/absl/strings/internal/escaping_test_common.h b/absl/strings/internal/escaping_test_common.h
new file mode 100644
index 00000000..cc41f431
--- /dev/null
+++ b/absl/strings/internal/escaping_test_common.h
@@ -0,0 +1,131 @@
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// 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
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// This test contains common things needed by both escaping_test.cc and
+// escaping_benchmark.cc.
+
+#ifndef ABSL_STRINGS_INTERNAL_ESCAPING_TEST_COMMON_H_
+#define ABSL_STRINGS_INTERNAL_ESCAPING_TEST_COMMON_H_
+
+#include <array>
+#include "absl/strings/string_view.h"
+
+namespace absl {
+namespace strings_internal {
+
+struct base64_testcase {
+ absl::string_view plaintext;
+ absl::string_view cyphertext;
+};
+
+inline const std::array<base64_testcase, 5>& base64_strings() {
+ static const std::array<base64_testcase, 5> testcase{{
+ // Some google quotes
+ // Cyphertext created with "uuencode (GNU sharutils) 4.6.3"
+ // (Note that we're testing the websafe encoding, though, so if
+ // you add messages, be sure to run "tr -- '+/' '-_'" on the output)
+ { "I was always good at math and science, and I never realized "
+ "that was unusual or somehow undesirable. So one of the things "
+ "I care a lot about is helping to remove that stigma, "
+ "to show girls that you can be feminine, you can like the things "
+ "that girls like, but you can also be really good at technology. "
+ "You can be really good at building things."
+ " - Marissa Meyer, Newsweek, 2010-12-22" "\n",
+
+ "SSB3YXMgYWx3YXlzIGdvb2QgYXQgbWF0aCBhbmQgc2NpZW5jZSwgYW5kIEkg"
+ "bmV2ZXIgcmVhbGl6ZWQgdGhhdCB3YXMgdW51c3VhbCBvciBzb21laG93IHVu"
+ "ZGVzaXJhYmxlLiBTbyBvbmUgb2YgdGhlIHRoaW5ncyBJIGNhcmUgYSBsb3Qg"
+ "YWJvdXQgaXMgaGVscGluZyB0byByZW1vdmUgdGhhdCBzdGlnbWEsIHRvIHNo"
+ "b3cgZ2lybHMgdGhhdCB5b3UgY2FuIGJlIGZlbWluaW5lLCB5b3UgY2FuIGxp"
+ "a2UgdGhlIHRoaW5ncyB0aGF0IGdpcmxzIGxpa2UsIGJ1dCB5b3UgY2FuIGFs"
+ "c28gYmUgcmVhbGx5IGdvb2QgYXQgdGVjaG5vbG9neS4gWW91IGNhbiBiZSBy"
+ "ZWFsbHkgZ29vZCBhdCBidWlsZGluZyB0aGluZ3MuIC0gTWFyaXNzYSBNZXll"
+ "ciwgTmV3c3dlZWssIDIwMTAtMTItMjIK" },
+
+ { "Typical first year for a new cluster: "
+ "~0.5 overheating "
+ "~1 PDU failure "
+ "~1 rack-move "
+ "~1 network rewiring "
+ "~20 rack failures "
+ "~5 racks go wonky "
+ "~8 network maintenances "
+ "~12 router reloads "
+ "~3 router failures "
+ "~dozens of minor 30-second blips for dns "
+ "~1000 individual machine failures "
+ "~thousands of hard drive failures "
+ "slow disks, bad memory, misconfigured machines, flaky machines, etc."
+ " - Jeff Dean, The Joys of Real Hardware" "\n",
+
+ "VHlwaWNhbCBmaXJzdCB5ZWFyIGZvciBhIG5ldyBjbHVzdGVyOiB-MC41IG92"
+ "ZXJoZWF0aW5nIH4xIFBEVSBmYWlsdXJlIH4xIHJhY2stbW92ZSB-MSBuZXR3"
+ "b3JrIHJld2lyaW5nIH4yMCByYWNrIGZhaWx1cmVzIH41IHJhY2tzIGdvIHdv"
+ "bmt5IH44IG5ldHdvcmsgbWFpbnRlbmFuY2VzIH4xMiByb3V0ZXIgcmVsb2Fk"
+ "cyB-MyByb3V0ZXIgZmFpbHVyZXMgfmRvemVucyBvZiBtaW5vciAzMC1zZWNv"
+ "bmQgYmxpcHMgZm9yIGRucyB-MTAwMCBpbmRpdmlkdWFsIG1hY2hpbmUgZmFp"
+ "bHVyZXMgfnRob3VzYW5kcyBvZiBoYXJkIGRyaXZlIGZhaWx1cmVzIHNsb3cg"
+ "ZGlza3MsIGJhZCBtZW1vcnksIG1pc2NvbmZpZ3VyZWQgbWFjaGluZXMsIGZs"
+ "YWt5IG1hY2hpbmVzLCBldGMuIC0gSmVmZiBEZWFuLCBUaGUgSm95cyBvZiBS"
+ "ZWFsIEhhcmR3YXJlCg" },
+
+ { "I'm the head of the webspam team at Google. "
+ "That means that if you type your name into Google and get porn back, "
+ "it's my fault. Unless you're a porn star, in which case porn is a "
+ "completely reasonable response."
+ " - Matt Cutts, Google Plus" "\n",
+
+ "SSdtIHRoZSBoZWFkIG9mIHRoZSB3ZWJzcGFtIHRlYW0gYXQgR29vZ2xlLiAg"
+ "VGhhdCBtZWFucyB0aGF0IGlmIHlvdSB0eXBlIHlvdXIgbmFtZSBpbnRvIEdv"
+ "b2dsZSBhbmQgZ2V0IHBvcm4gYmFjaywgaXQncyBteSBmYXVsdC4gVW5sZXNz"
+ "IHlvdSdyZSBhIHBvcm4gc3RhciwgaW4gd2hpY2ggY2FzZSBwb3JuIGlzIGEg"
+ "Y29tcGxldGVseSByZWFzb25hYmxlIHJlc3BvbnNlLiAtIE1hdHQgQ3V0dHMs"
+ "IEdvb2dsZSBQbHVzCg" },
+
+ { "It will still be a long time before machines approach human "
+ "intelligence. "
+ "But luckily, machines don't actually have to be intelligent; "
+ "they just have to fake it. Access to a wealth of information, "
+ "combined with a rudimentary decision-making capacity, "
+ "can often be almost as useful. Of course, the results are better yet "
+ "when coupled with intelligence. A reference librarian with access to "
+ "a good search engine is a formidable tool."
+ " - Craig Silverstein, Siemens Pictures of the Future, Spring 2004"
+ "\n",
+
+ "SXQgd2lsbCBzdGlsbCBiZSBhIGxvbmcgdGltZSBiZWZvcmUgbWFjaGluZXMg"
+ "YXBwcm9hY2ggaHVtYW4gaW50ZWxsaWdlbmNlLiBCdXQgbHVja2lseSwgbWFj"
+ "aGluZXMgZG9uJ3QgYWN0dWFsbHkgaGF2ZSB0byBiZSBpbnRlbGxpZ2VudDsg"
+ "dGhleSBqdXN0IGhhdmUgdG8gZmFrZSBpdC4gQWNjZXNzIHRvIGEgd2VhbHRo"
+ "IG9mIGluZm9ybWF0aW9uLCBjb21iaW5lZCB3aXRoIGEgcnVkaW1lbnRhcnkg"
+ "ZGVjaXNpb24tbWFraW5nIGNhcGFjaXR5LCBjYW4gb2Z0ZW4gYmUgYWxtb3N0"
+ "IGFzIHVzZWZ1bC4gT2YgY291cnNlLCB0aGUgcmVzdWx0cyBhcmUgYmV0dGVy"
+ "IHlldCB3aGVuIGNvdXBsZWQgd2l0aCBpbnRlbGxpZ2VuY2UuIEEgcmVmZXJl"
+ "bmNlIGxpYnJhcmlhbiB3aXRoIGFjY2VzcyB0byBhIGdvb2Qgc2VhcmNoIGVu"
+ "Z2luZSBpcyBhIGZvcm1pZGFibGUgdG9vbC4gLSBDcmFpZyBTaWx2ZXJzdGVp"
+ "biwgU2llbWVucyBQaWN0dXJlcyBvZiB0aGUgRnV0dXJlLCBTcHJpbmcgMjAw"
+ "NAo" },
+
+ // Degenerate edge case
+ { "",
+ "" },
+ }};
+
+ return testcase;
+}
+
+} // namespace strings_internal
+} // namespace absl
+
+#endif // ABSL_STRINGS_INTERNAL_ESCAPING_TEST_COMMON_H_
diff --git a/absl/strings/internal/escaping_test_common.inc b/absl/strings/internal/escaping_test_common.inc
deleted file mode 100644
index 6f29140e..00000000
--- a/absl/strings/internal/escaping_test_common.inc
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// 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
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// This test contains common things needed by both escaping_test.cc and
-// escaping_benchmark.cc.
-
-namespace {
-
-struct {
- absl::string_view plaintext;
- absl::string_view cyphertext;
-} const base64_strings[] = {
- // Some google quotes
- // Cyphertext created with "uuencode (GNU sharutils) 4.6.3"
- // (Note that we're testing the websafe encoding, though, so if
- // you add messages, be sure to run "tr -- '+/' '-_'" on the output)
- { "I was always good at math and science, and I never realized "
- "that was unusual or somehow undesirable. So one of the things "
- "I care a lot about is helping to remove that stigma, "
- "to show girls that you can be feminine, you can like the things "
- "that girls like, but you can also be really good at technology. "
- "You can be really good at building things."
- " - Marissa Meyer, Newsweek, 2010-12-22" "\n",
-
- "SSB3YXMgYWx3YXlzIGdvb2QgYXQgbWF0aCBhbmQgc2NpZW5jZSwgYW5kIEkg"
- "bmV2ZXIgcmVhbGl6ZWQgdGhhdCB3YXMgdW51c3VhbCBvciBzb21laG93IHVu"
- "ZGVzaXJhYmxlLiBTbyBvbmUgb2YgdGhlIHRoaW5ncyBJIGNhcmUgYSBsb3Qg"
- "YWJvdXQgaXMgaGVscGluZyB0byByZW1vdmUgdGhhdCBzdGlnbWEsIHRvIHNo"
- "b3cgZ2lybHMgdGhhdCB5b3UgY2FuIGJlIGZlbWluaW5lLCB5b3UgY2FuIGxp"
- "a2UgdGhlIHRoaW5ncyB0aGF0IGdpcmxzIGxpa2UsIGJ1dCB5b3UgY2FuIGFs"
- "c28gYmUgcmVhbGx5IGdvb2QgYXQgdGVjaG5vbG9neS4gWW91IGNhbiBiZSBy"
- "ZWFsbHkgZ29vZCBhdCBidWlsZGluZyB0aGluZ3MuIC0gTWFyaXNzYSBNZXll"
- "ciwgTmV3c3dlZWssIDIwMTAtMTItMjIK" },
-
- { "Typical first year for a new cluster: "
- "~0.5 overheating "
- "~1 PDU failure "
- "~1 rack-move "
- "~1 network rewiring "
- "~20 rack failures "
- "~5 racks go wonky "
- "~8 network maintenances "
- "~12 router reloads "
- "~3 router failures "
- "~dozens of minor 30-second blips for dns "
- "~1000 individual machine failures "
- "~thousands of hard drive failures "
- "slow disks, bad memory, misconfigured machines, flaky machines, etc."
- " - Jeff Dean, The Joys of Real Hardware" "\n",
-
- "VHlwaWNhbCBmaXJzdCB5ZWFyIGZvciBhIG5ldyBjbHVzdGVyOiB-MC41IG92"
- "ZXJoZWF0aW5nIH4xIFBEVSBmYWlsdXJlIH4xIHJhY2stbW92ZSB-MSBuZXR3"
- "b3JrIHJld2lyaW5nIH4yMCByYWNrIGZhaWx1cmVzIH41IHJhY2tzIGdvIHdv"
- "bmt5IH44IG5ldHdvcmsgbWFpbnRlbmFuY2VzIH4xMiByb3V0ZXIgcmVsb2Fk"
- "cyB-MyByb3V0ZXIgZmFpbHVyZXMgfmRvemVucyBvZiBtaW5vciAzMC1zZWNv"
- "bmQgYmxpcHMgZm9yIGRucyB-MTAwMCBpbmRpdmlkdWFsIG1hY2hpbmUgZmFp"
- "bHVyZXMgfnRob3VzYW5kcyBvZiBoYXJkIGRyaXZlIGZhaWx1cmVzIHNsb3cg"
- "ZGlza3MsIGJhZCBtZW1vcnksIG1pc2NvbmZpZ3VyZWQgbWFjaGluZXMsIGZs"
- "YWt5IG1hY2hpbmVzLCBldGMuIC0gSmVmZiBEZWFuLCBUaGUgSm95cyBvZiBS"
- "ZWFsIEhhcmR3YXJlCg" },
-
- { "I'm the head of the webspam team at Google. "
- "That means that if you type your name into Google and get porn back, "
- "it's my fault. Unless you're a porn star, in which case porn is a "
- "completely reasonable response."
- " - Matt Cutts, Google Plus" "\n",
-
- "SSdtIHRoZSBoZWFkIG9mIHRoZSB3ZWJzcGFtIHRlYW0gYXQgR29vZ2xlLiAg"
- "VGhhdCBtZWFucyB0aGF0IGlmIHlvdSB0eXBlIHlvdXIgbmFtZSBpbnRvIEdv"
- "b2dsZSBhbmQgZ2V0IHBvcm4gYmFjaywgaXQncyBteSBmYXVsdC4gVW5sZXNz"
- "IHlvdSdyZSBhIHBvcm4gc3RhciwgaW4gd2hpY2ggY2FzZSBwb3JuIGlzIGEg"
- "Y29tcGxldGVseSByZWFzb25hYmxlIHJlc3BvbnNlLiAtIE1hdHQgQ3V0dHMs"
- "IEdvb2dsZSBQbHVzCg" },
-
- { "It will still be a long time before machines approach human intelligence. "
- "But luckily, machines don't actually have to be intelligent; "
- "they just have to fake it. Access to a wealth of information, "
- "combined with a rudimentary decision-making capacity, "
- "can often be almost as useful. Of course, the results are better yet "
- "when coupled with intelligence. A reference librarian with access to "
- "a good search engine is a formidable tool."
- " - Craig Silverstein, Siemens Pictures of the Future, Spring 2004" "\n",
-
- "SXQgd2lsbCBzdGlsbCBiZSBhIGxvbmcgdGltZSBiZWZvcmUgbWFjaGluZXMg"
- "YXBwcm9hY2ggaHVtYW4gaW50ZWxsaWdlbmNlLiBCdXQgbHVja2lseSwgbWFj"
- "aGluZXMgZG9uJ3QgYWN0dWFsbHkgaGF2ZSB0byBiZSBpbnRlbGxpZ2VudDsg"
- "dGhleSBqdXN0IGhhdmUgdG8gZmFrZSBpdC4gQWNjZXNzIHRvIGEgd2VhbHRo"
- "IG9mIGluZm9ybWF0aW9uLCBjb21iaW5lZCB3aXRoIGEgcnVkaW1lbnRhcnkg"
- "ZGVjaXNpb24tbWFraW5nIGNhcGFjaXR5LCBjYW4gb2Z0ZW4gYmUgYWxtb3N0"
- "IGFzIHVzZWZ1bC4gT2YgY291cnNlLCB0aGUgcmVzdWx0cyBhcmUgYmV0dGVy"
- "IHlldCB3aGVuIGNvdXBsZWQgd2l0aCBpbnRlbGxpZ2VuY2UuIEEgcmVmZXJl"
- "bmNlIGxpYnJhcmlhbiB3aXRoIGFjY2VzcyB0byBhIGdvb2Qgc2VhcmNoIGVu"
- "Z2luZSBpcyBhIGZvcm1pZGFibGUgdG9vbC4gLSBDcmFpZyBTaWx2ZXJzdGVp"
- "biwgU2llbWVucyBQaWN0dXJlcyBvZiB0aGUgRnV0dXJlLCBTcHJpbmcgMjAw"
- "NAo" },
-
- // Degenerate edge case
- { "",
- "" },
-};
-
-} // namespace
diff --git a/absl/strings/internal/numbers_test_common.h b/absl/strings/internal/numbers_test_common.h
new file mode 100644
index 00000000..20e3af51
--- /dev/null
+++ b/absl/strings/internal/numbers_test_common.h
@@ -0,0 +1,178 @@
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// 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
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// This file contains common things needed by numbers_test.cc,
+// numbers_legacy_test.cc and numbers_benchmark.cc.
+
+#ifndef ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_
+#define ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_
+
+#include <array>
+#include <cstdint>
+#include <limits>
+#include <string>
+
+namespace absl {
+namespace strings_internal {
+
+template <typename IntType>
+inline bool Itoa(IntType value, int base, std::string* destination) {
+ destination->clear();
+ if (base <= 1 || base > 36) {
+ return false;
+ }
+
+ if (value == 0) {
+ destination->push_back('0');
+ return true;
+ }
+
+ bool negative = value < 0;
+ while (value != 0) {
+ const IntType next_value = value / base;
+ // Can't use std::abs here because of problems when IntType is unsigned.
+ int remainder = value > next_value * base ? value - next_value * base
+ : next_value * base - value;
+ char c = remainder < 10 ? '0' + remainder : 'A' + remainder - 10;
+ destination->insert(0, 1, c);
+ value = next_value;
+ }
+
+ if (negative) {
+ destination->insert(0, 1, '-');
+ }
+ return true;
+}
+
+struct uint32_test_case {
+ const char* str;
+ bool expect_ok;
+ int base; // base to pass to the conversion function
+ uint32_t expected;
+};
+
+inline const std::array<uint32_test_case, 27>& strtouint32_test_cases() {
+ static const std::array<uint32_test_case, 27> test_cases{{
+ {"0xffffffff", true, 16, std::numeric_limits<uint32_t>::max()},
+ {"0x34234324", true, 16, 0x34234324},
+ {"34234324", true, 16, 0x34234324},
+ {"0", true, 16, 0},
+ {" \t\n 0xffffffff", true, 16, std::numeric_limits<uint32_t>::max()},
+ {" \f\v 46", true, 10, 46}, // must accept weird whitespace
+ {" \t\n 72717222", true, 8, 072717222},
+ {" \t\n 072717222", true, 8, 072717222},
+ {" \t\n 072717228", false, 8, 07271722},
+ {"0", true, 0, 0},
+
+ // Base-10 version.
+ {"34234324", true, 0, 34234324},
+ {"4294967295", true, 0, std::numeric_limits<uint32_t>::max()},
+ {"34234324 \n\t", true, 10, 34234324},
+
+ // Unusual base
+ {"0", true, 3, 0},
+ {"2", true, 3, 2},
+ {"11", true, 3, 4},
+
+ // Invalid uints.
+ {"", false, 0, 0},
+ {" ", false, 0, 0},
+ {"abc", false, 0, 0}, // would be valid hex, but prefix is missing
+ {"34234324a", false, 0, 34234324},
+ {"34234.3", false, 0, 34234},
+ {"-1", false, 0, 0},
+ {" -123", false, 0, 0},
+ {" \t\n -123", false, 0, 0},
+
+ // Out of bounds.
+ {"4294967296", false, 0, std::numeric_limits<uint32_t>::max()},
+ {"0x100000000", false, 0, std::numeric_limits<uint32_t>::max()},
+ {nullptr, false, 0, 0},
+ }};
+ return test_cases;
+}
+
+struct uint64_test_case {
+ const char* str;
+ bool expect_ok;
+ int base;
+ uint64_t expected;
+};
+
+inline const std::array<uint64_test_case, 34>& strtouint64_test_cases() {
+ static const std::array<uint64_test_case, 34> test_cases{{
+ {"0x3423432448783446", true, 16, int64_t{0x3423432448783446}},
+ {"3423432448783446", true, 16, int64_t{0x3423432448783446}},
+
+ {"0", true, 16, 0},
+ {"000", true, 0, 0},
+ {"0", true, 0, 0},
+ {" \t\n 0xffffffffffffffff", true, 16,
+ std::numeric_limits<uint64_t>::max()},
+
+ {"012345670123456701234", true, 8, int64_t{012345670123456701234}},
+ {"12345670123456701234", true, 8, int64_t{012345670123456701234}},
+
+ {"12845670123456701234", false, 8, 0},
+
+ // Base-10 version.
+ {"34234324487834466", true, 0, int64_t{34234324487834466}},
+
+ {" \t\n 18446744073709551615", true, 0,
+ std::numeric_limits<uint64_t>::max()},
+
+ {"34234324487834466 \n\t ", true, 0, int64_t{34234324487834466}},
+
+ {" \f\v 46", true, 10, 46}, // must accept weird whitespace
+
+ // Unusual base
+ {"0", true, 3, 0},
+ {"2", true, 3, 2},
+ {"11", true, 3, 4},
+
+ {"0", true, 0, 0},
+
+ // Invalid uints.
+ {"", false, 0, 0},
+ {" ", false, 0, 0},
+ {"abc", false, 0, 0},
+ {"34234324487834466a", false, 0, 0},
+ {"34234487834466.3", false, 0, 0},
+ {"-1", false, 0, 0},
+ {" -123", false, 0, 0},
+ {" \t\n -123", false, 0, 0},
+
+ // Out of bounds.
+ {"18446744073709551616", false, 10, 0},
+ {"18446744073709551616", false, 0, 0},
+ {"0x10000000000000000", false, 16, std::numeric_limits<uint64_t>::max()},
+ {"0X10000000000000000", false, 16,
+ std::numeric_limits<uint64_t>::max()}, // 0X versus 0x.
+ {"0x10000000000000000", false, 0, std::numeric_limits<uint64_t>::max()},
+ {"0X10000000000000000", false, 0,
+ std::numeric_limits<uint64_t>::max()}, // 0X versus 0x.
+
+ {"0x1234", true, 16, 0x1234},
+
+ // Base-10 std::string version.
+ {"1234", true, 0, 1234},
+ {nullptr, false, 0, 0},
+ }};
+ return test_cases;
+}
+
+} // namespace strings_internal
+} // namespace absl
+
+#endif // ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_
diff --git a/absl/strings/internal/numbers_test_common.inc b/absl/strings/internal/numbers_test_common.inc
deleted file mode 100644
index 81d2a1b7..00000000
--- a/absl/strings/internal/numbers_test_common.inc
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// 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
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// This file contains common things needed by numbers_test.cc,
-// numbers_legacy_test.cc and numbers_benchmark.cc.
-
-namespace {
-
-template <typename IntType>
-bool Itoa(IntType value, int base, std::string* destination) {
- destination->clear();
- if (base <= 1 || base > 36) {
- return false;
- }
-
- if (value == 0) {
- destination->push_back('0');
- return true;
- }
-
- bool negative = value < 0;
- while (value != 0) {
- const IntType next_value = value / base;
- // Can't use std::abs here because of problems when IntType is unsigned.
- int remainder = value > next_value * base ? value - next_value * base
- : next_value * base - value;
- char c = remainder < 10 ? '0' + remainder : 'A' + remainder - 10;
- destination->insert(0, 1, c);
- value = next_value;
- }
-
- if (negative) {
- destination->insert(0, 1, '-');
- }
- return true;
-}
-
-struct uint32_test_case {
- const char* str;
- bool expect_ok;
- int base; // base to pass to the conversion function
- uint32_t expected;
-} const strtouint32_test_cases[] = {
- {"0xffffffff", true, 16, std::numeric_limits<uint32_t>::max()},
- {"0x34234324", true, 16, 0x34234324},
- {"34234324", true, 16, 0x34234324},
- {"0", true, 16, 0},
- {" \t\n 0xffffffff", true, 16, std::numeric_limits<uint32_t>::max()},
- {" \f\v 46", true, 10, 46}, // must accept weird whitespace
- {" \t\n 72717222", true, 8, 072717222},
- {" \t\n 072717222", true, 8, 072717222},
- {" \t\n 072717228", false, 8, 07271722},
- {"0", true, 0, 0},
-
- // Base-10 version.
- {"34234324", true, 0, 34234324},
- {"4294967295", true, 0, std::numeric_limits<uint32_t>::max()},
- {"34234324 \n\t", true, 10, 34234324},
-
- // Unusual base
- {"0", true, 3, 0},
- {"2", true, 3, 2},
- {"11", true, 3, 4},
-
- // Invalid uints.
- {"", false, 0, 0},
- {" ", false, 0, 0},
- {"abc", false, 0, 0}, // would be valid hex, but prefix is missing
- {"34234324a", false, 0, 34234324},
- {"34234.3", false, 0, 34234},
- {"-1", false, 0, 0},
- {" -123", false, 0, 0},
- {" \t\n -123", false, 0, 0},
-
- // Out of bounds.
- {"4294967296", false, 0, std::numeric_limits<uint32_t>::max()},
- {"0x100000000", false, 0, std::numeric_limits<uint32_t>::max()},
- {nullptr, false, 0, 0},
-};
-
-struct uint64_test_case {
- const char* str;
- bool expect_ok;
- int base;
- uint64_t expected;
-} const strtouint64_test_cases[] = {
- {"0x3423432448783446", true, 16, int64_t{0x3423432448783446}},
- {"3423432448783446", true, 16, int64_t{0x3423432448783446}},
-
- {"0", true, 16, 0},
- {"000", true, 0, 0},
- {"0", true, 0, 0},
- {" \t\n 0xffffffffffffffff", true, 16,
- std::numeric_limits<uint64_t>::max()},
-
- {"012345670123456701234", true, 8, int64_t{012345670123456701234}},
- {"12345670123456701234", true, 8, int64_t{012345670123456701234}},
-
- {"12845670123456701234", false, 8, 0},
-
- // Base-10 version.
- {"34234324487834466", true, 0, int64_t{34234324487834466}},
-
- {" \t\n 18446744073709551615", true, 0,
- std::numeric_limits<uint64_t>::max()},
-
- {"34234324487834466 \n\t ", true, 0, int64_t{34234324487834466}},
-
- {" \f\v 46", true, 10, 46}, // must accept weird whitespace
-
- // Unusual base
- {"0", true, 3, 0},
- {"2", true, 3, 2},
- {"11", true, 3, 4},
-
- {"0", true, 0, 0},
-
- // Invalid uints.
- {"", false, 0, 0},
- {" ", false, 0, 0},
- {"abc", false, 0, 0},
- {"34234324487834466a", false, 0, 0},
- {"34234487834466.3", false, 0, 0},
- {"-1", false, 0, 0},
- {" -123", false, 0, 0},
- {" \t\n -123", false, 0, 0},
-
- // Out of bounds.
- {"18446744073709551616", false, 10, 0},
- {"18446744073709551616", false, 0, 0},
- {"0x10000000000000000", false, 16, std::numeric_limits<uint64_t>::max()},
- {"0X10000000000000000", false, 16,
- std::numeric_limits<uint64_t>::max()}, // 0X versus 0x.
- {"0x10000000000000000", false, 0, std::numeric_limits<uint64_t>::max()},
- {"0X10000000000000000", false, 0,
- std::numeric_limits<uint64_t>::max()}, // 0X versus 0x.
-
- {"0x1234", true, 16, 0x1234},
-
- // Base-10 std::string version.
- {"1234", true, 0, 1234},
- {nullptr, false, 0, 0},
-};
-
-} // namespace
diff --git a/absl/strings/internal/ostringstream_benchmark.cc b/absl/strings/internal/ostringstream_benchmark.cc
new file mode 100644
index 00000000..c93f9690
--- /dev/null
+++ b/absl/strings/internal/ostringstream_benchmark.cc
@@ -0,0 +1,106 @@
+// Copyright 2018 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// 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
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/strings/internal/ostringstream.h"
+
+#include <sstream>
+#include <string>
+
+#include "benchmark/benchmark.h"
+
+namespace {
+
+enum StringType {
+ kNone,
+ kStdString,
+};
+
+// Benchmarks for std::ostringstream.
+template <StringType kOutput>
+void BM_StdStream(benchmark::State& state) {
+ const int num_writes = state.range(0);
+ const int bytes_per_write = state.range(1);
+ const std::string payload(bytes_per_write, 'x');
+ for (auto _ : state) {
+ std::ostringstream strm;
+ benchmark::DoNotOptimize(strm);
+ for (int i = 0; i != num_writes; ++i) {
+ strm << payload;
+ }
+ switch (kOutput) {
+ case kNone: {
+ break;
+ }
+ case kStdString: {
+ std::string s = strm.str();
+ benchmark::DoNotOptimize(s);
+ break;
+ }
+ }
+ }
+}
+
+// Create the stream, optionally write to it, then destroy it.
+BENCHMARK_TEMPLATE(BM_StdStream, kNone)
+ ->ArgPair(0, 0)
+ ->ArgPair(1, 16) // 16 bytes is small enough for SSO
+ ->ArgPair(1, 256) // 256 bytes requires heap allocation
+ ->ArgPair(1024, 256);
+// Create the stream, write to it, get std::string out, then destroy.
+BENCHMARK_TEMPLATE(BM_StdStream, kStdString)
+ ->ArgPair(1, 16) // 16 bytes is small enough for SSO
+ ->ArgPair(1, 256) // 256 bytes requires heap allocation
+ ->ArgPair(1024, 256);
+
+// Benchmarks for OStringStream.
+template <StringType kOutput>
+void BM_CustomStream(benchmark::State& state) {
+ const int num_writes = state.range(0);
+ const int bytes_per_write = state.range(1);
+ const std::string payload(bytes_per_write, 'x');
+ for (auto _ : state) {
+ std::string out;
+ absl::strings_internal::OStringStream strm(&out);
+ benchmark::DoNotOptimize(strm);
+ for (int i = 0; i != num_writes; ++i) {
+ strm << payload;
+ }
+ switch (kOutput) {
+ case kNone: {
+ break;
+ }
+ case kStdString: {
+ std::string s = out;
+ benchmark::DoNotOptimize(s);
+ break;
+ }
+ }
+ }
+}
+
+// Create the stream, optionally write to it, then destroy it.
+BENCHMARK_TEMPLATE(BM_CustomStream, kNone)
+ ->ArgPair(0, 0)
+ ->ArgPair(1, 16) // 16 bytes is small enough for SSO
+ ->ArgPair(1, 256) // 256 bytes requires heap allocation
+ ->ArgPair(1024, 256);
+// Create the stream, write to it, get std::string out, then destroy.
+// It's not useful in practice to extract std::string from OStringStream; we
+// measure it for completeness.
+BENCHMARK_TEMPLATE(BM_CustomStream, kStdString)
+ ->ArgPair(1, 16) // 16 bytes is small enough for SSO
+ ->ArgPair(1, 256) // 256 bytes requires heap allocation
+ ->ArgPair(1024, 256);
+
+} // namespace
diff --git a/absl/strings/numbers.h b/absl/strings/numbers.h
index 75925e61..cf3c5972 100644
--- a/absl/strings/numbers.h
+++ b/absl/strings/numbers.h
@@ -52,12 +52,16 @@ ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view s, int_type* out);
//
// Converts the given std::string (optionally followed or preceded by ASCII
// whitespace) into a float, which may be rounded on overflow or underflow.
+// See http://en.cppreference.com/w/c/std::string/byte/strtof for details about the
+// allowed formats for `str`.
ABSL_MUST_USE_RESULT bool SimpleAtof(absl::string_view str, float* value);
// SimpleAtod()
//
// Converts the given std::string (optionally followed or preceded by ASCII
// whitespace) into a double, which may be rounded on overflow or underflow.
+// See http://en.cppreference.com/w/c/std::string/byte/strtof for details about the
+// allowed formats for `str`.
ABSL_MUST_USE_RESULT bool SimpleAtod(absl::string_view str, double* value);
// SimpleAtob()
diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc
index e372eea1..24e7138c 100644
--- a/absl/strings/numbers_test.cc
+++ b/absl/strings/numbers_test.cc
@@ -38,7 +38,7 @@
#include "absl/base/internal/raw_logging.h"
#include "absl/strings/str_cat.h"
-#include "absl/strings/internal/numbers_test_common.inc"
+#include "absl/strings/internal/numbers_test_common.h"
namespace {
@@ -48,6 +48,9 @@ using absl::numbers_internal::safe_strto64_base;
using absl::numbers_internal::safe_strtou32_base;
using absl::numbers_internal::safe_strtou64_base;
using absl::numbers_internal::SixDigitsToBuffer;
+using absl::strings_internal::Itoa;
+using absl::strings_internal::strtouint32_test_cases;
+using absl::strings_internal::strtouint64_test_cases;
using absl::SimpleAtoi;
using testing::Eq;
using testing::MatchesRegex;
@@ -654,8 +657,8 @@ TEST(stringtest, safe_strtou64_random) {
}
TEST(stringtest, safe_strtou32_base) {
- for (int i = 0; strtouint32_test_cases[i].str != nullptr; ++i) {
- const auto& e = strtouint32_test_cases[i];
+ for (int i = 0; strtouint32_test_cases()[i].str != nullptr; ++i) {
+ const auto& e = strtouint32_test_cases()[i];
uint32_t value;
EXPECT_EQ(e.expect_ok, safe_strtou32_base(e.str, &value, e.base))
<< "str=\"" << e.str << "\" base=" << e.base;
@@ -667,8 +670,8 @@ TEST(stringtest, safe_strtou32_base) {
}
TEST(stringtest, safe_strtou32_base_length_delimited) {
- for (int i = 0; strtouint32_test_cases[i].str != nullptr; ++i) {
- const auto& e = strtouint32_test_cases[i];
+ for (int i = 0; strtouint32_test_cases()[i].str != nullptr; ++i) {
+ const auto& e = strtouint32_test_cases()[i];
std::string tmp(e.str);
tmp.append("12"); // Adds garbage at the end.
@@ -685,8 +688,8 @@ TEST(stringtest, safe_strtou32_base_length_delimited) {
}
TEST(stringtest, safe_strtou64_base) {
- for (int i = 0; strtouint64_test_cases[i].str != nullptr; ++i) {
- const auto& e = strtouint64_test_cases[i];
+ for (int i = 0; strtouint64_test_cases()[i].str != nullptr; ++i) {
+ const auto& e = strtouint64_test_cases()[i];
uint64_t value;
EXPECT_EQ(e.expect_ok, safe_strtou64_base(e.str, &value, e.base))
<< "str=\"" << e.str << "\" base=" << e.base;
@@ -697,8 +700,8 @@ TEST(stringtest, safe_strtou64_base) {
}
TEST(stringtest, safe_strtou64_base_length_delimited) {
- for (int i = 0; strtouint64_test_cases[i].str != nullptr; ++i) {
- const auto& e = strtouint64_test_cases[i];
+ for (int i = 0; strtouint64_test_cases()[i].str != nullptr; ++i) {
+ const auto& e = strtouint64_test_cases()[i];
std::string tmp(e.str);
tmp.append("12"); // Adds garbage at the end.
diff --git a/absl/strings/str_cat_benchmark.cc b/absl/strings/str_cat_benchmark.cc
index 1791410c..b6df9e30 100644
--- a/absl/strings/str_cat_benchmark.cc
+++ b/absl/strings/str_cat_benchmark.cc
@@ -138,5 +138,3 @@ void BM_DoubleToString_By_SixDigits(benchmark::State& state) {
BENCHMARK(BM_DoubleToString_By_SixDigits);
} // namespace
-
-BENCHMARK_MAIN();
diff --git a/absl/strings/str_join_benchmark.cc b/absl/strings/str_join_benchmark.cc
index 79cad5e3..7fb0e497 100644
--- a/absl/strings/str_join_benchmark.cc
+++ b/absl/strings/str_join_benchmark.cc
@@ -94,5 +94,3 @@ BENCHMARK(BM_JoinStreamable)
->ArgPair(256, 256);
} // namespace
-
-BENCHMARK_MAIN();
diff --git a/absl/strings/str_replace_benchmark.cc b/absl/strings/str_replace_benchmark.cc
index 9dd72eb6..e608de8d 100644
--- a/absl/strings/str_replace_benchmark.cc
+++ b/absl/strings/str_replace_benchmark.cc
@@ -120,5 +120,3 @@ void BM_StrReplaceAll(benchmark::State& state) {
BENCHMARK(BM_StrReplaceAll);
} // namespace
-
-BENCHMARK_MAIN();
diff --git a/absl/strings/str_split_benchmark.cc b/absl/strings/str_split_benchmark.cc
index c35787b7..326ff744 100644
--- a/absl/strings/str_split_benchmark.cc
+++ b/absl/strings/str_split_benchmark.cc
@@ -154,5 +154,3 @@ BENCHMARK_TEMPLATE(BM_SplitStringWithOneCharNoVector, OneCharLiteral);
BENCHMARK_TEMPLATE(BM_SplitStringWithOneCharNoVector, OneCharStringLiteral);
} // namespace
-
-BENCHMARK_MAIN();
diff --git a/absl/strings/string_view_benchmark.cc b/absl/strings/string_view_benchmark.cc
index c66f0fbd..fb46db18 100644
--- a/absl/strings/string_view_benchmark.cc
+++ b/absl/strings/string_view_benchmark.cc
@@ -327,5 +327,3 @@ void BM_AppendToStringNative(benchmark::State& state) {
BENCHMARK(BM_AppendToStringNative)->Range(1 << 3, 1 << 12);
} // namespace
-
-BENCHMARK_MAIN();
diff --git a/absl/strings/substitute.h b/absl/strings/substitute.h
index 5747d384..c4b25ba7 100644
--- a/absl/strings/substitute.h
+++ b/absl/strings/substitute.h
@@ -99,7 +99,10 @@ class Arg {
// Explicitly overload `const char*` so the compiler doesn't cast to `bool`.
Arg(const char* value) // NOLINT(runtime/explicit)
: piece_(absl::NullSafeStringView(value)) {}
- Arg(const std::string& value) // NOLINT(runtime/explicit)
+ template <typename Allocator>
+ Arg( // NOLINT
+ const std::basic_string<char, std::char_traits<char>, Allocator>&
+ value) noexcept
: piece_(value) {}
Arg(absl::string_view value) // NOLINT(runtime/explicit)
: piece_(value) {}