json/features/types/index.html

39 lines
93 KiB
HTML
Raw Normal View History

<!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/features/types/ rel=canonical><link rel=icon href=../../assets/images/favicon.png><meta name=generator content="mkdocs-1.4.2, mkdocs-material-8.5.10"><title>Types - JSON for Modern C++</title><link rel=stylesheet href=../../assets/stylesheets/main.975780f9.min.css><link rel=stylesheet href=../../assets/stylesheets/palette.2505c338.min.css><link rel=preconnect href=https://fonts.gstatic.com crossorigin><link rel=stylesheet href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback"><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> <script>var palette=__md_get("__palette");if(palette&&"object"==typeof palette.color)for(var key of Object.keys(palette.color))document.body.setAttribute("data-md-color-"+key,palette.color[key])</script> <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=#types 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.54Z"/></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 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2Z"/></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> Types </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_1> <label class="md-header__button md-icon" title="Switch to dark mode" for=__palette_2 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 12 20 8.69Z"/></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_2> <label class="md-header__button md-icon" title="Switch to light mode" for=__palette_1 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 12c0-2.42-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.69
<span class=w> </span><span class=k>template</span><span class=o>&lt;</span><span class=k>typename</span><span class=w> </span><span class=nc>U</span><span class=p>,</span><span class=w> </span><span class=k>typename</span><span class=w> </span><span class=nc>V</span><span class=p>,</span><span class=w> </span><span class=k>typename</span><span class=p>...</span><span class=w> </span><span class=n>Args</span><span class=o>&gt;</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>ObjectType</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>std</span><span class=o>::</span><span class=n>map</span><span class=p>,</span><span class=w></span>
<span class=w> </span><span class=k>template</span><span class=o>&lt;</span><span class=k>typename</span><span class=w> </span><span class=nc>U</span><span class=p>,</span><span class=w> </span><span class=k>typename</span><span class=p>...</span><span class=w> </span><span class=n>Args</span><span class=o>&gt;</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>ArrayType</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>std</span><span class=o>::</span><span class=n>vector</span><span class=p>,</span><span class=w></span>
<span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>StringType</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>std</span><span class=o>::</span><span class=n>string</span><span class=p>,</span><span class=w></span>
<span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>BooleanType</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=kt>bool</span><span class=p>,</span><span class=w></span>
<span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>NumberIntegerType</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>int64_t</span><span class=p>,</span><span class=w></span>
<span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>NumberUnsignedType</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>uint64_t</span><span class=p>,</span><span class=w></span>
<span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>NumberFloatType</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=kt>double</span><span class=p>,</span><span class=w></span>
<span class=w> </span><span class=k>template</span><span class=o>&lt;</span><span class=k>typename</span><span class=w> </span><span class=nc>U</span><span class=o>&gt;</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>AllocatorType</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>std</span><span class=o>::</span><span class=n>allocator</span><span class=p>,</span><span class=w></span>
<span class=w> </span><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=p>,</span><span class=w> </span><span class=k>typename</span><span class=w> </span><span class=nc>SFINAE</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=kt>void</span><span class=o>&gt;</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>JSONSerializer</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>adl_serializer</span><span class=p>,</span><span class=w></span>
<span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>BinaryType</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>std</span><span class=o>::</span><span class=n>vector</span><span class=o>&lt;</span><span class=n>std</span><span class=o>::</span><span class=kt>uint8_t</span><span class=o>&gt;</span><span class=w></span>
<span class=o>&gt;</span><span class=w></span>
<span class=k>class</span><span class=w> </span><span class=nc>basic_json</span><span class=p>;</span><span class=w></span>
</code></pre></div> <p>Type <code>json</code> is an alias for <code>basic_json&lt;&gt;</code> and uses the default types.</p> <p>From the template arguments, the following types are derived:</p> <div class=highlight><pre><span></span><code><span class=k>using</span><span class=w> </span><span class=n>object_comparator_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=n>less</span><span class=o>&lt;&gt;</span><span class=p>;</span><span class=w></span>
<span class=k>using</span><span class=w> </span><span class=n>object_t</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>ObjectType</span><span class=o>&lt;</span><span class=n>StringType</span><span class=p>,</span><span class=w> </span><span class=n>basic_json</span><span class=p>,</span><span class=w> </span><span class=n>object_comparator_t</span><span class=p>,</span><span class=w></span>
<span class=w> </span><span class=n>AllocatorType</span><span class=o>&lt;</span><span class=n>std</span><span class=o>::</span><span class=n>pair</span><span class=o>&lt;</span><span class=k>const</span><span class=w> </span><span class=n>StringType</span><span class=p>,</span><span class=w> </span><span class=n>basic_json</span><span class=o>&gt;&gt;&gt;</span><span class=p>;</span><span class=w></span>
<span class=k>using</span><span class=w> </span><span class=n>array_t</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>ArrayType</span><span class=o>&lt;</span><span class=n>basic_json</span><span class=p>,</span><span class=w> </span><span class=n>AllocatorType</span><span class=o>&lt;</span><span class=n>basic_json</span><span class=o>&gt;&gt;</span><span class=p>;</span><span class=w></span>
<span class=k>using</span><span class=w> </span><span class=n>string_t</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>StringType</span><span class=p>;</span><span class=w></span>
<span class=k>using</span><span class=w> </span><span class=n>boolean_t</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>BooleanType</span><span class=p>;</span><span class=w></span>
<span class=k>using</span><span class=w> </span><span class=n>number_integer_t</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>NumberIntegerType</span><span class=p>;</span><span class=w></span>
<span class=k>using</span><span class=w> </span><span class=n>number_unsigned_t</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>NumberUnsignedType</span><span class=p>;</span><span class=w></span>
<span class=k>using</span><span class=w> </span><span class=n>number_float_t</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>NumberFloatType</span><span class=p>;</span><span class=w></span>
<span class=k>using</span><span class=w> </span><span class=n>binary_t</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>nlohmann</span><span class=o>::</span><span class=n>byte_container_with_subtype</span><span class=o>&lt;</span><span class=n>BinaryType</span><span class=o>&gt;</span><span class=p>;</span><span class=w></span>
</code></pre></div> <h2 id=objects>Objects<a class=headerlink href=#objects title="Permanent link">&para;</a></h2> <p><a href=https://tools.ietf.org/html/rfc8259>RFC 8259</a> describes JSON objects as follows:</p> <blockquote> <p>An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array.</p> </blockquote> <h3 id=default-type>Default type<a class=headerlink href=#default-type title="Permanent link">&para;</a></h3> <p>With the default values for <em>ObjectType</em> (<code>std::map</code>), <em>StringType</em> (<code>std::string</code>), and <em>AllocatorType</em> (<code>std::allocator</code>), the default value for <code>object_t</code> is:</p> <div class=highlight><pre><span></span><code><span class=n>std</span><span class=o>::</span><span class=n>map</span><span class=o>&lt;</span><span class=w></span>
<span class=w> </span><span class=n>std</span><span class=o>::</span><span class=n>string</span><span class=p>,</span><span class=w> </span><span class=c1>// key_type</span>
<span class=w> </span><span class=n>basic_json</span><span class=p>,</span><span class=w> </span><span class=c1>// value_type</span>
<span class=w> </span><span class=n>std</span><span class=o>::</span><span class=n>less</span><span class=o>&lt;&gt;</span><span class=p>,</span><span class=w> </span><span class=c1>// key_compare</span>
<span class=w> </span><span class=n>std</span><span class=o>::</span><span class=n>allocator</span><span class=o>&lt;</span><span class=n>std</span><span class=o>::</span><span class=n>pair</span><span class=o>&lt;</span><span class=k>const</span><span class=w> </span><span class=n>std</span><span class=o>::</span><span class=n>string</span><span class=p>,</span><span class=w> </span><span class=n>basic_json</span><span class=o>&gt;&gt;</span><span class=w> </span><span class=c1>// allocator_type</span>
<span class=o>&gt;</span><span class=w></span>
</code></pre></div> <h3 id=behavior>Behavior<a class=headerlink href=#behavior title="Permanent link">&para;</a></h3> <p>The choice of <code>object_t</code> influences the behavior of the JSON class. With the default type, objects have the following behavior:</p> <ul> <li>When all names are unique, objects will be interoperable in the sense that all software implementations receiving that object will agree on the name-value mappings.</li> <li>When the names within an object are not unique, it is unspecified which one of the values for a given key will be chosen. For instance, <code class=highlight><span class=p>{</span><span class=nt>&quot;key&quot;</span><span class=p>:</span><span class=w> </span><span class=mi>2</span><span class=p>,</span><span class=w> </span><span class=nt>&quot;key&quot;</span><span class=p>:</span><span class=w> </span><span class=mi>1</span><span class=p>}</span><span class=w></span></code> could be equal to either <code class=highlight><span class=p>{</span><span class=nt>&quot;key&quot;</span><span class=p>:</span><span class=w> </span><span class=mi>1</span><span class=p>}</span><span class=w></span></code> or <code class=highlight><span class=p>{</span><span class=nt>&quot;key&quot;</span><span class=p>:</span><span class=w> </span><span class=mi>2</span><span class=p>}</span><span class=w></span></code>.</li> <li>Internally, name/value pairs are stored in lexicographical order of the names. Objects will also be serialized (see <code>dump</code>) in this order. For instance, both <code class=highlight><span class=p>{</span><span class=nt>&quot;b&quot;</span><span class=p>:</span><span class=w> </span><span class=mi>1</span><span class=p>,</span><span class=w> </span><span class=nt>&quot;a&quot;</span><span class=p>:</span><span class=w> </span><span class=mi>2</span><span class=p>}</span><span class=w></span></code> and <code class=highlight><span class=p>{</span><span class=nt>&quot;a&quot;</span><span class=p>:</span><span class=w> </span><span class=mi>2</span><span class=p>,</span><span class=w> </span><span class=nt>&quot;b&quot;</span><span class=p>:</span><span class=w> </span><span class=mi>1</span><span class=p>}</span><span class=w></span></code> will be stored and serialized as <code class=highlight><span class=p>{</span><span class=nt>&quot;a&quot;</span><span class=p>:</span><span class=w> </span><span class=mi>2</span><span class=p>,</span><span class=w> </span><span class=nt>&quot;b&quot;</span><span class=p>:</span><span class=w> </span><span class=mi>1</span><span class=p>}</span><span class=w></span></code>.</li> <li>When comparing objects, the order of the name/value pairs is irrelevant. This makes objects interoperable in the sense that they will not be affected by these differences. For instance, <code class=highlight><span class=p>{</span><span class=nt>&quot;b&quot;</span><span class=p>:</span><span class=w> </span><span class=mi>1</span><span class=p>,</span><span class=w> </span><span class=nt>&quot;a&quot;</span><span class=p>:</span><span class=w> </span><span class=mi>2</span><span class=p>}</span><span class=w></span></code> and <code class=highlight><span class=p>{</span><span class=nt>&quot;a&quot;</span><span class=p>:</span><span class=w> </span><span class=mi>2</span><span class=p>,</span><span class=w> </span><span class=nt>&quot;b&quot;</span><span class=p>:</span><span class=w> </span><span class=mi>1</span><span class=p>}</span><span class=w></span></code> will be treated as equal.</li> </ul> <h3 id=key-order>Key order<a class=headerlink href=#key-order title="Permanent link">&para;</a></h3> <p>The order name/value pairs are added to the object is <em>not</em> preserved by the library. Therefore, iterating an object may return name/value pairs in a different order than they were originally stored. In fact, keys will be traversed in alphabetical order as <code>std::map</code> with <code>std::less</code> is used by default. Please note this behavior conforms to <a href=https://tools.ietf.org/html/rfc8259>RFC 8259</a>, because any order implements the spec
<span class=w> </span><span class=n>basic_json</span><span class=p>,</span><span class=w> </span><span class=c1>// value_type</span>
<span class=w> </span><span class=n>std</span><span class=o>::</span><span class=n>allocator</span><span class=o>&lt;</span><span class=n>basic_json</span><span class=o>&gt;</span><span class=w> </span><span class=c1>// allocator_type</span>
<span class=o>&gt;</span><span class=w></span>
</code></pre></div> <h3 id=limits_1>Limits<a class=headerlink href=#limits_1 title="Permanent link">&para;</a></h3> <p><a href=https://tools.ietf.org/html/rfc8259>RFC 8259</a> specifies:</p> <blockquote> <p>An implementation may set limits on the maximum depth of nesting.</p> </blockquote> <p>In this class, the array's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the <code>max_size</code> function of a JSON array.</p> <h3 id=storage_2>Storage<a class=headerlink href=#storage_2 title="Permanent link">&para;</a></h3> <p>Arrays are stored as pointers in a <code>basic_json</code> type. That is, for any access to array values, a pointer of type <code>array_t*</code> must be dereferenced.</p> <h2 id=strings>Strings<a class=headerlink href=#strings title="Permanent link">&para;</a></h2> <p><a href=https://tools.ietf.org/html/rfc8259>RFC 8259</a> describes JSON strings as follows:</p> <blockquote> <p>A string is a sequence of zero or more Unicode characters.</p> </blockquote> <p>Unicode values are split by the JSON class into byte-sized characters during deserialization.</p> <h3 id=default-type_2>Default type<a class=headerlink href=#default-type_2 title="Permanent link">&para;</a></h3> <p>With the default values for <em>StringType</em> (<code>std::string</code>), the default value for <code>string_t</code> is <code class=highlight><span class=n>std</span><span class=o>::</span><span class=n>string</span><span class=w></span></code>.</p> <h3 id=encoding>Encoding<a class=headerlink href=#encoding title="Permanent link">&para;</a></h3> <p>Strings are stored in UTF-8 encoding. Therefore, functions like <code>std::string::size()</code> or <code>std::string::length()</code> return the number of <strong>bytes</strong> in the string rather than the number of characters or glyphs.</p> <h3 id=string-comparison>String comparison<a class=headerlink href=#string-comparison title="Permanent link">&para;</a></h3> <p><a href=https://tools.ietf.org/html/rfc8259>RFC 8259</a> states:</p> <blockquote> <p>Software implementations are typically required to test names of object members for equality. Implementations that transform the textual representation into sequences of Unicode code units and then perform the comparison numerically, code unit by code unit, are interoperable in the sense that implementations will agree in all cases on equality or inequality of two strings. For example, implementations that compare strings with escaped characters unconverted may incorrectly find that <code>"a\\b"</code> and <code>"a\u005Cb"</code> are not equal.</p> </blockquote> <p>This implementation is interoperable as it does compare strings code unit by code unit.</p> <h3 id=storage_3>Storage<a class=headerlink href=#storage_3 title="Permanent link">&para;</a></h3> <p>String values are stored as pointers in a <code>basic_json</code> type. That is, for any access to string values, a pointer of type <code>string_t*</code> must be dereferenced.</p> <h2 id=booleans>Booleans<a class=headerlink href=#booleans title="Permanent link">&para;</a></h2> <p><a href=https://tools.ietf.org/html/rfc8259>RFC 8259</a> implicitly describes a boolean as a type which differentiates the two literals <code>true</code> and <code>false</code>.</p> <h3 id=default-type_3>Default type<a class=headerlink href=#default-type_3 title="Permanent link">&para;</a></h3> <p>With the default values for <em>BooleanType</em> (<code class=highlight><span class=kt>bool</span><span class=w></span></code>), the default value for <code>boolean_t</code> is <code class=highlight><span class=kt>bool</span><span class=w></span></code>.</p> <h3 id=storage_4>Storage<a class=headerlink href=#storage_4 title="Permanent link">&para;</a></h3> <p>Boolean values are stored directly inside a <code>basic_json</code> type.</p> <h2 id=numbers>Numbers<a class=headerlink href=#numbers title="Permanent link">&para;</a></h2> <p>See the <a href=number_handling/ >number handling</a> a