ryml provides facilities for formatting/deformatting (imported from c4core into the ryml namespace).
3279{
3280
3281 {
3282 char buf_[256] = {};
3284 size_t size =
ryml::format(buf,
"a={} foo {} {} bar {}", 0.1, 10, 11, 12);
3285 CHECK(size == strlen(
"a=0.1 foo 10 11 bar 12"));
3286 CHECK(buf.
first(size) ==
"a=0.1 foo 10 11 bar 12");
3287
3288
3289 size =
ryml::format({} ,
"a={} foo {} {} bar {}",
"this_is_a", 10, 11, 12);
3290 CHECK(size ==
ryml::format(buf,
"a={} foo {} {} bar {}",
"this_is_a", 10, 11, 12));
3291 CHECK(size == strlen(
"a=this_is_a foo 10 11 bar 12"));
3292
3293 char smallbuf[8] = {};
3294 size =
ryml::format(smallbuf,
"{} is too large {}",
"this",
"for the buffer");
3295 CHECK(size == strlen(
"this is too large for the buffer"));
3296
3298
3299
3301 CHECK(result ==
"b=1, damn it.");
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318 std::string sbuf;
3320 CHECK(sbuf ==
"and c=2 seems about right");
3321 std::vector<char> vbuf;
3323 CHECK(sbuf ==
"and c=2 seems about right");
3324
3326 CHECK(sbuf ==
"and c=2 seems about right, and finally d=3 - done");
3327 }
3328
3329
3330 {
3331 char buf_[256];
3332
3333 int a = 0, b = 1, c = 2;
3335 CHECK(result ==
"0 and 1 and 2");
3336 int aa = -1, bb = -2, cc = -3;
3337 size_t num_characters =
ryml::unformat(result,
"{} and {} and {}", aa, bb, cc);
3343
3345 CHECK(result ==
"10 and 20 and 30");
3346 num_characters =
ryml::unformat(result,
"{} and {} and {}", aa, bb, cc);
3352 }
3353
3354
3355 {
3356 char buf_[256] = {};
3358 size_t size =
ryml::cat(buf,
"a=", 0.1,
"foo", 10, 11,
"bar", 12);
3359 CHECK(size == strlen(
"a=0.1foo1011bar12"));
3360 CHECK(buf.
first(size) ==
"a=0.1foo1011bar12");
3361
3362
3364
3365 char smallbuf[8] = {};
3366 size =
ryml::cat(smallbuf,
"this",
" is too large ",
"for the buffer");
3367 CHECK(size == strlen(
"this is too large for the buffer"));
3368
3370
3371
3373 CHECK(result ==
"b=1, damn it.");
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390 std::string sbuf;
3391 ryml::catrs(&sbuf,
"and c=", 2,
" seems about right");
3392 CHECK(sbuf ==
"and c=2 seems about right");
3393 std::vector<char> vbuf;
3394 ryml::catrs(&vbuf,
"and c=", 2,
" seems about right");
3395 CHECK(sbuf ==
"and c=2 seems about right");
3396
3398 CHECK(sbuf ==
"and c=2 seems about right, and finally d=3 - done");
3399 }
3400
3401
3402 {
3403 char buf_[256];
3404
3405 int a = 0, b = 1, c = 2;
3407 CHECK(result ==
"0 1 2");
3408 int aa = -1, bb = -2, cc = -3;
3409 char sep1 = 'a', sep2 = 'b';
3410 size_t num_characters =
ryml::uncat(result, aa, sep1, bb, sep2, cc);
3417
3419 CHECK(result ==
"10 20 30");
3420 num_characters =
ryml::uncat(result, aa, sep1, bb, sep2, cc);
3427 }
3428
3429
3430 {
3431 char buf_[256] = {};
3433
3434 size_t size =
ryml::catsep(buf,
' ',
"a=", 0,
"b=", 1,
"c=", 2, 45, 67);
3435 CHECK(buf.
first(size) ==
"a= 0 b= 1 c= 2 45 67");
3436
3437
3438 size =
ryml::catsep(buf,
" and ",
"a=0",
"b=1",
"c=2", 45, 67);
3439 CHECK(buf.
first(size) ==
"a=0 and b=1 and c=2 and 45 and 67");
3440
3441 size =
ryml::catsep(buf,
" ... ",
"a=0",
"b=1",
"c=2", 45, 67);
3442 CHECK(buf.
first(size) ==
"a=0 ... b=1 ... c=2 ... 45 ... 67");
3443
3444 size =
ryml::catsep(buf,
'/',
"a=", 0,
"b=", 1,
"c=", 2, 45, 67);
3445 CHECK(buf.
first(size) ==
"a=/0/b=/1/c=/2/45/67");
3446
3447 size =
ryml::catsep(buf, 888,
"a=0",
"b=1",
"c=2", 45, 67);
3448 CHECK(buf.
first(size) ==
"a=0888b=1888c=28884588867");
3449
3450
3451
3453
3454 char smallbuf[8] = {};
3456 CHECK(size == strlen(
"a=0888b=1888c=28884588867"));
3457
3459
3460
3462 CHECK(result ==
"a=0 and b=1 and c=2 and 45 and 67");
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479 std::string sbuf;
3481 CHECK(sbuf ==
"a=0 and b=1 and c=2 and 45 and 67");
3482 std::vector<char> vbuf;
3485
3486
3488 CHECK(sbuf ==
"a=0 and b=1 and c=2 and 45 and 67 --- a=0 well b=11 well c=12 well 145 well 167");
3489 }
3490
3491
3492 {
3493 char buf_[256] = {};
3494
3495 int a = 0, b = 1, c = 2;
3497 CHECK(result ==
"0 1 2");
3498 int aa = -1, bb = -2, cc = -3;
3504
3506 CHECK(result ==
"10--20--30");
3512 }
3513
3514
3515 {
3516 using namespace ryml;
3517 char buf_[256] = {};
3519
3520
3521
3522
3525
3528
3529
3530
3531
3536 CHECK(
"3735928559" ==
cat_sub(buf, UINT32_C(0xdeadbeef)));
3538
3539
3540
3549
3550
3551
3562
3563
3564
3575
3576
3577
3585
3592
3593
3594
3602
3609
3610
3611
3612
3613
3634
3640
3646
3652
3655
3656
3657
3658
3659 {
3660 C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH("-Wcast-align")
3661 const uint32_t payload[] = {10, 20, 30, 40, UINT32_C(0xdeadbeef)};
3662
3663 csubstr expected =
csubstr((
const char *)payload,
sizeof(payload));
3667
3668 for(const uint32_t value : payload)
3669 {
3670
3671 expected =
csubstr((
const char *)&value,
sizeof(value));
3673 CHECK(actual.
size() ==
sizeof(uint32_t));
3676
3678 CHECK(actual.
size() ==
sizeof(uint32_t));
3681
3682
3683 uint32_t result = 0;
3686
3687
3688 CHECK(result == value);
3689 }
3690 C4_SUPPRESS_WARNING_GCC_CLANG_POP
3691 }
3692
3693
3694
3695
3696 }
3697}
right_< T > right(T val, size_t width, char padchar=' ')
tag function to mark an argument to be aligned right
left_< T > left(T val, size_t width, char padchar=' ')
tag type to mark an argument to be aligned left.
csubstr catrs_append(CharOwningContainer *cont, Args const &...args)
cat+resize+append: like c4::cat(), but receives a container, and appends to it instead of overwriting...
size_t cat(substr buf, Arg const &a, Args const &...more)
serialize the arguments, concatenating them to the given fixed-size buffer.
void catrs(CharOwningContainer *cont, Args const &...args)
cat+resize: like c4::cat(), but receives a container, and resizes it as needed to contain the result.
substr cat_sub(substr buf, Args const &...args)
like c4::cat() but return a substr instead of a size
csubstr catseprs_append(CharOwningContainer *cont, Sep const &sep, Args const &...args)
catsep+resize+append: like c4::catsep(), but receives a container, and appends the arguments,...
void catseprs(CharOwningContainer *cont, Sep const &sep, Args const &...args)
catsep+resize: like c4::catsep(), but receives a container, and resizes it as needed to contain the r...
size_t catsep(substr buf, Sep const &sep, Arg const &a, Args const &...more)
serialize the arguments, concatenating them to the given fixed-size buffer, using a separator between...
substr catsep_sub(substr buf, Args &&...args)
like c4::catsep() but return a substr instead of a size
@ FTOA_FLEX
print the real number in flexible format (like g)
@ FTOA_SCIENT
print the real number in scientific format (like e)
@ FTOA_FLOAT
print the real number in floating point format (like f)
@ FTOA_HEXA
print the real number in hexadecimal format (like a)
integral_< intptr_t > hex(std::nullptr_t)
format null as an hexadecimal value
integral_< intptr_t > oct(std::nullptr_t)
format null as an octal value
integral_< intptr_t > bin(std::nullptr_t)
format null as a binary 0-1 value
const_raw_wrapper raw(cblob data, size_t alignment=alignof(max_align_t))
mark a variable to be written in raw binary format, using memcpy
const_raw_wrapper craw(cblob data, size_t alignment=alignof(max_align_t))
mark a variable to be written in raw binary format, using memcpy
real_< T > real(T val, int precision, RealFormat_e fmt=FTOA_FLOAT)
csubstr to_csubstr(const char(&s)[N]) noexcept
basic_substring< char > substr
a mutable string view
size_t uncat(csubstr buf, Arg &a, Args &...more)
deserialize the arguments from the given buffer.
size_t uncatsep(csubstr buf, csubstr sep, Arg &a, Args &...more)
deserialize the arguments from the given buffer, using a separator.
integral_padded_< T > zpad(T val, size_t num_digits)
pad the argument with zeroes on the left, with decimal radix
size_t size() const noexcept
bool overlaps(ro_substr const that) const noexcept
true if there is overlap of at least one element between that and *this
basic_substring first(size_t num) const noexcept
return the first num elements: [0,num[
bool is_sub(ro_substr const that) const noexcept
true if *this is a substring of that (ie, from the same buffer)