mirror of
https://github.com/nlohmann/json.git
synced 2026-02-17 17:14:00 +00:00
Compare commits
6 Commits
issue4755-
...
add-ci-ste
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41c94e06fc | ||
|
|
c17c7a8bd8 | ||
|
|
1415eb4cb5 | ||
|
|
eef76c200e | ||
|
|
3b02afb9d9 | ||
|
|
6b9199382b |
17
.github/workflows/ubuntu.yml
vendored
17
.github/workflows/ubuntu.yml
vendored
@@ -143,7 +143,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
# older GCC docker images (4, 5, 6) fail to check out code
|
||||
compiler: ['7', '8', '9', '10', '11', '12', '13', '14', 'latest']
|
||||
compiler: ['7', '8', '9', '10', '11', '12', '13', '14', '15', 'latest']
|
||||
container: gcc:${{ matrix.compiler }}
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
@@ -221,6 +221,21 @@ jobs:
|
||||
- name: Build
|
||||
run: cmake --build build --target ci_cuda_example
|
||||
|
||||
ci_module_cpp20:
|
||||
strategy:
|
||||
matrix:
|
||||
container: ['gcc:latest', 'silkeh/clang:latest']
|
||||
runs-on: ubuntu-latest
|
||||
container: ${{ matrix.container }}
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Get latest CMake and ninja
|
||||
uses: lukka/get-cmake@57c20a23a6cac5b90f31864439996e5b206df9dc # v4.0.1
|
||||
- name: Run CMake
|
||||
run: cmake -S . -B build -DJSON_CI=On
|
||||
- name: Build
|
||||
run: cmake --build build --target ci_module_cpp20
|
||||
|
||||
ci_icpc:
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/nlohmann/json-ci:v2.2.0
|
||||
|
||||
9
.github/workflows/windows.yml
vendored
9
.github/workflows/windows.yml
vendored
@@ -111,3 +111,12 @@ jobs:
|
||||
run: cmake --build build --config Debug --parallel 10
|
||||
- name: Test
|
||||
run: cd build ; ctest -j 10 -C Debug --exclude-regex "test-unicode" --output-on-failure
|
||||
|
||||
ci_module_cpp20:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Run CMake (Debug)
|
||||
run: cmake -S . -B build -G "Visual Studio 17 2022" -DJSON_CI=ON -DCMAKE_CXX_FLAGS="/permissive- /std:c++latest /utf-8 /W4 /WX"
|
||||
- name: Build
|
||||
run: cmake --build build --config Debug --target ci_module_cpp20
|
||||
|
||||
@@ -659,6 +659,17 @@ add_custom_target(ci_cuda_example
|
||||
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_cuda_example
|
||||
)
|
||||
|
||||
###############################################################################
|
||||
# C++ 20 modules
|
||||
###############################################################################
|
||||
|
||||
add_custom_target(ci_module_cpp20
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
||||
-S${PROJECT_SOURCE_DIR}/tests/module_cpp20 -B${PROJECT_BINARY_DIR}/ci_module_cpp20
|
||||
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/ci_module_cpp20
|
||||
)
|
||||
|
||||
###############################################################################
|
||||
# Intel C++ Compiler
|
||||
###############################################################################
|
||||
|
||||
@@ -76,6 +76,7 @@ violations will result in a failed build.
|
||||
| GNU 13.3.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
||||
| GNU 14.2.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
||||
| GNU 14.2.0 | arm64 | Linux 6.1.100 | Cirrus CI |
|
||||
| GNU 15.1.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
|
||||
| icpc (ICC) 2021.5.0 20211109 | x86_64 | Ubuntu 20.04.3 LTS | GitHub |
|
||||
| MSVC 19.0.24241.7 | x86 | Windows 8.1 | AppVeyor |
|
||||
| MSVC 19.16.27035.0 | x86 | Windows-10 (Build 14393) | AppVeyor |
|
||||
|
||||
@@ -34,6 +34,10 @@
|
||||
#include <optional> // optional
|
||||
#endif
|
||||
|
||||
#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
|
||||
#include <string_view> // u8string_view
|
||||
#endif
|
||||
|
||||
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||
namespace detail
|
||||
{
|
||||
|
||||
@@ -53,7 +53,7 @@ enum class cbor_tag_handler_t
|
||||
|
||||
@note from https://stackoverflow.com/a/1001328/266378
|
||||
*/
|
||||
static inline bool little_endianness(int num = 1) noexcept
|
||||
inline bool little_endianness(int num = 1) noexcept
|
||||
{
|
||||
return *reinterpret_cast<char*>(&num) == 1;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
#include <tuple> // tuple
|
||||
#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
|
||||
#include <utility> // declval
|
||||
|
||||
#if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L
|
||||
#include <cstddef> // byte
|
||||
#endif
|
||||
#include <nlohmann/detail/iterators/iterator_traits.hpp>
|
||||
#include <nlohmann/detail/macro_scope.hpp>
|
||||
#include <nlohmann/detail/meta/call_std/begin.hpp>
|
||||
@@ -239,6 +241,30 @@ struct char_traits<signed char> : std::char_traits<char>
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L
|
||||
template<>
|
||||
struct char_traits<std::byte> : std::char_traits<char>
|
||||
{
|
||||
using char_type = std::byte;
|
||||
using int_type = uint64_t;
|
||||
|
||||
static int_type to_int_type(char_type c) noexcept
|
||||
{
|
||||
return static_cast<int_type>(std::to_integer<unsigned char>(c));
|
||||
}
|
||||
|
||||
static char_type to_char_type(int_type i) noexcept
|
||||
{
|
||||
return std::byte(static_cast<unsigned char>(i));
|
||||
}
|
||||
|
||||
static constexpr int_type eof() noexcept
|
||||
{
|
||||
return static_cast<int_type>(std::char_traits<char>::eof());
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
///////////////////
|
||||
// is_ functions //
|
||||
///////////////////
|
||||
|
||||
@@ -62,7 +62,7 @@ inline StringType escape(StringType s)
|
||||
* Note the order of escaping "~1" to "/" and "~0" to "~" is important.
|
||||
*/
|
||||
template<typename StringType>
|
||||
static void unescape(StringType& s)
|
||||
inline void unescape(StringType& s)
|
||||
{
|
||||
replace_substring(s, StringType{"~1"}, StringType{"/"});
|
||||
replace_substring(s, StringType{"~0"}, StringType{"~"});
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <nlohmann/detail/hash.hpp>
|
||||
#include <nlohmann/detail/input/binary_reader.hpp>
|
||||
#include <nlohmann/detail/input/input_adapters.hpp>
|
||||
#include <nlohmann/detail/input/json_sax.hpp>
|
||||
#include <nlohmann/detail/input/lexer.hpp>
|
||||
#include <nlohmann/detail/input/parser.hpp>
|
||||
#include <nlohmann/detail/iterators/internal_iterator.hpp>
|
||||
|
||||
@@ -3126,7 +3126,7 @@ inline StringType escape(StringType s)
|
||||
* Note the order of escaping "~1" to "/" and "~0" to "~" is important.
|
||||
*/
|
||||
template<typename StringType>
|
||||
static void unescape(StringType& s)
|
||||
inline void unescape(StringType& s)
|
||||
{
|
||||
replace_substring(s, StringType{"~1"}, StringType{"/"});
|
||||
replace_substring(s, StringType{"~0"}, StringType{"~"});
|
||||
@@ -3367,7 +3367,9 @@ NLOHMANN_JSON_NAMESPACE_END
|
||||
#include <tuple> // tuple
|
||||
#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
|
||||
#include <utility> // declval
|
||||
|
||||
#if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L
|
||||
#include <cstddef> // byte
|
||||
#endif
|
||||
// #include <nlohmann/detail/iterators/iterator_traits.hpp>
|
||||
// __ _____ _____ _____
|
||||
// __| | __| | | | JSON for Modern C++
|
||||
@@ -3776,6 +3778,30 @@ struct char_traits<signed char> : std::char_traits<char>
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L
|
||||
template<>
|
||||
struct char_traits<std::byte> : std::char_traits<char>
|
||||
{
|
||||
using char_type = std::byte;
|
||||
using int_type = uint64_t;
|
||||
|
||||
static int_type to_int_type(char_type c) noexcept
|
||||
{
|
||||
return static_cast<int_type>(std::to_integer<unsigned char>(c));
|
||||
}
|
||||
|
||||
static char_type to_char_type(int_type i) noexcept
|
||||
{
|
||||
return std::byte(static_cast<unsigned char>(i));
|
||||
}
|
||||
|
||||
static constexpr int_type eof() noexcept
|
||||
{
|
||||
return static_cast<int_type>(std::char_traits<char>::eof());
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
///////////////////
|
||||
// is_ functions //
|
||||
///////////////////
|
||||
@@ -4819,6 +4845,10 @@ NLOHMANN_JSON_NAMESPACE_END
|
||||
#include <optional> // optional
|
||||
#endif
|
||||
|
||||
#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
|
||||
#include <string_view> // u8string_view
|
||||
#endif
|
||||
|
||||
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||
namespace detail
|
||||
{
|
||||
@@ -9838,7 +9868,7 @@ enum class cbor_tag_handler_t
|
||||
|
||||
@note from https://stackoverflow.com/a/1001328/266378
|
||||
*/
|
||||
static inline bool little_endianness(int num = 1) noexcept
|
||||
inline bool little_endianness(int num = 1) noexcept
|
||||
{
|
||||
return *reinterpret_cast<char*>(&num) == 1;
|
||||
}
|
||||
@@ -12859,6 +12889,8 @@ NLOHMANN_JSON_NAMESPACE_END
|
||||
|
||||
// #include <nlohmann/detail/input/input_adapters.hpp>
|
||||
|
||||
// #include <nlohmann/detail/input/json_sax.hpp>
|
||||
|
||||
// #include <nlohmann/detail/input/lexer.hpp>
|
||||
|
||||
// #include <nlohmann/detail/input/parser.hpp>
|
||||
|
||||
12
tests/module_cpp20/CMakeLists.txt
Normal file
12
tests/module_cpp20/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
cmake_minimum_required(VERSION 3.28)
|
||||
|
||||
project(json_test CXX)
|
||||
|
||||
add_executable(json_test)
|
||||
|
||||
target_sources(json_test
|
||||
PRIVATE main.cpp
|
||||
PUBLIC FILE_SET cxx_modules TYPE CXX_MODULES FILES json.cpp)
|
||||
|
||||
target_compile_features(json_test PUBLIC cxx_std_20)
|
||||
target_include_directories(json_test PRIVATE ../../include)
|
||||
17
tests/module_cpp20/json.cpp
Normal file
17
tests/module_cpp20/json.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
module;
|
||||
#include <nlohmann/json.hpp>
|
||||
export module json;
|
||||
|
||||
export namespace nlohmann
|
||||
{
|
||||
using ::nlohmann::adl_serializer;
|
||||
|
||||
using ::nlohmann::basic_json;
|
||||
using ::nlohmann::json_pointer;
|
||||
|
||||
using ::nlohmann::json;
|
||||
using ::nlohmann::ordered_json;
|
||||
using ::nlohmann::ordered_map;
|
||||
|
||||
using ::nlohmann::json_pointer;
|
||||
} // namespace nlohmann
|
||||
6
tests/module_cpp20/main.cpp
Normal file
6
tests/module_cpp20/main.cpp
Normal file
@@ -0,0 +1,6 @@
|
||||
import json;
|
||||
|
||||
int main()
|
||||
{
|
||||
nlohmann::json j;
|
||||
}
|
||||
@@ -1880,3 +1880,82 @@ TEST_CASE("MessagePack roundtrips" * doctest::skip())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
// Test suite for verifying MessagePack handling with std::byte input
|
||||
TEST_CASE("MessagePack with std::byte")
|
||||
{
|
||||
|
||||
SECTION("std::byte compatibility")
|
||||
{
|
||||
SECTION("vector roundtrip")
|
||||
{
|
||||
json original =
|
||||
{
|
||||
{"name", "test"},
|
||||
{"value", 42},
|
||||
{"array", {1, 2, 3}}
|
||||
};
|
||||
|
||||
std::vector<uint8_t> temp = json::to_msgpack(original);
|
||||
// Convert the uint8_t vector to std::byte vector
|
||||
std::vector<std::byte> msgpack_data(temp.size());
|
||||
for (size_t i = 0; i < temp.size(); ++i)
|
||||
{
|
||||
msgpack_data[i] = std::byte(temp[i]);
|
||||
}
|
||||
// Deserialize from std::byte vector back to JSON
|
||||
json from_bytes;
|
||||
CHECK_NOTHROW(from_bytes = json::from_msgpack(msgpack_data));
|
||||
|
||||
CHECK(from_bytes == original);
|
||||
}
|
||||
|
||||
SECTION("empty vector")
|
||||
{
|
||||
const std::vector<std::byte> empty_data;
|
||||
CHECK_THROWS_WITH_AS([&]()
|
||||
{
|
||||
[[maybe_unused]] auto result = json::from_msgpack(empty_data);
|
||||
return true;
|
||||
}
|
||||
(),
|
||||
"[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing MessagePack value: unexpected end of input",
|
||||
json::parse_error&);
|
||||
}
|
||||
|
||||
SECTION("comparison with workaround")
|
||||
{
|
||||
json original =
|
||||
{
|
||||
{"string", "hello"},
|
||||
{"integer", 42},
|
||||
{"float", 3.14},
|
||||
{"boolean", true},
|
||||
{"null", nullptr},
|
||||
{"array", {1, 2, 3}},
|
||||
{"object", {{"key", "value"}}}
|
||||
};
|
||||
|
||||
std::vector<uint8_t> temp = json::to_msgpack(original);
|
||||
|
||||
std::vector<std::byte> msgpack_data(temp.size());
|
||||
for (size_t i = 0; i < temp.size(); ++i)
|
||||
{
|
||||
msgpack_data[i] = std::byte(temp[i]);
|
||||
}
|
||||
// Attempt direct deserialization using std::byte input
|
||||
json direct_result = json::from_msgpack(msgpack_data);
|
||||
|
||||
// Test the workaround approach: reinterpret as unsigned char* and use iterator range
|
||||
const auto* const char_start = reinterpret_cast<unsigned char const*>(msgpack_data.data());
|
||||
const auto* const char_end = char_start + msgpack_data.size();
|
||||
json workaround_result = json::from_msgpack(char_start, char_end);
|
||||
|
||||
// Verify that the final deserialized JSON matches the original JSON
|
||||
CHECK(direct_result == workaround_result);
|
||||
CHECK(direct_result == original);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -396,7 +396,7 @@ struct Example_3810
|
||||
Example_3810() = default;
|
||||
};
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Example_3810, bla); // NOLINT(misc-use-internal-linkage)
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Example_3810, bla) // NOLINT(misc-use-internal-linkage)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// for #4740
|
||||
|
||||
@@ -60,12 +60,12 @@ TEST_CASE("Custom container member begin/end")
|
||||
{
|
||||
const char* data;
|
||||
|
||||
const char* begin() const
|
||||
const char* begin() const noexcept
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
const char* end() const
|
||||
const char* end() const noexcept
|
||||
{
|
||||
return data + strlen(data); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user