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.