mirror of
https://github.com/nlohmann/json.git
synced 2026-07-09 03:55:09 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f3d48e4f2f |
@@ -234,11 +234,20 @@ jobs:
|
|||||||
|
|
||||||
ci_cuda_example:
|
ci_cuda_example:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: ghcr.io/nlohmann/json-ci:v2.4.0
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
# matrix to empirically pin down which nvcc/CUDA versions reproduce #3907
|
||||||
|
# (a c++20 parse error in iteration_proxy.hpp's enable_borrowed_range) before
|
||||||
|
# attempting a source-level fix; 11.8 predates CUDA's C++20 support entirely.
|
||||||
|
cuda: ['11.8.0', '12.0.1', '12.1.1', '12.2.2', '12.3.2', '12.4.1', '12.5.1', '12.6.3']
|
||||||
|
container: nvidia/cuda:${{ matrix.cuda }}-devel-ubuntu22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
- name: Get latest CMake and ninja
|
||||||
|
uses: lukka/get-cmake@f5b8fbb4d77cec1acc5a5f9f0df4beffaf5d98d9 # v4.3.4
|
||||||
- name: Run CMake
|
- name: Run CMake
|
||||||
run: cmake -S . -B build -DJSON_CI=On
|
run: cmake -S . -B build -DJSON_CI=On
|
||||||
- name: Build
|
- name: Build
|
||||||
|
|||||||
@@ -669,7 +669,6 @@ add_custom_target(ci_test_compiler_default
|
|||||||
add_custom_target(ci_cuda_example
|
add_custom_target(ci_cuda_example
|
||||||
COMMAND ${CMAKE_COMMAND}
|
COMMAND ${CMAKE_COMMAND}
|
||||||
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
||||||
-DCMAKE_CUDA_HOST_COMPILER=g++-8
|
|
||||||
-S${PROJECT_SOURCE_DIR}/tests/cuda_example -B${PROJECT_BINARY_DIR}/build_cuda_example
|
-S${PROJECT_SOURCE_DIR}/tests/cuda_example -B${PROJECT_BINARY_DIR}/build_cuda_example
|
||||||
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_cuda_example
|
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_cuda_example
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
User-agent: *
|
|
||||||
Allow: /
|
|
||||||
|
|
||||||
Sitemap: https://json.nlohmann.me/sitemap.xml
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
"""Copy each documentation page's Markdown source into the built site."""
|
|
||||||
|
|
||||||
# Creates a `<path>.md` sibling of each HTML output (for example,
|
|
||||||
# `features/comments/` becomes `features/comments.md`) so agents and tools can
|
|
||||||
# fetch the raw Markdown directly instead of parsing rendered HTML.
|
|
||||||
|
|
||||||
import os
|
|
||||||
import shutil
|
|
||||||
|
|
||||||
_pages = []
|
|
||||||
|
|
||||||
|
|
||||||
def on_files(files, config):
|
|
||||||
global _pages
|
|
||||||
_pages = [f for f in files if f.is_documentation_page()]
|
|
||||||
return files
|
|
||||||
|
|
||||||
|
|
||||||
def on_post_build(config):
|
|
||||||
site_dir = config["site_dir"]
|
|
||||||
for file in _pages:
|
|
||||||
url = file.url.rstrip("/")
|
|
||||||
target = os.path.join(site_dir, (url or "index") + ".md")
|
|
||||||
os.makedirs(os.path.dirname(target), exist_ok=True)
|
|
||||||
shutil.copyfile(file.abs_src_path, target)
|
|
||||||
@@ -367,9 +367,6 @@ markdown_extensions:
|
|||||||
auto_append:
|
auto_append:
|
||||||
- ../includes/glossary.md
|
- ../includes/glossary.md
|
||||||
|
|
||||||
hooks:
|
|
||||||
- hooks/copy_markdown_source.py
|
|
||||||
|
|
||||||
plugins:
|
plugins:
|
||||||
- search:
|
- search:
|
||||||
separator: '[\s\-\.]'
|
separator: '[\s\-\.]'
|
||||||
@@ -392,33 +389,6 @@ plugins:
|
|||||||
- https://nlohmann.github.io/json/*
|
- https://nlohmann.github.io/json/*
|
||||||
- mailto:*
|
- mailto:*
|
||||||
- privacy
|
- privacy
|
||||||
- llmstxt:
|
|
||||||
markdown_description: >
|
|
||||||
JSON for Modern C++ is a C++11 header-only library implementing a JSON
|
|
||||||
value type with an STL-like API, JSON Pointer/Patch, CBOR/MessagePack/
|
|
||||||
BSON/UBJSON/BJData binary format support, and a SAX-style parser interface.
|
|
||||||
sections:
|
|
||||||
Home:
|
|
||||||
- index.md
|
|
||||||
- home/*.md
|
|
||||||
Features:
|
|
||||||
- features/*.md
|
|
||||||
- features/binary_formats/*.md
|
|
||||||
- features/element_access/*.md
|
|
||||||
- features/parsing/*.md
|
|
||||||
- features/types/*.md
|
|
||||||
Integration:
|
|
||||||
- integration/*.md
|
|
||||||
API Documentation:
|
|
||||||
- api/*.md
|
|
||||||
- api/basic_json/*.md
|
|
||||||
- api/adl_serializer/*.md
|
|
||||||
- api/byte_container_with_subtype/*.md
|
|
||||||
- api/json_pointer/*.md
|
|
||||||
- api/json_sax/*.md
|
|
||||||
- api/macros/*.md
|
|
||||||
Community:
|
|
||||||
- community/*.md
|
|
||||||
|
|
||||||
extra_css:
|
extra_css:
|
||||||
- css/custom.css
|
- css/custom.css
|
||||||
|
|||||||
@@ -7,6 +7,5 @@ mkdocs-material-extensions==1.3.1 # extensions
|
|||||||
mkdocs-minify-plugin==0.8.0 # plugin "minify"
|
mkdocs-minify-plugin==0.8.0 # plugin "minify"
|
||||||
mkdocs-redirects==1.2.3 # plugin "redirects"
|
mkdocs-redirects==1.2.3 # plugin "redirects"
|
||||||
mkdocs-htmlproofer-plugin==1.5.0 # plugin "htmlproofer"
|
mkdocs-htmlproofer-plugin==1.5.0 # plugin "htmlproofer"
|
||||||
mkdocs-llmstxt==0.5.0 # plugin "llmstxt"
|
|
||||||
|
|
||||||
PyYAML==6.0.3 # linter
|
PyYAML==6.0.3 # linter
|
||||||
|
|||||||
@@ -465,12 +465,18 @@ class serializer
|
|||||||
{
|
{
|
||||||
if (codepoint <= 0xFFFF)
|
if (codepoint <= 0xFFFF)
|
||||||
{
|
{
|
||||||
write_u_escape(bytes, static_cast<std::uint16_t>(codepoint));
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
||||||
|
static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
|
||||||
|
static_cast<std::uint16_t>(codepoint)));
|
||||||
|
bytes += 6;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
write_u_escape(bytes, static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)));
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
||||||
write_u_escape(bytes, static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
|
static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
|
||||||
|
static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
|
||||||
|
static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
|
||||||
|
bytes += 12;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -677,32 +683,6 @@ class serializer
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief write a lowercase "\uXXXX" escape sequence into @a string_buffer
|
|
||||||
*
|
|
||||||
* Branch-free replacement for `snprintf(buf, 7, "\\u%04x", codeunit)` in the
|
|
||||||
* string escaping hot path. It writes exactly six characters ('\\', 'u' and
|
|
||||||
* four hex digits) at position @a pos of @a string_buffer via a nibble
|
|
||||||
* lookup table, avoiding the format-string parsing and locale machinery of
|
|
||||||
* `snprintf`. Advances @a pos by the number of bytes written (6).
|
|
||||||
*
|
|
||||||
* @param[in] pos position in @a string_buffer to write at; there must
|
|
||||||
* be at least 6 bytes of headroom
|
|
||||||
* @param[in] codeunit 16-bit value to encode
|
|
||||||
*/
|
|
||||||
void write_u_escape(std::size_t& pos, std::uint16_t codeunit) noexcept
|
|
||||||
{
|
|
||||||
JSON_ASSERT(string_buffer.size() - pos >= 6);
|
|
||||||
constexpr const char* nibble_to_hex = "0123456789abcdef";
|
|
||||||
string_buffer[pos + 0] = '\\';
|
|
||||||
string_buffer[pos + 1] = 'u';
|
|
||||||
string_buffer[pos + 2] = nibble_to_hex[(codeunit >> 12u) & 0x0Fu];
|
|
||||||
string_buffer[pos + 3] = nibble_to_hex[(codeunit >> 8u) & 0x0Fu];
|
|
||||||
string_buffer[pos + 4] = nibble_to_hex[(codeunit >> 4u) & 0x0Fu];
|
|
||||||
string_buffer[pos + 5] = nibble_to_hex[codeunit & 0x0Fu];
|
|
||||||
pos += 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
// templates to avoid warnings about useless casts
|
// templates to avoid warnings about useless casts
|
||||||
template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
|
template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
|
||||||
bool is_negative_number(NumberType x)
|
bool is_negative_number(NumberType x)
|
||||||
|
|||||||
@@ -19962,12 +19962,18 @@ class serializer
|
|||||||
{
|
{
|
||||||
if (codepoint <= 0xFFFF)
|
if (codepoint <= 0xFFFF)
|
||||||
{
|
{
|
||||||
write_u_escape(bytes, static_cast<std::uint16_t>(codepoint));
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
||||||
|
static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
|
||||||
|
static_cast<std::uint16_t>(codepoint)));
|
||||||
|
bytes += 6;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
write_u_escape(bytes, static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)));
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
|
||||||
write_u_escape(bytes, static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
|
static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
|
||||||
|
static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
|
||||||
|
static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
|
||||||
|
bytes += 12;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -20174,32 +20180,6 @@ class serializer
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief write a lowercase "\uXXXX" escape sequence into @a string_buffer
|
|
||||||
*
|
|
||||||
* Branch-free replacement for `snprintf(buf, 7, "\\u%04x", codeunit)` in the
|
|
||||||
* string escaping hot path. It writes exactly six characters ('\\', 'u' and
|
|
||||||
* four hex digits) at position @a pos of @a string_buffer via a nibble
|
|
||||||
* lookup table, avoiding the format-string parsing and locale machinery of
|
|
||||||
* `snprintf`. Advances @a pos by the number of bytes written (6).
|
|
||||||
*
|
|
||||||
* @param[in] pos position in @a string_buffer to write at; there must
|
|
||||||
* be at least 6 bytes of headroom
|
|
||||||
* @param[in] codeunit 16-bit value to encode
|
|
||||||
*/
|
|
||||||
void write_u_escape(std::size_t& pos, std::uint16_t codeunit) noexcept
|
|
||||||
{
|
|
||||||
JSON_ASSERT(string_buffer.size() - pos >= 6);
|
|
||||||
constexpr const char* nibble_to_hex = "0123456789abcdef";
|
|
||||||
string_buffer[pos + 0] = '\\';
|
|
||||||
string_buffer[pos + 1] = 'u';
|
|
||||||
string_buffer[pos + 2] = nibble_to_hex[(codeunit >> 12u) & 0x0Fu];
|
|
||||||
string_buffer[pos + 3] = nibble_to_hex[(codeunit >> 8u) & 0x0Fu];
|
|
||||||
string_buffer[pos + 4] = nibble_to_hex[(codeunit >> 4u) & 0x0Fu];
|
|
||||||
string_buffer[pos + 5] = nibble_to_hex[codeunit & 0x0Fu];
|
|
||||||
pos += 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
// templates to avoid warnings about useless casts
|
// templates to avoid warnings about useless casts
|
||||||
template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
|
template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
|
||||||
bool is_negative_number(NumberType x)
|
bool is_negative_number(NumberType x)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ project(json_cuda LANGUAGES CUDA)
|
|||||||
|
|
||||||
add_executable(json_cuda json_cuda.cu)
|
add_executable(json_cuda json_cuda.cu)
|
||||||
target_include_directories(json_cuda PRIVATE ../../include)
|
target_include_directories(json_cuda PRIVATE ../../include)
|
||||||
target_compile_features(json_cuda PUBLIC cuda_std_11)
|
target_compile_features(json_cuda PUBLIC cuda_std_20)
|
||||||
set_target_properties(json_cuda PROPERTIES
|
set_target_properties(json_cuda PROPERTIES
|
||||||
CUDA_EXTENSIONS OFF
|
CUDA_EXTENSIONS OFF
|
||||||
CUDA_STANDARD_REQUIRED ON
|
CUDA_STANDARD_REQUIRED ON
|
||||||
|
|||||||
@@ -168,32 +168,6 @@ TEST_CASE("convenience functions")
|
|||||||
CHECK_THROWS_WITH_AS(check_escaped("\xC2"), "[json.exception.type_error.316] incomplete UTF-8 string; last byte: 0xC2", json::type_error&);
|
CHECK_THROWS_WITH_AS(check_escaped("\xC2"), "[json.exception.type_error.316] incomplete UTF-8 string; last byte: 0xC2", json::type_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("string escape with ensure_ascii")
|
|
||||||
{
|
|
||||||
// control characters are escaped regardless of ensure_ascii
|
|
||||||
check_escaped("\x01", "\\u0001", true);
|
|
||||||
check_escaped("\x1f", "\\u001f", true);
|
|
||||||
|
|
||||||
// non-ASCII code points in the Basic Multilingual Plane are emitted as
|
|
||||||
// a single lowercase \uXXXX escape (exercises every nibble position)
|
|
||||||
check_escaped("\xC2\x80", "\\u0080", true); // U+0080
|
|
||||||
check_escaped("\xC3\xBF", "\\u00ff", true); // U+00FF (ÿ)
|
|
||||||
check_escaped("\xDF\xBF", "\\u07ff", true); // U+07FF
|
|
||||||
check_escaped("\xE4\xBD\xA0", "\\u4f60", true); // U+4F60 (你)
|
|
||||||
check_escaped("\xEA\xAF\x8D", "\\uabcd", true); // U+ABCD
|
|
||||||
check_escaped("\xEF\xBF\xBD", "\\ufffd", true); // U+FFFD (replacement char, all-f nibbles)
|
|
||||||
|
|
||||||
// code points outside the BMP are emitted as a UTF-16 surrogate pair
|
|
||||||
// of two lowercase \uXXXX escapes
|
|
||||||
check_escaped("\xF0\x90\x80\x80", "\\ud800\\udc00", true); // U+10000 (lowest astral)
|
|
||||||
check_escaped("\xF0\x9F\x98\x80", "\\ud83d\\ude00", true); // U+1F600 (😀)
|
|
||||||
check_escaped("\xF4\x8F\xBF\xBF", "\\udbff\\udfff", true); // U+10FFFF (highest code point)
|
|
||||||
|
|
||||||
// with ensure_ascii disabled, non-ASCII input is passed through verbatim
|
|
||||||
check_escaped("\xE4\xBD\xA0", "\xE4\xBD\xA0", false);
|
|
||||||
check_escaped("\xF0\x9F\x98\x80", "\xF0\x9F\x98\x80", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("string concat")
|
SECTION("string concat")
|
||||||
{
|
{
|
||||||
using nlohmann::detail::concat;
|
using nlohmann::detail::concat;
|
||||||
|
|||||||
Reference in New Issue
Block a user