Skip to content

Releases: stephenberry/glaze

v4.3.0

06 Jan 18:39
Compare
Choose a tag to compare

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

Full Changelog: v4.2.4...v4.3.0

v4.2.4

02 Jan 16:18
Compare
Choose a tag to compare

Improvements

  • Skipping and tuple cleanup in #1531
  • Faster writing in #1534
  • number option clarification and better errors in #1535

In Development

Full Changelog: v4.2.3...v4.2.4

v4.2.3

26 Dec 20:37
Compare
Choose a tag to compare

Improvements

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

18 Dec 15:45
Compare
Choose a tag to compare

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

  • Include missing version header that could cause segfaults with GCC in #1508 (Many thanks to @hs-vc)

Full Changelog: v4.2.1...v4.2.2

v4.2.1

17 Dec 17:31
Compare
Choose a tag to compare

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

Full Changelog: v4.2.0...v4.2.1

v4.2.0

16 Dec 23:08
Compare
Choose a tag to compare

Breaking Partial Read Changes (Faster/Cleaner)

  • The option partial_read_nested has been removed, to simplify partial reading and bring better performance. If the option partial_read is true, 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 set error_on_unknown_keys = false. Either of these approaches will skip keys you don't care about.
  • The local metadata for static constexpr auto partial_read = true; will now be ignored. You must explicitly use glz::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.

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

14 Dec 15:03
Compare
Choose a tag to compare

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.

Full Changelog: v4.0.3...v4.1.0

v4.0.3

12 Dec 15:40
Compare
Choose a tag to compare

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

  • Improvements to glz::async_map in #1465
  • async_map -> shared_async_map in #1469

Full Changelog: v4.0.2...v4.0.3

v4.0.2

02 Dec 14:51
Compare
Choose a tag to compare

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

13 Nov 20:55
Compare
Choose a tag to compare

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