BSON Support
Glaze now supports BSON. Helper types (glz::bson::object_id, datetime, regex, javascript, decimal128, timestamp, binary, min_key, max_key) cover BSON wire types that have no native JSON equivalent, and glz::bson_to_json produces MongoDB Canonical Extended JSON v2.
- BSON read/write support by @stephenberry in #2518
Faster Float Writing
glz::to_chars for floats now uses a header-only port of Victor Zverovich's zmij (Schubfach + xjb) in place of dragonbox.
- ~2.7× faster than dragonbox on random finite doubles, ~3× faster on floats.
- The size-optimized path (
OptSize=true) is ~4–8× faster than the previoussimple_float::to_charsat roughly the same footprint. - Side-effect bugfix:
simple_float::from_charsno longer hits a 1-ULP rounding miss on platforms wherelong doublealiasesdouble(ARM64 macOS, MSVC).
Full exhaustive sweep over all 4,278,190,080 finite float values round-trips exactly.
- Replace dragonbox with zmij by @stephenberry in #2528
Struct Flattening with glz::merge
glz::merge now works inside glz::meta with member pointers, enabling both reading and writing of composite structs as flat JSON objects.
struct Species { std::string name{}; int legs{}; };
struct Appearance { double weight{}; std::string color{}; };
struct BearRecord { Species species{}; Appearance appearance{}; };
template <>
struct glz::meta<BearRecord> {
using T = BearRecord;
static constexpr auto value = glz::merge{&T::species, &T::appearance};
};
// Reads and writes as: {"name":"Grizzly","legs":4,"weight":300.5,"color":"brown"}Sub-types can be either glaze_object_t (with custom key names) or reflectable (automatic reflection), and any number of sub-structs can be merged. Implemented entirely at the reflect<T> layer, so JSON, BEVE, YAML, CBOR, and other formats all pick it up automatically.
glz::mergesupport for aggregate structs by @stephenberry in #2503
flatten_map Wrapper
A new glz::flatten_map wrapper serializes map-like containers as flat arrays of the form [key elements..., mapped value, ...], supporting fixed-size keys (std::pair, tuples, Glaze arrays, std::array) for both reading and writing.
std::unordered_map<std::pair<int, int>, std::string, pair_hash> map;
map[{1, 2}] = "example";
std::string out;
glz::write_json(glz::flatten_map_wrapper{map}, out);
// out == R"([1,2,"example"])"Usable both inside glz::meta via member pointer (glz::flatten_map<&T::m>) and as a top-level CTAD wrapper (glz::flatten_map_wrapper{map}).
flatten_mapwrapper by @stephenberry in #2412flatten_map_wrappertop-level wrapping via CTAD by @stephenberry in #2526
Improvements
- Cross-format
skip_null_membershonored by JSONB, CBOR, MsgPack, and BEVE map writers, matching the existing struct-writer behavior by @stephenberry in #2518 - Remove force inlining for YAML and TOML to improve compile times and reduce binary size by @stephenberry in #2517
Fixes
- Named enum map keys: reading a
std::mapkeyed by an enum declared with thekeys+valuearray form ofglz::metano longer fails withexpected_quoteby @stephenberry in #2523 jsonb_to_jsonnow emits9e999/-9e999for±Infinity(matching SQLite'sjson()convention) instead ofnull.NaNcontinues to map tonull. Documentation also clarifies that 64-bit integer /binary64float ranges are a Glaze implementation constraint, not a SQLite spec limit by @stephenberry in #2521
Full Changelog: v7.4.0...v7.5.0