From f445c0c0a4b31918c4bd61aa90e41b471645339f Mon Sep 17 00:00:00 2001 From: Dup4 Date: Tue, 28 Jun 2022 21:31:48 +0800 Subject: [PATCH] feat: support operator<< --- .vscode/settings.json | 1 + include/snapshot/internal/string_utility.h | 33 ++++++++++--------- .../has_class_internal_to_string.h | 26 +++++++++++++++ .../types_check/has_global_to_string.h | 26 +++++++++++++++ .../types_check/has_operator_stream.h | 27 +++++++++++++++ .../snapshot/types_check/has_std_to_string.h | 27 +++++++++++++++ test/internal/string_utility_test.cc | 18 +++------- test/snapshot_test.cc | 2 +- 8 files changed, 130 insertions(+), 30 deletions(-) create mode 100644 include/snapshot/types_check/has_class_internal_to_string.h create mode 100644 include/snapshot/types_check/has_global_to_string.h create mode 100644 include/snapshot/types_check/has_operator_stream.h create mode 100644 include/snapshot/types_check/has_std_to_string.h diff --git a/.vscode/settings.json b/.vscode/settings.json index 1fb3e69..0296d44 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -117,6 +117,7 @@ "cSpell.words": [ "cmake", "codecov", + "declval", "GCOVR", "jwlawson", "pnpm" diff --git a/include/snapshot/internal/string_utility.h b/include/snapshot/internal/string_utility.h index 5965095..5673e39 100644 --- a/include/snapshot/internal/string_utility.h +++ b/include/snapshot/internal/string_utility.h @@ -6,33 +6,34 @@ #include #include +#include "../types_check/has_class_internal_to_string.h" +#include "../types_check/has_global_to_string.h" +#include "../types_check/has_operator_stream.h" +#include "../types_check/has_std_to_string.h" + namespace snapshot { class StringUtility { friend class StringUtilityTest; public: - template - class HasStdToString { - private: - template - static auto check(int) -> decltype(std::to_string(std::declval()), std::true_type()); - - template - static std::false_type check(...); - - public: - enum { value = std::is_same(0)), std::true_type>::value }; - }; - -public: - template ::value, bool> = true> + template , bool> = true> static std::string ToString(const T& t) { return std::to_string(t); } - template ::value, bool> = true> + template , bool> = true> static std::string ToString(const T& t) { + return to_string(t); + } + + template , bool> = true> + static std::string ToString(const T& t) { + return t.ToString(); + } + + template , bool> = true> + static std::string ToString([[maybe_unused]] const T& t) { std::stringstream ss; std::string s; ss << t; diff --git a/include/snapshot/types_check/has_class_internal_to_string.h b/include/snapshot/types_check/has_class_internal_to_string.h new file mode 100644 index 0000000..94d7c5a --- /dev/null +++ b/include/snapshot/types_check/has_class_internal_to_string.h @@ -0,0 +1,26 @@ +#ifndef SNAPSHOT_INTERNAL_TYPES_CHECK_HAS_CLASS_INTERNAL_TO_STRING_H_ +#define SNAPSHOT_INTERNAL_TYPES_CHECK_HAS_CLASS_INTERNAL_TO_STRING_H_ + +#include + +namespace snapshot::internal { + +template +class has_class_internal_to_string { +private: + template + static auto check(int) -> decltype(std::declval().ToString(), std::true_type()); + + template + static std::false_type check(...); + +public: + enum { value = std::is_same(0)), std::true_type>::value }; +}; + +template +inline constexpr bool has_class_internal_to_string_v = has_class_internal_to_string::value; + +} // namespace snapshot::internal + +#endif // SNAPSHOT_INTERNAL_TYPES_CHECK_HAS_CLASS_INTERNAL_TO_STRING_H_ diff --git a/include/snapshot/types_check/has_global_to_string.h b/include/snapshot/types_check/has_global_to_string.h new file mode 100644 index 0000000..76e578f --- /dev/null +++ b/include/snapshot/types_check/has_global_to_string.h @@ -0,0 +1,26 @@ +#ifndef SNAPSHOT_INTERNAL_TYPES_CHECK_HAS_GLOBAL_TO_STRING_H_ +#define SNAPSHOT_INTERNAL_TYPES_CHECK_HAS_GLOBAL_TO_STRING_H_ + +#include + +namespace snapshot::internal { + +template +class has_global_to_string { +private: + template + static auto check(int) -> decltype(to_string(std::declval()), std::true_type()); + + template + static std::false_type check(...); + +public: + enum { value = std::is_same(0)), std::true_type>::value }; +}; + +template +inline constexpr bool has_global_to_string_v = has_global_to_string::value; + +} // namespace snapshot::internal + +#endif // SNAPSHOT_INTERNAL_TYPES_CHECK_HAS_GLOBAL_TO_STRING_H_ diff --git a/include/snapshot/types_check/has_operator_stream.h b/include/snapshot/types_check/has_operator_stream.h new file mode 100644 index 0000000..c056479 --- /dev/null +++ b/include/snapshot/types_check/has_operator_stream.h @@ -0,0 +1,27 @@ +#ifndef SNAPSHOT_INTERNAL_TYPES_CHECK_HAS_OPERATOR_STREAM_H_ +#define SNAPSHOT_INTERNAL_TYPES_CHECK_HAS_OPERATOR_STREAM_H_ + +#include +#include + +namespace snapshot::internal { + +template +class has_operator_stream { +private: + template + static auto check(int) -> decltype(operator<<(std::cout, std::declval()), std::true_type()); + + template + static std::false_type check(...); + +public: + enum { value = std::is_same(0)), std::true_type>::value }; +}; + +template +inline constexpr bool has_operator_stream_v = has_operator_stream::value; + +} // namespace snapshot::internal + +#endif // SNAPSHOT_INTERNAL_TYPES_CHECK_HAS_OPERATOR_STREAM_H_ diff --git a/include/snapshot/types_check/has_std_to_string.h b/include/snapshot/types_check/has_std_to_string.h new file mode 100644 index 0000000..197ab9f --- /dev/null +++ b/include/snapshot/types_check/has_std_to_string.h @@ -0,0 +1,27 @@ +#ifndef SNAPSHOT_TYPES_CHECK_HAS_STD_TO_STRING_H +#define SNAPSHOT_TYPES_CHECK_HAS_STD_TO_STRING_H + +#include +#include + +namespace snapshot::internal { + +template +class has_std_to_string { +private: + template + static auto check(int) -> decltype(std::to_string(std::declval()), std::true_type()); + + template + static std::false_type check(...); + +public: + enum { value = std::is_same(0)), std::true_type>::value }; +}; + +template +inline constexpr bool has_std_to_string_v = has_std_to_string::value; + +} // namespace snapshot::internal + +#endif // SNAPSHOT_TYPES_CHECK_HAS_STD_TO_STRING_H diff --git a/test/internal/string_utility_test.cc b/test/internal/string_utility_test.cc index e79c656..b3261e7 100644 --- a/test/internal/string_utility_test.cc +++ b/test/internal/string_utility_test.cc @@ -1,10 +1,12 @@ -#include +#include "gtest/gtest.h" + #include #include -using namespace std; +#include "snapshot/snapshot.h" -namespace snapshot { +using namespace std; +using namespace snapshot; class StringUtilityTest : public testing::Test { public: @@ -29,20 +31,10 @@ class CustomToString1 { int z; }; -} // namespace snapshot - -using namespace snapshot; - -namespace std { - string to_string(const CustomToString1& c) { return to_string(c.x) + " " + to_string(c.y) + " " + to_string(c.z) + "\n"; } -} // namespace std - -#include "snapshot/snapshot.h" - TEST_F(StringUtilityTest, to_string) { EXPECT_EQ(StringUtility::ToString(numeric_limits::min()), std::string("-2147483648")); EXPECT_EQ(StringUtility::ToString(numeric_limits::max()), std::string("2147483647")); diff --git a/test/snapshot_test.cc b/test/snapshot_test.cc index 1aed6e0..1c299dd 100644 --- a/test/snapshot_test.cc +++ b/test/snapshot_test.cc @@ -40,7 +40,7 @@ TEST_F(SnapshotTest, example) { RawString r; r.s = snapshot_inline; - SNAPSHOT_INLINE(r); + SNAPSHOT(r); SNAPSHOT_DIFF(a, b); }