jaulib v1.4.1-14-g15926ba
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
test_stringfmt_check.cpp
Go to the documentation of this file.
1/**
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2024 Gothel Software e.K.
4 *
5 * ***
6 *
7 * SPDX-License-Identifier: MIT
8 *
9 * This Source Code Form is subject to the terms of the MIT License
10 * If a copy of the MIT was not distributed with this
11 * file, You can obtain one at https://opensource.org/license/mit/.
12 *
13 */
14#include <sys/types.h>
15#include <cassert>
16#include <cinttypes>
17#include <cstdint>
18#include <cstdio>
19#include <cstring>
20#include <iostream>
21#include <sstream>
22#include <string_view>
23#include <type_traits>
24
25#include <jau/basic_types.hpp>
26#include <jau/cpp_lang_util.hpp>
27#include <jau/cpp_pragma.hpp>
28#include <jau/float_types.hpp>
29#include <jau/int_types.hpp>
30#include <jau/string_cfmt.hpp>
32#include <jau/string_util.hpp>
33#include <jau/test/catch2_ext.hpp>
34#include <jau/type_concepts.hpp>
36#include <jau/debug.hpp>
37
38#ifdef HAS_STD_FORMAT
39 #include <format>
40#endif
41
42using namespace std::literals;
43
44using namespace jau::float_literals;
45
46using namespace jau::int_literals;
47
48static std::string format_snprintf_ffszu64d(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
49 size_t nchars;
50 std::string str;
51 {
52 const size_t bsz = 1024; // including EOS
53 str.reserve(bsz); // incl. EOS
54 str.resize(bsz - 1); // excl. EOS
55
56 nchars = std::snprintf(&str[0], bsz,
57 "format_000a: %f, %f, %zu, %" PRIu64 ", %" PRIu64 ", %" PRIx64 ", %06" PRIu64 ", %06" PRIx64 ", %d\n",
58 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1,
59 a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64,
60 i + 1);
61
62 if( nchars < bsz ) {
63 str.resize(nchars);
64 str.shrink_to_fit();
65 return str;
66 }
67 }
68 str.clear(); // error
69 return str;
70}
71
72static std::string format_010a_jaufmtstr(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
73 return jau::format_string("format_010a: %f, %f, %zu, %" PRIu64 ", %" PRIu64 ", %" PRIx64 ", %06" PRIu64 ", %06" PRIx64 ", %d\n",
74 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1,
75 a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64,
76 i + 1);
77}
78
79static std::string format_020a_jaufmtstr_n(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
80 return jau::format_string_n(1023, "format_020a: %f, %f, %zu, %" PRIu64 ", %" PRIu64 ", %" PRIx64 ", %06" PRIu64 ", %06" PRIx64 ", %d\n",
81 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1,
82 a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64,
83 i + 1);
84}
85
86static std::string format_030a_strstream(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
87 std::ostringstream ss1;
88 ss1 << "format_030a: "
89 << fa + 1.0_f32 << ", "
90 << fb + 1.0_f32 << ", "
91 << sz1 + 1 << ", "
92 << a_u64 + 1_u64 << ", "
93 << i + 1 << "\n";
94 return ss1.str();
95}
96
97#ifdef HAS_STD_FORMAT
98std::string format_040a_stdformat(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
99 return std::format("format_040a: {0}, {1}, {3}, {4}, {5}\n",
100 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, a_u64 + 1_u64, i + 1);
101}
102#endif
103
104static std::string format_000b_vsnprintf(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
105 size_t nchars;
106 std::string str;
107 {
108 const size_t bsz = 1024; // including EOS
109 str.reserve(bsz); // incl. EOS
110 str.resize(bsz - 1); // excl. EOS
111
112 nchars = std::snprintf(&str[0], bsz,
113 "format_000b: %.2f, %2.2f, %zu, %" PRIu64 ", %" PRIu64 ", %" PRIx64 ", %06" PRIu64 ", %06" PRIx64 ", %03d\n",
114 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1,
115 a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64,
116 i + 1);
117
118 if( nchars < bsz ) {
119 str.resize(nchars);
120 str.shrink_to_fit();
121 return str;
122 }
123 }
124 str.clear(); // error
125 return str;
126}
127static std::string format_010b_jaufmtstr(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
128 return jau::format_string("format_010b: %.2f, %2.2f, %zu, %" PRIu64 ", %" PRIu64 ", %" PRIx64 ", %06" PRIu64 ", %06" PRIx64 ", %03d\n",
129 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1,
130 a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64,
131 i + 1);
132}
133
134static std::string format_020b_jaufmtstr_n(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
135 return jau::format_string_n(1023, "format_020b: %.2f, %2.2f, %zu, %" PRIu64 ", %" PRIu64 ", %" PRIx64 ", %06" PRIu64 ", %06" PRIx64 ", %03d\n",
136 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1,
137 a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64, a_u64 + 1_u64,
138 i + 1);
139}
140
141static std::string format_030b_strstream(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
142 std::ostringstream ss1;
143 ss1.precision(3);
144 ss1 << "format_030b: "
145 << fa + 1.0_f32 << ", ";
146 ss1.width(3);
147 ss1 << fb + 1.0_f32 << ", "
148 << sz1 + 1 << ", "
149 << a_u64 + 1_u64 << ", ";
150 ss1.width(3);
151 ss1 << i + 1 << "\n";
152 return ss1.str();
153}
154
155#ifdef HAS_STD_FORMAT
156std::string format_040b_stdformat(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
157 return std::format("format_040b: {0:.2f}, {1:2.2f}, {3}, {4}, {5:03d}\n",
158 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, a_u64 + 1_u64, i + 1);
159}
160#endif
161
162template <typename Func>
163static size_t test_format(const Func func, bool output) {
164 constexpr float fa = 1.1f, fb = 2.2f;
165 constexpr size_t sz1 = 1;
166 constexpr uint64_t sz2 = 2;
167 constexpr int i = 3;
168
169 const std::string s = func(fa, fb, sz1, sz2, i);
170 volatile size_t l = s.length();
171 if( output ) {
172 std::cout << s;
173 }
174 REQUIRE(0 < l);
175 REQUIRE(l < 1024);
176 return l;
177}
178
179static void format_0a() {
184
185#ifdef HAS_STD_FORMAT
186 test_format(format_040a_stdformat, true);
187#endif
188}
189static void format_0b() {
194
195#ifdef HAS_STD_FORMAT
196 test_format(format_040b_stdformat, true);
197#endif
198}
199
200TEST_CASE("jau::cfmt_10", "[jau][std::string][jau::cfmt]") {
201 char buf[1024];
202 constexpr float fa = 1.123456f, fb = 2.2f;
203 constexpr size_t sz1 = 1;
204 constexpr int64_t v_i64 = 2;
205 constexpr uint64_t v_u64 = 3;
206 constexpr int i = 3;
207 const float *pf = &fa;
208
209 {
210 std::string s;
211 jau::cfmt::Result r = jau::cfmt::formatR(s, "lala %d", 2);
212 std::cerr << "XXX: " << __LINE__ << ": " << r << std::endl;
213 REQUIRE( 1 == r.argumentCount() );
214 }
215 { // 'format_check: %.2f, %2.2f, %zu, %lu, %03d'
216 std::string s;
217 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",
218 fa, fb, sz1, v_i64, v_i64, v_i64, v_u64, v_u64, i);
219 std::cerr << "XXX: " << __LINE__ << ": " << r << std::endl;
220 REQUIRE(9 == r.argumentCount());
221 }
222 {
223 std::string s;
224 jau::cfmt::Result r = jau::cfmt::formatR(s, "lala %d - end", 2);
225 std::cerr << "XXX: " << __LINE__ << ": " << r << std::endl;
226 REQUIRE(1 == r.argumentCount());
227 }
228 {
229 static_assert( 0 == jau::cfmt::checkLine("lala %d", 2) );
230 static_assert( 1 == jau::cfmt::check("lala %d", 2) );
231
232 int i2 = 2;
233 constexpr const bool b2 = jau::cfmt::check("lala %d", i2);
234 static_assert( b2 );
235 }
236 {
237 static_assert(false == std::is_signed_v<const float*>);
238 static_assert(false == std::is_unsigned_v<const float*>);
239
240 static_assert(true == std::is_signed_v<float>);
241 static_assert(false == std::is_unsigned_v<float>);
242 }
243 {
244 using E = int;
245 using T = unsigned int;
246 // using U = std::conditional_t<std::is_unsigned_v<T>, std::make_signed_t<T>, T>; // triggers the instantiating the 'other' case and hence fails
247 using U = typename std::conditional_t<std::is_unsigned_v<T>, std::make_signed<T>, std::type_identity<T>>::type; // NOLINT
248 static_assert( std::is_same_v<T, T> );
249 static_assert( std::is_same_v<E, U> );
250 }
251 {
252 using E = float;
253 using T = float;
254 // using U = std::conditional_t<std::is_unsigned_v<T>, std::make_signed_t<T>, T>; // triggers the instantiating the 'other' case and hence fails
255 using U = typename std::conditional_t<std::is_unsigned_v<T>, std::make_signed<T>, std::type_identity<T>>::type; // NOLINT
256 static_assert( std::is_same_v<T, T> );
257 static_assert( std::is_same_v<E, U> );
258 }
259 {
260 static_assert(0 == jau::cfmt::checkLine(" lala %d", 1));
261 static_assert(0 == jau::cfmt::checkLine(" lala %ld", 1));
262 static_assert(0 == jau::cfmt::checkLine(" lala %zd", 1));
263 static_assert(0 == jau::cfmt::checkLine(" lala %8d", 1));
264 static_assert(0 == jau::cfmt::checkLine(" lala %08d", 1));
265 static_assert(0 == jau::cfmt::checkLine(" lala %08.2d", 1));
266 static_assert(0 == jau::cfmt::checkLine(" %" PRIi64 ", %" PRIi64 ", %08" PRIi64 ".", (int64_t)1, (int64_t)1, (int64_t)1));
267 }
268 {
269 // we support safe signedness conversion
270 static_assert( 1 == jau::cfmt::check(" int -> int %d", 1));
271 static_assert(-1 == jau::cfmt::check("unsigned int -> int %d", (unsigned int)1)); // error: sizeof(unsigned) == sizeof(signed)
272 static_assert( 1 == jau::cfmt::check("unsigned char -> int %d", (unsigned char)1)); // OK: sizeof(unsigned) < sizeof(signed)
273 static_assert( 1 == jau::cfmt::check("unsigned int -> unsigned int %u", (unsigned int)1));
274 static_assert( 1 == jau::cfmt::check(" int -> unsigned int %u", 1)); // OK: +signed -> unsigned
275 static_assert(-1 == jau::cfmt::check(" uint64_t -> int64_t %" PRIi64, (uint64_t)1)); // error: sizeof(unsigned) == sizeof(signed)
276 static_assert( 1 == jau::cfmt::check(" int64_t -> uint64_t %" PRIu64, (int64_t)1)); // OK: +signed -> unsigned
277
278 // given type <= integral target type
279 static_assert( 1 == jau::cfmt::check(" char -> int %d", (char)1)); // OK given type <= integral target type
280 static_assert(-1 == jau::cfmt::check(" char -> int %d", (uint64_t)1)); // ERR given type > integral target type
281 {
282 jau::cfmt::Result res = jau::cfmt::checkR(" error long -> int %d", (long)1);
283 // if( res.error() ) {
284 printf("XXX: sizeof(long) %zu, %s\n", sizeof(long), res.toString().c_str());
285 }
286 if constexpr ( sizeof(long) <= sizeof(int) ) {
287 REQUIRE( 1 == jau::cfmt::check(" OK long(4) -> int %d", (long)1)); // NOLINT(misc-static-assert)
288 } else {
289 REQUIRE(-1 == jau::cfmt::check(" error long(8) -> int %d", (long)1)); // NOLINT(misc-static-assert); error: given type > integral target type
290 }
291
292 static_assert(1 == jau::cfmt::check(" %d", i));
293 static_assert(1 == jau::cfmt::check(" %f", fa));
294 static_assert(1 == jau::cfmt::check(" %zd", (ssize_t)1));
295 static_assert(1 == jau::cfmt::check(" %zu", (size_t)1));
296 static_assert(3 == jau::cfmt::check(" %" PRIi64 ", %" PRIi64 ", %08" PRIi64 ".", (int64_t)1, (int64_t)1, (int64_t)1));
297 static_assert(3 == jau::cfmt::check(" %" PRIi64 ", %" PRIi64 ", %08" PRIi64 ".", v_i64, v_i64, v_i64));
298 static_assert(1 == jau::cfmt::check(" %p", pf));
299 const char* cs1 = "lala";
300 static_assert(1 == jau::cfmt::check(" %s", (const char*)"lala"));
301 static_assert(1 == jau::cfmt::check(" %s", cs1));
302 static_assert(0 == jau::cfmt::checkLine(" %s", cs1));
303 (void)cs1;
304
305 static_assert(0 == jau::cfmt::checkR("Hello World").argumentCount());
306 static_assert(1 == jau::cfmt::checkR("Hello World %d", 1).argumentCount());
307 static_assert(1 == jau::cfmt::checkR("Hello 1 %d", i).argumentCount());
308 static_assert(0 == jau::cfmt::check("Hello World"));
309 static_assert(1 == jau::cfmt::check("Hello World %d", 1));
310 static_assert(1 == jau::cfmt::check("Hello 1 %d", i));
311
312 static_assert(1 == jau::cfmt::checkR("Hello 1 %.2f", fa).argumentCount());
313 static_assert(1 == jau::cfmt::checkR("Hello 1 %.2f - end", fa).argumentCount());
314 static_assert(2 == jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f - end", fa, fb).argumentCount());
315 static_assert(3 == jau::cfmt::checkR("Hello 1 %.2f , 2 %2.2f, 3 %zu - end", fa, fb, sz1).argumentCount());
316 static_assert(4 == jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64 " - end", fa, fb, sz1, v_i64).argumentCount());
317 static_assert(5 == jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64 ", 5 %03d - end", fa, fb, sz1, v_i64, i).argumentCount());
318
319 static_assert(5 == jau::cfmt::checkR("Hello %" PRIi64 ", %" PRIu64 ", %" PRIx64 ", %06" PRIu64 ", %06" PRIx64 "",
320 v_i64, v_u64, v_u64, v_u64, v_u64).argumentCount());
321
322 // static_assert(6 == jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64 ", 5 %03d, 6 %p - end", fa, fb, sz1, sz2, i, pf).argumentCount());
323 // static_assert(1 == jau::cfmt::checkR(" %s", "lala").argumentCount());
324
325 static_assert(0 > jau::cfmt::check("Hello World %"));
326 static_assert(0 > jau::cfmt::checkR("Hello World %").argumentCount());
327 static_assert(0 > jau::cfmt::checkR("Hello 1 %d").argumentCount());
328 static_assert(-1 == jau::cfmt::checkR("Hello 1 %d", fa).argumentCount());
329 if constexpr ( sizeof(long) <= 4 ) {
330 assert( 1 == jau::cfmt::checkR("Hello 1 %d", sz1).argumentCount()); // NOLINT(misc-static-assert)
331 } else {
332 assert(-1 == jau::cfmt::checkR("Hello 1 %d", sz1).argumentCount()); // NOLINT(misc-static-assert)
333 }
334 static_assert(-6 == jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64 ", 5 %03d, 6 %p - end",
335 fa, fb, sz1, v_i64, i, i).argumentCount());
336 static_assert(-6 == jau::cfmt::check("Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64 ", 5 %03d, 6 %p - end",
337 fa, fb, sz1, v_i64, i, i));
338
339 {
340 static_assert(0 <= jau::cfmt::checkR("format_020a: %f, %f, %zu, %" PRIu64 ", %d\n",
341 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, v_i64 + 1_u64, i + 1).argumentCount()); // compile time validation!
342 const std::string s = jau_format_string("format_020a: %f, %f, %zu, %" PRIu64 ", %d\n",
343 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, v_i64 + 1_u64, i + 1);
344 REQUIRE( s.size() > 0 );
345 }
346 {
347 std::string s0 = jau::format_string("Hello %d", 1);
348 REQUIRE( s0.size() > 0 );
349 // FIXME
350 // const std::string s1 = jau::format_string<"Hello %d">(1);
351 // REQUIRE_THROWS_AS( s0 = jau::format_string("Hello %d", 1.0f), jau::IllegalArgumentError);
352 }
353 }
354 {
355 std::string s1 = jau_format_string("Hello %d", 1);
356 REQUIRE("Hello 1" == s1);
357
358 constexpr jau::cfmt::Result c1 = jau::cfmt::checkR("Hello %u", (unsigned int)1);
359 std::cerr << "XXX: " << __LINE__ << ": " << c1 << std::endl;
360 REQUIRE(true == c1.success());
361 }
362 {
363 constexpr jau::cfmt::Result c1 = jau::cfmt::checkR("Hello World");
364 REQUIRE(true == c1.success());
365 REQUIRE(0 == c1.argumentCount());
366 REQUIRE(0 == jau::cfmt::checkR("Hello World").argumentCount());
367 constexpr jau::cfmt::Result c3 = jau::cfmt::checkR("Hello 1 %d", i);
368 REQUIRE(true == c3.success());
369 REQUIRE(1 == c3.argumentCount());
370 REQUIRE(9 == std::snprintf(buf, sizeof(buf), "Hello 1 %d", i));
371
372 // `Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %li, 5 %03d, 6 %p - end`
373 REQUIRE(1 == jau::cfmt::checkR("Hello 1 %.2f", fa).argumentCount());
374 REQUIRE(1 == jau::cfmt::checkR("Hello 1 %.2f - end", fa).argumentCount());
375
376 // 'Hello 1 %.2f, 2 %2.2f - end'
377 jau::cfmt::Result pc = jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f - end", fa, fb);
378 std::cerr << "XXX: " << __LINE__ << ": " << pc << std::endl;
379 REQUIRE(2 == jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f - end", fa, fb).argumentCount());
380
381 // `Hello 1 %.2f, 2 %2.2f, 3 %zu - end`
382 pc = jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f, 3 %zu - end", fa, fb, sz1);
383 std::cerr << "XXX: " << __LINE__ << ": " << pc << std::endl;
384 REQUIRE(3 == jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f, 3 %zu - end", fa, fb, sz1).argumentCount());
385
386 REQUIRE(4 == jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64 " - end", fa, fb, sz1, v_i64).argumentCount());
387 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());
388 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());
389
390 // REQUIRE(13 == std::snprintf(buf, sizeof(buf), "Hello World %").argumentCount());
391 REQUIRE(0 > jau::cfmt::checkR("Hello World %").argumentCount());
392 REQUIRE(0 > jau::cfmt::checkR("Hello 1 %d").argumentCount());
393 REQUIRE(-1 == jau::cfmt::checkR("Hello 1 %d", fa).argumentCount());
394 if constexpr ( sizeof(long) <= 4 ) {
395 REQUIRE( 1 == jau::cfmt::checkR("Hello 1 %d", sz1).argumentCount());
396 } else {
397 REQUIRE(-1 == jau::cfmt::checkR("Hello 1 %d", sz1).argumentCount());
398 }
399 REQUIRE(-6 == jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64 ", 5 %03d, 6 %p - end",
400 fa, fb, sz1, v_i64, i, i).argumentCount());
401 }
402}
403
404TEST_CASE("jau::cfmt_01", "[jau][std::string][format_string]") {
405 format_0a();
406 format_0b();
407}
408
409TEST_CASE("jau::cfmt_10 debug", "[jau][std::string][format_string][debug]") {
410 INFO_PRINT("lala001");
411 INFO_PRINT("lala002 %d, %f, %s", 1, 3.14, "hello world");
412 std::string s1 = "Hello";
413 std::string_view sv1 = s1;
414 const char * s1p = s1.c_str();
415 INFO_PRINT("lala003 %s, %s, %s", s1, sv1, s1p);
416
417 ERR_PRINT3("error 01: '%s', %d", s1, 88);
418}
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: '.
Definition debug.hpp:184
#define INFO_PRINT(fmt,...)
Use for unconditional informal messages, prefix '[elapsed_time] Info: '.
Definition debug.hpp:193
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...
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 void format_0b()
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 void format_0a()
TEST_CASE("jau::cfmt_10", "[jau][std::string][jau::cfmt]")
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)