Skip to content

Releases: stephenberry/glaze

v4.0.0

31 Oct 14:43
Compare
Choose a tag to compare

Glaze 4.0

This release brings a number of bug fixes with very few API breaking changes. The primary breaking change is a new integer parsing algorithm that is faster and rejects decimals and negative exponents to avoid implicit data loss.

New Integer Parsing Logic

When parsing integer types such as uint16_t or int64_t, Glaze will now reject decimal values and negative exponents, so a value such as 1.37 would produce a parse_number_failure. This is important for avoiding implicit data loss. Developers often need to handle these conversions in various ways. Sometimes it is better to round (with various methodologies), other times truncate, and other times use the ceiling. It is recommended to use floating point types if you do not know if you will be receiving decimal values. A glz::custom lambda in your meta can be used to invisibly convert a parsed floating point value into an integer if you do not wish to do this elsewhere.

We are open to requests for additional integer parsing options, but don't want to add complexity to Glaze unless there is a concrete need. So, please open an issue if this change causes problems.

By narrowing the definition of what it means to parse an integer in Glaze it will allow us to perform variant type deduction on integer vs floating point types. So, we will be able to parse either into an integer or a float in a variant. This has been requested a few times and would allow interfaces to avoid data loss with large integers and floating point decimal values simultaneously.

In summary, this change in integer parsing provides the benefits:

  • Faster integer parsing
  • No implicit data loss
  • Disambiguation of integers and floats in JSON parsing to support dual integer/float types in variants and full numeric integrity

Positive exponents are still handled for integer parsing, such as 1e9, which can save space and be easier to read than 1000000000.

This release has no effect on integer serialization. Round-tripping in Glaze has not been affected.

Breaking Changes

  • String support for std::array<char, N> in #1247
    std::array<char, N> is now treated as a string type rather than an array of single character strings.

  • Roundtrip support for vector<pair>, better concatenate option support, and BEVE support for these in #1418
    When reading in a vector<pair> type objects are by default expected to be concatenated (as they are for output). The concatenate option must be set to false to read in a non-concatenated vector of pairs. Now both the concatenate = true and concatenate = false conditions properly roundtrip for both JSON and BEVE.

Improvements

  • json_t assignment operators and string_view constructor in #1412
  • Support for std::atomic in #1364
  • Use clang format 18.1 in #1374
  • Use jkj::dragonbox::to_decimal_ex for faster floating point serialization in #1392
  • Adding roundtrip format agnostic testing in #1380
  • Type "cls" or "clear" to bring the command line menu (glz::cli_menu) to the front in #1409

Fixes

  • Removing lots of noexcept qualifiers to allow exceptions to propagate when Glaze is used with exceptions enabled in #1420
  • Unknown fields fix with entirely null first object in #1367
  • [Concept update] string_t with resize also needs to have .data() by @sjanel in #1372
  • Support empty input NDJSON in #1381
  • Fix JSON RPC documentation link to json-rpc.cpp source by @pentatonick in #1385
  • Support reading into a const pointer to a member in #1387
  • Fix JSON parsing from arrays to set like types with custom structs by @sjanel in #1394
  • Put fast_float and dragonbox into glz namespace by @amosbird in #1398
  • Naming more things beve instead of binary in #1399
  • Using GLZ_ macro prefix for third party dependencies by @stephenberry in #1403
  • Add missing include inside of threadpool.hpp by @X-rays5 in #1413

Active Development (use at your own risk)

  • New binary REPE v1.0 spec implementation (repe::registry) in #1336
  • Capture functions by reference in repe::registry by @stephenberry in #1396
  • Removing repe::registry auto-locking in #1415

Full Changelog: v3.6.2...v4.0.0

v3.6.2

04 Oct 18:17
Compare
Choose a tag to compare

New AVX2 SIMD optimizations (faster string writing on some platforms)

The CMake now has the option glaze_ENABLE_AVX2. This will attempt to use AVX2 SIMD instructions in some cases to improve performance, as long as the system you are configuring on supports it. Set this option to OFF to disable the AVX2 instruction set, such as if you are cross-compiling for Arm. And, if you aren't using CMake the macro GLZ_USE_AVX2 enables the feature if defined.

Improvements

Fixes

  • Allow NDJSON in the skip_array requires statement. by @Haatschii in #1357

Full Changelog: v3.6.1...v3.6.2

v3.6.1

30 Sep 19:22
Compare
Choose a tag to compare

Generic JSON (glz::json_t) Improvements

See Generic JSON documentation for more details.

Calling .dump() on a json_t value is equivalent to calling glz::write_json(value), which returns an expected<std::string, glz::error_ctx>.

  • Support for reading json_t value as the source in #1337

After parsing into a json_t it is sometimes desirable to parse into a concrete struct or a portion of the json_t into a struct. Glaze allows a json_t value to be used as the source where a buffer would normally be passed.

auto json = glz::read_json<glz::json_t>(R"({"foo":"bar"})");
expect(json->contains("foo"));
auto obj = glz::read_json<std::map<std::string, std::string>>(json.value());
// This reads the json_t into a std::map

Another example:

