Skip site navigation (1)Skip section navigation (2)

  
 
  

home | help
LIBFYAML-MISC(3)		    libfyaml			LIBFYAML-MISC(3)

NAME
     libfyaml-misc - libfyaml miscellaneous API

UTILITIES
     This header provides the low-level building blocks shared by all other lib-
     fyaml  public  headers.   It has no libfyaml dependencies of its own and is
     safe to include in isolation.

     Platform portability

     * ssize_t shim for MSVC / Windows toolchains

     * struct iovec shim for Windows (sys/uio.h substitute)

     * FY_EXPORT / FY_DEPRECATED  /  FY_FORMAT	a  symbol  visibility  and  com-
       piler-attribute portability macros

     * FY_UNUSED,  FY_ALWAYS_INLINE,  FY_DEBUG_UNUSED  a  compiler hint wrappers
       with safe fallbacks on non-GCC/Clang toolchains

     * FY_CONSTRUCTOR / FY_DESTRUCTOR a GCC-style constructor/destructor attrib-
       utes with availability guards (FY_HAS_CONSTRUCTOR, FY_HAS_DESTRUCTOR)

     Core constants and sentinel values

     * FY_BIT(x)   a single-bit mask (1U << x)

     * FY_NT	   a sentinel meaning anull-terminateda; pass as a length  argu-
       ment to indicate that the string length should be inferred via strlen

     Memory helpers

     * FY_ALLOCA_COPY_FREE  /  FY_ALLOCA_COPY_FREE_NO_NULL  a  copy a malloc-re-
       turned string onto the stack and immediately free  the  heap  allocation;
       produces an alloca-lifetime copy in a single expression

     * fy_vsprintfa  /	fy_sprintfa a printf-style formatting into a stack-allo-
       cated (alloca) buffer; the result is valid for the lifetime  of	the  en-
       closing function

     Container and array helpers

     * container_of a recover a pointer to an enclosing struct from a pointer to
       one of its members

     * ARRAY_SIZE   a number of elements in a stack-allocated array

     Type safety and compile-time checks

     * FY_SAME_TYPE / FY_CHECK_SAME_TYPE a assert two expressions share the same
       C type (wraps __builtin_types_compatible_p with a fallback)

     * FY_COMPILE_ERROR_ON_ZERO a produce a compile-time error when the argument
       evaluates to zero; used for macro-level static assertions

     Overflow-safe arithmetic

     * FY_ADD_OVERFLOW,   FY_SUB_OVERFLOW,  FY_MUL_OVERFLOW  a	wrappers  around
       __builtin_*_overflow with portable fallback implementations

     Miscellaneous

     * FY_IMPOSSIBLE_ABORT a mark unreachable code paths; aborts at runtime

     * FY_STACK_SAVE / FY_STACK_RESTORE a save and restore the stack pointer for
       alloca-based temporary arenas

     * Lambda / closure macros and a CPP metaprogramming framework for	building
       variadic generic APIs

     * Diagnostic helpers and floating-point precision constants

     This  section implements a portable FY_CPP_* macro toolkit that enables ap-
     plying an operation to every argument in a __VA_ARGS__ list a  the  equiva-
     lent of a compile-time map() function.

     The  core challenge: The C preprocessor does not support recursion. A macro
     cannot call itself. The standard workaround is deferred evaluation: a macro
     is apostponeda so that it is not expanded in the current scan pass, only in
     a future one.  Multiple passes are forced by the FY_CPP_EVALn ladder  which
     re-expands the token stream a power-of-two number of times.

     Evaluation levels (FY_CPP_EVAL1 .. FY_CPP_EVAL):

     * FY_CPP_EVAL1  a one pass (no re-expansion)

     * FY_CPP_EVAL2  a 2 passes

     * FY_CPP_EVAL4  a 4 passes

     * FY_CPP_EVAL8  a 8 passes

     * FY_CPP_EVAL16 a 16 passes (GCC only; Clang craps out at 8)

     * FY_CPP_EVAL   a full depth (32 passes on GCC, 16 on Clang)

     Each  doubling  allows  mapping  over twice as many arguments.  FY_CPP_EVAL
     supports lists of up to ~32 elements (GCC) or ~16 elements (Clang) in prac-
     tice.

     Argument accessors a extract positional arguments from __VA_ARGS__:

     * FY_CPP_FIRST(...)  a first argument (0 if list is empty)

     * FY_CPP_SECOND(...) a second argument

     * FY_CPP_THIRD(...)  a third argument

     * FY_CPP_FOURTH(...) a fourth argument

     * FY_CPP_FIFTH(...)  a fifth argument

     * FY_CPP_SIXTH(...)  a sixth argument

     * FY_CPP_REST(...)   a all arguments after the first (empty if < 2)

     Map operations:

     * FY_CPP_MAP(macro, ...) a expand macro(x) for each argument x.

     * FY_CPP_MAP2(a, macro, ...) a expand macro(a, x) for each x,  threading  a
       fixed first argument a through every call.

     Utility:

     * FY_CPP_VA_COUNT(...)	    a number of arguments (integer expression).

     * FY_CPP_VA_ITEMS(_type,  ...)   a  compound-literal  array  of  _type from
       varargs.

     * FY_CPP_EMPTY()		    a deferred empty  token  (used  to	postpone
       macros).

     * FY_CPP_POSTPONE1(macro)	    a postpone a one-argument macro one pass.

     * FY_CPP_POSTPONE2(a, macro)   a postpone a two-argument macro one pass.

     Short-name mode (FY_CPP_SHORT_NAMES):

     By  default  the  implementation uses abbreviated internal names (_E1, _FM,
     etc.)    to    reduce    token-expansion	 buffer     pressure.	  Define
     FY_CPP_SHORT_NAMES_DEBUG before including this header to force the original
     long-name	implementation	(FY_CPP_EVAL1,	_FY_CPP_MAP_ONE,  etc.) which is
     easier to read in expansion traces.

     Example:

	// Count and collect variadic integer arguments into a C array:
	int do_sum(int count, int *items) { ... }

	#define do_sum_macro(...) \
	    do_sum(FY_CPP_VA_COUNT(__VA_ARGS__), \
		   FY_CPP_VA_ITEMS(int, __VA_ARGS__))

	// do_sum_macro(1, 2, 5, 100) expands to:
	// do_sum(4, ((int [4]){ 1, 2, 5, 100 }))

     Portable wrappers around GCC/Clang #pragma GCC diagnostic directives.   Use
     FY_DIAG_PUSH() and FY_DIAG_POP() to bracket a region where a specific warn-
     ing is suppressed:

	FY_DIAG_PUSH
	FY_DIAG_IGNORE_ARRAY_BOUNDS
	... code that triggers -Warray-bounds ...
	FY_DIAG_POP

     On  compilers other than GCC/Clang all macros in this group expand to noth-
     ing.

     Portable wrappers for the mantissa-digit and decimal-digit counts of float,
     double, and long double.  Each macro tries three sources in order:

     1. The standard <float.h> macro (e.g. FLT_MANT_DIG).

     2. The GCC/Clang predefined macro (e.g. __FLT_MANT_DIG__).

     3. A conservative hard-coded fallback.

     These constants are used when  formatting	floating-point	values	as  YAML
     scalars to ensure round-trip fidelity.

   macro __has_builtin
     __has_builtin(x)
	    Fallback for compilers that do not provide __has_builtin.

	    Parameters

		   * x a The builtin name to query.

   Description
     Always  evaluates	to  0  (false) so that all #if __has_builtin(...) guards
     safely fall back to the portable implementation.

   Return
     0.

   macro FY_BIT
     FY_BIT(x)
	    Produce an unsigned bitmask with bit x set.

	    Parameters

		   * x a Zero-based bit position (0a31 for a 32-bit result).

   Return
     1U << x.

   macro FY_NT
     FY_NT()
	    Sentinel value meaning anull-terminated; compute length at runtimea.

   Description
     Pass as the len argument to any libfyaml function	that  accepts  a  (const
     char  *str,  size_t  len)	pair  to indicate that str is a NUL-terminated C
     string whose length should be determined with strlen().

     Value: (size_t)-1

   macro FY_EXPORT
     FY_EXPORT()
	    Mark a symbol as part of the shared-library public ABI.

   Description
     On GCC/Clang  (version  >=  4)  expands  to  __attribute__((visibility("de-
     fault"))),  overriding  -fvisibility=hidden  for  the annotated symbol.  On
     other compilers expands to nothing (all symbols are visible by default).

   macro FY_DEPRECATED
     FY_DEPRECATED()
	    Mark a function or variable as deprecated.

   Description
     On GCC/Clang expands to __attribute__((deprecated)), causing a compile-time
     warning whenever the annotated symbol is used.  On other compilers  expands
     to nothing.

   macro FY_FORMAT
     FY_FORMAT(_t, _x, _y)
	    Annotate a function with printf-style format checking.

	    Parameters

		   * _t a Format type token (e.g. printf, scanf, strftime).

		   * _x a 1-based index of the format-string parameter.

		   * _y  a  1-based  index of the first variadic argument (0 for
		     va_list wrappers).

   Description
     On GCC/Clang expands to __attribute__((format(_t, _x, _y))),  enabling  the
     compiler to type-check the format string and variadic arguments.

   macro FY_ALLOCA_COPY_FREE
     FY_ALLOCA_COPY_FREE(_str, _len)
	    Copy a heap string onto the stack and free the original.

	    Parameters

		   * _str  a  Heap-allocated  string  to  copy	and free (may be
		     NULL).

		   * _len a Length in bytes, or FY_NT to use strlen().

   Expands to a statement expression that
     1. Copies _str (up to _len bytes, or the full  NUL-terminated  length  when
	_len is FY_NT) into a NUL-terminated stack buffer via alloca().

     2. Calls free(@_str) to release the heap allocation.

     3. Evaluates to a const char * pointing to the stack copy.

     When _str is NULL the macro evaluates to NULL and performs no copy or free.

     The  stack buffer is valid only for the lifetime of the enclosing function.
     Do not call this in a loop a each invocation grows the stack frame.

   Return
     const char * to the stack copy, or NULL if _str was NULL.

   macro FY_ALLOCA_COPY_FREE_NO_NULL
     FY_ALLOCA_COPY_FREE_NO_NULL(_str, _len)
	    Like FY_ALLOCA_COPY_FREE() but returns aa for NULL.

	    Parameters

		   * _str a Heap-allocated string  to  copy  and  free	(may  be
		     NULL).

		   * _len a Length in bytes, or FY_NT to use strlen().

   Description
     Identical to FY_ALLOCA_COPY_FREE but substitutes an empty string literal ""
     when _str is NULL, so callers never receive a NULL pointer.

   Return
     const char * to the stack copy, or "" if _str was NULL.

   macro container_of
     container_of(ptr, type, member)
	    Recover a pointer to a containing struct from a member pointer.

	    Parameters

		   * ptr a Pointer to the member field.

		   * type a Type of the containing struct.

		   * member a Name of the member field within type.

   Description
     Given  a  pointer ptr to a field named member inside a struct of type type,
     returns a pointer to the enclosing type instance.

     Uses __typeof__ to catch type mismatches at compile time (GCC/Clang).

   Return
     Pointer to the containing struct of type type.

   macro ARRAY_SIZE
     ARRAY_SIZE(x)
	    Compute the number of elements in a stack-allocated array.

	    Parameters

		   * x a The array expression.

   Description
     Evaluates to a compile-time constant. Only valid for arrays  with	a  known
     size at compile time (not pointers or VLAs).

   Return
     Number of elements, as a size_t.

   macro FY_UNUSED
     FY_UNUSED()
	    Suppress aunused variable/parametera warnings.

   Description
     On  GCC/Clang  (version >= 4) expands to __attribute__((unused)).	On other
     compilers expands to nothing.

     Use on parameters or local variables that are  intentionally  unreferenced,
     e.g. in debug-only code paths.

   macro FY_CONSTRUCTOR
     FY_CONSTRUCTOR()
	    Run a function automatically before main().

   Description
     On   GCC/Clang   expands	to  __attribute__((constructor)).  Also  defines
     FY_HAS_CONSTRUCTOR so callers can detect support at compile time.	On other
     compilers expands to nothing and FY_HAS_CONSTRUCTOR is not defined.

   macro FY_DESTRUCTOR
     FY_DESTRUCTOR()
	    Run a function automatically after main() (or on exit()).

   Description
     On  GCC/Clang  expands   to   __attribute__((destructor)).   Also	 defines
     FY_HAS_DESTRUCTOR	so callers can detect support at compile time.	On other
     compilers expands to nothing and FY_HAS_DESTRUCTOR is not defined.

   macro FY_DEBUG_UNUSED
     FY_DEBUG_UNUSED()
	    Mark a variable as potentially unused in non-debug builds.

   Description
     Expands to __attribute__((unused)) on GCC/Clang when NDEBUG is defined, si-
     lencing warnings for variables that are  only  referenced	inside	assert()
     calls  (which  disappear  in  release builds).  In debug builds (NDEBUG not
     set) expands to nothing.

   macro FY_IMPOSSIBLE_ABORT
     FY_IMPOSSIBLE_ABORT(void)
	    Assert that an unreachable code path has been reached.

	    Parameters

		   * void a no arguments

   Description
     Calls assert(0) followed by abort() to terminate the  process  immediately.
     Use  to  mark code paths that must never execute in a correct program, such
     as the default branch of a switch that covers all enum values.

     The double invocation ensures termination even when assertions are disabled
     (NDEBUG).

   macro FY_COMPILE_ERROR_ON_ZERO
     FY_COMPILE_ERROR_ON_ZERO(_e)
	    Trigger a compile error if expression _e is zero.

	    Parameters

		   * _e a Compile-time expression that must be non-zero.

   Description
     Evaluates _e at compile time. If _e is zero, sizeof(char[-1]) is ill-formed
     and the build fails. If _e is non-zero, the  expression  is  a  no-op  void
     cast.

     Prefer  FY_CHECK_SAME_TYPE or static_assert for clearer error messages; use
     this primitive when a compile-time boolean is needed in a macro context.

   macro FY_SAME_TYPE
     FY_SAME_TYPE(_a, _b)
	    Test whether two expressions have the same type.

	    Parameters

		   * _a a First expression.

		   * _b a Second expression.

   Description
     On GCC/Clang uses __builtin_types_compatible_p to compare the types  of  _a
     and _b (via __typeof__). On compilers without this builtin always evaluates
     to true to avoid false negatives.

   Return
     Non-zero (true) if the types match, zero (false) otherwise.

   macro FY_CHECK_SAME_TYPE
     FY_CHECK_SAME_TYPE(_a, _b)
	    Trigger a compile error if two expressions have different types.

	    Parameters

		   * _a a First expression.

		   * _b a Second expression.

   Description
     Combines  FY_SAME_TYPE and FY_COMPILE_ERROR_ON_ZERO. Use in macros that re-
     quire two operands to have the same type (e.g. overflow-safe arithmetic).

   macro FY_ADD_OVERFLOW
     FY_ADD_OVERFLOW(_a, _b, _resp)
	    Checked addition: detect signed/unsigned integer overflow.

	    Parameters

		   * _a a First operand.

		   * _b a Second operand (must have the same type as _a).

		   * _resp a Pointer to receive  the  result  (written	even  on
		     overflow).

   Description
     On  GCC/Clang maps directly to __builtin_add_overflow(_a, _b, _resp), which
     is a single compiler intrinsic with full type generality.

   On other compilers a portable fallback is used that
     * Requires _a and _b to have the same type (enforced at  compile  time  via
       FY_CHECK_SAME_TYPE).

     * Computes *_resp = _a + _b and returns true if the addition wrapped.

   Return
     true if the addition overflowed, false otherwise.

   macro FY_SUB_OVERFLOW
     FY_SUB_OVERFLOW(_a, _b, _resp)
	    Checked subtraction: detect signed/unsigned integer overflow.

	    Parameters

		   * _a a Minuend.

		   * _b a Subtrahend (must have the same type as _a).

		   * _resp  a  Pointer	to  receive  the result (written even on
		     overflow).

   Description
     On GCC/Clang maps to __builtin_sub_overflow(_a, _b, _resp).   The	portable
     fallback requires _a and _b to have the same type.

   Return
     true if the subtraction overflowed, false otherwise.

   macro FY_MUL_OVERFLOW
     FY_MUL_OVERFLOW(_a, _b, _resp)
	    Checked multiplication: detect signed/unsigned integer overflow.

	    Parameters

		   * _a a First factor.

		   * _b a Second factor (must have the same type as _a).

		   * _resp  a  Pointer	to  receive  the result (written even on
		     overflow).

   Description
     On GCC/Clang maps to __builtin_mul_overflow(_a, _b, _resp).   The	portable
     fallback  requires  _a and _b to have the same type and detects overflow by
     dividing the product back and comparing with the original operand.

   Return
     true if the multiplication overflowed, false otherwise.

   macro fy_sprintfa
     fy_sprintfa(_fmt, ...)
	    Format a string into a stack buffer using inline arguments.

	    Parameters

		   * _fmt a printf-style format string.

		   * ellipsis (ellipsis) a Format arguments.

   Description
     Like fy_vsprintfa() but accepts arguments directly (uses __VA_ARGS__).  Two
     calls to snprintf() are made: the first with a NULL buffer to  measure  the
     required  length,	the  second  to  write the result into a stack-allocated
     buffer.

     The returned pointer is valid only for the lifetime of the enclosing  func-
     tion.

   Return
     char * to a NUL-terminated stack buffer.

   macro FY_CPP_EVAL1
     FY_CPP_EVAL1(...)
	    Force one additional macro-expansion pass.

	    Parameters

		   * ellipsis (ellipsis) a Token sequence to re-expand.

   Description
     Expands  its argument list once. Use as a building block for deeper evalua-
     tion levels; prefer FY_CPP_EVAL() for most uses.

   macro FY_CPP_EVAL2
     FY_CPP_EVAL2(...)
	    Force two additional macro-expansion passes.

	    Parameters

		   * ellipsis (ellipsis) a Token sequence to re-expand.

   macro FY_CPP_EVAL4
     FY_CPP_EVAL4(...)
	    Force four additional macro-expansion passes.

	    Parameters

		   * ellipsis (ellipsis) a Token sequence to re-expand.

   macro FY_CPP_EVAL8
     FY_CPP_EVAL8(...)
	    Force eight additional macro-expansion passes.

	    Parameters

		   * ellipsis (ellipsis) a Token sequence to re-expand.

   macro FY_CPP_EVAL16
     FY_CPP_EVAL16(...)
	    Force 16 additional macro-expansion passes (GCC only).

	    Parameters

		   * ellipsis (ellipsis) a Token sequence to re-expand.

   Description
     Not defined on Clang, which exhausts its expansion buffer	before	reaching
     16  levels.  Wrap	FY_CPP_MAP() / FY_CPP_MAP2() in FY_CPP_EVAL() instead of
     calling this directly.

   macro FY_CPP_EVAL
     FY_CPP_EVAL(...)
	    Force maximum macro-expansion depth.

	    Parameters

		   * ellipsis (ellipsis) a Token sequence to fully expand.

   Description
     On GCC performs 32 expansion passes (supports lists up  to  ~32  elements).
     On Clang performs 16 passes (supports lists up to ~16 elements).

     Always  use  this	(rather  than  a specific EVALn) unless you have a known
     bound on the number of arguments.

   macro FY_CPP_EMPTY
     FY_CPP_EMPTY(void)
	    Produce an empty token sequence (deferred).

	    Parameters

		   * void a no arguments

   Description
     Expands  to  nothing.  Used  in  combination  with   FY_CPP_POSTPONE1()   /
     FY_CPP_POSTPONE2()  to defer macro expansion by one scan pass, breaking the
     preprocessoras blue-paint recursion guard.

   macro FY_CPP_POSTPONE1
     FY_CPP_POSTPONE1(macro)
	    Defer a single-argument macro by one expansion pass.

	    Parameters

		   * macro a Macro token to postpone.

   Description
     Expands to the macro name macro followed by a deferred  FY_CPP_EMPTY(),  so
     the macro call is not completed until the next pass.

   macro FY_CPP_POSTPONE2
     FY_CPP_POSTPONE2(a, macro)
	    Defer a two-argument macro by one expansion pass.

	    Parameters

		   * a a Fixed first argument (carried along, not expanded yet).

		   * macro a Macro token to postpone.

   Description
     Like  FY_CPP_POSTPONE1()  but for macros that take a leading fixed argument
     a.

   macro FY_CPP_FIRST
     FY_CPP_FIRST(...)
	    Extract the first argument from a variadic list.

	    Parameters

		   * ellipsis (ellipsis) a Variadic argument list.

   Description
     Returns the first argument, or 0 if the list is empty.

   Return
     First argument token, or 0.

   macro FY_CPP_SECOND
     FY_CPP_SECOND(...)
	    Extract the second argument from a variadic list.

	    Parameters

		   * ellipsis (ellipsis) a Variadic argument list.

   Description
     Returns the second argument, or 0 if fewer than two arguments are present.

   Return
     Second argument token, or 0.

   macro FY_CPP_THIRD
     FY_CPP_THIRD(...)
	    Extract the third argument.

	    Parameters

		   * ellipsis (ellipsis)  a  Variadic  argument  list.	Returns:
		     Third argument, or 0.

   macro FY_CPP_FOURTH
     FY_CPP_FOURTH(...)
	    Extract the fourth argument.

	    Parameters

		   * ellipsis  (ellipsis)  a  Variadic	argument  list. Returns:
		     Fourth argument, or 0.

   macro FY_CPP_FIFTH
     FY_CPP_FIFTH(...)
	    Extract the fifth argument.

	    Parameters

		   * ellipsis (ellipsis)  a  Variadic  argument  list.	Returns:
		     Fifth argument, or 0.

   macro FY_CPP_SIXTH
     FY_CPP_SIXTH(...)
	    Extract the sixth argument.

	    Parameters

		   * ellipsis  (ellipsis)  a  Variadic	argument  list. Returns:
		     Sixth argument, or 0.

   macro FY_CPP_REST
     FY_CPP_REST(...)
	    Return all arguments after the first.

	    Parameters

		   * ellipsis (ellipsis) a Variadic argument list.

   Description
     Expands to the tail of the variadic list with the	first  element	removed.
     Expands to nothing if the list has zero or one element.

   macro FY_CPP_MAP
     FY_CPP_MAP(macro, ...)
	    Apply a macro to every argument in a variadic list.

	    Parameters

		   * macro a Single-argument macro to apply.

		   * ellipsis (ellipsis) a Arguments to map over.

   Description
     Expands  macro(x) for each argument x in __VA_ARGS__, concatenating all the
     results. The argument list must be  non-empty.  Uses  FY_CPP_EVAL()  inter-
     nally, so the list length is bounded by the evaluation depth.

     For example:

	#define PRINT_ITEM(x)  printf("%d\n", x);
	FY_CPP_MAP(PRINT_ITEM, 1, 2, 3)
	// expands to: printf("%d\n", 1); printf("%d\n", 2); printf("%d\n", 3);

   macro FY_CPP_VA_COUNT
     FY_CPP_VA_COUNT(...)
	    Count the number of arguments in a variadic list.

	    Parameters

		   * ellipsis (ellipsis) a Variadic argument list.

   Description
     Evaluates to a compile-time integer expression equal to the number of argu-
     ments. Returns 0 for an empty list.

   Return
     Integer expression giving the argument count.

   macro FY_CPP_VA_ITEMS
     FY_CPP_VA_ITEMS(_type, ...)
	    Build a compound-literal array from variadic arguments.

	    Parameters

		   * _type a Element type of the resulting array.

		   * ellipsis (ellipsis) a Values to place in the array.

   Description
     Expands  to  a  compound literal of type _type[N] (where N is the number of
     arguments) initialised with the provided values. Useful for passing a vari-
     adic argument list as an array to a function.

     For example:

	// FY_CPP_VA_ITEMS(int, 1, 2, 5, 100)
	// expands to: ((int [4]){ 1, 2, 5, 100 })

   macro FY_CPP_MAP2
     FY_CPP_MAP2(a, macro, ...)
	    Apply a binary macro to every argument, threading a fixed first  ar-
	    gument.

	    Parameters

		   * a a Fixed first argument threaded into every call.

		   * macro a Two-argument macro to apply.

		   * ellipsis (ellipsis) a Arguments to map over.

   Description
     Expands  macro(a, x) for each argument x in __VA_ARGS__. The fixed argument
     a is passed as the first argument to every invocation.

   macro FY_CONCAT
     FY_CONCAT(_a, _b)
	    Token-paste two arguments after full macro expansion.

	    Parameters

		   * _a a Left token (expanded before pasting).

		   * _b a Right token (expanded before pasting).

   Description
     Unlike the raw ## operator, this macro forces both _a and _b  to  be  fully
     expanded  before  concatenation,  so  macro  arguments are substituted cor-
     rectly.

   macro FY_UNIQUE
     FY_UNIQUE(_base)
	    Generate a unique identifier using __COUNTER__.

	    Parameters

		   * _base a Identifier prefix.

   Description
     Concatenates _base with the current value of the  __COUNTER__  preprocessor
     counter,  which increments by one for each use in a translation unit. Guar-
     antees unique names across multiple macro expansions in the same file.

   macro FY_LUNIQUE
     FY_LUNIQUE(_base)
	    Generate a unique identifier using __LINE__.

	    Parameters

		   * _base a Identifier prefix.

   Description
     Like FY_UNIQUE() but  uses  the  current  source  line  number  instead  of
     __COUNTER__.  Sufficient when only one such identifier is needed per source
     line; prefer FY_UNIQUE() in general.

   macro FY_STACK_SAVE
     FY_STACK_SAVE(void)
	    Save the current stack pointer.

	    Parameters

		   * void a no arguments

   Description
     On compilers that provide __builtin_stack_save() (GCC, Clang)  returns  the
     current  stack  pointer  as a void *, allowing it to be restored later with
     FY_STACK_RESTORE(). On other compilers returns (void *)NULL.

     Use together with FY_STACK_RESTORE() to bound the stack growth  of  a  loop
     that calls alloca() on each iteration.

   Return
     Opaque stack pointer value, or NULL if unsupported.

   macro FY_STACK_RESTORE
     FY_STACK_RESTORE(_x)
	    Restore the stack pointer to a previously saved value.

	    Parameters

		   * _x a Value previously returned by FY_STACK_SAVE().

   Description
     On  compilers  that  provide  __builtin_stack_restore()  rewinds  the stack
     pointer to the value captured by FY_STACK_SAVE(). On other  compilers  this
     is a no-op that discards _x.

   macro FY_HAVE_LAMBDAS
     FY_HAVE_LAMBDAS()
	    Defined when the compiler supports anonymous functions.

   Set when either
     * Clang   is  compiling  with  -fblocks  (Blocks  extension)  a  also  sets
       FY_HAVE_BLOCK_LAMBDAS; or

     * GCC is in use a also sets FY_HAVE_NESTED_FUNC_LAMBDAS (nested functions).

     Code using lambdas should guard against this macro and provide  a	fallback
     for environments where it is not defined.

   macro FY_HAVE_BLOCK_LAMBDAS
     FY_HAVE_BLOCK_LAMBDAS()
	    Defined when Clang Block lambdas are available.

   Description
     Set  on  Clang when compiled with -fblocks. Implies FY_HAVE_LAMBDAS.  Block
     lambdas use the ^(args){ body } syntax.

   macro FY_HAVE_NESTED_FUNC_LAMBDAS
     FY_HAVE_NESTED_FUNC_LAMBDAS()
	    Defined when GCC nested-function lambdas are available.

   Description
     Set on GCC. Implies FY_HAVE_LAMBDAS. Nested function lambdas are defined as
     local functions inside the enclosing function and cannot outlive it.

   macro FY_DIAG_PUSH
     FY_DIAG_PUSH()
	    Save the current diagnostic state onto the compileras stack.

   Description
     Always paired with FY_DIAG_POP.

   macro FY_DIAG_POP
     FY_DIAG_POP()
	    Restore the diagnostic state saved by the last FY_DIAG_PUSH.

   macro FY_DIAG_IGNORE
     FY_DIAG_IGNORE(_warn)
	    Suppress a specific warning by pragma string.

	    Parameters

		   * _warn a A string literal suitable for use	in  a  _Pragma()
		     call, e.g. "GCC diagnostic ignored \"-Wsomething\"" .

   macro FY_DIAG_IGNORE_ARRAY_BOUNDS
     FY_DIAG_IGNORE_ARRAY_BOUNDS()
	    Suppress -Warray-bounds in the current region.

   macro FY_DIAG_IGNORE_UNUSED_VARIABLE
     FY_DIAG_IGNORE_UNUSED_VARIABLE()
	    Suppress -Wunused-variable in the current region.

   macro FY_DIAG_IGNORE_UNUSED_PARAMETER
     FY_DIAG_IGNORE_UNUSED_PARAMETER()
	    Suppress -Wunused-parameter in the current region.

   macro FY_FLT_MANT_DIG
     FY_FLT_MANT_DIG()
	    Number of base-2 mantissa digits in a float.

   Description
     Typically 24 (IEEE 754 single precision). Fallback: 9.

   macro FY_DBL_MANT_DIG
     FY_DBL_MANT_DIG()
	    Number of base-2 mantissa digits in a double.

   Description
     Typically 53 (IEEE 754 double precision). Fallback: 17.

   macro FY_LDBL_MANT_DIG
     FY_LDBL_MANT_DIG()
	    Number of base-2 mantissa digits in a long double.

   Description
     Varies  by  platform  (64-bit  x87  extended:  64; MSVC/ARM == double: 53).
     Fallback: 17.

   macro FY_FLT_DECIMAL_DIG
     FY_FLT_DECIMAL_DIG()
	    Decimal digits required for a round-trip float.

   Description
     The minimum number of significant decimal digits  such  that  converting  a
     float  to	decimal and back recovers the original value exactly.  Typically
     9. Fallback: 9.

   macro FY_DBL_DECIMAL_DIG
     FY_DBL_DECIMAL_DIG()
	    Decimal digits required for a round-trip double.

   Description
     Typically 17. Fallback: 17.

   macro FY_LDBL_DECIMAL_DIG
     FY_LDBL_DECIMAL_DIG()
	    Decimal digits required for a round-trip long double.

   Description
     Varies by platform; same as double on most non-x87 targets. Fallback: 17.

ALLOCATOR
     This header exposes libfyamlas pluggable allocator subsystem.  Rather  than
     using malloc/free directly, the library routes certain internal allocations
     through  a  struct fy_allocator.  This lets callers trade memory footprint,
     speed, and deduplication behaviour to match their workload.

     Available strategies (select by name when calling fy_allocator_create()):

     * "linear" a bump-pointer arena.  Allocation is O(1)  and	near-zero  over-
       head;  individual  frees  are a no-op.  Ideal for parse-and-discard work-
       flows where the entire arena is released at once.

     * "malloc" a thin wrapper around the system malloc/free.	Familiar  seman-
       tics;  useful  when individual node lifetimes vary.  Should never be used
       for regular application builds. The  presence  of  it  is  for  having  a
       ASAN/valgrind compatible allocator where buffer overflows can be detected
       easily.

     * "mremap"  a  growable  linear  arena backed by mremap(2).  Avoids copying
       when the arena needs to grow.  While mremap is Linux specific, this allo-
       cator can be configured to use mmap() or malloc() areas where  they  work
       for other platforms.

     * "dedup"	a  content-addressed store built on xxhash hashing.  Stores each
       unique byte sequence exactly once and returns a	shared	pointer  to  all
       callers.   Dramatically	reduces  memory  use when parsing documents with
       many repeated keys or values (e.g. large YAML configurations,  test-suite
       corpora).

     * "auto" a heuristic selection: given a policy. It usually can do the right
       thing and is a safe bet.

     Tags  partition an allocatoras address space.  Obtain a tag with fy_alloca-
     tor_get_tag() and	pass  it  to  every  fy_allocator_alloc()  /  fy_alloca-
     tor_store()  call; release the whole tagas memory in one shot with fy_allo-
     cator_release_tag().  This maps naturally to document lifetimes.

     In-place variants (fy_linear_allocator_create_in_place(),	fy_dedup_alloca-
     tor_create_in_place())  initialise  the  allocator inside a caller-supplied
     buffer a zero dynamic setup cost, useful in stack-allocated or  shared-mem-
     ory contexts.

   fy_allocator_iterate
     const char *fy_allocator_iterate(const char **prevp)
	    Iterate over available allocator names

	    Parameters

		   * prevp  (const  char**)  a	The  previous allocator iterator
		     pointer

   Description
     This method iterates over all the available allocator names.  The start  of
     the iteration is signalled by a NULL in *prevp.

   Return
     The next allocator name in sequence or NULL at the end.

   fy_allocator_is_available
     bool fy_allocator_is_available(const char *name)
	    Check if an allocator is available

	    Parameters

		   * name (const char*) a The name of the allocator to check

   Description
     Check if the named allocator is available.

   Return
     true if the allocator is available, false otherwise

   fy_allocator_create
     struct fy_allocator *fy_allocator_create(const char *name, const void *cfg)
	    Create an allocator.

	    Parameters

		   * name (const char*) a The name of the allocator

		   * cfg (const void*) a The type specific configuration for the
		     allocator, or NULL for the default.

   Description
     Creates  an  allocator  of the given type, using the configuration argument
     provided.	The allocator may  be  destroyed  by  a  corresponding	call  to
     fy_allocator_destroy().

     You  can  retrieve  the  names  of available allocators with the fy_alloca-
     tor_get_names() method.

   Return
     A pointer to the allocator or NULL in case of an error.

   fy_allocator_destroy
     void fy_allocator_destroy(struct fy_allocator *a)
	    Destroy the given allocator

	    Parameters

		   * a (struct fy_allocator*) a The allocator to destroy

   Description
     Destroy an allocator created earlier via  fy_allocator_create().	Tracking
     allocators will release all memory allocated using them.

   fy_linear_allocator_create_in_place
     struct fy_allocator *fy_linear_allocator_create_in_place(void *buffer,
     size_t size)
	    Create a linear allocator in place

	    Parameters

		   * buffer  (void*) a The memory buffer to use for both storage
		     and the allocator

		   * size (size_t) a The size of the memory buffer

   Description
     Creates a linear allocator in place, using the buffer provided.  No  memory
     allocations  will be performed, so itas safe to embed.  There is no need to
     call fy_allocator_destroy for this allocator.

   Return
     A pointer to the allocator, or NULL if there is no space

   fy_dedup_allocator_create_in_place
     struct fy_allocator *fy_dedup_allocator_create_in_place(void *buffer,
     size_t size)
	    Create a dedup allocator in place

	    Parameters

		   * buffer (void*) a The memory buffer to use for both  storage
		     and the allocator

		   * size (size_t) a The size of the memory buffer

   Description
     Creates  a  dedup allocator in place, using the buffer provided.  No memory
     allocations will be performed, so itas safe to embed.  There is no need  to
     call fy_allocator_destroy for this allocator.  The parent allocator of this
     will be a linear allocator.

   Return
     A pointer to the allocator, or NULL if there is no space

   fy_allocator_get_tag
     int fy_allocator_get_tag(struct fy_allocator *a)
	    Get a tag from an allocator

	    Parameters

		   * a (struct fy_allocator*) a The allocator

   Description
     The  allocator  interface	requires all allocation to belong to a tag. This
     call creates a tag and returns its value, or an error if not available.

     If an allocator only provides a single tag (like the linear  allocator  for
     instance), the same tag number, usually 0, is returned.

   Return
     The created tag or -1 in case of an error.

   fy_allocator_release_tag
     void fy_allocator_release_tag(struct fy_allocator *a, int tag)
	    Release a tag from an allocator

	    Parameters

		   * a (struct fy_allocator*) a The allocator

		   * tag (int) a The tag to release

   Description
     Releases a tag from an allocator and frees all memory it allocated (if such
     an operation is provided by the allocator).

   fy_allocator_get_tag_count
     int fy_allocator_get_tag_count(struct fy_allocator *a)
	    Get the maximum number of tags a allocator supports

	    Parameters

		   * a (struct fy_allocator*) a The allocator

   Description
     Get the maximum amount of tags an allocator supports.

     If  an  allocator only provides a single tag (like the linear allocator for
     instance), 1 will be returned.

   Return
     The number of tags, or -1 on error

   fy_allocator_set_tag_count
     int fy_allocator_set_tag_count(struct fy_allocator *a, unsigned int count)
	    Set the maximum number of tags a allocator supports

	    Parameters

		   * a (struct fy_allocator*) a The allocator

		   * count (unsigned int) a The amount	of  tags  the  allocator
		     should support

   Description
     Sets  the maximum amount of tags an allocator supports.  If the set alloca-
     tor tag count is less than the current the  additional  tags  will  be  re-
     leased.

   Return
     0 on success, -1 on error

   fy_allocator_trim_tag
     void fy_allocator_trim_tag(struct fy_allocator *a, int tag)
	    Trim a tag

	    Parameters

		   * a (struct fy_allocator*) a The allocator

		   * tag (int) a The tag to trim

   Description
     Trim  a tag, that is free any excess memory it allocator, fitting it to the
     size of the content it carries.  Allocators that cannot perform this opera-
     tion treat it as a NOP.

   fy_allocator_reset_tag
     void fy_allocator_reset_tag(struct fy_allocator *a, int tag)
	    Reset a tag

	    Parameters

		   * a (struct fy_allocator*) a The allocator

		   * tag (int) a The tag to reset

   Description
     Reset a tag, that is free any content it carries, but do  not  release  the
     tag.

   fy_allocator_alloc
     void *fy_allocator_alloc(struct fy_allocator *a, int tag, size_t size,
     size_t align)
	    Allocate memory from an allocator

	    Parameters

		   * a (struct fy_allocator*) a The allocator

		   * tag (int) a The tag to allocate from

		   * size (size_t) a The size of the memory to allocate

		   * align (size_t) a The alignment of the object

   Description
     Allocate memory from the given allocator tag, satisfying the size and align
     restrictions.

   Return
     A pointer to the allocated memory or NULL

   fy_allocator_free
     void fy_allocator_free(struct fy_allocator *a, int tag, void *ptr)
	    Free memory allocated from an allocator

	    Parameters

		   * a (struct fy_allocator*) a The allocator

		   * tag (int) a The tag used to allocate the memory

		   * ptr (void*) a The pointer to the memory to free

   Description
     Attempt  to  free	the  memory allocated previously by fy_allocator_alloc()
     Note that non per object tracking allocators treat this as a NOP

   fy_allocator_store
     const void *fy_allocator_store(struct fy_allocator *a, int tag, const void
     *data, size_t size, size_t align)
	    Store an object to an allocator

	    Parameters

		   * a (struct fy_allocator*) a The allocator

		   * tag (int) a The tag used to allocate the memory

		   * data (const void*) a The pointer to object to store

		   * size (size_t) a The size of the object

		   * align (size_t) a The alignment restriction of the object

   Description
     Store an object to an allocator and return a pointer to the location it was
     stored. When using a deduplicating allocator no new  allocation  will  take
     place and a pointer to the object already stored will be returned.

     The return pointer must not be modified, the objects stored are idempotent.

   Return
     A constant pointer to the object stored, or NULL in case of an error

   fy_allocator_storev
     const void *fy_allocator_storev(struct fy_allocator *a, int tag, const
     struct iovec *iov, int iovcnt, size_t align)
	    Store an object to an allocator (scatter gather)

	    Parameters

		   * a (struct fy_allocator*) a The allocator

		   * tag (int) a The tag used to allocate the memory from

		   * iov (const struct iovec*) a The I/O scatter gather vector

		   * iovcnt (int) a The number of vectors

		   * align (size_t) a The alignment restriction of the object

   Description
     Store an object to an allocator and return a pointer to the location it was
     stored.  When  using  a deduplicating allocator no new allocation will take
     place and a pointer to the object already stored will be returned.

     The object is created linearly from the scatter gather io vector provided.

     The return pointer must not be modified, the objects stored are immutable.

   Return
     A constant pointer to the object stored, or NULL in case of an error

   fy_allocator_lookup
     const void *fy_allocator_lookup(struct fy_allocator *a, int tag, const void
     *data, size_t size, size_t align)
	    Lookup for object in an allocator.

	    Parameters

		   * a (struct fy_allocator*) a The allocator

		   * tag (int) a The tag used to locate the memory

		   * data (const void*) a The pointer to object to store

		   * size (size_t) a The size of the object

		   * align (size_t) a The alignment restriction of the object

   Description
     Lookup for the exact contents of an object stored in an allocator	and  re-
     turn  a pointer to the location it was stored.  The allocator must have the
     FYACF_CAN_LOOKUP capability.

   Return
     A constant pointer to the object stored, or NULL if the object does not ex-
     ist

   fy_allocator_lookupv
     const void *fy_allocator_lookupv(struct fy_allocator *a, int tag, const
     struct iovec *iov, int iovcnt, size_t align)
	    Lookup for object in an allocator (scatter gather)

	    Parameters

		   * a (struct fy_allocator*) a The allocator

		   * tag (int) a The tag used to search into

		   * iov (const struct iovec*) a The I/O scatter gather vector

		   * iovcnt (int) a The number of vectors

		   * align (size_t) a The alignment restriction of the object

   Description
     Lookup for the exact contents of an object stored in an allocator	and  re-
     turn  a pointer to the location it was stored.  The allocator must have the
     FYACF_CAN_LOOKUP capability.

     The scatter gather vector is used to recreate the object.

   Return
     A constant pointer to the object stored, or NULL in case  the  object  does
     not exist

   fy_allocator_dump
     void fy_allocator_dump(struct fy_allocator *a)
	    Dump internal allocator state

	    Parameters

		   * a (struct fy_allocator*) a The allocator

   enum fy_allocator_cap_flags
     enum fy_allocator_cap_flags
	    Allocator capability flags

   Definition
	enum fy_allocator_cap_flags {
	    FYACF_CAN_FREE_INDIVIDUAL,
	    FYACF_CAN_FREE_TAG,
	    FYACF_CAN_DEDUP,
	    FYACF_HAS_CONTAINS,
	    FYACF_HAS_EFFICIENT_CONTAINS,
	    FYACF_HAS_TAGS,
	    FYACF_CAN_LOOKUP
	};

   Constants
     FYACF_CAN_FREE_INDIVIDUAL
	    Allocator supports freeing individual allocations

     FYACF_CAN_FREE_TAG
	    Allocator supports releasing entire tags

     FYACF_CAN_DEDUP
	    Allocator supports deduplication

     FYACF_HAS_CONTAINS
	    Allocator  can  report  if	it  contains  a pointer (even if ineffi-
	    ciently)

     FYACF_HAS_EFFICIENT_CONTAINS
	    Allocator can report if it contains a pointer (efficiently)

     FYACF_HAS_TAGS
	    Allocator has individual tags or not

     FYACF_CAN_LOOKUP
	    Allocator supports lookup for content

   Description
     These flags describe what operations an allocator supports.

   fy_allocator_get_caps
     enum fy_allocator_cap_flags fy_allocator_get_caps(struct fy_allocator *a)
	    Get allocator capabilities

	    Parameters

		   * a (struct fy_allocator*) a The allocator

   Description
     Retrieve the capabilities of an allocator.

   Return
     The capabilities of the allocator

   fy_allocator_contains
     bool fy_allocator_contains(struct fy_allocator *a, int tag, const void
     *ptr)
	    Check if a allocator contains a pointer

	    Parameters

		   * a (struct fy_allocator*) a The allocator

		   * tag (int) a Tag to search in, -1 for all

		   * ptr (const void*) a The object pointer

   Description
     Report if an allocator contains the pointer

   Return
     true if the pointer ptr is contained in the allocator, false otherwise

   fy_allocator_get_tag_linear_size
     ssize_t fy_allocator_get_tag_linear_size(struct fy_allocator *a, int tag)
	    Get the linear size of an allocator tag

	    Parameters

		   * a (struct fy_allocator*) a The allocator

		   * tag (int) a The tag

   Description
     Retrieve the linear size of the content of a tag.	That is the  size  of  a
     buffer if one was to copy the content of the tag in that buffer in a linear
     manner.

   Return
     The linear size of the content stored in the tag or -1 in case of an error.

   fy_allocator_get_tag_single_linear
     const void *fy_allocator_get_tag_single_linear(struct fy_allocator *a, int
     tag, size_t *sizep)
	    Get the linear extend of a tag

	    Parameters

		   * a (struct fy_allocator*) a The allocator

		   * tag (int) a The tag

		   * sizep (size_t*) a Pointer to a variable that will be filled
		     with the size.

   Description
     If  a  tag  stores  itas content in a single linear buffer, retrieve it di-
     rectly. This is possible only under careful arrangement of  allocator  con-
     figuration, but it is an important optimization case.

   Return
     A pointer to the linear content of the tag, or NULL if othersize.

   struct fy_linear_allocator_cfg
     struct fy_linear_allocator_cfg
	    linear allocator configuration

   Definition
	struct fy_linear_allocator_cfg {
	    void *buf;
	    size_t size;
	}

   Members
     buf    A  pointer	to a buffer that will be used, or NULL in order to allo-
	    cate

     size   Size of the buffer in bytes

   enum fy_mremap_arena_type
     enum fy_mremap_arena_type
	    The mremap allocator arena types

   Definition
	enum fy_mremap_arena_type {
	    FYMRAT_DEFAULT,
	    FYMRAT_MALLOC,
	    FYMRAT_MMAP
	};

   Constants
     FYMRAT_DEFAULT
	    Use whatas optimal for this platform

     FYMRAT_MALLOC
	    Use malloc/realloc arena type (not recommended)

     FYMRAT_MMAP
	    Use mmap/mremap arena type

   struct fy_mremap_allocator_cfg
     struct fy_mremap_allocator_cfg
	    mremap allocator configuration

   Definition
	struct fy_mremap_allocator_cfg {
	    size_t big_alloc_threshold;
	    size_t empty_threshold;
	    size_t minimum_arena_size;
	    float grow_ratio;
	    float balloon_ratio;
	    enum fy_mremap_arena_type arena_type;
	}

   Members
     big_alloc_threshold
	    Threshold for immediately creating a new arena.

     empty_threshold
	    The threshold under which an arena is moved to the full list.

     minimum_arena_size
	    The minimum (and starting size) of an arena.

     grow_ratio
	    The ratio which an arena will try to grow if full (>1.0)

     balloon_ratio
	    The multiplier for the vm area first allocation

     arena_type
	    The arena type

   Description
     If any of the fields is zero, then the system will provide (somewhat)  rea-
     sonable defaults.

   struct fy_dedup_allocator_cfg
     struct fy_dedup_allocator_cfg
	    dedup allocator configuration

   Definition
	struct fy_dedup_allocator_cfg {
	    struct fy_allocator *parent_allocator;
	    unsigned int bloom_filter_bits;
	    unsigned int bucket_count_bits;
	    size_t dedup_threshold;
	    unsigned int chain_length_grow_trigger;
	    size_t estimated_content_size;
	    float minimum_bucket_occupancy;
	}

   Members
     parent_allocator
	    The parent allocator (required)

     bloom_filter_bits
	    Number of bits of the bloom filter (or 0 for default)

     bucket_count_bits
	    Number of bits for the bucket count (or 0 for default)

     dedup_threshold
	    Number of bytes over which dedup takes place (default 0=always)

     chain_length_grow_trigger
	    Chain  length  of  a  bucket over which a grow takes place (or 0 for
	    auto)

     estimated_content_size
	    Estimated content size (or 0 for donat know)

     minimum_bucket_occupancy
	    The minimum amount that a tag bucket must be full before  growth  is
	    allowed (default 50%, or 0.0)

   enum fy_auto_allocator_scenario_type
     enum fy_auto_allocator_scenario_type
	    auto allocator scenario type

   Definition
	enum fy_auto_allocator_scenario_type {
	    FYAST_PER_TAG_FREE,
	    FYAST_PER_TAG_FREE_DEDUP,
	    FYAST_PER_OBJ_FREE,
	    FYAST_PER_OBJ_FREE_DEDUP,
	    FYAST_SINGLE_LINEAR_RANGE,
	    FYAST_SINGLE_LINEAR_RANGE_DEDUP
	};

   Constants
     FYAST_PER_TAG_FREE
	    only per tag freeing, no individual obj free

     FYAST_PER_TAG_FREE_DEDUP
	    per tag freeing, dedup obj store

     FYAST_PER_OBJ_FREE
	    object freeing allowed, tag freeing still works

     FYAST_PER_OBJ_FREE_DEDUP
	    per obj freeing, dedup obj store

     FYAST_SINGLE_LINEAR_RANGE
	    just a single linear range, no frees at all

     FYAST_SINGLE_LINEAR_RANGE_DEDUP
	    single linear range, with dedup

   struct fy_auto_allocator_cfg
     struct fy_auto_allocator_cfg
	    auto allocator configuration

   Definition
	struct fy_auto_allocator_cfg {
	    enum fy_auto_allocator_scenario_type scenario;
	    size_t estimated_max_size;
	}

   Members
     scenario
	    Auto allocator scenario

     estimated_max_size
	    Estimated max content size (or 0 for donat know)

THREADING
     This header provides a simple, portable thread pool built on POSIX threads.
     It  is  used  internally by the BLAKE3 hasher and the generic type systemas
     parallel map/filter/reduce operations, and is also available  as  a  public
     API for application use.

     Two operational modes are supported:

     Work-stealing  mode (FYTPCF_STEAL_MODE): the recommended mode for data-par-
     allel loops.  Submit a batch of work items with fy_thread_work_join();  the
     pool  distributes	items  across threads and the caller participates in the
     execution.  About 30% faster than reservation mode for typical workloads.

     Reservation mode: explicitly reserve  a  thread  with  fy_thread_reserve(),
     submit  a	single	work  item  with fy_thread_submit_work(), continue doing
     other   work   in	 the   calling	  thread,    then    synchronise    with
     fy_thread_wait_work().   Release the thread afterwards with fy_thread_unre-
     serve().

     Three convenience wrappers over fy_thread_work_join() cover the most common
     data-parallel patterns:

     * fy_thread_args_join()	  a array of heterogeneous argument pointers

     * fy_thread_arg_array_join() a flat array of equal-sized argument items

     * fy_thread_arg_join()	  a same argument broadcast to N invocations

     An optional fy_work_check_fn callback lets each call site decide at runtime
     whether a given item is worth offloading to a thread or running inline.

   typedef fy_work_exec_fn
     void fy_work_exec_fn(void *arg)
	    Work exec function

	    Parameters

		   * arg (void*) a The argument to the method

   Description
     The callback executed on work submission

   typedef fy_work_check_fn
     bool fy_work_check_fn(const void *arg)
	    Work check function

	    Parameters

		   * arg (const void*) a The argument to the method

   Description
     Work checker function to decide if itas worth to offload to a thread.

   Return
     true if it should offload to thread, false otherwise

   struct fy_thread_work
     struct fy_thread_work
	    Work submitted to a thread for execution

   Definition
	struct fy_thread_work {
	    fy_work_exec_fn fn;
	    void *arg;
	    struct fy_work_pool *wp;
	}

   Members
     fn     The execution function for this work

     arg    The argument to the fn

     wp     Used internally, must be set to NULL on entry

   Description
     This is the structure describing the work submitted to a thread for  execu-
     tion.

   enum fy_thread_pool_cfg_flags
     enum fy_thread_pool_cfg_flags
	    Thread pool configuration flags

   Definition
	enum fy_thread_pool_cfg_flags {
	    FYTPCF_STEAL_MODE
	};

   Constants
     FYTPCF_STEAL_MODE
	    Enable steal mode for the thread pool

   Description
     These  flags  control  the  operation of the thread pool.	For now only the
     steal mode flag is defined.

   struct fy_thread_pool_cfg
     struct fy_thread_pool_cfg
	    thread pool configuration structure.

   Definition
	struct fy_thread_pool_cfg {
	    enum fy_thread_pool_cfg_flags flags;
	    unsigned int num_threads;
	    void *userdata;
	}

   Members
     flags  Thread pool configuration flags

     num_threads
	    Number of threads, if 0 == online CPUs

     userdata
	    A userdata pointer

   Description
     Argument to the fy_thread_pool_create() method.

   fy_thread_pool_create
     struct fy_thread_pool *fy_thread_pool_create(const struct
     fy_thread_pool_cfg *cfg)
	    Create a thread pool

	    Parameters

		   * cfg (const struct fy_thread_pool_cfg*) a The  configuration
		     for the thread pool

   Description
     Creates a thread pool with its configuration cfg The thread pool may be de-
     stroyed by a corresponding call to fy_thread_pool_destroy().

   Return
     A pointer to the thread pool or NULL in case of an error.

   fy_thread_pool_destroy
     void fy_thread_pool_destroy(struct fy_thread_pool *tp)
	    Destroy the given thread pool

	    Parameters

		   * tp (struct fy_thread_pool*) a The thread pool to destroy

   Description
     Destroy  a  thread  pool created earlier via fy_thread_pool_create().  Note
     that this function will block until all threads of the pool are destroyed.

   fy_thread_pool_get_num_threads
     int fy_thread_pool_get_num_threads(struct fy_thread_pool *tp)
	    Get the number of threads

	    Parameters

		   * tp (struct fy_thread_pool*) a The thread pool

   Description
     Returns the actual number of created threads.

   Return
     > 0 for the number of actual threads created, -1 on error

   fy_thread_pool_get_cfg
     const struct fy_thread_pool_cfg *fy_thread_pool_get_cfg(struct
     fy_thread_pool *tp)
	    Get the configuration of a thread pool

	    Parameters

		   * tp (struct fy_thread_pool*) a The thread pool

   Return
     The configuration of the thread pool

   fy_thread_reserve
     struct fy_thread *fy_thread_reserve(struct fy_thread_pool *tp)
	    Reserve a thread from the pool.

	    Parameters

		   * tp (struct fy_thread_pool*) a The thread pool

   Description
     Reserve a thread from the pool and return it.  Note this is only valid  for
     a	non-work  stealing thread pool.  You release the thread again via a call
     to fy_thread_unreserve.

   Return
     A reserved thread if not NULL, NULL if no threads are available.

   fy_thread_unreserve
     void fy_thread_unreserve(struct fy_thread *t)
	    Unreserve a previously reserved thread

	    Parameters

		   * t (struct fy_thread*) a The thread

   Description
     Unreserve a thread previously reserved via a  call  to  fy_thread_reserve()
     Note this is only valid for a non-work stealing thread pool.

   fy_thread_submit_work
     int fy_thread_submit_work(struct fy_thread *t, struct fy_thread_work *work)
	    Submit work for execution

	    Parameters

		   * t (struct fy_thread*) a The thread

		   * work (struct fy_thread_work*) a The work

   Description
     Submit  work  for	execution. If successful the thread will start executing
     the work in parallel with the calling thread. You can wait for  the  thread
     to  terminate  via  a  call to fy_thread_wait_work().  The thread must have
     been reserved earlier via fy_thread_reserve()

     Note this is only valid for a non-work stealing thread pool.

   Return
     0 if work has been submitted, -1 otherwise.

   fy_thread_wait_work
     int fy_thread_wait_work(struct fy_thread *t)
	    Wait for completion of submitted work

	    Parameters

		   * t (struct fy_thread*) a The thread

   Description
     Wait until submitted work to the thread has finished.  Note  this	is  only
     valid for a non-work stealing thread pool.

   Return
     0 if work finished, -1 on error.

   fy_thread_pool_are_all_reserved
     bool fy_thread_pool_are_all_reserved(struct fy_thread_pool *tp)
	    Check whether no threads are free

	    Parameters

		   * tp (struct fy_thread_pool*) a The thread pool

   Return
     true if all threads are currently reserved, false otherwise.

   fy_thread_pool_is_any_reserved
     bool fy_thread_pool_is_any_reserved(struct fy_thread_pool *tp)
	    Check whether at least one thread is reserved

	    Parameters

		   * tp (struct fy_thread_pool*) a The thread pool

   Return
     true if any thread is currently reserved, false otherwise.

   fy_thread_work_join
     void fy_thread_work_join(struct fy_thread_pool *tp, struct fy_thread_work
     *works, size_t work_count, fy_work_check_fn check_fn)
	    Submit works for execution and wait

	    Parameters

		   * tp (struct fy_thread_pool*) a The thread pool

		   * works  (struct  fy_thread_work*)  a  Pointer to an array of
		     works sized work_count

		   * work_count (size_t) a The size of the works array

		   * check_fn (fy_work_check_fn) a Pointer to a check  function,
		     or NULL for no checks

   Description
     Submit  works for possible parallel execution. If no offloading is possible
     at the time execute in the current context.  It is possible to use in  both
     stealing and non-stealing mode with the difference being that stealing mode
     is about 30% faster.

   fy_thread_args_join
     void fy_thread_args_join(struct fy_thread_pool *tp, fy_work_exec_fn fn,
     fy_work_check_fn check_fn, void **args, size_t count)
	    Execute function in parallel using arguments as pointers

	    Parameters

		   * tp (struct fy_thread_pool*) a The thread pool

		   * fn (fy_work_exec_fn) a The function to execute in parallel

		   * check_fn  (fy_work_check_fn) a Pointer to a check function,
		     or NULL for no checks

		   * args (void**) a An  args  array  sized  count  of	argument
		     pointers

		   * count (size_t) a The count of the args array items

   Description
     Execute  fn possibly in parallel using the threads in the thread pool.  The
     arguments of the function are provided by the args array.

   fy_thread_arg_array_join
     void fy_thread_arg_array_join(struct fy_thread_pool *tp, fy_work_exec_fn
     fn, fy_work_check_fn check_fn, void *args, size_t argsize, size_t count)
	    Execute function in parallel using argument array

	    Parameters

		   * tp (struct fy_thread_pool*) a The thread pool

		   * fn (fy_work_exec_fn) a The function to execute in parallel

		   * check_fn (fy_work_check_fn) a Pointer to a check  function,
		     or NULL for no checks

		   * args (void*) a An args array of argsize items

		   * argsize (size_t) a The size of each argument array item

		   * count (size_t) a The count of the args array items

   Description
     Execute  fn possibly in parallel using the threads in the thread pool.  The
     arguments of the function are provided by the args array.

   fy_thread_arg_join
     void fy_thread_arg_join(struct fy_thread_pool *tp, fy_work_exec_fn fn,
     fy_work_check_fn check_fn, void *arg, size_t count)
	    Execute function in parallel with the same argument

	    Parameters

		   * tp (struct fy_thread_pool*) a The thread pool

		   * fn (fy_work_exec_fn) a The function to execute in parallel

		   * check_fn (fy_work_check_fn) a Pointer to a check  function,
		     or NULL for no checks

		   * arg (void*) a The common argument

		   * count (size_t) a The count of executions

   Description
     Execute  fn possibly in parallel using the threads in the thread pool.  The
     argument of the functions is the same.

BLAKE3 HASHING
     This header exposes libfyamlas embedded BLAKE3 hasher.  BLAKE3 is a modern,
     highly  parallelisable  cryptographic  hash  function   producing	 256-bit
     (32-byte) output.

     Three hashing modes are supported, selected via struct fy_blake3_hasher_cfg
     at creation time:

     * Standard: plain BLAKE3 hash (default when key and context are NULL)

     * Keyed: MAC-like hash using a 32-byte key

     * Key derivation: derive a subkey from an application context string

     The  hasher  can  be  used  in streaming fashion (update / finalize) or for
     one-shot  hashing	of   memory   regions	(fy_blake3_hash())   and   files
     (fy_blake3_hash_file()).  File hashing uses mmap by default for large files
     and can be further parallelised via a thread pool.

     Runtime  SIMD  backend  selection	is automatic: the best available backend
     (SSE2, SSE4.1, AVX2, AVX512 on x86; NEON on ARM; portable C  otherwise)  is
     used  unless  a  specific	backend  name  is  requested in the config.  Use
     fy_blake3_backend_iterate() to enumerate available backends.

     The hasher object is reusable: call fy_blake3_hasher_reset() to start a new
     hash without reallocating the object.

   fy_blake3_backend_iterate
     const char *fy_blake3_backend_iterate(const char **prevp)
	    Iterate over the supported BLAKE3 backends

	    Parameters

		   * prevp (const char**) a The  previous  backend  pointer,  or
		     NULL at start

   Description
     This  method iterates over the supported BLAKE3 backends.	The start of the
     iteration is signalled by a NULL in *prevp.

     The default backend is always the last in sequence, so for example  if  the
     order is [ aportablea, asse2a, NULL ] the default is asse2a.

   Return
     The next backend or NULL at the end.

   struct fy_blake3_hasher_cfg
     struct fy_blake3_hasher_cfg
	    BLAKE3 hasher configuration

   Definition
	struct fy_blake3_hasher_cfg {
	    const char *backend;
	    size_t file_buffer;
	    size_t mmap_min_chunk;
	    size_t mmap_max_chunk;
	    bool no_mmap;
	    const uint8_t *key;
	    const void *context;
	    size_t context_len;
	    struct fy_thread_pool *tp;
	    int num_threads;
	}

   Members
     backend
	    NULL for default, or a specific backend name

     file_buffer
	    Use this amount of buffer for buffering, zero for default

     mmap_min_chunk
	    Minimum chunk size for mmap case

     mmap_max_chunk
	    Maximum chunk size for mmap case

     no_mmap
	    Disable mmap for file access

     key    pointer to a FY_BLAKE3_KEY_LEN area when in keyed mode.  NULL other-
	    wise.

     context
	    pointer to a context when in key derivation mode.  NULL otherwise.

     context_len
	    The size of the context when in key derivation mode.  0 otherwise.

     tp     The thread pool to use, if NULL, create a private one

     num_threads
	    Number  of	threads to use - 0 means default: NUM_CPUS * 3 / 2 - > 0
	    specific number of threads - -1 disable threading entirely

   Description
     Argument to the fy_blake3_hasher_create() method which is the fyamlas  user
     facing  BLAKE3 API.  It is very minimal, on purpose, since itas meant to be
     exposing a full blown BLAKE3 API.

   fy_blake3_hasher_create
     struct fy_blake3_hasher *fy_blake3_hasher_create(const struct
     fy_blake3_hasher_cfg *cfg)
	    Create a BLAKE3 hasher object.

	    Parameters

		   * cfg (const struct fy_blake3_hasher_cfg*) a  The  configura-
		     tion for the BLAKE3 hasher

   Description
     Creates  a  BLAKE3  hasher with its configuration cfg The hasher may be de-
     stroyed by a corresponding call to fy_blake3_hasher_destroy().

   Return
     A pointer to the BLAKE3 hasher or NULL in case of an error.

   fy_blake3_hasher_destroy
     void fy_blake3_hasher_destroy(struct fy_blake3_hasher *fyh)
	    Destroy the given BLAKE3 hasher

	    Parameters

		   * fyh (struct fy_blake3_hasher*) a The BLAKE3 hasher  to  de-
		     stroy

   Description
     Destroy a BLAKE3 hasher created earlier via fy_blake3_hasher_create().

   fy_blake3_hasher_update
     void fy_blake3_hasher_update(struct fy_blake3_hasher *fyh, const void *in-
     put, size_t input_len)
	    Update the BLAKE3 hasher state with the given input

	    Parameters

		   * fyh (struct fy_blake3_hasher*) a The BLAKE3 hasher

		   * input (const void*) a Pointer to the input

		   * input_len (size_t) a Size of the input in bytes

   Description
     Updates the BLAKE3 hasher state by hashing the given input.

   fy_blake3_hasher_finalize
     const uint8_t *fy_blake3_hasher_finalize(struct fy_blake3_hasher *fyh)
	    Finalize the hash and get output

	    Parameters

		   * fyh (struct fy_blake3_hasher*) a The BLAKE3 hasher

   Description
     Finalizes the BLAKE3 hasher and returns the output

   Return
     A	pointer  to the BLAKE3 output (sized FY_BLAKE3_OUT_LEN), or NULL in case
     of an error.

   fy_blake3_hasher_reset
     void fy_blake3_hasher_reset(struct fy_blake3_hasher *fyh)
	    Resets the hasher

	    Parameters

		   * fyh (struct fy_blake3_hasher*) a The BLAKE3 hasher

   Description
     Resets the hasher for re-use

   fy_blake3_hash
     const uint8_t *fy_blake3_hash(struct fy_blake3_hasher *fyh, const void
     *mem, size_t size)
	    BLAKE3 hash a memory area

	    Parameters

		   * fyh (struct fy_blake3_hasher*) a The BLAKE3 hasher

		   * mem (const void*) a Pointer to the memory to use

		   * size (size_t) a The size of the memory in bytes

   Description
     Hash a memory area and return the BLAKE3 output.

   Return
     A pointer to the BLAKE3 output (sized FY_BLAKE3_OUT_LEN), or NULL	in  case
     of an error.

   fy_blake3_hash_file
     const uint8_t *fy_blake3_hash_file(struct fy_blake3_hasher *fyh, const char
     *filename)
	    BLAKE3 hash a file.

	    Parameters

		   * fyh (struct fy_blake3_hasher*) a The BLAKE3 hasher

		   * filename (const char*) a The filename

   Description
     Hash the given file (possibly using mmap)

   Return
     A	pointer  to the BLAKE3 output (sized FY_BLAKE3_OUT_LEN), or NULL in case
     of an error.

ALIGNMENT
     This header provides portable utilities for working with  memory  alignment
     requirements,  from  compile-time	attributes  to	runtime  allocation  and
     pointer-rounding helpers.	It has no libfyaml dependencies.

     Compile-time attributes

     * FY_ALIGNED_TO(x)   a apply an alignment attribute to a variable or  type;
       expands	 to   __attribute__((aligned(x)))   on	 GCC/Clang   and   __de-
       clspec(align(x)) on MSVC

     * FY_CACHELINE_ALIGN a shorthand for cache-line (64-byte) alignment, useful
       for preventing false sharing between fields accessed concurrently by dif-
       ferent threads

     Value rounding

     * FY_ALIGN(align, x)	  a round an integer up to the next multiple  of
       align (must be a power of two)

     * FY_CACHELINE_SIZE_ALIGN(x)  a round up to the next cache-line boundary

     * fy_ptr_align(p, align)	   a round a pointer up to alignment

     * fy_size_t_align(sz, align)  a round a size_t value up to alignment

     Heap allocation

     * fy_align_alloc(align, size) / fy_align_free(p) a allocate and free memory
       with  an  explicit alignment (posix_memalign on POSIX, _aligned_malloc on
       Windows)

     * fy_cacheline_alloc(size)    / fy_cacheline_free(p) a convenience wrappers
       that fix the alignment at FY_CACHELINE_SIZE

     Stack allocation

     * fy_alloca_align(sz, align) a allocate a block on the stack with a  speci-
       fied alignment; uses plain alloca when alignment fits within max_align_t,
       otherwise over-allocates and advances the pointer

   macro FY_ALIGNED_TO
     FY_ALIGNED_TO(x)
	    Declare that a variable or type has a minimum alignment.

	    Parameters

		   * x a Required alignment in bytes (must be a power of two).

   Description
     Expands   to  the	appropriate  compiler-specific	alignment  attribute:  -
     GCC/Clang:  __attribute__((aligned(x)))  -  MSVC:	     should   be   __de-
     clspec(align(x))  but  MSVC  does not support trailing alignmenta| - Other:
     empty (no enforced alignment)

   macro FY_ALIGN
     FY_ALIGN(_align, _x)
	    Round _x up to the next multiple of _align.

	    Parameters

		   * _align a Alignment boundary (power of two).

		   * _x a Value to round up.

   Description
     _align must be a power of two. The result is always >= _x and is the small-
     est multiple of _align that is >= _x.

   Return
     _x rounded up to the nearest multiple of _align.

   macro FY_CACHELINE_SIZE
     FY_CACHELINE_SIZE()
	    Size of a CPU cache line in bytes.

   Description
     Universally 64 bytes on all currently supported architectures (x86, x86_64,
     ARM, ARM64, PowerPC).

   macro FY_CACHELINE_SIZE_ALIGN
     FY_CACHELINE_SIZE_ALIGN(_x)
	    Round _x up to the next cache-line boundary.

	    Parameters

		   * _x a Value to round up.

   Return
     _x rounded up to the nearest multiple of FY_CACHELINE_SIZE.

   macro FY_CACHELINE_ALIGN
     FY_CACHELINE_ALIGN()
	    Alignment attribute for cache-line-aligned objects.

   Description
     Apply to a variable or struct field to ensure it  starts  on  a  cache-line
     boundary, preventing false sharing between concurrent readers/writers.

     Example:

	struct my_data {
	    FY_CACHELINE_ALIGN int hot_counter;
	    int cold_field;
	};

   fy_align_alloc
     void *fy_align_alloc(size_t align, size_t size)
	    Allocate memory with a specific alignment.

	    Parameters

		   * align  (size_t)  a  Required  alignment in bytes (must be a
		     power of two and >= sizeof(void *) ).

		   * size (size_t) a Number of bytes to allocate.

   Description
     Allocates size bytes rounded up to the nearest multiple of align, with  the
     returned pointer guaranteed to be a multiple of align.

     Uses  posix_memalign()  on  POSIX systems and _aligned_malloc() on Windows.
     Free the result with fy_align_free().

   Return
     Pointer to the allocated block, or NULL on failure.

   fy_align_free
     void fy_align_free(void *p)
	    Free memory allocated by fy_align_alloc().

	    Parameters

		   * p	 (void*)    a	 Pointer    previously	  returned    by
		     fy_align_alloc(), or NULL.

   Description
     A NULL p is silently ignored.

   fy_cacheline_alloc
     void *fy_cacheline_alloc(size_t size)
	    Allocate cache-line-aligned memory.

	    Parameters

		   * size (size_t) a Number of bytes to allocate.

   Description
     Equivalent  to  fy_align_alloc(FY_CACHELINE_SIZE,	size).	 Free the result
     with fy_cacheline_free().

   Return
     Cache-line-aligned pointer, or NULL on failure.

   fy_cacheline_free
     void fy_cacheline_free(void *p)
	    Free memory allocated by fy_cacheline_alloc().

	    Parameters

		   * p	 (void*)    a	 Pointer    previously	  returned    by
		     fy_cacheline_alloc(), or NULL.

   Description
     A NULL p is silently ignored.

   fy_ptr_align
     void *fy_ptr_align(void *p, size_t align)
	    Round a pointer up to the next multiple of align.

	    Parameters

		   * p (void*) a Pointer to align.

		   * align  (size_t)  a  Alignment  boundary in bytes (must be a
		     power of two).

   Description
     Does not allocate any memory; the caller is responsible  for  ensuring  the
     underlying buffer extends at least (@align - 1) bytes past p.

   Return
     p rounded up to the nearest multiple of align.

   fy_size_t_align
     size_t fy_size_t_align(size_t size, size_t align)
	    Round a size_t value up to the next multiple of align.

	    Parameters

		   * size (size_t) a Value to round up.

		   * align  (size_t)  a  Alignment  boundary in bytes (must be a
		     power of two).

   Return
     size rounded up to the nearest multiple of align.

   macro fy_alloca_align
     fy_alloca_align(_sz, _align)
	    Stack-allocate a buffer with a specific alignment.

	    Parameters

		   * _sz a Number of bytes to allocate.

		   * _align a Required alignment in bytes (must be  a  power  of
		     two).

   Description
     Expands  to a statement expression (GCC extension) that allocates _sz bytes
     on the stack, aligned to _align bytes. When _align <= sizeof(max_align_t) a
     plain alloca() is used; otherwise _sz + _align - 1 bytes are allocated  and
     the  pointer  is advanced with fy_ptr_align().  This macro does not work on
     MSVC.

     The result is valid only for the lifetime of the enclosing function; do not
     return or store it beyond that scope.

   Return
     Stack pointer aligned to _align.

ENDIANNESS
     This header provides a portable way to include  the  platformas  byte-order
     detection headers and ensures the following macros are always defined:

     * __BYTE_ORDER  a the byte order of the current platform

     * __BIG_ENDIAN  a big-endian sentinel value

     * __LITTLE_ENDIAN a little-endian sentinel value

     Usage:

	#include <libfyaml/fy-internal-endian.h>

	#if __BYTE_ORDER == __LITTLE_ENDIAN
	    // little-endian path
	#else
	    // big-endian path
	#endif

     Supported	platforms:  - Linux / Cygwin / OpenBSD / GNU Hurd / Emscripten a
     via <endian.h> - macOS / iOS a via <libkern/OSByteOrder.h>  +  <machine/en-
     dian.h>  -  NetBSD / FreeBSD / DragonFly BSD a via <sys/endian.h> - Windows
     (MSVC) a via <winsock2.h> (+ <sys/param.h> for MinGW)

     The non-standard BYTE_ORDER, BIG_ENDIAN, and  LITTLE_ENDIAN  spellings  are
     aliased to the double-underscore variants if needed.

   macro bswap_8
     bswap_8(x)
	    Byte-swap an 8-bit value (no-op).

	    Parameters

		   * x a The 8-bit value.

   Description
     Defined for symmetry with bswap_16(), bswap_32(), and bswap_64().	Swapping
     a single byte is always a no-op.

   Return
     x unchanged.

VARIABLE-LENGTH SIZE ENCODING
     Encodes unsigned integer sizes into a compact, self-delimiting byte stream.
     The  encoding  is modelled after the variable-length quantity (VLQ / LEB128
     big-endian variant) used in MIDI and other binary formats:

     * Each byte carries 7 bits of payload in bits 6..0.

     * Bit 7 (MSB) is a continuation flag: 1 means more bytes  follow,	0  means
       this is the last byte.

     * Exception:  the	final  (maximum-length) byte is always 8 bits of payload
       with no continuation bit, allowing the full 64-bit / 32-bit range.

     64-bit encoding (up to 9 bytes):

	bytes	bits   value range
	1	7      0 .. 127
	2	14     128 .. 16383
	3	21     16384 .. 2097151
	4	28     2097152 .. 268435455
	5	35     268435456 .. 34359738367
	6	42     ..
	7	49     ..
	8	56     ..
	9	64     full uint64_t range

     32-bit encoding (up to 5 bytes):

	bytes	bits   value range
	1	7      0 .. 127
	2	14     128 .. 16383
	3	21     16384 .. 2097151
	4	28     2097152 .. 268435455
	5	32     full uint32_t range (top 4 bits of byte 0 ignored)

     The native-width fy_encode_size() /  fy_decode_size()  family  selects  the
     64-bit or 32-bit variant based on SIZE_MAX.

     Each family provides four operations:

     * _bytes()     a compute the encoded length without writing anything

     * encode()     a write the encoding into a bounded buffer

     * decode()     a read and validate from a bounded buffer

     * decode_nocheck() a read without bounds checking (caller guarantees room)

     * skip()	    a advance past an encoded value in a bounded buffer

     * skip_nocheck()	a advance without bounds checking

   macro FYVL_SIZE_ENCODING_MAX_64
     FYVL_SIZE_ENCODING_MAX_64()
	    Maximum encoded length of a 64-bit size value.

   Description
     A	64-bit	value  requires at most 9 bytes: 8 x 7-bit groups plus one final
     unconstrained byte = 7 x 8 + 8 = 64 bits.

   macro FYVL_SIZE_ENCODING_MAX_32
     FYVL_SIZE_ENCODING_MAX_32()
	    Maximum encoded length of a 32-bit size value.

   Description
     A 32-bit value requires at most 5 bytes: 4 x 7-bit groups	plus  one  final
     unconstrained byte = 7 x 4 + 4 = 32 bits.

   fy_encode_size32_bytes
     unsigned int fy_encode_size32_bytes(uint32_t size)
	    Compute the encoded byte count for a 32-bit size.

	    Parameters

		   * size  (uint32_t)  a  The  value  whose  encoded  length  is
		     queried.

   Description
     Returns the number of bytes that fy_encode_size32() would write  for  size,
     without actually writing anything. Useful for pre-allocating buffers.

   Return
     Number of bytes required (1a5).

   fy_encode_size32
     uint8_t *fy_encode_size32(uint8_t *p, uint32_t bufsz, uint32_t size)
	    Encode a 32-bit size into a buffer.

	    Parameters

		   * p (uint8_t*) a Start of the output buffer.

		   * bufsz (uint32_t) a Available space in bytes.

		   * size (uint32_t) a Value to encode.

   Description
     Writes the variable-length encoding of size into the buffer [@p, p+@bufsz).

   Return
     Pointer to one past the last written byte, or NULL if bufsz was
	    too small.

   fy_decode_size32
     const uint8_t *fy_decode_size32(const uint8_t *start, size_t bufsz,
     uint32_t *sizep)
	    Decode a variable-length 32-bit size from a buffer.

	    Parameters

		   * start (const uint8_t*) a Start of the encoded data.

		   * bufsz (size_t) a Available bytes to read.

		   * sizep  (uint32_t*)  a  Output:  the  decoded  value. Set to
		     (uint32_t)-1 on error.

   Description
     Reads bytes from [@start, start+@bufsz) and reconstructs the encoded 32-bit
     value. Stops after FYVL_SIZE_ENCODING_MAX_32 bytes at most.

   Return
     Pointer to one past the last consumed byte, or NULL if the buffer
	    was exhausted before a complete value was found.

   fy_decode_size32_nocheck
     const uint8_t *fy_decode_size32_nocheck(const uint8_t *start, uint64_t
     *sizep)
	    Decode a 32-bit size without bounds checking.

	    Parameters

		   * start (const uint8_t*) a Start of the encoded data.

		   * sizep (uint64_t*) a Output: the decoded value as a uint64_t
		     for uniform handling.

   Description
     Like fy_decode_size32() but assumes the buffer is large enough  to  hold  a
     complete  encoding.  The  caller  must  guarantee at least FYVL_SIZE_ENCOD-
     ING_MAX_32 bytes are available at start.

   Return
     Pointer to one past the last consumed byte.

   fy_skip_size32
     const uint8_t *fy_skip_size32(const uint8_t *start, size_t bufsz)
	    Skip past a variable-length 32-bit size in a buffer.

	    Parameters

		   * start (const uint8_t*) a Start of the encoded data.

		   * bufsz (size_t) a Available bytes.

   Description
     Advances past the encoded value without decoding it. Useful when the  value
     itself is not needed.

   Return
     Pointer to one past the last consumed byte, or NULL if the buffer
	    was exhausted before a complete encoding was found.

   fy_skip_size32_nocheck
     const uint8_t *fy_skip_size32_nocheck(const uint8_t *p)
	    Skip a 32-bit encoded size without bounds checking.

	    Parameters

		   * p (const uint8_t*) a Start of the encoded data.

   Description
     Like  fy_skip_size32()  but  assumes the buffer is large enough. The caller
     must guarantee at least FYVL_SIZE_ENCODING_MAX_32 bytes are readable.

   Return
     Pointer to one past the last consumed byte.

   fy_encode_size64_bytes
     unsigned int fy_encode_size64_bytes(uint64_t size)
	    Compute the encoded byte count for a 64-bit size.

	    Parameters

		   * size  (uint64_t)  a  The  value  whose  encoded  length  is
		     queried.

   Description
     Returns  the  number of bytes that fy_encode_size64() would write for size,
     without writing anything.

   Return
     Number of bytes required (1a9).

   fy_encode_size64
     uint8_t *fy_encode_size64(uint8_t *p, size_t bufsz, uint64_t size)
	    Encode a 64-bit size into a buffer.

	    Parameters

		   * p (uint8_t*) a Start of the output buffer.

		   * bufsz (size_t) a Available space in bytes.

		   * size (uint64_t) a Value to encode.

   Description
     Writes the variable-length encoding of size into the buffer [@p, p+@bufsz).

   Return
     Pointer to one past the last written byte, or NULL if bufsz was
	    too small.

   fy_decode_size64
     const uint8_t *fy_decode_size64(const uint8_t *start, size_t bufsz,
     uint64_t *sizep)
	    Decode a variable-length 64-bit size from a buffer.

	    Parameters

		   * start (const uint8_t*) a Start of the encoded data.

		   * bufsz (size_t) a Available bytes to read.

		   * sizep (uint64_t*) a  Output:  the	decoded  value.  Set  to
		     (size_t)-1 on error.

   Description
     Reads bytes from [@start, start+@bufsz) and reconstructs the encoded 64-bit
     value. Stops after FYVL_SIZE_ENCODING_MAX_64 bytes at most.

   Return
     Pointer to one past the last consumed byte, or NULL if the buffer
	    was exhausted before a complete value was found.

   fy_decode_size64_nocheck
     const uint8_t *fy_decode_size64_nocheck(const uint8_t *start, uint64_t
     *sizep)
	    Decode a 64-bit size without bounds checking.

	    Parameters

		   * start (const uint8_t*) a Start of the encoded data.

		   * sizep (uint64_t*) a Output: the decoded value.

   Description
     Like  fy_decode_size64() but assumes the buffer is large enough. The caller
     must guarantee at least FYVL_SIZE_ENCODING_MAX_64 bytes are readable.

   Return
     Pointer to one past the last consumed byte.

   fy_skip_size64
     const uint8_t *fy_skip_size64(const uint8_t *start, size_t bufsz)
	    Skip past a variable-length 64-bit size in a buffer.

	    Parameters

		   * start (const uint8_t*) a Start of the encoded data.

		   * bufsz (size_t) a Available bytes.

   Description
     Advances past the encoded value without decoding it.

   Return
     Pointer to one past the last consumed byte, or NULL if the buffer
	    was exhausted before a complete encoding was found.

   fy_skip_size64_nocheck
     const uint8_t *fy_skip_size64_nocheck(const uint8_t *p)
	    Skip a 64-bit encoded size without bounds checking.

	    Parameters

		   * p (const uint8_t*) a Start of the encoded data.

   Description
     Like fy_skip_size64() but assumes the buffer is large  enough.  The  caller
     must guarantee at least FYVL_SIZE_ENCODING_MAX_64 bytes are readable.

   Return
     Pointer to one past the last consumed byte.

   fy_encode_size_bytes
     unsigned int fy_encode_size_bytes(size_t size)
	    Compute encoded byte count for a native size_t.

	    Parameters

		   * size (size_t) a The value whose encoded length is queried.

   Description
     Selects   fy_encode_size64_bytes()  or  fy_encode_size32_bytes()  based  on
     SIZE_MAX.

   Return
     Number of bytes required.

   fy_encode_size
     uint8_t *fy_encode_size(uint8_t *p, size_t bufsz, size_t size)
	    Encode a native size_t into a buffer.

	    Parameters

		   * p (uint8_t*) a Start of the output buffer.

		   * bufsz (size_t) a Available space in bytes.

		   * size (size_t) a Value to encode.

   Description
     Selects fy_encode_size64() or fy_encode_size32() based on SIZE_MAX.

   Return
     Pointer to one past the last written byte, or NULL on overflow.

   fy_decode_size
     const uint8_t *fy_decode_size(const uint8_t *start, size_t bufsz, size_t
     *sizep)
	    Decode a native size_t from a buffer.

	    Parameters

		   * start (const uint8_t*) a Start of the encoded data.

		   * bufsz (size_t) a Available bytes.

		   * sizep (size_t*) a Output: the decoded value.

   Description
     Selects fy_decode_size64() or fy_decode_size32() based on SIZE_MAX.

   Return
     Pointer to one past the last consumed byte, or NULL on error.

   fy_decode_size_nocheck
     const uint8_t *fy_decode_size_nocheck(const uint8_t *start, size_t *sizep)
	    Decode a native size_t without bounds checking.

	    Parameters

		   * start (const uint8_t*) a Start of the encoded data.

		   * sizep (size_t*) a Output: the decoded value.

   Description
     Selects the 64-bit or 32-bit nocheck variant based on sizeof(size_t).   The
     caller must guarantee enough bytes are available at start.

   Return
     Pointer to one past the last consumed byte.

   fy_skip_size
     const uint8_t *fy_skip_size(const uint8_t *start, size_t bufsz)
	    Skip a native size_t encoding in a buffer.

	    Parameters

		   * start (const uint8_t*) a Start of the encoded data.

		   * bufsz (size_t) a Available bytes.

   Description
     Selects fy_skip_size64() or fy_skip_size32() based on SIZE_MAX.

   Return
     Pointer to one past the last consumed byte, or NULL on error.

   fy_skip_size_nocheck
     const uint8_t *fy_skip_size_nocheck(const uint8_t *start)
	    Skip a native size_t encoding without bounds checking.

	    Parameters

		   * start (const uint8_t*) a Start of the encoded data.

   Description
     Selects the 64-bit or 32-bit nocheck variant based on SIZE_MAX.  The caller
     must guarantee enough bytes are available.

   Return
     Pointer to one past the last consumed byte.

   macro FYVL_SIZE_ENCODING_MAX
     FYVL_SIZE_ENCODING_MAX()
	    Maximum encoded length for a native size_t.

   Description
     Equals  FYVL_SIZE_ENCODING_MAX_64	on  64-bit  platforms,	FYVL_SIZE_ENCOD-
     ING_MAX_32 on 32-bit platforms.

ATOMIC OPERATIONS
     This header provides a thin, portable abstraction	over  C11  <stdatomic.h>
     with  graceful  fallback for compilers that support _Atomic as an extension
     (GCC without -std=c11, Clang) and a  last-resort  non-atomic  fallback  for
     toolchains that support neither.

     Detection macros (defined by this header, not meant for direct use):

     *

       FY_HAVE_STDATOMIC_H ^a <stdatomic.h> was successfully included;
	      the standard atomic_* functions and types are available.

     *

       FY_HAVE_C11_ATOMICS ^a the _Atomic qualifier is available, either
	      from <stdatomic.h> or as a compiler extension.

     *

       FY_HAVE_ATOMICS ^a effective atomics are available (_Atomic
	      maps  to	a  real atomic type).  When not defined, _Atomic(_x) ex-
	      pands  to  plain	_x  and  all  operations  are  non-atomic   sin-
	      gle-threaded stubs.

     *

       FY_HAVE_SAFE_ATOMIC_OPS ^a the underlying operations are properly
	      memory-ordered  (i.e. <stdatomic.h> is in use).  Without this, op-
	      erations are performed as plain loads/stores with no memory barri-
	      ers.

     Public API a all fy_atomic_* macros delegate to the selected backend:

     * FY_ATOMIC()		       a qualify a type as atomic

     * fy_atomic_flag		       a boolean flag type

     * fy_atomic_load() / fy_atomic_store()

     * fy_atomic_exchange()

     * fy_atomic_compare_exchange_strong() / fy_atomic_compare_exchange_weak()

     * fy_atomic_fetch_add() / fy_atomic_fetch_sub()

     * fy_atomic_fetch_or() / fy_atomic_fetch_xor() / fy_atomic_fetch_and()

     * fy_atomic_flag_clear()	      / 	 fy_atomic_flag_set()	       /
       fy_atomic_flag_test_and_set()

     * fy_cpu_relax()			  a   emit   a	 CPU   relaxation   hint
       (PAUSE/YIELD)

     * fy_atomic_get_and_clear_counter()  a  atomically  read  and  subtract   a
       counter

   macro FY_ATOMIC
     FY_ATOMIC(_x)
	    Qualify a type as atomic.

	    Parameters

		   * _x a The underlying C type.

   Description
     Expands to _Atomic(_x) when FY_HAVE_ATOMICS is defined, or to plain _x oth-
     erwise (non-atomic fallback).

     Example:

	FY_ATOMIC(uint64_t) refcount;

   macro fy_atomic_flag
     fy_atomic_flag()
	    A boolean flag that can be set/cleared/tested atomically.

   Description
     Backed by atomic_flag from <stdatomic.h> when available, or a plain bool in
     the fallback path.

   macro fy_atomic_load
     fy_atomic_load(_ptr)
	    Atomically load the value at _ptr.

	    Parameters

		   * _ptr a Pointer to an FY_ATOMIC-qualified variable.

   Return
     The current value.

   macro fy_atomic_store
     fy_atomic_store(_ptr, _v)
	    Atomically store _v at _ptr.

	    Parameters

		   * _ptr a Pointer to an FY_ATOMIC-qualified variable.

		   * _v a Value to store.

   macro fy_atomic_exchange
     fy_atomic_exchange(_ptr, _v)
	    Atomically replace the value at _ptr with _v.

	    Parameters

		   * _ptr a Pointer to an FY_ATOMIC-qualified variable.

		   * _v a New value to store.

   Return
     The old value that was at _ptr before the exchange.

   macro fy_atomic_compare_exchange_strong
     fy_atomic_compare_exchange_strong(_ptr, _e, _d)
	    Strong CAS: replace _ptras value if it equals _e.

	    Parameters

		   * _ptr a Pointer to an FY_ATOMIC-qualified variable.

		   * _e a Pointer to the expected value (updated on failure).

		   * _d a Desired value to store on success.

   Description
     If  *_ptr	==  *_e, stores _d into _ptr and returns true.	Otherwise, loads
     the current value into _e and returns false.  The strong variant never spu-
     riously fails.

   Return
     true if the exchange succeeded, false otherwise.

   macro fy_atomic_compare_exchange_weak
     fy_atomic_compare_exchange_weak(_ptr, _e, _d)
	    Weak CAS: may spuriously fail.

	    Parameters

		   * _ptr a Pointer to an FY_ATOMIC-qualified variable.

		   * _e a Pointer to the expected value (updated on failure).

		   * _d a Desired value to store on success.

   Description
     Like fy_atomic_compare_exchange_strong() but may fail even  when  *_ptr  ==
     *_e. Prefer in retry loops where a spurious failure is harmless and perfor-
     mance matters.

   Return
     true if the exchange succeeded, false otherwise.

   macro fy_atomic_fetch_add
     fy_atomic_fetch_add(_ptr, _v)
	    Atomically add _v to _ptr and return the old value.

	    Parameters

		   * _ptr a Pointer to an FY_ATOMIC-qualified integer variable.

		   * _v a Value to add.

   Return
     The value of _ptr before the addition.

   macro fy_atomic_fetch_sub
     fy_atomic_fetch_sub(_ptr, _v)
	    Atomically subtract _v from _ptr and return the old value.

	    Parameters

		   * _ptr a Pointer to an FY_ATOMIC-qualified integer variable.

		   * _v a Value to subtract.

   Return
     The value of _ptr before the subtraction.

   macro fy_atomic_fetch_or
     fy_atomic_fetch_or(_ptr, _v)
	    Atomically OR _v into _ptr and return the old value.

	    Parameters

		   * _ptr a Pointer to an FY_ATOMIC-qualified integer variable.

		   * _v a Value to OR in.

   Return
     The value of _ptr before the operation.

   macro fy_atomic_fetch_xor
     fy_atomic_fetch_xor(_ptr, _v)
	    Atomically XOR _v into _ptr and return the old value.

	    Parameters

		   * _ptr a Pointer to an FY_ATOMIC-qualified integer variable.

		   * _v a Value to XOR in.

   Return
     The value of _ptr before the operation.

   macro fy_atomic_fetch_and
     fy_atomic_fetch_and(_ptr, _v)
	    Atomically AND _v into _ptr and return the old value.

	    Parameters

		   * _ptr a Pointer to an FY_ATOMIC-qualified integer variable.

		   * _v a Value to AND in.

   Return
     The value of _ptr before the operation.

   macro fy_atomic_flag_clear
     fy_atomic_flag_clear(_ptr)
	    Atomically clear a flag (set to false).

	    Parameters

		   * _ptr a Pointer to an fy_atomic_flag.

   macro fy_atomic_flag_set
     fy_atomic_flag_set(_ptr)
	    Atomically set a flag (set to true).

	    Parameters

		   * _ptr a Pointer to an fy_atomic_flag.

   Note
     this   is	a  libfyaml  extension;  standard  <stdatomic.h>  only	provides
     atomic_flag_test_and_set().  In the fallback path this is implemented as  a
     plain store.

   macro fy_atomic_flag_test_and_set
     fy_atomic_flag_test_and_set(_ptr)
	    Atomically set a flag and return its old value.

	    Parameters

		   * _ptr a Pointer to an fy_atomic_flag.

   Description
     Sets  the	flag to true and returns the value it held before the operation.
     This is the standard test-and-set primitive.

   Return
     true if the flag was already set, false if it was clear.

   fy_cpu_relax
     void fy_cpu_relax(void)
	    Emit a CPU relaxation hint inside a spin-wait loop.

	    Parameters

		   * void a no arguments

   Description
     Reduces power  consumption  and  improves	hyper-threading  performance  on
     x86/x86_64  (PAUSE),  signals  a  yield on AArch64/ARM (YIELD), and emits a
     low-priority hint on PowerPC (or 27,27,27).  Falls back to a compiler  mem-
     ory barrier on unsupported architectures.

     Use  inside  tight  spin loops to avoid memory-ordering penalties and allow
     sibling hardware threads to make progress:

	while (!fy_atomic_load(&ready))
	    fy_cpu_relax();

COPYRIGHT
     2019-2026, Pantelis Antoniou

				  Mar 15, 2026			LIBFYAML-MISC(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=libfyaml-misc&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help