Fmt: Question: How to elegantly format vector of integer

Created on 7 Sep 2020  路  2Comments  路  Source: fmtlib/fmt

I have read through the doc, but have found an elegant solution.

Input:

std::vector vec{1, 2, 16};

Expected output:

"0x1 0x2 0x10"

I think it may be achieved by combine join and format, but it seems that the current API doesn't support this kind of usage, thanks!

Most helpful comment

It can be easily done using join:

#include <vector>
#include <fmt/format.h>

int main () {
  std::vector vec{1, 2, 16};
  fmt::print("{:#x}", fmt::join(vec, " "));
}

Output:

0x1 0x2 0x10

Godbolt: https://godbolt.org/z/7Y3xs5

All 2 comments

Not really elegant but this works, doesn't do uppercase formatting eg. 0XA1, but I think
it can be achieved with an enum + switch

#include <fmt/format.h>
#include <vector>

template<>
struct fmt::formatter<std::vector<int>>
{
    bool hex {false};

    constexpr auto parse(format_parse_context& ctx)
    {
        auto it = ctx.begin();
        const auto end = ctx.end();

        if(it != end && *it == 'x')
        {
            hex = true;
            ++it;
        }

        if(it != end && *it != '}')
            throw format_error("invalid format");

        return it;
    }

    template<typename FormatContext>
    auto format(const std::vector<int>& vec, FormatContext& fc)
    {
        format_to(fc.out(), "[");
        for(auto it = vec.cbegin(); it != vec.cend() - 1; ++it)
        {
            format_to(fc.out(), hex ? "{:#x}, " : "{}, ", *it);
        }
        return format_to(fc.out(), hex ? "{:#x}]" : "{}]", vec.back());
    }
};

int main()
{
    std::vector nums {18, 47, 128, 10};
    fmt::print("{}\n", nums);
    fmt::print("{:x}\n", nums);
}

Output:

[18, 47, 128, 10]
[0x12, 0x2f, 0x80, 0xa]

The int may be templated in the struct definition.

Also replacing the ternary with an if-else might look better

It can be easily done using join:

#include <vector>
#include <fmt/format.h>

int main () {
  std::vector vec{1, 2, 16};
  fmt::print("{:#x}", fmt::join(vec, " "));
}

Output:

0x1 0x2 0x10

Godbolt: https://godbolt.org/z/7Y3xs5

Was this page helpful?
0 / 5 - 0 ratings

Related issues

arthurdead picture arthurdead  路  12Comments

gabime picture gabime  路  12Comments

cjdb picture cjdb  路  13Comments

abrownsword picture abrownsword  路  15Comments

christhomas picture christhomas  路  12Comments