Wiki

Clone wiki

miniformat / Home

miniformat

miniformat is a fast, type-safe & minimal string formatting library. Here is my post about this, mostly focused on a recent performance improvement.

Features

  • Type safe: no more run-time error due-to printf format/argument mismatches
  • Much faster than sprintf
  • A single header library with no dependency
  • Uses positional format specifiers like boost::format
  • Supports int32_t/uint32_t, int64_t/uint64_t, double, char, char*, and pointer types as an argument type
  • Supports width & precision options
  • Can output to a raw char array or std::string (one can easily add a support for one's own string type by creating an adaptor for it.)

Weak points

  • Doesn't support all the printf features
  • A heavy C++ template usage

Sample usages

template <typename T>
void test()
{
    T str;
    mini::format(str, "String: %1 Int: %0, Float: %(.3)2\n", 100, "JJ", 3.141592);
    assert(std::string(str) == "String: JJ Int: 100, Float: 3.142\n");
    mini::format(str, "%1 %1 %1\n", 100, "JJ", 3.141592);
    assert(std::string(str) == "JJ JJ JJ\n");
    mini::format(str, "%(.2)2 %(.3)2 %(.4)2\n", 100, "JJ", 3.141592);
    assert(std::string(str) == "3.14 3.142 3.1416\n");
    mini::format(str, "%2 %1 %0 %0 %1 %2\n", 100, "JJ", 3.141592);
    assert(std::string(str) == "3.141592 JJ 100 100 JJ 3.141592\n");
    mini::format(str, "%0\n", "P1");
    assert(std::string(str) == "P1\n");
    mini::format(str, "%0\n", 7);
    assert(std::string(str) == "7\n");
    mini::format(str, "%0\n", 3.14);
    assert(std::string(str) == "3.140000\n");
    mini::format(str, "%0 %1\n", "one", "two");
    assert(std::string(str) == "one two\n");
    mini::format(str, "%0 %1 %2 %3\n", "one", "two", "three", "four");
    assert(std::string(str) == "one two three four\n");
    mini::format(str, "%0 %1 %2 %3 %4\n", "one", "two", "three", "four", "five");
    assert(std::string(str) == "one two three four five\n");
    mini::format(str, "%0 %1 %2 %3 %4 %5\n", "one", "two", "three", "four", "five", "six");
    assert(std::string(str) == "one two three four five six\n");
    mini::format(str, "%0 %1 %2 %3 %4 %5 %6\n", "one", "two", "three", "four", "five", "six", "seven");
    assert(std::string(str) == "one two three four five six seven\n");
    mini::format(str, "%0 %1 %2 %3 %4 %5 %6 %7\n", "one", "two", "three", "four", "five", "six", "seven", "eight");
    assert(std::string(str) == "one two three four five six seven eight\n");
    mini::format(str, "%0 %1 %2 %3 %4 %5 %6 %7 %8\n", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine");
    assert(std::string(str) == "one two three four five six seven eight nine\n");
    mini::format(str, "%0 %%, %%0\n", "Literal");
    assert(std::string(str) == "Literal %, %0\n");
    mini::format(str, "%(6)0\n", 100);
    assert(std::string(str) == "   100\n");
    mini::format(str, "%(2)0\n", 100);
    assert(std::string(str) == "100\n");
    mini::format(str, "%(3)0\n", 100);
    assert(std::string(str) == "100\n");
    mini::format(str, "%(6.2)0\n", 3.14);
    assert(std::string(str) == "  3.14\n");
    mini::format(str, "%(6.2)0\n", -3.14);
    assert(std::string(str) == " -3.14\n");
    mini::format(str, "%0%1%2", 'J', 'J', '1');
    assert(std::string(str) == "JJ1");
    mini::format(str, "%0", (void*)0x00);
    assert(std::string(str) == (sizeof(void*)==8 ? "0000000000000000" : "00000000"));
    mini::format(str, "%0", (void*)0xDEADBEEF);
    assert(std::string(str) == (sizeof(void*)==8 ? "00000000DEADBEEF": "DEADBEEF"));
    // Followings should assert in debug.
    //mini::format(std::string(str), "%0 %n\n", 3);
    //mini::format(std::string(str), "%(.3)1\n", 3.141592);
    //mini::format(std::string(str), "String: %1 Int: %0, Float: %(.3)3\n", 100, "JJ", 3.141592);
}

License

cc_by.png CC BY 4.0

Updated