glz::json_t json{};
expect(not glz::read_json(json, R"("Beautiful beginning")"));
std::string v{};
expect(not glz::read<glz::opts{}>(v, json));
expect(v == "Beautiful beginning");

Full Changelog: v3.6.0...v3.6.1

v3.6.0

26 Sep 17:56
Compare
Choose a tag to compare

Reflection API formalization progress

Caution

The glz::reflect API is under development and may evolve with time, albeit slowly.

We are beginning to formalize the core reflection API in Glaze. glz::refl was renamed to glz::reflect and the inline definition was removed.

Internal Improvements

  • Removed duplicate glz::custom code by @stephenberry in #1324
  • Moving skip_member to core/write for more general usage in #1329
  • Reflection API changes in #1327
  • Adding glz::flat_map in #1332
  • Updated feature test macros in glaze/core/feature_test

Full Changelog: v3.5.0...v3.6.0

v3.5.0

24 Sep 20:16
Compare
Choose a tag to compare

Major API (naming) breaking changes

Important

This is only an API (naming) change. No internal logic was changed.

Format Specifiers

Format in glz::opts are now all caps. This is to disambiguate from structs with similar names.
binary -> BEVE
json -> JSON
ndjson -> NDJSON
csv -> CSV

Important

If you set the format in glz::opts the naming changes from glz::opts{.format = glz::json} to glz::opts{.format = glz::JSON}

to/from specializations

For those who use custom serialization and have specialized to_json<T> and from_json<T>, these have been changed to be more generic. Use to<JSON, T> and from<JSON, T> instead.

This will significantly reduce internal code duplication across formats.

Binary (BEVE) name changes

Glaze used to refer to the BEVE format as binary. This was confusing and would become even more confusing as we add more binary formats.

Pretty much everywhere binary was referred to is now referred to as beve. So write_binary becomes write_beve.

  • The file paths glaze/binary have been renamed to glaze/beve
  • The header glaze/binary.hpp has been renamed to glaze/beve.hpp

by @stephenberry in #1323

Full Changelog: v3.4.3...v3.5.0

v3.4.3

24 Sep 18:02
Compare
Choose a tag to compare

Internal cleanup and faster hashing

Full Changelog: v3.4.2...v3.4.3

v3.4.2

23 Sep 13:20
Compare
Choose a tag to compare

Internal Improvements

Full Changelog: v3.4.1...v3.4.2

v3.4.1

17 Sep 23:45
Compare
Choose a tag to compare

Improvements

  • New glz::write_at, to write to a target value given a JSON Pointer path by @stephenberry in #1300
  • Limit recursive depth in beve_to_json in #1301
  • new_lines_in_arrays support for .prettify = true write in #1302
  • Enum reading with new hash approach in #1303
  • Support for partial writing of const qualified objects in #1304
  • Using new hash approach in glz::mustache in #1306

glz::write_at example:

std::string buffer = R"({"str":"hello","number":3.14,"sub":{"target":"X"}})";
auto ec = glz::write_at<"/sub/target">("42", buffer);
expect(buffer == R"({"str":"hello","number":3.14,"sub":{"target":42}})");

Full Changelog: v3.4.0...v3.4.1

v3.4.0

16 Sep 15:48
Compare
Choose a tag to compare

Breaking Change of glz::nameof enum interface

The typical use case of glz::enumerate within a glz::meta has been unaffected, and therefore most users will be unaffected by this change.

This update removes the enum_macro.hpp header (GLZ_ENUM and GLZ_ENUM_MAP) and adds a new glz::meta approach that takes an array of keys and an array of values. This keys/values approach only supports enums in Glaze (currently to support faster internal compilation of enums), but broader support can be added in the future.

The enum_macro approach of using ADL created issues with other repositories that would declare a namespace nameof, and the macro expansion increased compilation time and was not a good, generic solution.

glz::nameof function for internal Glaze enums has been removed.

by @stephenberry in #1297

Other Fixes

  • fixes min/max macro conflict in dragonbox.hpp on MSVC by @lambwheit in #1298
  • glz::meta keys for enums, removing nameof ADL and enum_macro.hpp

Experimental glz::asio_client changes

Full Changelog: v3.3.4...v3.4.0

v3.3.4

10 Sep 17:20
Compare
Choose a tag to compare

Experimental glz::repe::registry reworking of locking logic by @stephenberry in #1290

This makes the registry locking logic behave the same for reading and writing. This limits reading a bit more by not allowing asynchronous reads to the exact same field, but it makes asynchronous writing possible, and keeps the locking logic simpler. We can now asynchronously write to differing targets, and importantly we can call asynchronous invocations.

We are removing automatic invoke locking. With variables, there is no place for a user to put logic when it comes to locking/unlocking access. However, when it comes to functions, there is room for users to add mutexes and locks to customize lock behavior. Also, functions often have complex side effects that need to be known to the programmer. On top of this, if we don't manipulate references in an RPC, we'd like the default behavior to be able to asynchronously call these functions. For these reasons we don't automatically lock the path taken to the function call. Because we also don't want to assume that a function call would manipulate the returned state of a data, which would block reads to the data.

Full Changelog: v3.3.3...v3.3.4