#include <sys/types.h>
#include <cassert>
#include <cinttypes>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <sstream>
#include <string_view>
#include <jau/test/catch2_ext.hpp>
#ifdef HAS_STD_FORMAT
#include <format>
#endif
using namespace std::literals;
TEST_CASE(
"jau::cfmt benchmark_all",
"[benchmark][jau][std::string][format_string]") {
const size_t loops = 1000;
WARN(
"Benchmark with " + std::to_string(
loops) +
" loops");
CHECK(true);
static constexpr const char *format_check_exp = "format_check: 1.10, 2.20, 1, 2, 003, Hi World";
BENCHMARK("fmt1.01 check bench") {
float fa = 1.1f, fb = 2.2f;
size_t sz1 = 1;
uint64_t sz2 = 2;
int i1 = 3;
std::string str1 = "Hi World";
volatile size_t res = 0;
for(
size_t i = 0; i <
loops; ++i ) {
ssize_t r =
jau::cfmt::check(
"format_check: %.2f, %2.2f, %zu, %" PRIu64
", %03d, %10s", fa, fb, sz1, sz2, i1, str1);
REQUIRE(6 == r);
res = res + r;
}
return res;
};
BENCHMARK("fmt1.02 checkR bench") {
float fa = 1.1f, fb = 2.2f;
size_t sz1 = 1;
uint64_t sz2 = 2;
int i1 = 3;
std::string str1 = "Hi World";
volatile size_t res = 0;
for(
size_t i = 0; i <
loops; ++i ) {
jau::cfmt::Result pc =
jau::cfmt::checkR(
"format_check: %.2f, %2.2f, %zu, %" PRIu64
", %03d, %10s", fa, fb, sz1, sz2, i1, str1);
}
return res;
};
BENCHMARK("fmt1.20 format-ckd rsrved bench") {
float fa = 1.1f, fb = 2.2f;
size_t sz1 = 1;
uint64_t sz2 = 2;
int i1 = 3;
std::string str1 = "Hi World";
volatile size_t res = 0;
for(
size_t i = 0; i <
loops; ++i ) {
std::string s =
jau_format_string(
"format_check: %.2f, %2.2f, %zu, %" PRIu64
", %03d, %10s", fa, fb, sz1, sz2, i1, str1);
REQUIRE(format_check_exp == s);
res = res + s.size();
}
return res;
};
BENCHMARK("fmt1.30 formatR rsrved bench") {
float fa = 1.1f, fb = 2.2f;
size_t sz1 = 1;
uint64_t sz2 = 2;
int i1 = 3;
std::string str1 = "Hi World";
volatile size_t res = 0;
for(
size_t i = 0; i <
loops; ++i ) {
std::string s;
jau::cfmt::formatR(s,
"format_check: %.2f, %2.2f, %zu, %" PRIu64
", %03d, %10s", fa, fb, sz1, sz2, i1, str1);
REQUIRE(format_check_exp == s);
res = res + s.size();
}
return res;
};
BENCHMARK("fmt1.31 formatR2 rsrved bench") {
float fa = 1.1f, fb = 2.2f;
size_t sz1 = 1;
uint64_t sz2 = 2;
int i1 = 3;
std::string str1 = "Hi World";
volatile size_t res = 0;
for(
size_t i = 0; i <
loops; ++i ) {
std::string s;
std::exception_ptr eptr;
try {
jau::cfmt::formatR(s,
"format_check: %.2f, %2.2f, %zu, %" PRIu64
", %03d, %10s", fa, fb, sz1, sz2, i1, str1);
} catch (...) {
eptr = std::current_exception();
}
REQUIRE(format_check_exp == s);
res = res + s.size();
}
return res;
};
BENCHMARK("fmt1.32 format rsrved bench") {
float fa = 1.1f, fb = 2.2f;
size_t sz1 = 1;
uint64_t sz2 = 2;
int i1 = 3;
std::string str1 = "Hi World";
volatile size_t res = 0;
for(
size_t i = 0; i <
loops; ++i ) {
std::string s =
jau::format_string(
"format_check: %.2f, %2.2f, %zu, %" PRIu64
", %03d, %10s", fa, fb, sz1, sz2, i1, str1);
REQUIRE(format_check_exp == s);
res = res + s.size();
}
return res;
};
BENCHMARK("fmtX.32 snprintf rsrved bench") {
float fa = 1.1f, fb = 2.2f;
size_t sz1 = 1;
uint64_t sz2 = 2;
int i1 = 3;
std::string str1 = "Hi World";
volatile size_t res = 0;
for(
size_t i = 0; i <
loops; ++i ) {
std::string s;
s.reserve(bsz);
s.resize(bsz - 1);
size_t nchars = std::snprintf(&s[0], bsz, "format_check: %.2f, %2.2f, %zu, %" PRIu64 ", %03d, %10s", fa, fb, sz1, sz2, i1, str1.c_str());
if( nchars < bsz ) {
s.resize(nchars);
s.shrink_to_fit();
}
REQUIRE(format_check_exp == s);
res = res + nchars;
}
return res;
};
BENCHMARK("fmt1.42 format bench") {
float fa = 1.1f, fb = 2.2f;
size_t sz1 = 1;
uint64_t sz2 = 2;
int i1 = 3;
std::string str1 = "Hi World";
volatile size_t res = 0;
for(
size_t i = 0; i <
loops; ++i ) {
std::string s =
jau::cfmt::format(
"format_check: %.2f, %2.2f, %zu, %" PRIu64
", %03d, %10s", fa, fb, sz1, sz2, i1, str1);
REQUIRE(format_check_exp == s);
res = res + s.size();
}
return res;
};
BENCHMARK("fmtX.50 stringstream bench") {
float fa = 1.1f, fb = 2.2f;
size_t sz1 = 1;
uint64_t sz2 = 2;
int i1 = 3;
std::string str1 = "Hi World";
volatile size_t res = 0;
for(
size_t i = 0; i <
loops; ++i ) {
std::ostringstream ss1;
ss1 << "format_check: "
<< fa << ", "
<< fb << ", "
<< sz1 << ", "
<< sz2 << ", "
<< i1 << ", "
<< str1;
std::string s = ss1.str();
REQUIRE("format_check: 1.1, 2.2, 1, 2, 3, Hi World" == s);
res = res + s.size();
}
return res;
};
#ifdef HAS_STD_FORMAT
BENCHMARK("fmtX.60 stdformat bench") {
float fa = 1.1f, fb = 2.2f;
size_t sz1 = 1;
uint64_t sz2 = 2;
int i1 = 3;
std::string str1 = "Hi World";
volatile size_t res = 0;
for(
size_t i = 0; i <
loops; ++i ) {
std::string s = std::format("format_040b: {0:.2f}, {1:2.2f}, {3}, {4}, {5:03d}, {6:10s}", fa, fb, sz1, sz2, i1, str1);
REQUIRE(format_check_exp == s);
res = res + s.size();
}
return res;
};
#endif
}
TEST_CASE(
"jau::cfmt benchmark_int1",
"[benchmark][jau][std::string][format_string]") {
const size_t loops = 1000;
WARN(
"Benchmark with " + std::to_string(
loops) +
" loops");
CHECK(true);
static constexpr const char *format_check_exp = "format_check: 3";
BENCHMARK("fmt1.32 format rsrved bench") {
int i1 = 3;
volatile size_t res = 0;
for(
size_t i = 0; i <
loops; ++i ) {
REQUIRE(format_check_exp == s);
res = res + s.size();
}
return res;
};
BENCHMARK("fmtX.32 snprintf rsrved bench") {
int i1 = 3;
volatile size_t res = 0;
for(
size_t i = 0; i <
loops; ++i ) {
std::string s;
s.reserve(bsz);
s.resize(bsz - 1);
size_t nchars = std::snprintf(&s[0], bsz, "format_check: %d", i1);
if( nchars < bsz ) {
s.resize(nchars);
s.shrink_to_fit();
}
REQUIRE(format_check_exp == s);
res = res + nchars;
}
return res;
};
}
TEST_CASE(
"jau::cfmt benchmark_int2",
"[benchmark][jau][std::string][format_string]") {
const size_t loops = 1000;
WARN(
"Benchmark with " + std::to_string(
loops) +
" loops");
CHECK(true);
static constexpr const char *format_check_exp = "format_check: 003";
BENCHMARK("fmt1.32 format rsrved bench") {
int i1 = 3;
volatile size_t res = 0;
for(
size_t i = 0; i <
loops; ++i ) {
REQUIRE(format_check_exp == s);
res = res + s.size();
}
return res;
};
BENCHMARK("fmtX.32 snprintf rsrved bench") {
int i1 = 3;
volatile size_t res = 0;
for(
size_t i = 0; i <
loops; ++i ) {
std::string s;
s.reserve(bsz);
s.resize(bsz - 1);
size_t nchars = std::snprintf(&s[0], bsz, "format_check: %03d", i1);
if( nchars < bsz ) {
s.resize(nchars);
s.shrink_to_fit();
}
REQUIRE(format_check_exp == s);
res = res + nchars;
}
return res;
};
}
TEST_CASE(
"jau::cfmt benchmark_str1",
"[benchmark][jau][std::string][format_string]") {
const size_t loops = 1000;
WARN(
"Benchmark with " + std::to_string(
loops) +
" loops");
CHECK(true);
static constexpr const char *format_check_exp = "format_check: ' Hi World'";
BENCHMARK("fmt1.32 format rsrved bench") {
std::string str1 = "Hi World";
volatile size_t res = 0;
for(
size_t i = 0; i <
loops; ++i ) {
REQUIRE(format_check_exp == s);
res = res + s.size();
}
return res;
};
BENCHMARK("fmtX.32 snprintf rsrved bench") {
std::string str1 = "Hi World";
volatile size_t res = 0;
for(
size_t i = 0; i <
loops; ++i ) {
std::string s;
s.reserve(bsz);
s.resize(bsz - 1);
size_t nchars = std::snprintf(&s[0], bsz, "format_check: '%10s'", str1.c_str());
if( nchars < bsz ) {
s.resize(nchars);
s.shrink_to_fit();
}
REQUIRE(format_check_exp == s);
res = res + nchars;
}
return res;
};
}
TEST_CASE(
"jau::cfmt benchmark_str2",
"[benchmark][jau][std::string][format_string]") {
const size_t loops = 1000;
WARN(
"Benchmark with " + std::to_string(
loops) +
" loops");
CHECK(true);
static constexpr const char *format_check_exp = "format_check: 003, ' Hi World'";
BENCHMARK("fmt1.32 format rsrved bench") {
int i1 = 3;
std::string str1 = "Hi World";
volatile size_t res = 0;
for(
size_t i = 0; i <
loops; ++i ) {
REQUIRE(format_check_exp == s);
res = res + s.size();
}
return res;
};
BENCHMARK("fmtX.32 snprintf rsrved bench") {
int i1 = 3;
std::string str1 = "Hi World";
volatile size_t res = 0;
for(
size_t i = 0; i <
loops; ++i ) {
std::string s;
s.reserve(bsz);
s.resize(bsz - 1);
size_t nchars = std::snprintf(&s[0], bsz, "format_check: %03d, '%10s'", i1, str1.c_str());
if( nchars < bsz ) {
s.resize(nchars);
s.shrink_to_fit();
}
REQUIRE(format_check_exp == s);
res = res + nchars;
}
return res;
};
}
constexpr ssize_t argumentCount() const noexcept
Arguments processed.
bool handle_exception(std::exception_ptr eptr)
Handle given optional exception (nullable std::exception_ptr) and send std::exception::what() message...
Result formatR(std::string &s, std::string_view fmt, const Targs &...args) noexcept
Strict format with type validation of arguments against the format string, appending to the given des...
consteval_cxx20 Result checkR(std::string_view fmt, const Targs &...) noexcept
Strict type validation of arguments against the format string.
#define jau_format_string(fmt,...)
Macro, safely returns a (non-truncated) string according to snprintf() formatting rules using a reser...
constexpr const size_t default_string_capacity
Default string reserved capacity w/o EOS (511)
consteval_cxx20 ssize_t check(std::string_view fmt, const Targs &...) noexcept
Strict type validation of arguments against the format string.
std::string format(std::string_view fmt, const Targs &...args) noexcept
Strict format with type validation of arguments against the format string.
std::string format_string(std::string_view format, const Args &...args) noexcept
Safely returns a (non-truncated) string according to snprintf() formatting rules using a reserved str...
TEST_CASE("Endianess Test 00", "[endian]")