Skip to content

Commit

Permalink
feat: support operator<<
Browse files Browse the repository at this point in the history
  • Loading branch information
Dup4 committed Jun 28, 2022
1 parent 1095b44 commit f445c0c
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 30 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
"cSpell.words": [
"cmake",
"codecov",
"declval",
"GCOVR",
"jwlawson",
"pnpm"
Expand Down
33 changes: 17 additions & 16 deletions include/snapshot/internal/string_utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,34 @@
#include <type_traits>
#include <vector>

#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 <typename T>
class HasStdToString {
private:
template <typename U>
static auto check(int) -> decltype(std::to_string(std::declval<U>()), std::true_type());

template <typename U>
static std::false_type check(...);

public:
enum { value = std::is_same<decltype(check<T>(0)), std::true_type>::value };
};

public:
template <typename T, std::enable_if_t<HasStdToString<T>::value, bool> = true>
template <typename T, std::enable_if_t<internal::has_std_to_string_v<T>, bool> = true>
static std::string ToString(const T& t) {
return std::to_string(t);
}

template <typename T, std::enable_if_t<!HasStdToString<T>::value, bool> = true>
template <typename T, std::enable_if_t<internal::has_global_to_string_v<T>, bool> = true>
static std::string ToString(const T& t) {
return to_string(t);
}

template <typename T, std::enable_if_t<internal::has_class_internal_to_string_v<T>, bool> = true>
static std::string ToString(const T& t) {
return t.ToString();
}

template <typename T, std::enable_if_t<internal::has_operator_stream_v<T>, bool> = true>
static std::string ToString([[maybe_unused]] const T& t) {
std::stringstream ss;
std::string s;
ss << t;
Expand Down
26 changes: 26 additions & 0 deletions include/snapshot/types_check/has_class_internal_to_string.h
Original file line number Diff line number Diff line change
@@ -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 <type_traits>

namespace snapshot::internal {

template <typename T>
class has_class_internal_to_string {
private:
template <typename U>
static auto check(int) -> decltype(std::declval<U>().ToString(), std::true_type());

template <typename U>
static std::false_type check(...);

public:
enum { value = std::is_same<decltype(check<T>(0)), std::true_type>::value };
};

template <typename T>
inline constexpr bool has_class_internal_to_string_v = has_class_internal_to_string<T>::value;

} // namespace snapshot::internal

#endif // SNAPSHOT_INTERNAL_TYPES_CHECK_HAS_CLASS_INTERNAL_TO_STRING_H_
26 changes: 26 additions & 0 deletions include/snapshot/types_check/has_global_to_string.h
Original file line number Diff line number Diff line change
@@ -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 <type_traits>

namespace snapshot::internal {

template <typename T>
class has_global_to_string {
private:
template <typename U>
static auto check(int) -> decltype(to_string(std::declval<U>()), std::true_type());

template <typename U>
static std::false_type check(...);

public:
enum { value = std::is_same<decltype(check<T>(0)), std::true_type>::value };
};

template <typename T>
inline constexpr bool has_global_to_string_v = has_global_to_string<T>::value;

} // namespace snapshot::internal

#endif // SNAPSHOT_INTERNAL_TYPES_CHECK_HAS_GLOBAL_TO_STRING_H_
27 changes: 27 additions & 0 deletions include/snapshot/types_check/has_operator_stream.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef SNAPSHOT_INTERNAL_TYPES_CHECK_HAS_OPERATOR_STREAM_H_
#define SNAPSHOT_INTERNAL_TYPES_CHECK_HAS_OPERATOR_STREAM_H_

#include <iostream>
#include <utility>

namespace snapshot::internal {

template <typename T>
class has_operator_stream {
private:
template <typename U>
static auto check(int) -> decltype(operator<<(std::cout, std::declval<U>()), std::true_type());

template <typename U>
static std::false_type check(...);

public:
enum { value = std::is_same<decltype(check<T>(0)), std::true_type>::value };
};

template <typename T>
inline constexpr bool has_operator_stream_v = has_operator_stream<T>::value;

} // namespace snapshot::internal

#endif // SNAPSHOT_INTERNAL_TYPES_CHECK_HAS_OPERATOR_STREAM_H_
27 changes: 27 additions & 0 deletions include/snapshot/types_check/has_std_to_string.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef SNAPSHOT_TYPES_CHECK_HAS_STD_TO_STRING_H
#define SNAPSHOT_TYPES_CHECK_HAS_STD_TO_STRING_H

#include <string>
#include <type_traits>

namespace snapshot::internal {

template <typename T>
class has_std_to_string {
private:
template <typename U>
static auto check(int) -> decltype(std::to_string(std::declval<U>()), std::true_type());

template <typename U>
static std::false_type check(...);

public:
enum { value = std::is_same<decltype(check<T>(0)), std::true_type>::value };
};

template <typename T>
inline constexpr bool has_std_to_string_v = has_std_to_string<T>::value;

} // namespace snapshot::internal

#endif // SNAPSHOT_TYPES_CHECK_HAS_STD_TO_STRING_H
18 changes: 5 additions & 13 deletions test/internal/string_utility_test.cc
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#include <gtest/gtest.h>
#include "gtest/gtest.h"

#include <iostream>
#include <limits>

using namespace std;
#include "snapshot/snapshot.h"

namespace snapshot {
using namespace std;
using namespace snapshot;

class StringUtilityTest : public testing::Test {
public:
Expand All @@ -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<int>::min()), std::string("-2147483648"));
EXPECT_EQ(StringUtility::ToString(numeric_limits<int>::max()), std::string("2147483647"));
Expand Down
2 changes: 1 addition & 1 deletion test/snapshot_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ TEST_F(SnapshotTest, example) {
RawString r;
r.s = snapshot_inline;

SNAPSHOT_INLINE(r);
SNAPSHOT(r);

SNAPSHOT_DIFF(a, b);
}
Expand Down

0 comments on commit f445c0c

Please sign in to comment.