Releases: stephenberry/glaze
v4.3.0
New append_arrays
compile time option
Adds the compile time option (and wrapper) append_arrays
, which appends data to types like std::vector rather than overwrite. (#1549)
Example:
std::vector<int> v{};
constexpr glz::opts append_opts{.append_arrays = true};
expect(not glz::read<append_opts>(v, "[1,2,3]"));
expect(v == std::vector<int>{1,2,3});
expect(not glz::read<append_opts>(v, "[4,5,6]"));
expect(v == std::vector<int>{1,2,3,4,5,6});
Improvements
- Support for dynamically sized Eigen types by @WanZhiQiu-ac in #1541
- Support for reflection with Eigen vector types in #1552
- Improved glz::async_string with more methods and std::format support by @stephenberry in #1536, #1538
- Cleanup of map writing in #1542
- Fix for always_null_t in object handling and faster always null write in #1545
- More efficient numerical keys in dynamic maps in #1546
Minor Deprecation
- Removed global
glz::trace
in #1544
Because C++ has inline variables and other ways to make global instances it is better to let the programmer handle global instances of glz::trace rather than offer two separate APIs. This also removes the unnecessary glz::write_file_trace as
glz::write_file_json(trace
is more generic and there is no longer a global instance of the trace.
New Contributors
- @WanZhiQiu-ac made their first contribution in #1541
Full Changelog: v4.2.4...v4.3.0
v4.2.4
Improvements
- Skipping and tuple cleanup in #1531
- Faster writing in #1534
number
option clarification and better errors in #1535
In Development
- Simplify REPE error handling by @stephenberry in #1527
- Better API for REPE requests in #1528
Full Changelog: v4.2.3...v4.2.4
v4.2.3
Improvements
- Improved compilation performance (many thanks to @arturbac) in #1512, #1514, #1516, #1513, #1517
- Remove constexpr requirement for glz::schema fields & cleaned JSON schema code by @stephenberry in #1518
Fixes
- Fixed glz::merge with empty objects in #1519 (thanks @SenseOnline)
- Fixed enum string read for vector of pairs in concatenate mode by @sjanel in #1525
In Development
- REPE conformance for registry errors in #1526
Full Changelog: v4.2.2...v4.2.3
v4.2.2
Slice support for glz::read_jmespath
std::vector<int> data{0,1,2,3,4,5,6,7,8,9};
std::string buffer{};
expect(not glz::write_json(data, buffer));
std::vector<int> slice{};
expect(not glz::read_jmespath<"[0:5]">(slice, buffer));
expect(slice.size() == 5);
expect(slice[0] == 0);
expect(slice[1] == 1);
expect(slice[2] == 2);
expect(slice[3] == 3);
expect(slice[4] == 4);
Pre-compute JMESPath run-time expressions
The run-time version of glz::read_jmespath
also now takes in a const jmespath_expression&
. This allows a jmespath_expression
to be "compiled" once in the code and reused for much better runtime performance. This caches the tokenization.
Person child{};
// A runtime expression can be pre-computed and saved for more efficient lookups
glz::jmespath_expression expression{"family.children[0]"};
expect(not glz::read_jmespath(expression, child, buffer));
expect(child.first_name == "Lilly");
Note that this still works:
expect(not glz::read_jmespath("family.children[0]", child, buffer));
by @stephenberry in #1510
Fixes
Full Changelog: v4.2.1...v4.2.2
v4.2.1
First steps for compile-time and run-time JMESPath query support
v4.2.0 neutered the partial_read
option, due to its complexity and confusing behavior (and to make it faster). This release brings another approach to partial reading that is far more extensible, by utilizing the JMESPath query specification.
More JMESPath support will be added in the future, but this release brings both compile-time and run-time JMESPath expression handling to read a value at a target location in a buffer.
Example
struct Person
{
std::string first_name{};
std::string last_name{};
uint16_t age{};
};
struct Family
{
Person father{};
Person mother{};
std::vector<Person> children{};
};
struct Home
{
Family family{};
std::string address{};
};
suite jmespath_read_at_tests = [] {
"compile-time read_jmespath"_test = [] {
Home home{.family = {.father = {"Gilbert", "Fox", 28},
.mother = {"Anne", "Fox", 30},
.children = {{"Lilly"}, {"Vincent"}}}};
std::string buffer{};
expect(not glz::write_json(home, buffer));
std::string first_name{};
auto ec = glz::read_jmespath<"family.father.first_name">(first_name, buffer);
expect(not ec) << glz::format_error(ec, buffer);
expect(first_name == "Gilbert");
Person child{};
expect(not glz::read_jmespath<"family.children[0]">(child, buffer));
expect(child.first_name == "Lilly");
expect(not glz::read_jmespath<"family.children[1]">(child, buffer));
expect(child.first_name == "Vincent");
};
"run-time read_jmespath"_test = [] {
Home home{.family = {.father = {"Gilbert", "Fox", 28},
.mother = {"Anne", "Fox", 30},
.children = {{"Lilly"}, {"Vincent"}}}};
std::string buffer{};
expect(not glz::write_json(home, buffer));
std::string first_name{};
auto ec = glz::read_jmespath("family.father.first_name", first_name, buffer);
expect(not ec) << glz::format_error(ec, buffer);
expect(first_name == "Gilbert");
Person child{};
expect(not glz::read_jmespath("family.children[0]", child, buffer));
expect(child.first_name == "Lilly");
expect(not glz::read_jmespath("family.children[1]", child, buffer));
expect(child.first_name == "Vincent");
};
};
by @stephenberry in #1509
Other Improvements
- allow subclassing json_t by @benine203 in #1504
Full Changelog: v4.2.0...v4.2.1
v4.2.0
Breaking Partial Read Changes (Faster/Cleaner)
- The option
partial_read_nested
has been removed, to simplify partial reading and bring better performance. If the optionpartial_read
istrue
, then short circuiting will occur after the deepest value is read. This ensures that a true "partial" read occurs and post-read skipping is not necessary.- If you only want to read certain fields in a struct and perform this multiple times within a larger object, then use
glz::skip
or seterror_on_unknown_keys = false
. Either of these approaches will skip keys you don't care about.
- If you only want to read certain fields in a struct and perform this multiple times within a larger object, then use
- The local metadata for
static constexpr auto partial_read = true;
will now be ignored. You must explicitly useglz::opts{.partial_read = true}
in the Glaze options for partial reading.- The local meta parameter was a poor design choice, because we want to separate serialization logic from options, so that the same
glz::meta
information can be used with various options. It also complicated the code/API.
- The local meta parameter was a poor design choice, because we want to separate serialization logic from options, so that the same
Tip
When setting up partial reading, it is best to just include the parts of the deepest structure you care about and the parent structures to that location. This ensures the most efficient traversal to the fields of interest and the least amount of C++ struct writing.
The documentation for partial reading has been updated here: [Partial Read](https://github.com/stephenberry/glaze/blob/main/docs/partial-read.md)
by @stephenberry in #1502
Improvements
- Faster string skipping with SWAR in #1499
Full Changelog: v4.1.0...v4.2.0
v4.1.0
Improvements
- Update to fast_float v7.0.0 in #1488
- Adding example_json for newcomers to Glaze in #1490
- Document glz::convert_struct in #1491
- Faster skipping in #1495
New Reflection Feature
- glz::for_each_field in #1497
struct test_type
{
int32_t int1{};
int64_t int2{};
};
test_type var{42, 43};
glz::for_each_field(var, [](auto& field) { field += 1; });
expect(var.int1 == 43);
expect(var.int2 == 44);
In Development (Breaking Changes)
glz::mustache
has been renamed to glz::stencil
along with all other associated names. The decision was made to make a more optimal approach that does not conform strictly to the mustache specification, with the long term goal of adding compile time options that satisfy full compliance. The more generally useful string interpolation will be named stencil
and not automatically escape HTML characters.
- Sections and inverted sections in stencils
- Other stencil improvements and buffer API
by @stephenberry in #1471, #1492, #1493, #1494
Full Changelog: v4.0.3...v4.1.0
v4.0.3
Improvements
- Support for nullable value types in #1460
- This adds support for optional like types that cannot provide an operator bool() because that operator is reserved for some other action. This adds a nullable_value_t concept that only checks for value() and has_value().
- Adding
glz::convert_struct
for reflection conversion in #1472 - Faster
glz::validate_json
in #1478 - Use constructible_from rather than convertible to string_view in #1486
- Cleanup and minor optimizations by @stephenberry in #1461, #1462, #1464, #1475, #1479
Fixes
- Fix issue with variants of 1 type and tags in #1485
- validate_skipped for glz::validate_jsonc in #1476
In Development
Full Changelog: v4.0.2...v4.0.3
v4.0.2
Improvements
- Faster JSON object reading in some cases in #1442
- Simplified JSON read code in #1449
- Adding title for json schema when writing variants in #1451
Fixes
- Fixed volatile bug by @stephenberry in #1440
- Handling for escaped string reading (at least for column wise CSV) in #1446
- Avoiding _umul128, fallback to umul128_generic in MSYS2/MINGW32 by @jalius in #1453
- Eigen check for get_member to avoid invocable branch in #1458
In Development
- Asio improvementsin #1444
- Use a single vector for async_map and support atomic (non-movable) types directly in #1456
Full Changelog: v4.0.1...v4.0.2
v4.0.1
Improvements
- Integer assignment support for glz::json_t by @stephenberry in #1425
- Using a compile time linear search for partial writing index finding in #1427
Fixes
- Fix extra comma when unknown writer is empty in #1435
- Fix number parsing for glz::raw_json by @stephenberry in #1432
In Development
- Fix for asio_client call with no parameters in #1424
- Fix invalid notify check on response rather than request in #1430
- glz::async_map: using proxy rather than allocating unique_ptr in #1433
Full Changelog: v4.0.0...v4.0.1