This commit is contained in:
nlohmann committed 2026-09-25 10:23:21 +00:00
1 parent 1374e776a3
commit 5831f33884
261 files changed
+624 -340

No files matched your search

+39 -14
View File
@@ -1,8 +1,32 @@
<!doctype html><html lang=en class=no-js> <head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=author content="Niels Lohmann"><link href="https://json.nlohmann.me/home/architecture/" rel="canonical"><link href=../design_goals/ rel=prev><link href=../customers/ rel=next><link rel=icon href=../../assets/images/favicon.png><meta name=generator content="mkdocs-1.6.1, mkdocs-material-9.7.7"><title>Architecture - JSON for Modern C++</title><link rel=stylesheet href=../../assets/stylesheets/main.ec1eaa64.min.css><link rel=stylesheet href=../../assets/stylesheets/palette.ab4e12ef.min.css><link rel="stylesheet" href="../../assets/external/fonts.googleapis.com/css.61a430c9.css"><style>:root{--md-text-font:"Roboto";--md-code-font:"JetBrains Mono"}</style><link rel=stylesheet href=../../css/custom.css><script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script></head> <body dir=ltr data-md-color-scheme=default data-md-color-primary=indigo data-md-color-accent=indigo> <input class=md-toggle data-md-toggle=drawer type=checkbox id=__drawer autocomplete=off> <input class=md-toggle data-md-toggle=search type=checkbox id=__search autocomplete=off> <label class=md-overlay for=__drawer></label> <div data-md-component=skip> <a href=#architecture class=md-skip> Skip to content </a> </div> <div data-md-component=announce> </div> <header class=md-header data-md-component=header> <nav class="md-header__inner md-grid" aria-label=Header> <a href=../.. title="JSON for Modern C++" class="md-header__button md-logo" aria-label="JSON for Modern C++" data-md-component=logo> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg> </a> <label class="md-header__button md-icon" for=__drawer> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg> </label> <div class=md-header__title data-md-component=header-title> <div class=md-header__ellipsis> <div class=md-header__topic> <span class=md-ellipsis> JSON for Modern C++ </span> </div> <div class=md-header__topic data-md-component=header-topic> <span class=md-ellipsis> Architecture </span> </div> </div> </div> <form class=md-header__option data-md-component=palette> <input class=md-option data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme=default data-md-color-primary=indigo data-md-color-accent=indigo aria-label="Switch to dark mode" type=radio name=__palette id=__palette_0> <label class="md-header__button md-icon" title="Switch to dark mode" for=__palette_1 hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg> </label> <input class=md-option data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme=slate data-md-color-primary=indigo data-md-color-accent=indigo aria-label="Switch to light mode" type=radio name=__palette id=__palette_1> <label class="md-header__button md-icon" title="Switch to light mode" for=__palette_0 hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg> </label> </form> <script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script> <label class="md-header__button md-icon" for=__search> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg> </label> <div class=md-seaLine truncated
<span class=n>value_t</span><span class=w> </span><span class=n>m_type</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>value_t</span><span class=o>::</span><span class=n>null</span><span class=p>;</span>
<!doctype html><html lang=en class=no-js> <head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=author content="Niels Lohmann"><link href="https://json.nlohmann.me/home/architecture/" rel="canonical"><link href=../design_goals/ rel=prev><link href=../customers/ rel=next><link rel=icon href=../../assets/images/favicon.png><meta name=generator content="mkdocs-1.6.1, mkdocs-material-9.7.7"><title>Architecture - JSON for Modern C++</title><link rel=stylesheet href=../../assets/stylesheets/main.ec1eaa64.min.css><link rel=stylesheet href=../../assets/stylesheets/palette.ab4e12ef.min.css><link rel="stylesheet" href="../../assets/external/fonts.googleapis.com/css.61a430c9.css"><style>:root{--md-text-font:"Roboto";--md-code-font:"JetBrains Mono"}</style><link rel=stylesheet href=../../css/custom.css><script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script></head> <body dir=ltr data-md-color-scheme=default data-md-color-primary=indigo data-md-color-accent=indigo> <input class=md-toggle data-md-toggle=drawer type=checkbox id=__drawer autocomplete=off> <input class=md-toggle data-md-toggle=search type=checkbox id=__search autocomplete=off> <label class=md-overlay for=__drawer></label> <div data-md-component=skip> <a href=#architecture class=md-skip> Skip to content </a> </div> <div data-md-component=announce> </div> <header class=md-header data-md-component=header> <nav class="md-header__inner md-grid" aria-label=Header> <a href=../.. title="JSON for Modern C++" class="md-header__button md-logo" aria-label="JSON for Modern C++" data-md-component=logo> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg> </a> <label class="md-header__button md-icon" for=__drawer> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg> </label> <div class=md-header__title data-md-component=header-title> <div class=md-header__ellipsis> <div class=md-header__topic> <span class=md-ellipsis> JSON for Modern C++ </span> </div> <div class=md-header__topic data-md-component=header-topic> <span class=md-ellipsis> Architecture </span> </div> </div> </div> <form class=md-header__option data-md-component=palette> <input class=md-option data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme=default data-md-color-primary=indigo data-md-color-accent=indigo aria-label="Switch to dark mode" type=radio name=__palette id=__palette_0> <label class="md-header__button md-icon" title="Switch to dark mode" for=__palette_1 hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg> </label> <input class=md-option data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme=slate data-md-color-primary=indigo data-md-color-accent=indigo aria-label="Switch to light mode" type=radio name=__palette id=__palette_1> <label class="md-header__button md-icon" title="Switch to light mode" for=__palette_0 hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg> </label> </form> <script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script> <label class="md-header__button md-icon" for=__search> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg> </label> <div class=md-seaLine truncated
input[/"input&lt;br&gt;(string, stream,&lt;br&gt;iterator range, file)"/]
ia["input adapter"]
lexer["lexer"]
parser["parser"]
breader["binary_reader"]
sax["SAX interface"]
value[("basic_json&lt;br&gt;value tree")]
serializer["serializer"]
bwriter["binary_writer"]
oa["output adapter"]
output[/"output&lt;br&gt;(string, stream,&lt;br&gt;vector)"/]
<span class=c1>/// the value of the current element</span>
<span class=n>json_value</span><span class=w> </span><span class=n>m_value</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=p>{};</span>
input --&gt; ia
ia --&gt; lexer --&gt; parser --&gt; sax
ia --&gt; breader --&gt; sax
sax --&gt; value
value --&gt; serializer --&gt; oa
value --&gt; bwriter --&gt; oa
oa --&gt; output</code></pre> <ul> <li><strong><abbr title="JavaScript Object Notation">JSON</abbr> text</strong> is read by an <a href=#input-adapters>input adapter</a>, tokenized by the lexer, and turned into <abbr title="Simple API for XML">SAX</abbr> events by the parser.</li> <li><strong>Binary formats</strong> (<abbr title="Binary JData">BJData</abbr>, <abbr title="Binary JSON">BSON</abbr>, <abbr title="Concise Binary Object Representation">CBOR</abbr>, MessagePack, <abbr title="Universal Binary JSON">UBJSON</abbr>) are read by an input adapter and turned into the same <abbr title="Simple API for XML">SAX</abbr> events by the <code>binary_reader</code>.</li> <li>A <a href=#sax-interface><abbr title="Simple API for XML">SAX</abbr> consumer</a> receives the events. The one used by <a href=../../api/basic_json/parse/ ><code>parse</code></a> builds a <code>basic_json</code> value tree.</li> <li>The <code>serializer</code> (<abbr title="JavaScript Object Notation">JSON</abbr> text) or the <code>binary_writer</code> (binary formats) writes a value tree to an <a href=#output-adapters>output adapter</a>.</li> </ul> <h2 id=source-layout>Source layout<a class=headerlink href=#source-layout title="Permanent link">&para;</a></h2> <p>The public headers are in <a href="https://github.com/nlohmann/json/tree/develop/include/nlohmann"><code>include/nlohmann</code></a>:</p> <ul> <li><a href="https://github.com/nlohmann/json/blob/develop/include/nlohmann/json.hpp"><code>json.hpp</code></a> defines class <a href=../../api/basic_json/ ><code>basic_json</code></a>.</li> <li><a href="https://github.com/nlohmann/json/blob/develop/include/nlohmann/json_fwd.hpp"><code>json_fwd.hpp</code></a> contains forward declarations.</li> <li><a href="https://github.com/nlohmann/json/blob/develop/include/nlohmann/adl_serializer.hpp"><code>adl_serializer.hpp</code></a>, <a href="https://github.com/nlohmann/json/blob/develop/include/nlohmann/byte_container_with_subtype.hpp"><code>byte_container_with_subtype.hpp</code></a>, and <a href="https://github.com/nlohmann/json/blob/develop/include/nlohmann/ordered_map.hpp"><code>ordered_map.hpp</code></a> define <a href=../../api/adl_serializer/ ><code>adl_serializer</code></a>, <a href=../../api/byte_container_with_subtype/ ><code>byte_container_with_subtype</code></a>, and <a href=../../api/ordered_map/ ><code>ordered_map</code></a>.</li> </ul> <p>Everything else lives in <a href="https://github.com/nlohmann/json/tree/develop/include/nlohmann/detail"><code>detail/</code></a> and namespace <code>nlohmann::detail</code>, which is not part of the public <abbr title="Application Programming Interfaces">API</abbr>. Paths below are relative to <code>include/nlohmann</code>.</p> <table> <thead> <tr> <th>Component</th> <th>Location</th> </tr> </thead> <tbody> <tr> <td>Value type enumeration</td> <td><a href="https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/value_t.hpp"><code>detail/value_t.hpp</code></a></td> </tr> <tr> <td>Input adapters</td> <td><a href="https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/input_adapters.hpp"><code>detail/input/input_adapters.hpp</code></a></td> </tr> <tr> <td>Lexer</td> <td><a href="https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/lexer.hpp"><code>detail/input/lexer.hpp</code></a>, <a href="https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/number_parse.hpp"><code>detail/input/number_parse.hpp</code></a>, <a href="https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/string_scan.hpp"><code>detail/input/string_scan.hpp</code></a></td> </tr> <tr> <td>Parser</td> <td><a href="https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/parser.hpp"><code>detail/input/parser.hpp</code></a></td> </tr> <tr> <td><abbr title="Simple API for XML">SAX</abbr> interface and <abbr title="Document Object Model">DOM</abbr> builders</td> <td><a href="https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/json_sax.hpp"><code>detail/input/json_sax.hpp</code></a></td> </tr> <tr> <td>Binary format readers</td> <td><a href="https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/binary_reader.hpp"><code>detail/input/binary_reader.hpp</code></a></td> </tr> <tr> <td><abbr title="JavaScript Object Notation">JSON</abbr> serializer</td> <td><a href="https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/output/serializer.hpp"><code>detail/output/serializer.hpp</code></a>, <a href="https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/conversions/to_chars.hpp"><code>detail/conversions/to_chars.hpp</code></a></td> </tr> <tr> <td>Binary format writers</td> <td><a href="https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/output/binary_writer.hpp"><code>detail/output/binary_writer.hpp</code></a></td> </tr> <tr> <td>Output adapters</td> <td><a href="https://github.com/nlohmann/Line truncated
<span class=p>{</span>
<span class=w> </span><span class=c1>/// the type of the current element</span>
<span class=w> </span><span class=n>value_t</span><span class=w> </span><span class=n>m_type</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>value_t</span><span class=o>::</span><span class=n>null</span><span class=p>;</span>
<span class=w> </span><span class=c1>/// the value of the current element</span>
<span class=w> </span><span class=n>json_value</span><span class=w> </span><span class=n>m_value</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=p>{};</span>
<span class=p>};</span>
<span class=n>data</span><span class=w> </span><span class=n>m_data</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=p>{};</span>
</code></pre></div> <p>with</p> <div class=highlight><pre><span></span><code><span class=k>enum</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>value_t</span><span class=w> </span><span class=o>:</span><span class=w> </span><span class=n>std</span><span class=o>::</span><span class=kt>uint8_t</span>
<span class=p>{</span>
<span class=w> </span><span class=n>null</span><span class=p>,</span><span class=w> </span><span class=c1>///&lt; null value</span>
@@ -35,21 +59,22 @@
<span class=w> </span><span class=c1>/// number (floating-point)</span>
<span class=w> </span><span class=n>number_float_t</span><span class=w> </span><span class=n>number_float</span><span class=p>;</span>
<span class=p>};</span>
</code></pre></div> <h2 id=parsing-inputs-deserialization>Parsing inputs (deserialization)<a class=headerlink href=#parsing-inputs-deserialization title="Permanent link">&para;</a></h2> <p>Input is read via <strong>input adapters</strong> that abstract a source with a common interface:</p> <div class=highlight><pre><span></span><code><span class=c1>/// read a single character</span>
<span class=n>std</span><span class=o>::</span><span class=n>char_traits</span><span class=o>&lt;</span><span class=kt>char</span><span class=o>&gt;::</span><span class=n>int_type</span><span class=w> </span><span class=n>get_character</span><span class=p>()</span><span class=w> </span><span class=k>noexcept</span><span class=p>;</span>
</code></pre></div> <p>Objects, arrays, strings, and binary values are allocated on the heap with <code>AllocatorType</code>, and the union only stores a pointer to them. This keeps a <code>basic_json</code> value small: one pointer-sized union and one byte for the type. The class maintains the invariant that the pointer matching <code>m_type</code> is never null; <code>assert_invariant()</code> checks it with <a href=../../features/assertions/ >runtime assertions</a>.</p> <h2 id=input-adapters>Input adapters<a class=headerlink href=#input-adapters title="Permanent link">&para;</a></h2> <p>Input is read via <strong>input adapters</strong> that abstract a source. Every input adapter provides this interface:</p> <div class=highlight><pre><span></span><code><span class=c1>/// the type of the characters in the input</span>
<span class=k>using</span><span class=w> </span><span class=n>char_type</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=p>...;</span>
<span class=c1>/// read multiple characters to a destination buffer and</span>
<span class=c1>/// returns the number of characters successfully read</span>
<span class=c1>/// read a single character; returns std::char_traits&lt;char_type&gt;::eof() at the end of the input</span>
<span class=k>typename</span><span class=w> </span><span class=nc>std</span><span class=o>::</span><span class=n>char_traits</span><span class=o>&lt;</span><span class=n>char_type</span><span class=o>&gt;::</span><span class=n>int_type</span><span class=w> </span><span class=n>get_character</span><span class=p>();</span>
<span class=c1>/// read up to count * sizeof(T) bytes into dest and return the number of bytes read</span>
<span class=c1>/// (used by the binary readers)</span>
<span class=k>template</span><span class=o>&lt;</span><span class=k>class</span><span class=w> </span><span class=nc>T</span><span class=o>&gt;</span>
<span class=n>std</span><span class=o>::</span><span class=kt>size_t</span><span class=w> </span><span class=n>get_elements</span><span class=p>(</span><span class=n>T</span><span class=o>*</span><span class=w> </span><span class=n>dest</span><span class=p>,</span><span class=w> </span><span class=n>std</span><span class=o>::</span><span class=kt>size_t</span><span class=w> </span><span class=n>count</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=mi>1</span><span class=p>);</span>
</code></pre></div> <p>List examples of input adapters.</p> <h2 id=sax-interface><abbr title="Simple API for XML">SAX</abbr> Interface<a class=headerlink href=#sax-interface title="Permanent link">&para;</a></h2> <p>TODO</p> <h2 id=writing-outputs-serialization>Writing outputs (serialization)<a class=headerlink href=#writing-outputs-serialization title="Permanent link">&para;</a></h2> <p>Output is written via <strong>output adapters</strong>:</p> <div class=highlight><pre><span></span><code><span class=k>template</span><span class=o>&lt;</span><span class=k>typename</span><span class=w> </span><span class=nc>T</span><span class=o>&gt;</span>
<span class=kt>void</span><span class=w> </span><span class=n>write_character</span><span class=p>(</span><span class=n>CharType</span><span class=w> </span><span class=n>c</span><span class=p>);</span>
</code></pre></div> <p>The lexer detects two optional extensions at compile time. Only <code>iterator_input_adapter</code> provides them, and only for random-access input of single-byte characters:</p> <ul> <li><code>supports_seek</code>, <code>get_consumed_count()</code>, and <code>copy_consumed_range()</code> let the lexer reconstruct already consumed input for error messages instead of copying every character it reads.</li> <li><code>supports_bulk_scan</code>, <code>bulk_data()</code>, <code>bulk_remaining()</code>, and <code>bulk_skip()</code> let the lexer scan strings directly in contiguous memory, several bytes at a time.</li> </ul> <p>The function <code>input_adapter</code> picks the right adapter for the argument passed to <code>parse</code>, <code>accept</code>, <code>sax_parse</code>, or the <code>from_*</code> functions:</p> <ul> <li><code>iterator_input_adapter</code> reads from an iterator range, which also covers strings, containers, and pointers.</li> <li><code>wide_string_input_adapter</code> reads from ranges of <code>wchar_t</code>, <code>char16_t</code>, or <code>char32_t</code> and converts them to <abbr title="Unicode Transformation Format">UTF</abbr>-8. It cannot be used for binary formats; its <code>get_elements()</code> throws.</li> <li><code>input_stream_adapter</code> reads from a <code>std::istream</code>.</li> <li><code>file_input_adapter</code> reads from a <code>std::FILE*</code>.</li> </ul> <h2 id=sax-interface><abbr title="Simple API for XML">SAX</abbr> interface<a class=headerlink href=#sax-interface title="Permanent link">&para;</a></h2> <p>The parser does not build values itself. It reports what it reads as events to a <a href=../../features/parsing/sax_interface/ ><abbr title="Simple API for XML">SAX</abbr></a> consumer, which implements the interface <a href=../../api/json_sax/ ><code>json_sax</code></a>: <code>null</code>, <code>boolean</code>, <code>number_integer</code>, <code>number_unsigned</code>, <code>number_float</code>, <code>string</code>, <code>binary</code>, <code>start_object</code>, <code>key</code>, <code>end_object</code>, <code>start_array</code>, <code>end_array</code>, and <code>parse_error</code>.</p> <p>The library comes with two consumers in <code>detail/input/json_sax.hpp</code>:</p> <ul> <li><code>json_sax_dom_parser</code> builds a <a href=../../api/basic_json/ ><code>basic_json</code></a> value tree. <a href=../../api/basic_json/parse/ ><code>parse</code></a> uses it.</li> <li><code>json_sax_dom_callback_parser</code> does the same, but calls a <a href=../../features/parsing/parser_callbacks/ >parser callback</a> for each event, which can skip values. <code>parse</code> uses it when a callback is given.</li> </ul> <p>The <code>binary_reader</code> emits the same events for binary formats, so <a href=../../api/basic_json/sax_parse/ ><code>sax_parse</code></a> works with a user-defined consumer for <abbr title="JavaScript Object Notation">JSON</abbr> and for all binary formats alike.</p> <h2 id=output-adapters>Output adapters<a class=headerlink href=#output-adapters title="Permanent link">&para;</a></h2> <p>Output is written via <strong>output adapters</strong>:</p> <div class=highlight><pre><span></span><code><span class=kt>void</span><span class=w> </span><span class=nf>write_character</span><span class=p>(</span><span class=n>CharType</span><span class=w> </span><span class=n>c</span><span class=p>);</span>
<span class=k>template</span><span class=o>&lt;</span><span class=k>typename</span><span class=w> </span><span class=nc>CharType</span><span class=o>&gt;</span>
<span class=kt>void</span><span class=w> </span><span class=n>write_characters</span><span class=p>(</span><span class=k>const</span><span class=w> </span><span class=n>CharType</span><span class=o>*</span><span class=w> </span><span class=n>s</span><span class=p>,</span><span class=w> </span><span class=n>std</span><span class=o>::</span><span class=kt>size_t</span><span class=w> </span><span class=n>length</span><span class=p>);</span>
</code></pre></div> <p>List examples of output adapters.</p> <h2 id=value-conversion>Value conversion<a class=headerlink href=#value-conversion title="Permanent link">&para;</a></h2> <div class=highlight><pre><span></span><code><span class=k>template</span><span class=o>&lt;</span><span class=k>class</span><span class=w> </span><span class=nc>T</span><span class=o>&gt;</span>
<span class=kt>void</span><span class=w> </span><span class=nf>write_characters</span><span class=p>(</span><span class=k>const</span><span class=w> </span><span class=n>CharType</span><span class=o>*</span><span class=w> </span><span class=n>s</span><span class=p>,</span><span class=w> </span><span class=n>std</span><span class=o>::</span><span class=kt>size_t</span><span class=w> </span><span class=n>length</span><span class=p>);</span>
</code></pre></div> <p>The <code>serializer</code> (used by <a href=../../api/basic_json/dump/ ><code>dump</code></a> and <a href=../../api/operator_ltlt/ ><code>operator&lt;&lt;</code></a>) and the <code>binary_writer</code> (used by the <code>to_*</code> functions) write to one of these adapters:</p> <ul> <li><code>output_vector_adapter</code> appends to a <code>std::vector</code>.</li> <li><code>output_stream_adapter</code> writes to a <code>std::ostream</code>.</li> <li><code>output_string_adapter</code> appends to a string.</li> </ul> <h2 id=value-conversion>Value conversion<a class=headerlink href=#value-conversion title="Permanent link">&para;</a></h2> <p>Values are converted from and to other types with the <code>JSONSerializer</code> template parameter. The default, <a href=../../api/adl_serializer/ ><code>adl_serializer</code></a>, calls the free functions</p> <div class=highlight><pre><span></span><code><span class=k>template</span><span class=o>&lt;</span><span class=k>class</span><span class=w> </span><span class=nc>T</span><span class=o>&gt;</span>
<span class=kt>void</span><span class=w> </span><span class=n>to_json</span><span class=p>(</span><span class=n>basic_json</span><span class=o>&amp;</span><span class=w> </span><span class=n>j</span><span class=p>,</span><span class=w> </span><span class=k>const</span><span class=w> </span><span class=n>T</span><span class=o>&amp;</span><span class=w> </span><span class=n>t</span><span class=p>);</span>
<span class=k>template</span><span class=o>&lt;</span><span class=k>class</span><span class=w> </span><span class=nc>T</span><span class=o>&gt;</span>
<span class=kt>void</span><span class=w> </span><span class=n>from_json</span><span class=p>(</span><span class=k>const</span><span class=w> </span><span class=n>basic_json</span><span class=o>&amp;</span><span class=w> </span><span class=n>j</span><span class=p>,</span><span class=w> </span><span class=n>T</span><span class=o>&amp;</span><span class=w> </span><span class=n>t</span><span class=p>);</span>
</code></pre></div> <h2 id=additional-features>Additional features<a class=headerlink href=#additional-features title="Permanent link">&para;</a></h2> <ul> <li><abbr title="JavaScript Object Notation">JSON</abbr> Pointers</li> <li>Binary formats</li> <li>Custom base class</li> <li>Conversion macros</li> </ul> <h2 id=details-namespace>Details namespace<a class=headerlink href=#details-namespace title="Permanent link">&para;</a></h2> <ul> <li>C++ feature backports</li> </ul> <!-- https://squidfunk.github.io/mkdocs-material/reference/tooltips/#adding-a-glossary --> <aside class=md-source-file> <span class=md-source-file__fact> <span class=md-icon title="Last update"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z"/></svg> </span> <span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-date" title="September 24, 2026 15:05:37 UTC">September 24, 2026</span> </span> </aside> </article> </div> <script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script> <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script> </div> <button type=button class="md-top md-icon" data-md-component=top hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg> Back to top </button> </main> <footer class=md-footer> <div class="md-footer-meta md-typeset"> <div class="md-footer-meta__inner md-grid"> <div class=md-copyright> <div class=md-copyright__highlight> Copyright &copy; 2013-2026 Niels Lohmann </div> </div> <div class=md-social> <a href="https://github.com/nlohmann" target="_blank" rel="noopener" title="github.com" class="md-social__link"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 512 512"><!-- Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg> </a> <a href="https://www.linkedin.com/in/nielslohmann/" target="_blank" rel="noopener" title="www.linkedin.com" class="md-social__link"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 448 512"><!-- Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3M135.4 416H69V202.2h66.5V416zM102.2 96a38.5 38.5 0 1 1 0 77 38.5 38.5 0 1 1 0-77m282.1 320h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9z"/></svg> </a> <a href="https://www.xing.com/profile/Niels_Lohmann" target="_blank" rel="noopener" title="www.xing.com" class="md-social__link"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 384 512"><!-- Font Awesome Free 7.1.0 by @fontawesome - https://fontawesomLine truncated
</code></pre></div> <p>found by argument-dependent lookup. The library defines them for standard types in <code>detail/conversions</code>; users add them for their own types, see <a href=../../features/arbitrary_types/ >Arbitrary Type Conversions</a>. The <a href=../../features/macros/ >serialization macros</a> generate these functions.</p> <h2 id=additional-features>Additional features<a class=headerlink href=#additional-features title="Permanent link">&para;</a></h2> <ul> <li><a href=../../features/json_pointer/ ><abbr title="JavaScript Object Notation">JSON</abbr> Pointer</a> (class <code>json_pointer</code>) addresses values inside a tree. It is also the basis of <a href=../../features/json_patch/ ><abbr title="JavaScript Object Notation">JSON</abbr> Patch</a>.</li> <li><a href=../../features/binary_formats/ >Binary formats</a> are read by <code>binary_reader</code> and written by <code>binary_writer</code>.</li> <li>A <a href=../../api/basic_json/json_base_class_t/ >custom base class</a> can add members to every <a href=../../api/basic_json/ ><code>basic_json</code></a> value.</li> <li><a href=../../features/macros/ >Serialization macros</a> generate <code>to_json</code> and <code>from_json</code> functions for user-defined types.</li> </ul> <h2 id=details-namespace>Details namespace<a class=headerlink href=#details-namespace title="Permanent link">&para;</a></h2> <p>Namespace <code>nlohmann::detail</code> contains all implementation details. It is not part of the public <abbr title="Application Programming Interfaces">API</abbr> and may change in any release. Besides the components above, it contains:</p> <ul> <li>type traits to detect the capabilities of user-defined types (<code>detail/meta/type_traits.hpp</code>),</li> <li>backports of C++14/17 features to C++11 (<code>detail/meta/cpp_future.hpp</code>), and</li> <li>helpers such as <code>string_concat</code> and <code>string_escape</code>.</li> </ul> <!-- https://squidfunk.github.io/mkdocs-material/reference/tooltips/#adding-a-glossary --> <aside class=md-source-file> <span class=md-source-file__fact> <span class=md-icon title="Last update"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z"/></svg> </span> <span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-date" title="September 25, 2026 06:28:00 UTC">September 25, 2026</span> </span> </aside> </article> </div> <script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script> <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script> </div> <button type=button class="md-top md-icon" data-md-component=top hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg> Back to top </button> </main> <footer class=md-footer> <div class="md-footer-meta md-typeset"> <div class="md-footer-meta__inner md-grid"> <div class=md-copyright> <div class=md-copyright__highlight> Copyright &copy; 2013-2026 Niels Lohmann </div> </div> <div class=md-social> <a href="https://github.com/nlohmann" target="_blank" rel="noopener" title="github.com" class="md-social__link"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 512 512"><!-- Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 36Line truncated
+142 -34
View File
@@ -1,33 +1,109 @@
# Architecture
Info
This page is still under construction. Its goal is to provide a high-level overview of the library's architecture. This should help new contributors to get an idea of the used concepts and where to make changes.
This page gives a high-level overview of the library's architecture. It should help new contributors to get an idea of the used concepts and where to make changes.
## Overview
The main structure is class [nlohmann::basic_json](https://json.nlohmann.me/api/basic_json/index.md).
The library is built around a single class template, [`nlohmann::basic_json`](https://json.nlohmann.me/api/basic_json/index.md). A `basic_json` value is a node in a tree of JSON values. All other components either create such a tree from an input (parsing), write a tree to an output (serialization), or give access to it (iterators, JSON Pointer, conversions).
- public API
- container interface
- iterators
```
flowchart LR
input[/"input<br>(string, stream,<br>iterator range, file)"/]
ia["input adapter"]
lexer["lexer"]
parser["parser"]
breader["binary_reader"]
sax["SAX interface"]
value[("basic_json<br>value tree")]
serializer["serializer"]
bwriter["binary_writer"]
oa["output adapter"]
output[/"output<br>(string, stream,<br>vector)"/]
## Template specializations
input --> ia
ia --> lexer --> parser --> sax
ia --> breader --> sax
sax --> value
value --> serializer --> oa
value --> bwriter --> oa
oa --> output
```
- describe template parameters of `basic_json`
- [`json`](https://json.nlohmann.me/api/json/index.md)
- [`ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md) via [`ordered_map`](https://json.nlohmann.me/api/ordered_map/index.md)
- **JSON text** is read by an [input adapter](#input-adapters), tokenized by the lexer, and turned into SAX events by the parser.
- **Binary formats** (BJData, BSON, CBOR, MessagePack, UBJSON) are read by an input adapter and turned into the same SAX events by the `binary_reader`.
- A [SAX consumer](#sax-interface) receives the events. The one used by [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) builds a `basic_json` value tree.
- The `serializer` (JSON text) or the `binary_writer` (binary formats) writes a value tree to an [output adapter](#output-adapters).
## Source layout
The public headers are in [`include/nlohmann`](https://github.com/nlohmann/json/tree/develop/include/nlohmann):
- [`json.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/json.hpp) defines class [`basic_json`](https://json.nlohmann.me/api/basic_json/index.md).
- [`json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/json_fwd.hpp) contains forward declarations.
- [`adl_serializer.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/adl_serializer.hpp), [`byte_container_with_subtype.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/byte_container_with_subtype.hpp), and [`ordered_map.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/ordered_map.hpp) define [`adl_serializer`](https://json.nlohmann.me/api/adl_serializer/index.md), [`byte_container_with_subtype`](https://json.nlohmann.me/api/byte_container_with_subtype/index.md), and [`ordered_map`](https://json.nlohmann.me/api/ordered_map/index.md).
Everything else lives in [`detail/`](https://github.com/nlohmann/json/tree/develop/include/nlohmann/detail) and namespace `nlohmann::detail`, which is not part of the public API. Paths below are relative to `include/nlohmann`.
| Component | Location |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Value type enumeration | [`detail/value_t.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/value_t.hpp) |
| Input adapters | [`detail/input/input_adapters.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/input_adapters.hpp) |
| Lexer | [`detail/input/lexer.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/lexer.hpp), [`detail/input/number_parse.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/number_parse.hpp), [`detail/input/string_scan.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/string_scan.hpp) |
| Parser | [`detail/input/parser.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/parser.hpp) |
| SAX interface and DOM builders | [`detail/input/json_sax.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/json_sax.hpp) |
| Binary format readers | [`detail/input/binary_reader.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/binary_reader.hpp) |
| JSON serializer | [`detail/output/serializer.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/output/serializer.hpp), [`detail/conversions/to_chars.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/conversions/to_chars.hpp) |
| Binary format writers | [`detail/output/binary_writer.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/output/binary_writer.hpp) |
| Output adapters | [`detail/output/output_adapters.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/output/output_adapters.hpp) |
| Iterators | [`detail/iterators/`](https://github.com/nlohmann/json/tree/develop/include/nlohmann/detail/iterators) |
| Conversions from/to arbitrary types | [`detail/conversions/from_json.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/conversions/from_json.hpp), [`detail/conversions/to_json.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/conversions/to_json.hpp) |
| JSON Pointer | [`detail/json_pointer.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/json_pointer.hpp) |
| Exceptions | [`detail/exceptions.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/exceptions.hpp) |
| Type traits and C++ feature backports | [`detail/meta/`](https://github.com/nlohmann/json/tree/develop/include/nlohmann/detail/meta) |
| Macros | [`detail/macro_scope.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/macro_scope.hpp), [`detail/macro_unscope.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/macro_unscope.hpp), [`detail/abi_macros.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/abi_macros.hpp) |
The single-header version [`single_include/nlohmann/json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) is generated from these files with `make amalgamate` and must not be edited by hand.
## Template parameters
[`basic_json`](https://json.nlohmann.me/api/basic_json/index.md) is parameterized by the types it uses to store values and to convert from and to other types:
| Template parameter | Default | Used for |
| -------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `ObjectType` | `std::map` | objects, see [`object_t`](https://json.nlohmann.me/api/basic_json/object_t/index.md) |
| `ArrayType` | `std::vector` | arrays, see [`array_t`](https://json.nlohmann.me/api/basic_json/array_t/index.md) |
| `StringType` | `std::string` | strings and object keys, see [`string_t`](https://json.nlohmann.me/api/basic_json/string_t/index.md) |
| `BooleanType` | `bool` | Booleans, see [`boolean_t`](https://json.nlohmann.me/api/basic_json/boolean_t/index.md) |
| `NumberIntegerType` | `std::int64_t` | signed integers, see [`number_integer_t`](https://json.nlohmann.me/api/basic_json/number_integer_t/index.md) |
| `NumberUnsignedType` | `std::uint64_t` | unsigned integers, see [`number_unsigned_t`](https://json.nlohmann.me/api/basic_json/number_unsigned_t/index.md) |
| `NumberFloatType` | `double` | floating-point numbers, see [`number_float_t`](https://json.nlohmann.me/api/basic_json/number_float_t/index.md) |
| `AllocatorType` | `std::allocator` | allocating objects, arrays, strings, and binary values |
| `JSONSerializer` | `adl_serializer` | conversions from/to other types, see [`adl_serializer`](https://json.nlohmann.me/api/adl_serializer/index.md) |
| `BinaryType` | `std::vector<std::uint8_t>` | binary values, see [`binary_t`](https://json.nlohmann.me/api/basic_json/binary_t/index.md) |
| `CustomBaseClass` | `void` | an optional base class, see [`json_base_class_t`](https://json.nlohmann.me/api/basic_json/json_base_class_t/index.md) |
The library provides two specializations:
- [`json`](https://json.nlohmann.me/api/json/index.md) uses all default template arguments.
- [`ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md) uses [`ordered_map`](https://json.nlohmann.me/api/ordered_map/index.md) as `ObjectType` to keep the insertion order of object keys.
The requirements on the template arguments are listed in [Template Parameter Requirements](https://json.nlohmann.me/features/types/template_parameters/index.md).
## Value storage
Values are stored as a tagged union of [value_t](https://json.nlohmann.me/api/basic_json/value_t/index.md) and json_value.
Each [`basic_json`](https://json.nlohmann.me/api/basic_json/index.md) value stores its content as a tagged union: an enumeration [`value_t`](https://json.nlohmann.me/api/basic_json/value_t/index.md) names the type of the value, and a union `json_value` holds the value itself. Both are members of the nested struct `data`, which is the only data member `m_data` of `basic_json`:
```
/// the type of the current element
value_t m_type = value_t::null;
struct data
{
/// the type of the current element
value_t m_type = value_t::null;
/// the value of the current element
json_value m_value = {};
/// the value of the current element
json_value m_value = {};
};
data m_data = {};
```
with
@@ -67,42 +143,68 @@ union json_value {
};
```
## Parsing inputs (deserialization)
Objects, arrays, strings, and binary values are allocated on the heap with `AllocatorType`, and the union only stores a pointer to them. This keeps a `basic_json` value small: one pointer-sized union and one byte for the type. The class maintains the invariant that the pointer matching `m_type` is never null; `assert_invariant()` checks it with [runtime assertions](https://json.nlohmann.me/features/assertions/index.md).
Input is read via **input adapters** that abstract a source with a common interface:
## Input adapters
Input is read via **input adapters** that abstract a source. Every input adapter provides this interface:
```
/// read a single character
std::char_traits<char>::int_type get_character() noexcept;
/// the type of the characters in the input
using char_type = ...;
/// read multiple characters to a destination buffer and
/// returns the number of characters successfully read
/// read a single character; returns std::char_traits<char_type>::eof() at the end of the input
typename std::char_traits<char_type>::int_type get_character();
/// read up to count * sizeof(T) bytes into dest and return the number of bytes read
/// (used by the binary readers)
template<class T>
std::size_t get_elements(T* dest, std::size_t count = 1);
```
List examples of input adapters.
The lexer detects two optional extensions at compile time. Only `iterator_input_adapter` provides them, and only for random-access input of single-byte characters:
## SAX Interface
- `supports_seek`, `get_consumed_count()`, and `copy_consumed_range()` let the lexer reconstruct already consumed input for error messages instead of copying every character it reads.
- `supports_bulk_scan`, `bulk_data()`, `bulk_remaining()`, and `bulk_skip()` let the lexer scan strings directly in contiguous memory, several bytes at a time.
TODO
The function `input_adapter` picks the right adapter for the argument passed to `parse`, `accept`, `sax_parse`, or the `from_*` functions:
## Writing outputs (serialization)
- `iterator_input_adapter` reads from an iterator range, which also covers strings, containers, and pointers.
- `wide_string_input_adapter` reads from ranges of `wchar_t`, `char16_t`, or `char32_t` and converts them to UTF-8. It cannot be used for binary formats; its `get_elements()` throws.
- `input_stream_adapter` reads from a `std::istream`.
- `file_input_adapter` reads from a `std::FILE*`.
## SAX interface
The parser does not build values itself. It reports what it reads as events to a [SAX](https://json.nlohmann.me/features/parsing/sax_interface/index.md) consumer, which implements the interface [`json_sax`](https://json.nlohmann.me/api/json_sax/index.md): `null`, `boolean`, `number_integer`, `number_unsigned`, `number_float`, `string`, `binary`, `start_object`, `key`, `end_object`, `start_array`, `end_array`, and `parse_error`.
The library comes with two consumers in `detail/input/json_sax.hpp`:
- `json_sax_dom_parser` builds a [`basic_json`](https://json.nlohmann.me/api/basic_json/index.md) value tree. [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) uses it.
- `json_sax_dom_callback_parser` does the same, but calls a [parser callback](https://json.nlohmann.me/features/parsing/parser_callbacks/index.md) for each event, which can skip values. `parse` uses it when a callback is given.
The `binary_reader` emits the same events for binary formats, so [`sax_parse`](https://json.nlohmann.me/api/basic_json/sax_parse/index.md) works with a user-defined consumer for JSON and for all binary formats alike.
## Output adapters
Output is written via **output adapters**:
```
template<typename T>
void write_character(CharType c);
template<typename CharType>
void write_characters(const CharType* s, std::size_t length);
```
List examples of output adapters.
The `serializer` (used by [`dump`](https://json.nlohmann.me/api/basic_json/dump/index.md) and [`operator<<`](https://json.nlohmann.me/api/operator_ltlt/index.md)) and the `binary_writer` (used by the `to_*` functions) write to one of these adapters:
- `output_vector_adapter` appends to a `std::vector`.
- `output_stream_adapter` writes to a `std::ostream`.
- `output_string_adapter` appends to a string.
## Value conversion
Values are converted from and to other types with the `JSONSerializer` template parameter. The default, [`adl_serializer`](https://json.nlohmann.me/api/adl_serializer/index.md), calls the free functions
```
template<class T>
void to_json(basic_json& j, const T& t);
@@ -111,13 +213,19 @@ template<class T>
void from_json(const basic_json& j, T& t);
```
found by argument-dependent lookup. The library defines them for standard types in `detail/conversions`; users add them for their own types, see [Arbitrary Type Conversions](https://json.nlohmann.me/features/arbitrary_types/index.md). The [serialization macros](https://json.nlohmann.me/features/macros/index.md) generate these functions.
## Additional features
- JSON Pointers
- Binary formats
- Custom base class
- Conversion macros
- [JSON Pointer](https://json.nlohmann.me/features/json_pointer/index.md) (class `json_pointer`) addresses values inside a tree. It is also the basis of [JSON Patch](https://json.nlohmann.me/features/json_patch/index.md).
- [Binary formats](https://json.nlohmann.me/features/binary_formats/index.md) are read by `binary_reader` and written by `binary_writer`.
- A [custom base class](https://json.nlohmann.me/api/basic_json/json_base_class_t/index.md) can add members to every [`basic_json`](https://json.nlohmann.me/api/basic_json/index.md) value.
- [Serialization macros](https://json.nlohmann.me/features/macros/index.md) generate `to_json` and `from_json` functions for user-defined types.
## Details namespace
- C++ feature backports
Namespace `nlohmann::detail` contains all implementation details. It is not part of the public API and may change in any release. Besides the components above, it contains:
- type traits to detect the capabilities of user-defined types (`detail/meta/type_traits.hpp`),
- backports of C++14/17 features to C++11 (`detail/meta/cpp_future.hpp`), and
- helpers such as `string_concat` and `string_escape`.