简体   繁体   English

使用 fmt 格式化提升多精度 cpp_int

[英]format boost multiprecision cpp_int with fmt

I'm trying to format a boost multiprecision cpp_int using fmt library.我正在尝试使用 fmt 库格式化 boost 多精度 cpp_int。

Here's the code I tried这是我试过的代码

using boost::multiprecision::cpp_int;

int main() {
    cpp_int v("0x8FFFFFFFFFFFFFFFF");
    std::string buffer;   
    fmt::format_to(std::back_inserter(buffer),"{}", v);
    std::cout << buffer;
}

https://godbolt.org/z/M4zKc5hr6 using boost 1.73, fmt 9.1, gcc 7.3 https://godbolt.org/z/M4zKc5hr6使用 boost 1.73,fmt 9.1,gcc 7.3

I'm getting compilation error:我收到编译错误:

error: static assertion failed: Cannot format an argument.错误:static 断言失败:无法格式化参数。 To make type T formattable provide a formatter specialization使类型 T 可格式化提供格式化程序专业化

I stumbled upon this issue https://github.com/fmtlib/fmt/issues/918 that seems to be resolved, so I was expecting fmt to be able to format boost multiprecision numbers.我偶然发现这个问题https://github.com/fmtlib/fmt/issues/918似乎已经解决了,所以我期待 fmt 能够格式化提升多精度数字。 Do I still need to write a formatter specialization?我还需要编写格式化程序专业化吗?

You need to provide a formatter.您需要提供格式化程序。 Eg you can opt-in to the ostream formatter:例如,您可以选择加入 ostream 格式化程序:

template <> struct fmt::formatter<cpp_int> : fmt::ostream_formatter {};

Live demo: Live On Coliru现场演示: Live On Coliru

#include <boost/multiprecision/cpp_int.hpp>
#include <fmt/format.h>
#include <fmt/ostream.h>
using boost::multiprecision::cpp_int;

template <> struct fmt::formatter<cpp_int> : fmt::ostream_formatter {};

int main() {
    cpp_int v("0x8FFFFFFFFFFFFFFFF");

    std::string buffer;
    fmt::format_to(std::back_inserter(buffer), "Hello world: {}", v);

    fmt::print("Print directly: {} (buffer: {})", v, buffer);
}

Outputs:输出:

Print directly: 166020696663385964543 (buffer: Hello world: 166020696663385964543)

BONUS: Hex, showbase, lower/uppercase奖励:十六进制、showbase、小写/大写

Demonstrating a simple custom formatter that invokes i.str(...) with the required formatting parameters:演示一个简单的自定义格式化程序,它使用所需的格式化参数调用i.str(...)

Live On Coliru生活在 Coliru

#include <boost/multiprecision/cpp_int.hpp>
#include <fmt/format.h>
using boost::multiprecision::cpp_int;

template <> struct fmt::formatter<cpp_int> {
    uint8_t showbase_ : 1 = 0, hex_ : 1 = 0, upper_ : 1 = 0;

    auto constexpr parse(auto& ctx) {
        auto e = std::find(ctx.begin(), ctx.end(), '}');
        if (std::string_view f{ctx.begin(), e}; f == "#x")
            showbase_ = hex_ = true;
        else if (f == "#X")
            showbase_ = hex_ = upper_ = true;
        else {
            hex_   = (f == "x") || (f == "X");
            upper_ = (f == "X");
        }
        return e;
    }

    auto format(cpp_int const& i, auto& ctx) {
        auto f = hex_ ? std::ios::hex : std::ios::dec;
        if (showbase_) f |= std::ios::showbase;
        if (upper_)    f |= std::ios::uppercase;
        auto s = i.str(0, f);
        return std::copy(s.begin(), s.end(), ctx.out());
    }
};

int main() {{
    cpp_int v("0x8FFFFFFFFFFFFFFFF");

    fmt::print("{{}}:    {}\n", v);
    fmt::print("{{:}}:   {:}\n", v);
    fmt::print("{{:x}}:  {:x}\n", v);
    fmt::print("{{:#x}}: {:#x}\n", v);
    fmt::print("{{:X}}:  {:X}\n", v);
    fmt::print("{{:#X}}: {:#X}\n", v);
}}

Prints印刷

{}:    166020696663385964543
{:}:   166020696663385964543
{:x}:  8ffffffffffffffff
{:#x}: 0x8ffffffffffffffff
{:X}:  8FFFFFFFFFFFFFFFF
{:#X}: 0X8FFFFFFFFFFFFFFFF

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM