diff options
Diffstat (limited to 'absl/strings')
-rw-r--r-- | absl/strings/BUILD.bazel | 3 | ||||
-rw-r--r-- | absl/strings/internal/str_split_internal.h | 26 | ||||
-rw-r--r-- | absl/strings/str_format.h | 20 | ||||
-rw-r--r-- | absl/strings/str_split_test.cc | 28 |
4 files changed, 64 insertions, 13 deletions
diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel index 3e50d24a322a..17831c208230 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 a1b10f3addcf..9cf0833f4902 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 98e0fef4906b..a3fb89c79581 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 c172a7629933..c6898863dc0e 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 |