Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 33 additions & 12 deletions src/debug_utils-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,41 @@

namespace node {

template <typename T>
concept StringViewConvertible = requires(T a) {
{
a.ToStringView()
} -> std::convertible_to<std::string_view>;
};
template <typename T>
concept StringConvertible = requires(T a) {
{
a.ToString()
} -> std::convertible_to<std::string>;
};

struct ToStringHelper {
template <typename T>
static std::string Convert(
const T& value,
std::string(T::* to_string)() const = &T::ToString) {
return (value.*to_string)();
requires(StringConvertible<T>) && (!StringViewConvertible<T>)
static std::string Convert(const T& value) {
return value.ToString();
}
template <typename T>
requires StringViewConvertible<T>
static std::string_view Convert(const T& value) {
return value.ToStringView();
}

template <typename T,
typename test_for_number = typename std::
enable_if<std::is_arithmetic<T>::value, bool>::type,
typename dummy = bool>
static std::string Convert(const T& value) { return std::to_string(value); }
static std::string Convert(const char* value) {
static std::string_view Convert(const char* value) {
return value != nullptr ? value : "(null)";
}
static std::string Convert(const std::string& value) { return value; }
static std::string Convert(std::string_view value) {
return std::string(value);
}
static std::string_view Convert(std::string_view value) { return value; }
static std::string Convert(bool value) { return value ? "true" : "false"; }
template <unsigned BASE_BITS,
typename T,
Expand All @@ -50,18 +66,23 @@ struct ToStringHelper {
template <unsigned BASE_BITS,
typename T,
typename = std::enable_if_t<!std::is_integral_v<T>>>
static std::string BaseConvert(T& value) { // NOLINT(runtime/references)
static auto BaseConvert(T&& value) {
return Convert(std::forward<T>(value));
}
};

template <typename T>
std::string ToString(const T& value) {
auto ToStringOrStringView(const T& value) {
return ToStringHelper::Convert(value);
}

template <typename T>
std::string ToString(const T& value) {
return std::string(ToStringOrStringView(value));
}

template <unsigned BASE_BITS, typename T>
std::string ToBaseString(const T& value) {
auto ToBaseString(const T& value) {
return ToStringHelper::BaseConvert<BASE_BITS>(value);
}

Expand Down Expand Up @@ -97,7 +118,7 @@ std::string COLD_NOINLINE SPrintFImpl( // NOLINT(runtime/string)
case 'i':
case 'u':
case 's':
ret += ToString(arg);
ret += ToStringOrStringView(arg);
break;
case 'o':
ret += ToBaseString<3>(arg);
Expand Down
2 changes: 2 additions & 0 deletions src/debug_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class Environment;

template <typename T>
inline std::string ToString(const T& value);
template <typename T>
inline auto ToStringOrStringView(const T& value);

// C++-style variant of sprintf()/fprintf() that:
// - Returns an std::string
Expand Down
24 changes: 16 additions & 8 deletions src/util-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,21 +194,29 @@ char ToLower(char c) {
return std::tolower(c, std::locale::classic());
}

std::string ToLower(const std::string& in) {
std::string out(in.size(), 0);
for (size_t i = 0; i < in.size(); ++i)
out[i] = ToLower(in[i]);
template <typename T>
std::string ToLower(const T& in) {
auto it = std::cbegin(in);
auto end = std::cend(in);
std::string out(std::distance(it, end), 0);
size_t i;
for (i = 0; it != end; ++it, ++i) out[i] = ToLower(*it);
DCHECK_EQ(i, out.size());
return out;
}

char ToUpper(char c) {
return std::toupper(c, std::locale::classic());
}

std::string ToUpper(const std::string& in) {
std::string out(in.size(), 0);
for (size_t i = 0; i < in.size(); ++i)
out[i] = ToUpper(in[i]);
template <typename T>
std::string ToUpper(const T& in) {
auto it = std::cbegin(in);
auto end = std::cend(in);
std::string out(std::distance(it, end), 0);
size_t i;
for (i = 0; it != end; ++it, ++i) out[i] = ToUpper(*it);
DCHECK_EQ(i, out.size());
return out;
}

Expand Down
6 changes: 4 additions & 2 deletions src/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -366,11 +366,13 @@ inline v8::Local<v8::String> FIXED_ONE_BYTE_STRING(v8::Isolate* isolate,

// tolower() is locale-sensitive. Use ToLower() instead.
inline char ToLower(char c);
inline std::string ToLower(const std::string& in);
template <typename T>
inline std::string ToLower(const T& in);

// toupper() is locale-sensitive. Use ToUpper() instead.
inline char ToUpper(char c);
inline std::string ToUpper(const std::string& in);
template <typename T>
inline std::string ToUpper(const T& in);

// strcasecmp() is locale-sensitive. Use StringEqualNoCase() instead.
inline bool StringEqualNoCase(const char* a, const char* b);
Expand Down
Loading