Shared internal helpers for parquet_column: argument guards, the validity-bitmap
primitives, and the two kind-category predicates.
These live in a submodule of their own — rather than contained in parquet_columns itself —
for one concrete reason: a procedure contained in a submodule is invisible to that
submodule's siblings, while one contained in the module is reported as
-Wunused-function when the module is compiled as its own translation unit (its only
callers being in other files). Declaring the interfaces in the module and implementing them
here gives every submodule access with no warnings, and matches how parquet_core.f90 already
shares its private helpers.
The bitmap. A hand-rolled integer(int64) block array with 1 = null, 0 = valid, so
an all-zero map means "no nulls" and the whole map can be dropped in O(1) rather than
scanned. Bit b (1-based) lives in block (b-1)/64 + 1 at position mod(b-1, 64). It is
indexed per ELEMENT, not per row, so a vector column needs nrows*width bits (RF8).
Measured against stdlib's bitset_large, this is 1.6-2x faster on random set/test and on the
reindex rebuild at identical memory, and it has no int32 bit-index ceiling — which is why this
library takes no stdlib dependency for it.