This commit is contained in:
nlohmann committed 2026-11-10 06:10:03 +00:00
1 parent eeea067a72
commit 8ddeea7128
18 files changed
+452 -439

No files matched your search

+3
View File
@@ -34,6 +34,9 @@ or quotes.
Note that enabling this macro increases the size of every JSON value by two `std::size_t` fields and adds slight runtime
overhead to parsing, copying JSON value objects, and the generation of error messages for exceptions. It also causes
these values to be reported in those error messages.
In addition, `parse()`, `accept()`, and `sax_parse()` no longer use the
[faster path for input in one block of memory](../../features/parsing/index.md#input-sources-and-performance), so
parsing a string or a buffer is slower than without the macro.
If [`JSON_DIAGNOSTICS`](json_diagnostics.md) is also set, the message contains the path and the byte range, such as
`(/1) (bytes 4-8)`. An exception about the root value has no path and only the range, such as `(bytes 0-4)`.
@@ -1,5 +1,5 @@
<!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=description content="JSON for Modern C++ is a header-only C++11 library that makes JSON a first-class data type."><meta name=author content="Niels Lohmann"><link href="https://json.nlohmann.me/api/macros/json_diagnostic_positions/" rel="canonical"><link href=../json_delete_deprecated_functions/ rel=prev><link href=../json_disable_enum_serialization/ rel=next><link rel=icon href=../../../assets/images/favicon.png><meta name=generator content="mkdocs-1.6.1, mkdocs-material-9.8.0"><title>JSON_DIAGNOSTIC_POSITIONS - JSON for Modern C++</title><link rel=stylesheet href=../../../assets/stylesheets/main.57a0d79d.min.css><link rel=stylesheet href=../../../assets/stylesheets/palette.fb2fffe2.min.css><link rel=stylesheet href=../../../css/custom.css><link rel=stylesheet href=../../../css/brand.css><link rel=stylesheet href=../../../css/fig-sax.css><link rel=stylesheet href=../../../css/fig-jsonview.css><link rel=stylesheet href=../../../css/fig-exceptions.css><link rel=stylesheet href=../../../css/fig-pointer.css><link rel=stylesheet href=../../../css/fig-charts.css><link rel=stylesheet href=../../../css/fig-integration.css><link rel=stylesheet href=../../../css/fig-macros.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=custom data-md-color-accent=custom> <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=#json_diagnostic_positions 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> <img src=../../../images/wordmark-header.svg alt=logo> </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> JSON_DIAGNOSTIC_POSITIONS </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=custom data-md-color-accent=custom 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=custom data-md-color-accent=custom 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=Line truncated
</code></pre></div> <p>This macro enables position diagnostics for generated <abbr title="JavaScript Object Notation">JSON</abbr> objects.</p> <p>When enabled, two new member functions <a href=../../basic_json/start_pos/ ><code>start_pos()</code></a> and <a href=../../basic_json/end_pos/ ><code>end_pos()</code></a> are added to <a href=../../basic_json/ ><code>basic_json</code></a> values. If the value was created by calling the<a href=../../basic_json/parse/ ><code>parse</code></a> function, then these functions allow querying the byte positions of the value in the input it was parsed from. In case the value was constructed by other means, <code>std::string::npos</code> is returned.</p> <p><a href=../../basic_json/start_pos/ ><code>start_pos()</code></a> returns the position of the first character of a given value in the original <abbr title="JavaScript Object Notation">JSON</abbr> string, while <a href=../../basic_json/end_pos/ ><code>end_pos()</code></a> returns the position of the character <em>following</em> the last character. For objects and arrays, the first and last characters correspond to the opening or closing braces/brackets, respectively. For primitive values, the first and last character represents the opening and closing quotes (strings) or the first and last character of the field's numerical or predefined value (<code>true</code>, <code>false</code>, <code>null</code>), respectively.</p> <table> <thead> <tr> <th><abbr title="JavaScript Object Notation">JSON</abbr> type</th> <th>return value <a href=../../basic_json/start_pos/ ><code>start_pos()</code></a></th> <th>return value <a href=../../basic_json/end_pos/ ><code>end_pos()</code></a></th> </tr> </thead> <tbody> <tr> <td>object</td> <td>position of the opening <code>{</code></td> <td>position after the closing <code>}</code></td> </tr> <tr> <td>array</td> <td>position of the opening <code>[</code></td> <td>position after the closing <code>]</code></td> </tr> <tr> <td>string</td> <td>position of the opening <code>"</code></td> <td>position after the closing <code>"</code></td> </tr> <tr> <td>number</td> <td>position of the first character</td> <td>position after the last character</td> </tr> <tr> <td>boolean</td> <td>position of <code>t</code> for <code>true</code> and <code>f</code> for <code>false</code></td> <td>position after <code>e</code></td> </tr> <tr> <td>null</td> <td>position of <code>n</code></td> <td>position after <code>l</code></td> </tr> </tbody> </table> <p>Given the above, <a href=../../basic_json/end_pos/ ><code>end_pos()</code></a><code>-</code><a href=../../basic_json/start_pos/ ><code>start_pos()</code></a> for a <abbr title="JavaScript Object Notation">JSON</abbr> value provides the length of the parsed <abbr title="JavaScript Object Notation">JSON</abbr> string for that value, including the opening or closing braces, brackets, or quotes.</p> <p>Note that enabling this macro increases the size of every <abbr title="JavaScript Object Notation">JSON</abbr> value by two <code>std::size_t</code> fields and adds slight runtime overhead to parsing, copying <abbr title="JavaScript Object Notation">JSON</abbr> value objects, and the generation of error messages for exceptions. It also causes these values to be reported in those error messages.</p> <p>If <a href=../json_diagnostics/ ><code>JSON_DIAGNOSTICS</code></a> is also set, the message contains the path and the byte range, such as <code>(/1) (bytes 4-8)</code>. An exception about the root value has no path and only the range, such as <code>(bytes 0-4)</code>.</p> <h2 id=default-definition>Default definition<a class=headerlink href=#default-definition title="Permanent link">&para;</a></h2> <p>The default value is <code>0</code> (position diagnostics are switched off).</p> <div class=highlight><pre><span></span><code><span class=cp>#define JSON_DIAGNOSTIC_POSITIONS 0</span>
</code></pre></div> <p>This macro enables position diagnostics for generated <abbr title="JavaScript Object Notation">JSON</abbr> objects.</p> <p>When enabled, two new member functions <a href=../../basic_json/start_pos/ ><code>start_pos()</code></a> and <a href=../../basic_json/end_pos/ ><code>end_pos()</code></a> are added to <a href=../../basic_json/ ><code>basic_json</code></a> values. If the value was created by calling the<a href=../../basic_json/parse/ ><code>parse</code></a> function, then these functions allow querying the byte positions of the value in the input it was parsed from. In case the value was constructed by other means, <code>std::string::npos</code> is returned.</p> <p><a href=../../basic_json/start_pos/ ><code>start_pos()</code></a> returns the position of the first character of a given value in the original <abbr title="JavaScript Object Notation">JSON</abbr> string, while <a href=../../basic_json/end_pos/ ><code>end_pos()</code></a> returns the position of the character <em>following</em> the last character. For objects and arrays, the first and last characters correspond to the opening or closing braces/brackets, respectively. For primitive values, the first and last character represents the opening and closing quotes (strings) or the first and last character of the field's numerical or predefined value (<code>true</code>, <code>false</code>, <code>null</code>), respectively.</p> <table> <thead> <tr> <th><abbr title="JavaScript Object Notation">JSON</abbr> type</th> <th>return value <a href=../../basic_json/start_pos/ ><code>start_pos()</code></a></th> <th>return value <a href=../../basic_json/end_pos/ ><code>end_pos()</code></a></th> </tr> </thead> <tbody> <tr> <td>object</td> <td>position of the opening <code>{</code></td> <td>position after the closing <code>}</code></td> </tr> <tr> <td>array</td> <td>position of the opening <code>[</code></td> <td>position after the closing <code>]</code></td> </tr> <tr> <td>string</td> <td>position of the opening <code>"</code></td> <td>position after the closing <code>"</code></td> </tr> <tr> <td>number</td> <td>position of the first character</td> <td>position after the last character</td> </tr> <tr> <td>boolean</td> <td>position of <code>t</code> for <code>true</code> and <code>f</code> for <code>false</code></td> <td>position after <code>e</code></td> </tr> <tr> <td>null</td> <td>position of <code>n</code></td> <td>position after <code>l</code></td> </tr> </tbody> </table> <p>Given the above, <a href=../../basic_json/end_pos/ ><code>end_pos()</code></a><code>-</code><a href=../../basic_json/start_pos/ ><code>start_pos()</code></a> for a <abbr title="JavaScript Object Notation">JSON</abbr> value provides the length of the parsed <abbr title="JavaScript Object Notation">JSON</abbr> string for that value, including the opening or closing braces, brackets, or quotes.</p> <p>Note that enabling this macro increases the size of every <abbr title="JavaScript Object Notation">JSON</abbr> value by two <code>std::size_t</code> fields and adds slight runtime overhead to parsing, copying <abbr title="JavaScript Object Notation">JSON</abbr> value objects, and the generation of error messages for exceptions. It also causes these values to be reported in those error messages. In addition, <code>parse()</code>, <code>accept()</code>, and <code>sax_parse()</code> no longer use the <a href=../../../features/parsing/#input-sources-and-performance>faster path for input in one block of memory</a>, so parsing a string or a buffer is slower than without the macro.</p> <p>If <a href=../json_diagnostics/ ><code>JSON_DIAGNOSTICS</code></a> is also set, the message contains the path and the byte range, such as <code>(/1) (bytes 4-8)</code>. An exception about the root value has no path and only the range, such as <code>(bytes 0-4)</code>.</p> <h2 id=default-definition>Default definition<a class=headerlink href=#default-definition title="Permanent link">&para;</a></h2> <p>The default value is <code>0</code> (position diagnostics are switched off).</p> <div class=highlight><pre><span></span><code><span class=cp>#define JSON_DIAGNOSTIC_POSITIONS 0</span>
</code></pre></div> <p>When the macro is not defined, the library will define it to its default value.</p> <h2 id=notes>Notes<a class=headerlink href=#notes title="Permanent link">&para;</a></h2> <div class="admonition note"> <p class=admonition-title>CMake option</p> <p>Diagnostic positions can also be controlled with the CMake option <a href=../../../integration/cmake/#json_diagnostic_positions><code>JSON_Diagnostic_Positions</code></a> (<code>OFF</code> by default) which defines <code>JSON_DIAGNOSTIC_POSITIONS</code> accordingly.</p> </div> <div class="admonition note"> <p class=admonition-title>Availability</p> <p>Diagnostic positions are only available if the value was created by the <a href=../../basic_json/parse/ ><code>parse</code></a> function. The <a href=../../basic_json/sax_parse/ ><code>sax_parse</code></a> function or all other means to create a <abbr title="JavaScript Object Notation">JSON</abbr> value <strong>do not</strong> set the diagnostic positions and <a href=../../basic_json/start_pos/ ><code>start_pos()</code></a> and <a href=../../basic_json/end_pos/ ><code>end_pos()</code></a> will only return <code>std::string::npos</code> for these values.</p> </div> <div class="admonition warning"> <p class=admonition-title>Invalidation</p> <p>The returned positions are only valid as long as the <abbr title="JavaScript Object Notation">JSON</abbr> value is not changed. The positions are <em>not</em> updated when the <abbr title="JavaScript Object Notation">JSON</abbr> value is changed.</p> </div> <h2 id=examples>Examples<a class=headerlink href=#examples title="Permanent link">&para;</a></h2> <details class=example> <summary>Example: retrieving positions</summary> <div class=highlight><pre><span></span><code><span class=cp>#include</span><span class=w> </span><span class=cpf>&lt;iostream&gt;</span>
<span class=cp>#define JSON_DIAGNOSTIC_POSITIONS 1</span>
@@ -165,4 +165,4 @@ Parsed string:
<span class=p>}</span>
</code></pre></div> <p>Output:</p> <div class=highlight><pre><span></span><code>[json.exception.type_error.302] (/address/housenumber) (bytes 92-95) type must be number, but is string
</code></pre></div> <div class=codehilite><pre><span></span><code>The output shows the exception with diagnostic path info and start/end positions.
</code></pre></div> </details> <h2 id=see-also>See also<a class=headerlink href=#see-also title="Permanent link">&para;</a></h2> <ul> <li><a href=../../../integration/cmake/#json_diagnostic_positions><span class=twemoji><svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M11.769.066.067 23.206l12.76-10.843zm11.438 23.868L7.471 17.587 0 23.934zm.793-.198L12.298.463l1.719 19.24zM12.893 12.959l-5.025 4.298 5.62 2.248z"/></svg></span> JSON_Diagnostic_Positions</a> - CMake option to control the macro</li> <li><a href=../json_diagnostics/ ><code>JSON_DIAGNOSTICS</code></a> - macro to control extended diagnostics</li> <li><a href=../../basic_json_view/materialize/ ><code>materialize()</code></a> - values of a <abbr title="JavaScript Object Notation">JSON</abbr> view, with the same positions</li> <li><a href=../../../features/parsing/parse_exceptions/ >Parsing and Exceptions</a> - handling parse errors and locating them in the input</li> </ul> <h2 id=version-history>Version history<a class=headerlink href=#version-history title="Permanent link">&para;</a></h2> <ul> <li>Added in version 3.12.0.</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="November 2, 2026 16:50:40 UTC">November 2, 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> <nav class="md-footer__inner md-grid" aria-label=Footer> <a href=../json_delete_deprecated_functions/ class="md-footer__link md-footer__link--prev" aria-label="Previous: JSON_DELETE_DEPRECATED_FUNCTIONS"> <div class="md-footer__button md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg> </div> <div class=md-footer__title> <span class=md-footer__direction> Previous </span> <div class=md-ellipsis> JSON_DELETE_DEPRECATED_FUNCTIONS </div> </div> </a> <a href=../json_disable_enum_serialization/ class="md-footer__link md-footer__link--next" aria-label="Next: JSON_DISABLE_ENUM_SERIALIZATION"> <div class=md-footer__title> <span class=md-footer__direction> Next </span> <div class=md-ellipsis> JSON_DISABLE_ENUM_SERIALIZATION </div> </div> <div class="md-footer__button md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg> </div> </a> </nav> <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.Line truncated
</code></pre></div> </details> <h2 id=see-also>See also<a class=headerlink href=#see-also title="Permanent link">&para;</a></h2> <ul> <li><a href=../../../integration/cmake/#json_diagnostic_positions><span class=twemoji><svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M11.769.066.067 23.206l12.76-10.843zm11.438 23.868L7.471 17.587 0 23.934zm.793-.198L12.298.463l1.719 19.24zM12.893 12.959l-5.025 4.298 5.62 2.248z"/></svg></span> JSON_Diagnostic_Positions</a> - CMake option to control the macro</li> <li><a href=../json_diagnostics/ ><code>JSON_DIAGNOSTICS</code></a> - macro to control extended diagnostics</li> <li><a href=../../basic_json_view/materialize/ ><code>materialize()</code></a> - values of a <abbr title="JavaScript Object Notation">JSON</abbr> view, with the same positions</li> <li><a href=../../../features/parsing/parse_exceptions/ >Parsing and Exceptions</a> - handling parse errors and locating them in the input</li> </ul> <h2 id=version-history>Version history<a class=headerlink href=#version-history title="Permanent link">&para;</a></h2> <ul> <li>Added in version 3.12.0.</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="November 10, 2026 06:08:44 UTC">November 10, 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> <nav class="md-footer__inner md-grid" aria-label=Footer> <a href=../json_delete_deprecated_functions/ class="md-footer__link md-footer__link--prev" aria-label="Previous: JSON_DELETE_DEPRECATED_FUNCTIONS"> <div class="md-footer__button md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg> </div> <div class=md-footer__title> <span class=md-footer__direction> Previous </span> <div class=md-ellipsis> JSON_DELETE_DEPRECATED_FUNCTIONS </div> </div> </a> <a href=../json_disable_enum_serialization/ class="md-footer__link md-footer__link--next" aria-label="Next: JSON_DISABLE_ENUM_SERIALIZATION"> <div class=md-footer__title> <span class=md-footer__direction> Next </span> <div class=md-ellipsis> JSON_DISABLE_ENUM_SERIALIZATION </div> </div> <div class="md-footer__button md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg> </div> </a> </nav> <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-Line truncated
@@ -21,7 +21,7 @@ When enabled, two new member functions [`start_pos()`](https://json.nlohmann.me/
Given the above, [`end_pos()`](https://json.nlohmann.me/api/basic_json/end_pos/index.md)`-`[`start_pos()`](https://json.nlohmann.me/api/basic_json/start_pos/index.md) for a JSON value provides the length of the parsed JSON string for that value, including the opening or closing braces, brackets, or quotes.
Note that enabling this macro increases the size of every JSON value by two `std::size_t` fields and adds slight runtime overhead to parsing, copying JSON value objects, and the generation of error messages for exceptions. It also causes these values to be reported in those error messages.
Note that enabling this macro increases the size of every JSON value by two `std::size_t` fields and adds slight runtime overhead to parsing, copying JSON value objects, and the generation of error messages for exceptions. It also causes these values to be reported in those error messages. In addition, `parse()`, `accept()`, and `sax_parse()` no longer use the [faster path for input in one block of memory](https://json.nlohmann.me/features/parsing/#input-sources-and-performance), so parsing a string or a buffer is slower than without the macro.
If [`JSON_DIAGNOSTICS`](https://json.nlohmann.me/api/macros/json_diagnostics/index.md) is also set, the message contains the path and the byte range, such as `(/1) (bytes 4-8)`. An exception about the root value has no path and only the range, such as `(bytes 0-4)`.
+2 -2
View File
@@ -48,8 +48,8 @@ The default value is `0`: streams are scanned in bulk.
!!! note "Performance"
Parsing from a `std::ifstream` or `std::istringstream` is typically 1.5 to 2 times as fast as before, and reading
many small values from one stream with `operator>>` 1.4 to 4 times as fast. Parsing from a stream is then within
about 10 to 20 % of first reading the whole file into a `std::string` and parsing that.
many small values from one stream with `operator>>` 1.4 to 4 times as fast. Parsing from a stream then takes about
1.15 to 1.45 times as long as first reading the whole file into a `std::string` and parsing that.
A stream buffer without a get area (one that only overrides `underflow()` and `uflow()` and hands out every
character from there) offers nothing to scan in bulk, so it is read one character at a time as before.
@@ -1,6 +1,6 @@
<!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=description content="JSON for Modern C++ is a header-only C++11 library that makes JSON a first-class data type."><meta name=author content="Niels Lohmann"><link href="https://json.nlohmann.me/api/macros/json_disable_stream_bulk_scan/" rel="canonical"><link href=../json_disable_enum_serialization/ rel=prev><link href=../json_disable_tuple_reference_conversion/ rel=next><link rel=icon href=../../../assets/images/favicon.png><meta name=generator content="mkdocs-1.6.1, mkdocs-material-9.8.0"><title>JSON_DISABLE_STREAM_BULK_SCAN - JSON for Modern C++</title><link rel=stylesheet href=../../../assets/stylesheets/main.57a0d79d.min.css><link rel=stylesheet href=../../../assets/stylesheets/palette.fb2fffe2.min.css><link rel=stylesheet href=../../../css/custom.css><link rel=stylesheet href=../../../css/brand.css><link rel=stylesheet href=../../../css/fig-sax.css><link rel=stylesheet href=../../../css/fig-jsonview.css><link rel=stylesheet href=../../../css/fig-exceptions.css><link rel=stylesheet href=../../../css/fig-pointer.css><link rel=stylesheet href=../../../css/fig-charts.css><link rel=stylesheet href=../../../css/fig-integration.css><link rel=stylesheet href=../../../css/fig-macros.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=custom data-md-color-accent=custom> <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=#json_disable_stream_bulk_scan 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> <img src=../../../images/wordmark-header.svg alt=logo> </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> JSON_DISABLE_STREAM_BULK_SCAN </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=custom data-md-color-accent=custom 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=custom data-md-color-accent=custom 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-headeLine truncated
</code></pre></div> <p>When defined to <code>1</code>, parsing from a <code class=highlight><span class=n>std</span><span class=o>::</span><span class=n>istream</span></code> reads the input one character at a time through the stream buffer, as in version 3.12.0 and earlier, instead of scanning the characters that the stream buffer already holds in bulk.</p> <p>The macro is an escape hatch for stream buffers that do not follow the usual contract of <code>std::basic_streambuf</code> (see the requirements on the stream buffer in the notes below). It does not change any result: values, exceptions, and the position of the stream after parsing are the same either way. Only the speed differs.</p> <h2 id=default-definition>Default definition<a class=headerlink href=#default-definition title="Permanent link">&para;</a></h2> <p>The default value is <code>0</code>: streams are scanned in bulk.</p> <div class=highlight><pre><span></span><code><span class=cp>#define JSON_DISABLE_STREAM_BULK_SCAN 0</span>
</code></pre></div> <h2 id=notes>Notes<a class=headerlink href=#notes title="Permanent link">&para;</a></h2> <div class="admonition note"> <p class=admonition-title>How streams are scanned</p> <p>A <code>std::streambuf</code> keeps the part of the input it has read but not yet handed out in its <em>get area</em>, the range from <code>gptr()</code> to <code>egptr()</code>. A <code>std::filebuf</code>, for instance, reads the file in blocks of a few kilobytes into its get area, and a <code>std::stringbuf</code> exposes its whole string as one get area.</p> <p>When parsing from a <code>std::istream</code>, the parser scans this get area directly, with the same fast paths that it uses for a <code>std::string</code>: runs of ordinary string characters, numbers, and indentation are recognized several bytes at a time instead of being requested from the stream buffer one character at a time. When the parser reaches the end of the get area, it asks the stream buffer for the next character as before, which makes the stream buffer refill its get area.</p> <p>The parser only reads characters that it would also have read one at a time, and it advances the stream buffer exactly over the characters it consumes. Nothing is read ahead, buffered elsewhere, or put back. Therefore, the stream is left exactly where it was left before:</p> <ul> <li><a href=../../operator_gtgt/ ><code>operator&gt;&gt;</code></a> and <a href=../../basic_json/sax_parse/ ><code>sax_parse</code></a> with <code>strict = false</code> can still read several values from one stream, and the stream can still be used with other <code>std::istream</code> functions after a value has been read.</li> <li>With <a href=../json_precise_stream_position/ ><code>JSON_PRECISE_STREAM_POSITION</code></a>, the stream is still positioned right after a parsed number.</li> <li>Exception messages, including the line, the column, and the last read token, are unchanged.</li> </ul> </div> <div class="admonition note"> <p class=admonition-title>Performance</p> <p>Parsing from a <code>std::ifstream</code> or <code>std::istringstream</code> is typically 1.5 to 2 times as fast as before, and reading many small values from one stream with <code>operator&gt;&gt;</code> 1.4 to 4 times as fast. Parsing from a stream is then within about 10 to 20 % of first reading the whole file into a <code>std::string</code> and parsing that.</p> <p>A stream buffer without a get area (one that only overrides <code>underflow()</code> and <code>uflow()</code> and hands out every character from there) offers nothing to scan in bulk, so it is read one character at a time as before.</p> </div> <div class="admonition note"> <p class=admonition-title>Requirements on the stream buffer</p> <p>The bulk scan relies on the following behavior, which every stream buffer of the standard library and every stream buffer that keeps its input in its get area has:</p> <ul> <li>When <code>sgetc()</code> returns a character while <code>gptr() &lt; egptr()</code>, that character is <code>*gptr()</code>; when <code>sbumpc()</code> returns one, it was at <code>gptr()</code> before the call.</li> <li>Characters in the get area are not changed while they are in the get area.</li> <li><code>underflow()</code> or <code>uflow()</code> either sets up a get area that holds the returned character at <code>gptr()</code> (or at <code>gptr() - 1</code> after <code>uflow()</code>), or leaves the get area empty.</li> </ul> <p>A stream buffer that returns characters from <code>uflow()</code> while leaving unrelated characters in its get area, or that changes the characters in its get area in place, does not meet these requirements. Define the macro to <code>1</code> for such stream buffers.</p> </div> <div class="admonition note"> <p class=admonition-title><abbr title="Application Binary Interface">ABI</abbr> compatibility</p> <p>The value of this macro is encoded in the <a href=../../../features/namespace/ >namespace</a> (tag <code>_dsbs</code>), resulting in distinct symbol names. Translation units compiled with and without it can therefore be linked into the same program without One Definition Rule (<abbr title="One Definition Rule">ODR</abbr>) violations, but they cannot exchange instances of library types.</p> </div> <div class="admonition note"> <p class=admonition-title>Other inputs</p> <p>Strings, string views, vectors, arrays, and pointer or iterator ranges over contiguous memory are scanned in bulk anyway. Reading from a <code class=highlight><span class=kt>FILE</span><span class=o>*</span></code> is not affected by this macro; see <a href=../json_disable_unlocked_file_io/ ><code>JSON_DISABLE_UNLOCKED_FILE_IO</code></a> for that input.</p> </div> <h2 id=examples>Examples<a class=headerlink href=#examples title="Permanent link">&para;</a></h2> <details class=example> <summary>Example: reading values from a stream (default)</summary> <p>The stream is scanned in bulk, and the values are read one after the other:</p> <div class=higLine truncated
</code></pre></div> <h2 id=notes>Notes<a class=headerlink href=#notes title="Permanent link">&para;</a></h2> <div class="admonition note"> <p class=admonition-title>How streams are scanned</p> <p>A <code>std::streambuf</code> keeps the part of the input it has read but not yet handed out in its <em>get area</em>, the range from <code>gptr()</code> to <code>egptr()</code>. A <code>std::filebuf</code>, for instance, reads the file in blocks of a few kilobytes into its get area, and a <code>std::stringbuf</code> exposes its whole string as one get area.</p> <p>When parsing from a <code>std::istream</code>, the parser scans this get area directly, with the same fast paths that it uses for a <code>std::string</code>: runs of ordinary string characters, numbers, and indentation are recognized several bytes at a time instead of being requested from the stream buffer one character at a time. When the parser reaches the end of the get area, it asks the stream buffer for the next character as before, which makes the stream buffer refill its get area.</p> <p>The parser only reads characters that it would also have read one at a time, and it advances the stream buffer exactly over the characters it consumes. Nothing is read ahead, buffered elsewhere, or put back. Therefore, the stream is left exactly where it was left before:</p> <ul> <li><a href=../../operator_gtgt/ ><code>operator&gt;&gt;</code></a> and <a href=../../basic_json/sax_parse/ ><code>sax_parse</code></a> with <code>strict = false</code> can still read several values from one stream, and the stream can still be used with other <code>std::istream</code> functions after a value has been read.</li> <li>With <a href=../json_precise_stream_position/ ><code>JSON_PRECISE_STREAM_POSITION</code></a>, the stream is still positioned right after a parsed number.</li> <li>Exception messages, including the line, the column, and the last read token, are unchanged.</li> </ul> </div> <div class="admonition note"> <p class=admonition-title>Performance</p> <p>Parsing from a <code>std::ifstream</code> or <code>std::istringstream</code> is typically 1.5 to 2 times as fast as before, and reading many small values from one stream with <code>operator&gt;&gt;</code> 1.4 to 4 times as fast. Parsing from a stream then takes about 1.15 to 1.45 times as long as first reading the whole file into a <code>std::string</code> and parsing that.</p> <p>A stream buffer without a get area (one that only overrides <code>underflow()</code> and <code>uflow()</code> and hands out every character from there) offers nothing to scan in bulk, so it is read one character at a time as before.</p> </div> <div class="admonition note"> <p class=admonition-title>Requirements on the stream buffer</p> <p>The bulk scan relies on the following behavior, which every stream buffer of the standard library and every stream buffer that keeps its input in its get area has:</p> <ul> <li>When <code>sgetc()</code> returns a character while <code>gptr() &lt; egptr()</code>, that character is <code>*gptr()</code>; when <code>sbumpc()</code> returns one, it was at <code>gptr()</code> before the call.</li> <li>Characters in the get area are not changed while they are in the get area.</li> <li><code>underflow()</code> or <code>uflow()</code> either sets up a get area that holds the returned character at <code>gptr()</code> (or at <code>gptr() - 1</code> after <code>uflow()</code>), or leaves the get area empty.</li> </ul> <p>A stream buffer that returns characters from <code>uflow()</code> while leaving unrelated characters in its get area, or that changes the characters in its get area in place, does not meet these requirements. Define the macro to <code>1</code> for such stream buffers.</p> </div> <div class="admonition note"> <p class=admonition-title><abbr title="Application Binary Interface">ABI</abbr> compatibility</p> <p>The value of this macro is encoded in the <a href=../../../features/namespace/ >namespace</a> (tag <code>_dsbs</code>), resulting in distinct symbol names. Translation units compiled with and without it can therefore be linked into the same program without One Definition Rule (<abbr title="One Definition Rule">ODR</abbr>) violations, but they cannot exchange instances of library types.</p> </div> <div class="admonition note"> <p class=admonition-title>Other inputs</p> <p>Strings, string views, vectors, arrays, and pointer or iterator ranges over contiguous memory are scanned in bulk anyway. Reading from a <code class=highlight><span class=kt>FILE</span><span class=o>*</span></code> is not affected by this macro; see <a href=../json_disable_unlocked_file_io/ ><code>JSON_DISABLE_UNLOCKED_FILE_IO</code></a> for that input.</p> </div> <h2 id=examples>Examples<a class=headerlink href=#examples title="Permanent link">&para;</a></h2> <details class=example> <summary>Example: reading values from a stream (default)</summary> <p>The stream is scanned in bulk, and the values are read one after the other:</p> <dLine truncated
<span class=cp>#include</span><span class=w> </span><span class=cpf>&lt;sstream&gt;</span>
<span class=cp>#include</span><span class=w> </span><span class=cpf>&lt;nlohmann/json.hpp&gt;</span>
@@ -31,4 +31,4 @@
<span class=w> </span><span class=n>std</span><span class=o>::</span><span class=n>string</span><span class=w> </span><span class=n>word</span><span class=p>;</span>
<span class=w> </span><span class=n>input</span><span class=w> </span><span class=o>&gt;&gt;</span><span class=w> </span><span class=n>word</span><span class=p>;</span><span class=w> </span><span class=c1>// "rest"</span>
<span class=p>}</span>
</code></pre></div> </details> <h2 id=see-also>See also<a class=headerlink href=#see-also title="Permanent link">&para;</a></h2> <ul> <li><a href=../../basic_json/parse/ ><code>parse</code></a> - deserialize from a compatible input</li> <li><a href=../../operator_gtgt/ ><code>operator&gt;&gt;</code></a> - deserialize from stream</li> <li><a href=../../basic_json/sax_parse/ ><code>sax_parse</code></a> - generate <abbr title="Simple API for XML">SAX</abbr> events</li> <li><a href=../json_precise_stream_position/ ><code>JSON_PRECISE_STREAM_POSITION</code></a> - leave an input stream positioned right after a parsed number</li> <li><a href=../json_disable_unlocked_file_io/ ><code>JSON_DISABLE_UNLOCKED_FILE_IO</code></a> - read a <code>FILE*</code> with the locking stdio functions</li> <li><a href=../../../features/parsing/#input-sources-and-performance>Parsing: input sources and performance</a> - how input sources affect parsing performance</li> <li><a href=../../../features/parsing/large_and_partial_input/ >Large, Streamed, and Partial Input</a> - chunked, concatenated, and very large input</li> </ul> <h2 id=version-history>Version history<a class=headerlink href=#version-history title="Permanent link">&para;</a></h2> <ul> <li>Added in version 3.13.0 <span class=unreleased-version title="Not part of a release yet; the latest release is 3.12.0.">unreleased</span>.</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="October 27, 2026 06:41:42 UTC">October 27, 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> <nav class="md-footer__inner md-grid" aria-label=Footer> <a href=../json_disable_enum_serialization/ class="md-footer__link md-footer__link--prev" aria-label="Previous: JSON_DISABLE_ENUM_SERIALIZATION"> <div class="md-footer__button md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg> </div> <div class=md-footer__title> <span class=md-footer__direction> Previous </span> <div class=md-ellipsis> JSON_DISABLE_ENUM_SERIALIZATION </div> </div> </a> <a href=../json_disable_tuple_reference_conversion/ class="md-footer__link md-footer__link--next" aria-label="Next: JSON_DISABLE_TUPLE_REFERENCE_CONVERSION"> <div class=md-footer__title> <span class=md-footer__direction> Next </span> <div class=md-ellipsis> JSON_DISABLE_TUPLE_REFERENCE_CONVERSION </div> </div> <div class="md-footer__button md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg> </div> </a> </nav> <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-.3Line truncated
</code></pre></div> </details> <h2 id=see-also>See also<a class=headerlink href=#see-also title="Permanent link">&para;</a></h2> <ul> <li><a href=../../basic_json/parse/ ><code>parse</code></a> - deserialize from a compatible input</li> <li><a href=../../operator_gtgt/ ><code>operator&gt;&gt;</code></a> - deserialize from stream</li> <li><a href=../../basic_json/sax_parse/ ><code>sax_parse</code></a> - generate <abbr title="Simple API for XML">SAX</abbr> events</li> <li><a href=../json_precise_stream_position/ ><code>JSON_PRECISE_STREAM_POSITION</code></a> - leave an input stream positioned right after a parsed number</li> <li><a href=../json_disable_unlocked_file_io/ ><code>JSON_DISABLE_UNLOCKED_FILE_IO</code></a> - read a <code>FILE*</code> with the locking stdio functions</li> <li><a href=../../../features/parsing/#input-sources-and-performance>Parsing: input sources and performance</a> - how input sources affect parsing performance</li> <li><a href=../../../features/parsing/large_and_partial_input/ >Large, Streamed, and Partial Input</a> - chunked, concatenated, and very large input</li> </ul> <h2 id=version-history>Version history<a class=headerlink href=#version-history title="Permanent link">&para;</a></h2> <ul> <li>Added in version 3.13.0 <span class=unreleased-version title="Not part of a release yet; the latest release is 3.12.0.">unreleased</span>.</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="November 10, 2026 06:08:44 UTC">November 10, 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> <nav class="md-footer__inner md-grid" aria-label=Footer> <a href=../json_disable_enum_serialization/ class="md-footer__link md-footer__link--prev" aria-label="Previous: JSON_DISABLE_ENUM_SERIALIZATION"> <div class="md-footer__button md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg> </div> <div class=md-footer__title> <span class=md-footer__direction> Previous </span> <div class=md-ellipsis> JSON_DISABLE_ENUM_SERIALIZATION </div> </div> </a> <a href=../json_disable_tuple_reference_conversion/ class="md-footer__link md-footer__link--next" aria-label="Next: JSON_DISABLE_TUPLE_REFERENCE_CONVERSION"> <div class=md-footer__title> <span class=md-footer__direction> Next </span> <div class=md-ellipsis> JSON_DISABLE_TUPLE_REFERENCE_CONVERSION </div> </div> <div class="md-footer__button md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg> </div> </a> </nav> <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-Line truncated
@@ -32,7 +32,7 @@ The parser only reads characters that it would also have read one at a time, and
Performance
Parsing from a `std::ifstream` or `std::istringstream` is typically 1.5 to 2 times as fast as before, and reading many small values from one stream with `operator>>` 1.4 to 4 times as fast. Parsing from a stream is then within about 10 to 20 % of first reading the whole file into a `std::string` and parsing that.
Parsing from a `std::ifstream` or `std::istringstream` is typically 1.5 to 2 times as fast as before, and reading many small values from one stream with `operator>>` 1.4 to 4 times as fast. Parsing from a stream then takes about 1.15 to 1.45 times as long as first reading the whole file into a `std::string` and parsing that.
A stream buffer without a get area (one that only overrides `underflow()` and `uflow()` and hands out every character from there) offers nothing to scan in bulk, so it is read one character at a time as before.