1111
1212namespace node {
1313
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+
1427struct ToStringHelper {
1528 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 ();
2032 }
33+ template <typename T>
34+ requires StringViewConvertible<T>
35+ static std::string_view Convert (const T& value) {
36+ return value.ToStringView ();
37+ }
38+
2139 template <typename T,
2240 typename test_for_number = typename std::
2341 enable_if<std::is_arithmetic<T>::value, bool >::type,
2442 typename dummy = bool >
2543 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) {
2745 return value != nullptr ? value : " (null)" ;
2846 }
2947 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; }
3349 static std::string Convert (bool value) { return value ? " true" : " false" ; }
3450 template <unsigned BASE_BITS,
3551 typename T,
@@ -50,18 +66,23 @@ struct ToStringHelper {
5066 template <unsigned BASE_BITS,
5167 typename T,
5268 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) {
5470 return Convert (std::forward<T>(value));
5571 }
5672};
5773
5874template <typename T>
59- std::string ToString (const T& value) {
75+ auto ToStringOrStringView (const T& value) {
6076 return ToStringHelper::Convert (value);
6177}
6278
79+ template <typename T>
80+ std::string ToString (const T& value) {
81+ return std::string (ToStringOrStringView (value));
82+ }
83+
6384template <unsigned BASE_BITS, typename T>
64- std::string ToBaseString (const T& value) {
85+ auto ToBaseString (const T& value) {
6586 return ToStringHelper::BaseConvert<BASE_BITS>(value);
6687}
6788
@@ -106,7 +127,7 @@ std::string COLD_NOINLINE SPrintFImpl( // NOLINT(runtime/string)
106127 case ' i' :
107128 case ' u' :
108129 case ' s' :
109- ret += ToString (arg);
130+ ret += ToStringOrStringView (arg);
110131 break ;
111132 case ' o' :
112133 ret += ToBaseString<3 >(arg);
0 commit comments