I would like to know if there is built-in checkers in std
which checks if a type is printable via operator<<
or if it is formattable via std::format
.
I tried to search it and could not find built-in checker to check if operator<<
can be called on a type. I only found std::formattable<T>
and could not figure out how to use it.
I want to use built-in type traits and concepts from std
, I do not want to create my own utility.
What I would like to be able to do is:
template<typename DATA_T>
struct std::formatter<MyClass<DATA_T>> : std::formatter<std::string>
{
static auto format(const MyClass<DATA_T>& my_class, std::format_context& ctx)
{
std::string result = std::format("Name: {}\n", my_class.name());
// Check if the data it holds printable or formattable and add it.
// Should be replaced with correct usage
if constexpr (std::formattable<DATA_T>)
{
result += std::format("Data: {}", my_class.data());
}
// Should be replaced with correct std functionality
else if constexpr (std::ostreambale<DATA_T>)
{
std::ostringstream oss;
oss << my_class.data();
result += "Data: ";
result += oss.str();
}
result += std::format("\nLocation: {}", my_class.location());
return std::format_to(ctx.out(), "{}", result);
}
};
I would like to know if there is built-in checkers in std
which checks if a type is printable via operator<<
or if it is formattable via std::format
.
I tried to search it and could not find built-in checker to check if operator<<
can be called on a type. I only found std::formattable<T>
and could not figure out how to use it.
I want to use built-in type traits and concepts from std
, I do not want to create my own utility.
What I would like to be able to do is:
template<typename DATA_T>
struct std::formatter<MyClass<DATA_T>> : std::formatter<std::string>
{
static auto format(const MyClass<DATA_T>& my_class, std::format_context& ctx)
{
std::string result = std::format("Name: {}\n", my_class.name());
// Check if the data it holds printable or formattable and add it.
// Should be replaced with correct usage
if constexpr (std::formattable<DATA_T>)
{
result += std::format("Data: {}", my_class.data());
}
// Should be replaced with correct std functionality
else if constexpr (std::ostreambale<DATA_T>)
{
std::ostringstream oss;
oss << my_class.data();
result += "Data: ";
result += oss.str();
}
result += std::format("\nLocation: {}", my_class.location());
return std::format_to(ctx.out(), "{}", result);
}
};
Share
Improve this question
edited Mar 15 at 20:12
JeJo
33.5k7 gold badges55 silver badges95 bronze badges
asked Mar 15 at 15:10
sakcakocasakcakoca
1194 bronze badges
2
|
1 Answer
Reset to default 11I tried to search it and could not find built-in checker to check if
operator<<
can be called on a type. I only foundstd::formattable<T>
[...]
Yes, that is correct. For streamability via operator<<
, there is no built-in trait in the standard library; therefore unfortunately, you must define your own check.
// Custom concept to check if a type is streamable via operator<<
template<typename T>
concept OStreamable = requires(std::ostream& os, const T& t)
{
{ os << t } -> std::convertible_to<std::ostream&>;
};
With that update, you might do:
template<typename DATA_T>
struct std::formatter<MyClass<DATA_T>> : std::formatter<std::string>
{
auto format(const MyClass<DATA_T>& my_class, std::format_context& ctx) const
{
std::string result = std::format("Name: {}\n", my_class.name());
// Check if DATA_T is formattable
if constexpr (std::formattable<DATA_T, char>)
{
result += std::format("Data: {}", my_class.data());
}
// Use custom OStreamable concept for streamability
else if constexpr (OStreamable<DATA_T>) {
std::ostringstream oss;
oss << my_class.data();
result += "Data: " + oss.str();
}
result += std::format("\nLocation: {}", my_class.location());
return std::format_to(ctx.out(), "{}", result);
}
};
((See live demo))
formattable
is connected tostd::format
, and has nothing to do withoperator<<
. – BoP Commented Mar 15 at 15:26requires { oss << my_class.data(); }
. – BoP Commented Mar 15 at 15:27