diff options
| -rw-r--r-- | include/cxxformat/core.hpp | 53 | ||||
| -rw-r--r-- | 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>(output)); const auto format_arg = [&args..., &out]<format_specifier spec>(holder<spec>) -> decltype(auto) { - optional_int<std::size_t> minWidth = spec.minWidth; - if constexpr (spec.flags.widthAsArg) + if constexpr (sizeof...(Args) > 0) { - using Arg = std::decay_t<nth_type<*spec.minWidth, Args...>>; - static_assert(std::unsigned_integral<Arg>, "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>(args)...); + optional_int<std::size_t> minWidth = spec.minWidth; + if constexpr (spec.flags.widthAsArg) + { + using Arg = std::decay_t<nth_type<*spec.minWidth, Args...>>; + static_assert(std::unsigned_integral<Arg>, "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>(args)...); + } + optional_int<std::size_t> precision = spec.precision; + if constexpr (spec.flags.precisionAsArg) + { + using Arg = std::decay_t<nth_type<*spec.precision, Args...>>; + static_assert(std::unsigned_integral<Arg>, "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>(args)...); + } + + using Arg = nth_type<spec.argIndex, Args...>; + Arg&& arg = nth_argument<spec.argIndex>(std::forward<Args>(args)...); + using formatter = formatter_with_fallback<std::decay_t<Arg>>; + + []() consteval { + // throws on error + formatter::conversionSupported(spec); + }(); + + return formatter::format(out, std::forward<Arg>(arg), spec, minWidth, precision); } - optional_int<std::size_t> precision = spec.precision; - if constexpr (spec.flags.precisionAsArg) - { - using Arg = std::decay_t<nth_type<*spec.precision, Args...>>; - static_assert(std::unsigned_integral<Arg>, "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>(args)...); - } - - using Arg = nth_type<spec.argIndex, Args...>; - Arg&& arg = nth_argument<spec.argIndex>(std::forward<Args>(args)...); - using formatter = formatter_with_fallback<std::decay_t<Arg>>; - - []() consteval { - // throws on error - formatter::conversionSupported(spec); - }(); - - return formatter::format(out, std::forward<Arg>(arg), spec, minWidth, precision); }; (([&]{ @@ -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)"); |
