This C++ unit test validates specific aspects of the implementation.
This C++ unit test validates specific aspects of the implementation.
#include <sys/types.h>
#include <cassert>
#include <cinttypes>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <sstream>
#include <string_view>
#include <type_traits>
#include <jau/test/catch2_ext.hpp>
#ifdef HAS_STD_FORMAT
#include <format>
#endif
using namespace std::literals;
size_t nchars;
std::string str;
{
const size_t bsz = 1024;
str.reserve(bsz);
str.resize(bsz - 1);
nchars = std::snprintf(&str[0], bsz,
"format_000a: %f, %f, %zu, %" PRIu64 ", %" PRIu64 ", %" PRIx64 ", %06" PRIu64 ", %06" PRIx64 ", %d\n",
fa + 1.0_f32, fb + 1.0_f32, sz1 + 1,
a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64,
i + 1);
if( nchars < bsz ) {
str.resize(nchars);
str.shrink_to_fit();
return str;
}
}
str.clear();
return str;
}
return jau::format_string(
"format_010a: %f, %f, %zu, %" PRIu64
", %" PRIu64
", %" PRIx64
", %06" PRIu64
", %06" PRIx64
", %d\n",
fa + 1.0_f32, fb + 1.0_f32, sz1 + 1,
a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64,
i + 1);
}
return jau::format_string_n(1023,
"format_020a: %f, %f, %zu, %" PRIu64
", %" PRIu64
", %" PRIx64
", %06" PRIu64
", %06" PRIx64
", %d\n",
fa + 1.0_f32, fb + 1.0_f32, sz1 + 1,
a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64,
i + 1);
}
std::ostringstream ss1;
ss1 << "format_030a: "
<< fa + 1.0_f32 << ", "
<< fb + 1.0_f32 << ", "
<< sz1 + 1 << ", "
<< a_u64 + 1_u64 << ", "
<< i + 1 << "\n";
return ss1.str();
}
#ifdef HAS_STD_FORMAT
std::string format_040a_stdformat(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
return std::format("format_040a: {0}, {1}, {3}, {4}, {5}\n",
fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, a_u64 + 1_u64, i + 1);
}
#endif
size_t nchars;
std::string str;
{
const size_t bsz = 1024;
str.reserve(bsz);
str.resize(bsz - 1);
nchars = std::snprintf(&str[0], bsz,
"format_000b: %.2f, %2.2f, %zu, %" PRIu64 ", %" PRIu64 ", %" PRIx64 ", %06" PRIu64 ", %06" PRIx64 ", %03d\n",
fa + 1.0_f32, fb + 1.0_f32, sz1 + 1,
a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64,
i + 1);
if( nchars < bsz ) {
str.resize(nchars);
str.shrink_to_fit();
return str;
}
}
str.clear();
return str;
}
return jau::format_string(
"format_010b: %.2f, %2.2f, %zu, %" PRIu64
", %" PRIu64
", %" PRIx64
", %06" PRIu64
", %06" PRIx64
", %03d\n",
fa + 1.0_f32, fb + 1.0_f32, sz1 + 1,
a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64,
i + 1);
}
return jau::format_string_n(1023,
"format_020b: %.2f, %2.2f, %zu, %" PRIu64
", %" PRIu64
", %" PRIx64
", %06" PRIu64
", %06" PRIx64
", %03d\n",
fa + 1.0_f32, fb + 1.0_f32, sz1 + 1,
a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64,
i + 1);
}
std::ostringstream ss1;
ss1.precision(3);
ss1 << "format_030b: "
<< fa + 1.0_f32 << ", ";
ss1.width(3);
ss1 << fb + 1.0_f32 << ", "
<< sz1 + 1 << ", "
<< a_u64 + 1_u64 << ", ";
ss1.width(3);
ss1 << i + 1 << "\n";
return ss1.str();
}
#ifdef HAS_STD_FORMAT
std::string format_040b_stdformat(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
return std::format("format_040b: {0:.2f}, {1:2.2f}, {3}, {4}, {5:03d}\n",
fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, a_u64 + 1_u64, i + 1);
}
#endif
template <typename Func>
constexpr float fa = 1.1f, fb = 2.2f;
constexpr size_t sz1 = 1;
constexpr uint64_t sz2 = 2;
constexpr int i = 3;
const std::string s =
func(fa, fb, sz1, sz2, i);
volatile size_t l = s.length();
if( output ) {
std::cout << s;
}
REQUIRE(0 < l);
REQUIRE(l < 1024);
}
#ifdef HAS_STD_FORMAT
#endif
}
#ifdef HAS_STD_FORMAT
#endif
}
TEST_CASE(
"jau::cfmt_10",
"[jau][std::string][jau::cfmt]") {
char buf[1024];
constexpr float fa = 1.123456f, fb = 2.2f;
constexpr size_t sz1 = 1;
constexpr int64_t v_i64 = 2;
constexpr uint64_t v_u64 = 3;
constexpr int i = 3;
const float *pf = &fa;
{
std::string s;
std::cerr << "XXX: " << __LINE__ << ": " << r << std::endl;
}
{
std::string s;
jau::cfmt::Result r =
jau::cfmt::formatR(s,
"format_check: %.2f, %2.2f, %zu, %" PRIi64
", %" PRIi64
"d, %" PRIi64
"X, %06" PRIu64
"d, %06" PRIu64
"X, %03d\n",
fa, fb, sz1, v_i64, v_i64, v_i64, v_u64, v_u64, i);
std::cerr << "XXX: " << __LINE__ << ": " << r << std::endl;
}
{
std::string s;
std::cerr << "XXX: " << __LINE__ << ": " << r << std::endl;
}
{
int i2 = 2;
static_assert( b2 );
}
{
static_assert(false == std::is_signed_v<const float*>);
static_assert(false == std::is_unsigned_v<const float*>);
static_assert(true == std::is_signed_v<float>);
static_assert(false == std::is_unsigned_v<float>);
}
{
using E = int;
using T = unsigned int;
using U =
typename std::conditional_t<std::is_unsigned_v<T>, std::make_signed<T>, std::type_identity<T>>
::type;
static_assert( std::is_same_v<T, T> );
static_assert( std::is_same_v<E, U> );
}
{
using E = float;
using T = float;
using U =
typename std::conditional_t<std::is_unsigned_v<T>, std::make_signed<T>, std::type_identity<T>>
::type;
static_assert( std::is_same_v<T, T> );
static_assert( std::is_same_v<E, U> );
}
{
static_assert(0 ==
jau::cfmt::checkLine(
" %" PRIi64
", %" PRIi64
", %08" PRIi64
".", (int64_t)1, (int64_t)1, (int64_t)1));
}
{
static_assert(-1 ==
jau::cfmt::check(
"unsigned int -> int %d", (
unsigned int)1));
static_assert( 1 ==
jau::cfmt::check(
"unsigned char -> int %d", (
unsigned char)1));
static_assert( 1 ==
jau::cfmt::check(
"unsigned int -> unsigned int %u", (
unsigned int)1));
static_assert(-1 ==
jau::cfmt::check(
" uint64_t -> int64_t %" PRIi64, (uint64_t)1));
static_assert( 1 ==
jau::cfmt::check(
" int64_t -> uint64_t %" PRIu64, (int64_t)1));
{
printf(
"XXX: sizeof(long) %zu, %s\n",
sizeof(
long), res.
toString().c_str());
}
if constexpr ( sizeof(long) <= sizeof(int) ) {
} else {
}
static_assert(3 ==
jau::cfmt::check(
" %" PRIi64
", %" PRIi64
", %08" PRIi64
".", (int64_t)1, (int64_t)1, (int64_t)1));
static_assert(3 ==
jau::cfmt::check(
" %" PRIi64
", %" PRIi64
", %08" PRIi64
".", v_i64, v_i64, v_i64));
const char* cs1 = "lala";
(void)cs1;
static_assert(5 ==
jau::cfmt::checkR(
"Hello %" PRIi64
", %" PRIu64
", %" PRIx64
", %06" PRIu64
", %06" PRIx64
"",
if constexpr ( sizeof(long) <= 4 ) {
} else {
}
static_assert(-6 ==
jau::cfmt::checkR(
"Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64
", 5 %03d, 6 %p - end",
static_assert(-6 ==
jau::cfmt::check(
"Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64
", 5 %03d, 6 %p - end",
fa, fb, sz1, v_i64, i, i));
{
fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, v_i64 + 1_u64, i + 1).
argumentCount());
const std::string s =
jau_format_string(
"format_020a: %f, %f, %zu, %" PRIu64
", %d\n",
fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, v_i64 + 1_u64, i + 1);
REQUIRE( s.size() > 0 );
}
{
REQUIRE( s0.size() > 0 );
}
}
{
REQUIRE("Hello 1" == s1);
std::cerr << "XXX: " << __LINE__ << ": " << c1 << std::endl;
}
{
REQUIRE(9 == std::snprintf(buf, sizeof(buf), "Hello 1 %d", i));
std::cerr << "XXX: " << __LINE__ << ": " << pc << std::endl;
REQUIRE(2 ==
jau::cfmt::checkR(
"Hello 1 %.2f, 2 %2.2f - end", fa, fb).argumentCount());
std::cerr << "XXX: " << __LINE__ << ": " << pc << std::endl;
REQUIRE(3 ==
jau::cfmt::checkR(
"Hello 1 %.2f, 2 %2.2f, 3 %zu - end", fa, fb, sz1).argumentCount());
REQUIRE(4 ==
jau::cfmt::checkR(
"Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64
" - end", fa, fb, sz1, v_i64).argumentCount());
REQUIRE(5 ==
jau::cfmt::checkR(
"Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64
", 5 %03d - end", fa, fb, sz1, v_i64, i).argumentCount());
REQUIRE(6 ==
jau::cfmt::checkR(
"Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64
", 5 %03d, 6 %p - end", fa, fb, sz1, v_i64, i, pf).argumentCount());
if constexpr ( sizeof(long) <= 4 ) {
} else {
}
REQUIRE(-6 ==
jau::cfmt::checkR(
"Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64
", 5 %03d, 6 %p - end",
fa, fb, sz1, v_i64, i, i).argumentCount());
}
}
TEST_CASE(
"jau::cfmt_01",
"[jau][std::string][format_string]") {
}
TEST_CASE(
"jau::cfmt_10 debug",
"[jau][std::string][format_string][debug]") {
INFO_PRINT(
"lala002 %d, %f, %s", 1, 3.14,
"hello world");
std::string s1 = "Hello";
std::string_view sv1 = s1;
const char * s1p = s1.c_str();
}
constexpr ssize_t argumentCount() const noexcept
Arguments processed.
std::string toString() const
constexpr bool success() const noexcept
true if operation was successful, otherwise indicates error
#define ERR_PRINT3(...)
Use for unconditional error messages, prefix '[elapsed_time] Error @ FILE:LINE FUNC: '.
#define INFO_PRINT(fmt,...)
Use for unconditional informal messages, prefix '[elapsed_time] Info: '.
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 int checkLine(std::string_view fmt, const Targs &...) noexcept
Strict type validation of arguments against the format string.
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...
consteval_cxx20 ssize_t check(std::string_view fmt, const Targs &...) noexcept
Strict type validation of arguments against the format string.
std::string format_string_n(const std::size_t maxStrLen, std::string_view format, const Args &...args) noexcept
Safely returns a (potentially truncated) string according to snprintf() formatting rules and variable...
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]")
int printf(const char *format,...)
Operating Systems predefined macros.
static size_t test_format(const Func func, bool output)
static std::string format_020b_jaufmtstr_n(float fa, float fb, size_t sz1, uint64_t a_u64, int i)
static std::string format_snprintf_ffszu64d(float fa, float fb, size_t sz1, uint64_t a_u64, int i)
static std::string format_010a_jaufmtstr(float fa, float fb, size_t sz1, uint64_t a_u64, int i)
static std::string format_000b_vsnprintf(float fa, float fb, size_t sz1, uint64_t a_u64, int i)
static std::string format_020a_jaufmtstr_n(float fa, float fb, size_t sz1, uint64_t a_u64, int i)
static std::string format_030a_strstream(float fa, float fb, size_t sz1, uint64_t a_u64, int i)
static std::string format_030b_strstream(float fa, float fb, size_t sz1, uint64_t a_u64, int i)
static std::string format_010b_jaufmtstr(float fa, float fb, size_t sz1, uint64_t a_u64, int i)