From e7917bbdfbdcccdf5516910709f60f245830c59c Mon Sep 17 00:00:00 2001 From: Markus Mittendrein Date: Tue, 22 Mar 2022 21:29:06 +0100 Subject: Fix compile time formatters for use with 0 arguments --- include/cxxformat/core.hpp | 53 ++++++++++++++++++++++++---------------------- main.cpp | 2 ++ 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/include/cxxformat/core.hpp b/include/cxxformat/core.hpp index 662f4f8..43b3c41 100644 --- a/include/cxxformat/core.hpp +++ b/include/cxxformat/core.hpp @@ -486,33 +486,36 @@ namespace format { const auto out = make_output(std::forward(output)); const auto format_arg = [&args..., &out](holder) -> decltype(auto) { - optional_int minWidth = spec.minWidth; - if constexpr (spec.flags.widthAsArg) + if constexpr (sizeof...(Args) > 0) { - using Arg = std::decay_t>; - static_assert(std::unsigned_integral, "Width argument must be an unsigned integral"); - static_assert(sizeof(Arg) <= sizeof(std::size_t), "Width argument type must be at most as big as std::size_t"); - minWidth = nth_argument<*spec.minWidth>(std::forward(args)...); + optional_int minWidth = spec.minWidth; + if constexpr (spec.flags.widthAsArg) + { + using Arg = std::decay_t>; + static_assert(std::unsigned_integral, "Width argument must be an unsigned integral"); + static_assert(sizeof(Arg) <= sizeof(std::size_t), "Width argument type must be at most as big as std::size_t"); + minWidth = nth_argument<*spec.minWidth>(std::forward(args)...); + } + optional_int precision = spec.precision; + if constexpr (spec.flags.precisionAsArg) + { + using Arg = std::decay_t>; + static_assert(std::unsigned_integral, "Precision argument must be an unsigned integral"); + static_assert(sizeof(Arg) <= sizeof(std::size_t), "Precision argument type must be at most as big as std::size_t"); + precision = nth_argument<*spec.precision>(std::forward(args)...); + } + + using Arg = nth_type; + Arg&& arg = nth_argument(std::forward(args)...); + using formatter = formatter_with_fallback>; + + []() consteval { + // throws on error + formatter::conversionSupported(spec); + }(); + + return formatter::format(out, std::forward(arg), spec, minWidth, precision); } - optional_int precision = spec.precision; - if constexpr (spec.flags.precisionAsArg) - { - using Arg = std::decay_t>; - static_assert(std::unsigned_integral, "Precision argument must be an unsigned integral"); - static_assert(sizeof(Arg) <= sizeof(std::size_t), "Precision argument type must be at most as big as std::size_t"); - precision = nth_argument<*spec.precision>(std::forward(args)...); - } - - using Arg = nth_type; - Arg&& arg = nth_argument(std::forward(args)...); - using formatter = formatter_with_fallback>; - - []() consteval { - // throws on error - formatter::conversionSupported(spec); - }(); - - return formatter::format(out, std::forward(arg), spec, minWidth, precision); }; (([&]{ diff --git a/main.cpp b/main.cpp index 849face..17a1f64 100644 --- a/main.cpp +++ b/main.cpp @@ -30,6 +30,8 @@ int main(int argc, char* argv[]) format_to("Hallo %%du %1$s %s%c %s %u = %4$#x = %4$#X = %4$#o %f!\n", std::cout, "Knirp", 's', argv[0], 42u, 1.337); assert(format("Hallo %%du %1$s %s%c %s %u = %4$#x = %4$#X = %4$#o %f!\n", "Knirp", 's', argv[0], 42u, 1.337) == "Hallo %%du %1$s %s%c %s %u = %4$#x = %4$#X = %4$#o %f!\n"_format("Knirp", 's', argv[0], 42u, 1.337)); + "Hallo\n"_format_to(stdout); + format_to("Hallo\n", stdout); "-%20s-\n"_format_to(stdout, "Hallo"); "-%'20s-\n"_format_to(stdout, R"(H\"all"o)"); "-%'-20s-\n"_format_to(stdout, R"(H\"all"o)"); -- cgit v1.2.3-54-g00ecf