Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
6be974c
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
cca70eb
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
f449267
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
320547c
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
6466528
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
6d6fd22
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
f5284bc
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
77c529d
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
ba86f6a
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
c6b90c9
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
08df0df
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
c46595d
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
b83996a
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
5b3673e
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
9304121
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
8b6bc0b
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
936a38c
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
24edc61
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
9f94c73
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
f9d0d1c
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
9969321
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
305e5b8
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
74c501e
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
fe0a6db
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
b3b811d
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
f0f1ddd
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
bac9abd
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
4170e87
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
5801ea1
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
b2a4658
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
00304f2
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
f946e44
Added translation using Weblate (Chinese (Simplified Han script))
Apr 22, 2026
5d8d7b2
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
ad270c8
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
5fdbb04
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
f8ec730
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
816a73a
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
bcbffea
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
e5ec032
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
cc81a66
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
a048efa
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
8ff1a82
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
557f1f0
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
4c846b6
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
dcc4b35
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
3867d15
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
23ad003
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
bbf4d49
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
c2d3b8f
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
fbc1c1f
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
0b6d84c
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
3db17b7
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
198912b
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
7de8b82
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
c2e29ec
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
be660c7
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
8de4b0a
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
2fd7fac
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
acf8373
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
951a6a4
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
3de6bf3
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
40a213e
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
070bd5a
Update translation files
weblate Apr 23, 2026
fb32ada
Update translation files
weblate Apr 23, 2026
fcb4049
Update translation files
weblate Apr 23, 2026
ed9e3c8
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
dcc902e
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
bb47117
Translated using Weblate (Chinese (Simplified Han script))
Apr 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions doc/library-detail_zh_Hans.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
https://www.boost.org/doc/libs/release/libs/json/[image:https://raw.githubusercontent.com/CPPAlliance/json/master/doc/images/repo-logo-3.png[Boost.JSON]]

[width="100%", cols="12%,43%,45%", options="header"]
|===
|分支 |https://github.com/boostorg/json/tree/master[`master`]
|https://github.com/boostorg/json/tree/develop[`develop`]
|https://azure.microsoft.com/en-us/services/devops/pipelines/[Azure]
|https://vinniefalco.visualstudio.com/json/_build/latest?definitionId=5&branchName=master[image:https://img.shields.io/azure-devops/build/vinniefalco/2571d415-8cc8-4120-a762-c03a8eda0659/8/master[构建状态]]
|https://vinniefalco.visualstudio.com/json/_build/latest?definitionId=8&branchName=develop[image:https://img.shields.io/azure-devops/build/vinniefalco/2571d415-8cc8-4120-a762-c03a8eda0659/8/develop[构建状态]]

|文档
|https://www.boost.org/doc/libs/master/libs/json/[image:https://img.shields.io/badge/docs-master-brightgreen.svg[文档]]
|https://www.boost.org/doc/libs/develop/libs/json/[image:https://img.shields.io/badge/docs-develop-brightgreen.svg[文档]]

|https://drone.io/[Drone]
|https://drone.cpp.al/boostorg/json[image:https://drone.cpp.al/api/badges/boostorg/json/status.svg?ref=refs/heads/master[构建状态]]
|https://drone.cpp.al/boostorg/json[image:https://drone.cpp.al/api/badges/boostorg/json/status.svg?ref=refs/heads/develop[构建状态]]

|测试矩阵
|http://www.boost.org/development/tests/master/developer/json.html[image:https://img.shields.io/badge/matrix-master-brightgreen.svg[测试矩阵]]
|http://www.boost.org/development/tests/develop/developer/json.html[image:https://img.shields.io/badge/matrix-develop-brightgreen.svg[测试矩阵]]

|模糊测试 |—
|https://github.com/boostorg/json/actions?query=workflow%3Afuzz+branch%3Adevelop[image:https://github.com/boostorg/json/workflows/fuzz/badge.svg?branch=develop[模糊测试]]

|https://ci.appveyor.com/[Appveyor]
|https://ci.appveyor.com/project/vinniefalco/cppalliance-json/branch/master[image:https://ci.appveyor.com/api/projects/status/8csswcnmfm798203?branch=master&svg=true[构建状态]]
|https://ci.appveyor.com/project/vinniefalco/cppalliance-json/branch/develop[image:https://ci.appveyor.com/api/projects/status/8csswcnmfm798203?branch=develop&svg=true[构建状态]]

