jaulib v1.3.6
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
test_stringfmt01.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/cpp_lang_util.hpp>
26#include <jau/cpp_pragma.hpp>
27#include <jau/float_types.hpp>
28#include <jau/int_types.hpp>
29#include <jau/string_cfmt.hpp>
30#include <jau/string_util.hpp>
31#include <jau/test/catch2_ext.hpp>
33
34#include "string_cfmt2.hpp"
35
36#ifdef HAS_STD_FORMAT
37 #include <format>
38#endif
39
40using namespace std::literals;
41
42using namespace jau::float_literals;
43
44using namespace jau::int_literals;
45
46template <typename... Args>
47constexpr std::string format_string000(const std::size_t maxStrLen, const std::string_view format, const Args &...args) {
48 std::string str;
49 str.reserve(maxStrLen + 1); // incl. EOS
50 str.resize(maxStrLen); // excl. EOS
51
52 // -Wformat=2 -> -Wformat -Wformat-nonliteral -Wformat-security -Wformat-y2k
53 // -Wformat=2 -Wformat-overflow=2 -Wformat-signedness
56 const size_t nchars = std::snprintf(&str[0], maxStrLen + 1, format.data(), args...);
58 if( nchars < maxStrLen + 1 ) {
59 str.resize(nchars);
60 str.shrink_to_fit();
61 } // else truncated w/ nchars > MaxStrLen
62 return str;
63}
64
65std::string format_000a_vsnprintf(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
66 size_t nchars;
67 std::string str;
68 {
69 const size_t bsz = 1024; // including EOS
70 str.reserve(bsz); // incl. EOS
71 str.resize(bsz - 1); // excl. EOS
72
73 nchars = std::snprintf(&str[0], bsz,
74 "format_000a: %f, %f, %zu, %" PRIu64 ", %d\n",
75 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, a_u64 + 1_u64, i + 1);
76
77 if( nchars < bsz ) {
78 str.resize(nchars);
79 str.shrink_to_fit();
80 return str;
81 }
82 }
83 str.clear(); // error
84 return str;
85}
86
87std::string format_010a_vsnprintf(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
88 return jau::format_string("format_010a: %f, %f, %zu, %" PRIu64 ", %d\n",
89 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, a_u64 + 1_u64, i + 1);
90}
91
92constexpr std::string format_020a_tsnprintf(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
93 return jau::format_string_v(1023, "format_020a: %f, %f, %zu, %" PRIu64 ", %d\n",
94 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, a_u64 + 1_u64, i + 1);
95}
96
97std::string format_030a_strstream(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
98 std::ostringstream ss1;
99 ss1 << "format_030a: "
100 << fa + 1.0_f32 << ", "
101 << fb + 1.0_f32 << ", "
102 << sz1 + 1 << ", "
103 << a_u64 + 1_u64 << ", "
104 << i + 1 << "\n";
105 return ss1.str();
106}
107
108#ifdef HAS_STD_FORMAT
109std::string format_040a_stdformat(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
110 return std::format("format_040a: {0}, {1}, {3}, {4}, {5}\n",
111 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, a_u64 + 1_u64, i + 1);
112}
113#endif
114
115std::string format_000b_vsnprintf(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
116 size_t nchars;
117 std::string str;
118 {
119 const size_t bsz = 1024; // including EOS
120 str.reserve(bsz); // incl. EOS
121 str.resize(bsz - 1); // excl. EOS
122
123 nchars = std::snprintf(&str[0], bsz,
124 "format_000b: %.2f, %2.2f, %zu, %" PRIu64 ", %03d\n",
125 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, a_u64 + 1_u64, i + 1);
126
127 if( nchars < bsz ) {
128 str.resize(nchars);
129 str.shrink_to_fit();
130 return str;
131 }
132 }
133 str.clear(); // error
134 return str;
135}
136std::string format_010b_vsnprintf(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
137 return jau::format_string("format_010b: %.2f, %2.2f, %zu, %" PRIu64 ", %03d\n",
138 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, a_u64 + 1_u64, i + 1);
139}
140
141std::string format_020b_tsnprintf(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
142 return jau::format_string_v(1023, "format_020b: %.2f, %2.2f, %zu, %" PRIu64 ", %03d\n",
143 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, a_u64 + 1_u64, i + 1);
144}
145
146std::string format_030b_strstream(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
147 std::ostringstream ss1;
148 ss1.precision(3);
149 ss1 << "format_030b: "
150 << fa + 1.0_f32 << ", ";
151 ss1.width(3);
152 ss1 << fb + 1.0_f32 << ", "
153 << sz1 + 1 << ", "
154 << a_u64 + 1_u64 << ", ";
155 ss1.width(3);
156 ss1 << i + 1 << "\n";
157 return ss1.str();
158}
159
160#ifdef HAS_STD_FORMAT
161std::string format_040b_stdformat(float fa, float fb, size_t sz1, uint64_t a_u64, int i) {
162 return std::format("format_040b: {0:.2f}, {1:2.2f}, {3}, {4}, {5:03d}\n",
163 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, a_u64 + 1_u64, i + 1);
164}
165#endif
166
167template <typename Func>
168size_t test_format(const Func func, bool output) {
169 constexpr float fa = 1.1f, fb = 2.2f;
170 constexpr size_t sz1 = 1;
171 constexpr uint64_t sz2 = 2;
172 constexpr int i = 3;
173
174 const std::string s = func(fa, fb, sz1, sz2, i);
175 volatile size_t l = s.length();
176 if( output ) {
177 std::cout << s;
178 }
179 REQUIRE(0 < l);
180 REQUIRE(l < 1024);
181 return l;
182}
183
184void format_0a() {
189
190#ifdef HAS_STD_FORMAT
191 test_format(format_040a_stdformat, true);
192#endif
193}
194void format_0b() {
199
200#ifdef HAS_STD_FORMAT
201 test_format(format_040b_stdformat, true);
202#endif
203}
204
205template <typename... Args>
206constexpr std::string format_string_static2(const std::string_view fmt, const Args &...) {
207 // constexpr const std::string format2(format);
208 // constexpr const bool b = jau::cfmt::check2<Args...>("Haus"sv);
209 constexpr const bool b = jau::cfmt::check3<Args...>(fmt);
210 static_assert( b );
211 (void)b;
212 return ""; // jau::format_string_v(1024, format, args...);
213}
214
215
216template <typename... Targs>
217constexpr jau::cfmt2::PResult check(const std::string_view fmt, const Targs &...) noexcept {
218 return jau::cfmt2::impl::checkRec<Targs...>( jau::cfmt2::PResult(fmt) );
219}
220
221template <typename... Targs>
222constexpr std::string format_string_static3(const std::string_view format, const Targs &...args) {
223 // constexpr const jau::cfmt2::PResult ctx2 = jau::cfmt2::impl::checkRec<Targs...>( jau::cfmt2::PResult(format) );
224 // static_assert( 0 <= jau::cfmt2::impl::checkRec<Targs...>( jau::cfmt2::PResult(format)).argCount() );
225 if( 0 <= jau::cfmt2::impl::checkRec<Targs...>( jau::cfmt2::PResult(format)).argCount() ) {
226 return jau::format_string_v(1024, format, args...);
227 } else {
228 return "";
229 }
230}
231
232
233TEST_CASE("jau::cfmt_00", "[jau][std::string][jau::cfmt]") {
234 char buf[1024];
235 constexpr float fa = 1.123456f, fb = 2.2f;
236 constexpr size_t sz1 = 1;
237 constexpr int64_t sz2 = 2;
238 constexpr int i = 3;
239 const float *pf = &fa;
240
241 {
242 constexpr jau::cfmt2::PResult pr = jau::cfmt2::checkR("lala %d", 2);
243 std::cerr << "XXX: " << __LINE__ << ": " << pr << std::endl;
244 static_assert( 0 <= pr.argCount() );
245 }
246 { // 'format_check: %.2f, %2.2f, %zu, %lu, %03d'
247 constexpr jau::cfmt2::PResult pc = jau::cfmt2::checkR("format_check: %.2f, %2.2f, %zu, %" PRIu64 ", %03d\n",
248 fa, fb, sz1, sz2, i);
249 std::cerr << "XXX: " << __LINE__ << ": " << pc << std::endl;
250 // static_assert( 5 == pc.argCount() );
251 REQUIRE(5 == pc.argCount());
252 }
253 {
254 constexpr jau::cfmt2::PResult pr = jau::cfmt2::checkR("lala %d - end", 2);
255 std::cerr << "XXX: " << __LINE__ << ": " << pr << std::endl;
256 // static_assert( 0 <= pr.argCount() );
257 REQUIRE(0 <= pr.argCount());
258 }
259 {
260 constexpr const bool b1 = jau::cfmt::check("lala %d", 2);
261 static_assert( b1 );
262
263 constexpr const bool b2 = jau::cfmt::check2<int>("lala %d");
264 static_assert( b2 );
265
266 // constexpr jau::cfmt2::PResult pr1 = check(fmt3, 2);
267 constexpr jau::cfmt2::PResult pr1 = check("Hello %d", 2);
268 std::cerr << "XXX: " << __LINE__ << ": " << pr1 << std::endl;
269 static_assert( 0 <= pr1.argCount() );
270
271 std::string s3 = format_string_static3("Hello %d", 2);
272 std::cerr << "XXX: " << __LINE__ << ": " << s3 << std::endl;
273 REQUIRE( s3.length() > 0 );
274
275 // constexpr const std::string f2 = "Hello %d"s;
276 // constexpr const std::string_view f2v = "Hello %d"sv;
277 // format_string_static2(f2v, (int)2);
278 // constexpr const std::string_view f3 = "Hello %d"sv;
279 // constexpr const char f3[] = "Hello %d";
280 // format_string_static2("Hello %d"sv, (int)2);
281 }
282 {
283 static_assert(false == std::is_signed_v<const float*>);
284 static_assert(false == std::is_unsigned_v<const float*>);
285
286 static_assert(true == std::is_signed_v<float>);
287 static_assert(false == std::is_unsigned_v<float>);
288 }
289 {
290 using E = int;
291 using T = unsigned int;
292 // 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
293 using U = typename std::conditional_t<std::is_unsigned_v<T>, std::make_signed<T>, std::type_identity<T>>::type; // NOLINT
294 static_assert( std::is_same_v<T, T> );
295 static_assert( std::is_same_v<E, U> );
296 }
297 {
298 using E = float;
299 using T = float;
300 // 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
301 using U = typename std::conditional_t<std::is_unsigned_v<T>, std::make_signed<T>, std::type_identity<T>>::type; // NOLINT
302 static_assert( std::is_same_v<T, T> );
303 static_assert( std::is_same_v<E, U> );
304 }
305 {
306 // we shall ignore signedness like snprintf
307 static_assert(true == jau::cfmt::check(" int -> int %d", 1));
308 static_assert(true == jau::cfmt::check("unsigned int -> int %d", (unsigned int)1));
309 static_assert(true == jau::cfmt::check("unsigned int -> unsigned int %u", (unsigned int)1));
310 static_assert(true == jau::cfmt::check(" int -> unsigned int %u", 1));
311 static_assert(true == jau::cfmt::check(" char -> int %d", (char)1)); // integral target type > given type
312 {
313 jau::cfmt::PResult res = jau::cfmt::checkR(" error long -> int %d", (long)1);
314 // if( res.error() ) {
315 printf("XXX: sizeof(long) %zu, %s\n", sizeof(long), res.toString().c_str());
316 }
317 if constexpr ( sizeof(long) <= 4 ) {
318 assert(true == jau::cfmt::check(" OK long(4) -> int %d", (long)1)); // NOLINT(misc-static-assert)
319 } else {
320 assert(false == jau::cfmt::check(" error long(8) -> int %d", (long)1)); // NOLINT(misc-static-assert); error: integral target type < given type
321 }
322
323 static_assert(true == jau::cfmt::check(" %d", i));
324 static_assert(true == jau::cfmt::check(" %f", fa));
325 static_assert(true == jau::cfmt::check(" %zd", (ssize_t)1));
326 static_assert(true == jau::cfmt::check(" %zu", (size_t)1));
327 static_assert(true == jau::cfmt::check(" %" PRIi64 ".", (int64_t)1));
328 static_assert(true == jau::cfmt::check(" %" PRIi64 ".", sz2));
329 static_assert(true == jau::cfmt::check(" %p", pf));
330
331 static_assert(0 == jau::cfmt::checkR("Hello World").argCount());
332 static_assert(1 == jau::cfmt::checkR("Hello World %d", 1).argCount());
333 static_assert(1 == jau::cfmt::checkR("Hello 1 %d", i).argCount());
334 static_assert(true == jau::cfmt::check("Hello World"));
335 static_assert(true == jau::cfmt::check("Hello World %d", 1));
336 static_assert(true == jau::cfmt::check("Hello 1 %d", i));
337
338 static_assert(1 == jau::cfmt::checkR("Hello 1 %.2f", fa).argCount());
339 static_assert(1 == jau::cfmt::checkR("Hello 1 %.2f - end", fa).argCount());
340 static_assert(2 == jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f - end", fa, fb).argCount());
341 static_assert(3 == jau::cfmt::checkR("Hello 1 %.2f , 2 %2.2f, 3 %zu - end", fa, fb, sz1).argCount());
342 static_assert(4 == jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64 " - end", fa, fb, sz1, sz2).argCount());
343 static_assert(5 == jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64 ", 5 %03d - end", fa, fb, sz1, sz2, i).argCount());
344 // 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).argCount());
345
346 static_assert(false == jau::cfmt::check("Hello World %"));
347 static_assert(0 > jau::cfmt::checkR("Hello World %").argCount());
348 static_assert(0 > jau::cfmt::checkR("Hello 1 %d").argCount());
349 static_assert(-1 == jau::cfmt::checkR("Hello 1 %d", fa).argCount());
350 if constexpr ( sizeof(long) <= 4 ) {
351 assert( 1 == jau::cfmt::checkR("Hello 1 %d", sz1).argCount()); // NOLINT(misc-static-assert)
352 } else {
353 assert(-1 == jau::cfmt::checkR("Hello 1 %d", sz1).argCount()); // NOLINT(misc-static-assert)
354 }
355 static_assert(-6 == jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64 ", 5 %03d, 6 %p - end",
356 fa, fb, sz1, sz2, i, i).argCount());
357 static_assert(false == jau::cfmt::check("Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64 ", 5 %03d, 6 %p - end",
358 fa, fb, sz1, sz2, i, i));
359
360 const std::string s = jau_format_string_static("format_020a: %f, %f, %zu, %" PRIu64 ", %d\n",
361 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, sz2 + 1_u64, i + 1);
362 (void)s;
363 }
364 {
365 constexpr bool b1 = std::is_nothrow_assignable_v<int&, uint64_t>;
366 static_assert( b1, "Not Assignable" );
367 constexpr bool b2 = std::is_nothrow_assignable_v<unsigned int&, long double>;
368 static_assert( b2, "Not Assignable" );
370 jau_format_string_static("Hello %d", (int)2);
371 jau_format_string_static("Hello %d", (unsigned int)2);
372 jau_format_string_static("Hello %u", (unsigned int)2);
373 jau_format_string_static("Hello %u", (int)2);
374
375 // constexpr std::string_view fmt2 = "Hello %d"sv;
376 // format_string_static2("Hello %d"sv, (int)2);
377 // format_string_static2("Hello %d"s, (int)2);
378
379 constexpr jau::cfmt::PResult c1 = jau::cfmt::checkR("Hello %u", (unsigned int)1);
380 std::cerr << "XXX: " << __LINE__ << ": " << c1 << std::endl;
381 REQUIRE(false == c1.error());
382 }
383 {
384 constexpr jau::cfmt::PResult c1 = jau::cfmt::checkR("Hello World");
385 REQUIRE(false == c1.error());
386 REQUIRE(0 == c1.argCount());
387 REQUIRE(0 == jau::cfmt::checkR("Hello World").argCount());
388 constexpr jau::cfmt::PResult c3 = jau::cfmt::checkR("Hello 1 %d", i);
389 REQUIRE(false == c3.error());
390 REQUIRE(1 == c3.argCount());
391 REQUIRE(9 == std::snprintf(buf, sizeof(buf), "Hello 1 %d", i));
392
393 // `Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %li, 5 %03d, 6 %p - end`
394 REQUIRE(1 == jau::cfmt::checkR("Hello 1 %.2f", fa).argCount());
395 REQUIRE(1 == jau::cfmt::checkR("Hello 1 %.2f - end", fa).argCount());
396
397 // 'Hello 1 %.2f, 2 %2.2f - end'
398 jau::cfmt::PResult pc = jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f - end", fa, fb);
399 std::cerr << "XXX: " << __LINE__ << ": " << pc << std::endl;
400 REQUIRE(2 == jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f - end", fa, fb).argCount());
401
402 // `Hello 1 %.2f, 2 %2.2f, 3 %zu - end`
403 pc = jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f, 3 %zu - end", fa, fb, sz1);
404 std::cerr << "XXX: " << __LINE__ << ": " << pc << std::endl;
405 REQUIRE(3 == jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f, 3 %zu - end", fa, fb, sz1).argCount());
406
407 REQUIRE(4 == jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64 " - end", fa, fb, sz1, sz2).argCount());
408 REQUIRE(5 == jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64 ", 5 %03d - end", fa, fb, sz1, sz2, i).argCount());
409 REQUIRE(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).argCount());
410
411 // REQUIRE(13 == std::snprintf(buf, sizeof(buf), "Hello World %").argCount());
412 REQUIRE(0 > jau::cfmt::checkR("Hello World %").argCount());
413 REQUIRE(0 > jau::cfmt::checkR("Hello 1 %d").argCount());
414 REQUIRE(-1 == jau::cfmt::checkR("Hello 1 %d", fa).argCount());
415 if constexpr ( sizeof(long) <= 4 ) {
416 REQUIRE( 1 == jau::cfmt::checkR("Hello 1 %d", sz1).argCount());
417 } else {
418 REQUIRE(-1 == jau::cfmt::checkR("Hello 1 %d", sz1).argCount());
419 }
420 REQUIRE(-6 == jau::cfmt::checkR("Hello 1 %.2f, 2 %2.2f, 3 %zu, 4 %" PRIi64 ", 5 %03d, 6 %p - end",
421 fa, fb, sz1, sz2, i, i).argCount());
422 }
423}
424
425TEST_CASE("jau::cfmt_01", "[jau][std::string][format_string]") {
426 format_0a();
427 format_0b();
428}
429
430/// Execute with `test_stringfmt --perf_analysis`
431TEST_CASE("jau::cfmt_10", "[benchmark][jau][std::string][format_string]") {
432 const size_t loops = 1000; // catch_auto_run ? 1000 : 1000;
433 WARN("Benchmark with " + std::to_string(loops) + " loops");
434 CHECK(true);
435
436 BENCHMARK("fmt__check bench") {
437 volatile size_t res = 0;
438 for( size_t i = 0; i < loops; ++i ) {
439 float fa = 1.1f, fb = 2.2f;
440 size_t sz1 = 1;
441 uint64_t sz2 = 2;
442 int i1 = 3;
443
444 size_t r = jau::cfmt::checkR("format_check: %.2f, %2.2f, %zu, %" PRIu64 ", %03d\n",
445 fa, fb, sz1, sz2, i1).argCount();
446 REQUIRE(5 == r);
447 res = res + r;
448 }
449 return res;
450 };
451 BENCHMARK("fmt__check cnstexpr bench") {
452 volatile size_t res = 0;
453 for( size_t i = 0; i < loops; ++i ) {
454 constexpr float fa = 1.1f, fb = 2.2f;
455 constexpr size_t sz1 = 1;
456 constexpr uint64_t sz2 = 2;
457 constexpr int i1 = 3;
458
459 constexpr jau::cfmt::PResult pc = jau::cfmt::checkR("format_check: %.2f, %2.2f, %zu, %" PRIu64 ", %03d\n",
460 fa, fb, sz1, sz2, i1);
461 constexpr size_t r = pc.argCount();
462 REQUIRE(5 == r);
463 res = res + r;
464 }
465 return res;
466 };
467 BENCHMARK("fmt__check cnstexp2 bench") {
468 volatile size_t res = 0;
469 for( size_t i = 0; i < loops; ++i ) {
470 constexpr float fa = 1.1f, fb = 2.2f;
471 constexpr size_t sz1 = 1;
472 constexpr uint64_t sz2 = 2;
473 constexpr int i1 = 3;
474
475 constexpr jau::cfmt2::PResult pc = jau::cfmt2::checkR("format_check: %.2f, %2.2f, %zu, %" PRIu64 ", %03d\n",
476 fa, fb, sz1, sz2, i1);
477 constexpr size_t r = pc.argCount();
478 REQUIRE(5 == r);
479 res = res + r;
480 }
481 return res;
482 };
483 BENCHMARK("format_000a_vsnprintf bench") {
484 volatile size_t res = 0;
485 for( size_t i = 0; i < loops; ++i ) {
486 res = res + test_format(format_000a_vsnprintf, false);
487 }
488 return res;
489 };
490 BENCHMARK("format_010a_vsnprintf bench") {
491 volatile size_t res = 0;
492 for( size_t i = 0; i < loops; ++i ) {
493 res = res + test_format(format_010a_vsnprintf, false);
494 }
495 return res;
496 };
497 BENCHMARK("fmt__020a macro bench") {
498 volatile size_t res = 0;
499 for( size_t i = 0; i < loops; ++i ) {
500 {
501 constexpr float fa = 1.1f, fb = 2.2f;
502 constexpr size_t sz1 = 1;
503 constexpr uint64_t a_u64 = 2;
504 constexpr int j = 3;
505 const std::string s = jau_format_string_static("format_020a: %f, %f, %zu, %" PRIu64 ", %d\n",
506 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, a_u64 + 1_u64, j + 1);
507 res = res + s.length();
508 }
509 }
510 return res;
511 };
512 BENCHMARK("fmt__020a cnstexpr-in bench") {
513 volatile size_t res = 0;
514 for( size_t i = 0; i < loops; ++i ) {
515 {
516 constexpr float fa = 1.1f, fb = 2.2f;
517 constexpr size_t sz1 = 1;
518 constexpr uint64_t a_u64 = 2;
519 constexpr int j = 3;
520 if constexpr( jau::cfmt::check("format_020a: %f, %f, %zu, %" PRIu64 ", %d\n",
521 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, a_u64 + 1_u64, j + 1) ) {
522 std::string s;
523 s.reserve(1023 + 1); // incl. EOS
524 s.resize(1023); // excl. EOS
525
526 // -Wformat=2 -> -Wformat -Wformat-nonliteral -Wformat-security -Wformat-y2k
527 // -Wformat=2 -Wformat-overflow=2 -Wformat-signedness
530 const size_t nchars = std::snprintf(&s[0], 1023 + 1, "format_020a: %f, %f, %zu, %" PRIu64 ", %d\n",
531 fa + 1.0_f32, fb + 1.0_f32, sz1 + 1, a_u64 + 1_u64, j + 1);
533 if( nchars < 1023 + 1 ) {
534 s.resize(nchars);
535 s.shrink_to_fit();
536 } // else truncated w/ nchars > MaxStrLen
537 res = res + s.length();
538 }
539 }
540 }
541 return res;
542 };
543 BENCHMARK("fmt__020a_tsnprintf bench") {
544 volatile size_t res = 0;
545 for( size_t i = 0; i < loops; ++i ) {
546 res = res + test_format(format_020a_tsnprintf, false);
547 }
548 return res;
549 };
550 BENCHMARK("format_030a_strstream bench") {
551 volatile size_t res = 0;
552 for( size_t i = 0; i < loops; ++i ) {
553 res = res + test_format(format_030a_strstream, false);
554 }
555 return res;
556 };
557#ifdef HAS_STD_FORMAT
558 BENCHMARK("format_040a_stdformat bench") {
559 volatile size_t res = 0;
560 for( size_t i = 0; i < iterations; ++i ) {
561 res = res + test_format(format_040a_stdformat, false);
562 }
563 return res;
564 };
565#endif
566
567 BENCHMARK("format_000b_vsnprintf bench") {
568 volatile size_t res = 0;
569 for( size_t i = 0; i < loops; ++i ) {
570 res = res + test_format(format_000b_vsnprintf, false);
571 }
572 return res;
573 };
574 BENCHMARK("format_010b_vsnprintf bench") {
575 volatile size_t res = 0;
576 for( size_t i = 0; i < loops; ++i ) {
577 res = res + test_format(format_010b_vsnprintf, false);
578 }
579 return res;
580 };
581 BENCHMARK("format_020b__snprintf bench") {
582 volatile size_t res = 0;
583 for( size_t i = 0; i < loops; ++i ) {
584 res = res + test_format(format_020b_tsnprintf, false);
585 }
586 return res;
587 };
588 BENCHMARK("format_030b_strstream bench") {
589 volatile size_t res = 0;
590 for( size_t i = 0; i < loops; ++i ) {
591 res = res + test_format(format_030b_strstream, false);
592 }
593 return res;
594 };
595#ifdef HAS_STD_FORMAT
596 BENCHMARK("format_040b_stdformat bench") {
597 volatile size_t res = 0;
598 for( size_t i = 0; i < iterations; ++i ) {
599 res = res + test_format(format_040b_stdformat, false);
600 }
601 return res;
602 };
603#endif
604}
#define PRAGMA_DISABLE_WARNING_PUSH
#define PRAGMA_DISABLE_WARNING_POP
#define PRAGMA_DISABLE_WARNING_FORMAT_NONLITERAL
constexpr std::string format_string_v(const std::size_t maxStrLen, const std::string_view format, const Args &...args)
Safely returns a string according to printf() formatting rules and variable number of arguments follo...
constexpr const PResult checkR(const std::string_view fmt, const Targs &...) noexcept
Strict type validation of arguments against the format string.
constexpr bool check(const std::string_view fmt, const Targs &...) noexcept
Strict type validation of arguments against the format string.
constexpr bool check2(const std::string_view fmt) noexcept
Strict type validation of arguments against the format string.
constexpr PResult checkR(const std::string_view fmt, const Targs &...) noexcept
Strict type validation of arguments against the format string.
std::string format_string(const char *format,...)
Returns a string according to printf() formatting rules and variable number of arguments following th...
constexpr bool check3(StrView fmt) noexcept
constexpr const PResult checkRec(const PResult ctx) noexcept
#define jau_format_string_static(...)
constexpr ssize_t argCount() const noexcept
constexpr bool error() const noexcept
constexpr ssize_t argCount() const noexcept
std::string toString() const
static int loops
int printf(const char *format,...)
Operating Systems predefined macros.
std::string format_020b_tsnprintf(float fa, float fb, size_t sz1, uint64_t a_u64, int i)
std::string format_030b_strstream(float fa, float fb, size_t sz1, uint64_t a_u64, int i)
constexpr jau::cfmt2::PResult check(const std::string_view fmt, const Targs &...) noexcept
std::string format_010a_vsnprintf(float fa, float fb, size_t sz1, uint64_t a_u64, int i)
std::string format_030a_strstream(float fa, float fb, size_t sz1, uint64_t a_u64, int i)
std::string format_010b_vsnprintf(float fa, float fb, size_t sz1, uint64_t a_u64, int i)
constexpr std::string format_string000(const std::size_t maxStrLen, const std::string_view format, const Args &...args)
size_t test_format(const Func func, bool output)
void format_0b()
constexpr std::string format_string_static3(const std::string_view format, const Targs &...args)
constexpr std::string format_string_static2(const std::string_view fmt, const Args &...)
std::string format_000b_vsnprintf(float fa, float fb, size_t sz1, uint64_t a_u64, int i)
void format_0a()
std::string format_000a_vsnprintf(float fa, float fb, size_t sz1, uint64_t a_u64, int i)
TEST_CASE("jau::cfmt_00", "[jau][std::string][jau::cfmt]")
constexpr std::string format_020a_tsnprintf(float fa, float fb, size_t sz1, uint64_t a_u64, int i)