diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index f16bc910dff..19095ce15d6 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -98,7 +98,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner +<<<<<<< HEAD uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2 +======= + uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1 +>>>>>>> 572a2572 (:arrow_up: Bump step-security/harden-runner from 2.12.0 to 2.12.1 (#4815)) with: egress-policy: audit @@ -252,7 +256,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner +<<<<<<< HEAD uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2 +======= + uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1 +>>>>>>> 572a2572 (:arrow_up: Bump step-security/harden-runner from 2.12.0 to 2.12.1 (#4815)) with: egress-policy: audit @@ -273,7 +281,11 @@ jobs: target: [ci_test_examples, ci_test_build_documentation] steps: - name: Harden Runner +<<<<<<< HEAD uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2 +======= + uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1 +>>>>>>> 572a2572 (:arrow_up: Bump step-security/harden-runner from 2.12.0 to 2.12.1 (#4815)) with: egress-policy: audit diff --git a/README.md b/README.md index 0ead1db6ccf..93da5ccf9b6 100644 --- a/README.md +++ b/README.md @@ -163,6 +163,19 @@ If using modules (enabled with `NLOHMANN_JSON_BUILD_MODULES`), this example beco import std; import nlohmann.json; +using nlohmann::json; + +// ... + +std::ifstream f("example.json"); +json data = json::parse(f); +``` + +If using modules (enabled with `NLOHMANN_JSON_BUILD_MODULES`), this example becomes: +```cpp +import std; +import nlohmann.json; + using json = nlohmann::json; // ... @@ -1758,6 +1771,7 @@ I deeply appreciate the help of the following people. 382. [bitFiedler](https://github.com/bitFiedler) made GDB pretty printer work with Python 3.8. 383. [Gianfranco Costamagna](https://github.com/LocutusOfBorg) fixed a compiler warning. 384. [risa2000](https://github.com/risa2000) made `std::filesystem::path` conversion to/from UTF-8 encoded string explicit. +385. [mikomikotaishi](https://github.com/mikomikotaishi) adding module support. Thanks a lot for helping out! Please [let me know](mailto:mail@nlohmann.me) if I forgot someone. diff --git a/docs/mkdocs/docs/features/modules.md b/docs/mkdocs/docs/features/modules.md index 884e9b07ac0..6068108b8b0 100644 --- a/docs/mkdocs/docs/features/modules.md +++ b/docs/mkdocs/docs/features/modules.md @@ -25,6 +25,7 @@ json data = json::parse(f); ## Modules do not export macros It should be noted that as modules do not export macros, the `nlohmann.json` module will not export any macros, but rather only the following symbols: + - `nlohmann::adl_serializer` - `nlohmann::basic_json` - `nlohmann::json` diff --git a/modules/json.cppm b/modules/json.cppm new file mode 100644 index 00000000000..5f55acc2b85 --- /dev/null +++ b/modules/json.cppm @@ -0,0 +1,14 @@ +module; + +#include + +export module nlohmann.json; + +export namespace nlohmann { + using ::nlohmann::adl_serializer; + using ::nlohmann::basic_json; + using ::nlohmann::json; + using ::nlohmann::json_pointer; + using ::nlohmann::ordered_json; + using ::nlohmann::ordered_map; +} // namespace nlohmann diff --git a/src/modules/json.cppm b/src/modules/json.cppm index 71a4bd82705..5f55acc2b85 100644 --- a/src/modules/json.cppm +++ b/src/modules/json.cppm @@ -5,18 +5,10 @@ module; export module nlohmann.json; export namespace nlohmann { - template - using adl_serializer = ::nlohmann::adl_serializer; - - using basic_json = ::nlohmann::basic_json<>; - - using json = ::nlohmann::json; - - template - using json_pointer = ::nlohmann::json_pointer; - + using ::nlohmann::adl_serializer; + using ::nlohmann::basic_json; + using ::nlohmann::json; + using ::nlohmann::json_pointer; using ::nlohmann::ordered_json; - - template - using ordered_map = ::nlohmann::ordered_map; + using ::nlohmann::ordered_map; } // namespace nlohmann diff --git a/tests/src/unit-regression2.cpp b/tests/src/unit-regression2.cpp index 54b3fd59716..9a38e04f887 100644 --- a/tests/src/unit-regression2.cpp +++ b/tests/src/unit-regression2.cpp @@ -1188,4 +1188,71 @@ TEST_CASE_TEMPLATE("issue #4798 - nlohmann::json::to_msgpack() encode float NaN CHECK(json::from_cbor(cbor_z_3).get() == -std::numeric_limits::infinity()); } +TEST_CASE_TEMPLATE("issue #4798 - nlohmann::json::to_msgpack() encode float NaN as double", T, double, float) // NOLINT(readability-math-missing-parentheses) +{ + // With issue #4798, we encode NaN, infinity, and -infinity as float instead + // of double to allow for smaller encodings. + const json jx = std::numeric_limits::quiet_NaN(); + const json jy = std::numeric_limits::infinity(); + const json jz = -std::numeric_limits::infinity(); + + ///////////////////////////////////////////////////////////////////////// + // MessagePack + ///////////////////////////////////////////////////////////////////////// + + // expected MessagePack values + const std::vector msgpack_x = {{0xCA, 0x7F, 0xC0, 0x00, 0x00}}; + const std::vector msgpack_y = {{0xCA, 0x7F, 0x80, 0x00, 0x00}}; + const std::vector msgpack_z = {{0xCA, 0xFF, 0x80, 0x00, 0x00}}; + + CHECK(json::to_msgpack(jx) == msgpack_x); + CHECK(json::to_msgpack(jy) == msgpack_y); + CHECK(json::to_msgpack(jz) == msgpack_z); + + CHECK(std::isnan(json::from_msgpack(msgpack_x).get())); + CHECK(json::from_msgpack(msgpack_y).get() == std::numeric_limits::infinity()); + CHECK(json::from_msgpack(msgpack_z).get() == -std::numeric_limits::infinity()); + + // Make sure the other MessagePakc encodings for NaN, infinity, and + // -infinity are still supported. + const std::vector msgpack_x_2 = {{0xCB, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + const std::vector msgpack_y_2 = {{0xCB, 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + const std::vector msgpack_z_2 = {{0xCB, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + CHECK(std::isnan(json::from_msgpack(msgpack_x_2).get())); + CHECK(json::from_msgpack(msgpack_y_2).get() == std::numeric_limits::infinity()); + CHECK(json::from_msgpack(msgpack_z_2).get() == -std::numeric_limits::infinity()); + + ///////////////////////////////////////////////////////////////////////// + // CBOR + ///////////////////////////////////////////////////////////////////////// + + // expected CBOR values + const std::vector cbor_x = {{0xF9, 0x7E, 0x00}}; + const std::vector cbor_y = {{0xF9, 0x7C, 0x00}}; + const std::vector cbor_z = {{0xF9, 0xfC, 0x00}}; + + CHECK(json::to_cbor(jx) == cbor_x); + CHECK(json::to_cbor(jy) == cbor_y); + CHECK(json::to_cbor(jz) == cbor_z); + + CHECK(std::isnan(json::from_cbor(cbor_x).get())); + CHECK(json::from_cbor(cbor_y).get() == std::numeric_limits::infinity()); + CHECK(json::from_cbor(cbor_z).get() == -std::numeric_limits::infinity()); + + // Make sure the other CBOR encodings for NaN, infinity, and -infinity are + // still supported. + const std::vector cbor_x_2 = {{0xFA, 0x7F, 0xC0, 0x00, 0x00}}; + const std::vector cbor_y_2 = {{0xFA, 0x7F, 0x80, 0x00, 0x00}}; + const std::vector cbor_z_2 = {{0xFA, 0xFF, 0x80, 0x00, 0x00}}; + const std::vector cbor_x_3 = {{0xFB, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + const std::vector cbor_y_3 = {{0xFB, 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + const std::vector cbor_z_3 = {{0xFB, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + CHECK(std::isnan(json::from_cbor(cbor_x_2).get())); + CHECK(json::from_cbor(cbor_y_2).get() == std::numeric_limits::infinity()); + CHECK(json::from_cbor(cbor_z_2).get() == -std::numeric_limits::infinity()); + CHECK(std::isnan(json::from_cbor(cbor_x_3).get())); + CHECK(json::from_cbor(cbor_y_3).get() == std::numeric_limits::infinity()); + CHECK(json::from_cbor(cbor_z_3).get() == -std::numeric_limits::infinity()); +} + DOCTEST_CLANG_SUPPRESS_WARNING_POP