Files
json/docs/mkdocs/mkdocs.yml
T
Niels Lohmann e486005583 Bound the descent of the copy constructor
basic_json's copy constructor copied objects and arrays by handing the
container to its own copy constructor, which copy-constructs every element
and so reaches this constructor again, once per nesting level. A value
nested deeply enough exhausted the call stack and terminated the process
with a segmentation fault - no exception, nothing the caller could catch.
Parsing such a value works, as the parser is iterative, and so does
destroying one, as #1436 made destruction iterative.

Bound how far the copy descends rather than take the call stack away from
it. The first levels are copied exactly as they were - the containers copy
their own elements, which is by far the fastest way to fill them - and only
once the copy has descended 128 levels is the value below it finished
without the call stack, through an explicit worklist. Copying can therefore
no longer exhaust the stack, however deeply a value is nested, while a value
nested less deeply than the bound - all but a vanishing minority - is copied
by the very same code as before and pays only for one counter.

That counter lives in thread_local storage, as one shared between threads
would be raced. JSON_NO_THREAD_LOCAL switches it off for toolchains without
thread_local; copying then goes through the worklist right away, which
yields the same values but is measurably slower.

The deferred values are completed before the copy they belong to returns, so
a value copied while another copy is going on - by a custom base class, say -
is unaffected by the copy it is nested in.

operator= takes its argument by value, so copy assignment is fixed as well.

Copying is as fast as it was, within measurement noise (medians of 9
interleaved runs, clang -O3): -1.3% for an array of strings, +0.0% for a
flat object, +0.1% for a flat array of numbers, +0.3% for nested arrays,
+0.6% for nested objects and +1.2% for a twitter-like document. Copying a
three-key object costs about ten nanoseconds more, the counter. Deferring
every level instead, rather than only those below the bound, measured
between 3% and 9% slower depending on the shape of the value.

This fixes #5387 for the copy constructor. dump() is still recursive.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-08-20 19:22:16 +02:00

431 lines
19 KiB
YAML

