From b65a703a2ea65a908655b873d1293560bfde9f56 Mon Sep 17 00:00:00 2001 From: Markus Mittendrein Date: Thu, 6 Jan 2022 03:47:39 +0100 Subject: New implementation for compile time format strings (run time format strings not yet) --- main.cpp | 144 +++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 98 insertions(+), 46 deletions(-) (limited to 'main.cpp') diff --git a/main.cpp b/main.cpp index 2431b73..b858b85 100644 --- a/main.cpp +++ b/main.cpp @@ -1,54 +1,106 @@ -#include "cxxformat.hpp" -#include -#include #include +#include -template -struct format::FormatConvert, char>>> +#include "cxxformat/cxxformat.hpp" + +void numberTests() { - template - static std::string accessConvert(const T *from) - { - if constexpr (_N == N) - { - return "}"; - } - else - { - return format::format("%v", from[_N]) + (_N + 1 < N ? ", " : "") + accessConvert<_N + 1>(from); - } - } - - static std::string convert(const T *from) - { - return "array[" + std::to_string(N) + "]{" + accessConvert<0>(from); - } -}; - -template -struct format::FormatConvert> + using format::parseNumber; + static_assert(!parseNumber("", 0).first); + static_assert(!parseNumber("-", 0).first); + static_assert(parseNumber("1", 0).first == 1); + static_assert(parseNumber("10", 0).first == 10); + static_assert(parseNumber("10907", 0).first == 10907); + static_assert(parseNumber("-1", 0).first == -1); + static_assert(parseNumber("-11097", 0).first == -11097); +} + +int main(int argc, char* argv[]) { - static std::string convert(const std::array &from) - { - return format::FormatConvert::convert(from.data()); - } -}; + using namespace format; + "-%20g-\n"_format_to(stdout, 0x1.8p0); + "-%20.0a-\n"_format_to(stdout, 0.0); + "-%#+20.0a-\n"_format_to(stdout, 1.0); + "-%#+20.0e-\n"_format_to(stdout, 1.0); + "-%#+20.0f-\n"_format_to(stdout, 1.0); + "-%#+20.0g-\n"_format_to(stdout, 1.0); + "-%#+20.3g-\n"_format_to(stdout, 1.0); + "-%+20.0a-\n"_format_to(stdout, 1.0); + "-%+20.0e-\n"_format_to(stdout, 1.0); + "-%+20.0f-\n"_format_to(stdout, 1.0); + "-%+20.3g-\n"_format_to(stdout, 1.0); + "-%020.3e-\n"_format_to(stdout, 1.2); + "-%020.3f-\n"_format_to(stdout, 1.2); + "-%020.3g-\n"_format_to(stdout, 1.2); + "-%020.3a-\n"_format_to(stdout, 1.2); + "-%020.3a-\n"_format_to(stdout, -1.2); + "-%20.3a-\n"_format_to(stdout, -1.2); + "-%-20.3a-\n"_format_to(stdout, -1.2); + "-%+020.3a-\n"_format_to(stdout, -1.2); + "-%+020.3a-\n"_format_to(stdout, 1.2); + "-% 020.3a-\n"_format_to(stdout, 1.2); + "-%20.3e-%20.3e-\n"_format_to(stdout, 1.234567890123456789, 1.2); + "-%p-\n"_format_to(stdout, nullptr); + "-%p-\n"_format_to(stdout, argv); + "-%p-\n"_format_to(stdout, argv[0]); + "-%s-\n"_format_to(stdout, argv[0]); + "-%#05x-\n"_format_to(stdout, 10u); + "-%1$5.3s--%1$-5.3s-\n"_format_to(stdout, "Hallo"); + "-%1$5.10s--%1$-5.10s-\n"_format_to(stdout, "Hallo"); + "%1$d %1$-*3$d %1$d %2$d\n"_format_to(stdout, 1, 4, 10u); + "%1$u %*d %1$u %d\n"_format_to(stdout, 5u, 2, 3); + "%1$u %-*d %1$u %d\n"_format_to(stdout, 5u, 2, 3); + "%1$u %0*d %1$u %d\n"_format_to(stdout, 5u, 2, 3); + "%1$u %0-*d %1$u %d\n"_format_to(stdout, 5u, 2, 3); + "%1$u %-0*d %1$u %d\n"_format_to(stdout, 5u, 2, 3); + "%u % d % d %d\n"_format_to(stdout, 5u, 2, -2, 4); + "%u %+d %+d %d\n"_format_to(stdout, 5u, 2, -2, 4); + "%d %.0d %.d %0d\n"_format_to(stdout, 0, 0, 0, 1); + std::cout << "Hallo %%du %1$s %s%c %s %u = %4$#x = %4$#X = %4$#o %f!\n"_format("Knirp", 's', argv[0], 42u, 1.337) << std::flush; + "-%#09x-\n"_format_to(std::cout, 10u); -template -struct format::AutoConversion> : format::SimpleAutoConversion<'s', const std::array &> {}; +#define TEST(fmt, ...) do{ char* plain; asprintf(&plain, fmt, __VA_ARGS__); assert(std::string_view{plain} == operator""_format()(__VA_ARGS__)); free(plain); }while(0) -template -struct format::AutoConversion, char>>> : format::SimpleAutoConversion<'s', const T(&)[N]> {}; + TEST("%d", 1); + TEST("%1$d %1$-*3$d %1$d %2$d\n", 1, 2, 10u); + TEST("%d %.0d %.d %0d\n", 0, 0, 0, 1); + TEST("%1$a %1$A\n", 1.5); + TEST("%1$a %1$A\n", 0.0/0.0); + TEST("-%1$5.3s--%1$-5.3s-\n", "Hallo"); + TEST("-%1$5.10s--%1$-5.10s-\n", "Hallo"); + TEST("-%1$5c--%1$-5c-\n", 55); + TEST("-%#09.3x-", 10u); + TEST("-%#05x-\n", 10u); + TEST("-%#05o-\n", 10u); + TEST("-%.0o-\n", 0u); + TEST("-%.0x-\n", 0u); + TEST("-%.0X-\n", 0u); + TEST("-%#.0o-\n", 0u); + TEST("-%#.0x-\n", 0u); + TEST("-%#.0X-\n", 0u); + TEST("-%.0u-\n", 0u); + TEST("-%.0i-\n", 0); + TEST("-%.0d-\n", 0); -int main(int, char *[]) -{ - constexpr std::array array[] = {std::array{1, 2, 3, 4, 5}, std::array{1, 2, 3, 4, 5}, std::array{1, 2, 3, 4, 5}, std::array{1, 2, 3, 4, 5}, std::array{1, 2, 3, 4, 5}}; - - std::cout << format::format<"Hello %s: %d %03.5f %V">("World", 7, 3.5, array) << std::endl; - std::cout << format::format<"%v%v%v%v%v">('H', 'e', 'l', 'l', 'o') << std::endl; - std::cout << format::format("%V", &array) << std::endl; - std::cout << format::format("%s", std::array{1, 2, 3, 4, 5}) << std::endl; - std::cout << format::format("Hello %v: %-7v %v", "World", 3.5, 5) << std::endl; - std::cout << format::format("Hello %s: %d %03.5f", "World", 7, 3.5) << std::endl; - return 0; + TEST("-%020.3e-\n", -1.2); + TEST("-%020.3f-\n", -1.2); + TEST("-%020.3g-\n", -1.2); + TEST("-%+020.3a-\n", 1.2); + TEST("-% 020.3a-\n", 1.2); + TEST("-% 20.3a-\n", 1.2); + TEST("-%+20.3a-\n", 1.2); + TEST("-% -20.3a-\n", 1.2); + + TEST("-%0.0a-\n", 0.0); + TEST("-%#0.0e-\n", 0.0); + TEST("-%0.0f-\n", 0.0); + TEST("-%#020.3g-\n", -1.2); + TEST("-%+-20.3a-\n", 1.2); + TEST("-%#+20.3g-\n", 1.0); + + // these might fail, because %p format is implementation defined, although POSIX seems to define it as %#x + TEST("-%p-\n", nullptr); + TEST("-%p-\n", argv); + TEST("-%p-\n", argv[0]); +#undef TEST } -- cgit v1.2.3-54-g00ecf