11
11
12
12
namespace node {
13
13
14
+ template <typename T>
15
+ concept StringViewConvertible = requires (T a) {
16
+ {
17
+ a.ToStringView ()
18
+ } -> std::convertible_to<std::string_view>;
19
+ };
20
+ template <typename T>
21
+ concept StringConvertible = requires (T a) {
22
+ {
23
+ a.ToString ()
24
+ } -> std::convertible_to<std::string>;
25
+ };
26
+
14
27
struct ToStringHelper {
15
28
template <typename T>
16
- static std::string Convert (
17
- const T& value,
18
- std::string (T::* to_string)() const = &T::ToString) {
19
- return (value.*to_string)();
29
+ requires (StringConvertible<T>) && (!StringViewConvertible<T>)
30
+ static std::string Convert (const T& value) {
31
+ return value.ToString ();
20
32
}
33
+ template <typename T>
34
+ requires StringViewConvertible<T>
35
+ static std::string_view Convert (const T& value) {
36
+ return value.ToStringView ();
37
+ }
38
+
21
39
template <typename T,
22
40
typename test_for_number = typename std::
23
41
enable_if<std::is_arithmetic<T>::value, bool >::type,
24
42
typename dummy = bool >
25
43
static std::string Convert (const T& value) { return std::to_string (value); }
26
- static std::string Convert (const char * value) {
44
+ static std::string_view Convert (const char * value) {
27
45
return value != nullptr ? value : " (null)" ;
28
46
}
29
47
static std::string Convert (const std::string& value) { return value; }
30
- static std::string Convert (std::string_view value) {
31
- return std::string (value);
32
- }
48
+ static std::string_view Convert (std::string_view value) { return value; }
33
49
static std::string Convert (bool value) { return value ? " true" : " false" ; }
34
50
template <unsigned BASE_BITS,
35
51
typename T,
@@ -50,18 +66,23 @@ struct ToStringHelper {
50
66
template <unsigned BASE_BITS,
51
67
typename T,
52
68
typename = std::enable_if_t <!std::is_integral_v<T>>>
53
- static std::string BaseConvert (T& value) { // NOLINT(runtime/references)
69
+ static auto BaseConvert (T&& value) {
54
70
return Convert (std::forward<T>(value));
55
71
}
56
72
};
57
73
58
74
template <typename T>
59
- std::string ToString (const T& value) {
75
+ auto ToStringOrStringView (const T& value) {
60
76
return ToStringHelper::Convert (value);
61
77
}
62
78
79
+ template <typename T>
80
+ std::string ToString (const T& value) {
81
+ return std::string (ToStringOrStringView (value));
82
+ }
83
+
63
84
template <unsigned BASE_BITS, typename T>
64
- std::string ToBaseString (const T& value) {
85
+ auto ToBaseString (const T& value) {
65
86
return ToStringHelper::BaseConvert<BASE_BITS>(value);
66
87
}
67
88
@@ -106,7 +127,7 @@ std::string COLD_NOINLINE SPrintFImpl( // NOLINT(runtime/string)
106
127
case ' i' :
107
128
case ' u' :
108
129
case ' s' :
109
- ret += ToString (arg);
130
+ ret += ToStringOrStringView (arg);
110
131
break ;
111
132
case ' o' :
112
133
ret += ToBaseString<3 >(arg);
0 commit comments