summaryrefslogtreecommitdiff
path: root/absl/strings
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2023-09-13 07:57:51 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2023-09-13 07:58:42 -0700
commit9e1789ffea47fdeb3133aa42aa9592f3673fb6ed (patch)
treea41313482e10f78947308b7a0aab28cdee09c501 /absl/strings
parent6c6b2733f8453f53e4e07fe4e311d52d51aad100 (diff)
Make `HasAbslStringify` public.
PiperOrigin-RevId: 565050503 Change-Id: I8f4c463be4ef513a2788745d1b454a7ede489152
Diffstat (limited to 'absl/strings')
-rw-r--r--absl/strings/BUILD.bazel13
-rw-r--r--absl/strings/CMakeLists.txt13
-rw-r--r--absl/strings/has_absl_stringify.h63
-rw-r--r--absl/strings/has_absl_stringify_test.cc37
-rw-r--r--absl/strings/internal/has_absl_stringify.h21
-rw-r--r--absl/strings/internal/str_format/arg.h15
-rw-r--r--absl/strings/str_cat.h14
-rw-r--r--absl/strings/substitute.h4
8 files changed, 147 insertions, 33 deletions
diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel
index e226a27d..6d0ed698 100644
--- a/absl/strings/BUILD.bazel
+++ b/absl/strings/BUILD.bazel
@@ -70,6 +70,7 @@ cc_library(
"ascii.h",
"charconv.h",
"escaping.h",
+ "has_absl_stringify.h",
"internal/damerau_levenshtein_distance.h",
"internal/has_absl_stringify.h",
"internal/string_constant.h",
@@ -180,6 +181,18 @@ cc_test(
)
cc_test(
+ name = "has_absl_stringify_test",
+ size = "small",
+ srcs = ["has_absl_stringify_test.cc"],
+ copts = ABSL_TEST_COPTS,
+ visibility = ["//visibility:private"],
+ deps = [
+ ":strings",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_test(
name = "ascii_test",
size = "small",
srcs = ["ascii_test.cc"],
diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt
index 8bd93271..ebf085db 100644
--- a/absl/strings/CMakeLists.txt
+++ b/absl/strings/CMakeLists.txt
@@ -38,6 +38,7 @@ absl_cc_library(
"ascii.h"
"charconv.h"
"escaping.h"
+ "has_absl_stringify.h"
"internal/damerau_levenshtein_distance.h"
"internal/string_constant.h"
"internal/has_absl_stringify.h"
@@ -156,6 +157,18 @@ absl_cc_test(
absl_cc_test(
NAME
+ has_absl_stringify_test
+ SRCS
+ "has_absl_stringify_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
+ DEPS
+ absl::strings
+ GTest::gmock_main
+)
+
+absl_cc_test(
+ NAME
ascii_test
SRCS
"ascii_test.cc"
diff --git a/absl/strings/has_absl_stringify.h b/absl/strings/has_absl_stringify.h
new file mode 100644
index 00000000..274a7865
--- /dev/null
+++ b/absl/strings/has_absl_stringify.h
@@ -0,0 +1,63 @@
+// Copyright 2022 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
+//
+// https://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.
+
+#ifndef ABSL_STRINGS_HAS_ABSL_STRINGIFY_H_
+#define ABSL_STRINGS_HAS_ABSL_STRINGIFY_H_
+
+#include <type_traits>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+
+namespace strings_internal {
+
+// This is an empty class not intended to be used. It exists so that
+// `HasAbslStringify` can reference a universal class rather than needing to be
+// copied for each new sink.
+class UnimplementedSink {
+ public:
+ void Append(size_t count, char ch);
+
+ void Append(string_view v);
+
+ // Support `absl::Format(&sink, format, args...)`.
+ friend void AbslFormatFlush(UnimplementedSink* sink, absl::string_view v);
+};
+
+} // namespace strings_internal
+
+// `HasAbslStringify<T>` detects if type `T` supports the `AbslStringify()`
+// customization point (see
+// https://abseil.io/docs/cpp/guides/format#abslstringify for the
+// documentation).
+//
+// Note that there are types that can be `StrCat`-ed that do not use the
+// `AbslStringify` customization point (for example, `int`).
+
+template <typename T, typename = void>
+struct HasAbslStringify : std::false_type {};
+
+template <typename T>
+struct HasAbslStringify<
+ T, std::enable_if_t<std::is_void<decltype(AbslStringify(
+ std::declval<strings_internal::UnimplementedSink&>(),
+ std::declval<const T&>()))>::value>> : std::true_type {};
+
+ABSL_NAMESPACE_END
+} // namespace absl
+
+#endif // ABSL_STRINGS_HAS_ABSL_STRINGIFY_H_
diff --git a/absl/strings/has_absl_stringify_test.cc b/absl/strings/has_absl_stringify_test.cc
new file mode 100644
index 00000000..e9915c66
--- /dev/null
+++ b/absl/strings/has_absl_stringify_test.cc
@@ -0,0 +1,37 @@
+// Copyright 2023 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
+//
+// https://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/has_absl_stringify.h"
+
+#include <string>
+
+#include "gtest/gtest.h"
+
+namespace {
+
+struct TypeWithoutAbslStringify {};
+
+struct TypeWithAbslStringify {
+ template <typename Sink>
+ friend void AbslStringify(Sink&, const TypeWithAbslStringify&) {}
+};
+
+TEST(HasAbslStringifyTest, Works) {
+ EXPECT_FALSE(absl::HasAbslStringify<int>::value);
+ EXPECT_FALSE(absl::HasAbslStringify<std::string>::value);
+ EXPECT_FALSE(absl::HasAbslStringify<TypeWithoutAbslStringify>::value);
+ EXPECT_TRUE(absl::HasAbslStringify<TypeWithAbslStringify>::value);
+}
+
+} // namespace
diff --git a/absl/strings/internal/has_absl_stringify.h b/absl/strings/internal/has_absl_stringify.h
index 55a08508..5eaddad1 100644
--- a/absl/strings/internal/has_absl_stringify.h
+++ b/absl/strings/internal/has_absl_stringify.h
@@ -18,31 +18,20 @@
#include <type_traits>
#include <utility>
-#include "absl/strings/string_view.h"
+#include "absl/base/attributes.h"
+#include "absl/strings/has_absl_stringify.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace strings_internal {
-// This is an empty class not intended to be used. It exists so that
-// `HasAbslStringify` can reference a universal class rather than needing to be
-// copied for each new sink.
-class UnimplementedSink {
- public:
- void Append(size_t count, char ch);
-
- void Append(string_view v);
-
- // Support `absl::Format(&sink, format, args...)`.
- friend void AbslFormatFlush(UnimplementedSink* sink, absl::string_view v);
-};
-
template <typename T, typename = void>
-struct HasAbslStringify : std::false_type {};
+struct ABSL_DEPRECATED("Use absl::HasAbslStringify") HasAbslStringify
+ : std::false_type {};
template <typename T>
-struct HasAbslStringify<
+struct ABSL_DEPRECATED("Use absl::HasAbslStringify") HasAbslStringify<
T, std::enable_if_t<std::is_void<decltype(AbslStringify(
std::declval<strings_internal::UnimplementedSink&>(),
std::declval<const T&>()))>::value>> : std::true_type {};
diff --git a/absl/strings/internal/str_format/arg.h b/absl/strings/internal/str_format/arg.h
index 3ce30feb..2e017549 100644
--- a/absl/strings/internal/str_format/arg.h
+++ b/absl/strings/internal/str_format/arg.h
@@ -31,7 +31,7 @@
#include "absl/base/port.h"
#include "absl/meta/type_traits.h"
#include "absl/numeric/int128.h"
-#include "absl/strings/internal/has_absl_stringify.h"
+#include "absl/strings/has_absl_stringify.h"
#include "absl/strings/internal/str_format/extension.h"
#include "absl/strings/string_view.h"
@@ -333,7 +333,7 @@ IntegralConvertResult FormatConvertImpl(T v, FormatConversionSpecImpl conv,
template <typename T>
typename std::enable_if<std::is_enum<T>::value &&
!HasUserDefinedConvert<T>::value &&
- !strings_internal::HasAbslStringify<T>::value,
+ !HasAbslStringify<T>::value,
IntegralConvertResult>::type
FormatConvertImpl(T v, FormatConversionSpecImpl conv, FormatSinkImpl* sink);
@@ -447,7 +447,7 @@ class FormatArgImpl {
struct DecayType {
static constexpr bool kHasUserDefined =
str_format_internal::HasUserDefinedConvert<T>::value ||
- strings_internal::HasAbslStringify<T>::value;
+ HasAbslStringify<T>::value;
using type = typename std::conditional<
!kHasUserDefined && std::is_convertible<T, const char*>::value,
const char*,
@@ -456,11 +456,10 @@ class FormatArgImpl {
VoidPtr, const T&>::type>::type;
};
template <typename T>
- struct DecayType<T,
- typename std::enable_if<
- !str_format_internal::HasUserDefinedConvert<T>::value &&
- !strings_internal::HasAbslStringify<T>::value &&
- std::is_enum<T>::value>::type> {
+ struct DecayType<
+ T, typename std::enable_if<
+ !str_format_internal::HasUserDefinedConvert<T>::value &&
+ !HasAbslStringify<T>::value && std::is_enum<T>::value>::type> {
using type = decltype(+typename std::underlying_type<T>::type());
};
diff --git a/absl/strings/str_cat.h b/absl/strings/str_cat.h
index 554c89de..e7823683 100644
--- a/absl/strings/str_cat.h
+++ b/absl/strings/str_cat.h
@@ -102,7 +102,7 @@
#include "absl/base/attributes.h"
#include "absl/base/port.h"
#include "absl/meta/type_traits.h"
-#include "absl/strings/internal/has_absl_stringify.h"
+#include "absl/strings/has_absl_stringify.h"
#include "absl/strings/internal/resize_uninitialized.h"
#include "absl/strings/internal/stringify_sink.h"
#include "absl/strings/numbers.h"
@@ -357,7 +357,7 @@ class AlphaNum {
: piece_(pc) {}
template <typename T, typename = typename std::enable_if<
- strings_internal::HasAbslStringify<T>::value>::type>
+ HasAbslStringify<T>::value>::type>
AlphaNum( // NOLINT(runtime/explicit)
const T& v ABSL_ATTRIBUTE_LIFETIME_BOUND,
strings_internal::StringifySink&& sink ABSL_ATTRIBUTE_LIFETIME_BOUND = {})
@@ -384,17 +384,17 @@ class AlphaNum {
template <typename T,
typename = typename std::enable_if<
std::is_enum<T>{} && std::is_convertible<T, int>{} &&
- !strings_internal::HasAbslStringify<T>::value>::type>
+ !HasAbslStringify<T>::value>::type>
AlphaNum(T e) // NOLINT(runtime/explicit)
: AlphaNum(+e) {}
// This overload matches scoped enums. We must explicitly cast to the
// underlying type, but use integral promotion for the same reason as above.
template <typename T,
- typename std::enable_if<
- std::is_enum<T>{} && !std::is_convertible<T, int>{} &&
- !strings_internal::HasAbslStringify<T>::value,
- char*>::type = nullptr>
+ typename std::enable_if<std::is_enum<T>{} &&
+ !std::is_convertible<T, int>{} &&
+ !HasAbslStringify<T>::value,
+ char*>::type = nullptr>
AlphaNum(T e) // NOLINT(runtime/explicit)
: AlphaNum(+static_cast<typename std::underlying_type<T>::type>(e)) {}
diff --git a/absl/strings/substitute.h b/absl/strings/substitute.h
index d6a5a690..0d6cb7c7 100644
--- a/absl/strings/substitute.h
+++ b/absl/strings/substitute.h
@@ -176,7 +176,7 @@ class Arg {
: piece_(value ? "true" : "false") {}
template <typename T, typename = typename std::enable_if<
- strings_internal::HasAbslStringify<T>::value>::type>
+ HasAbslStringify<T>::value>::type>
Arg( // NOLINT(google-explicit-constructor)
const T& v, strings_internal::StringifySink&& sink = {})
: piece_(strings_internal::ExtractStringification(sink, v)) {}
@@ -204,7 +204,7 @@ class Arg {
template <typename T,
typename = typename std::enable_if<
std::is_enum<T>{} && !std::is_convertible<T, int>{} &&
- !strings_internal::HasAbslStringify<T>::value>::type>
+ !HasAbslStringify<T>::value>::type>
Arg(T value) // NOLINT(google-explicit-constructor)
: Arg(static_cast<typename std::underlying_type<T>::type>(value)) {}