# Project information
site_name: JSON for Modern C++
site_author: Niels Lohmann
site_url: https://json.nlohmann.me/
# Repository
repo_name: nlohmann/json
repo_url: https://github.com/nlohmann/json
edit_uri: edit/develop/docs/mkdocs/docs
# Copyright
copyright: Copyright &copy; 2013-2026 Niels Lohmann
# Configuration
theme:
name: material
language: en
palette:
- media: '(prefers-color-scheme: light)'
scheme: default
primary: indigo
accent: indigo
toggle:
icon: material/brightness-7
name: Switch to dark mode
- media: '(prefers-color-scheme: dark)'
scheme: slate
primary: indigo
accent: indigo
toggle:
icon: material/brightness-4
name: Switch to light mode
icon:
repo: fontawesome/brands/github
font:
text: Roboto
code: JetBrains Mono
features:
- navigation.instant
- navigation.tracking
- navigation.tabs
- navigation.indexes
- navigation.top
- content.tabs.link
- content.action.edit
- content.action.view
nav:
- Home:
- index.md
- home/license.md
- "FAQ": home/faq.md
- home/exceptions.md
- home/releases.md
- home/design_goals.md
- home/architecture.md
- home/customers.md
- home/sponsors.md
- home/debugging.md
- Features:
- features/index.md
- features/arbitrary_types.md
- Binary Formats:
- features/binary_formats/index.md
- features/binary_formats/bjdata.md
- features/binary_formats/bson.md
- features/binary_formats/cbor.md
- features/binary_formats/messagepack.md
- features/binary_formats/ubjson.md
- features/binary_values.md
- features/comments.md
- features/conversions.md
- features/creating_values.md
- Element Access:
- features/element_access/index.md
- features/element_access/unchecked_access.md
- features/element_access/checked_access.md
- features/element_access/default_value.md
- features/iterators.md
- features/merge_patch.md
- features/json_patch.md
- features/json_pointer.md
- features/modifying_values.md
- features/modules.md
- 'nlohmann Namespace': features/namespace.md
- features/object_order.md
- Parsing:
- features/parsing/index.md
- features/parsing/json_lines.md
- features/parsing/parse_exceptions.md
- features/parsing/parser_callbacks.md
- features/parsing/sax_interface.md
- features/assertions.md
- features/serialization.md
- features/enum_conversion.md
- features/macros.md
- features/trailing_commas.md
- Types:
- features/types/index.md
- features/types/number_handling.md
- Integration:
- integration/index.md
- integration/migration_guide.md
- integration/cmake.md
- integration/package_managers.md
- integration/pkg-config.md
- API Documentation:
- basic_json:
- 'Overview': api/basic_json/index.md
- '(Constructor)': api/basic_json/basic_json.md
- '(Destructor)': api/basic_json/~basic_json.md
- 'accept': api/basic_json/accept.md
- 'array': api/basic_json/array.md
- 'array_t': api/basic_json/array_t.md
- 'at': api/basic_json/at.md
- 'back': api/basic_json/back.md
- 'begin': api/basic_json/begin.md
- 'binary': api/basic_json/binary.md
- 'binary_t': api/basic_json/binary_t.md
- 'boolean_t': api/basic_json/boolean_t.md
- 'cbegin': api/basic_json/cbegin.md
- 'cbor_tag_handler_t': api/basic_json/cbor_tag_handler_t.md
- 'cend': api/basic_json/cend.md
- 'clear': api/basic_json/clear.md
- 'contains': api/basic_json/contains.md
- 'count': api/basic_json/count.md
- 'crbegin': api/basic_json/crbegin.md
- 'crend': api/basic_json/crend.md
- 'default_object_comparator_t': api/basic_json/default_object_comparator_t.md
- 'diff': api/basic_json/diff.md
- 'dump': api/basic_json/dump.md
- 'emplace': api/basic_json/emplace.md
- 'emplace_back': api/basic_json/emplace_back.md
- 'empty': api/basic_json/empty.md
- 'end': api/basic_json/end.md
- 'end_pos': api/basic_json/end_pos.md
- 'erase': api/basic_json/erase.md
- 'error_handler_t': api/basic_json/error_handler_t.md
- 'exception': api/basic_json/exception.md
- 'find': api/basic_json/find.md
- 'flatten': api/basic_json/flatten.md
- 'format_as': api/basic_json/format_as.md
- 'from_bjdata': api/basic_json/from_bjdata.md
- 'from_bson': api/basic_json/from_bson.md
- 'from_cbor': api/basic_json/from_cbor.md
- 'from_msgpack': api/basic_json/from_msgpack.md
- 'from_ubjson': api/basic_json/from_ubjson.md
- 'front': api/basic_json/front.md
- 'get': api/basic_json/get.md
- 'get_allocator': api/basic_json/get_allocator.md
- 'get_binary': api/basic_json/get_binary.md
- 'get_ptr': api/basic_json/get_ptr.md
- 'get_ref': api/basic_json/get_ref.md
- 'get_to': api/basic_json/get_to.md
- 'std::formatter&lt;basic_json&gt;': api/basic_json/std_formatter.md
- 'std::hash&lt;basic_json&gt;': api/basic_json/std_hash.md
- 'input_format_t': api/basic_json/input_format_t.md
- 'insert': api/basic_json/insert.md
- 'invalid_iterator': api/basic_json/invalid_iterator.md
- 'is_array': api/basic_json/is_array.md
- 'is_binary': api/basic_json/is_binary.md
- 'is_boolean': api/basic_json/is_boolean.md
- 'is_discarded': api/basic_json/is_discarded.md
- 'is_null': api/basic_json/is_null.md
- 'is_number': api/basic_json/is_number.md
- 'is_number_float': api/basic_json/is_number_float.md
- 'is_number_integer': api/basic_json/is_number_integer.md
- 'is_number_unsigned': api/basic_json/is_number_unsigned.md
- 'is_object': api/basic_json/is_object.md
- 'is_primitive': api/basic_json/is_primitive.md
- 'is_string': api/basic_json/is_string.md
- 'is_structured': api/basic_json/is_structured.md
- 'items': api/basic_json/items.md
- 'json_base_class_t': api/basic_json/json_base_class_t.md
- 'json_serializer': api/basic_json/json_serializer.md
- 'max_size': api/basic_json/max_size.md
- 'meta': api/basic_json/meta.md
- 'merge_patch': api/basic_json/merge_patch.md
- 'number_float_t': api/basic_json/number_float_t.md
- 'number_integer_t': api/basic_json/number_integer_t.md
- 'number_unsigned_t': api/basic_json/number_unsigned_t.md
- 'object': api/basic_json/object.md
- 'object_comparator_t': api/basic_json/object_comparator_t.md
- 'object_t': api/basic_json/object_t.md
- 'operator ValueType': api/basic_json/operator_ValueType.md
- 'operator value_t': api/basic_json/operator_value_t.md
- 'operator[]': api/basic_json/operator[].md
- 'operator=': api/basic_json/operator=.md
- 'operator+=': api/basic_json/operator+=.md
- 'operator==': api/basic_json/operator_eq.md
- 'operator!=': api/basic_json/operator_ne.md
- 'operator<': api/basic_json/operator_lt.md
- 'operator>': api/basic_json/operator_gt.md
- 'operator<=': api/basic_json/operator_le.md
- 'operator>=': api/basic_json/operator_ge.md
- 'operator<=>': api/basic_json/operator_spaceship.md
- 'out_of_range': api/basic_json/out_of_range.md
- 'other_error': api/basic_json/other_error.md
- 'parse': api/basic_json/parse.md
- 'parse_error': api/basic_json/parse_error.md
- 'parse_event_t': api/basic_json/parse_event_t.md
- 'parser_callback_t': api/basic_json/parser_callback_t.md
- 'patch': api/basic_json/patch.md
- 'patch_inplace': api/basic_json/patch_inplace.md
- 'push_back': api/basic_json/push_back.md
- 'rbegin': api/basic_json/rbegin.md
- 'rend': api/basic_json/rend.md
- 'sax_parse': api/basic_json/sax_parse.md
- 'size': api/basic_json/size.md
- 'start_pos': api/basic_json/start_pos.md
- 'string_t': api/basic_json/string_t.md
- 'swap': api/basic_json/swap.md
- 'std::swap&lt;basic_json&gt;': api/basic_json/std_swap.md
- 'to_bjdata': api/basic_json/to_bjdata.md
- 'to_bson': api/basic_json/to_bson.md
- 'to_cbor': api/basic_json/to_cbor.md
- 'to_msgpack': api/basic_json/to_msgpack.md
- 'to_string': api/basic_json/to_string.md
- 'to_ubjson': api/basic_json/to_ubjson.md
- 'type': api/basic_json/type.md
- 'type_error': api/basic_json/type_error.md
- 'type_name': api/basic_json/type_name.md
- 'unflatten': api/basic_json/unflatten.md
- 'update': api/basic_json/update.md
- 'value': api/basic_json/value.md
- 'value_t': api/basic_json/value_t.md
- byte_container_with_subtype:
- 'Overview': api/byte_container_with_subtype/index.md
- '(constructor)': api/byte_container_with_subtype/byte_container_with_subtype.md
- 'clear_subtype': api/byte_container_with_subtype/clear_subtype.md
- 'has_subtype': api/byte_container_with_subtype/has_subtype.md
- 'set_subtype': api/byte_container_with_subtype/set_subtype.md
- 'subtype': api/byte_container_with_subtype/subtype.md
- adl_serializer:
- 'Overview': api/adl_serializer/index.md
- 'from_json': api/adl_serializer/from_json.md
- 'to_json': api/adl_serializer/to_json.md
- 'json': api/json.md
- json_pointer:
- 'Overview': api/json_pointer/index.md
- '(Constructor)': api/json_pointer/json_pointer.md
- 'back': api/json_pointer/back.md
- 'empty': api/json_pointer/empty.md
- 'front': api/json_pointer/front.md
- 'operator string_t': api/json_pointer/operator_string_t.md
- 'operator==': api/json_pointer/operator_eq.md
- 'operator!=': api/json_pointer/operator_ne.md
- 'operator/': api/json_pointer/operator_slash.md
- 'operator/=': api/json_pointer/operator_slasheq.md
- 'parent_pointer': api/json_pointer/parent_pointer.md
- 'pop_back': api/json_pointer/pop_back.md
- 'pop_front': api/json_pointer/pop_front.md
- 'push_back': api/json_pointer/push_back.md
- 'push_front': api/json_pointer/push_front.md
- 'string_t': api/json_pointer/string_t.md
- 'to_string': api/json_pointer/to_string.md
- json_sax:
- 'Overview': api/json_sax/index.md
- 'binary': api/json_sax/binary.md
- 'boolean': api/json_sax/boolean.md
- 'end_array': api/json_sax/end_array.md
- 'end_object': api/json_sax/end_object.md
- 'key': api/json_sax/key.md
- 'null': api/json_sax/null.md
- 'number_float': api/json_sax/number_float.md
- 'number_integer': api/json_sax/number_integer.md
- 'number_unsigned': api/json_sax/number_unsigned.md
- 'parse_error': api/json_sax/parse_error.md
- 'start_array': api/json_sax/start_array.md
- 'start_object': api/json_sax/start_object.md
- 'string': api/json_sax/string.md
- 'operator<<(basic_json), operator<<(json_pointer)': api/operator_ltlt.md
- 'operator>>(basic_json)': api/operator_gtgt.md
- 'operator""_json': api/operator_literal_json.md
- 'operator""_json_pointer': api/operator_literal_json_pointer.md
- 'ordered_json': api/ordered_json.md
- 'ordered_map': api/ordered_map.md
- macros:
- 'Overview': api/macros/index.md
- 'JSON_ASSERT': api/macros/json_assert.md
- 'JSON_BRACE_INIT_COPY_SEMANTICS': api/macros/json_brace_init_copy_semantics.md
- 'JSON_CATCH_USER, JSON_THROW_USER, JSON_TRY_USER': api/macros/json_throw_user.md
- 'JSON_DIAGNOSTICS': api/macros/json_diagnostics.md
- 'JSON_DIAGNOSTIC_POSITIONS': api/macros/json_diagnostic_positions.md
- 'JSON_DISABLE_ENUM_SERIALIZATION': api/macros/json_disable_enum_serialization.md
- 'JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20': api/macros/json_has_cpp_11.md
- 'JSON_HAS_EXPERIMENTAL_FILESYSTEM, JSON_HAS_FILESYSTEM': api/macros/json_has_filesystem.md
- 'JSON_HAS_RANGES': api/macros/json_has_ranges.md
- 'JSON_HAS_STATIC_RTTI': api/macros/json_has_static_rtti.md
- 'JSON_HAS_STD_FORMAT': api/macros/json_has_std_format.md
- 'JSON_HAS_THREE_WAY_COMPARISON': api/macros/json_has_three_way_comparison.md
- 'JSON_NOEXCEPTION': api/macros/json_noexception.md
- 'JSON_NO_IO': api/macros/json_no_io.md
- 'JSON_NO_THREAD_LOCAL': api/macros/json_no_thread_local.md
- 'JSON_SKIP_LIBRARY_VERSION_CHECK': api/macros/json_skip_library_version_check.md
- 'JSON_SKIP_UNSUPPORTED_COMPILER_CHECK': api/macros/json_skip_unsupported_compiler_check.md
- 'JSON_USE_GLOBAL_UDLS': api/macros/json_use_global_udls.md
- 'JSON_USE_IMPLICIT_CONVERSIONS': api/macros/json_use_implicit_conversions.md
- 'JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON': api/macros/json_use_legacy_discarded_value_comparison.md
- 'NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE': api/macros/nlohmann_define_derived_type.md
- 'NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE': api/macros/nlohmann_define_type_intrusive.md
- 'NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE': api/macros/nlohmann_define_type_non_intrusive.md
- 'NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES': api/macros/nlohmann_define_type_with_names.md
- 'NLOHMANN_JSON_NAMESPACE': api/macros/nlohmann_json_namespace.md
- 'NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END': api/macros/nlohmann_json_namespace_begin.md
- 'NLOHMANN_JSON_NAMESPACE_NO_VERSION': api/macros/nlohmann_json_namespace_no_version.md
- 'NLOHMANN_JSON_SERIALIZE_ENUM': api/macros/nlohmann_json_serialize_enum.md
- 'NLOHMANN_JSON_SERIALIZE_ENUM_STRICT': api/macros/nlohmann_json_serialize_enum_strict.md
- 'NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH': api/macros/nlohmann_json_version_major.md
- Community:
- community/index.md
- community/ecosystem.md
- "Code of Conduct": community/code_of_conduct.md
- community/contribution_guidelines.md
- community/quality_assurance.md
- community/governance.md
- community/security_policy.md
# Extras
extra:
social:
- icon: fontawesome/brands/github
link: https://github.com/nlohmann
- icon: fontawesome/brands/linkedin
link: https://www.linkedin.com/in/nielslohmann/
- icon: fontawesome/brands/xing
link: https://www.xing.com/profile/Niels_Lohmann
- icon: fontawesome/brands/paypal
link: https://www.paypal.me/nlohmann
generator: false
# Extensions
markdown_extensions:
- abbr
- admonition
- attr_list
- def_list
- codehilite:
guess_lang: false
- toc:
permalink: true
- md_in_html
- pymdownx.arithmatex
- pymdownx.betterem:
smart_enable: all
- pymdownx.caret
- pymdownx.critic
- pymdownx.details
- pymdownx.emoji:
emoji_index: !!python/name:material.extensions.emoji.twemoji
emoji_generator: !!python/name:material.extensions.emoji.to_svg
- pymdownx.inlinehilite
- pymdownx.magiclink
- pymdownx.mark
#- pymdownx.smartsymbols
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format
- pymdownx.tasklist:
custom_checkbox: true
- pymdownx.tabbed:
alternate_style: true
- pymdownx.tilde
- pymdownx.snippets:
base_path: docs
check_paths: true
restrict_base_path: false # needed to allow including files from the .github folder
auto_append:
- ../includes/glossary.md
hooks:
- hooks/copy_markdown_source.py
plugins:
- search:
separator: '[\s\-\.]'
lang: en
- minify:
minify_html: true
- git-revision-date-localized
- redirects:
redirect_maps:
'api/basic_json/operator_gtgt.md': api/operator_gtgt.md
'api/basic_json/operator_ltlt.md': api/operator_ltlt.md
'api/basic_json/operator_literal_json.md': api/operator_literal_json.md
'api/basic_json/operator_literal_json_pointer.md': api/operator_literal_json_pointer.md
'api/json_pointer/operator_string.md': api/json_pointer/operator_string_t.md
'home/code_of_conduct.md': community/code_of_conduct.md
- htmlproofer: # see https://github.com/manuzhang/mkdocs-htmlproofer-plugin
enabled: !ENV [ENABLED_HTMLPROOFER, False]
ignore_urls:
- http://nlohmann.github.io/json/*
- https://nlohmann.github.io/json/*
- mailto:*
- 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:
- css/custom.css
extra_javascript:
- https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-MML-AM_CHTML