|https://codecov.io[codecov.io]
|https://codecov.io/gh/boostorg/json/branch/master[image:https://codecov.io/gh/boostorg/json/branch/master/graph/badge.svg[codecov]]
|https://codecov.io/gh/boostorg/json/branch/develop[image:https://codecov.io/gh/boostorg/json/branch/develop/graph/badge.svg[codecov]]
|===

== Boost.JSON

=== 概述

Boost.JSON 是一个可移植的 C++ 库,提供了实现 [JavaScript Object Notation](https://json.org/)(简称 “JSON”)的容器和算法,这是一种轻量级的数据交换格式。该格式易于人类读写,也易于机器解析和生成。该格式基于 JavaScript 编程语言的一个子集([ECMA-262 标准](https://www.ecma-international.org/ecma-262/10.0/index.html)),目前已在 [RFC 8259](https://datatracker.ietf.org/doc/html/rfc8259) 中标准化。JSON 是一种独立于语言但使用 C 语言家族(包括 C、C++、C#、Java、JavaScript、Perl、Python 等)程序员熟悉的约定的文本格式。这些特性使 JSON 成为理想的数据交换语言。

该库专注于一个常见且广泛使用的场景:解析和序列化到一个名为 `value` 的容器,或从中进行解析和序列化(该容器用于存储 JSON 类型)。任何构建的 `value` 都可以被序列化后再反序列化,并保证结果与原始值相等。使用该库生成的任何 JSON 输出,均可被大多数主流编程语言中的常见 JSON 实现正确读取。

`value` 容器被设计为一种适合作为公共接口和库中词汇类型的组件,便于组合使用。该库将可表示的数据类型限制在绝大多数 JSON 实现(尤其是 JavaScript)普遍接受的范围内。解析器和序列化器均具备高性能,其基准性能达到或超过了同类优秀库的水平。对分配器的支持非常完善。使用这些类型的代码将易于理解、灵活且高效。

Boost.JSON 提供以下特性:

* 快速编译
* 仅需 C++11
* 高性能流式解析器和序列化器
* 对象的常量时间键查找
* 允许非标准 JSON 的选项
* 提供易于使用且安全的现代 API,并支持分配器
* 可选的纯头文件方式,无需链接库

若要获取完整文档请访问以下链接: https://boost.org/libs/json

=== 要求

* 仅需 C++11
* 可链接预构建的静态或动态 Boost 库,也可使用纯头文件方式(见下文)。
* Supports -fno-exceptions(可自动检测)

该库在其接口中大量依赖以下众所周知的 C++ 类型(以下称为 _standard types_):

* `string_view`
* `memory_resource`, `polymorphic_allocator`
* `error_category`, `error_code`, `error_condition`, `system_error`

==== 纯头文件

要使用纯头文件模式(即无需将程序链接到静态或动态的 Boost.JSON 库),只需在项目中恰好一个新建或现有源文件中添加以下行。

....
#include <boost/json/src.hpp>
....

MSVC 用户还必须定义宏 `BOOST_JSON_NO_LIB` ,以禁用自动链接。

==== 嵌入式

Boost.JSON 在嵌入式设备上表现优异。该库使用局部栈缓冲区来提升某些操作的性能。在 Intel 平台上,这些缓冲区较大(4KB),而在非 Intel 平台上则较小(256 字节)。若要在嵌入式应用中调整栈缓冲区的大小,请在构建库或包含函数定义时定义以下宏:

....
#define BOOST_JSON_STACK_BUFFER_SIZE 1024
#include <boost/json/src.hpp>
....

==== 支持的编译器

Boost.JSON 已在以下编译器上进行过测试:

* clang: 3.5, 3.6, 3.7, 3.8, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
* gcc: 4.8, 4.9, 5, 6, 7, 8, 9, 10, 11, 12
* msvc: 14.0, 14.1, 14.2, 14.3

==== 支持的 JSON 文本

该库要求输入文本使用 UTF-8 编码,这是 [RFC](https://datatracker.ietf.org/doc/html/rfc8259#section-8.1) 对系统间交换的所有 JSON 所规定的强制要求。同样,该库生成的文本也是有效的 UTF-8。

RFC 不允许字节顺序标记(BOM)出现在 JSON 文本中,因此该库将 BOM 视为语法错误。

该库支持多种流行的 JSON 扩展,但这些扩展必须显式启用。

==== Visual Studio 解决方案

....
cmake -G "Visual Studio 16 2019" -A Win32 -B bin -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/msvc.cmake
cmake -G "Visual Studio 16 2019" -A x64 -B bin64 -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/msvc.cmake
....

=== 质量保证

该库的开发基础设施包括以下每次提交的分析:

* 覆盖率报告
* 基准性能比较
* 在 Drone.io、Azure Pipelines 和 AppVeyor 上进行编译与测试
* 使用 clang-llvm 和机器学习的模糊测试

=== 许可证

根据 Boost 软件许可协议 1.0 版分发。(详见随附文件 LICENSE_1_0.txt 文件或访问 https://www.boost.org/LICENSE_1_0.txt )
89 changes: 89 additions & 0 deletions doc/pages/allocators/background_zh_Hans.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
////
Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
Copyright (c) 2025 Dmitry Arkhipov (grisumbras@yandex.ru)

Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

Official repository: https://github.com/boostorg/json
////

= 背景
C++中分配器的第一个版本定义了名为{req_Allocator}的要求,并将每个标准容器设计为以分配器类型为模板参数的类模板。例如,以下是 {std_vector} 的声明:

[source]
----
include::../../../test/doc_background.cpp[tag=doc_background_1,indent=0]
----

标准分配器是{req_DefaultConstructible}。为支持有状态分配器,容器提供了额外的构造函数重载,接受一个分配器实例参数。

[source]
----
include::../../../test/doc_background.cpp[tag=doc_background_2,indent=0]
----

尽管该机制能够正常工作,但仍存在一些可用性问题:

* 容器必须是一个类模板。
* 在元素类型上参数化分配器的方式显得笨拙。
* 分配器特征机制(尤其是 POCCA 和 POCMA)复杂且容易出错。

使用多种分配器类型的基于分配器的程序会引发更多的函数模板实例化,且通常编译速度更慢,因为类模板的函数定义必须在所有调用点可见。

== 多态分配器

{cpp}17通过引入一个名为 {ref_memory_resource} 的抽象接口来表示底层分配操作,从而改进分配器模型。该接口未在元素类型上参数化,且无特征:

[source]
----
include::../../../test/doc_background.cpp[tag=doc_background_3,indent=0]
----

类模板{ref_polymorphic_allocator}包装了{ref_memory_resource}指针,并满足{req_Allocator}要求,使其可在需要分配器的地方使用。标准库为使用多态分配器的标准容器提供了类型别名:

[source]
----
include::../../../test/doc_background.cpp[tag=doc_background_4,indent=0]
----

多态分配器通过一个指向内存资源的指针进行构造:

[source]
----
include::../../../test/doc_background.cpp[tag=doc_background_5,indent=0]
----

内存资源通过指针传递;所有权不发生转移。调用方需负责确保该内存资源的生命周期持续到所有使用它的容器都离开作用域为止,否则行为未定义。在某些场景下,这种模型是合适的,例如以下示例中使用了一个基于局部栈缓冲区构造的单调内存资源:

[source]
----
include::../../../test/doc_background.cpp[tag=doc_background_6,indent=0]
----

然而,有时需要共享所有权,即内存资源的生命周期应自动延长。例如,若某个库希望返回一个容器,该容器拥有该库自定义内存资源的实例,如下所示:

[source]
----
include::../../../test/doc_background.cpp[tag=doc_background_7,indent=0]
----

可通过声明容器使用自定义分配器(可能使用`std::shared_ptr&lt; std::pmr::memory_resource &gt;`作为数据成员)来解决此问题。这会阻碍库的组合;每个库都会导出各自独特且互不兼容的容器类型。原始内存资源指针也容易被误用:

[source]
----
include::../../../test/doc_background.cpp[tag=doc_background_8,indent=0]
----

针对此问题的变通方案往往比问题本身更糟糕。该库可以返回一个包含 vector 和`std::unique_ptr<std::pmr::memory_resource>`的pair,必须由调用方自行管理。或者,该库也可以修改其函数签名,接受调用方提供的{ref_memory_resource}``*``,同时将所需的内存资源(如上文的`my_resource`)公开。

== 问题陈述

我们希望采用一种使用单一类型`T`的分配器模型,该模型具有以下特性:

* `T`不是类模板
* `T`引用一个 {ref_memory_resource}
* `T`同时支持引用语义和共享所有权
* `T`能与已使用`std::pmr`的代码互操作

Boost.JSON通过引入一个名为<<ref_storage_ptr>> 的新型智能指针解决此问题,该指针基于{cpp}17的内存分配接口构建,实现了上述目标。因此,使用该类型的库更易于组合,并能获得更快的编译速度,因为使用该类型的容器的成员函数可以定义在类外(out-of-line)。
22 changes: 22 additions & 0 deletions doc/pages/allocators/overview_zh_Hans.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
////
Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
Copyright (c) 2025 Dmitry Arkhipov (grisumbras@yandex.ru)

Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

Official repository: https://github.com/boostorg/json
////

= 分配器

本文将首先讨论C++标准中使用的各种分配器模型,随后介绍本库所采用的模型及其优势,最后说明该库如何与使用多态分配器的现有代码进行互操作。

:leveloffset: +1

include::background.adoc[]
include::storage_ptr.adoc[]
include::uses_allocator.adoc[]

:leveloffset: -1
149 changes: 149 additions & 0 deletions doc/pages/allocators/storage_ptr_zh_Hans.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
////
Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
Copyright (c) 2025 Dmitry Arkhipov (grisumbras@yandex.ru)

Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

Official repository: https://github.com/boostorg/json
////

= `storage_ptr`
本库中的可变长度容器均使用动态分配的内存来存储其内容。调用方可通过在特定构造函数和函数参数列表中指定 <<ref_storage_ptr>> ,以控制所使用的内存分配策略。<<ref_storage_ptr>> 具有以下特性:

* 存储指针始终指向一个有效的、类型擦除后的 {ref_memory_resource}。

* 默认构造的存储指针引用 <<default_memory_resource,default resource>>(默认资源),这是一个由实现定义的实例,始终使用等效于全局 operator new 和 operator delete 的方式。

* 从 {ref_memory_resource} 或 {ref_polymorphic_allocator} 构造的存储指针不获取所有权;调用方负责确保资源的生命周期持续到不再被引用为止。

* 通过 <<ref_make_shared_resource>> 获取的存储指针会获得对内存资源的共享所有权;该资源的生命周期将延长,直至所有该存储指针的副本均被销毁。

* 存储指针在对资源进行类型擦除之前会记录 <<ref_is_deallocate_trivial>> 的值,从而允许在运行时查询该值。

以下是使用该库时所有与分配相关的类型和函数列表:

.函数与类型
|===
|Name|描述

| <<ref_get_null_resource>>
| 返回一个指向内存资源实例的指针,该实例在分配内存时总是抛出异常。此机制用于确保解析或容器操作不会进行动态内存分配,从而维持该不变性。

| <<ref_is_deallocate_trivial>>
| 一个自定义点,允许内存资源类型表明其 deallocate 调用是平凡的。

| <<ref_make_shared_resource>>
| 一个返回智能指针的函数,该智能指针对新分配的内存资源具有共享所有权。

| {ref_memory_resource}
| 表示分配器的抽象基类。

| <<ref_monotonic_resource>>
| 一种内存资源,用于分配大块内存,且其 deallocate 函数是平凡的。所分配的内存不会被释放,直到该资源被销毁,因此在解析场景下速度很快,但不适合执行修改操作。

| {ref_polymorphic_allocator}
| 一个 {req_Allocator},它通过引用 {ref_memory_resource} 执行内存分配。

| <<ref_static_resource>>
| 一种使用调用方提供的单一缓冲区的内存资源,不进行任何动态分配。该资源在解析时速度很快,但不适合执行修改操作。

| <<ref_storage_ptr>>
| 一种用于管理和访问 {ref_memory_resource} 的智能指针。
|===

== 默认内存资源
默认内存资源使用全局 `operator new` 和 `operator delete` 来进行内存分配。该资源不采用引用计数,且其 deallocate 函数是非平凡的。所有默认构造的 <<ref_storage_ptr>> 对象均引用同一个内存资源:

[source]
----
include::../../../test/doc_storage_ptr.cpp[tag=doc_storage_ptr_1,indent=0]
----

默认构造的库容器使用默认内存资源:

[source]
----
include::../../../test/doc_storage_ptr.cpp[tag=doc_storage_ptr_2,indent=0]
----

默认内存资源适用于一般用途。它在解析时提供合理的性能,在修改容器内容时则具有保守的内存使用特性。

[NOTE]
该内存资源不保证与 `boost::container::pmr::get_default_resource` 的返回结果相同,也无法通过 `boost::container::pmr::set_default_resource` 进行更改。

== 单调资源
考虑解析过程中的内存分配模式:当遇到数组、对象或字符串时,解析器会将其元素累积在临时存储区中。当所有元素都已知后,在构造值时会向内存资源发起一次内存分配请求。因此,解析过程仅在容器最终大小确定时进行一次分配和构造,不会发生内存重分配;也就是说,内存缓冲区无需通过分配更大的新缓冲区并释放旧缓冲区的方式来扩容。

<<ref_monotonic_resource>> 通过在内部分配逐渐增大的全局内存块,并将这些块切分为更小的部分以满足分配请求,从而优化了该内存分配模式。它具有平凡的 deallocate 函数,实际上不会释放内存,直到该资源被销毁。因此,它非常适合用于解析 JSON 后仅检查结果值而不对其进行修改的场景。

在调用 <<ref_parse>> 时,可按如下方式指定构造值所使用的内存资源:

[source]
----
include::../../../test/doc_storage_ptr.cpp[tag=doc_storage_ptr_3,indent=0]
----

或者,可按如下方式解析到一个对内存资源具有共享所有权的值:

[source]
----
include::../../../test/doc_storage_ptr.cpp[tag=doc_storage_ptr_4,indent=0]
----

单调资源在构造时可选择性地指定一个初始缓冲区,优先使用该缓冲区,之后才会转而使用堆内存。这使得调用方可以利用栈空间,避免对大多数 JSON 解析进行动态分配;仅当输入的 JSON 大于平均水平时,才会退回到从堆中进行动态分配,如下所示:

[source]
----
include::../../../test/doc_storage_ptr.cpp[tag=doc_storage_ptr_5,indent=0]
----

== 静态资源
<<ref_static_resource>> 由调用方提供的缓冲区构造而成,并从该缓冲区满足所有内存分配请求。一旦缓冲区耗尽,后续的分配调用将抛出 `std::bad_alloc` 异常。该资源提供一个简单的不变式:永不执行动态堆分配。

要使用该资源,请用一个局部缓冲区对其进行构造:

[source]
----
include::../../../test/doc_storage_ptr.cpp[tag=doc_storage_ptr_6,indent=0]
----

== 空资源
函数 <<ref_get_null_resource>> 返回一个全局的空资源实例。该资源提供一个简单的不变式:所有内存分配调用都会抛出 `std::bad_alloc` 异常。通过使用空资源实例,可确保解析过程绝不会进行堆内存分配。这一点将在后文进一步详细说明。

== 分配器传播
容器 <<ref_array>>, <<ref_object>> 和 <<ref_value>> 在构造时所使用的内存资源会自动传播给其子元素:

[source]
----
include::../../../test/doc_storage_ptr.cpp[tag=doc_storage_ptr_7,indent=0]
----

这种传播是递归进行的:嵌套容器中的所有子容器都会获得相同的内存资源。一旦容器被构造,其内存资源就永远无法更改。

== 资源生命周期
需要注意的是,<<ref_storage_ptr>> 同时支持共享所有权和引用生命周期模型。从内存资源指针构造时不会转移所有权:

[source]
----
include::../../../test/doc_storage_ptr.cpp[tag=doc_storage_ptr_8,indent=0]
----

以这种方式使用内存资源时(包括从 {ref_polymorphic_allocator} 构造存储指针或容器的情况),调用方必须确保资源的生命周期延长至不再被任何变量引用为止;否则,可能会出现未定义行为。

通过函数 <<ref_make_shared_resource>> 可实现共享所有权,该函数会动态分配内存以创建一个新的、带引用计数的内存资源,并将其以 <<ref_storage_ptr>> 的形式返回:

[source]
----
include::../../../test/doc_storage_ptr.cpp[tag=doc_storage_ptr_9,indent=0]
----

当存储指针以这种方式构造时,其所引用的内存资源的生命周期将延长,直至所有引用它的变量均被销毁为止。

== 用户定义资源
要实现自定义内存分配策略,请从 {ref_memory_resource} 派生类,并实现函数 `do_allocate`、`do_deallocate` 和 `do_is_equal`,如下例所示,该示例将其执行的每个操作记录到控制台:

[source]
----
include::../../../test/doc_storage_ptr.cpp[tag=doc_storage_ptr_10,indent=0]
----
Loading