summaryrefslogtreecommitdiff
path: root/absl/strings
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings')
-rw-r--r--absl/strings/BUILD.bazel3
-rw-r--r--absl/strings/internal/str_split_internal.h26
-rw-r--r--absl/strings/str_format.h20
-rw-r--r--absl/strings/str_split_test.cc28
4 files changed, 64 insertions, 13 deletions
diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel
index 3e50d24a..17831c20 100644
--- a/absl/strings/BUILD.bazel
+++ b/absl/strings/BUILD.bazel
@@ -486,6 +486,9 @@ cc_test(
srcs = [
"charconv_benchmark.cc",
],
+ tags = [
+ "benchmark",
+ ],
deps = [
":strings",
"//absl/base",
diff --git a/absl/strings/internal/str_split_internal.h b/absl/strings/internal/str_split_internal.h
index a1b10f3a..9cf0833f 100644
--- a/absl/strings/internal/str_split_internal.h
+++ b/absl/strings/internal/str_split_internal.h
@@ -228,14 +228,31 @@ struct IsInitializerList
// compiled in C++11 will get an error due to ambiguous conversion paths (in
// C++11 std::vector<T>::operator= is overloaded to take either a std::vector<T>
// or an std::initializer_list<T>).
+
+template <typename C, bool has_value_type, bool has_mapped_type>
+struct SplitterIsConvertibleToImpl : std::false_type {};
+
+template <typename C>
+struct SplitterIsConvertibleToImpl<C, true, false>
+ : std::is_constructible<typename C::value_type, absl::string_view> {};
+
+template <typename C>
+struct SplitterIsConvertibleToImpl<C, true, true>
+ : absl::conjunction<
+ std::is_constructible<typename C::key_type, absl::string_view>,
+ std::is_constructible<typename C::mapped_type, absl::string_view>> {};
+
template <typename C>
struct SplitterIsConvertibleTo
- : std::enable_if<
+ : SplitterIsConvertibleToImpl<
+ C,
#ifdef _GLIBCXX_DEBUG
!IsStrictlyBaseOfAndConvertibleToSTLContainer<C>::value &&
#endif // _GLIBCXX_DEBUG
- !IsInitializerList<C>::value && HasValueType<C>::value &&
- HasConstIterator<C>::value> {
+ !IsInitializerList<
+ typename std::remove_reference<C>::type>::value &&
+ HasValueType<C>::value && HasConstIterator<C>::value,
+ HasMappedType<C>::value> {
};
// This class implements the range that is returned by absl::StrSplit(). This
@@ -281,7 +298,8 @@ class Splitter {
// An implicit conversion operator that is restricted to only those containers
// that the splitter is convertible to.
template <typename Container,
- typename OnlyIf = typename SplitterIsConvertibleTo<Container>::type>
+ typename = typename std::enable_if<
+ SplitterIsConvertibleTo<Container>::value>::type>
operator Container() const { // NOLINT(runtime/explicit)
return ConvertToContainer<Container, typename Container::value_type,
HasMappedType<Container>::value>()(*this);
diff --git a/absl/strings/str_format.h b/absl/strings/str_format.h
index 98e0fef4..a3fb89c7 100644
--- a/absl/strings/str_format.h
+++ b/absl/strings/str_format.h
@@ -344,13 +344,13 @@ ABSL_MUST_USE_RESULT str_format_internal::Streamable StreamFormat(
// PrintF()
//
// Writes to stdout given a format std::string and zero or more arguments. This
-// function is functionally equivalent to `std::print()` (and type-safe); prefer
-// `absl::PrintF()` over `std::printf()`.
+// function is functionally equivalent to `std::printf()` (and type-safe);
+// prefer `absl::PrintF()` over `std::printf()`.
//
// Example:
//
// std::string_view s = "Ulaanbaatar";
-// absl::PrintF("The capital of Mongolia is: %s \n", s);
+// absl::PrintF("The capital of Mongolia is %s", s);
//
// Outputs: "The capital of Mongolia is Ulaanbaatar"
//
@@ -364,13 +364,13 @@ int PrintF(const FormatSpec<Args...>& format, const Args&... args) {
// FPrintF()
//
// Writes to a file given a format std::string and zero or more arguments. This
-// function is functionally equivalent to `std::fprint()` (and type-safe);
+// function is functionally equivalent to `std::fprintf()` (and type-safe);
// prefer `absl::FPrintF()` over `std::fprintf()`.
//
// Example:
//
// std::string_view s = "Ulaanbaatar";
-// absl::FPrintF("The capital of Mongolia is: %s \n", s);
+// absl::FPrintF("The capital of Mongolia is %s", s);
//
// Outputs: "The capital of Mongolia is Ulaanbaatar"
//
@@ -385,15 +385,17 @@ int FPrintF(std::FILE* output, const FormatSpec<Args...>& format,
// SNPrintF()
//
// Writes to a sized buffer given a format std::string and zero or more arguments.
-// This function is functionally equivalent to `std::snprint()` (and type-safe);
-// prefer `absl::SNPrintF()` over `std::snprintf()`.
+// This function is functionally equivalent to `std::snprintf()` (and
+// type-safe); prefer `absl::SNPrintF()` over `std::snprintf()`.
//
// Example:
//
// std::string_view s = "Ulaanbaatar";
-// absl::FPrintF("The capital of Mongolia is: %s \n", s);
+// char output[128];
+// absl::SNPrintF(output, sizeof(output),
+// "The capital of Mongolia is %s", s);
//
-// Outputs: "The capital of Mongolia is Ulaanbaatar"
+// Post-condition: output == "The capital of Mongolia is Ulaanbaatar"
//
template <typename... Args>
int SNPrintF(char* output, std::size_t size, const FormatSpec<Args...>& format,
diff --git a/absl/strings/str_split_test.cc b/absl/strings/str_split_test.cc
index c172a762..c6898863 100644
--- a/absl/strings/str_split_test.cc
+++ b/absl/strings/str_split_test.cc
@@ -37,6 +37,34 @@ using ::testing::ElementsAre;
using ::testing::Pair;
using ::testing::UnorderedElementsAre;
+TEST(Split, TraitsTest) {
+ static_assert(!absl::strings_internal::SplitterIsConvertibleTo<int>::value,
+ "");
+ static_assert(!absl::strings_internal::SplitterIsConvertibleTo<std::string>::value,
+ "");
+ static_assert(absl::strings_internal::SplitterIsConvertibleTo<
+ std::vector<std::string>>::value,
+ "");
+ static_assert(
+ !absl::strings_internal::SplitterIsConvertibleTo<std::vector<int>>::value,
+ "");
+ static_assert(absl::strings_internal::SplitterIsConvertibleTo<
+ std::vector<absl::string_view>>::value,
+ "");
+ static_assert(absl::strings_internal::SplitterIsConvertibleTo<
+ std::map<std::string, std::string>>::value,
+ "");
+ static_assert(absl::strings_internal::SplitterIsConvertibleTo<
+ std::map<absl::string_view, absl::string_view>>::value,
+ "");
+ static_assert(!absl::strings_internal::SplitterIsConvertibleTo<
+ std::map<int, std::string>>::value,
+ "");
+ static_assert(!absl::strings_internal::SplitterIsConvertibleTo<
+ std::map<std::string, int>>::value,
+ "");
+}
+
// This tests the overall split API, which is made up of the absl::StrSplit()
// function and the Delimiter objects in the absl:: namespace.
// This TEST macro is outside of any namespace to require full specification of