Assume a tuple should be output in a comma-separated form:
#include <iostream>
#include <tuple>
template <typename TupleT, std::size_t... Is>
void printTupleImp(const TupleT& tp, std::index_sequence<Is...>) {
size_t index = 0;
std::cout << "(";
( ((index++ > 0 ? (std::cout << ", ", true) : true),
void(std::cout << std::get<Is>(tp))), ... );
std::cout << ")";
}
template <typename TupleT, std::size_t TupSize = std::tuple_size_v<TupleT>>
void printTuple(const TupleT& tp) {
printTupleImp(tp, std::make_index_sequence<TupSize>{});
}
int main() {
std::tuple tp { 10, 20, "hello"};
printTuple(tp);
}
Output: (10, 20, hello)
It looks like optimization of fold-expression went quite efficiently Compiler Explorer.
Is there a way to do the same using solely fmt instead of doing it by outputting to an ostream first, like here?
If that involves fmt::formatter specialization, how would one generate a format string?
Recent versions of fmt (specifically, fmt 6.0.0 and upwards) support formatting of ranges and tuples. See Range and Tuple Formatting in the documentation.
#include <fmt/ranges.h>
int main() {
std::tuple tp { 10, 20, "hello"};
// Prints "(10, 20, "hello")"
fmt::print("{}", tp);
}
If you want to heavily customize the formatting of a tuple or if you're working with a very old version of fmt, you can also emulate it as follows:
template <typename TupleT, std::size_t... Is>
void printTupleImp(const TupleT& tp, std::index_sequence<Is...>) {
int index = 0;
fmt::print("(");
( (fmt::print(index++ > 0 ? ", {}" : "{}", std::get<Is>(tp))), ... );
fmt::print(")");
}
See live example at Compiler Explorer.
If you want a custom formatter that does this instead, you can look into recent versions of fmt and copy one from there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With