Full Code of hgarrereyn/GraphFuzz for AI

master 1894510f75b0 cached
284 files
16.7 MB
4.4M tokens
12217 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (17,522K chars total). Download the full file to get everything.
Repository: hgarrereyn/GraphFuzz
Branch: master
Commit: 1894510f75b0
Files: 284
Total size: 16.7 MB

Directory structure:
gitextract_m9nptssz/

├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── README.md
├── cli/
│   ├── README.md
│   ├── gfuzz/
│   │   ├── __init__.py
│   │   ├── api.py
│   │   ├── cli.py
│   │   ├── commands/
│   │   │   ├── __init__.py
│   │   │   ├── cliopt.py
│   │   │   ├── doxygen/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── docker/
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   └── in/
│   │   │   │   │       ├── Doxyfile.template
│   │   │   │   │       └── run.py
│   │   │   │   └── extractor.py
│   │   │   ├── gen/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── cpp/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── base_schema.yaml
│   │   │   │   │   ├── cpp_sig.py
│   │   │   │   │   ├── gen_cpp.py
│   │   │   │   │   └── test_cpp_sig.py
│   │   │   │   └── gen.py
│   │   │   ├── minimizer.py
│   │   │   └── schema.py
│   │   ├── docker_util.py
│   │   └── schema.py
│   └── pyproject.toml
├── core/
│   ├── build_tests.sh
│   ├── graph.hpp
│   ├── graph.proto
│   ├── graphTest.cpp
│   ├── harness.cpp
│   ├── ignorelist.txt
│   ├── json.hpp
│   ├── schema.hpp
│   └── schemaTest.cpp
├── docs/
│   ├── .nojekyll
│   ├── README.md
│   ├── _sidebar.md
│   ├── experiments/
│   │   └── overview.md
│   ├── index.html
│   ├── quick_start/
│   │   ├── basic_usage.md
│   │   ├── endpoints.md
│   │   └── installation.md
│   └── schema_format.md
└── experiments/
    ├── README.md
    ├── base/
    │   └── Dockerfile
    ├── build
    ├── custom_endpoints/
    │   ├── Dockerfile
    │   └── in/
    │       ├── build.sh
    │       ├── lib.h
    │       └── schema.yaml
    ├── eigen/
    │   ├── Dockerfile
    │   └── in/
    │       ├── build.sh
    │       ├── f1/
    │       │   ├── fuzz_exec.cpp
    │       │   ├── fuzz_write.cpp
    │       │   ├── schema.json
    │       │   └── schema.yaml
    │       └── test.sh
    ├── ex_array_demo/
    │   ├── Dockerfile
    │   └── in/
    │       ├── build.sh
    │       ├── build_lib.sh
    │       ├── fuzz/
    │       │   ├── fuzz_exec.cpp
    │       │   ├── fuzz_write.cpp
    │       │   ├── schema.json
    │       │   └── schema.yaml
    │       └── lib/
    │           ├── lib.cpp
    │           └── lib.h
    ├── ex_auto_cpp/
    │   ├── Dockerfile
    │   ├── README.md
    │   ├── in/
    │   │   ├── auto_schema.yaml
    │   │   ├── build.sh
    │   │   ├── build_lib.sh
    │   │   ├── fuzz/
    │   │   │   ├── fuzz_exec.cpp
    │   │   │   ├── fuzz_write.cpp
    │   │   │   └── schema.json
    │   │   └── lib/
    │   │       ├── point.cpp
    │   │       ├── point.h
    │   │       ├── rect.cpp
    │   │       └── rect.h
    │   └── make_schema.sh
    ├── hello_graphfuzz/
    │   ├── Dockerfile
    │   └── in/
    │       ├── build.sh
    │       ├── lib.h
    │       ├── schema.yaml
    │       └── schema_verbose.yaml
    ├── iowow/
    │   ├── Dockerfile
    │   └── in/
    │       ├── bug.sh
    │       ├── bugs/
    │       │   ├── bug1.c
    │       │   └── bug2.c
    │       ├── build.sh
    │       ├── db_tracker.h
    │       ├── f1/
    │       │   ├── fuzz_exec.cpp
    │       │   ├── fuzz_write.cpp
    │       │   ├── schema.json
    │       │   └── schema.yaml
    │       └── test.sh
    ├── rdkit/
    │   ├── Dockerfile
    │   ├── build_rdkit.sh
    │   └── in/
    │       ├── Fuzz/
    │       │   ├── build.sh
    │       │   ├── fuzz_exec.cpp
    │       │   ├── fuzz_write.cpp
    │       │   ├── schema.json
    │       │   └── schema.yaml
    │       ├── bugs/
    │       │   ├── README.md
    │       │   ├── bug1.cpp
    │       │   ├── bug1.py
    │       │   ├── bug1_min.cpp
    │       │   ├── bug2.cpp
    │       │   ├── bug2_min.cpp
    │       │   ├── bug3.cpp
    │       │   ├── bug3_min.cpp
    │       │   ├── bug4.cpp
    │       │   ├── bug4_min.cpp
    │       │   ├── bug4_min2.cpp
    │       │   ├── bug5.cpp
    │       │   ├── bug5_min.cpp
    │       │   ├── bug6.cpp
    │       │   ├── bug6_min.cpp
    │       │   ├── bug7.cpp
    │       │   ├── bug7_min.cpp
    │       │   ├── bug8.cpp
    │       │   ├── bug9.cpp
    │       │   └── bug9_min.cpp
    │       ├── example/
    │       │   ├── build.sh
    │       │   └── test.cpp
    │       ├── launch.sh
    │       ├── make.sh
    │       ├── raw_schema.yaml
    │       └── test.sh
    ├── rdkit_demo/
    │   ├── Dockerfile
    │   ├── build_rdkit.sh
    │   └── in/
    │       ├── build.sh
    │       ├── demo.cpp
    │       ├── schema.yaml
    │       └── set_flags.sh
    ├── run
    ├── skia/
    │   ├── Dockerfile
    │   ├── README.md
    │   ├── gf_fuzz/
    │   │   ├── FuzzCanvas/
    │   │   │   ├── api_image_filter/
    │   │   │   │   ├── fuzz_exec.cpp
    │   │   │   │   ├── fuzz_write.cpp
    │   │   │   │   ├── schema.json
    │   │   │   │   └── schema.yaml
    │   │   │   ├── api_mock_gpu_canvas/
    │   │   │   │   ├── BUILD.gn
    │   │   │   │   ├── README.md
    │   │   │   │   ├── build.sh
    │   │   │   │   ├── fuzz_exec.cpp
    │   │   │   │   ├── fuzz_write.cpp
    │   │   │   │   ├── schema.json
    │   │   │   │   └── schema.yaml
    │   │   │   ├── api_null_canvas/
    │   │   │   │   ├── fuzz_exec.cpp
    │   │   │   │   ├── fuzz_write.cpp
    │   │   │   │   ├── schema.json
    │   │   │   │   └── schema.yaml
    │   │   │   ├── api_raster_n32_canvas/
    │   │   │   │   ├── fuzz_exec.cpp
    │   │   │   │   ├── fuzz_write.cpp
    │   │   │   │   ├── schema.json
    │   │   │   │   └── schema.yaml
    │   │   │   ├── api_svg_canvas/
    │   │   │   │   ├── fuzz_exec.cpp
    │   │   │   │   ├── fuzz_write.cpp
    │   │   │   │   ├── schema.json
    │   │   │   │   └── schema.yaml
    │   │   │   ├── build_baseline.sh
    │   │   │   ├── fuzz_exec.cpp
    │   │   │   ├── fuzz_util.h
    │   │   │   ├── fuzz_write.cpp
    │   │   │   ├── image_filter_deserialize/
    │   │   │   │   ├── fuzz_exec.cpp
    │   │   │   │   ├── fuzz_write.cpp
    │   │   │   │   ├── schema.json
    │   │   │   │   └── schema.yaml
    │   │   │   ├── schema.json
    │   │   │   └── schema.yaml
    │   │   ├── FuzzDrawFunctions/
    │   │   │   ├── build_baseline.sh
    │   │   │   ├── fuzz_exec.cpp
    │   │   │   ├── fuzz_write.cpp
    │   │   │   ├── schema.json
    │   │   │   └── schema.yaml
    │   │   ├── FuzzPathMeasure/
    │   │   │   ├── fuzz_exec.cpp
    │   │   │   ├── fuzz_write.cpp
    │   │   │   ├── schema.json
    │   │   │   └── schema.yaml
    │   │   ├── FuzzPathOp/
    │   │   │   ├── fuzz_exec.cpp
    │   │   │   ├── fuzz_write.cpp
    │   │   │   ├── schema.json
    │   │   │   └── schema.yaml
    │   │   ├── FuzzPolyUtils/
    │   │   │   ├── fuzz_exec.cpp
    │   │   │   ├── fuzz_write.cpp
    │   │   │   ├── poly_util.h
    │   │   │   ├── schema.json
    │   │   │   └── schema.yaml
    │   │   ├── FuzzRegionOp/
    │   │   │   ├── fuzz_exec.cpp
    │   │   │   ├── fuzz_write.cpp
    │   │   │   ├── schema.json
    │   │   │   └── schema.yaml
    │   │   ├── FuzzRegionSetPath/
    │   │   │   ├── fuzz_exec.cpp
    │   │   │   ├── fuzz_write.cpp
    │   │   │   ├── schema.json
    │   │   │   └── schema.yaml
    │   │   ├── FuzzSkParagraph/
    │   │   │   ├── build.sh
    │   │   │   ├── build_cov.sh
    │   │   │   ├── fuzz_exec.cpp
    │   │   │   ├── fuzz_write.cpp
    │   │   │   ├── paragraph_util.h
    │   │   │   ├── schema.json
    │   │   │   └── schema.yaml
    │   │   └── gen.sh
    │   ├── patch/
    │   │   ├── BUILD.gn
    │   │   └── fuzz/
    │   │       ├── Fuzz.cpp
    │   │       ├── Fuzz.h
    │   │       ├── FuzzCanvas.cpp
    │   │       ├── FuzzCommon.cpp
    │   │       ├── FuzzCommon.h
    │   │       ├── FuzzCreateDDL.cpp
    │   │       ├── FuzzDDLThreading.cpp
    │   │       ├── FuzzDrawFunctions.cpp
    │   │       ├── FuzzEncoders.cpp
    │   │       ├── FuzzGradients.cpp
    │   │       ├── FuzzMain.cpp
    │   │       ├── FuzzParsePath.cpp
    │   │       ├── FuzzPath.cpp
    │   │       ├── FuzzPathMeasure.cpp
    │   │       ├── FuzzPathop.cpp
    │   │       ├── FuzzPolyUtils.cpp
    │   │       ├── FuzzRRect.cpp
    │   │       ├── FuzzRegionOp.cpp
    │   │       ├── FuzzSkParagraph.cpp
    │   │       ├── FuzzTriangulation.cpp
    │   │       ├── README.md
    │   │       ├── coverage
    │   │       └── oss_fuzz/
    │   │           ├── FuzzAPICreateDDL.cpp
    │   │           ├── FuzzAPIImageFilter.cpp
    │   │           ├── FuzzAPISVGCanvas.cpp
    │   │           ├── FuzzAndroidCodec.cpp
    │   │           ├── FuzzAnimatedImage.cpp
    │   │           ├── FuzzDDLThreading.cpp
    │   │           ├── FuzzDrawFunctions.cpp
    │   │           ├── FuzzGradients.cpp
    │   │           ├── FuzzImage.cpp
    │   │           ├── FuzzImageFilterDeserialize.cpp
    │   │           ├── FuzzIncrementalImage.cpp
    │   │           ├── FuzzJPEGEncoder.cpp
    │   │           ├── FuzzJSON.cpp
    │   │           ├── FuzzMockGPUCanvas.cpp
    │   │           ├── FuzzNullCanvas.cpp
    │   │           ├── FuzzPNGEncoder.cpp
    │   │           ├── FuzzPathDeserialize.cpp
    │   │           ├── FuzzPathMeasure.cpp
    │   │           ├── FuzzPathop.cpp
    │   │           ├── FuzzPolyUtils.cpp
    │   │           ├── FuzzRasterN32Canvas.cpp
    │   │           ├── FuzzRegionDeserialize.cpp
    │   │           ├── FuzzRegionOp.cpp
    │   │           ├── FuzzRegionSetPath.cpp
    │   │           ├── FuzzSKP.cpp
    │   │           ├── FuzzSKSL2GLSL.cpp
    │   │           ├── FuzzSKSL2Metal.cpp
    │   │           ├── FuzzSKSL2Pipeline.cpp
    │   │           ├── FuzzSKSL2SPIRV.cpp
    │   │           ├── FuzzSVG.cpp
    │   │           ├── FuzzSkDescriptorDeserialize.cpp
    │   │           ├── FuzzSkParagraph.cpp
    │   │           ├── FuzzSkRuntimeEffect.cpp
    │   │           ├── FuzzTextBlobDeserialize.cpp
    │   │           ├── FuzzTriangulation.cpp
    │   │           └── FuzzWEBPEncoder.cpp
    │   └── scripts/
    │       ├── llvm-gcov.sh
    │       └── run.py
    └── sqlite3/
        ├── Dockerfile
        └── in/
            ├── bug.sh
            ├── bugs/
            │   ├── bug1.c
            │   └── bug2.c
            ├── build.sh
            ├── c_api.yaml
            ├── db_tracker.h
            ├── extra.h
            ├── f1/
            │   ├── fuzz_exec.cpp
            │   ├── fuzz_write.cpp
            │   ├── schema.json
            │   └── schema.yaml
            ├── sql.dict
            ├── sqlite3.c
            ├── sqlite3.h
            └── test.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
**/__pycache__
build/
python/dist


================================================
FILE: CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.10)
project(GraphFuzz VERSION 1.0)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

include(FindProtobuf)
find_package(Protobuf REQUIRED)

include_directories(${PROTOBUF_INCLUDE_DIRS}) 
include_directories(${CMAKE_CURRENT_BINARY_DIR}) 

protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS core/graph.proto) 

add_library(graphfuzz STATIC
    core/harness.cpp
    core/graph.proto ${PROTO_SRCS} ${PROTO_HDRS}
)

install(
    TARGETS graphfuzz
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION bin
)


================================================
FILE: LICENSE
================================================
Copyright 2022 Harrison Green

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
# GraphFuzz: _Library API Fuzzing with Lifetime-aware Dataflow Graphs_

GraphFuzz is an experimental framework for building structure-aware, library API fuzzers.

Read our ICSE'22 paper: [GraphFuzz: Library API Fuzzing with Lifetime-aware Dataflow Graphs](https://hgarrereyn.github.io/GraphFuzz/research/GraphFuzz_ICSE_2022.pdf)

GraphFuzz consists of:
- `gfuzz`: A command-line tool to synthesize harnesses
- `libgraphfuzz`: A runtime graph-mutation engine

Documentation: [hgarrereyn.github.io/GraphFuzz](https://hgarrereyn.github.io/GraphFuzz)

## How it Works

With GraphFuzz, you create a _schema_ that describes your target library API. The schema is written in human-readable YAML and contains a list of all functions, classes and structs that you want to fuzz test:

**schema.yaml**
```yaml
Foo:
    methods:
    - Foo()
    - ~Foo()
    - void foo(int x, int y, float z)
Bar:
    methods:
    - Bar(Foo *, int)
    - ~Bar()
    - void bar(int x)
```

At runtime, GraphFuzz will generate test cases that invoke your library API in different orders and with different arguments. Importantly, it will explicily track object lifetimes and ensure that all test cases respect the API contract defined by the schema:

```cpp
{ // Example 1
    Foo *v0 = new Foo();
    v0->foo(3, 4, 0.5);
    Bar *v1 = new Bar(v0, 1000);
    v1->bar(123);
    del v1;
    del v0;
}
{ // Example 2
    Foo *v0 = new Foo();
    v0->foo(3, 4, 0.5);
    v0->foo(1, 0, 0.5);
    v0->foo(0, 4, 0.5);
    del v0;
}
{ // Example 3
    Foo *v0 = new Foo();
    v0->foo(3, 4, 0.5);
    Bar *v1 = new Bar(v0, 1000);
    Bar *v2 = new Bar(v0, 0);
    del v2;
    del v1;
    del v0;
}
```

The example test cases above are represented as C++ source code. However, internally, GraphFuzz represents every test case as a _dataflow graph_ where vertices are functions and edges are object dependencies (hence **Graph**Fuzz). In this way, GraphFuzz executes test cases _without_ code synthesis or recompilation; rather, it dynamically traverses each graph, invoking one endpoint per vertex.

![a](docs/assets/readme_graphs.png)

## Using GraphFuzz

GraphFuzz is implemented as a custom mutation engine on top of libFuzzer and as such it can be easily incorporated into build systems that already handle libFuzzer harnesses.

1. Use `gfuzz` to synthesize C++ harness files from your `schema.yaml` harness spec.

```
gfuzz gen cpp schema.yaml .
```

2. Compile the generated harness files as standard libFuzzer harnesses (`-fsanitize=fuzzer`) and link libgraphfuzz and protobuf dependencies (`-lgraphfuzz -lprotobuf`). Optionally, include any extra sanitizers (ASAN, UBSAN, TSAN, etc...). GraphFuzz will actually create two mirror harnesses: `fuzz_exec` is used for fuzzing and actually invokes the library API while `fuzz_write` generates equivalent source code for a given dataflow graph.

```bash
# fuzz_exec: main fuzzer, executes test cases
clang++ fuzz_exec.cpp \
    -lgraphfuzz -lprotobuf \
    -fsanitize=address,fuzzer \
    -o fuzz_exec

# fuzz_write: converts test cases to source code
clang++ fuzz_write.cpp \
    -lgraphfuzz -lprotobuf \
    -fsanitize=address,fuzzer \
    -o fuzz_write
```

3. Run the generated binary with any standard libFuzzer command-line arguments. In addition, there are several additional GraphFuzz-specific arguments prefixed with `--graphfuzz_`. Crash reports are identical to standard libFuzzer reports.

```
$ ./fuzz_exec

[*] Loading: schema.json
[*] GraphFuzz: loading trees from cache...
[*] After validation: total scopes: 4
[*] After validation: usable scopes: 4
INFO: Seed: 545606100
INFO: Loaded 1 modules   (13 inline 8-bit counters): 13 [0x82f2c0, 0x82f2cd),
INFO: Loaded 1 PC tables (13 PCs): 13 [0x5de960,0x5dea30),
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: A corpus is not provided, starting from an empty corpus
#2	INITED cov: 1 ft: 1 corp: 1/1b exec/s: 0 rss: 39Mb
	NEW_FUNC[0/6]: 0x554910 in shim_finalize (/harness/in/fuzz/fuzz_exec+0x554910)
	NEW_FUNC[1/6]: 0x554b70 in shim_1 (/harness/in/fuzz/fuzz_exec+0x554b70)
#3	NEW    cov: 7 ft: 8 corp: 2/206b exec/s: 0 rss: 43Mb L: 205/205 MS: 1 Custom-
#4	NEW    cov: 7 ft: 9 corp: 3/224b exec/s: 0 rss: 43Mb L: 18/205 MS: 1 CustomCrossOver-
#32	NEW    cov: 7 ft: 12 corp: 4/600b exec/s: 0 rss: 44Mb L: 376/376 MS: 4 CustomCrossOver-ChangeBinInt-Custom-CustomCrossOver-
#35	NEW    cov: 7 ft: 15 corp: 5/1336b exec/s: 0 rss: 44Mb L: 736/736 MS: 5 ShuffleBytes-Custom-CrossOver-Custom-CustomCrossOver-
#55	NEW    cov: 7 ft: 18 corp: 6/1894b exec/s: 0 rss: 45Mb L: 558/736 MS: 6 CustomCrossOver-Custom-ChangeByte-Custom-CustomCrossOver-CustomCrossOver-
#78	NEW    cov: 7 ft: 19 corp: 7/2812b exec/s: 0 rss: 46Mb L: 918/918 MS: 4 CustomCrossOver-ChangeBit-Custom-CustomCrossOver-
#84	REDUCE cov: 7 ft: 19 corp: 7/2803b exec/s: 0 rss: 46Mb L: 196/918 MS: 1 CustomCrossOver-
	NEW_FUNC[0/2]: 0x554930 in shim_0 (/harness/in/fuzz/fuzz_exec+0x554930)
	NEW_FUNC[1/2]: 0x555160 in Test::fuzz1(int*) (/harness/in/fuzz/fuzz_exec+0x555160)
#85	NEW    cov: 10 ft: 22 corp: 8/2860b exec/s: 0 rss: 46Mb L: 57/918 MS: 1 CustomCrossOver-
#86	REDUCE cov: 10 ft: 22 corp: 8/2712b exec/s: 0 rss: 47Mb L: 770/770 MS: 1 Custom-
#102	NEW    cov: 10 ft: 23 corp: 9/3660b exec/s: 0 rss: 47Mb L: 948/948 MS: 1 CustomCrossOver-
#115	REDUCE cov: 10 ft: 27 corp: 10/4822b exec/s: 0 rss: 48Mb L: 1162/1162 MS: 3 CustomCrossOver-CustomCrossOver-CustomCrossOver-
#280	NEW    cov: 10 ft: 30 corp: 11/6672b exec/s: 0 rss: 55Mb L: 1850/1850 MS: 7 CustomCrossOver-ChangeBinInt-Custom-CrossOver-Custom-CustomCrossOver-CustomCrossOver-
#286	REDUCE cov: 10 ft: 30 corp: 11/6665b exec/s: 0 rss: 56Mb L: 50/1850 MS: 1 CustomCrossOver-
#307	NEW    cov: 10 ft: 31 corp: 12/8335b exec/s: 0 rss: 57Mb L: 1670/1850 MS: 1 CustomCrossOver-
#310	NEW    cov: 10 ft: 32 corp: 13/10937b exec/s: 0 rss: 57Mb L: 2602/2602 MS: 4 CustomCrossOver-CMP-Custom-CustomCrossOver- DE: "num_s"-
#318	REDUCE cov: 10 ft: 32 corp: 13/10757b exec/s: 0 rss: 58Mb L: 1490/2602 MS: 5 ShuffleBytes-Custom-PersAutoDict-Custom-CustomCrossOver- DE: "num_s"-
#319	NEW    cov: 10 ft: 33 corp: 14/12967b exec/s: 0 rss: 58Mb L: 2210/2602 MS: 1 CustomCrossOver-
#338	NEW    cov: 10 ft: 36 corp: 15/16289b exec/s: 0 rss: 60Mb L: 3322/3322 MS: 7 EraseBytes-Custom-CMP-Custom-EraseBytes-Custom-CustomCrossOver- DE: "finalizers"-
#339	NEW    cov: 10 ft: 37 corp: 16/18Kb exec/s: 0 rss: 60Mb L: 2242/3322 MS: 1 CustomCrossOver-
#384	NEW    cov: 10 ft: 38 corp: 17/21Kb exec/s: 0 rss: 63Mb L: 3110/3322 MS: 5 CustomCrossOver-Custom-Custom-Custom-CustomCrossOver-
#390	NEW    cov: 10 ft: 41 corp: 18/24Kb exec/s: 0 rss: 63Mb L: 3174/3322 MS: 1 CustomCrossOver-
#392	REDUCE cov: 10 ft: 42 corp: 19/27Kb exec/s: 0 rss: 63Mb L: 3142/3322 MS: 2 CustomCrossOver-CustomCrossOver-
#483	NEW    cov: 10 ft: 43 corp: 20/30Kb exec/s: 0 rss: 74Mb L: 3714/3714 MS: 1 CustomCrossOver-
#515	NEW    cov: 10 ft: 46 corp: 21/34Kb exec/s: 0 rss: 80Mb L: 3386/3714 MS: 3 EraseBytes-Custom-CustomCrossOver-
#537	REDUCE cov: 10 ft: 46 corp: 21/34Kb exec/s: 0 rss: 83Mb L: 1342/3714 MS: 2 CustomCrossOver-CustomCrossOver-
...
ChangeByte-Custom-CrossOver-Custom-ChangeBit-Custom-ShuffleBytes-Custom-CustomCrossOver-
#22527	REDUCE cov: 11 ft: 72 corp: 40/47Kb exec/s: 1072 rss: 590Mb L: 1198/4024 MS: 3 EraseBytes-Custom-CustomCrossOver-
#22794	REDUCE cov: 11 ft: 72 corp: 40/47Kb exec/s: 1085 rss: 590Mb L: 112/4024 MS: 2 Custom-CustomCrossOver-
#22973	REDUCE cov: 11 ft: 72 corp: 40/47Kb exec/s: 1093 rss: 591Mb L: 1476/4024 MS: 6 CopyPart-Custom-CustomCrossOver-ShuffleBytes-Custom-CustomCrossOver-
==39== ERROR: libFuzzer: deadly signal
    #0 0x523c09 in __sanitizer_print_stack_trace (/harness/in/fuzz/fuzz_exec+0x523c09)
    #1 0x434106 in fuzzer::Fuzzer::CrashCallback() (/harness/in/fuzz/fuzz_exec+0x434106)
    #2 0x43415f in fuzzer::Fuzzer::StaticCrashSignalCallback() (/harness/in/fuzz/fuzz_exec+0x43415f)
    #3 0x7f5d0329f97f  (/lib/x86_64-linux-gnu/libpthread.so.0+0x1297f)
    #4 0x55528d in Test::fuzz1(int*) (/harness/in/fuzz/fuzz_exec+0x55528d)
    #5 0x554abe in shim_0 (/harness/in/fuzz/fuzz_exec+0x554abe)
    #6 0x5581f1 in LLVMFuzzerTestOneInput (/harness/in/fuzz/fuzz_exec+0x5581f1)
    #7 0x434847 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/harness/in/fuzz/fuzz_exec+0x434847)
    #8 0x43f0b4 in fuzzer::Fuzzer::MutateAndTestOne() (/harness/in/fuzz/fuzz_exec+0x43f0b4)
    #9 0x44071f in fuzzer::Fuzzer::Loop(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, fuzzer::fuzzer_allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&) (/harness/in/fuzz/fuzz_exec+0x44071f)
    #10 0x42fadc in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/harness/in/fuzz/fuzz_exec+0x42fadc)
    #11 0x4229a2 in main (/harness/in/fuzz/fuzz_exec+0x4229a2)
    #12 0x7f5d02899bf6 in __libc_start_main /build/glibc-S9d2JN/glibc-2.27/csu/../csu/libc-start.c:310
    #13 0x422a19 in _start (/harness/in/fuzz/fuzz_exec+0x422a19)

NOTE: libFuzzer has rudimentary signal handlers.
      Combine libFuzzer with AddressSanitizer or similar for better crash reports.
SUMMARY: libFuzzer: deadly signal
MS: 8 EraseBytes-Custom-CopyPart-Custom-ChangeBinInt-Custom-ChangeBit-Custom-; base unit: 34135396532491fa3706b611a9ebd0665e5fa6d0
artifact_prefix='./'; Test unit written to ./crash-23b6ad2375371d36f46f75fa28f297a1b0e84a53
```

4. Upon finding a crash, use `fuzz_write` to convert the serialized dataflow graph into source code which can be recompiled externally for debugging purposes:

```
$ ./fuzz_write ./crash-23b6ad2375371d36f46f75fa28f297a1b0e84a53
...

#include "lib.h"


#define MAKE(t) static_cast<t *>(calloc(sizeof(t), 1))

struct GFUZZ_BUNDLE {
public:
    void *active;
    void *inactive;
    GFUZZ_BUNDLE(void *_active, void *_inactive): active(_active), inactive(_inactive) {}
};

#define BUNDLE(a,b) new GFUZZ_BUNDLE((void *)a, (void *)b)

int main() {
    Test *var_0;
    { // begin shim_2
        var_0 = MAKE(Test);
        Test ref = Test();
        *var_0 = ref;
    } // end shim_2
    Test *var_1;
    { // begin shim_1
    int _a0[32] = {
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1048576, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };
    float _a1[8] = {0, 0, 0, 0, 0, 0, 0, 0};
        var_0->fuzz2(_a0, _a1);
        var_1 = var_0;
    } // end shim_1
    Test *var_2;
    { // begin shim_0
    int _a0[4] = {0, 0, 0, 0};
        var_1->fuzz1(_a0);
        var_2 = var_1;
    } // end shim_0
    Test *var_3;
    { // begin shim_0
    int _a0[4] = {0, 0, 0, 0};
        var_2->fuzz1(_a0);
        var_3 = var_2;
    } // end shim_0
    Test *var_4;
    { // begin shim_0
    int _a0[4] = {0, 0, 0, 0};
        var_3->fuzz1(_a0);
        var_4 = var_3;
    } // end shim_0
    Test *var_5;
    { // begin shim_0
    int _a0[4] = {0, 0, 0, 0};
        var_4->fuzz1(_a0);
        var_5 = var_4;
    } // end shim_0
    Test *var_6;
    { // begin shim_1
    int _a0[32] = {
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };
    float _a1[8] = {0, 0, 0, 0, 0, 0, 0, 0};
        var_5->fuzz2(_a0, _a1);
        var_6 = var_5;
    } // end shim_1

    ...

    { // begin shim_0
    int _a0[4] = {0, 0, 0, 0};
        var_33->fuzz1(_a0);
        var_34 = var_33;
    } // end shim_0
    Test *var_35;
    { // begin shim_0
    int _a0[4] = {0, 0, 3, 0};
        var_34->fuzz1(_a0);
        var_35 = var_34;
    } // end shim_0
    Test *var_36;
    { // begin shim_0
    int _a0[4] = {0, 0, 0, 0};
        var_35->fuzz1(_a0);
        var_36 = var_35;
    } // end shim_0
    { // begin shim_3
        free(var_36);
    } // end shim_3
}
```

5. (optional) Use the `gfuzz` tool to perform graph-aware test case minimization:

```console
$ gfuzz min ./fuzz_exec ./crash-23b6ad2375371d36f46f75fa28f297a1b0e84a53

Minimizing ./crash-23b6ad2375371d36f46f75fa28f297a1b0e84a53...
Base case size: 2058
---[Crash]---
libFuzzer: deadly signal
-------------
Minimizing...
[3] Found smaller crash: 2026
[7] Found smaller crash: 1994
[8] Found smaller crash: 678
[9] Found smaller crash: 306
[10] Found smaller crash: 274
[12] Found smaller crash: 242
[13] Found smaller crash: 178
[14] Found smaller crash: 146
[16] Found smaller crash: 114
[17] Found smaller crash: 82
[21] Found smaller crash: 50
No improvement for 50 steps, stopping...
Minimized crash saved to: ./crash-23b6ad2375371d36f46f75fa28f297a1b0e84a53.min
```

```
$ ./fuzz_write crash-23b6ad2375371d36f46f75fa28f297a1b0e84a53.min
...

#include "lib.h"


#define MAKE(t) static_cast<t *>(calloc(sizeof(t), 1))

struct GFUZZ_BUNDLE {
public:
    void *active;
    void *inactive;
    GFUZZ_BUNDLE(void *_active, void *_inactive): active(_active), inactive(_inactive) {}
};

#define BUNDLE(a,b) new GFUZZ_BUNDLE((void *)a, (void *)b)

int main() {
    Test *var_0;
    { // begin shim_2
        var_0 = MAKE(Test);
        Test ref = Test();
        *var_0 = ref;
    } // end shim_2
    Test *var_1;
    { // begin shim_0
    int _a0[4] = {0, 0, 3, 4};
        var_0->fuzz1(_a0);
        var_1 = var_0;
    } // end shim_0
    { // begin shim_3
        free(var_1);
    } // end shim_3
}
```

## Learn More

For help on setting up your first GraphFuzz harness, see [Basic Usage](https://hgarrereyn.github.io/GraphFuzz/#/quick_start/basic_usage).

For some more in-depth examples, see our collection of Dockerized, runnable [Experiments](https://hgarrereyn.github.io/GraphFuzz/#/experiments/overview).


================================================
FILE: cli/README.md
================================================
# Graphfuzz command line interface

## Usage:

## Crash minimization

```sh
$ gfuzz min <fuzzer> <crash>
```

## Doxygen generation

```
$ gfuzz doxygen --inputs in1 [in2, in3...] --output <output>
```

## Schema infererence

```
$ gfuzz schema infer </path/to/doxygen_xml>
```


================================================
FILE: cli/gfuzz/__init__.py
================================================


================================================
FILE: cli/gfuzz/api.py
================================================

import os
import yaml

from parser import parse_sig


class API(object):
    def __init__(self, fpath):
        self.fpath = fpath
        self.methods = []
        self.headers = []
        self.cpp_headers = []
        self.initializer = ''
        self.finalizer = ''

        if not os.path.exists(self.fpath):
            print('[*] Error API file not found: %s' % self.fpath)
            return

        api = yaml.safe_load(open(self.fpath, 'r').read())

        if 'headers' in api:
            self.headers = api['headers']

        if 'cpp_headers' in api:
            self.cpp_headers = api['cpp_headers']

        if 'initializer' in api:
            self.initializer = api['initializer']

        if 'finalizer' in api:
            self.finalizer = api['finalizer']

        for raw_sig in api['methods']:
            sig = parse_sig(raw_sig)

            if sig is None:
                print('[!] Could not parse signature: %s' % raw_sig)
            else:
                self.methods.append(sig)
    
        print('[*] Loaded %d methods' % len(self.methods))


================================================
FILE: cli/gfuzz/cli.py
================================================

import argparse


from .commands import COMMANDS


def main():
    parser = argparse.ArgumentParser(description='GraphFuzz CLI')
    sub = parser.add_subparsers(dest='mode')

    options = {api._name: api for api in COMMANDS}

    for opt in COMMANDS:
        opt.add_args(sub)

    args = parser.parse_args()

    if args.mode is None:
        parser.print_help()
        exit(0)
    elif args.mode in options:
        options[args.mode].execute(args)
    else:
        return

if __name__=='__main__':
    main()


================================================
FILE: cli/gfuzz/commands/__init__.py
================================================

from .minimizer import MinAPI
from .doxygen.extractor import DoxygenAPI
from .schema import SchemaAPI
from .gen.gen import GenAPI


COMMANDS = [
    MinAPI,
    DoxygenAPI,
    SchemaAPI,
    GenAPI
]


================================================
FILE: cli/gfuzz/commands/cliopt.py
================================================

class CLIOpt(object):
    def __init__(self, name, help_str, register_fn, execute_fn):
        self._name = name
        self._help_str = help_str
        self._register_fn = register_fn
        self._execute_fn = execute_fn

        self._subparser = None

    def add_args(self, parser):
        sub = parser.add_parser(self._name, help=self._help_str)
        self._register_fn(sub)
        self._subparser = sub

    def execute(self, args):
        res = self._execute_fn(args)
        if res == False:
            self._subparser.print_help()


================================================
FILE: cli/gfuzz/commands/doxygen/__init__.py
================================================


================================================
FILE: cli/gfuzz/commands/doxygen/docker/Dockerfile
================================================

FROM ubuntu:20.04

RUN apt-get -y update && \
    apt-get -y upgrade && \
    apt-get -y install doxygen git python3

WORKDIR /src
COPY in ./in

ENTRYPOINT ["/src/in/run.py"]


================================================
FILE: cli/gfuzz/commands/doxygen/docker/in/Doxyfile.template
================================================
EXTRACT_ALL = YES
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = YES

INPUT = {input}
RECURSIVE = true

GENERATE_XML = YES
XML_PROGRAMLISTING = NO
MACRO_EXPANSION = YES

GENERATE_HTML = NO
GENERATE_LATEX = NO
GENERATE_RTF = NO
GENERATE_MAN = NO
GENERATE_AUTOGEN_DEF = NO
GENERATE_PERLMOD = NO


================================================
FILE: cli/gfuzz/commands/doxygen/docker/in/run.py
================================================
#!/usr/bin/python3

import argparse
import os
import subprocess


def _run_doxygen(inputs):
    template = open('/src/in/Doxyfile.template', 'r').read()
    open('/src/out/Doxyfile', 'w').write(template.format(
        input=' '.join(inputs)
    ))

    r = subprocess.run('cd /src/out && doxygen', shell=True)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--inputs', required=True, nargs='+', type=str,
        help='Doxygen input paths.')
    args = parser.parse_args()

    _run_doxygen(args.inputs)


if __name__=='__main__':
    main()


================================================
FILE: cli/gfuzz/commands/doxygen/extractor.py
================================================

import argparse
import os
import pathlib
import subprocess


from ... import docker_util
from ..cliopt import CLIOpt


EXTRACTOR_IMAGE_TAG = 'util_graphfuzz_doxygen_extractor'


def build_extractor_image():
    package = pathlib.Path(__file__).parent.absolute()
    docker_path = package / 'docker'

    docker_util.build_image(docker_path, EXTRACTOR_IMAGE_TAG)


def run_extractor_image(inputs, output):
    out = pathlib.Path(output).absolute()

    input_paths = [pathlib.Path(x) for x in inputs]

    # Map input path on host to path inside container.
    volumes = {
        str(p.absolute()): str('/src/target' / p.relative_to(p.root)) for p in input_paths
    }
    volumes[str(out)] = '/src/out'

    inner_args = '--inputs ' + ' '.join(
        volumes[host] for host in volumes
    )

    docker_util.run_image(EXTRACTOR_IMAGE_TAG, '', volumes, inner_args)


def register(sub):
    sub.add_argument('--inputs', required=True, nargs='+', type=str,
        help='Doxygen input paths.')
    sub.add_argument('--output', required=True, type=str,
        help='Doxygen output directory.')


def execute(args):
    docker_util.check_docker()
    build_extractor_image()
    run_extractor_image(args.inputs, args.output)


DoxygenAPI = CLIOpt(
    'doxygen',
    'Build Doxygen xml from source code.',
    register,
    execute
)


================================================
FILE: cli/gfuzz/commands/gen/__init__.py
================================================


================================================
FILE: cli/gfuzz/commands/gen/cpp/README.md
================================================


# C++ harness generation

## Overview

A C++ schema can be broken down into two components: `types` and `scopes`.

A `type` is an object and there are two versions:
- `live types` are things like `structs` and `classes` that have explicit constructors and destructors. These objects are tracked by the dataflow graph.
- `simple types` are things like `int`, `float` or `enum` types that exist only within the context of a single function and are embedded in the `context` string during fuzzing.

A `scope` is a function and for C++ code, we have four types:
- `constructor`: A function with the same name as the enclosing `struct` or `class`.
- `destructor`: A function with the form `~MyStruct`.
- `method`: A function defined for an instance of an object, e.g. `myObj::foo()`
- `static`: A function not bound to a class, e.g. `void foo()`.

To generate harnesses, we first construct a list of `scopes` by enumerating functions defined in the schema. Each `scope` has a list of input and output `types`.

In the next stage, we resolve `types` (following typedef's as necessary), and determine the version. For example, `int x` should resolve as a "simple type of size 4" while `MyStruct &ref` should resolve to a "reference to `MyStruct`."

After the type resolution stage, we can compute the necessary "context" size for a scope and determine how many "live" inputs and outputs there will be.

Finally, we can layout the scope using a code generation template. We need to do this once for both the "exec" harness and the "write" harness.

## Method call

```cpp
extern "C" void shim_N(void **in_ref, void **out_ref, const char *context) {
    MyClass *ref = (MyClass *)in_ref[0];
    ref->myMethod();
    out_ref[0] = ref;
}
```

================================================
FILE: cli/gfuzz/commands/gen/cpp/__init__.py
================================================


================================================
FILE: cli/gfuzz/commands/gen/cpp/base_schema.yaml
================================================
simple_int:
  type: simple
  context_size: 4
  name: int
simple_float:
  type: simple
  context_size: 4
  name: float
simple_double:
  type: simple
  context_size: 8
  name: double
simple_void:
  type: ignore
  name: void
simple_char:
  type: simple
  context_size: 1
  name: char
  print_cast: int
simple_size_t:
  type: simple
  context_size: 8
  name: size_t

simple_bool:
  type: simple
  context_size: 1
  name: bool
  print_cast: int
  load: "    {var_type} {arg_name} = *(static_cast<const char *>(context + {context_offset})) & 1;\n"
  load_arr: |
    {var_type} {arg_name}[{count}];
    for (int i = 0; i < {count}; ++i) {arg_name}[i] = *(static_cast<const char *>(context + {context_offset} + i)) & 1;

simple_int8_t:
  type: simple
  context_size: 1
  name: int8_t
  print_cast: int
simple_int16_t:
  type: simple
  context_size: 2
  name: int16_t
simple_int32_t:
  type: simple
  context_size: 4
  name: int32_t
simple_int64_t:
  type: simple
  context_size: 8
  name: int64_t
simple_uint8_t:
  type: simple
  context_size: 1
  name: uint8_t
  print_cast: int
simple_uint16_t:
  type: simple
  context_size: 2
  name: uint16_t
simple_uint32_t:
  type: simple
  context_size: 4
  name: uint32_t
simple_uint64_t:
  type: simple
  context_size: 8
  name: uint64_t
simple_char16_t:
  type: simple
  context_size: 2
  name: char16_t


================================================
FILE: cli/gfuzz/commands/gen/cpp/cpp_sig.py
================================================
"""
Utilities for parsing Cpp-like signatures.
"""
from dataclasses import dataclass
from typing import Set, Optional, List

import pyparsing as pp


@dataclass
class CPPTypeModifier:
    modifiers: Set[str]
    
    @staticmethod
    def action(tok):
        return CPPTypeModifier(set(tok))
    
    @staticmethod
    def build() -> pp.ParseExpression:
        modifiers = ['unsigned', 'const', 'override', 'constexpr']
        modifier_list = pp.Each([pp.Optional(pp.Keyword(x)) for x in modifiers])
        modifier_list.setParseAction(CPPTypeModifier.action)
        return modifier_list

    
@dataclass
class CPPBaseType:
    """
    For simplicity, we consider three types:
    - bare types: e.g. "int"
    - reference types: e.g. "MyClass &"
    - pointer types: e.g. "MyClass *"
    """
    base_type: str
    is_ref: bool = False
    is_ptr: bool = False

    def __repr__(self):
        if self.is_ref:
            return f'{self.base_type} &'
        elif self.is_ptr:
            return f'{self.base_type} *'
        else:
            return f'{self.base_type}'
        
    @staticmethod
    def action(tok):
        if len(tok) == 1:
            return CPPBaseType(tok[0])
        elif tok[1] == '*':
            return CPPBaseType(tok[0], is_ptr=True)
        elif tok[1] == '&':
            return CPPBaseType(tok[0], is_ref=True)
        else:
            return None
        
    @staticmethod
    def build() -> pp.ParseExpression:
        identifier = pp.Word(pp.alphanums + '_:<>')
        base_type = identifier & pp.Optional(pp.Or(['&', '*']))
        base_type.setParseAction(CPPBaseType.action)
        return base_type


@dataclass
class CPPArgName:
    name: Optional[str] = None
        
    @staticmethod
    def action(tok):
        if len(tok) == 1:
            return CPPArgName(tok[0])
        else:
            return CPPArgName()
    
    @staticmethod
    def build() -> pp.ParseExpression:
        identifier = pp.Word(pp.alphanums + '_')
        arg_name = pp.Optional(identifier)
        arg_name.setParseAction(CPPArgName.action)
        return arg_name
    
@dataclass
class CPPArgument:
    """Represents a full type name and argument name in a function signature.
    
    For example:
    - unsigned char
    - const char *foo
    - MyClass&
    - int
    """
    modifiers: CPPTypeModifier
    base_type: CPPBaseType
    arg_name: CPPArgName
    raw_value: str = ''
    is_raw: bool = False

    def __repr__(self):
        if self.is_raw:
            return '{' + self.raw_value + '}'
        else:
            parts = (
                list(self.modifiers.modifiers) + 
                [repr(self.base_type), self.arg_name.name])
            
            return ' '.join([str(x) for x in parts])
        
    @staticmethod
    def action(tok):
        assert len(tok) == 3
        return CPPArgument(*tok)
    
    @staticmethod
    def action_raw(tok):
        assert len(tok) == 1
        raw_value = tok[0].strip()[1:-1]
        return CPPArgument(modifiers=None, base_type=None, arg_name=None, raw_value=raw_value, is_raw=True)

    @staticmethod
    def build() -> pp.ParseExpression:
        full_arg = (
            CPPTypeModifier.build() + \
            CPPBaseType.build() + \
            CPPArgName.build()
        )
        full_arg.setParseAction(CPPArgument.action)

        raw_arg = (
            pp.Regex('\{[^\{\}]*\}')
        )
        raw_arg.setParseAction(CPPArgument.action_raw)

        return pp.Or([full_arg, raw_arg])
    

@dataclass
class CPPArgList:
    args: List[CPPArgument]
        
    def __repr__(self):
        return ', '.join(repr(x) for x in self.args)

    @staticmethod
    def action(tok):
        if len(tok) == 0:
            return CPPArgList([])
        else:
            return CPPArgList(tok)
    
    @staticmethod
    def build() -> pp.ParseExpression:
        arg_list = pp.Optional(pp.delimitedList(CPPArgument.build()))
        arg_list.setParseAction(CPPArgList.action)
        return arg_list
    

@dataclass
class CPPFuncName:
    name: str
        
    @staticmethod
    def action(tok):
        return CPPFuncName(tok[0])
    
    @staticmethod
    def build() -> pp.ParseExpression:
        # Allow some special characters for operator overloads.
        func_name = pp.Word(pp.alphanums + '_:+-[]<>=*/^%-&|~!,')
        func_name.setParseAction(CPPFuncName.action)
        return func_name
    

@dataclass
class CPPFuncSignature:
    modifiers: CPPTypeModifier
    func_type: CPPBaseType
    func_name: CPPFuncName
    func_args: CPPArgList
    trailing_modifiers: CPPTypeModifier

    def __repr__(self):
        if self.func_type is None:
            # Untyped.
            return f'{self.func_name.name}({self.func_args});'
        else:
            # Typed.
            parts = (
                list(self.modifiers.modifiers) +
                [repr(self.func_type), self.func_name.name]
            )
            pre = ' '.join(parts)
            return f'{pre}({self.func_args});'

    @staticmethod
    def action_typed(tok):
        assert len(tok) == 5
        return CPPFuncSignature(*tok)
    
    @staticmethod
    def action_untyped(tok):
        assert len(tok) == 3
        return CPPFuncSignature(None, None, *tok)
    
    @staticmethod
    def build() -> pp.ParseExpression:
        typed_func = (
            CPPTypeModifier.build() + 
            CPPBaseType.build() +
            CPPFuncName.build() + 
            pp.Suppress(pp.Literal('(')) +
            CPPArgList.build() +
            pp.Suppress(pp.Literal(')')) +
            CPPTypeModifier.build() +
            pp.Suppress(pp.Optional(pp.Literal(';')))
        )
        typed_func.setParseAction(CPPFuncSignature.action_typed)
        
        # e.g. constructors and destructors
        untyped_func = (
            CPPFuncName.build() + 
            pp.Suppress(pp.Literal('(')) +
            CPPArgList.build() +
            pp.Suppress(pp.Literal(')')) +
            CPPTypeModifier.build() +
            pp.Suppress(pp.Optional(pp.Literal(';')))
        )
        untyped_func.setParseAction(CPPFuncSignature.action_untyped)
        
        return pp.Or([typed_func, untyped_func])
    

cpp_signature_parser = CPPFuncSignature.build()
def parse_signature(signature: str) -> Optional[CPPFuncSignature]:
    try:
        sig = cpp_signature_parser.parseString(signature.strip(), parseAll=True)
        return sig[0]
    except:
        return None


================================================
FILE: cli/gfuzz/commands/gen/cpp/gen_cpp.py
================================================

import enum
import pathlib
from typing import List, Tuple, Set, Dict
import json
import re
import yaml

from gfuzz.commands.cliopt import CLIOpt
from gfuzz.schema import Schema

from .cpp_sig import parse_signature, CPPFuncSignature


CPP_TEMPLATE_MAIN = '''
/* {comment} */
extern "C" void {shim_name}(void **in_ref, void **out_ref, const char *context) {{
{load_args}{fn_call}{save_args}}}
'''

CPP_TEMPLATE_MAIN_WRITE = '''
/* {comment} */
extern "C" void {shim_name}(void **in_ref, void **out_ref, const char *context) {{
{load_args}
    std::cout << "    {{" << std::endl;
{inner_load_args}
{fn_call}{save_args}
    std::cout << "    }}" << std::endl;
}}
'''

CPP_TEMPLATE_MAIN_SOFT = '''
/* {comment} */
extern "C" void {shim_name}(void **in_ref, void **out_ref, const char *context) {{
{load_args}
    if (!graphfuzz_try()) {{
    {fn_call}    }}

{save_args}}}
'''

CPP_LOAD_REF = '''\
    {var_type} *{arg_name} = reinterpret_cast<{var_type} *>(in_ref[{in_ref_idx}]);
'''

CPP_LOAD_REF_BUNDLE = '''\
    GFUZZ_BUNDLE *_b{arg_name} = (GFUZZ_BUNDLE *)in_ref[{in_ref_idx}];
    {var_type} *{arg_name} = reinterpret_cast<{var_type} *>(_b{arg_name}->active);
'''

CPP_LOAD_REF_WRITE = '''\
    unsigned long {arg_name} = reinterpret_cast<unsigned long>(in_ref[{in_ref_idx}]);
'''

CPP_SAVE_REF = '''\
    out_ref[{out_ref_idx}] = reinterpret_cast<void *>({arg_name});
'''

CPP_LOAD_SIMPLE = '''\
    {var_type} {arg_name};
    memcpy(&{arg_name}, context + {context_offset}, sizeof({var_type}));
'''

CPP_LOAD_SIMPLE_ARRAY = '''\
    {var_type} {arg_name}[{count}];
    memcpy(&{arg_name}, context + {context_offset}, {context_size} * {count});
'''

CPP_LOAD_SIMPLE_ARRAY_WRITE = '''\
    std::cout << "    {var_type} {arg_name}[{count}] = {{";
    for (int i = 0; i < {count}; ++i) {{
        if (i % 16 == 0 && {count} > 16) std::cout << std::endl << "        ";
        {var_type} ref;
        memcpy(&ref, context + {context_offset} + ({context_size} * i), {context_size});
        std::cout << {print_cast}ref;
        if (i < {count} - 1) std::cout << ", ";
    }}
    if ({count} > 16) std::cout << std::endl << "    ";
    std::cout << "}};" << std::endl;
'''

CPP_PRINT_SIMPLE_ARRAY = '''\
    std::cout << "    {var_type} {arg_name}[{count}] = {{";
    for (int i = 0; i < {count}; ++i) {{
        if (i % 16 == 0 && {count} > 16) std::cout << std::endl << "        ";
        std::cout << {print_cast}{arg_name}[i];
        if (i < {count} - 1) std::cout << ", ";
    }}
    if ({count} > 16) std::cout << std::endl << "    ";
    std::cout << "}};" << std::endl;
'''

CPP_LOAD_ENUM = '''\
    {var_type} {arg_name};
    switch (*(reinterpret_cast<const unsigned char *>(context + {context_offset})) % {enum_size}) {{
{enum_cases}    }}
'''

CPP_LOAD_ENUM_WRITE = '''\
    const char *{arg_name};
    switch (*(reinterpret_cast<const unsigned char *>(context + {context_offset})) % {enum_size}) {{
{enum_cases}    }}
'''

CPP_ENUM_CASE = '''\
        case {case}: {arg_name} = {enum_value}; break;
'''

CPP_ENUM_CASE_WRITE = '''\
        case {case}: {arg_name} = "{enum_value}"; break;
'''

CPP_NEW_REF_CUSTOM = '''\
    unsigned long {name} = CURR_ID++;
    std::cout << "    {var_type} *var_" << {name} << ";" << std::endl;
'''


WRITE_ARG_REF = '''"*var_" << {arg_name}'''
WRITE_ARG_VAL = '''{arg_name}'''
WRITE_ARG_SEP = ''' << ", " << '''

SHIM_ARRAY = '''
void __attribute__((visibility ("default"))) (*FUZZER_SHIMS[])(void **, void **, const char *) = {{
{shims}
}};
'''

SHIM_MACROS = '''
#define MAKE(t) static_cast<t *>(calloc(sizeof(t), 1))

struct GFUZZ_BUNDLE {
public:
    void *active;
    void *inactive;
    GFUZZ_BUNDLE(void *_active, void *_inactive): active(_active), inactive(_inactive) {}
};

#define BUNDLE(a,b) new GFUZZ_BUNDLE((void *)a, (void *)b)
'''

SHIM_MACROS_DRY = '''
#ifdef FUZZ_DRY
#define FUZZ_ENDPOINT(T) 0;
#else
#define FUZZ_ENDPOINT(T) T
#endif
'''

SHIM_HEADER = '''
#include <string.h>
#include <stdlib.h>
#include <cstdint>

extern "C" int graphfuzz_try();
extern "C" void graphfuzz_bail();

extern "C" void __attribute__((visibility ("default"))) global_init(int *argc, char ***argv) {{
{global_init}
}}

extern "C" void __attribute__((visibility ("default"))) shim_init() {{
{initializer}
}}

extern "C" void __attribute__((visibility ("default"))) shim_finalize() {{
{finalizer}
}}

{macros}
'''

SHIM_HEADER_WRITE = '''
#include <string.h>
#include <string>
#include <iostream>

unsigned long CURR_ID = 0;

extern "C" void __attribute__((visibility ("default"))) global_init(int *argc, char ***argv) {{
    char **new_argv = (char **)malloc((*argc + 2) * sizeof(char *));
    memcpy(new_argv, *argv, sizeof(*new_argv) * *argc);
    new_argv[*argc] = (char *)"-detect_leaks=0";
    new_argv[*argc + 1] = 0;
    (*argc)++;
    *argv = new_argv;
}}

extern "C" void __attribute__((visibility ("default"))) shim_init() {{
    CURR_ID = 0;

    std::cout << "{header_string}" << std::endl;
    std::cout << "{macros}" << std::endl;

    std::cout << "int main() {{" << std::endl;
}}

extern "C" void __attribute__((visibility ("default"))) shim_finalize() {{
    std::cout << "}}" << std::endl;
}}
'''

CPP_INCLUDE = '''\
#include "{header}"
'''

CPP_INCLUDE_LIB = '''\
#include {header}
'''

CPP_INCLUDE_C = '''\
extern "C" {{
    #include "{header}" 
}}
'''

FULL_HARNESS = '''\
{includes}
{header}
{shim_code}
{shim_array}
'''


class CPPScopeType(enum.Enum):
    # MyClass::MyClass(...)
    CONSTRUCTOR = 1

    # MyClass::~MyClass(...)
    DESTRUCTOR = 2

    # MyClass MyClass::Make(...)
    STATIC_CONSTRUCTOR = 3

    # void MyClass::foo(...)
    METHOD = 4

    # void foo(...)
    # int MyClass::DoFoo(...)
    STATIC = 5


def _is_live_type(obj: dict) -> bool:
    return obj['type'] in ['struct', 'class', 'bundle']


def _classify(parent: dict, sig: CPPFuncSignature, is_static: bool) -> CPPScopeType:
    """Determine the scope type."""

    # TODO: remove?
    if parent['type'] == 'file':
        return CPPScopeType.STATIC
    
    obj_name = parent['name']

    if sig.func_name.name == obj_name and not is_static:
        return CPPScopeType.CONSTRUCTOR
    elif sig.func_name.name == f'~{obj_name}' and not is_static:
        return CPPScopeType.DESTRUCTOR
    elif sig.func_type.base_type == obj_name and is_static:
        return CPPScopeType.STATIC_CONSTRUCTOR
    elif is_static:
        return CPPScopeType.STATIC
    else:
        return CPPScopeType.METHOD


def _escape_text(t: str) -> str:
    return t.replace('\\', '\\\\').replace('\"', '\\\"')


class CPPScope(object):
    def __init__(self, name: str, inputs: List[str], outputs: List[str], 
            args: List[str], exec_str: str):
        self.name = name
        self.inputs = inputs
        self.outputs = outputs
        self.args = args
        self.exec = exec_str

        self.needs_resolve = True
        self.has_all_refs = True
        self.missing_refs = []

        # *_ref is a list of schema objects filled during resolve_all
        self.inputs_ref = []
        self.outputs_ref = []
        self.args_ref = []

        # arg_count contains a positive integer describing the size of the
        # argument array. I.e. "1" for a single value and 2+ for an array.
        self.arg_count = []

    @staticmethod
    def from_dict(info: dict) -> 'CPPScope':
        """Initialize from a manual scope definition.
        
        Info is a dict of the form:

        "scope_name": {
            "inputs": ["MyClass"]
            "outputs": ["MyClass"]
            "args": ["int", "float"]
            "exec": "$i0->fuzz($a0, $a1);\n$o0 = $i0;"
        }
        """
        keys = [k for k in info]
        assert(len(keys) == 1)

        name = keys[0]
        dat = info[name]

        inputs = dat.get('inputs') or []
        outputs = dat.get('outputs') or []
        args = dat.get('args') or []
        exec_str = dat.get('exec') or ''

        return CPPScope(name, inputs, outputs, args, exec_str)

    @staticmethod
    def destructor_for(schema: Schema, parent: dict) -> 'CPPScope':
        sig = parse_signature(f'~{parent["name"]}()')
        return CPPScope.from_signature(schema, parent, sig, False)

    @staticmethod
    def from_signature(schema: Schema, parent: dict, sig: CPPFuncSignature, is_static: bool, generate_dry: bool = False) -> 'CPPScope':
        """Initialize from a C++ signature.
        
        Inputs/Outputs/Args are automatically inferred.

        Args:
        - schema: The global schema.
        - parent: The parent struct/class object.
        - sig: A parsed CPPFuncSignature.
        - is_static: True if this function was defined in static_methods.

        Returns a CPPScope if succesful, None if the types could not be resolved.
        """
        # Try to infer the scope type.
        scope_type = _classify(parent, sig, is_static)
        
        # Temporarily resolve type to figure out if they are arguments or inputs.
        # TODO: Clean this up, we end up resolving types twice in this pathway.
        resolved = []
        missing = []
        for arg in sig.func_args.args:
            if arg.is_raw:
                resolved.append(arg.raw_value)
            else:
                obj = schema.resolve(arg.base_type.base_type)
                if obj is None:
                    missing.append(arg.base_type.base_type)

                resolved.append(obj)

        func_base_type = None
        if sig.func_type is not None:
            func_base_type = schema.resolve(sig.func_type.base_type)
            if func_base_type is None:
                missing.append(sig.func_type.base_type)
        
        if len(missing) > 0:
            # Missing types.
            scp = CPPScope('', [], [], [], '')
            scp.needs_resolve = False
            scp.missing_refs = missing
            scp.has_all_refs = False

            return scp

        live_types = [k for k in resolved if type(k) is dict and _is_live_type(k)]
        context_types = [k for k in resolved if type(k) is dict and not _is_live_type(k)]

        inputs = [k['name'] for k in live_types]
        outputs = [k['name'] for k in live_types]
        args = [k['name'] for k in context_types]
        exec_str = ''

        arg_list = []
        idx_input = 0
        idx_arg = 0
        for i in range(len(resolved)):
            k = resolved[i]
            if type(k) is str:
                # raw type
                arg_list.append(k)
            else:
                if _is_live_type(k):
                    if sig.func_args.args[i].base_type.is_ptr:
                        arg_list.append(f'$i{idx_input}')
                    else:
                        arg_list.append(f'*$i{idx_input}')
                    idx_input += 1
                else:
                    arg_list.append(f'$a{idx_arg}')
                    idx_arg += 1
        arg_list = ', '.join(arg_list)

        if scope_type == CPPScopeType.CONSTRUCTOR:
            outputs = [parent['name']] + outputs
            copy_inputs = '\n'.join([
                f'$o{i+1} = $i{i};' for i in range(len(inputs))
            ])
            # Copy with memcpy or operator= ?
            if 'alloc_with_new' in parent and parent['alloc_with_new']:
                exec_str = f'''\
$o0 = new {parent['name']}({arg_list});
{copy_inputs}
                '''
            else:
                exec_str = f'''\
$o0 = MAKE({parent['name']});
{parent['name']} ref = {parent['name']}({arg_list});
*$o0 = ref;
{copy_inputs}
                '''
        elif scope_type == CPPScopeType.STATIC_CONSTRUCTOR:
            outputs = [parent['name']] + outputs
            copy_inputs = '\n'.join([
                f'$o{i+1} = $i{i};' for i in range(len(inputs))
            ])
            func_name = sig.func_name.name
            # If the func_name is not fully scoped (i.e. does not include "::") assume
            # it uses the base class.
            if not '::' in func_name:
                func_name = f'{parent["name"]}::{func_name}'

            # TODO: alloc_with_new for static constructors?
            if False or 'alloc_with_new' in parent and parent['alloc_with_new']:
                exec_str = f'''\
$o0 = MAKE({parent['name']});
{parent['name']} ref = {func_name}({arg_list});
*$o0 = ref;
{copy_inputs}
                '''
            else:
                exec_str = f'''\
$o0 = MAKE({parent['name']});
{parent['name']} ref = {func_name}({arg_list});
*$o0 = ref;
{copy_inputs}
                '''
        elif scope_type == CPPScopeType.METHOD:
            inputs = [parent['name']] + inputs
            outputs = [parent['name']] + outputs
            copy_inputs = '\n'.join([
                f'$o{i} = $i{i};' for i in range(len(inputs))
            ])
            arg_list = []
            idx_input = 1
            idx_arg = 0
            for i in range(len(resolved)):
                k = resolved[i]
                if type(k) is str:
                    # raw type
                    arg_list.append(k)
                else:
                    if _is_live_type(k):
                        if sig.func_args.args[i].base_type.is_ptr:
                            arg_list.append(f'$i{idx_input}')
                        else:
                            arg_list.append(f'*$i{idx_input}')
                        idx_input += 1
                    else:
                        arg_list.append(f'$a{idx_arg}')
                        idx_arg += 1
            arg_list = ', '.join(arg_list)

            if func_base_type is not None and _is_live_type(func_base_type):
                # Method-constructor
                outputs.append(func_base_type['name'])
                exec_str = f'''\
$o{len(inputs)} = MAKE({func_base_type['name']});
*$o{len(inputs)} = $i0->{sig.func_name.name}({arg_list});
{copy_inputs}
                '''
            else:
                if generate_dry:
                    exec_str = f'''\
FUZZ_ENDPOINT($i0->{sig.func_name.name}({arg_list});)
{copy_inputs}
                    '''
                else:
                    exec_str = f'''\
$i0->{sig.func_name.name}({arg_list});
{copy_inputs}
                    '''
        elif scope_type == CPPScopeType.STATIC:
            copy_inputs = '\n'.join([
                f'$o{i} = $i{i};' for i in range(len(inputs))
            ])
            if generate_dry:
                exec_str = f'''\
FUZZ_ENDPOINT({sig.func_name.name}({arg_list});)
{copy_inputs}
                '''
            else:
                exec_str = f'''\
{sig.func_name.name}({arg_list});
{copy_inputs}
                '''
        elif scope_type == CPPScopeType.DESTRUCTOR:
            inputs = [parent['name']] + inputs
            copy_inputs = '\n'.join([
                f'$o{i-1} = $i{i};' for i in range(1,len(inputs))
            ])
            if 'alloc_with_new' in parent and parent['alloc_with_new'] is True:
                exec_str = f'''\
delete $i0;
{copy_inputs}
                '''
            else:
                exec_str = f'''\
free($i0);
{copy_inputs}
                '''
        else:
            return None

        name = f'(auto) {parent["name"]}::{repr(sig)}'

        return CPPScope(name, inputs, outputs, args, exec_str)

    def __repr__(self):
        return f'CPPScope(name={self.name})'

    def resolve_all(self, schema: Schema, verbose=False):
        if not self.needs_resolve:
            return
        
        # TODO: maybe do this a bit cleaner
        # Process argument arrays.
        for i in range(len(self.args)):
            k = self.args[i]
            m = re.match('([^\[\]]*)\[([0-9]+)\]', k)

            if m is None:
                self.arg_count.append(1)
            else:
                typ, num = m.groups()
                self.args[i] = typ
                self.arg_count.append(int(num))

        to_resolve = [
            (self.inputs, self.inputs_ref),
            (self.outputs, self.outputs_ref),
            (self.args, self.args_ref),
        ]

        for src, res in to_resolve:
            for k in src:
                obj = schema.resolve(k)
                res.append(obj)

                if obj is None:
                    self.has_all_refs = False
                    self.missing_refs.append(k)

        for k in self.inputs_ref:
            if k is not None and not _is_live_type(k):
                self.has_all_refs = False
                print(f'[!] Error: {k["name"]} was defined as an input but it is not'\
                      f' a live type. Consider defining it in "args". (in "{self.name}")')

        for k in self.outputs_ref:
            if k is not None and not _is_live_type(k):
                self.has_all_refs = False
                print(f'[!] Error: {k["name"]} was defined as an output but it is not'\
                      f' a live type. (in "{self.name}")')

        for i in range(len(self.args_ref)):
            k = self.args_ref[i]
            if k is not None and _is_live_type(k):
                self.has_all_refs = False
                print(f'[!] Error: {k["name"]} was defined as an argument but it is '\
                      f'a live type. Consider defining it in "inputs". (in "{self.name}")')

            if k is not None and k['type'] =='enum' and self.arg_count[i] != 1:
                self.has_all_refs = False
                print(f'[!] Error: Array types are not supported for enums. Found {k["name"]}[{self.arg_count[i]}] in "{self.name}"')

    def is_resolved(self) -> bool:
        return self.has_all_refs

    def get_resolve_errors(self) -> List[str]:
        return self.missing_refs

    def build_scopedef(self):
        context_size = 0
        for i in range(len(self.args_ref)):
            k = self.args_ref[i]
            if k['type'] == 'simple':
                context_size += (k['context_size'] * self.arg_count[i])
            elif k['type'] == 'enum':
                context_size += 1

        return {
            'name': self.name,
            'inputs': [k['id'] for k in self.inputs_ref],
            'outputs': [k['id'] for k in self.outputs_ref],
            'context': context_size
        }

    def build_exec_shim(self, shim_name, soft_execution=False, generate_dry=False) -> str:
        load_args = []
        
        context_offset = 0
        arg_idx = 0

        var_map = {}

        bundle_input_idx = [i for i in range(len(self.inputs_ref)) if self.inputs_ref[i]['type'] == 'bundle']
        bundle_output_idx = [i for i in range(len(self.outputs_ref)) if self.outputs_ref[i]['type'] == 'bundle']

        assert len(bundle_input_idx) <= 1
        assert len(bundle_output_idx) <= 1

        for i in range(len(self.inputs_ref)):
            name = f'_i{i}'
            if self.inputs_ref[i]['type'] == 'bundle':
                # Input bundle has two forms:
                # 1. input only, i.e. reference the bundle directly (in unlink procedure)
                # 2. input+output, reference just the active type
                if len(bundle_output_idx) == 0:
                    # form 1
                    load_args.append(CPP_LOAD_REF.format(
                        var_type='GFUZZ_BUNDLE',
                        arg_name=name,
                        in_ref_idx=i
                    ))
                    var_map[f'$i{i}'] = name
                else:
                    # form 2
                    load_args.append(CPP_LOAD_REF.format(
                        var_type='GFUZZ_BUNDLE',
                        arg_name=name,
                        in_ref_idx=i
                    ))
                    var_type = self.inputs_ref[i]['active']
                    var_map[f'$i{i}'] = f'(({var_type} *){name}->active)'
            else:
                load_args.append(CPP_LOAD_REF.format(
                    var_type=self.inputs_ref[i]['name'],
                    arg_name=name,
                    in_ref_idx=i
                ))
                var_map[f'$i{i}'] = name
        
        context_offset = 0
        for i in range(len(self.args_ref)):
            name = f'_a{i}'
            k = self.args_ref[i]

            if k['type'] == 'simple':
                if self.arg_count[i] == 1:
                    fmt = k['load'] if 'load' in k else CPP_LOAD_SIMPLE
                    load_args.append(fmt.format(
                        var_type=k['name'],
                        arg_name=name,
                        context_offset=context_offset
                    ))
                    context_offset += k['context_size']
                else:
                    fmt = k['load_arr'] if 'load_arr' in k else CPP_LOAD_SIMPLE_ARRAY
                    load_args.append(fmt.format(
                        var_type=k['name'],
                        count=self.arg_count[i],
                        arg_name=name,
                        context_offset=context_offset,
                        context_size=k['context_size']
                    ))
                    context_offset += k['context_size'] * self.arg_count[i]
            elif k['type'] == 'enum':
                cases = [
                    CPP_ENUM_CASE.format(
                        case=i,
                        arg_name=name,
                        enum_value=f'{k["name"]}::{k["values"][i]}'
                    )
                    for i in range(len(k['values']))
                ]
                load_args.append(CPP_LOAD_ENUM.format(
                    var_type=k['name'],
                    arg_name=name,
                    enum_size=len(k['values']),
                    context_offset=context_offset,
                    enum_cases=''.join(cases)
                ))
                context_offset += 1
            
            var_map[f'$a{i}'] = name

        # Predefine scope outputs.
        scope_outputs = []
        for i in range(len(self.outputs_ref)):
            name = f'_o{i}'
            if self.outputs_ref[i]['type'] == 'bundle':
                # TODO: this is hacky
                # Currently bundle ouput has two forms:
                # 1. bundle output only, i.e. we are allocating a new bundle.
                # 2. bundle input+output, i.e. the bundle needs to be preserved so we copy it.
                if len(bundle_input_idx) == 0:
                    # form 1
                    load_args.append('    GFUZZ_BUNDLE *{name};\n'.format(
                        name=name
                    ))
                    # Reference the bundle directly.
                    var_map[f'$o{i}'] = name
                else:
                    # form 2, copy the input bundle and reference the active type.
                    load_args.append('    GFUZZ_BUNDLE *{name} = (GFUZZ_BUNDLE *)in_ref[{idx}];\n'.format(
                        name=name,
                        idx=bundle_input_idx[0]
                    ))
                    # Reference the active type.
                    var_map[f'$o{i}'] = f'({name}->active)'
            else:
                load_args.append('    {var_type} *{name};\n'.format(
                    var_type=self.outputs_ref[i]['name'],
                    name=name
                ))
                var_map[f'$o{i}'] = name
    
            scope_outputs.append(name)

        exec_fn = self.exec

        # indent
        exec_fn = '\n'.join(['    ' + x for x in exec_fn.split('\n')])

        for key in var_map:
            exec_fn = exec_fn.replace(key, var_map[key])
        exec_fn = exec_fn.replace('$$', '$')
        exec_fn = exec_fn + '\n'

        save_args = []
        for i in range(len(scope_outputs)):
            save_args.append(CPP_SAVE_REF.format(
                out_ref_idx=i,
                arg_name=scope_outputs[i]
            ))

        code = CPP_TEMPLATE_MAIN.format(
            comment=repr(self),
            shim_name=shim_name,
            load_args=''.join(load_args),
            fn_call=exec_fn,
            save_args=''.join(save_args)
        )

        return code

    def build_write_shim(self, shim_name) -> str:
        load_args = []
        inner_load_args = []
        
        context_offset = 0
        arg_idx = 0

        var_map = {}
        arg_map = {}

        bundle_input_idx = [i for i in range(len(self.inputs_ref)) if self.inputs_ref[i]['type'] == 'bundle']
        bundle_output_idx = [i for i in range(len(self.outputs_ref)) if self.outputs_ref[i]['type'] == 'bundle']

        assert len(bundle_input_idx) <= 1
        assert len(bundle_output_idx) <= 1

        # for i in range(len(self.inputs_ref)):
        #     name = f'_i{i}'
        #     if self.inputs_ref[i]['type'] == 'bundle':
        #         # Input bundle has two forms:
        #         # 1. input only, i.e. reference the bundle directly (in unlink procedure)
        #         # 2. input+output, reference just the active type
        #         if len(bundle_output_idx) == 0:
        #             # form 1
        #             load_args.append(CPP_LOAD_REF.format(
        #                 var_type='GFUZZ_BUNDLE',
        #                 arg_name=name,
        #                 in_ref_idx=i
        #             ))
        #             var_map[f'$i{i}'] = name
        #         else:
        #             # form 2
        #             load_args.append(CPP_LOAD_REF.format(
        #                 var_type='GFUZZ_BUNDLE',
        #                 arg_name=name,
        #                 in_ref_idx=i
        #             ))
        #             var_type = self.inputs_ref[i]['active']
        #             var_map[f'$i{i}'] = f'(({var_type} *){name}->active)'
        #     else:
        #         load_args.append(CPP_LOAD_REF.format(
        #             var_type=self.inputs_ref[i]['name'],
        #             arg_name=name,
        #             in_ref_idx=i
        #         ))
        #         var_map[f'$i{i}'] = name

        for i in range(len(self.inputs_ref)):
            name = f'_i{i}'
            if self.inputs_ref[i]['type'] == 'bundle':
                # Input bundle has two forms:
                # 1. input only, i.e. reference the bundle directly (in unlink procedure)
                # 2. input+output, reference just the active type
                if len(bundle_output_idx) == 0:
                    # form 1
                    load_args.append(CPP_LOAD_REF_WRITE.format(
                        arg_name=name,
                        in_ref_idx=i
                    ))
                    var_map[f'$i{i}'] = f'"var_" << {name}'
                else:
                    # form 2
                    load_args.append(CPP_LOAD_REF_WRITE.format(
                        arg_name=name,
                        in_ref_idx=i
                    ))
                    var_type = self.inputs_ref[i]['active']
                    var_map[f'$i{i}'] = f'"(({var_type} *)var_" << {name} << "->active)"'
            else:
                load_args.append(CPP_LOAD_REF_WRITE.format(
                    arg_name=name,
                    in_ref_idx=i
                ))
                var_map[f'$i{i}'] = f'"var_" << {name}'

        
        context_offset = 0
        for i in range(len(self.args_ref)):
            name = f'_a{i}'
            k = self.args_ref[i]

            if k['type'] == 'simple':
                if self.arg_count[i] == 1:
                    fmt = k['load'] if 'load' in k else CPP_LOAD_SIMPLE
                    load_args.append(fmt.format(
                        var_type=k['name'],
                        arg_name=name,
                        context_offset=context_offset
                    ))
                    context_offset += k['context_size']
                    if 'print_cast' in k:
                        name = f'({k["print_cast"]})_a{i}'
                else:
                    fmt = k['load_arr'] if 'load_arr' in k else CPP_LOAD_SIMPLE_ARRAY
                    inner_load_args.append(fmt.format(
                        var_type=k['name'],
                        count=self.arg_count[i],
                        arg_name=name,
                        context_offset=context_offset,
                        context_size=k['context_size']
                    ))
                    inner_load_args.append(CPP_PRINT_SIMPLE_ARRAY.format(
                        var_type=k['name'],
                        count=self.arg_count[i],
                        arg_name=name,
                        print_cast=f'({k["print_cast"]})' if 'print_cast' in k else ''
                    ))
                    # inner_load_args.append(CPP_LOAD_SIMPLE_ARRAY_WRITE.format(
                    #     var_type=k['name'],
                    #     count=self.arg_count[i],
                    #     arg_name=name,
                    #     context_offset=context_offset,
                    #     context_size=k['context_size'],
                    #     print_cast=f'({k["print_cast"]})' if 'print_cast' in k else ''
                    # ))
                    context_offset += k['context_size'] * self.arg_count[i]
                    # name references array
                    name = f'"_a{i}"'
            elif k['type'] == 'enum':
                cases = [
                    CPP_ENUM_CASE_WRITE.format(
                        case=i,
                        arg_name=name,
                        enum_value=f'{k["name"]}::{k["values"][i]}'
                    )
                    for i in range(len(k['values']))
                ]
                load_args.append(CPP_LOAD_ENUM_WRITE.format(
                    var_type=k['name'],
                    arg_name=name,
                    enum_size=len(k['values']),
                    context_offset=context_offset,
                    enum_cases=''.join(cases)
                ))
                context_offset += 1
            
            arg_map[f'$a{i}'] = name

        # Predefine scope outputs.
        scope_outputs = []
        for i in range(len(self.outputs_ref)):
            name = f'_o{i}'
            var_type = self.outputs_ref[i]['name']
            if self.outputs_ref[i]['type'] == 'bundle':
                var_type = 'GFUZZ_BUNDLE'
            load_args.append(CPP_NEW_REF_CUSTOM.format(
                name=name,
                var_type=var_type
            ))
            var_map[f'$o{i}'] = f'"var_" << {name}'
            scope_outputs.append(name)


        # Format exec code as a printed string.

        # (double indent)
        write_fn = '        ' + _escape_text(self.exec.strip())
        write_fn = write_fn.replace('\n', '\\n        ')

        # Replace largest macros first. i.e. "$i10" before "$i1"
        for key in sorted(var_map, key=len, reverse=True):
            write_fn = write_fn.replace(key, f'" << {var_map[key]} << "')
        for key in sorted(arg_map, key=len, reverse=True):
            write_fn = write_fn.replace(key, f'" << {arg_map[key]} << "')
        write_fn = write_fn.replace('$$', '$')
        write_fn = f'    std::cout << "{write_fn}" << std::endl;\n'

        save_args = []
        for i in range(len(scope_outputs)):
            save_args.append(CPP_SAVE_REF.format(
                out_ref_idx=i,
                arg_name=scope_outputs[i]
            ))

        code = CPP_TEMPLATE_MAIN_WRITE.format(
            comment=repr(self),
            shim_name=shim_name,
            load_args=''.join(load_args),
            inner_load_args=''.join(inner_load_args),
            fn_call=write_fn,
            save_args=''.join(save_args)
        )

        return code


def _apply_signature_filter(sig: str, ignore_keywords: List[str] = []) -> str:
    filtered = sig
    for word in ignore_keywords:
        filtered = filtered.replace(word, '')
    return filtered


def _build_custom_scope(info: dict) -> CPPScope:
    try:
        scope = CPPScope.from_dict(info)
        return scope
    except:
        print(f'[!] Unable to process custom scope: {info}')
        return None


def collect_scopes(schema: Schema, ignore_keywords: List[str] = [], generate_dry: bool = False) -> Tuple[List[CPPScope], int, dict]:
    """Enumerate methods in a schema and return CPPScope objects.
    
    Args:
    - schema: The Schema object to enumerate.
    - ignore_keywords: If set, these keywords will be removed from function
      signatures. For example, this is useful if certain functions have keywords
      like "WARN_UNUSED" which are really attributes.

    Returns:
    - scopes, max_num, errors
    """
    scopes = []
    max_num = 0

    # (obj, sig, err)
    errors = []

    for k in schema.objects:
        obj = schema.objects[k]

        if len(obj['headers']) == 0 and len(obj['c_headers']) == 0:
            continue

        if obj['type'] in ['class', 'struct']:

            # (signature, is_static)
            sigs: List[Tuple[str, bool]] = []
            custom: List[CPPScope] = []

            if 'methods' in obj:
                for sig in obj['methods']:
                    max_num += 1
                    if type(sig) is str:
                        sigs.append((sig, False))
                    else:
                        custom.append(_build_custom_scope(sig))

            if 'static_methods' in obj:
                for sig in obj['static_methods']:
                    max_num += 1
                    if type(sig) is str:
                        sigs.append((sig, True))
                    else:
                        custom.append(_build_custom_scope(sig))

            scopes += [x for x in custom if x is not None]

            for sig, is_static in sigs:
                sig = _apply_signature_filter(sig, ignore_keywords)
                psig = parse_signature(sig)
                if psig is None:
                    errors.append((obj, sig, 'parse error'))
                    # print(f'[!] Could not parse signature: {sig}')
                    continue

                try:
                    scope = CPPScope.from_signature(schema, obj, psig, is_static, generate_dry=generate_dry)
                except Exception as e:
                    errors.append((obj, sig, 'parse error'))
                    print(f'[!] Error while parsing: {sig}')
                    print(e)
                    continue

                scopes.append(scope)


        if obj['type'] in ['class', 'struct']:
            # Check if user wants to add a default destructor.
            if 'default_destructor' in obj and obj['default_destructor'] is True:
                max_num += 1
                scopes.append(CPPScope.destructor_for(schema, obj))

    return scopes, max_num, errors


def collect_headers(schema: Schema) -> Tuple[List[str], List[str]]:
    """Returns (headers, c_headers)."""
    headers = set()
    c_headers = set()

    for k in schema.objects:
        obj = schema.objects[k]
        if obj['type'] in ['struct', 'class', 'enum']:
            if 'headers' in obj:
                headers |= set(obj['headers'])
            if 'c_headers' in obj:
                c_headers |= set(obj['c_headers'])

    return sorted(list(headers)), sorted(list(c_headers))


def make_exec_harness(schema: Schema, scopes: List[CPPScope], soft_execution: bool = False, generate_dry: bool = False) -> str:
    shims = [
        scopes[i].build_exec_shim(f'shim_{i}', soft_execution, generate_dry)
        for i in range(len(scopes))
    ]
    shim_code = '\n'.join(shims)

    headers, c_headers = collect_headers(schema)
    includes = [
        CPP_INCLUDE.format(header=h)
        for h in headers if h.endswith('.h')
    ] + [
        CPP_INCLUDE_LIB.format(header=h)
        for h in headers if h.startswith('<') and h.endswith('>')
    ] + [
        CPP_INCLUDE_C.format(header=h)
        for h in c_headers
    ]
    includes = ''.join(includes)

    # Check for custom initializer/finalizer
    global_init = ''
    initializer = ''
    finalizer = ''
    for k in schema.objects:
        if schema.objects[k]['type'] == 'config':
            if 'global_init' in schema.objects[k]:
                global_init = schema.objects[k]['global_init']
            if 'initializer' in schema.objects[k]:
                initializer = schema.objects[k]['initializer']
            if 'finalizer' in schema.objects[k]:
                finalizer = schema.objects[k]['finalizer']

    code = FULL_HARNESS.format(
        includes=includes,
        header=SHIM_HEADER.format(
            global_init=global_init,
            initializer=initializer,
            finalizer=finalizer,
            macros=SHIM_MACROS + (SHIM_MACROS_DRY if generate_dry else '')
        ),
        shim_code=shim_code,
        shim_array=SHIM_ARRAY.format(
            shims='\n'.join(
                f'    &shim_{i},' for i in range(len(shims))
            )
        )
    )

    return code


def make_write_harness(schema: Schema, scopes: List[CPPScope]) -> str:
    shims = [
        scopes[i].build_write_shim(f'shim_{i}')
        for i in range(len(scopes))
    ]
    shim_code = '\n'.join(shims)

    headers, c_headers = collect_headers(schema)
    includes = [
        CPP_INCLUDE.format(header=h)
        for h in headers if h.endswith('.h')
    ] + [
        CPP_INCLUDE_LIB.format(header=h)
        for h in headers if h.startswith('<') and h.endswith('>')
    ] + [
        CPP_INCLUDE_C.format(header=h)
        for h in c_headers
    ]
    includes = ''.join(includes)
    header_string = includes.replace('"', "\\\"").replace('\n', '\\n')

    code = FULL_HARNESS.format(
        includes='',
        header=SHIM_HEADER_WRITE.format(
            header_string=header_string,
            macros=SHIM_MACROS.replace('"', "\\\"").replace('\n', '\\n')
        ),
        shim_code=shim_code,
        shim_array=SHIM_ARRAY.format(
            shims='\n'.join(
                f'    &shim_{i},' for i in range(len(shims))
            )
        )
    )

    return code


def make_fuzz_schema(schema: Schema, scopes: List[CPPScope]) -> dict:
    defs = [k.build_scopedef() for k in scopes]
    types = [{
        'id': schema.objects[k]['id'],
        'name': schema.objects[k]['name']
    } for k in schema.objects if schema.objects[k]['type'] in ['struct', 'class', 'bundle']]

    return {
        'types': types,
        'scopes': defs
    }


def _enumerate_bundleable(bundle: dict, types: List[dict]) -> List[int]:
    out = []
    for i in range(len(types)):
        typ = types[i]
        # TODO: nested bundling (hard)

        # if typ['type'] == 'bundle':
        #     if typ['inactive'] == bundle['active']:
        #         out.append(i)
        # else:

        if typ['name'] == bundle['active']:
            out.append(i)
    
    return out


def _compose_bundle(outer: dict, inner: dict):
    """
    outer has form <A,B>
    inner has form <B,C>

    produces a new bundle of form <A,<B,C>>
    """
    return {
        'type': 'bundle',
        'name': f'(auto) ({outer["name"]}, {inner["name"]})',
        'active': outer['active'],
        'inactive': inner['name']
    }


def make_bundled_scope(schema: Schema, scope: CPPScope, bundle: dict) -> CPPScope:

    active_input_idx = _enumerate_bundleable(bundle, scope.inputs_ref)
    active_output_idx = _enumerate_bundleable(bundle, scope.outputs_ref)

    if len(active_input_idx) != 1 or len(active_output_idx) != 1:
        # TODO: warn user if len is greater than 1, i.e. we can't infer what
        # the bundled scope should look like.
        return None

    in_idx = active_input_idx[0]
    out_idx = active_output_idx[0]

    in_typ = scope.inputs_ref[in_idx]
    out_typ = scope.outputs_ref[out_idx]

    in_bundle = bundle
    out_bundle = bundle

    # Check if we need to compose bundles.
    if in_typ['type'] == 'bundle':
        comp = _compose_bundle(in_typ, bundle)
        comp = schema.add_unique(comp)
        in_bundle = comp

    if out_typ['type'] == 'bundle':
        comp = _compose_bundle(out_typ, bundle)
        comp = schema.add_unique(comp)
        out_bundle = comp

    bscope = CPPScope(f'bundled_{scope.name}', [], [], [], scope.exec)
    
    inputs_ref = scope.inputs_ref[:in_idx] + [in_bundle] + scope.inputs_ref[in_idx+1:]
    outputs_ref = scope.outputs_ref[:out_idx] + [out_bundle] + scope.outputs_ref[out_idx+1:]

    bscope.inputs_ref = inputs_ref
    bscope.outputs_ref = outputs_ref
    bscope.args_ref = scope.args_ref
    bscope.arg_count = scope.arg_count

    return bscope


def duplicate_bundle_scopes(schema: Schema, scopes: List[CPPScope]) -> List[CPPScope]:
    bundle_defs = [
        schema.objects[k] for k in schema.objects 
        if schema.objects[k]['type'] == 'bundle'
    ]

    extra_scopes = []

    for bundle in bundle_defs:
        for scope in scopes:
            bscope = make_bundled_scope(schema, scope, bundle)
            if bscope:
                extra_scopes.append(bscope)

    return scopes + extra_scopes


def generate_harness(schema: Schema, output_path: str, soft_execution: bool = False, ignore_keywords: List[str] = [], generate_dry: bool =False):

    schema.assign_ids()

    # 1. Collect and parse scopes.
    raw_scopes, max_num, errors = collect_scopes(schema, ignore_keywords, generate_dry)

    if max_num == 0:
        print('No scopes found')
        exit(0)

    paths = list(set([x[0]['orig_path'] for x in errors]))
    for p in paths:
        print(f'{p}:')
        sub_errors = [x for x in errors if x[0]['orig_path'] == p]

        for obj, sig, typ in sub_errors:
            print(f'- ({typ}) {obj["name"]} "{sig}"')

    # 2. Resolve type names and compute scope details.
    for s in raw_scopes:
        s.resolve_all(schema, verbose=True)

    # 3. Filter out unresolvable scopes.
    scopes = [k for k in raw_scopes if k.is_resolved()]
    unresolved = [k for k in raw_scopes if not k.is_resolved()]

    # name: count
    missing_refs: Dict[str, int] = {}

    for k in unresolved:
        for ref in k.get_resolve_errors():
            if not ref in missing_refs:
                missing_refs[ref] = 0
            missing_refs[ref] += 1

    missing_refs_sorted = sorted(
        [(k, missing_refs[k]) for k in missing_refs],
        key=lambda x:x[1],
        reverse=True
    )

    if len(missing_refs_sorted) > 0:
        print('\nMissing refs:')
        for k,c in missing_refs_sorted:
            print(f'- {k} ({c})')

    # 3.5. Enumerate scopes for bundles.
    scopes = duplicate_bundle_scopes(schema, scopes)

    # 4. Generate fuzzer files.
    fuzz_schema = make_fuzz_schema(schema, scopes)
    exec_code = make_exec_harness(schema, scopes, soft_execution, generate_dry)
    write_code = make_write_harness(schema, scopes)

    # Save generated components.
    path = pathlib.Path(output_path)
    open(path / 'schema.json', 'w').write(json.dumps(fuzz_schema))
    open(path / 'fuzz_exec.cpp', 'w').write(exec_code)
    open(path / 'fuzz_write.cpp', 'w').write(write_code)

    print('\n[Results]:')
    print(f'- Parsed {len(raw_scopes)} / {max_num} ({len(raw_scopes) * 100.0 / max_num:.1f}%)')
    print(f'- Generated {len(scopes)} / {max_num} ({len(scopes) * 100.0 / max_num:.1f}%)')


def register(sub):
    sub.add_argument('schema', help='Path to schema.yaml.')
    sub.add_argument('output_path', default='.', help='Folder to save generated fuzzer files.')
    sub.add_argument(
        '--enable_soft_execution', default=False, action='store_true', 
        help='If enabled, catch assertion errors in nodes and continue execution.')
    
    sub.add_argument('--ignore_keywords', default=[], type=str, nargs='+', 
        help='If set, ignore these keywords in function signatures.')

    sub.add_argument('--generate_dry', default=False, action='store_true',
        help='If enabled, wrap method calls in a no-opable FUZZ_ENDPOINT macro.')

def execute(args):
    base_path = pathlib.Path(__file__).parent / 'base_schema.yaml'
    base_schema = Schema.load(str(base_path))

    schema = Schema.load(args.schema)
    schema.add_all(base_schema)
    
    generate_harness(
        schema, 
        args.output_path, 
        args.enable_soft_execution,
        args.ignore_keywords,
        args.generate_dry
    )


GenCppAPI = CLIOpt(
    'cpp',
    'Generate a C++ harness.',
    register,
    execute
)


================================================
FILE: cli/gfuzz/commands/gen/cpp/test_cpp_sig.py
================================================

import unittest

from .cpp_sig import parse_signature, CPPArgument, CPPTypeModifier, CPPBaseType, CPPArgName



class TestCPPSig(unittest.TestCase):

    def test_invalid(self):
        invalid = [
            'void foo', # No args.
            'void foo(...)', # Invalid args.
            'void void foo()', # Double function type.
        ]

        for txt in invalid:
            self.assertIsNone(parse_signature(txt))

    def test_foo(self):
        sig = parse_signature('void foo()')
        self.assertEqual(sig.func_name.name, 'foo')
        self.assertEqual(len(sig.func_args.args), 0)

    def test_named_args(self):
        sig = parse_signature('void foo(int a, const char *b, MyRect &rect)')
        self.assertEqual(sig.func_name.name, 'foo')
        self.assertEqual(len(sig.func_args.args), 3)

        self.assertEqual(sig.func_args.args[0], CPPArgument(
            CPPTypeModifier(set()),
            CPPBaseType('int', is_ptr=False, is_ref=False),
            CPPArgName('a')
        ))

        self.assertEqual(sig.func_args.args[1], CPPArgument(
            CPPTypeModifier(set(['const'])),
            CPPBaseType('char', is_ptr=True, is_ref=False),
            CPPArgName('b')
        ))

        self.assertEqual(sig.func_args.args[2], CPPArgument(
            CPPTypeModifier(set()),
            CPPBaseType('MyRect', is_ptr=False, is_ref=True),
            CPPArgName('rect')
        ))

    def test_unnamed_args(self):
        sig = parse_signature('void foo(int, const char *, MyRect &, unsigned long)')
        self.assertEqual(sig.func_name.name, 'foo')
        self.assertEqual(len(sig.func_args.args), 4)

        self.assertEqual(sig.func_args.args[0], CPPArgument(
            CPPTypeModifier(set()),
            CPPBaseType('int', is_ptr=False, is_ref=False),
            CPPArgName(None)
        ))

        self.assertEqual(sig.func_args.args[1], CPPArgument(
            CPPTypeModifier(set(['const'])),
            CPPBaseType('char', is_ptr=True, is_ref=False),
            CPPArgName(None)
        ))

        self.assertEqual(sig.func_args.args[2], CPPArgument(
            CPPTypeModifier(set()),
            CPPBaseType('MyRect', is_ptr=False, is_ref=True),
            CPPArgName(None)
        ))

        self.assertEqual(sig.func_args.args[3], CPPArgument(
            CPPTypeModifier(set(['unsigned'])),
            CPPBaseType('long', is_ptr=False, is_ref=False),
            CPPArgName(None)
        ))

    def test_overloaded(self):
        sig = parse_signature('MyRect operator+=(MyRect other)')
        self.assertEqual(sig.func_name.name, 'operator+=')
        self.assertEqual(len(sig.func_args.args), 1)
    
        self.assertEqual(sig.func_args.args[0], CPPArgument(
            CPPTypeModifier(set()),
            CPPBaseType('MyRect', is_ptr=False, is_ref=False),
            CPPArgName('other')
        ))

        self.assertEqual(sig.func_type, CPPBaseType(
            'MyRect', is_ptr=False, is_ref=False
        ))

    def test_trailing_modifiers(self):
        sig = parse_signature('MyPoint MakePoint(int x, int y) const')
        self.assertEqual(sig.func_name.name, 'MakePoint')
        self.assertEqual(len(sig.func_args.args), 2)
    
        self.assertEqual(sig.func_args.args[0], CPPArgument(
            CPPTypeModifier(set()),
            CPPBaseType('int', is_ptr=False, is_ref=False),
            CPPArgName('x')
        ))

        self.assertEqual(sig.func_args.args[1], CPPArgument(
            CPPTypeModifier(set()),
            CPPBaseType('int', is_ptr=False, is_ref=False),
            CPPArgName('y')
        ))

        self.assertEqual(sig.func_type, CPPBaseType(
            'MyPoint', is_ptr=False, is_ref=False
        ))

    def test_raw_values(self):
        sig = parse_signature('MyType foo({nullptr}, int x, {MakeThing()})')
        
        self.assertTrue(sig.func_args.args[0].is_raw)
        self.assertFalse(sig.func_args.args[1].is_raw)
        self.assertTrue(sig.func_args.args[2].is_raw)

        self.assertEqual(sig.func_args.args[0].raw_value, 'nullptr')
        self.assertEqual(sig.func_args.args[2].raw_value, 'MakeThing()')

if __name__ == '__main__':
    unittest.main()

================================================
FILE: cli/gfuzz/commands/gen/gen.py
================================================

from ..cliopt import CLIOpt
from .cpp.gen_cpp import GenCppAPI


COMMANDS = [
    GenCppAPI
]

OPTIONS = {
    k._name: k for k in COMMANDS
}


def register(parser):
    sub = parser.add_subparsers(dest='gen_mode')

    for opt in COMMANDS:
        opt.add_args(sub)


def execute(args):
    if args.gen_mode in OPTIONS:
        OPTIONS[args.gen_mode].execute(args)
    else:
        return False


GenAPI = CLIOpt(
    'gen',
    'Generate a GraphFuzz harness.',
    register,
    execute
)


================================================
FILE: cli/gfuzz/commands/minimizer.py
================================================

import subprocess
import random

from .cliopt import CLIOpt


def template_for(word):
    if word.startswith('0x'):
        return '<pointer>'
    
    return word

def test_example(fuzzer, example, extra):
    open('.tmp_run', 'wb').write(example)

    p = subprocess.run(f'./{fuzzer} .tmp_run {extra}', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    #print(p)
    out = p.stderr.decode('ascii')

    tag = ''
    if 'error: ' in out:
        tag = 'error: '
    elif 'ERROR: ' in out:
        tag = 'ERROR: '
    else:
        return ''

    e = out.split(tag)[1].split('\n')[0]

    # Replace addresses with a template so ASLR doesn't affect crash output message.
    e = e.replace('(','').replace(')','')
    words = e.split()
    words = [template_for(x) for x in words]
    e = ' '.join(words)

    return e

def mutate(fuzzer, example):
    open('.min_in', 'wb').write(example)

    p = subprocess.run(
        f'./{fuzzer} --graphfuzz_ignore_invalid --graphfuzz_context_mutation_prob=0 --graphfuzz_mutate_one {random.randint(0,2**32-2)} .min_in .min_out',
        shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
    )

    if p.returncode != 0:
        return None
    
    ex = open('.min_out', 'rb').read()
    return ex

def minimize_crash(fuzzer, crash, extra='', early_stop=50):
    print('Minimizing %s...' % crash)

    base = open(crash, 'rb').read()
    print('Base case size: %d' % len(base))

    base_err = test_example(fuzzer, base, extra)
    if len(base_err) == 0:
        print('Base case doesn\'t crash')
        return

    print('---[Crash]---')
    print(base_err)
    print('-------------')

    print('Minimizing...')

    best = base

    last_min = 0

    i = 0
    while True:
        if i - last_min >= early_stop:
            print('No improvement for %d steps, stopping...' % early_stop)
            break

        m = mutate(fuzzer, best)

        # Check length.
        if m is None or len(m) >= len(best):
            continue

        # Check crash.
        i += 1
        err = test_example(fuzzer, m, extra)
        if err != base_err:
            continue

        print('[%d] Found smaller crash: %d' % (i, len(m)))
        best = m
        last_min = i

    fpath = f'{crash}.min'
    open(fpath, 'wb').write(best)
    print(f'Minimized crash saved to: {fpath}')

def register(sub):
    sub.add_argument('fuzzer', help='Path to fuzz_exec binary.')
    sub.add_argument('crash', help='Path to crash file.')
    sub.add_argument('-k', '--early_stop', default=50, type=int,
        help='Number of failed steps before quitting.')
    sub.add_argument('--extra', default="", help='Extra fuzzer args.')

def execute(args):
    minimize_crash(args.fuzzer, args.crash, args.extra, args.early_stop)

MinAPI = CLIOpt(
    'min',
    'Minimize a crash file.',
    register,
    execute
)


================================================
FILE: cli/gfuzz/commands/schema.py
================================================

import pathlib
from typing import Tuple
import yaml


import bs4
from bs4 import BeautifulSoup as BS
import tqdm


from .cliopt import CLIOpt


def parse_function(tag: bs4.element.Tag) -> str:
    """Convert a function memberdef tag to a signature string."""

    ret = str(tag.find('type').text)
    name = tag.find('name').string
    args = tag.find('argsstring').string
    
    return f'{ret} {name}{args}'.strip()


def parse_enum(tag: bs4.element.Tag, header: str) -> dict:
    name = str(tag.find('name').string)
    values = [
        str(x.find('name').string)
        for x in tag.find_all('enumvalue')
    ]

    return (f'enum_{name}', {
        'type': 'enum',
        'headers': [header],
        'name': name,
        'values': values
    })


def parse_typedef(tag: bs4.element.Tag, header: str) -> dict:
    # The name of the newly defined type.
    typ = str(tag.find('type').string)
    name = str(tag.find('name').string)

    return (f'typedef_{name}', {
        'type': 'typedef',
        'headers': [header],
        'value': typ,
        'name': name
    })


def extract_file(root: pathlib.Path, refid: str) -> Tuple[str, dict]:
    """Extract file information.
    
    """
    path = root / f'{refid}.xml'
    dat = BS(open(path, 'r'), features="lxml")

    compoundname = str(dat.find('compoundname').string)

    info = []

    for k in dat.find_all('memberdef', kind='enum'):
        info.append(parse_enum(k, header=compoundname))

    for k in dat.find_all('memberdef', kind='typedef'):
        info.append(parse_typedef(k, header=compoundname))

    # Bundle global functions by file so we can organize and filter them.
    file_info = {}
    file_info['type'] = 'file'
    file_info['name'] = compoundname
    file_info['headers'] = [
        str(k.string)
        for k in dat.find_all('includes')
    ]
    file_info['methods'] = [
        parse_function(k)
        for k in dat.find_all('memberdef', kind='function', prot='public')
    ]

    # Ignore files that have no global functions.
    if len(file_info['methods']) > 0:
        info.append((f'file_{compoundname}', file_info))

    return info


def extract_struct(root: pathlib.Path, refid: str) -> Tuple[str, dict]:
    """Extract struct information.
    
    Returns (refid, info) where info contains:
    - type: "struct"
    - name: Name of the struct.
    - headers: A list of header files used by this struct.
    - methods: A list of function signatures.
    """
    path = root / f'{refid}.xml'
    dat = BS(open(path, 'r'), features="lxml")
    
    info = {}
    info['type'] = 'struct'
    info['name'] = str(dat.find('compoundname').string)
    info['default_destructor'] = True
    info['headers'] = [
        str(k.string)
        for k in dat.find_all('includes')
    ]
    info['methods'] = [
        parse_function(k)
        for k in dat.find_all('memberdef', kind='function', static='no', prot='public')
    ]
    info['static_methods'] = [
        parse_function(k)
        for k in dat.find_all('memberdef', kind='function', static='yes', prot='public')
    ]
    
    return [(f'struct_{info["name"]}', info)]


def extract_all(root: pathlib.Path) -> dict:
    index = root / 'index.xml'
    dat = BS(open(index, 'r'), features="lxml")
    
    info = []
    
    for k in tqdm.tqdm(dat.find_all('compound', kind='struct'), desc='Parsing structs...'):
        info += extract_struct(root, str(k['refid']))

    for k in tqdm.tqdm(dat.find_all('compound', kind='class'), desc='Parsing classes...'):
        info += extract_struct(root, str(k['refid']))

    for k in tqdm.tqdm(dat.find_all('compound', kind='file'), desc='Parsing files...'):
        info += extract_file(root, str(k['refid']))

    
    return {k:v for k,v in info}


def run_infer(args):
    try:
        info = extract_all(pathlib.Path(args.doxygen_xml))
    except:
        print('[!] Could not parse doxygen output. Make sure there is an ' \
              '"index.xml" file in the target directory.')
        return

    open(args.output, 'w').write(yaml.dump(info))

    print(f'[*] Generated a schema with {len([k for k in info])} items.')


COMMANDS = {
    'infer': run_infer,
}


def register(parser):
    sub = parser.add_subparsers(dest='schema_mode')

    infer_parser = sub.add_parser('infer', help='Infer a schema from Doxygen xml.')
    infer_parser.add_argument('doxygen_xml', help='Path to a folder containing Doxygen xml.')
    infer_parser.add_argument('output', help='Path to output *.yaml file.')


def execute(args):
    if args.schema_mode in COMMANDS:
        COMMANDS[args.schema_mode](args)
    else:
        return False


SchemaAPI = CLIOpt(
    'schema',
    'Schema subcommands.',
    register,
    execute
)


================================================
FILE: cli/gfuzz/docker_util.py
================================================

import pathlib
import subprocess


def check_docker():
    """Check if docker is available as a shell command."""
    r = subprocess.run('docker -v', shell=True, stdout=subprocess.PIPE, 
        stderr=subprocess.PIPE)

    output = r.stdout.decode('ascii')
    if 'Docker version' in output:
        return

    print('Error: docker not found on path')
    exit(-1)


def build_image(path: pathlib.Path, tag: str):
    """Build a docker image.
    
    Args:
    - path: Path to a folder with a Dockerfile.
    - tag: Name to use as a tag.
    """
    r = subprocess.run(
        f'docker build {path} -t {tag}', 
        shell=True)

    if r.returncode != 0:
        print('Error building image')
        exit(-1)


def run_image(tag: str, cmd: str, volumes: dict = {}, inner_args: str = '', run_args: str = ''):
    """Run a command in a docker image."""

    volume_str = ' '.join(
        f'-v {k}:{volumes[k]}' for k in volumes
    )

    r = subprocess.run(
        f'docker run {volume_str} {run_args} -it {tag} {cmd} {inner_args}', 
        shell=True)


================================================
FILE: cli/gfuzz/schema.py
================================================

from typing import Set
import yaml


def _validate_obj(name: str, obj: dict, orig_path: str) -> dict:
    if not 'type' in obj:
        print(f'[!] Error {name} has no attribute "type"')
        return None

    obj['orig_path'] = orig_path
    obj['headers'] = obj.get('headers') or []
    obj['c_headers'] = obj.get('c_headers') or []

    # Ensure headers are only .h files.
    # obj['headers'] = [x for x in obj['headers'] if x.endswith('.h')]

    obj['name'] = obj.get('name') or ''

    if obj['type'] in ['struct', 'class', 'file']:
        obj['methods'] = obj.get('methods') or []
        obj['static_methods'] = obj.get('static_methods') or []

    return obj

class Schema(object):
    """A schema represents the API surface of a target."""

    def __init__(self):
        self.objects = {}

    def add_all(self, other: 'Schema'):
        self.objects.update(other.objects)

    def add_unique(self, obj: dict) -> dict:
        v_id = len([k for k in self.objects])
        key = 'part_%d' % v_id

        # Return existing dict or append new.
        for k in self.objects:
            if self.objects[k]['name'] == obj['name']:
                return self.objects[k]

        obj['id'] = v_id
        self.objects[key] = obj
        return obj

    @staticmethod
    def load(path: str, loaded: Set[str] = None) -> 'Schema':
        s = Schema()
        objects = yaml.safe_load(open(path, 'r'))

        valid = {}

        for k in objects:
            if k == 'include':
                continue

            res = _validate_obj(k, objects[k], path)
            if res is not None:
                valid[k] = res

        s.objects = valid

        # Process include list.
        if loaded is None:
            loaded = set()
            
        include = objects.get('include') or []
        for sub_path in include:
            if sub_path in loaded:
                print(f'[*] Skipping duplicate include of "{sub_path}"')
                continue

            sub_schema = Schema.load(sub_path, loaded)
            loaded.add(sub_schema)

            s.add_all(sub_schema)

        return s

    def save(self, path: str):
        open(path, 'w').write(yaml.dump(self.objects))

    def resolve(self, name: str) -> dict:
        for k in self.objects:
            obj = self.objects[k]
            if obj['name'] == name:
                if obj['type'] == 'typedef':
                    return self.resolve(obj['value'])
                else:
                    return self.objects[k]

        return None

    def assign_ids(self):
        """Assign a unique 'id' attribute to each object."""
        i = 0
        for k in self.objects:
            self.objects[k]['id'] = i
            i += 1


================================================
FILE: cli/pyproject.toml
================================================
[tool.poetry]
name = "gfuzz"
version = "1.0.0"
description = ""
authors = ["hgarrereyn"]

[tool.poetry.dependencies]
python = "^3.6"
PyYAML = "^5.4.1"
beautifulsoup4 = "^4.9.3"
tqdm = "^4.62.0"
pyparsing = "^2.4.7"
dataclasses = {version = "^0.8", python = ">=3.6, <3.7"}
lxml = "^4.8.0"

[tool.poetry.dev-dependencies]

[tool.poetry.scripts]
gfuzz = "gfuzz.cli:main"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"


================================================
FILE: core/build_tests.sh
================================================

clang++ -o schemaTest \
    schemaTest.cpp \
    -pthread \
    -lgtest

clang++ -o graphTest \
    graphTest.cpp \
    graph.pb.cc \
    -pthread \
    -lprotobuf \
    -lgtest


================================================
FILE: core/graph.hpp
================================================

#include <algorithm>
#include <fstream>
#include <iostream>
#include <setjmp.h>
#include <signal.h>
#include <sstream>
#include <stdint.h>
#include <stdlib.h>
#include <tuple>
#include <unordered_set>
#include <vector>

#ifdef TEST
#include <gtest/gtest.h>
#endif

#include <google/protobuf/text_format.h>
#include <google/protobuf/repeated_field.h>
#include "graph.pb.h"

#include "schema.hpp"


extern "C" size_t LLVMFuzzerMutate(char *data, int size, int max_size);


// Represents an open scope connection.
struct NodeLink {
    int node_idx;   /* Index of the current node in the graph. */
    bool forward;   /* True if this is a forward connection. */
    int conn_idx;   /* Connection index in the node. */
    int type;       /* Type of the connection. */
    int layer;      /* Layer of the existing node (used for filtering). */
};


class TGraph {
private:
    Schema *schema;
    Graph g;

    // Define tests that can access private methods.
    #ifdef TEST
    FRIEND_TEST(graph, fillTerminal);
    FRIEND_TEST(graph, fillMultiTerminal);
    #endif

    /**
     * Adds a new node to the graph tree without linking it.
     * 
     * Returns the node index.
     */
    int AddNode(ScopeDef scope, unsigned int layer) {
        auto index = g.nodes_size();

        Node *n = g.add_nodes();
        ResetNode(n, scope);
        n->set_index(index);
        n->set_layer(layer);

        return index;
    }

    /**
     * Reset a node in-place. This method doesn't change the layer.
     */
    void ResetNode(Node *n, ScopeDef scope) {
        n->set_type(scope.type);
        n->clear_in_ref();
        n->clear_out_ref();

        for (unsigned long i = 0; i < scope.in_ref.size(); ++i) {
            NodeRef *r = n->add_in_ref();
            r->set_node_idx(-1);
        }
            
        for (unsigned long i = 0; i < scope.out_ref.size(); ++i) {
            NodeRef *r = n->add_out_ref();
            r->set_node_idx(-1);
        }

        if (scope.context_size > 0) {
            n->set_context(std::string(scope.context_size, '\x00'));
        }
    }

    /**
     * Returns a vector of NodeLink's containing open connections in the
     * current graph.
     */
    std::vector<NodeLink> GetOpenLinks() {
        std::vector<NodeLink> open;

        for (unsigned int i = 0; i < (unsigned int)g.nodes_size(); ++i) {
            Node n = g.nodes(i);
            ScopeDef scope = schema->GetScope(n.type());

            for (size_t j = 0; j < scope.in_ref.size(); ++j)
                if ((int)n.in_ref((int)j).node_idx() == -1)
                    open.push_back(
                        {(int)i, false, (int)j, (int)scope.in_ref[j], n.layer()});
            
            for (size_t j = 0; j < scope.out_ref.size(); ++j)
                if ((int)n.out_ref((int)j).node_idx() == -1)
                    open.push_back(
                        {(int)i, true, (int)j, (int)scope.out_ref[j], n.layer()});
        }

        return open;
    }

    std::vector<NodeLink> GetAllLinks() {
        std::vector<NodeLink> links;

        for (unsigned int i = 0; i < (unsigned int)g.nodes_size(); ++i) {
            Node n = g.nodes(i);
            ScopeDef scope = schema->GetScope(n.type());

            for (size_t j = 0; j < scope.in_ref.size(); ++j)
                links.push_back(
                    {(int)i, false, (int)j, (int)scope.in_ref[j], n.layer()});
            
            for (size_t j = 0; j < scope.out_ref.size(); ++j)
                links.push_back(
                    {(int)i, true, (int)j, (int)scope.out_ref[j], n.layer()});
        }

        return links;
    }

    /**
     * Link node A to node B. A->B is always a forward connection.
     */
    void Link(int node_a, int conn_a, int node_b, int conn_b) {
        NodeRef *ra = g.mutable_nodes(node_a)->mutable_out_ref(conn_a);
        ra->set_node_idx(node_b);
        ra->set_conn_idx(conn_b);

        NodeRef *rb = g.mutable_nodes(node_b)->mutable_in_ref(conn_b);
        rb->set_node_idx(node_a);
        rb->set_conn_idx(conn_a);
    }

    /**
     * Unlink node A from its forward connection.
     */
    void Unlink(int node_a, int conn_a) {
        NodeRef *ra = g.mutable_nodes(node_a)->mutable_out_ref(conn_a);
        auto node_b = ra->node_idx();
        auto conn_b = ra->conn_idx();
        ra->set_node_idx(-1);

        NodeRef *rb = g.mutable_nodes(node_b)->mutable_in_ref(conn_b);
        rb->set_node_idx(-1);
    }

    /**
     * Unlink Node b from its backward connection.
     */
    void UnlinkBackward(int node_b, int conn_b) {
        NodeRef *rb = g.mutable_nodes(node_b)->mutable_in_ref(conn_b);
        auto node_a = rb->node_idx();
        auto conn_a = rb->conn_idx();
        rb->set_node_idx(-1);

        NodeRef *ra = g.mutable_nodes(node_a)->mutable_out_ref(conn_a);
        ra->set_node_idx(-1);
    }

    /**
     * DFS on the graph structure in both directions. Visited nodes are added
     * to an unordered set.
     */
    void Visit(std::unordered_set<int> *seen, int idx) {
        if (idx == -1 || seen->count(idx)) return;
        seen->insert(idx);

        for (int i = 0; i < g.nodes(idx).in_ref_size(); ++i)
            Visit(seen, g.nodes(idx).in_ref(i).node_idx());

        for (int i = 0; i < g.nodes(idx).out_ref_size(); ++i)
            Visit(seen, g.nodes(idx).out_ref(i).node_idx());
    }

    /**
     * Reindex node n with a new index.
     * 
     * This method also updates neighbors of node n.
     */
    void ReindexNode(Node *n, int new_idx) {
        n->set_index(new_idx);

        for (int i = 0; i < n->in_ref_size(); ++i) {
            NodeRef r = n->in_ref(i);
            if (r.node_idx() == -1) continue;
            g.mutable_nodes(r.node_idx())->mutable_out_ref(r.conn_idx())->set_node_idx(new_idx);
        }

        for (int i = 0; i < n->out_ref_size(); ++i) {
            NodeRef r = n->out_ref(i);
            if (r.node_idx() == -1) continue;
            g.mutable_nodes(r.node_idx())->mutable_in_ref(r.conn_idx())->set_node_idx(new_idx);
        }
    }

    /**
     * Offset all node indexes and layers by a fixed amount to prepare for merging.
     */
    void ApplyOffset(int idx_offset, int layer_offset) {
        for (unsigned int i = 0; i < (unsigned int)g.nodes_size(); ++i) {
            Node *n = g.mutable_nodes(i);
            n->set_index(n->index() + idx_offset);
            n->set_layer(n->layer() + layer_offset);

            for (unsigned int j = 0; j < n->in_ref_size(); ++j) {
                NodeRef *r = n->mutable_in_ref(j);
                if (r->node_idx() == -1) continue;
                r->set_node_idx(r->node_idx() + idx_offset);
            }

            for (unsigned int j = 0; j < n->out_ref_size(); ++j) {
                NodeRef *r = n->mutable_out_ref(j);
                if (r->node_idx() == -1) continue;
                r->set_node_idx(r->node_idx() + idx_offset);
            }
        }
    }

    /**
     * Remove all nodes not in keep.
     */
    void Collapse(std::unordered_set<int> keep) {
        google::protobuf::RepeatedPtrField<Node> *nodes = g.mutable_nodes();
        
        unsigned int write_idx = 0;
        for (unsigned int i = 0; i < (unsigned int)g.nodes_size(); ++i) {
            if (keep.count(i)) {
                if (i != write_idx) {
                    ReindexNode(g.mutable_nodes(i), write_idx);
                    nodes->SwapElements(i, write_idx);
                }
                write_idx += 1;
            }
        }

        // Delete unused elements from the end.
        nodes->DeleteSubrange(write_idx, g.nodes_size() - write_idx);
    }

    /**
     * Append a node to the current graph.
     */
    void AppendNode(const Node &n2) {
        Node *n = g.add_nodes();
        n->set_type(n2.type());
        n->set_layer(n2.layer());
        n->set_index(n2.index());
        n->set_context(n2.context());

        for (unsigned long i = 0; i < n2.in_ref_size(); ++i) {
            NodeRef *r = n->add_in_ref();
            r->set_node_idx(n2.in_ref(i).node_idx());
            r->set_conn_idx(n2.in_ref(i).conn_idx());
        }

        for (unsigned long i = 0; i < n2.out_ref_size(); ++i) {
            NodeRef *r = n->add_out_ref();
            r->set_node_idx(n2.out_ref(i).node_idx());
            r->set_conn_idx(n2.out_ref(i).conn_idx());
        }
    }

    /**
     * Copy another graph into this one.
     */
    void CopyOther(TGraph other) {
        // Reindex all other nodes.
        unsigned int g1_size = (unsigned int)g.nodes_size();
        int g1_max_layer = g.nodes(0).layer();
        for (unsigned int i = 0; i < (unsigned int)g.nodes_size(); ++i) {
            if (g.nodes(i).layer() > g1_max_layer) {
                g1_max_layer = g.nodes(i).layer();
            }
        }
        other.ApplyOffset(g1_size, g1_max_layer);

        // Copy nodes.
        for (unsigned int i = 0; i < (unsigned int)other.g.nodes_size(); ++i) {
            AppendNode(other.g.nodes(i));
        }
    }

    /**
     * Normalize layer numbering to prevent integer overflows.
     */
    void SimplifyLayers() {
        // Generate a sorted ordering.
        std::vector<Node *> nodes;
        for (unsigned int i = 0; i < (unsigned int)g.nodes_size(); ++i) {
            nodes.push_back(g.mutable_nodes(i));
        }

        std::sort(nodes.begin(), nodes.end(), [](auto *lhs, auto *rhs) {
            if (lhs->layer() == rhs->layer()) {
                return lhs->index() < rhs->index();
            } else {
                return lhs->layer() < rhs->layer();
            }
        });

        // Iterate and assign new layers.
        int new_layer = 0;
        int curr_layer = nodes[0]->layer();

        for (unsigned int i = 0; i < nodes.size(); ++i) {
            if (nodes[i]->layer() != curr_layer) {
                curr_layer = nodes[i]->layer();
                new_layer += 1;
                nodes[i]->set_layer(new_layer);
            } else {
                nodes[i]->set_layer(new_layer);
            }
        }
    }

    /**
     * Set the layer of a node and ripple this layer across the graph.
     */
    void ResetLayers(unsigned int node_idx, int layer) {
        g.mutable_nodes(node_idx)->set_layer(layer);

        for (int i = 0; i < g.nodes(node_idx).in_ref_size(); ++i) {
            unsigned other_idx = g.nodes(node_idx).in_ref(i).node_idx();
            if (other_idx == -1 || g.nodes(other_idx).layer() < layer) continue;
            ResetLayers(other_idx, layer - 1);
        }

        for (int i = 0; i < g.nodes(node_idx).out_ref_size(); ++i) {
            unsigned other_idx = g.nodes(node_idx).out_ref(i).node_idx();
            if (other_idx == -1 || g.nodes(other_idx).layer() > layer) continue;
            ResetLayers(other_idx, layer + 1);
        }
    }

    /**
     * Recursively sample and append nodes from a type tree.
     */
    void AppendTree(unsigned int node_idx, unsigned int conn_idx, int layer, bool forward, TypeTree tree) {
        int sample = ((unsigned int)rand()) % tree.num_subtrees;
        unsigned int sample_idx = -1;
        while (sample >= 0) {
            sample_idx += 1;
            sample -= tree.children[sample_idx].num_subtrees;
        }

        ScopeTree stree = tree.children[sample_idx];
        ScopeDef root_def = schema->SampleSignatureIndex(stree.sig_idx);

        int next_layer = forward ? layer + 1 : layer - 1;
        int rev_layer = forward ? layer - 1 : layer + 1;

        unsigned int root = AddNode(root_def, next_layer);

        if (forward) {
            Link(node_idx, conn_idx, root, stree.conn_idx);
        } else {
            Link(root, stree.conn_idx, node_idx, conn_idx);
        }

        // Recurse through forward children.
        for (unsigned int i = 0; i < stree.children.size(); ++i) {
            AppendTree(root, i, next_layer, forward, stree.children[i]);
        }

        // Recurse through reverse children.
        for (unsigned int i = 0; i < stree.rev_children.size(); ++i) {
            unsigned int rev_conn_idx = i < stree.conn_idx ? i : i + 1;
            AppendTree(root, rev_conn_idx, rev_layer, !forward, stree.rev_children[i]);
        }
    }

    /**
     * Fill one connection with a finalizer or initializer.
     */
    void FillOneTerminal(NodeLink n) {
        TypeTree tree = (n.forward ? schema->GetFinalizer(n.type) 
                                   : schema->GetInitializer(n.type));
        AppendTree(n.node_idx, n.conn_idx, n.layer, n.forward, tree);
    }

    /**
     * Fill open connections with terminal nodes.
     */
    void FillTerminal() {
        auto open = GetOpenLinks();

        for (size_t i = 0; i < open.size(); ++i) {
            NodeLink n = open[i];
            FillOneTerminal(n);
        }
    }

    /**
     * Mutate the graph by invoking LLVMFuzzerMutate on a node's context.
     */
    bool MutateContext() {
        std::vector<int> with_context;
        for (unsigned int i = 0; i < (unsigned int)g.nodes_size(); ++i) {
            if (g.nodes(i).context().size() > 0) {
                with_context.push_back(i);
            }
        }

        if (with_context.size() == 0) return false;

        int node_idx = with_context[rand() % with_context.size()];
        std::string *s = g.mutable_nodes(node_idx)->mutable_context();

        if (s == nullptr) {
            return false;
        }

        LLVMFuzzerMutate((char *)&(*s)[0], (int)s->size(), (int)s->size());

        return true;
    }

    /**
     * Mutate by replacing a destructor scope with a random consumer scope.
     */
    void MutateExtendDestructor() {
        std::vector<unsigned int> destructors;
        for (unsigned int i = 0; i < (unsigned int)g.nodes_size(); ++i) {
            if (schema->IsDestructor(g.nodes(i).type())) {
                destructors.push_back(i);
            }
        }

        if (destructors.size() == 0) return;

        // Select a random destructor.
        auto target_idx = destructors[rand() % destructors.size()];

        // Unlink the destructor.
        NodeRef r = g.nodes(target_idx).in_ref(0);
        unsigned int parent_idx = r.node_idx();
        unsigned int parent_conn = r.conn_idx();
        Unlink(parent_idx, parent_conn);

        // Pick a new consumer.
        ScopeDef scope = schema->GetScope(g.nodes(target_idx).type());
        unsigned int ref_type = scope.in_ref[0];

        ScopeDef consumer;
        unsigned int consumer_conn_idx;
        std::tie(consumer, consumer_conn_idx) = schema->GetRandomConsumer(ref_type);

        // Replace the node.
        Node *n = g.mutable_nodes(target_idx);
        ResetNode(n, consumer);

        // Re-link.
        Link(parent_idx, parent_conn, target_idx, consumer_conn_idx);

        // Fill remaining spots.
        FillTerminal();
    }

    /**
     * Mutate by replacing a constructor scope with a random producer scope.
     */
    void MutateExtendConstructor() {
        std::vector<unsigned int> constructors;
        for (unsigned int i = 0; i < (unsigned int)g.nodes_size(); ++i) {
            if (schema->IsConstructor(g.nodes(i).type())) {
                constructors.push_back(i);
            }
        }

        if (constructors.size() == 0) return;

        // Select a random constructor.
        auto target_idx = constructors[rand() % constructors.size()];

        // Unlink the constructor.
        NodeRef r = g.nodes(target_idx).out_ref(0);
        unsigned int parent_idx = r.node_idx();
        unsigned int parent_conn = r.conn_idx();
        Unlink(target_idx, 0);

        // Pick a new producer.
        ScopeDef scope = schema->GetScope(g.nodes(target_idx).type());
        unsigned int ref_type = scope.out_ref[0];

        ScopeDef producer;
        unsigned int producer_conn_idx;
        std::tie(producer, producer_conn_idx) = schema->GetRandomProducer(ref_type);

        // Replace the node.
        Node *n = g.mutable_nodes(target_idx);
        ResetNode(n, producer);

        // Re-link.
        Link(target_idx, producer_conn_idx, parent_idx, parent_conn);

        // Fill remaining spots.
        FillTerminal();
    }

    /**
     * Mutate by cross-linking two nodes.
     *
     * If a non-zero split is provided, the producer node index will be strictly
     * less than split and the consumer node index will be greater than split.
     * This mechanism is used when crosslinking two different graphs.
     */
    void MutateCrosslink(unsigned int split=0) {
        assert(split <= g.nodes_size());

        // Early check.
        if (g.nodes_size() <= 2) {
            return;
        }

        // Generate a list of producers.
        // (node_idx, conn_idx, ref_type)
        std::vector<std::tuple<unsigned int, unsigned int, unsigned int>> producers;
        unsigned int producer_limit = split == 0 ? (unsigned int)g.nodes_size() : split;
        for (unsigned int i = 0; i < producer_limit; ++i) {
            ScopeDef scope = schema->GetScope(g.nodes(i).type());
            for (unsigned int j = 0; j < scope.out_ref.size(); ++j) {
                producers.push_back(std::make_tuple(i, j, scope.out_ref[j]));
            }
        }

        if (producers.size() == 0) return;

        unsigned int start_node;
        unsigned int start_conn;
        unsigned int start_type;
        std::tie(start_node, start_conn, start_type) = producers[rand() % producers.size()];

        NodeRef start_ref = g.nodes(start_node).out_ref(start_conn);
        unsigned int avoid_node = start_ref.node_idx();
        unsigned int avoid_conn = start_ref.conn_idx();

        int start_layer = g.nodes(start_node).layer();

        // Generate a list of consumers with specified type.
        // (node_idx, conn_idx)
        std::vector<std::tuple<unsigned int, unsigned int>> consumers;
        for (unsigned int i = split; i < (unsigned int)g.nodes_size(); ++i) {
            if (g.nodes(i).layer() <= start_layer) continue;

            ScopeDef scope = schema->GetScope(g.nodes(i).type());
            for (unsigned int j = 0; j < scope.in_ref.size(); ++j) {
                if (i == avoid_node && j == avoid_conn) continue;

                if (scope.in_ref[j] == start_type) {
                    consumers.push_back(std::make_tuple(i, j));
                }
            }
        }

        if (consumers.size() == 0) return;

        unsigned int end_node;
        unsigned int end_conn;
        std::tie(end_node, end_conn) = consumers[rand() % consumers.size()];

        // Unlink nodes.
        Unlink(start_node, start_conn);
        UnlinkBackward(end_node, end_conn);

        // Re-link.
        Link(start_node, start_conn, end_node, end_conn);

        // Remove orphaned nodes.
        std::unordered_set<int> component;
        Visit(&component, start_node);
        Collapse(component);

        FillTerminal();
    }

    /**
     * Mutate by replacing a consumer scope with a destructor.
     */
    void MutateTruncateDestructor() {
        // Generate a list of producers.
        // (node_idx, conn_idx)
        std::vector<std::tuple<unsigned int, unsigned int, unsigned int>> producers;
        for (unsigned int i = 0; i < (unsigned int)g.nodes_size(); ++i) {
            ScopeDef scope = schema->GetScope(g.nodes(i).type());
            for (unsigned int j = 0; j < scope.out_ref.size(); ++j) {
                producers.push_back(std::make_tuple(i, j, scope.out_ref[j]));
            }
        }

        if (producers.size() == 0) return;

        // Select a random producer.
        unsigned int start_node;
        unsigned int start_conn;
        unsigned int start_type;
        std::tie(start_node, start_conn, start_type) = producers[rand() % producers.size()];

        // Unlink target node.
        Unlink(start_node, start_conn);

        // Remove orphaned nodes.
        std::unordered_set<int> component;
        Visit(&component, start_node);
        Collapse(component);

        FillTerminal();
    }

    /**
     * Mutate by replacing a producer scope with a constructor.
     */
    void MutateTruncateConstructor() {
        // Generate a list of consumers.
        // (node_idx, conn_idx)
        std::vector<std::tuple<unsigned int, unsigned int, unsigned int>> consumers;
        for (unsigned int i = 0; i < (unsigned int)g.nodes_size(); ++i) {
            ScopeDef scope = schema->GetScope(g.nodes(i).type());
            for (unsigned int j = 0; j < scope.in_ref.size(); ++j) {
                consumers.push_back(std::make_tuple(i, j, scope.in_ref[j]));
            }
        }

        if (consumers.size() == 0) return;

        // Select a random producer.
        unsigned int end_node;
        unsigned int end_conn;
        unsigned int end_type;
        std::tie(end_node, end_conn, end_type) = consumers[rand() % consumers.size()];

        // Unlink target node.
        UnlinkBackward(end_node, end_conn);

        // Remove orphaned nodes.
        std::unordered_set<int> component;
        Visit(&component, end_node);
        Collapse(component);

        FillTerminal();
    }

    /**
     * Replace an endpoint with one that has the same signature.
     */
    void MutateSwapEquivalent() {
        unsigned int idx_a = rand() % g.nodes_size();

        ScopeDef def = schema->GetScope(g.nodes(idx_a).type());
        ScopeDef other = schema->WithMatchingSignature(def);

        if (def.type == other.type) return;

        g.mutable_nodes(idx_a)->set_type(other.type);
        
        std::string new_context(other.context_size, '\x00');
        g.mutable_nodes(idx_a)->set_context(new_context);
    }

    /**
     * Swap the index of two nodes on the same layer.
     */
    void MutateLayerIndex() {
        // Get a random node.
        unsigned int idx_a = rand() % g.nodes_size();
        int layer_a = g.nodes(idx_a).layer();

        // Find other nodes with the same layer.
        std::vector<unsigned int> other;
        for (unsigned int i = 0; i < g.nodes_size(); ++i) {
            if (i == idx_a || g.nodes(i).layer() != layer_a) continue;
            other.push_back(i);
        }

        if (other.size() == 0) return;

        unsigned int idx_b = other[rand() % other.size()];

        // Swap indexes
        ReindexNode(g.mutable_nodes(idx_a), idx_b);
        ReindexNode(g.mutable_nodes(idx_b), idx_a);
        g.mutable_nodes()->SwapElements(idx_a, idx_b);
    }

    /**
     * Given edge A->A, splice in an endpoint with signature Ax...->Ax...
     * (i.e. this usually adds a method call)
     */
    void MutateSpliceIn() {
        // Generate a list of producers.
        // (node_idx, conn_idx)
        std::vector<std::tuple<unsigned int, unsigned int, unsigned int>> producers;
        for (unsigned int i = 0; i < (unsigned int)g.nodes_size(); ++i) {
            ScopeDef scope = schema->GetScope(g.nodes(i).type());
            for (unsigned int j = 0; j < scope.out_ref.size(); ++j) {
                producers.push_back(std::make_tuple(i, j, scope.out_ref[j]));
            }
        }

        if (producers.size() == 0) return;

        // Select a random producer.
        unsigned int start_node;
        unsigned int start_conn;
        unsigned int start_type;
        std::tie(start_node, start_conn, start_type) = producers[rand() % producers.size()];

        // Find a scope to splice in.
        if (!schema->HasUser(start_type)) return;

        ScopeDef def;
        unsigned int in_idx;
        unsigned int out_idx;
        std::tie(def, in_idx, out_idx) = schema->GetRandomUser(start_type);

        int new_idx = AddNode(def, g.nodes(start_node).layer() + 1);

        // Unlink old connection.
        int back_node_idx = g.nodes(start_node).out_ref(start_conn).node_idx();
        int back_node_conn = g.nodes(start_node).out_ref(start_conn).conn_idx();
        Unlink(start_node, start_conn);

        // Add new connection
        Link(start_node, start_conn, new_idx, in_idx);
        Link(new_idx, out_idx, back_node_idx, back_node_conn);

        ResetLayers(new_idx, 0);

        FillTerminal();
    }

    /**
     * Given A->A->A, remove the middle scope.
     */
    void MutateSpliceOut() {
        std::vector<unsigned int> removable;
        for (int i = 0; i < g.nodes_size(); ++i) {
            if (schema->IsSpliceable(g.nodes(i).type())) {
                removable.push_back(i);
            }
        }

        if (removable.size() == 0) return;

        unsigned int node_idx = removable[rand() % removable.size()];

        unsigned int type;
        unsigned int in_idx;
        unsigned int out_idx;
        std::tie(type, in_idx, out_idx) = schema->GetRandomSplicePath(g.nodes(node_idx).type());

        // Unlink the middle node
        unsigned int prev_node = g.nodes(node_idx).in_ref(in_idx).node_idx();
        unsigned int prev_conn = g.nodes(node_idx).in_ref(in_idx).conn_idx();
        unsigned int next_node = g.nodes(node_idx).out_ref(out_idx).node_idx();
        unsigned int next_conn = g.nodes(node_idx).out_ref(out_idx).conn_idx();

        Unlink(node_idx, out_idx);
        Unlink(prev_node, prev_conn);
        Link(prev_node, prev_conn, next_node, next_conn);

        // Remove orphaned nodes.
        std::unordered_set<int> component;
        Visit(&component, prev_node);
        Collapse(component);

        FillTerminal();
    }

    /**
     * Perform a crossover mutation.
     *
     * Returns false if crossover is not possible.
     */
    bool MutateCross(TGraph other) {
        unsigned int g1_size = (unsigned int)g.nodes_size();

        // Copy other graph into this.
        CopyOther(other);

        MutateCrosslink(g1_size);

        SimplifyLayers();

        return true;
    }

public:
    TGraph(Schema *schema) : schema(schema) {}

    /**
     * Create a new graph from a seed with an upper bound on the node count.
     */
    bool Create(unsigned int seed, unsigned int max_nodes) {
        srand(seed);
        ScopeDef init = schema->GetRandomScope();
        return CreateWithScope(init);
    }

    bool CreateWithScope(ScopeDef def) {
        g = Graph();
        AddNode(def, 0);
        FillTerminal();

        return true;
    }

    bool Mutate(unsigned int seed, unsigned int max_nodes, float context_mutation_prob, int *mut_id) {
        srand(seed);

        if (((float)rand() / (float)RAND_MAX) < context_mutation_prob) {
            MutateContext();
            *mut_id = -1;
        } else {
            unsigned int mut_choice = rand() % 9;
            *mut_id = mut_choice;

            switch (mut_choice) {
                case 0: MutateCrosslink(); break;
                case 1: MutateTruncateDestructor(); break;
                case 2: MutateTruncateConstructor(); break;
                case 3: MutateLayerIndex(); break;
                case 4: MutateSwapEquivalent(); break;
                case 5: MutateExtendDestructor(); break;
                case 6: MutateExtendConstructor(); break;
                case 7: MutateSpliceIn(); break;
                case 8: MutateSpliceOut(); break;
            }

            // Remove orphaned nodes.
            std::unordered_set<int> component;
            Visit(&component, 0);
            Collapse(component);
        }

        return true;
    }

    bool Cross(TGraph other, unsigned int seed, unsigned int max_nodes) {
        srand(seed);
        MutateCross(other);

        // Remove orphaned nodes.
        std::unordered_set<int> component;
        Visit(&component, 0);
        Collapse(component);

        return true;
    }

    void Complete() {
        this->FillTerminal();
    }

    void PrintNode(Node n) {
        ScopeDef scope = schema->GetScope(n.type());
        std::cerr << "(" << n.index() << ")<" << n.layer() << ">" << scope.name << "::";

        std::cerr << "(";
        for (int j = 0; j < n.in_ref_size(); ++j) {
            if (j > 0) std::cerr << ", ";
            std::cerr << n.in_ref(j).node_idx() << "[" << n.in_ref(j).conn_idx() << "]";
        }
        std::cerr << ")(";
        for (int j = 0; j < n.out_ref_size(); ++j) {
            if (j > 0) std::cerr << ", ";
            std::cerr << n.out_ref(j).node_idx() << "[" << n.out_ref(j).conn_idx() << "]";
        }

        std::cerr << ")" << std::endl;
    }

    void PrintAll() {
        std::cerr << "-----------" << std::endl;
        for (unsigned int i = 0; i < (unsigned int)g.nodes_size(); ++i) {
            Node n = g.nodes(i);
            PrintNode(n);
        }
    }

    /**
     * Returns a vector of Node objects ordered by layer, ascending.
     */
    std::vector<Node> GetOrderedNodes() {
        std::vector<Node> nodes;
        for (unsigned int i = 0; i < (unsigned int)g.nodes_size(); ++i) {
            nodes.push_back(g.nodes(i));
        }

        std::sort(nodes.begin(), nodes.end(), [](const auto &lhs, const auto &rhs) {
            if (lhs.layer() == rhs.layer()) {
                return lhs.index() < rhs.index();
            } else {
                return lhs.layer() < rhs.layer();
            }
        });

        return nodes;
    }

    std::string Write(bool *err) {
        std::string out;
        if (!g.SerializeToString(&out)) *err = true;
        return out;
    }

    bool Read(std::string inp) {
        return g.ParseFromString(inp);
    }

    bool Validate() {
        if (g.nodes_size() == 0) return false;
        for (unsigned int i = 0; i < (unsigned int)g.nodes_size(); ++i) {
            Node n = g.nodes(i);
            ScopeDef scope = schema->GetScope(n.type());

            if (scope.in_ref.size() != (unsigned long)n.in_ref_size()) return false;
            if (scope.out_ref.size() != (unsigned long)n.out_ref_size()) return false;
        }
        return true;
    }
};


================================================
FILE: core/graph.proto
================================================

syntax = "proto3";

// A NodeRef identifies a doubly-linked connection between neighboring nodes.
//
// For example, given the graph:
// 
//     A(0) -> B(1)
//
// Node A would contain a NodeRef in its out_ref list:
// { node_idx: 1, conn_idx: 0 }
// Node B would contain a backreference in its in_ref list:
// { node_idx: 0, conn_idx: 0 }
//
// In a more complex graph such as:
// 
//     A(0)-\
//           x-C(2)
//     B(1)-/
// 
// A has one output (to C), B has one output (to C), C has two inputs (A & B).
// 
// Node A contains a single NodeRef in out_ref:
// { node_idx: 2, conn_idx: 0 }
// Node B contains a single NodeRef in out_ref:
// { node_idx: 2, conn_idx: 1 }
// Node C contains two NodeRef's in in_ref:
// [
//     { node_idx: 0, conn_idx: 0 },
//     { node_idx: 1, conn_idx: 0 }    
// ]
//
// The "connection index" of a NodeRef is simply the index of the
// complementary NodeRef in the target Node. This attribute simplifies graph
// mutation operations where we need to add and remove nodes efficiently.
message NodeRef {
    // The index of the target node.
    int32 node_idx = 1;

    // The connection index in the target node.
    int32 conn_idx = 2;
}

/* A node represents a single "scope" */
message Node {
    // Each node has a unique integer index. NodeRef messages use this index
    // to uniquely identify nodes in a graph.
    int32 index = 1;

    // The type of a node is an integer corresponding to a scope index in a
    // schema. Therefore, interpreting the "type" of a node requires a schema.
    int32 type = 2;

    // A node's layer describes its position in the hierarchy of the graph. A
    // node may only form a forward connection to a node with a higher layer
    // value. When a new forward node is added, it inherits the layer value of
    // its parent plus 1. A new backward node inherits the layer value of its
    // parent minus 1. This formalization ensures the graph has no cycles.
    int32 layer = 3;

    // A list of input references.
    repeated NodeRef in_ref = 4;

    // A list of output references.
    repeated NodeRef out_ref = 5;

    // A variable size bytestring representing ephemeral variable context.
    bytes context = 6;
}

// A graph represents a list of nodes. This is the primary serialization
// container.
message Graph {
    repeated Node nodes = 1;
}


================================================
FILE: core/graphTest.cpp
================================================

#include "graph.hpp"

#include <gtest/gtest.h>


TEST(graph, fillTerminal) {
    Schema schema = Schema::FromString(R"(
        {
            "types": [
                {"name": "dat *", "id": 0}
            ],
            "scopes": [
                { "name": "init_dat", "inputs": [], "outputs": [0], "context": 0 },
                { "name": "consume_dat", "inputs": [0], "outputs": [], "context": 0 }
            ]
        }
    )");

    ASSERT_EQ(true, schema.Validate());
    TGraph graph(schema);

    graph.AddNode(schema.GetScope(0), 0);
    graph.FillTerminal();

    Node n = graph.g.nodes(1);

    ASSERT_EQ(n.index(), 1);
    ASSERT_EQ(n.type(), 1);
    ASSERT_EQ(n.in_ref(0).node_idx(), 0);
    ASSERT_EQ(n.in_ref(0).conn_idx(), 0);
}

TEST(graph, fillMultiTerminal) {
    Schema schema = Schema::FromString(R"(
        {
            "types": [
                {"name": "a", "id": 0},
                {"name": "b", "id": 1},
                {"name": "c", "id": 2},
                {"name": "d", "id": 3}
            ],
            "scopes": [
                { "name": "multi", "inputs": [0,1], "outputs": [2,3], "context": 0 },
                { "name": "init_a", "inputs": [], "outputs": [0], "context": 0 },
                { "name": "consume_a", "inputs": [0], "outputs": [], "context": 0 },
                { "name": "init_b", "inputs": [], "outputs": [1], "context": 0 },
                { "name": "consume_b", "inputs": [1], "outputs": [], "context": 0 },
                { "name": "init_c", "inputs": [], "outputs": [2], "context": 0 },
                { "name": "consume_c", "inputs": [2], "outputs": [], "context": 0 },
                { "name": "init_d", "inputs": [], "outputs": [3], "context": 0 },
                { "name": "consume_d", "inputs": [3], "outputs": [], "context": 0 }
            ]
        }
    )");

    ASSERT_EQ(true, schema.Validate());
    TGraph graph(schema);

    graph.AddNode(schema.GetScope(0), 0);
    graph.FillTerminal();

    Node multi = graph.g.nodes(0);

    Node a = graph.g.nodes(multi.in_ref(0).node_idx());
    ASSERT_EQ(a.type(), 1);
    ASSERT_EQ(a.out_ref(0).node_idx(), 0);
    ASSERT_EQ(a.out_ref(0).conn_idx(), 0);

    Node b = graph.g.nodes(multi.in_ref(1).node_idx());
    ASSERT_EQ(b.type(), 3);
    ASSERT_EQ(b.out_ref(0).node_idx(), 0);
    ASSERT_EQ(b.out_ref(0).conn_idx(), 1);

    Node c = graph.g.nodes(multi.out_ref(0).node_idx());
    ASSERT_EQ(c.type(), 6);
    ASSERT_EQ(c.in_ref(0).node_idx(), 0);
    ASSERT_EQ(c.in_ref(0).conn_idx(), 0);

    Node d = graph.g.nodes(multi.out_ref(1).node_idx());
    ASSERT_EQ(d.type(), 8);
    ASSERT_EQ(d.in_ref(0).node_idx(), 0);
    ASSERT_EQ(d.in_ref(0).conn_idx(), 1);
}

int main(int argc, char **argv) {
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}


================================================
FILE: core/harness.cpp
================================================

#include "graph.hpp"

#include <sys/types.h>
#include <unistd.h>
#include <time.h>

#ifdef TRACE_MUTATIONS
#include <openssl/sha.h>
#endif

using namespace std;


#define DBG_PRINT 0

// Maximum number of input/output arguments for stack array sizing.
#define MAX_CONN 20

// Fuzzer entrypoint.
extern "C" void (*FUZZER_SHIMS[])(void **, void **, const char *);
extern "C" void global_init(int *argc, char ***argv);
extern "C" void shim_init();
extern "C" void shim_finalize();

// Fuzzer mutation API.
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, size_t MaxSize, unsigned int Seed);
extern "C" int MutateOne(const char *s_seed, const char *in_file, const char *out_file);
extern "C" int InitCorpus(const char *init_corpus_dir);

// Saved jump buffer.
static jmp_buf buf;

static bool mark_invalid;
static bool will_bail;

// Global schema.
Schema *global_schema;

// Command line flags:
std::vector<int> graphfuzz_catch = std::vector<int>();
bool graphfuzz_debug = false;
unsigned int graphfuzz_scope_max_depth = 10;
bool graphfuzz_skip_validation = false;
float graphfuzz_context_mutation_prob = 0.95; // Probability of performing mutation on context variables.
bool graphfuzz_enable_soft_execution = false;
bool graphfuzz_ignore_invalid = false;
int graphfuzz_max_nodes = 200; // Max nodes per graph.
const char *graphfuzz_schema_path = "schema.json";

// mutation trace api
bool graphfuzz_trace_mutations = false;
bool has_log = false;
ofstream mutation_log;

#define MUT_LOG_CONTEXT (-1);
#define MUT_LOG_CREATE (-2);
#define MUT_LOG_CROSSOVER (-3);

// If true, refresh the cache.json file.
bool graphfuzz_prune_cache = false;


void sig_handler(int a) {
    // Return to the pre-configured jump target.
    siglongjmp(buf, 1);
}

void register_signals() {
    struct sigaction action;
    action.sa_handler = sig_handler;
    for (auto num : graphfuzz_catch) {
        sigaction(num, &action, NULL);
    }
}

std::vector<int> readInts(char *input) {
    std::vector<int> ints;

    char *inp = strdup(input);

    char *tok = strtok(inp, ",");
    while (tok != NULL) {
        ints.push_back(atoi(tok));
        tok = strtok(NULL, ",");
    }

    free(inp);

    return ints;
}

const char HEX_DIGIT[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};

std::string hexlify(unsigned char *arr, int size) {
    std::stringstream str;
    for (int i = 0; i < size; ++i) {
        str << HEX_DIGIT[arr[i] >> 4];
        str << HEX_DIGIT[arr[i] & 0xf];
    }
    return str.str();
}

extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) {
    bool mutate_one = false;
    const char *mutate_seed;
    const char *mutate_in;
    const char *mutate_out;

    int *orig_argc = argc;
    char ***orig_argv = argv;

    bool init_corpus = false;
    const char *init_corpus_dir;

    for (int i = 0; i < *argc; ++i) {
        char *opt = (*argv)[i];
        if (strcmp(opt, "--graphfuzz_debug") == 0) graphfuzz_debug = true;
        if (strcmp(opt, "--graphfuzz_skip_validation") == 0) graphfuzz_skip_validation = true;
        if (strcmp(opt, "--graphfuzz_prune_cache") == 0) graphfuzz_prune_cache = true;
        if (strcmp(opt, "--graphfuzz_enable_soft_execution") == 0) graphfuzz_enable_soft_execution = true;
        if (strcmp(opt, "--graphfuzz_ignore_invalid") == 0) graphfuzz_ignore_invalid = true;
        #ifdef TRACE_MUTATIONS
        if (strcmp(opt, "--graphfuzz_trace_mutations") == 0) graphfuzz_trace_mutations = true;
        #endif

        if (strncmp(opt, "--graphfuzz_catch=", 18) == 0) {
            graphfuzz_catch = readInts(opt + 18);
            cerr << "[*] GraphFuzz: will catch execeptions:" << endl;
            for (auto num : graphfuzz_catch) {
                cerr << "  - " << num << endl;
            }
        }

        if (strncmp(opt, "--graphfuzz_scope_max_depth=", 28) == 0) {
            const char *val = opt + 28;
            graphfuzz_scope_max_depth = atoi(val);
            cerr << "[*] GraphFuzz: scope_max_depth = " << graphfuzz_scope_max_depth << endl;
        }

        if (strncmp(opt, "--graphfuzz_context_mutation_prob=", 34) == 0) {
            const char *val = opt + 34;
            graphfuzz_context_mutation_prob = atof(val);
            cerr << "[*] GraphFuzz: context_mutation_prob = " << graphfuzz_context_mutation_prob << endl;
        }

        if (strncmp(opt, "--graphfuzz_max_nodes=", 22) == 0) {
            const char *val = opt + 22;
            graphfuzz_max_nodes = atoi(val);
            cerr << "[*] GraphFuzz: max_nodes = " << graphfuzz_max_nodes << endl;
        }

        if (strncmp(opt, "--graphfuzz_schema=", 19) == 0) {
            const char *val = opt + 19;
            graphfuzz_schema_path = val;
            cerr << "[*] GraphFuzz: schema path = " << graphfuzz_schema_path << endl;
        }

        // External mutation API.
        // --graphfuzz_mutate_one <seed> <input> <output>
        if (strcmp(opt, "--graphfuzz_mutate_one") == 0) {
            assert(i + 3 < *argc);
            mutate_one = true;
            mutate_seed = (*argv)[i+1];
            mutate_in = (*argv)[i+2];
            mutate_out = (*argv)[i+3];
            i += 3;
        }

        // External completion API.
        // --graphfuzz_init_corpus <corpus>
        if (strcmp(opt, "--graphfuzz_init_corpus") == 0) {
            assert(i + 1 < *argc);
            init_corpus = true;
            init_corpus_dir = (*argv)[i+1];
        }

        if (graphfuzz_trace_mutations) {
            cerr << "[*] GraphFuzz: tracing mutations..." << endl;
        }
    }

    global_schema = Schema::FromFile(graphfuzz_schema_path);
    if (!global_schema->Validate(
            graphfuzz_debug, 
            graphfuzz_scope_max_depth, 
            graphfuzz_skip_validation,
            graphfuzz_prune_cache)) {
        if (graphfuzz_ignore_invalid) {
            cerr << "[!] Schema is invalid. Running anyways..." << endl;
        } else {
            cerr << "[!] Schema is invalid. (Run with \"--graphfuzz_ignore_invalid\" to continue with usable scopes)." << endl;
            exit(-1);
        }
    }

    register_signals();

    if (mutate_one) {
        int res = MutateOne(mutate_seed, mutate_in, mutate_out);
        exit(res);
    } else if (init_corpus) {
        int res = InitCorpus(init_corpus_dir);
        exit(res);
    }

    global_init(orig_argc, orig_argv);

    return 0;
}

extern "C" int MutateOne(const char *s_seed, const char *in_file, const char *out_file) {
    cerr << "[*] GraphFuzz: mutate one <" << in_file << ">::<" << out_file << ">" << endl;

    unsigned int seed = (unsigned int)atoi(s_seed);

    fstream ex_file;
    stringstream ex_dat;
    ex_file.open(in_file);
    ex_dat << ex_file.rdbuf();
    ex_file.close();
    string ex_str = ex_dat.str();

    uint8_t ex_buffer[ex_str.size()];
    memcpy(ex_buffer, ex_str.c_str(), ex_str.size());

    size_t out_size = LLVMFuzzerCustomMutator(ex_buffer, ex_str.size(), ex_str.size(), seed);

    if (graphfuzz_debug) {
        cerr << "Input size: " << ex_str.size() << endl;
        cerr << "Output size: " << out_size << endl;
    }

    if (out_size == 0 || out_size > ex_str.size()) {
        return -1;
    }

    ofstream out(out_file);
    out.write((const char *)ex_buffer, out_size);

    return 0;
}

extern "C" int InitCorpus(const char *init_corpus_dir) {
    cerr << "[*] Init corpus" << endl;
    std::string base_dir(init_corpus_dir);
    
    std::vector<unsigned int> usable = global_schema->GetUsableScopes();

    for (int i = 0; i < usable.size(); ++i) {
        ScopeDef def = global_schema->GetScope(usable[i]);
        cerr << "\t[" << usable[i] << "] :: " << def.name << endl;

        TGraph g = TGraph(global_schema);
        g.CreateWithScope(def);

        std::string fpath = base_dir + "/seed_" + to_string(i);
        
        bool err = false;
        string out_str = g.Write(&err);
        if (err) return -1;

        ofstream out(fpath);
        out.write(out_str.data(), out_str.size());
    }

    cerr << "[*] Done" << endl;

    return 0;
}

extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, size_t MaxSize, unsigned int Seed) {
    string inp = string((const char *)Data, Size);

    int mut_id = MUT_LOG_CREATE;

    TGraph g = TGraph(global_schema);
    if (!g.Read(inp) || !g.Validate()) {
        // Create a new graph.
        if (!g.Create(Seed, graphfuzz_max_nodes)) return 0;
    } else {
        // Mutate existing graph.
        if (!g.Mutate(Seed, graphfuzz_max_nodes, graphfuzz_context_mutation_prob, &mut_id)) {
            if (graphfuzz_debug) cerr << "mutate failed" << endl;
            return 0;
        }
    }

    bool err = false;
    string out = g.Write(&err);
    if (err || out.size() > MaxSize) return 0;

    #ifdef TRACE_MUTATIONS
    if (graphfuzz_trace_mutations) {
        if (!has_log) {
            pid_t pid = getpid();
            string log_path = ".mutation_log." + to_string(pid);
            mutation_log = ofstream(log_path, ofstream::out | ofstream::app);
            has_log = true;
        }

        unsigned char hash1[SHA_DIGEST_LENGTH];
        unsigned char hash2[SHA_DIGEST_LENGTH];

        SHA1((unsigned char *)inp.data(), inp.size(), hash1);
        SHA1((unsigned char *)out.data(), out.size(), hash2);

        time_t curr_time = time(NULL);

        stringstream str;
        str << hexlify((unsigned char *)hash1, SHA_DIGEST_LENGTH) << "," \
            << hexlify((unsigned char *)hash2, SHA_DIGEST_LENGTH) << "," \
            << mut_id << "," \
            << curr_time << endl;
        string out_string = str.str();

        {
            mutation_log.write(out_string.data(), out_string.size());
            mutation_log.flush();
        }
    }
    #endif

    memcpy(Data, out.data(), out.size());
    return out.size();
}

extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1, const uint8_t *Data2, size_t Size2, uint8_t *Out, size_t MaxOutSize, unsigned int Seed) {
    string inp1 = string((const char *)Data1, Size1);
    string inp2 = string((const char *)Data2, Size2);

    TGraph g1 = TGraph(global_schema);
    TGraph g2 = TGraph(global_schema);

    if (!g1.Read(inp1) || !g1.Validate() || !g2.Read(inp2) || !g2.Validate()) {
        // Create a new graph.
        if (!g1.Create(Seed, graphfuzz_max_nodes)) return 0;
    } else {
        // Crossover.

        if (graphfuzz_debug) {
            cerr << "G1:" << endl;
            g1.PrintAll();
            cerr << "G2:" << endl;
            g2.PrintAll();
        }

        if (!g1.Cross(g2, Seed, graphfuzz_max_nodes)) {
            if (graphfuzz_debug) cerr << "crossover failed" << endl;
            return 0;
        }

        if (graphfuzz_debug) {
            cerr << "Cross:" << endl;
            g1.PrintAll();
        }
    }

    bool err = false;
    string out = g1.Write(&err);
    if (err || out.size() > MaxOutSize) return 0;

    #ifdef TRACE_MUTATIONS
    if (graphfuzz_trace_mutations) {
        if (!has_log) {
            pid_t pid = getpid();
            string log_path = ".mutation_log." + to_string(pid);
            mutation_log = ofstream(log_path, ofstream::out | ofstream::app);
            has_log = true;
        }

        unsigned char hash1[SHA_DIGEST_LENGTH];
        unsigned char hash2[SHA_DIGEST_LENGTH];
        unsigned char hash3[SHA_DIGEST_LENGTH];

        SHA1((unsigned char *)inp1.data(), inp1.size(), hash1);
        SHA1((unsigned char *)inp2.data(), inp2.size(), hash2);
        SHA1((unsigned char *)out.data(), out.size(), hash3);

        time_t curr_time = time(NULL);

        int mut_id = MUT_LOG_CROSSOVER;

        stringstream str;
        str << hexlify((unsigned char *)hash1, SHA_DIGEST_LENGTH) << "," \
            << hexlify((unsigned char *)hash2, SHA_DIGEST_LENGTH) << "," \
            << hexlify((unsigned char *)hash3, SHA_DIGEST_LENGTH) << "," \
            << mut_id << "," \
            << curr_time << endl;
        string out_string = str.str();

        {
            mutation_log.write(out_string.data(), out_string.size());
            mutation_log.flush();
        }
    }
    #endif

    memcpy(Out, out.data(), out.size());
    return out.size();
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
    int val = sigsetjmp(buf, 1);
    if (val != 0) {
        return 0;
    }

    // Call shim_init() immediately to ensure we always have coverage data.
    shim_init();

    if (Size == 0) return 0; // Ignore empty inputs.
    string inp = string((const char *)Data, Size);

    TGraph g = TGraph(global_schema);
    if (!g.Read(inp)) {
        if (graphfuzz_debug) cerr << "invalid proto" << endl;
        return 0;
    }
    if (!g.Validate()) {
        if (graphfuzz_debug) cerr << "invalid" << endl;
        return 0;
    }

    if (graphfuzz_debug) g.PrintAll();

    vector<Node> nodes = g.GetOrderedNodes();
    void *ref[nodes.size()][MAX_CONN];

    for (Node n : nodes) {
        void *in_ref[n.in_ref_size()];
        void *out_ref[n.out_ref_size()];
        const char *context = n.context().data();

        // Load inputs.
        for (int i = 0; i < n.in_ref_size(); ++i) {
            in_ref[i] = ref[n.index()][i];
            if (graphfuzz_debug) {
                cerr << "Prepare input: " << i << " :: " << in_ref[i] << endl;
            }
        }

        // Mark input as valid.
        mark_invalid = false;

        // Unset bail flag.
        will_bail = false;

        // Invoke shim.
        void (*func)(void **, void **, const char *) = FUZZER_SHIMS[n.type()];
        func(in_ref, out_ref, context);

        if (will_bail) {
            // Target called graphfuzz_bail()
            if (graphfuzz_debug) {
                cerr << "Bailing..." << endl;
            }
            return mark_invalid;
        }

        // Copy outputs.
        for (int i = 0; i < n.out_ref_size(); ++i) {
            NodeRef r = n.out_ref(i);
            ref[r.node_idx()][r.conn_idx()] = out_ref[i];
            if (graphfuzz_debug) {
                cerr << "Got output: " << i << " :: " << out_ref[i] << endl;
            }
        }
    }

    shim_finalize();

    return mark_invalid;
}

extern "C" void graphfuzz_invalid() {
    mark_invalid = true;
}

extern "C" int graphfuzz_try() {
    if (graphfuzz_enable_soft_execution) {
        return sigsetjmp(buf, 1);
    } else {
        return 0;
    }
}

extern "C" void graphfuzz_bail() {
    will_bail = true;
}


================================================
FILE: core/ignorelist.txt
================================================

# Ignore GraphFuzz core files
src:.*graphfuzz/src/harness.cpp


================================================
FILE: core/json.hpp
================================================
/*
    __ _____ _____ _____
 __|  |   __|     |   | |  JSON for Modern C++
|  |  |__   |  |  | | | |  version 3.9.1
|_____|_____|_____|_|___|  https://github.com/nlohmann/json

Licensed under the MIT License <http://opensource.org/licenses/MIT>.
SPDX-License-Identifier: MIT
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.

Permission is hereby  granted, free of charge, to any  person obtaining a copy
of this software and associated  documentation files (the "Software"), to deal
in the Software  without restriction, including without  limitation the rights
to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

#ifndef INCLUDE_NLOHMANN_JSON_HPP_
#define INCLUDE_NLOHMANN_JSON_HPP_

#define NLOHMANN_JSON_VERSION_MAJOR 3
#define NLOHMANN_JSON_VERSION_MINOR 9
#define NLOHMANN_JSON_VERSION_PATCH 1

#include <algorithm> // all_of, find, for_each
#include <cstddef> // nullptr_t, ptrdiff_t, size_t
#include <functional> // hash, less
#include <initializer_list> // initializer_list
#include <iosfwd> // istream, ostream
#include <iterator> // random_access_iterator_tag
#include <memory> // unique_ptr
#include <numeric> // accumulate
#include <string> // string, stoi, to_string
#include <utility> // declval, forward, move, pair, swap
#include <vector> // vector

// #include <nlohmann/adl_serializer.hpp>


#include <utility>

// #include <nlohmann/detail/conversions/from_json.hpp>


#include <algorithm> // transform
#include <array> // array
#include <forward_list> // forward_list
#include <iterator> // inserter, front_inserter, end
#include <map> // map
#include <string> // string
#include <tuple> // tuple, make_tuple
#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
#include <unordered_map> // unordered_map
#include <utility> // pair, declval
#include <valarray> // valarray

// #include <nlohmann/detail/exceptions.hpp>


#include <exception> // exception
#include <stdexcept> // runtime_error
#include <string> // to_string

// #include <nlohmann/detail/input/position_t.hpp>


#include <cstddef> // size_t

namespace nlohmann
{
namespace detail
{
/// struct to capture the start position of the current token
struct position_t
{
    /// the total number of characters read
    std::size_t chars_read_total = 0;
    /// the number of characters read in the current line
    std::size_t chars_read_current_line = 0;
    /// the number of lines read
    std::size_t lines_read = 0;

    /// conversion to size_t to preserve SAX interface
    constexpr operator size_t() const
    {
        return chars_read_total;
    }
};

} // namespace detail
} // namespace nlohmann

// #include <nlohmann/detail/macro_scope.hpp>


#include <utility> // pair
// #include <nlohmann/thirdparty/hedley/hedley.hpp>
/* Hedley - https://nemequ.github.io/hedley
 * Created by Evan Nemerson <evan@nemerson.com>
 *
 * To the extent possible under law, the author(s) have dedicated all
 * copyright and related and neighboring rights to this software to
 * the public domain worldwide. This software is distributed without
 * any warranty.
 *
 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
 * SPDX-License-Identifier: CC0-1.0
 */

#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 14)
#if defined(JSON_HEDLEY_VERSION)
    #undef JSON_HEDLEY_VERSION
#endif
#define JSON_HEDLEY_VERSION 14

#if defined(JSON_HEDLEY_STRINGIFY_EX)
    #undef JSON_HEDLEY_STRINGIFY_EX
#endif
#define JSON_HEDLEY_STRINGIFY_EX(x) #x

#if defined(JSON_HEDLEY_STRINGIFY)
    #undef JSON_HEDLEY_STRINGIFY
#endif
#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)

#if defined(JSON_HEDLEY_CONCAT_EX)
    #undef JSON_HEDLEY_CONCAT_EX
#endif
#define JSON_HEDLEY_CONCAT_EX(a,b) a##b

#if defined(JSON_HEDLEY_CONCAT)
    #undef JSON_HEDLEY_CONCAT
#endif
#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)

#if defined(JSON_HEDLEY_CONCAT3_EX)
    #undef JSON_HEDLEY_CONCAT3_EX
#endif
#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c

#if defined(JSON_HEDLEY_CONCAT3)
    #undef JSON_HEDLEY_CONCAT3
#endif
#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)

#if defined(JSON_HEDLEY_VERSION_ENCODE)
    #undef JSON_HEDLEY_VERSION_ENCODE
#endif
#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))

#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
    #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
#endif
#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)

#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
    #undef JSON_HEDLEY_VERSION_DECODE_MINOR
#endif
#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)

#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
    #undef JSON_HEDLEY_VERSION_DECODE_REVISION
#endif
#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)

#if defined(JSON_HEDLEY_GNUC_VERSION)
    #undef JSON_HEDLEY_GNUC_VERSION
#endif
#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
    #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
#elif defined(__GNUC__)
    #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
#endif

#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
    #undef JSON_HEDLEY_GNUC_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_GNUC_VERSION)
    #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_MSVC_VERSION)
    #undef JSON_HEDLEY_MSVC_VERSION
#endif
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
#elif defined(_MSC_FULL_VER) && !defined(__ICL)
    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
#elif defined(_MSC_VER) && !defined(__ICL)
    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
#endif

#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
    #undef JSON_HEDLEY_MSVC_VERSION_CHECK
#endif
#if !defined(JSON_HEDLEY_MSVC_VERSION)
    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
#else
    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
#endif

#if defined(JSON_HEDLEY_INTEL_VERSION)
    #undef JSON_HEDLEY_INTEL_VERSION
#endif
#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
    #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
#elif defined(__INTEL_COMPILER) && !defined(__ICL)
    #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
#endif

#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
    #undef JSON_HEDLEY_INTEL_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_INTEL_VERSION)
    #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
    #undef JSON_HEDLEY_INTEL_CL_VERSION
#endif
#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
    #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
#endif

#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
    #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
    #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_PGI_VERSION)
    #undef JSON_HEDLEY_PGI_VERSION
#endif
#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
    #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
#endif

#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
    #undef JSON_HEDLEY_PGI_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_PGI_VERSION)
    #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_SUNPRO_VERSION)
    #undef JSON_HEDLEY_SUNPRO_VERSION
#endif
#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
#elif defined(__SUNPRO_C)
    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
#elif defined(__SUNPRO_CC)
    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
#endif

#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
    #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_SUNPRO_VERSION)
    #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
    #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
#endif
#if defined(__EMSCRIPTEN__)
    #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
#endif

#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
    #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
    #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_ARM_VERSION)
    #undef JSON_HEDLEY_ARM_VERSION
#endif
#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
    #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
    #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
#endif

#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
    #undef JSON_HEDLEY_ARM_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_ARM_VERSION)
    #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_IBM_VERSION)
    #undef JSON_HEDLEY_IBM_VERSION
#endif
#if defined(__ibmxl__)
    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
#elif defined(__xlC__) && defined(__xlC_ver__)
    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
#elif defined(__xlC__)
    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
#endif

#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
    #undef JSON_HEDLEY_IBM_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_IBM_VERSION)
    #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_TI_VERSION)
    #undef JSON_HEDLEY_TI_VERSION
#endif
#if \
    defined(__TI_COMPILER_VERSION__) && \
    ( \
      defined(__TMS470__) || defined(__TI_ARM__) || \
      defined(__MSP430__) || \
      defined(__TMS320C2000__) \
    )
#if (__TI_COMPILER_VERSION__ >= 16000000)
    #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
#endif
#endif

#if defined(JSON_HEDLEY_TI_VERSION_CHECK)
    #undef JSON_HEDLEY_TI_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_TI_VERSION)
    #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
    #undef JSON_HEDLEY_TI_CL2000_VERSION
#endif
#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
    #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
#endif

#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
    #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
    #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_TI_CL430_VERSION)
    #undef JSON_HEDLEY_TI_CL430_VERSION
#endif
#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
    #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
#endif

#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
    #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_TI_CL430_VERSION)
    #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
    #undef JSON_HEDLEY_TI_ARMCL_VERSION
#endif
#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
    #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
#endif

#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
    #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
    #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
    #undef JSON_HEDLEY_TI_CL6X_VERSION
#endif
#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
    #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
#endif

#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
    #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
    #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
    #undef JSON_HEDLEY_TI_CL7X_VERSION
#endif
#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
    #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
#endif

#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
    #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
    #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
    #undef JSON_HEDLEY_TI_CLPRU_VERSION
#endif
#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
    #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
#endif

#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
    #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
    #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_CRAY_VERSION)
    #undef JSON_HEDLEY_CRAY_VERSION
#endif
#if defined(_CRAYC)
    #if defined(_RELEASE_PATCHLEVEL)
        #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
    #else
        #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
    #endif
#endif

#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
    #undef JSON_HEDLEY_CRAY_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_CRAY_VERSION)
    #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_IAR_VERSION)
    #undef JSON_HEDLEY_IAR_VERSION
#endif
#if defined(__IAR_SYSTEMS_ICC__)
    #if __VER__ > 1000
        #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
    #else
        #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(VER / 100, __VER__ % 100, 0)
    #endif
#endif

#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
    #undef JSON_HEDLEY_IAR_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_IAR_VERSION)
    #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_TINYC_VERSION)
    #undef JSON_HEDLEY_TINYC_VERSION
#endif
#if defined(__TINYC__)
    #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
#endif

#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
    #undef JSON_HEDLEY_TINYC_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_TINYC_VERSION)
    #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_DMC_VERSION)
    #undef JSON_HEDLEY_DMC_VERSION
#endif
#if defined(__DMC__)
    #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
#endif

#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
    #undef JSON_HEDLEY_DMC_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_DMC_VERSION)
    #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_COMPCERT_VERSION)
    #undef JSON_HEDLEY_COMPCERT_VERSION
#endif
#if defined(__COMPCERT_VERSION__)
    #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
#endif

#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
    #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_COMPCERT_VERSION)
    #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_PELLES_VERSION)
    #undef JSON_HEDLEY_PELLES_VERSION
#endif
#if defined(__POCC__)
    #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
#endif

#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
    #undef JSON_HEDLEY_PELLES_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_PELLES_VERSION)
    #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_GCC_VERSION)
    #undef JSON_HEDLEY_GCC_VERSION
#endif
#if \
    defined(JSON_HEDLEY_GNUC_VERSION) && \
    !defined(__clang__) && \
    !defined(JSON_HEDLEY_INTEL_VERSION) && \
    !defined(JSON_HEDLEY_PGI_VERSION) && \
    !defined(JSON_HEDLEY_ARM_VERSION) && \
    !defined(JSON_HEDLEY_TI_VERSION) && \
    !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
    !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
    !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
    !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
    !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
    !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
    !defined(__COMPCERT__)
    #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
#endif

#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
    #undef JSON_HEDLEY_GCC_VERSION_CHECK
#endif
#if defined(JSON_HEDLEY_GCC_VERSION)
    #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
#else
    #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
#endif

#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
    #undef JSON_HEDLEY_HAS_ATTRIBUTE
#endif
#if defined(__has_attribute)
    #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
#else
    #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
#endif

#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
    #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
#endif
#if defined(__has_attribute)
    #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
#else
    #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
#endif

#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
    #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
#endif
#if defined(__has_attribute)
    #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
#else
    #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
#endif

#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
    #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
#endif
#if \
    defined(__has_cpp_attribute) && \
    defined(__cplusplus) && \
    (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
#else
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
#endif

#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
    #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
#endif
#if !defined(__cplusplus) || !defined(__has_cpp_attribute)
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
#elif \
    !defined(JSON_HEDLEY_PGI_VERSION) && \
    !defined(JSON_HEDLEY_IAR_VERSION) && \
    (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
    (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
#else
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
#endif

#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
    #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
#endif
#if defined(__has_cpp_attribute) && defined(__cplusplus)
    #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
#else
    #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
#endif

#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
    #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
#endif
#if defined(__has_cpp_attribute) && defined(__cplusplus)
    #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
#else
    #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
#endif

#if defined(JSON_HEDLEY_HAS_BUILTIN)
    #undef JSON_HEDLEY_HAS_BUILTIN
#endif
#if defined(__has_builtin)
    #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
#else
    #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
#endif

#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
    #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
#endif
#if defined(__has_builtin)
    #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
#else
    #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
#endif

#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
    #undef JSON_HEDLEY_GCC_HAS_BUILTIN
#endif
#if defined(__has_builtin)
    #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
#else
    #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
#endif

#if defined(JSON_HEDLEY_HAS_FEATURE)
    #undef JSON_HEDLEY_HAS_FEATURE
#endif
#if defined(__has_feature)
    #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
#else
    #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
#endif

#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
    #undef JSON_HEDLEY_GNUC_HAS_FEATURE
#endif
#if defined(__has_feature)
    #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
#else
    #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
#endif

#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
    #undef JSON_HEDLEY_GCC_HAS_FEATURE
#endif
#if defined(__has_feature)
    #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
#else
    #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
#endif

#if defined(JSON_HEDLEY_HAS_EXTENSION)
    #undef JSON_HEDLEY_HAS_EXTENSION
#endif
#if defined(__has_extension)
    #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
#else
    #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
#endif

#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
    #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
#endif
#if defined(__has_extension)
    #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
#else
    #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
#endif

#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
    #undef JSON_HEDLEY_GCC_HAS_EXTENSION
#endif
#if defined(__has_extension)
    #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
#else
    #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
#endif

#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
    #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
#endif
#if defined(__has_declspec_attribute)
    #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
#else
    #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
#endif

#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
    #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
#endif
#if defined(__has_declspec_attribute)
    #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
#else
    #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
#endif

#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
    #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
#endif
#if defined(__has_declspec_attribute)
    #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
#else
    #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
#endif

#if defined(JSON_HEDLEY_HAS_WARNING)
    #undef JSON_HEDLEY_HAS_WARNING
#endif
#if defined(__has_warning)
    #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
#else
    #define JSON_HEDLEY_HAS_WARNING(warning) (0)
#endif

#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
    #undef JSON_HEDLEY_GNUC_HAS_WARNING
#endif
#if defined(__has_warning)
    #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
#else
    #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
#endif

#if defined(JSON_HEDLEY_GCC_HAS_WARNING)
    #undef JSON_HEDLEY_GCC_HAS_WARNING
#endif
#if defined(__has_warning)
    #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
#else
    #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
#endif

#if \
    (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
    defined(__clang__) || \
    JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
    JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
    JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
    JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
    (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
    #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
    #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
#else
    #define JSON_HEDLEY_PRAGMA(value)
#endif

#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
    #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
#endif
#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
    #undef JSON_HEDLEY_DIAGNOSTIC_POP
#endif
#if defined(__clang__)
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
#elif \
    JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
    #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
#elif \
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
#else
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH
    #define JSON_HEDLEY_DIAGNOSTIC_POP
#endif

/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
   HEDLEY INTERNAL USE ONLY.  API subject to change without notice. */
#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
#endif
#if defined(__cplusplus)
#  if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
#    if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
#      if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
#        define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
    _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
    _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
    _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
    xpr \
    JSON_HEDLEY_DIAGNOSTIC_POP
#      else
#        define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
    _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
    _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
    xpr \
    JSON_HEDLEY_DIAGNOSTIC_POP
#      endif
#    else
#      define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
    _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
    xpr \
    JSON_HEDLEY_DIAGNOSTIC_POP
#    endif
#  endif
#endif
#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
#endif

#if defined(JSON_HEDLEY_CONST_CAST)
    #undef JSON_HEDLEY_CONST_CAST
#endif
#if defined(__cplusplus)
#  define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
#elif \
  JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
  JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
#  define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
        JSON_HEDLEY_DIAGNOSTIC_PUSH \
        JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
        ((T) (expr)); \
        JSON_HEDLEY_DIAGNOSTIC_POP \
    }))
#else
#  define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
#endif

#if defined(JSON_HEDLEY_REINTERPRET_CAST)
    #undef JSON_HEDLEY_REINTERPRET_CAST
#endif
#if defined(__cplusplus)
    #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
#else
    #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
#endif

#if defined(JSON_HEDLEY_STATIC_CAST)
    #undef JSON_HEDLEY_STATIC_CAST
#endif
#if defined(__cplusplus)
    #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
#else
    #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
#endif

#if defined(JSON_HEDLEY_CPP_CAST)
    #undef JSON_HEDLEY_CPP_CAST
#endif
#if defined(__cplusplus)
#  if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
#    define JSON_HEDLEY_CPP_CAST(T, expr) \
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
    _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
    ((T) (expr)) \
    JSON_HEDLEY_DIAGNOSTIC_POP
#  elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
#    define JSON_HEDLEY_CPP_CAST(T, expr) \
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
    _Pragma("diag_suppress=Pe137") \
    JSON_HEDLEY_DIAGNOSTIC_POP
#  else
#    define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
#  endif
#else
#  define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
#endif

#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
#endif
#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
#elif \
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
#else
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
#endif

#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
#endif
#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
#elif \
    JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
#else
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
#endif

#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
#endif
#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
#elif \
    JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
#else
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
#endif

#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
#endif
#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
#else
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
#endif

#if defined(JSON_HEDLEY_DEPRECATED)
    #undef JSON_HEDLEY_DEPRECATED
#endif
#if defined(JSON_HEDLEY_DEPRECATED_FOR)
    #undef JSON_HEDLEY_DEPRECATED_FOR
#endif
#if \
    JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
#elif \
    JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) || \
    JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
    JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
    #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
#elif defined(__cplusplus) && (__cplusplus >= 201402L)
    #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
#elif \
    JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
    #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
#elif \
    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
    JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
    #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
#else
    #define JSON_HEDLEY_DEPRECATED(since)
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
#endif

#if defined(JSON_HEDLEY_UNAVAILABLE)
    #undef JSON_HEDLEY_UNAVAILABLE
#endif
#if \
    JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
    JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
    #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
#else
    #define JSON_HEDLEY_UNAVAILABLE(available_since)
#endif

#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
    #undef JSON_HEDLEY_WARN_UNUSED_RESULT
#endif
#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
    #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
#endif
#if \
    JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
    JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
    (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
    #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
    #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
    #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
#elif defined(_Check_return_) /* SAL */
    #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
#else
    #define JSON_HEDLEY_WARN_UNUSED_RESULT
    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
#endif

#if defined(JSON_HEDLEY_SENTINEL)
    #undef JSON_HEDLEY_SENTINEL
#endif
#if \
    JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
    JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0)
    #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
#else
    #define JSON_HEDLEY_SENTINEL(position)
#endif

#if defined(JSON_HEDLEY_NO_RETURN)
    #undef JSON_HEDLEY_NO_RETURN
#endif
#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
    #define JSON_HEDLEY_NO_RETURN __noreturn
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
    #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
    #define JSON_HEDLEY_NO_RETURN _Noreturn
#elif defined(__cplusplus) && (__cplusplus >= 201103L)
    #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
#elif \
    JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
    JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
    #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
    #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
#elif \
    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
    #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
    #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
    #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
#else
    #define JSON_HEDLEY_NO_RETURN
#endif

#if defined(JSON_HEDLEY_NO_ESCAPE)
    #undef JSON_HEDLEY_NO_ESCAPE
#endif
#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
    #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
#else
    #define JSON_HEDLEY_NO_ESCAPE
#endif

#if defined(JSON_HEDLEY_UNREACHABLE)
    #undef JSON_HEDLEY_UNREACHABLE
#endif
#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
    #undef JSON_HEDLEY_UNREACHABLE_RETURN
#endif
#if defined(JSON_HEDLEY_ASSUME)
    #undef JSON_HEDLEY_ASSUME
#endif
#if \
    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
    #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
    #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
#elif \
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
    #if defined(__cplusplus)
        #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
    #else
        #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
    #endif
#endif
#if \
    (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
    JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
    JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
    JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5)
    #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
#elif defined(JSON_HEDLEY_ASSUME)
    #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
#endif
#if !defined(JSON_HEDLEY_ASSUME)
    #if defined(JSON_HEDLEY_UNREACHABLE)
        #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
    #else
        #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
    #endif
#endif
#if defined(JSON_HEDLEY_UNREACHABLE)
    #if  \
        JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
        JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
        #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
    #else
        #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
    #endif
#else
    #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
#endif
#if !defined(JSON_HEDLEY_UNREACHABLE)
    #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
#endif

JSON_HEDLEY_DIAGNOSTIC_PUSH
#if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
    #pragma clang diagnostic ignored "-Wpedantic"
#endif
#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
    #pragma clang diag
Download .txt
gitextract_m9nptssz/

├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── README.md
├── cli/
│   ├── README.md
│   ├── gfuzz/
│   │   ├── __init__.py
│   │   ├── api.py
│   │   ├── cli.py
│   │   ├── commands/
│   │   │   ├── __init__.py
│   │   │   ├── cliopt.py
│   │   │   ├── doxygen/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── docker/
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   └── in/
│   │   │   │   │       ├── Doxyfile.template
│   │   │   │   │       └── run.py
│   │   │   │   └── extractor.py
│   │   │   ├── gen/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── cpp/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── base_schema.yaml
│   │   │   │   │   ├── cpp_sig.py
│   │   │   │   │   ├── gen_cpp.py
│   │   │   │   │   └── test_cpp_sig.py
│   │   │   │   └── gen.py
│   │   │   ├── minimizer.py
│   │   │   └── schema.py
│   │   ├── docker_util.py
│   │   └── schema.py
│   └── pyproject.toml
├── core/
│   ├── build_tests.sh
│   ├── graph.hpp
│   ├── graph.proto
│   ├── graphTest.cpp
│   ├── harness.cpp
│   ├── ignorelist.txt
│   ├── json.hpp
│   ├── schema.hpp
│   └── schemaTest.cpp
├── docs/
│   ├── .nojekyll
│   ├── README.md
│   ├── _sidebar.md
│   ├── experiments/
│   │   └── overview.md
│   ├── index.html
│   ├── quick_start/
│   │   ├── basic_usage.md
│   │   ├── endpoints.md
│   │   └── installation.md
│   └── schema_format.md
└── experiments/
    ├── README.md
    ├── base/
    │   └── Dockerfile
    ├── build
    ├── custom_endpoints/
    │   ├── Dockerfile
    │   └── in/
    │       ├── build.sh
    │       ├── lib.h
    │       └── schema.yaml
    ├── eigen/
    │   ├── Dockerfile
    │   └── in/
    │       ├── build.sh
    │       ├── f1/
    │       │   ├── fuzz_exec.cpp
    │       │   ├── fuzz_write.cpp
    │       │   ├── schema.json
    │       │   └── schema.yaml
    │       └── test.sh
    ├── ex_array_demo/
    │   ├── Dockerfile
    │   └── in/
    │       ├── build.sh
    │       ├── build_lib.sh
    │       ├── fuzz/
    │       │   ├── fuzz_exec.cpp
    │       │   ├── fuzz_write.cpp
    │       │   ├── schema.json
    │       │   └── schema.yaml
    │       └── lib/
    │           ├── lib.cpp
    │           └── lib.h
    ├── ex_auto_cpp/
    │   ├── Dockerfile
    │   ├── README.md
    │   ├── in/
    │   │   ├── auto_schema.yaml
    │   │   ├── build.sh
    │   │   ├── build_lib.sh
    │   │   ├── fuzz/
    │   │   │   ├── fuzz_exec.cpp
    │   │   │   ├── fuzz_write.cpp
    │   │   │   └── schema.json
    │   │   └── lib/
    │   │       ├── point.cpp
    │   │       ├── point.h
    │   │       ├── rect.cpp
    │   │       └── rect.h
    │   └── make_schema.sh
    ├── hello_graphfuzz/
    │   ├── Dockerfile
    │   └── in/
    │       ├── build.sh
    │       ├── lib.h
    │       ├── schema.yaml
    │       └── schema_verbose.yaml
    ├── iowow/
    │   ├── Dockerfile
    │   └── in/
    │       ├── bug.sh
    │       ├── bugs/
    │       │   ├── bug1.c
    │       │   └── bug2.c
    │       ├── build.sh
    │       ├── db_tracker.h
    │       ├── f1/
    │       │   ├── fuzz_exec.cpp
    │       │   ├── fuzz_write.cpp
    │       │   ├── schema.json
    │       │   └── schema.yaml
    │       └── test.sh
    ├── rdkit/
    │   ├── Dockerfile
    │   ├── build_rdkit.sh
    │   └── in/
    │       ├── Fuzz/
    │       │   ├── build.sh
    │       │   ├── fuzz_exec.cpp
    │       │   ├── fuzz_write.cpp
    │       │   ├── schema.json
    │       │   └── schema.yaml
    │       ├── bugs/
    │       │   ├── README.md
    │       │   ├── bug1.cpp
    │       │   ├── bug1.py
    │       │   ├── bug1_min.cpp
    │       │   ├── bug2.cpp
    │       │   ├── bug2_min.cpp
    │       │   ├── bug3.cpp
    │       │   ├── bug3_min.cpp
    │       │   ├── bug4.cpp
    │       │   ├── bug4_min.cpp
    │       │   ├── bug4_min2.cpp
    │       │   ├── bug5.cpp
    │       │   ├── bug5_min.cpp
    │       │   ├── bug6.cpp
    │       │   ├── bug6_min.cpp
    │       │   ├── bug7.cpp
    │       │   ├── bug7_min.cpp
    │       │   ├── bug8.cpp
    │       │   ├── bug9.cpp
    │       │   └── bug9_min.cpp
    │       ├── example/
    │       │   ├── build.sh
    │       │   └── test.cpp
    │       ├── launch.sh
    │       ├── make.sh
    │       ├── raw_schema.yaml
    │       └── test.sh
    ├── rdkit_demo/
    │   ├── Dockerfile
    │   ├── build_rdkit.sh
    │   └── in/
    │       ├── build.sh
    │       ├── demo.cpp
    │       ├── schema.yaml
    │       └── set_flags.sh
    ├── run
    ├── skia/
    │   ├── Dockerfile
    │   ├── README.md
    │   ├── gf_fuzz/
    │   │   ├── FuzzCanvas/
    │   │   │   ├── api_image_filter/
    │   │   │   │   ├── fuzz_exec.cpp
    │   │   │   │   ├── fuzz_write.cpp
    │   │   │   │   ├── schema.json
    │   │   │   │   └── schema.yaml
    │   │   │   ├── api_mock_gpu_canvas/
    │   │   │   │   ├── BUILD.gn
    │   │   │   │   ├── README.md
    │   │   │   │   ├── build.sh
    │   │   │   │   ├── fuzz_exec.cpp
    │   │   │   │   ├── fuzz_write.cpp
    │   │   │   │   ├── schema.json
    │   │   │   │   └── schema.yaml
    │   │   │   ├── api_null_canvas/
    │   │   │   │   ├── fuzz_exec.cpp
    │   │   │   │   ├── fuzz_write.cpp
    │   │   │   │   ├── schema.json
    │   │   │   │   └── schema.yaml
    │   │   │   ├── api_raster_n32_canvas/
    │   │   │   │   ├── fuzz_exec.cpp
    │   │   │   │   ├── fuzz_write.cpp
    │   │   │   │   ├── schema.json
    │   │   │   │   └── schema.yaml
    │   │   │   ├── api_svg_canvas/
    │   │   │   │   ├── fuzz_exec.cpp
    │   │   │   │   ├── fuzz_write.cpp
    │   │   │   │   ├── schema.json
    │   │   │   │   └── schema.yaml
    │   │   │   ├── build_baseline.sh
    │   │   │   ├── fuzz_exec.cpp
    │   │   │   ├── fuzz_util.h
    │   │   │   ├── fuzz_write.cpp
    │   │   │   ├── image_filter_deserialize/
    │   │   │   │   ├── fuzz_exec.cpp
    │   │   │   │   ├── fuzz_write.cpp
    │   │   │   │   ├── schema.json
    │   │   │   │   └── schema.yaml
    │   │   │   ├── schema.json
    │   │   │   └── schema.yaml
    │   │   ├── FuzzDrawFunctions/
    │   │   │   ├── build_baseline.sh
    │   │   │   ├── fuzz_exec.cpp
    │   │   │   ├── fuzz_write.cpp
    │   │   │   ├── schema.json
    │   │   │   └── schema.yaml
    │   │   ├── FuzzPathMeasure/
    │   │   │   ├── fuzz_exec.cpp
    │   │   │   ├── fuzz_write.cpp
    │   │   │   ├── schema.json
    │   │   │   └── schema.yaml
    │   │   ├── FuzzPathOp/
    │   │   │   ├── fuzz_exec.cpp
    │   │   │   ├── fuzz_write.cpp
    │   │   │   ├── schema.json
    │   │   │   └── schema.yaml
    │   │   ├── FuzzPolyUtils/
    │   │   │   ├── fuzz_exec.cpp
    │   │   │   ├── fuzz_write.cpp
    │   │   │   ├── poly_util.h
    │   │   │   ├── schema.json
    │   │   │   └── schema.yaml
    │   │   ├── FuzzRegionOp/
    │   │   │   ├── fuzz_exec.cpp
    │   │   │   ├── fuzz_write.cpp
    │   │   │   ├── schema.json
    │   │   │   └── schema.yaml
    │   │   ├── FuzzRegionSetPath/
    │   │   │   ├── fuzz_exec.cpp
    │   │   │   ├── fuzz_write.cpp
    │   │   │   ├── schema.json
    │   │   │   └── schema.yaml
    │   │   ├── FuzzSkParagraph/
    │   │   │   ├── build.sh
    │   │   │   ├── build_cov.sh
    │   │   │   ├── fuzz_exec.cpp
    │   │   │   ├── fuzz_write.cpp
    │   │   │   ├── paragraph_util.h
    │   │   │   ├── schema.json
    │   │   │   └── schema.yaml
    │   │   └── gen.sh
    │   ├── patch/
    │   │   ├── BUILD.gn
    │   │   └── fuzz/
    │   │       ├── Fuzz.cpp
    │   │       ├── Fuzz.h
    │   │       ├── FuzzCanvas.cpp
    │   │       ├── FuzzCommon.cpp
    │   │       ├── FuzzCommon.h
    │   │       ├── FuzzCreateDDL.cpp
    │   │       ├── FuzzDDLThreading.cpp
    │   │       ├── FuzzDrawFunctions.cpp
    │   │       ├── FuzzEncoders.cpp
    │   │       ├── FuzzGradients.cpp
    │   │       ├── FuzzMain.cpp
    │   │       ├── FuzzParsePath.cpp
    │   │       ├── FuzzPath.cpp
    │   │       ├── FuzzPathMeasure.cpp
    │   │       ├── FuzzPathop.cpp
    │   │       ├── FuzzPolyUtils.cpp
    │   │       ├── FuzzRRect.cpp
    │   │       ├── FuzzRegionOp.cpp
    │   │       ├── FuzzSkParagraph.cpp
    │   │       ├── FuzzTriangulation.cpp
    │   │       ├── README.md
    │   │       ├── coverage
    │   │       └── oss_fuzz/
    │   │           ├── FuzzAPICreateDDL.cpp
    │   │           ├── FuzzAPIImageFilter.cpp
    │   │           ├── FuzzAPISVGCanvas.cpp
    │   │           ├── FuzzAndroidCodec.cpp
    │   │           ├── FuzzAnimatedImage.cpp
    │   │           ├── FuzzDDLThreading.cpp
    │   │           ├── FuzzDrawFunctions.cpp
    │   │           ├── FuzzGradients.cpp
    │   │           ├── FuzzImage.cpp
    │   │           ├── FuzzImageFilterDeserialize.cpp
    │   │           ├── FuzzIncrementalImage.cpp
    │   │           ├── FuzzJPEGEncoder.cpp
    │   │           ├── FuzzJSON.cpp
    │   │           ├── FuzzMockGPUCanvas.cpp
    │   │           ├── FuzzNullCanvas.cpp
    │   │           ├── FuzzPNGEncoder.cpp
    │   │           ├── FuzzPathDeserialize.cpp
    │   │           ├── FuzzPathMeasure.cpp
    │   │           ├── FuzzPathop.cpp
    │   │           ├── FuzzPolyUtils.cpp
    │   │           ├── FuzzRasterN32Canvas.cpp
    │   │           ├── FuzzRegionDeserialize.cpp
    │   │           ├── FuzzRegionOp.cpp
    │   │           ├── FuzzRegionSetPath.cpp
    │   │           ├── FuzzSKP.cpp
    │   │           ├── FuzzSKSL2GLSL.cpp
    │   │           ├── FuzzSKSL2Metal.cpp
    │   │           ├── FuzzSKSL2Pipeline.cpp
    │   │           ├── FuzzSKSL2SPIRV.cpp
    │   │           ├── FuzzSVG.cpp
    │   │           ├── FuzzSkDescriptorDeserialize.cpp
    │   │           ├── FuzzSkParagraph.cpp
    │   │           ├── FuzzSkRuntimeEffect.cpp
    │   │           ├── FuzzTextBlobDeserialize.cpp
    │   │           ├── FuzzTriangulation.cpp
    │   │           └── FuzzWEBPEncoder.cpp
    │   └── scripts/
    │       ├── llvm-gcov.sh
    │       └── run.py
    └── sqlite3/
        ├── Dockerfile
        └── in/
            ├── bug.sh
            ├── bugs/
            │   ├── bug1.c
            │   └── bug2.c
            ├── build.sh
            ├── c_api.yaml
            ├── db_tracker.h
            ├── extra.h
            ├── f1/
            │   ├── fuzz_exec.cpp
            │   ├── fuzz_write.cpp
            │   ├── schema.json
            │   └── schema.yaml
            ├── sql.dict
            ├── sqlite3.c
            ├── sqlite3.h
            └── test.sh
Copy disabled (too large) Download .txt
Showing preview only (45,348K chars total). Download the full file to get everything.
SYMBOL INDEX (12217 symbols across 151 files)

FILE: cli/gfuzz/api.py
  class API (line 8) | class API(object):
    method __init__ (line 9) | def __init__(self, fpath):

FILE: cli/gfuzz/cli.py
  function main (line 8) | def main():

FILE: cli/gfuzz/commands/cliopt.py
  class CLIOpt (line 2) | class CLIOpt(object):
    method __init__ (line 3) | def __init__(self, name, help_str, register_fn, execute_fn):
    method add_args (line 11) | def add_args(self, parser):
    method execute (line 16) | def execute(self, args):

FILE: cli/gfuzz/commands/doxygen/docker/in/run.py
  function _run_doxygen (line 8) | def _run_doxygen(inputs):
  function main (line 17) | def main():

FILE: cli/gfuzz/commands/doxygen/extractor.py
  function build_extractor_image (line 15) | def build_extractor_image():
  function run_extractor_image (line 22) | def run_extractor_image(inputs, output):
  function register (line 40) | def register(sub):
  function execute (line 47) | def execute(args):

FILE: cli/gfuzz/commands/gen/cpp/cpp_sig.py
  class CPPTypeModifier (line 11) | class CPPTypeModifier:
    method action (line 15) | def action(tok):
    method build (line 19) | def build() -> pp.ParseExpression:
  class CPPBaseType (line 27) | class CPPBaseType:
    method __repr__ (line 38) | def __repr__(self):
    method action (line 47) | def action(tok):
    method build (line 58) | def build() -> pp.ParseExpression:
  class CPPArgName (line 66) | class CPPArgName:
    method action (line 70) | def action(tok):
    method build (line 77) | def build() -> pp.ParseExpression:
  class CPPArgument (line 84) | class CPPArgument:
    method __repr__ (line 99) | def __repr__(self):
    method action (line 110) | def action(tok):
    method action_raw (line 115) | def action_raw(tok):
    method build (line 121) | def build() -> pp.ParseExpression:
  class CPPArgList (line 138) | class CPPArgList:
    method __repr__ (line 141) | def __repr__(self):
    method action (line 145) | def action(tok):
    method build (line 152) | def build() -> pp.ParseExpression:
  class CPPFuncName (line 159) | class CPPFuncName:
    method action (line 163) | def action(tok):
    method build (line 167) | def build() -> pp.ParseExpression:
  class CPPFuncSignature (line 175) | class CPPFuncSignature:
    method __repr__ (line 182) | def __repr__(self):
    method action_typed (line 196) | def action_typed(tok):
    method action_untyped (line 201) | def action_untyped(tok):
    method build (line 206) | def build() -> pp.ParseExpression:
  function parse_signature (line 234) | def parse_signature(signature: str) -> Optional[CPPFuncSignature]:

FILE: cli/gfuzz/commands/gen/cpp/gen_cpp.py
  class CPPScopeType (line 225) | class CPPScopeType(enum.Enum):
  function _is_live_type (line 243) | def _is_live_type(obj: dict) -> bool:
  function _classify (line 247) | def _classify(parent: dict, sig: CPPFuncSignature, is_static: bool) -> C...
  function _escape_text (line 268) | def _escape_text(t: str) -> str:
  class CPPScope (line 272) | class CPPScope(object):
    method __init__ (line 273) | def __init__(self, name: str, inputs: List[str], outputs: List[str],
    method from_dict (line 295) | def from_dict(info: dict) -> 'CPPScope':
    method destructor_for (line 321) | def destructor_for(schema: Schema, parent: dict) -> 'CPPScope':
    method from_signature (line 326) | def from_signature(schema: Schema, parent: dict, sig: CPPFuncSignature...
    method __repr__ (line 524) | def __repr__(self):
    method resolve_all (line 527) | def resolve_all(self, schema: Schema, verbose=False):
    method is_resolved (line 582) | def is_resolved(self) -> bool:
    method get_resolve_errors (line 585) | def get_resolve_errors(self) -> List[str]:
    method build_scopedef (line 588) | def build_scopedef(self):
    method build_exec_shim (line 604) | def build_exec_shim(self, shim_name, soft_execution=False, generate_dr...
    method build_write_shim (line 753) | def build_write_shim(self, shim_name) -> str:
  function _apply_signature_filter (line 939) | def _apply_signature_filter(sig: str, ignore_keywords: List[str] = []) -...
  function _build_custom_scope (line 946) | def _build_custom_scope(info: dict) -> CPPScope:
  function collect_scopes (line 955) | def collect_scopes(schema: Schema, ignore_keywords: List[str] = [], gene...
  function collect_headers (line 1031) | def collect_headers(schema: Schema) -> Tuple[List[str], List[str]]:
  function make_exec_harness (line 1047) | def make_exec_harness(schema: Schema, scopes: List[CPPScope], soft_execu...
  function make_write_harness (line 1099) | def make_write_harness(schema: Schema, scopes: List[CPPScope]) -> str:
  function make_fuzz_schema (line 1137) | def make_fuzz_schema(schema: Schema, scopes: List[CPPScope]) -> dict:
  function _enumerate_bundleable (line 1150) | def _enumerate_bundleable(bundle: dict, types: List[dict]) -> List[int]:
  function _compose_bundle (line 1167) | def _compose_bundle(outer: dict, inner: dict):
  function make_bundled_scope (line 1182) | def make_bundled_scope(schema: Schema, scope: CPPScope, bundle: dict) ->...
  function duplicate_bundle_scopes (line 1225) | def duplicate_bundle_scopes(schema: Schema, scopes: List[CPPScope]) -> L...
  function generate_harness (line 1242) | def generate_harness(schema: Schema, output_path: str, soft_execution: b...
  function register (line 1308) | def register(sub):
  function execute (line 1321) | def execute(args):

FILE: cli/gfuzz/commands/gen/cpp/test_cpp_sig.py
  class TestCPPSig (line 8) | class TestCPPSig(unittest.TestCase):
    method test_invalid (line 10) | def test_invalid(self):
    method test_foo (line 20) | def test_foo(self):
    method test_named_args (line 25) | def test_named_args(self):
    method test_unnamed_args (line 48) | def test_unnamed_args(self):
    method test_overloaded (line 77) | def test_overloaded(self):
    method test_trailing_modifiers (line 92) | def test_trailing_modifiers(self):
    method test_raw_values (line 113) | def test_raw_values(self):

FILE: cli/gfuzz/commands/gen/gen.py
  function register (line 15) | def register(parser):
  function execute (line 22) | def execute(args):

FILE: cli/gfuzz/commands/minimizer.py
  function template_for (line 8) | def template_for(word):
  function test_example (line 14) | def test_example(fuzzer, example, extra):
  function mutate (line 39) | def mutate(fuzzer, example):
  function minimize_crash (line 53) | def minimize_crash(fuzzer, crash, extra='', early_stop=50):
  function register (line 100) | def register(sub):
  function execute (line 107) | def execute(args):

FILE: cli/gfuzz/commands/schema.py
  function parse_function (line 15) | def parse_function(tag: bs4.element.Tag) -> str:
  function parse_enum (line 25) | def parse_enum(tag: bs4.element.Tag, header: str) -> dict:
  function parse_typedef (line 40) | def parse_typedef(tag: bs4.element.Tag, header: str) -> dict:
  function extract_file (line 53) | def extract_file(root: pathlib.Path, refid: str) -> Tuple[str, dict]:
  function extract_struct (line 90) | def extract_struct(root: pathlib.Path, refid: str) -> Tuple[str, dict]:
  function extract_all (line 122) | def extract_all(root: pathlib.Path) -> dict:
  function run_infer (line 141) | def run_infer(args):
  function register (line 159) | def register(parser):
  function execute (line 167) | def execute(args):

FILE: cli/gfuzz/docker_util.py
  function check_docker (line 6) | def check_docker():
  function build_image (line 19) | def build_image(path: pathlib.Path, tag: str):
  function run_image (line 35) | def run_image(tag: str, cmd: str, volumes: dict = {}, inner_args: str = ...

FILE: cli/gfuzz/schema.py
  function _validate_obj (line 6) | def _validate_obj(name: str, obj: dict, orig_path: str) -> dict:
  class Schema (line 26) | class Schema(object):
    method __init__ (line 29) | def __init__(self):
    method add_all (line 32) | def add_all(self, other: 'Schema'):
    method add_unique (line 35) | def add_unique(self, obj: dict) -> dict:
    method load (line 49) | def load(path: str, loaded: Set[str] = None) -> 'Schema':
    method save (line 82) | def save(self, path: str):
    method resolve (line 85) | def resolve(self, name: str) -> dict:
    method assign_ids (line 96) | def assign_ids(self):

FILE: core/graph.hpp
  type NodeLink (line 29) | struct NodeLink {
  class TGraph (line 38) | class TGraph {
    method AddNode (line 54) | int AddNode(ScopeDef scope, unsigned int layer) {
    method ResetNode (line 68) | void ResetNode(Node *n, ScopeDef scope) {
    method GetOpenLinks (line 92) | std::vector<NodeLink> GetOpenLinks() {
    method GetAllLinks (line 113) | std::vector<NodeLink> GetAllLinks() {
    method Link (line 135) | void Link(int node_a, int conn_a, int node_b, int conn_b) {
    method Unlink (line 148) | void Unlink(int node_a, int conn_a) {
    method UnlinkBackward (line 161) | void UnlinkBackward(int node_b, int conn_b) {
    method Visit (line 175) | void Visit(std::unordered_set<int> *seen, int idx) {
    method ReindexNode (line 191) | void ReindexNode(Node *n, int new_idx) {
    method ApplyOffset (line 210) | void ApplyOffset(int idx_offset, int layer_offset) {
    method Collapse (line 233) | void Collapse(std::unordered_set<int> keep) {
    method AppendNode (line 254) | void AppendNode(const Node &n2) {
    method CopyOther (line 277) | void CopyOther(TGraph other) {
    method SimplifyLayers (line 297) | void SimplifyLayers() {
    method ResetLayers (line 330) | void ResetLayers(unsigned int node_idx, int layer) {
    method AppendTree (line 349) | void AppendTree(unsigned int node_idx, unsigned int conn_idx, int laye...
    method FillOneTerminal (line 386) | void FillOneTerminal(NodeLink n) {
    method FillTerminal (line 395) | void FillTerminal() {
    method MutateContext (line 407) | bool MutateContext() {
    method MutateExtendDestructor (line 432) | void MutateExtendDestructor() {
    method MutateExtendConstructor (line 473) | void MutateExtendConstructor() {
    method MutateCrosslink (line 518) | void MutateCrosslink(unsigned int split=0) {
    method MutateTruncateDestructor (line 590) | void MutateTruncateDestructor() {
    method MutateTruncateConstructor (line 623) | void MutateTruncateConstructor() {
    method MutateSwapEquivalent (line 656) | void MutateSwapEquivalent() {
    method MutateLayerIndex (line 673) | void MutateLayerIndex() {
    method MutateSpliceIn (line 699) | void MutateSpliceIn() {
    method MutateSpliceOut (line 745) | void MutateSpliceOut() {
    method MutateCross (line 785) | bool MutateCross(TGraph other) {
    method TGraph (line 799) | TGraph(Schema *schema) : schema(schema) {}
    method Create (line 804) | bool Create(unsigned int seed, unsigned int max_nodes) {
    method CreateWithScope (line 810) | bool CreateWithScope(ScopeDef def) {
    method Mutate (line 818) | bool Mutate(unsigned int seed, unsigned int max_nodes, float context_m...
    method Cross (line 849) | bool Cross(TGraph other, unsigned int seed, unsigned int max_nodes) {
    method Complete (line 861) | void Complete() {
    method PrintNode (line 865) | void PrintNode(Node n) {
    method PrintAll (line 883) | void PrintAll() {
    method GetOrderedNodes (line 894) | std::vector<Node> GetOrderedNodes() {
    method Write (line 911) | std::string Write(bool *err) {
    method Read (line 917) | bool Read(std::string inp) {
    method Validate (line 921) | bool Validate() {

FILE: core/graphTest.cpp
  function TEST (line 7) | TEST(graph, fillTerminal) {
  function TEST (line 34) | TEST(graph, fillMultiTerminal) {
  function main (line 86) | int main(int argc, char **argv) {

FILE: core/harness.cpp
  function sig_handler (line 64) | void sig_handler(int a) {
  function register_signals (line 69) | void register_signals() {
  function readInts (line 77) | std::vector<int> readInts(char *input) {
  function hexlify (line 95) | std::string hexlify(unsigned char *arr, int size) {
  function LLVMFuzzerInitialize (line 104) | int LLVMFuzzerInitialize(int *argc, char ***argv) {
  function MutateOne (line 212) | int MutateOne(const char *s_seed, const char *in_file, const char *out_f...
  function InitCorpus (line 244) | int InitCorpus(const char *init_corpus_dir) {
  function LLVMFuzzerCustomMutator (line 272) | size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, size_t MaxSiz...
  function LLVMFuzzerCustomCrossOver (line 328) | size_t LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1, con...
  function LLVMFuzzerTestOneInput (line 403) | int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
  function graphfuzz_invalid (line 476) | void graphfuzz_invalid() {
  function graphfuzz_try (line 480) | int graphfuzz_try() {
  function graphfuzz_bail (line 488) | void graphfuzz_bail() {

FILE: core/json.hpp
  type nlohmann (line 81) | namespace nlohmann
    type detail (line 83) | namespace detail
      type position_t (line 86) | struct position_t
      class exception (line 2419) | class exception : public std::exception
        method JSON_HEDLEY_RETURNS_NON_NULL (line 2423) | JSON_HEDLEY_RETURNS_NON_NULL
        method JSON_HEDLEY_NON_NULL (line 2433) | JSON_HEDLEY_NON_NULL(3)
        method name (line 2436) | static std::string name(const std::string& ename, int id_)
      class parse_error (line 2491) | class parse_error : public exception
        method parse_error (line 2503) | static parse_error create(int id_, const position_t& pos, const st...
        method parse_error (line 2510) | static parse_error create(int id_, std::size_t byte_, const std::s...
        method parse_error (line 2530) | parse_error(int id_, std::size_t byte_, const char* what_arg)
        method position_string (line 2533) | static std::string position_string(const position_t& pos)
      class invalid_iterator (line 2577) | class invalid_iterator : public exception
        method invalid_iterator (line 2580) | static invalid_iterator create(int id_, const std::string& what_arg)
        method JSON_HEDLEY_NON_NULL (line 2587) | JSON_HEDLEY_NON_NULL(3)
      class type_error (line 2631) | class type_error : public exception
        method type_error (line 2634) | static type_error create(int id_, const std::string& what_arg)
        method JSON_HEDLEY_NON_NULL (line 2641) | JSON_HEDLEY_NON_NULL(3)
      class out_of_range (line 2678) | class out_of_range : public exception
        method out_of_range (line 2681) | static out_of_range create(int id_, const std::string& what_arg)
        method JSON_HEDLEY_NON_NULL (line 2688) | JSON_HEDLEY_NON_NULL(3)
      class other_error (line 2716) | class other_error : public exception
        method other_error (line 2719) | static other_error create(int id_, const std::string& what_arg)
        method JSON_HEDLEY_NON_NULL (line 2726) | JSON_HEDLEY_NON_NULL(3)
      type index_sequence (line 2754) | struct index_sequence
        method size (line 2758) | static constexpr std::size_t size() noexcept
      type merge_and_renumber (line 2765) | struct merge_and_renumber
      type make_index_sequence (line 2772) | struct make_index_sequence
      type make_index_sequence<0> (line 2776) | struct make_index_sequence<0> : index_sequence<> {}
      type make_index_sequence<1> (line 2777) | struct make_index_sequence<1> : index_sequence<0> {}
      type priority_tag (line 2783) | struct priority_tag : priority_tag < N - 1 > {}
      type priority_tag<0> (line 2784) | struct priority_tag<0> {}
      type static_const (line 2788) | struct static_const
      type make_void (line 2817) | struct make_void
      type iterator_types (line 2833) | struct iterator_types {}
      type iterator_types <
    It,
    void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
    typename It::reference, typename It::iterator_category >> (line 2836) | struct iterator_types <
      type iterator_traits (line 2851) | struct iterator_traits
      type iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >> (line 2856) | struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
      type iterator_traits<T*, enable_if_t<std::is_object<T>::value>> (line 2862) | struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
      type nonesuch (line 2890) | struct nonesuch
        method nonesuch (line 2892) | nonesuch() = delete;
        method nonesuch (line 2894) | nonesuch(nonesuch const&) = delete;
        method nonesuch (line 2895) | nonesuch(nonesuch const&&) = delete;
      type detector (line 2904) | struct detector
      type is_basic_json (line 3044) | struct is_basic_json : std::false_type {}
      class json_ref (line 3054) | class json_ref
        method json_ref (line 12606) | json_ref(value_type&& value)
        method json_ref (line 12612) | json_ref(const value_type& value)
        method json_ref (line 12617) | json_ref(std::initializer_list<json_ref> init)
        method json_ref (line 12626) | json_ref(Args && ... args)
        method json_ref (line 12633) | json_ref(json_ref&&) = default;
        method json_ref (line 12634) | json_ref(const json_ref&) = delete;
        method json_ref (line 12635) | json_ref& operator=(const json_ref&) = delete;
        method json_ref (line 12636) | json_ref& operator=(json_ref&&) = delete;
        method value_type (line 12639) | value_type moved_or_copied() const
        method value_type (line 12648) | value_type const& operator*() const
        method value_type (line 12653) | value_type const* operator->() const
      type is_json_ref (line 3057) | struct is_json_ref : std::false_type {}
      type is_json_ref<json_ref<T>> (line 3060) | struct is_json_ref<json_ref<T>> : std::true_type {}
      type has_from_json (line 3101) | struct has_from_json : std::false_type {}
      type is_getable (line 3108) | struct is_getable
      type has_from_json < BasicJsonType, T,
           enable_if_t < !is_basic_json<T>::value >> (line 3114) | struct has_from_json < BasicJsonType, T,
      type has_non_default_from_json (line 3127) | struct has_non_default_from_json : std::false_type {}
      type has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >> (line 3130) | struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !...
      type has_to_json (line 3142) | struct has_to_json : std::false_type {}
      type has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >> (line 3145) | struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<...
      type is_iterator_traits (line 3160) | struct is_iterator_traits : std::false_type {}
      type is_iterator_traits<iterator_traits<T>> (line 3163) | struct is_iterator_traits<iterator_traits<T>>
      type is_complete_type (line 3180) | struct is_complete_type : std::false_type {}
      type is_complete_type<T, decltype(void(sizeof(T)))> (line 3183) | struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_ty...
      type is_compatible_object_type_impl (line 3187) | struct is_compatible_object_type_impl : std::false_type {}
      type is_compatible_object_type_impl <
    BasicJsonType, CompatibleObjectType,
    enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
    is_detected<key_type_t, CompatibleObjectType>::value >> (line 3190) | struct is_compatible_object_type_impl <
      type is_compatible_object_type (line 3207) | struct is_compatible_object_type
      type is_constructible_object_type_impl (line 3212) | struct is_constructible_object_type_impl : std::false_type {}
      type is_constructible_object_type_impl <
    BasicJsonType, ConstructibleObjectType,
    enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
    is_detected<key_type_t, ConstructibleObjectType>::value >> (line 3215) | struct is_constructible_object_type_impl <
      type is_constructible_object_type (line 3239) | struct is_constructible_object_type
      type is_compatible_string_type_impl (line 3245) | struct is_compatible_string_type_impl : std::false_type {}
      type is_compatible_string_type_impl <
    BasicJsonType, CompatibleStringType,
    enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
    value_type_t, CompatibleStringType>::value >> (line 3248) | struct is_compatible_string_type_impl <
      type is_compatible_string_type (line 3258) | struct is_compatible_string_type
      type is_constructible_string_type_impl (line 3263) | struct is_constructible_string_type_impl : std::false_type {}
      type is_constructible_string_type_impl <
    BasicJsonType, ConstructibleStringType,
    enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
    value_type_t, ConstructibleStringType>::value >> (line 3266) | struct is_constructible_string_type_impl <
      type is_constructible_string_type (line 3277) | struct is_constructible_string_type
      type is_compatible_array_type_impl (line 3281) | struct is_compatible_array_type_impl : std::false_type {}
      type is_compatible_array_type (line 3300) | struct is_compatible_array_type
      type is_constructible_array_type_impl (line 3304) | struct is_constructible_array_type_impl : std::false_type {}
      type is_constructible_array_type_impl <
    BasicJsonType, ConstructibleArrayType,
    enable_if_t<std::is_same<ConstructibleArrayType,
    typename BasicJsonType::value_type>::value >> (line 3307) | struct is_constructible_array_type_impl <
      type is_constructible_array_type_impl <
    BasicJsonType, ConstructibleArrayType,
    enable_if_t < !std::is_same<ConstructibleArrayType,
    typename BasicJsonType::value_type>::value&&
    std::is_default_constructible<ConstructibleArrayType>::value&&
(std::is_move_assignable<ConstructibleArrayType>::value ||
 std::is_copy_assignable<ConstructibleArrayType>::value)&&
is_detected<value_type_t, ConstructibleArrayType>::value&&
is_detected<iterator_t, ConstructibleArrayType>::value&&
is_complete_type <
detected_t<value_type_t, ConstructibleArrayType >>::value >> (line 3314) | struct is_constructible_array_type_impl <
      type is_constructible_array_type (line 3343) | struct is_constructible_array_type
      type is_compatible_integer_type_impl (line 3348) | struct is_compatible_integer_type_impl : std::false_type {}
      type is_compatible_integer_type_impl <
    RealIntegerType, CompatibleNumberIntegerType,
    enable_if_t < std::is_integral<RealIntegerType>::value&&
    std::is_integral<CompatibleNumberIntegerType>::value&&
    !std::is_same<bool, CompatibleNumberIntegerType>::value >> (line 3351) | struct is_compatible_integer_type_impl <
      type is_compatible_integer_type (line 3369) | struct is_compatible_integer_type
      type is_compatible_type_impl (line 3374) | struct is_compatible_type_impl: std::false_type {}
      type is_compatible_type_impl <
    BasicJsonType, CompatibleType,
    enable_if_t<is_complete_type<CompatibleType>::value >> (line 3377) | struct is_compatible_type_impl <
      type is_compatible_type (line 3386) | struct is_compatible_type
      type conjunction (line 3390) | struct conjunction : std::true_type { }
      type conjunction<B1> (line 3391) | struct conjunction<B1> : B1 { }
      type is_constructible_tuple (line 3397) | struct is_constructible_tuple : std::false_type {}
      type value_t (line 3444) | enum class value_t : std::uint8_t
      function from_json (line 3493) | void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
      function get_arithmetic_value (line 3507) | void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
      function from_json (line 3533) | void from_json(const BasicJsonType& j, typename BasicJsonType::boole...
      function from_json (line 3543) | void from_json(const BasicJsonType& j, typename BasicJsonType::strin...
      function from_json (line 3559) | void from_json(const BasicJsonType& j, ConstructibleStringType& s)
      function from_json (line 3570) | void from_json(const BasicJsonType& j, typename BasicJsonType::numbe...
      function from_json (line 3576) | void from_json(const BasicJsonType& j, typename BasicJsonType::numbe...
      function from_json (line 3582) | void from_json(const BasicJsonType& j, typename BasicJsonType::numbe...
      function from_json (line 3589) | void from_json(const BasicJsonType& j, EnumType& e)
      function from_json (line 3599) | void from_json(const BasicJsonType& j, std::forward_list<T, Allocato...
      function from_json (line 3616) | void from_json(const BasicJsonType& j, std::valarray<T>& l)
      function from_json (line 3631) | auto from_json(const BasicJsonType& j, T (&arr)[N])
      function from_json_array_impl (line 3641) | void from_json_array_impl(const BasicJsonType& j, typename BasicJson...
      function from_json_array_impl (line 3647) | auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& ...
      function from_json_array_impl (line 3658) | auto from_json_array_impl(const BasicJsonType& j, ConstructibleArray...
      function from_json_array_impl (line 3679) | void from_json_array_impl(const BasicJsonType& j, ConstructibleArray...
      function from_json (line 3704) | auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
      function from_json (line 3719) | void from_json(const BasicJsonType& j, typename BasicJsonType::binar...
      function from_json (line 3731) | void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
      function from_json (line 3763) | void from_json(const BasicJsonType& j, ArithmeticType& val)
      function from_json (line 3794) | void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
      function from_json_tuple_impl (line 3800) | void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_se...
      function from_json (line 3806) | void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
      function from_json (line 3814) | void from_json(const BasicJsonType& j, std::map<Key, Value, Compare,...
      function from_json (line 3834) | void from_json(const BasicJsonType& j, std::unordered_map<Key, Value...
      type from_json_fn (line 3851) | struct from_json_fn
      function int_to_string (line 3902) | void int_to_string( string_type& target, std::size_t value )
      class iteration_proxy_value (line 3908) | class iteration_proxy_value
        method iteration_proxy_value (line 3931) | explicit iteration_proxy_value(IteratorType it) noexcept : anchor(...
        method iteration_proxy_value (line 3934) | iteration_proxy_value& operator*()
        method iteration_proxy_value (line 3940) | iteration_proxy_value& operator++()
        method string_type (line 3961) | const string_type& key() const
        method value (line 3989) | typename IteratorType::reference value() const
      class iteration_proxy (line 3996) | class iteration_proxy
        method iteration_proxy (line 4004) | explicit iteration_proxy(typename IteratorType::reference cont) no...
        method begin (line 4008) | iteration_proxy_value<IteratorType> begin() noexcept
        method end (line 4014) | iteration_proxy_value<IteratorType> end() noexcept
      function get (line 4023) | auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>...
      function get (line 4031) | auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>...
      type external_constructor (line 4081) | struct external_constructor
      type external_constructor<value_t::boolean> (line 4084) | struct external_constructor<value_t::boolean>
        method construct (line 4087) | static void construct(BasicJsonType& j, typename BasicJsonType::bo...
      type external_constructor<value_t::string> (line 4096) | struct external_constructor<value_t::string>
        method construct (line 4099) | static void construct(BasicJsonType& j, const typename BasicJsonTy...
        method construct (line 4107) | static void construct(BasicJsonType& j, typename BasicJsonType::st...
        method construct (line 4117) | static void construct(BasicJsonType& j, const CompatibleStringType...
      type external_constructor<value_t::binary> (line 4126) | struct external_constructor<value_t::binary>
        method construct (line 4129) | static void construct(BasicJsonType& j, const typename BasicJsonTy...
        method construct (line 4138) | static void construct(BasicJsonType& j, typename BasicJsonType::bi...
      type external_constructor<value_t::number_float> (line 4148) | struct external_constructor<value_t::number_float>
        method construct (line 4151) | static void construct(BasicJsonType& j, typename BasicJsonType::nu...
      type external_constructor<value_t::number_unsigned> (line 4160) | struct external_constructor<value_t::number_unsigned>
        method construct (line 4163) | static void construct(BasicJsonType& j, typename BasicJsonType::nu...
      type external_constructor<value_t::number_integer> (line 4172) | struct external_constructor<value_t::number_integer>
        method construct (line 4175) | static void construct(BasicJsonType& j, typename BasicJsonType::nu...
      type external_constructor<value_t::array> (line 4184) | struct external_constructor<value_t::array>
        method construct (line 4187) | static void construct(BasicJsonType& j, const typename BasicJsonTy...
        method construct (line 4195) | static void construct(BasicJsonType& j, typename BasicJsonType::ar...
        method construct (line 4205) | static void construct(BasicJsonType& j, const CompatibleArrayType&...
        method construct (line 4215) | static void construct(BasicJsonType& j, const std::vector<bool>& arr)
        method construct (line 4229) | static void construct(BasicJsonType& j, const std::valarray<T>& arr)
      type external_constructor<value_t::object> (line 4243) | struct external_constructor<value_t::object>
        method construct (line 4246) | static void construct(BasicJsonType& j, const typename BasicJsonTy...
        method construct (line 4254) | static void construct(BasicJsonType& j, typename BasicJsonType::ob...
        method construct (line 4263) | static void construct(BasicJsonType& j, const CompatibleObjectType...
      function to_json (line 4280) | void to_json(BasicJsonType& j, T b) noexcept
      function to_json (line 4287) | void to_json(BasicJsonType& j, const CompatibleString& s)
      function to_json (line 4293) | void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
      function to_json (line 4300) | void to_json(BasicJsonType& j, FloatType val) noexcept
      function to_json (line 4307) | void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noe...
      function to_json (line 4314) | void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noex...
      function to_json (line 4321) | void to_json(BasicJsonType& j, EnumType e) noexcept
      function to_json (line 4328) | void to_json(BasicJsonType& j, const std::vector<bool>& e)
      function to_json (line 4341) | void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
      function to_json (line 4347) | void to_json(BasicJsonType& j, const typename BasicJsonType::binary_...
      function to_json (line 4354) | void to_json(BasicJsonType& j, const std::valarray<T>& arr)
      function to_json (line 4360) | void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
      function to_json (line 4367) | void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
      function to_json (line 4373) | void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
      function to_json (line 4383) | void to_json(BasicJsonType& j, const T(&arr)[N])
      function to_json (line 4389) | void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
      function to_json (line 4397) | void to_json(BasicJsonType& j, const T& b)
      function to_json_tuple_impl (line 4403) | void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequ...
      function to_json (line 4409) | void to_json(BasicJsonType& j, const T& t)
      type to_json_fn (line 4414) | struct to_json_fn
      function combine (line 4662) | inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
      function hash (line 4680) | std::size_t hash(const BasicJsonType& j)
      type input_format_t (line 4812) | enum class input_format_t { json, cbor, msgpack, ubjson, bson }
      class file_input_adapter (line 4822) | class file_input_adapter
        method file_input_adapter (line 4828) | explicit file_input_adapter(std::FILE* f) noexcept
        method file_input_adapter (line 4833) | file_input_adapter(const file_input_adapter&) = delete;
        method file_input_adapter (line 4834) | file_input_adapter(file_input_adapter&&) = default;
        method file_input_adapter (line 4835) | file_input_adapter& operator=(const file_input_adapter&) = delete;
        method file_input_adapter (line 4836) | file_input_adapter& operator=(file_input_adapter&&) = delete;
        method get_character (line 4838) | std::char_traits<char>::int_type get_character() noexcept
      class input_stream_adapter (line 4858) | class input_stream_adapter
        method input_stream_adapter (line 4873) | explicit input_stream_adapter(std::istream& i)
        method input_stream_adapter (line 4878) | input_stream_adapter(const input_stream_adapter&) = delete;
        method input_stream_adapter (line 4879) | input_stream_adapter& operator=(input_stream_adapter&) = delete;
        method input_stream_adapter (line 4880) | input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
        method input_stream_adapter (line 4882) | input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs...
        method get_character (line 4891) | std::char_traits<char>::int_type get_character()
      class iterator_input_adapter (line 4911) | class iterator_input_adapter
        method iterator_input_adapter (line 4916) | iterator_input_adapter(IteratorType first, IteratorType last)
        method get_character (line 4919) | typename std::char_traits<char_type>::int_type get_character()
        method empty (line 4940) | bool empty() const
      type wide_string_input_helper (line 4949) | struct wide_string_input_helper
      type wide_string_input_helper<BaseInputAdapter, 4> (line 4952) | struct wide_string_input_helper<BaseInputAdapter, 4>
        method fill_buffer (line 4955) | static void fill_buffer(BaseInputAdapter& input,
      type wide_string_input_helper<BaseInputAdapter, 2> (line 5010) | struct wide_string_input_helper<BaseInputAdapter, 2>
        method fill_buffer (line 5013) | static void fill_buffer(BaseInputAdapter& input,
      class wide_string_input_adapter (line 5073) | class wide_string_input_adapter
        method wide_string_input_adapter (line 5078) | wide_string_input_adapter(BaseInputAdapter base)
        method get_character (line 5081) | typename std::char_traits<char>::int_type get_character() noexcept
        method fill_buffer (line 5102) | void fill_buffer()
      type iterator_input_adapter_factory (line 5118) | struct iterator_input_adapter_factory
        method adapter_type (line 5124) | static adapter_type create(IteratorType first, IteratorType last)
      type is_iterator_of_multibyte (line 5131) | struct is_iterator_of_multibyte
      type iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>> (line 5141) | struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_i...
        method adapter_type (line 5148) | static adapter_type create(IteratorType first, IteratorType last)
      function input_adapter (line 5156) | typename iterator_input_adapter_factory<IteratorType>::adapter_type ...
      function input_adapter (line 5164) | auto input_adapter(const ContainerType& container) -> decltype(input...
      function file_input_adapter (line 5174) | inline file_input_adapter input_adapter(std::FILE* file)
        method file_input_adapter (line 4828) | explicit file_input_adapter(std::FILE* f) noexcept
        method file_input_adapter (line 4833) | file_input_adapter(const file_input_adapter&) = delete;
        method file_input_adapter (line 4834) | file_input_adapter(file_input_adapter&&) = default;
        method file_input_adapter (line 4835) | file_input_adapter& operator=(const file_input_adapter&) = delete;
        method file_input_adapter (line 4836) | file_input_adapter& operator=(file_input_adapter&&) = delete;
        method get_character (line 4838) | std::char_traits<char>::int_type get_character() noexcept
      function input_stream_adapter (line 5179) | inline input_stream_adapter input_adapter(std::istream& stream)
        method input_stream_adapter (line 4873) | explicit input_stream_adapter(std::istream& i)
        method input_stream_adapter (line 4878) | input_stream_adapter(const input_stream_adapter&) = delete;
        method input_stream_adapter (line 4879) | input_stream_adapter& operator=(input_stream_adapter&) = delete;
        method input_stream_adapter (line 4880) | input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
        method input_stream_adapter (line 4882) | input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs...
        method get_character (line 4891) | std::char_traits<char>::int_type get_character()
      function input_stream_adapter (line 5184) | inline input_stream_adapter input_adapter(std::istream&& stream)
        method input_stream_adapter (line 4873) | explicit input_stream_adapter(std::istream& i)
        method input_stream_adapter (line 4878) | input_stream_adapter(const input_stream_adapter&) = delete;
        method input_stream_adapter (line 4879) | input_stream_adapter& operator=(input_stream_adapter&) = delete;
        method input_stream_adapter (line 4880) | input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
        method input_stream_adapter (line 4882) | input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs...
        method get_character (line 4891) | std::char_traits<char>::int_type get_character()
      function contiguous_bytes_input_adapter (line 5199) | contiguous_bytes_input_adapter input_adapter(CharT b)
      function input_adapter (line 5207) | auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, a...
      class span_input_adapter (line 5215) | class span_input_adapter
        method span_input_adapter (line 5224) | span_input_adapter(CharT b, std::size_t l)
        method span_input_adapter (line 5231) | span_input_adapter(IteratorType first, IteratorType last)
        method contiguous_bytes_input_adapter (line 5234) | contiguous_bytes_input_adapter&& get()
      class json_sax_dom_parser (line 5396) | class json_sax_dom_parser
        method json_sax_dom_parser (line 5410) | explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_ex...
        method json_sax_dom_parser (line 5415) | json_sax_dom_parser(const json_sax_dom_parser&) = delete;
        method json_sax_dom_parser (line 5416) | json_sax_dom_parser(json_sax_dom_parser&&) = default;
        method json_sax_dom_parser (line 5417) | json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
        method json_sax_dom_parser (line 5418) | json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
        method null (line 5421) | bool null()
        method boolean (line 5427) | bool boolean(bool val)
        method number_integer (line 5433) | bool number_integer(number_integer_t val)
        method number_unsigned (line 5439) | bool number_unsigned(number_unsigned_t val)
        method number_float (line 5445) | bool number_float(number_float_t val, const string_t& /*unused*/)
        method string (line 5451) | bool string(string_t& val)
        method binary (line 5457) | bool binary(binary_t& val)
        method start_object (line 5463) | bool start_object(std::size_t len)
        method key (line 5476) | bool key(string_t& val)
        method end_object (line 5483) | bool end_object()
        method start_array (line 5489) | bool start_array(std::size_t len)
        method end_array (line 5502) | bool end_array()
        method parse_error (line 5509) | bool parse_error(std::size_t /*unused*/, const std::string& /*unus...
        method is_errored (line 5521) | constexpr bool is_errored() const
        method JSON_HEDLEY_RETURNS_NON_NULL (line 5534) | JSON_HEDLEY_RETURNS_NON_NULL
      class json_sax_dom_callback_parser (line 5570) | class json_sax_dom_callback_parser
        method json_sax_dom_callback_parser (line 5581) | json_sax_dom_callback_parser(BasicJsonType& r,
        method json_sax_dom_callback_parser (line 5590) | json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) ...
        method json_sax_dom_callback_parser (line 5591) | json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = def...
        method json_sax_dom_callback_parser (line 5592) | json_sax_dom_callback_parser& operator=(const json_sax_dom_callbac...
        method json_sax_dom_callback_parser (line 5593) | json_sax_dom_callback_parser& operator=(json_sax_dom_callback_pars...
        method null (line 5596) | bool null()
        method boolean (line 5602) | bool boolean(bool val)
        method number_integer (line 5608) | bool number_integer(number_integer_t val)
        method number_unsigned (line 5614) | bool number_unsigned(number_unsigned_t val)
        method number_float (line 5620) | bool number_float(number_float_t val, const string_t& /*unused*/)
        method string (line 5626) | bool string(string_t& val)
        method binary (line 5632) | bool binary(binary_t& val)
        method start_object (line 5638) | bool start_object(std::size_t len)
        method key (line 5656) | bool key(string_t& val)
        method end_object (line 5673) | bool end_object()
        method start_array (line 5702) | bool start_array(std::size_t len)
        method end_array (line 5719) | bool end_array()
        method parse_error (line 5748) | bool parse_error(std::size_t /*unused*/, const std::string& /*unus...
        method is_errored (line 5760) | constexpr bool is_errored() const
        method handle_value (line 5782) | std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool...
      class json_sax_acceptor (line 5866) | class json_sax_acceptor
        method null (line 5875) | bool null()
        method boolean (line 5880) | bool boolean(bool /*unused*/)
        method number_integer (line 5885) | bool number_integer(number_integer_t /*unused*/)
        method number_unsigned (line 5890) | bool number_unsigned(number_unsigned_t /*unused*/)
        method number_float (line 5895) | bool number_float(number_float_t /*unused*/, const string_t& /*unu...
        method string (line 5900) | bool string(string_t& /*unused*/)
        method binary (line 5905) | bool binary(binary_t& /*unused*/)
        method start_object (line 5910) | bool start_object(std::size_t /*unused*/ = std::size_t(-1))
        method key (line 5915) | bool key(string_t& /*unused*/)
        method end_object (line 5920) | bool end_object()
        method start_array (line 5925) | bool start_array(std::size_t /*unused*/ = std::size_t(-1))
        method end_array (line 5930) | bool end_array()
        method parse_error (line 5935) | bool parse_error(std::size_t /*unused*/, const std::string& /*unus...
      class lexer_base (line 5973) | class lexer_base
        type token_type (line 5977) | enum class token_type
      class lexer (line 6050) | class lexer : public lexer_base<BasicJsonType>
        method lexer (line 6062) | explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ =...
        method lexer (line 6069) | lexer(const lexer&) = delete;
        method lexer (line 6070) | lexer(lexer&&) = default;
        method lexer (line 6071) | lexer& operator=(lexer&) = delete;
        method lexer (line 6072) | lexer& operator=(lexer&&) = default;
        method JSON_HEDLEY_PURE (line 6081) | JSON_HEDLEY_PURE
        method get_codepoint (line 6108) | int get_codepoint()
        method next_byte_in_range (line 6156) | bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
        method token_type (line 6193) | token_type scan_string()
        method scan_comment (line 6783) | bool scan_comment()
        method strtof (line 6851) | static void strtof(float& f, const char* str, char** endptr) noexcept
        method strtof (line 6857) | static void strtof(double& f, const char* str, char** endptr) noex...
        method strtof (line 6863) | static void strtof(long double& f, const char* str, char** endptr)...
        method token_type (line 6908) | token_type scan_number()  // lgtm [cpp/use-of-goto]
      type is_sax (line 7641) | struct is_sax
      type is_sax_static_asserts (line 7672) | struct is_sax_static_asserts
      type cbor_tag_handler_t (line 7736) | enum class cbor_tag_handler_t
      function little_endianess (line 7749) | static inline bool little_endianess(int num = 1) noexcept
      class binary_reader (line 7763) | class binary_reader
        method binary_reader (line 7780) | explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(...
        method binary_reader (line 7786) | binary_reader(const binary_reader&) = delete;
        method binary_reader (line 7787) | binary_reader(binary_reader&&) = default;
        method binary_reader (line 7788) | binary_reader& operator=(const binary_reader&) = delete;
        method binary_reader (line 7789) | binary_reader& operator=(binary_reader&&) = default;
        method JSON_HEDLEY_NON_NULL (line 7800) | JSON_HEDLEY_NON_NULL(3)
        method parse_bson_internal (line 7862) | bool parse_bson_internal()
        method get_bson_cstr (line 7887) | bool get_bson_cstr(string_t& result)
        method get_bson_string (line 7917) | bool get_bson_string(const NumberType len, string_t& result)
        method get_bson_binary (line 7938) | bool get_bson_binary(const NumberType len, binary_t& result)
        method parse_bson_element_internal (line 7964) | bool parse_bson_element_internal(const char_int_type element_type,
        method parse_bson_element_list (line 8042) | bool parse_bson_element_list(const bool is_array)
        method parse_bson_array (line 8080) | bool parse_bson_array()
        method parse_cbor_internal (line 8110) | bool parse_cbor_internal(const bool get_char,
        method get_cbor_string (line 8556) | bool get_cbor_string(string_t& result)
        method get_cbor_binary (line 8651) | bool get_cbor_binary(binary_t& result)
        method get_cbor_array (line 8745) | bool get_cbor_array(const std::size_t len,
        method get_cbor_object (line 8783) | bool get_cbor_object(const std::size_t len,
        method parse_msgpack_internal (line 8836) | bool parse_msgpack_internal()
        method get_msgpack_string (line 9216) | bool get_msgpack_string(string_t& result)
        method get_msgpack_binary (line 9298) | bool get_msgpack_binary(binary_t& result)
        method get_msgpack_array (line 9409) | bool get_msgpack_array(const std::size_t len)
        method get_msgpack_object (line 9431) | bool get_msgpack_object(const std::size_t len)
        method parse_ubjson_internal (line 9468) | bool parse_ubjson_internal(const bool get_char = true)
        method get_ubjson_string (line 9487) | bool get_ubjson_string(string_t& result, const bool get_char = true)
        method get_ubjson_size_value (line 9541) | bool get_ubjson_size_value(std::size_t& result)
        method get_ubjson_size_type (line 9618) | bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& r...
        method get_ubjson_value (line 9659) | bool get_ubjson_value(const char_int_type prefix)
        method get_ubjson_array (line 9760) | bool get_ubjson_array()
        method get_ubjson_object (line 9822) | bool get_ubjson_object()
        method get_ubjson_high_precision_number (line 9897) | bool get_ubjson_high_precision_number()
        method char_int_type (line 9959) | char_int_type get()
        method char_int_type (line 9968) | char_int_type get_ignore_noop()
        method get_number (line 9993) | bool get_number(const input_format_t format, NumberType& result)
        method get_string (line 10036) | bool get_string(const input_format_t format,
        method get_binary (line 10069) | bool get_binary(const input_format_t format,
        method JSON_HEDLEY_NON_NULL (line 10092) | JSON_HEDLEY_NON_NULL(3)
        method get_token_string (line 10106) | std::string get_token_string() const
        method exception_message (line 10119) | std::string exception_message(const input_format_t format,
      type parse_event_t (line 10206) | enum class parse_event_t : uint8_t
      class parser (line 10232) | class parser
        method parser (line 10243) | explicit parser(InputAdapterType&& adapter,
        method parse (line 10265) | void parse(const bool strict, BasicJsonType& result)
        method accept (line 10326) | bool accept(const bool strict = true)
        method sax_parse (line 10334) | bool sax_parse(SAX* sax, const bool strict = true)
        method sax_parse_internal (line 10354) | bool sax_parse_internal(SAX* sax)
        method token_type (line 10636) | token_type get_token()
        method exception_message (line 10641) | std::string exception_message(const token_type expected, const std...
      class primitive_iterator_t (line 10705) | class primitive_iterator_t
        method difference_type (line 10717) | constexpr difference_type get_value() const noexcept
        method set_begin (line 10723) | void set_begin() noexcept
        method set_end (line 10729) | void set_end() noexcept
        method is_begin (line 10735) | constexpr bool is_begin() const noexcept
        method is_end (line 10741) | constexpr bool is_end() const noexcept
        method primitive_iterator_t (line 10756) | primitive_iterator_t operator+(difference_type n) noexcept
        method difference_type (line 10763) | constexpr difference_type operator-(primitive_iterator_t lhs, prim...
        method primitive_iterator_t (line 10768) | primitive_iterator_t& operator++() noexcept
        method primitive_iterator_t (line 10774) | primitive_iterator_t const operator++(int) noexcept
        method primitive_iterator_t (line 10781) | primitive_iterator_t& operator--() noexcept
        method primitive_iterator_t (line 10787) | primitive_iterator_t const operator--(int) noexcept
        method primitive_iterator_t (line 10794) | primitive_iterator_t& operator+=(difference_type n) noexcept
        method primitive_iterator_t (line 10800) | primitive_iterator_t& operator-=(difference_type n) noexcept
      type internal_iterator (line 10820) | struct internal_iterator
      class iteration_proxy (line 10858) | class iteration_proxy
        method iteration_proxy (line 4004) | explicit iteration_proxy(typename IteratorType::reference cont) no...
        method begin (line 4008) | iteration_proxy_value<IteratorType> begin() noexcept
        method end (line 4014) | iteration_proxy_value<IteratorType> end() noexcept
      class iteration_proxy_value (line 10859) | class iteration_proxy_value
        method iteration_proxy_value (line 3931) | explicit iteration_proxy_value(IteratorType it) noexcept : anchor(...
        method iteration_proxy_value (line 3934) | iteration_proxy_value& operator*()
        method iteration_proxy_value (line 3940) | iteration_proxy_value& operator++()
        method string_type (line 3961) | const string_type& key() const
        method value (line 3989) | typename IteratorType::reference value() const
      function set_end (line 10878) | class iter_impl
      class json_reverse_iterator (line 11514) | class json_reverse_iterator : public std::reverse_iterator<Base>
        method json_reverse_iterator (line 11524) | explicit json_reverse_iterator(const typename base_iterator::itera...
        method json_reverse_iterator (line 11528) | explicit json_reverse_iterator(const base_iterator& it) noexcept :...
        method json_reverse_iterator (line 11531) | json_reverse_iterator const operator++(int)
        method json_reverse_iterator (line 11537) | json_reverse_iterator& operator++()
        method json_reverse_iterator (line 11543) | json_reverse_iterator const operator--(int)
        method json_reverse_iterator (line 11549) | json_reverse_iterator& operator--()
        method json_reverse_iterator (line 11555) | json_reverse_iterator& operator+=(difference_type i)
        method json_reverse_iterator (line 11561) | json_reverse_iterator operator+(difference_type i) const
        method json_reverse_iterator (line 11567) | json_reverse_iterator operator-(difference_type i) const
        method difference_type (line 11573) | difference_type operator-(const json_reverse_iterator& other) const
        method reference (line 11579) | reference operator[](difference_type n) const
        method key (line 11585) | auto key() const -> decltype(std::declval<Base>().key())
        method reference (line 11592) | reference value() const
      class json_ref (line 12601) | class json_ref
        method json_ref (line 12606) | json_ref(value_type&& value)
        method json_ref (line 12612) | json_ref(const value_type& value)
        method json_ref (line 12617) | json_ref(std::initializer_list<json_ref> init)
        method json_ref (line 12626) | json_ref(Args && ... args)
        method json_ref (line 12633) | json_ref(json_ref&&) = default;
        method json_ref (line 12634) | json_ref(const json_ref&) = delete;
        method json_ref (line 12635) | json_ref& operator=(const json_ref&) = delete;
        method json_ref (line 12636) | json_ref& operator=(json_ref&&) = delete;
        method value_type (line 12639) | value_type moved_or_copied() const
        method value_type (line 12648) | value_type const& operator*() const
        method value_type (line 12653) | value_type const* operator->() const
      type output_adapter_protocol (line 12706) | struct output_adapter_protocol
      class output_vector_adapter (line 12719) | class output_vector_adapter : public output_adapter_protocol<CharType>
        method output_vector_adapter (line 12722) | explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
        method write_character (line 12726) | void write_character(CharType c) override
        method JSON_HEDLEY_NON_NULL (line 12731) | JSON_HEDLEY_NON_NULL(2)
      class output_stream_adapter (line 12743) | class output_stream_adapter : public output_adapter_protocol<CharType>
        method output_stream_adapter (line 12746) | explicit output_stream_adapter(std::basic_ostream<CharType>& s) no...
        method write_character (line 12750) | void write_character(CharType c) override
        method JSON_HEDLEY_NON_NULL (line 12755) | JSON_HEDLEY_NON_NULL(2)
      class output_string_adapter (line 12767) | class output_string_adapter : public output_adapter_protocol<CharType>
        method output_string_adapter (line 12770) | explicit output_string_adapter(StringType& s) noexcept
        method write_character (line 12774) | void write_character(CharType c) override
        method JSON_HEDLEY_NON_NULL (line 12779) | JSON_HEDLEY_NON_NULL(2)
      class output_adapter (line 12790) | class output_adapter
        method output_adapter (line 12793) | output_adapter(std::vector<CharType>& vec)
        method output_adapter (line 12796) | output_adapter(std::basic_ostream<CharType>& s)
        method output_adapter (line 12799) | output_adapter(StringType& s)
      class binary_writer (line 12826) | class binary_writer
        method binary_writer (line 12838) | explicit binary_writer(output_adapter_t<CharType> adapter) : oa(ad...
        method write_bson (line 12847) | void write_bson(const BasicJsonType& j)
        method write_cbor (line 12867) | void write_cbor(const BasicJsonType& j)
        method write_msgpack (line 13172) | void write_msgpack(const BasicJsonType& j)
        method write_ubjson (line 13496) | void write_ubjson(const BasicJsonType& j, const bool use_count,
        method calc_bson_entry_header_size (line 13703) | static std::size_t calc_bson_entry_header_size(const string_t& name)
        method write_bson_entry_header (line 13718) | void write_bson_entry_header(const string_t& name,
        method write_bson_boolean (line 13730) | void write_bson_boolean(const string_t& name,
        method write_bson_double (line 13740) | void write_bson_double(const string_t& name,
        method calc_bson_string_size (line 13750) | static std::size_t calc_bson_string_size(const string_t& value)
        method write_bson_string (line 13758) | void write_bson_string(const string_t& name,
        method write_bson_null (line 13772) | void write_bson_null(const string_t& name)
        method calc_bson_integer_size (line 13780) | static std::size_t calc_bson_integer_size(const std::int64_t value)
        method write_bson_integer (line 13790) | void write_bson_integer(const string_t& name,
        method calc_bson_unsigned_size (line 13808) | static constexpr std::size_t calc_bson_unsigned_size(const std::ui...
        method write_bson_unsigned (line 13818) | void write_bson_unsigned(const string_t& name,
        method write_bson_object_entry (line 13840) | void write_bson_object_entry(const string_t& name,
        method calc_bson_array_size (line 13850) | static std::size_t calc_bson_array_size(const typename BasicJsonTy...
        method calc_bson_binary_size (line 13865) | static std::size_t calc_bson_binary_size(const typename BasicJsonT...
        method write_bson_array (line 13873) | void write_bson_array(const string_t& name,
        method write_bson_binary (line 13892) | void write_bson_binary(const string_t& name,
        method calc_bson_element_size (line 13907) | static std::size_t calc_bson_element_size(const string_t& name,
        method write_bson_element (line 13955) | void write_bson_element(const string_t& name,
        method calc_bson_object_size (line 14001) | static std::size_t calc_bson_object_size(const typename BasicJsonT...
        method write_bson_object (line 14016) | void write_bson_object(const typename BasicJsonType::object_t& value)
        method CharType (line 14032) | static constexpr CharType get_cbor_float_prefix(float /*unused*/)
        method CharType (line 14037) | static constexpr CharType get_cbor_float_prefix(double /*unused*/)
        method CharType (line 14046) | static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
        method CharType (line 14051) | static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
        method write_number_with_ubjson_prefix (line 14063) | void write_number_with_ubjson_prefix(const NumberType n,
        method write_number_with_ubjson_prefix (line 14076) | void write_number_with_ubjson_prefix(const NumberType n,
        method write_number_with_ubjson_prefix (line 14139) | void write_number_with_ubjson_prefix(const NumberType n,
        method CharType (line 14203) | CharType ubjson_prefix(const BasicJsonType& j) const noexcept
        method CharType (line 14283) | static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
        method CharType (line 14288) | static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
        method write_number (line 14309) | void write_number(const NumberType n)
        method write_compact_float (line 14325) | void write_compact_float(const number_float_t n, detail::input_for...
        method CharType (line 14352) | static constexpr CharType to_char_type(std::uint8_t x) noexcept
        method CharType (line 14359) | static CharType to_char_type(std::uint8_t x) noexcept
        method CharType (line 14370) | static constexpr CharType to_char_type(std::uint8_t x) noexcept
        method CharType (line 14381) | static constexpr CharType to_char_type(InputCharType x) noexcept
      type dtoa_impl (line 14450) | namespace dtoa_impl
        function Target (line 14454) | Target reinterpret_bits(const Source source)
        type diyfp (line 14463) | struct diyfp // f * 2^e
          method diyfp (line 14470) | constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_...
          method diyfp (line 14476) | static diyfp sub(const diyfp& x, const diyfp& y) noexcept
          method diyfp (line 14488) | static diyfp mul(const diyfp& x, const diyfp& y) noexcept
          method diyfp (line 14553) | static diyfp normalize(diyfp x) noexcept
          method diyfp (line 14570) | static diyfp normalize_to(const diyfp& x, const int target_expon...
        type boundaries (line 14581) | struct boundaries
        function boundaries (line 14595) | boundaries compute_boundaries(FloatType value)
        type cached_power (line 14720) | struct cached_power // c = f * 2^e ~= 10^k
        function cached_power (line 14734) | inline cached_power get_cached_power_for_binary_exponent(int e)
        function find_largest_pow10 (line 14898) | inline int find_largest_pow10(const std::uint32_t n, std::uint32_t...
        function grisu2_round (line 14954) | inline void grisu2_round(char* buf, int len, std::uint64_t dist, s...
        function grisu2_digit_gen (line 14995) | inline void grisu2_digit_gen(char* buffer, int& length, int& decim...
        function grisu2 (line 15236) | inline void grisu2(char* buf, int& len, int& decimal_exponent,
        function JSON_HEDLEY_NON_NULL (line 15295) | JSON_HEDLEY_NON_NULL(1)
      type error_handler_t (line 15543) | enum class error_handler_t
      class serializer (line 15551) | class serializer
        method serializer (line 15567) | serializer(output_adapter_t<char> s, const char ichar,
        method serializer (line 15579) | serializer(const serializer&) = delete;
        method serializer (line 15580) | serializer& operator=(const serializer&) = delete;
        method serializer (line 15581) | serializer(serializer&&) = delete;
        method serializer (line 15582) | serializer& operator=(serializer&&) = delete;
        method dump (line 15607) | void dump(const BasicJsonType& val,
        method switch (line 15905) | switch (decode(state, codepoint, byte))
    type detail (line 2385) | namespace detail
      type position_t (line 86) | struct position_t
      class exception (line 2419) | class exception : public std::exception
        method JSON_HEDLEY_RETURNS_NON_NULL (line 2423) | JSON_HEDLEY_RETURNS_NON_NULL
        method JSON_HEDLEY_NON_NULL (line 2433) | JSON_HEDLEY_NON_NULL(3)
        method name (line 2436) | static std::string name(const std::string& ename, int id_)
      class parse_error (line 2491) | class parse_error : public exception
        method parse_error (line 2503) | static parse_error create(int id_, const position_t& pos, const st...
        method parse_error (line 2510) | static parse_error create(int id_, std::size_t byte_, const std::s...
        method parse_error (line 2530) | parse_error(int id_, std::size_t byte_, const char* what_arg)
        method position_string (line 2533) | static std::string position_string(const position_t& pos)
      class invalid_iterator (line 2577) | class invalid_iterator : public exception
        method invalid_iterator (line 2580) | static invalid_iterator create(int id_, const std::string& what_arg)
        method JSON_HEDLEY_NON_NULL (line 2587) | JSON_HEDLEY_NON_NULL(3)
      class type_error (line 2631) | class type_error : public exception
        method type_error (line 2634) | static type_error create(int id_, const std::string& what_arg)
        method JSON_HEDLEY_NON_NULL (line 2641) | JSON_HEDLEY_NON_NULL(3)
      class out_of_range (line 2678) | class out_of_range : public exception
        method out_of_range (line 2681) | static out_of_range create(int id_, const std::string& what_arg)
        method JSON_HEDLEY_NON_NULL (line 2688) | JSON_HEDLEY_NON_NULL(3)
      class other_error (line 2716) | class other_error : public exception
        method other_error (line 2719) | static other_error create(int id_, const std::string& what_arg)
        method JSON_HEDLEY_NON_NULL (line 2726) | JSON_HEDLEY_NON_NULL(3)
      type index_sequence (line 2754) | struct index_sequence
        method size (line 2758) | static constexpr std::size_t size() noexcept
      type merge_and_renumber (line 2765) | struct merge_and_renumber
      type make_index_sequence (line 2772) | struct make_index_sequence
      type make_index_sequence<0> (line 2776) | struct make_index_sequence<0> : index_sequence<> {}
      type make_index_sequence<1> (line 2777) | struct make_index_sequence<1> : index_sequence<0> {}
      type priority_tag (line 2783) | struct priority_tag : priority_tag < N - 1 > {}
      type priority_tag<0> (line 2784) | struct priority_tag<0> {}
      type static_const (line 2788) | struct static_const
      type make_void (line 2817) | struct make_void
      type iterator_types (line 2833) | struct iterator_types {}
      type iterator_types <
    It,
    void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
    typename It::reference, typename It::iterator_category >> (line 2836) | struct iterator_types <
      type iterator_traits (line 2851) | struct iterator_traits
      type iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >> (line 2856) | struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
      type iterator_traits<T*, enable_if_t<std::is_object<T>::value>> (line 2862) | struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
      type nonesuch (line 2890) | struct nonesuch
        method nonesuch (line 2892) | nonesuch() = delete;
        method nonesuch (line 2894) | nonesuch(nonesuch const&) = delete;
        method nonesuch (line 2895) | nonesuch(nonesuch const&&) = delete;
      type detector (line 2904) | struct detector
      type is_basic_json (line 3044) | struct is_basic_json : std::false_type {}
      class json_ref (line 3054) | class json_ref
        method json_ref (line 12606) | json_ref(value_type&& value)
        method json_ref (line 12612) | json_ref(const value_type& value)
        method json_ref (line 12617) | json_ref(std::initializer_list<json_ref> init)
        method json_ref (line 12626) | json_ref(Args && ... args)
        method json_ref (line 12633) | json_ref(json_ref&&) = default;
        method json_ref (line 12634) | json_ref(const json_ref&) = delete;
        method json_ref (line 12635) | json_ref& operator=(const json_ref&) = delete;
        method json_ref (line 12636) | json_ref& operator=(json_ref&&) = delete;
        method value_type (line 12639) | value_type moved_or_copied() const
        method value_type (line 12648) | value_type const& operator*() const
        method value_type (line 12653) | value_type const* operator->() const
      type is_json_ref (line 3057) | struct is_json_ref : std::false_type {}
      type is_json_ref<json_ref<T>> (line 3060) | struct is_json_ref<json_ref<T>> : std::true_type {}
      type has_from_json (line 3101) | struct has_from_json : std::false_type {}
      type is_getable (line 3108) | struct is_getable
      type has_from_json < BasicJsonType, T,
           enable_if_t < !is_basic_json<T>::value >> (line 3114) | struct has_from_json < BasicJsonType, T,
      type has_non_default_from_json (line 3127) | struct has_non_default_from_json : std::false_type {}
      type has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >> (line 3130) | struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !...
      type has_to_json (line 3142) | struct has_to_json : std::false_type {}
      type has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >> (line 3145) | struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<...
      type is_iterator_traits (line 3160) | struct is_iterator_traits : std::false_type {}
      type is_iterator_traits<iterator_traits<T>> (line 3163) | struct is_iterator_traits<iterator_traits<T>>
      type is_complete_type (line 3180) | struct is_complete_type : std::false_type {}
      type is_complete_type<T, decltype(void(sizeof(T)))> (line 3183) | struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_ty...
      type is_compatible_object_type_impl (line 3187) | struct is_compatible_object_type_impl : std::false_type {}
      type is_compatible_object_type_impl <
    BasicJsonType, CompatibleObjectType,
    enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
    is_detected<key_type_t, CompatibleObjectType>::value >> (line 3190) | struct is_compatible_object_type_impl <
      type is_compatible_object_type (line 3207) | struct is_compatible_object_type
      type is_constructible_object_type_impl (line 3212) | struct is_constructible_object_type_impl : std::false_type {}
      type is_constructible_object_type_impl <
    BasicJsonType, ConstructibleObjectType,
    enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
    is_detected<key_type_t, ConstructibleObjectType>::value >> (line 3215) | struct is_constructible_object_type_impl <
      type is_constructible_object_type (line 3239) | struct is_constructible_object_type
      type is_compatible_string_type_impl (line 3245) | struct is_compatible_string_type_impl : std::false_type {}
      type is_compatible_string_type_impl <
    BasicJsonType, CompatibleStringType,
    enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
    value_type_t, CompatibleStringType>::value >> (line 3248) | struct is_compatible_string_type_impl <
      type is_compatible_string_type (line 3258) | struct is_compatible_string_type
      type is_constructible_string_type_impl (line 3263) | struct is_constructible_string_type_impl : std::false_type {}
      type is_constructible_string_type_impl <
    BasicJsonType, ConstructibleStringType,
    enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
    value_type_t, ConstructibleStringType>::value >> (line 3266) | struct is_constructible_string_type_impl <
      type is_constructible_string_type (line 3277) | struct is_constructible_string_type
      type is_compatible_array_type_impl (line 3281) | struct is_compatible_array_type_impl : std::false_type {}
      type is_compatible_array_type (line 3300) | struct is_compatible_array_type
      type is_constructible_array_type_impl (line 3304) | struct is_constructible_array_type_impl : std::false_type {}
      type is_constructible_array_type_impl <
    BasicJsonType, ConstructibleArrayType,
    enable_if_t<std::is_same<ConstructibleArrayType,
    typename BasicJsonType::value_type>::value >> (line 3307) | struct is_constructible_array_type_impl <
      type is_constructible_array_type_impl <
    BasicJsonType, ConstructibleArrayType,
    enable_if_t < !std::is_same<ConstructibleArrayType,
    typename BasicJsonType::value_type>::value&&
    std::is_default_constructible<ConstructibleArrayType>::value&&
(std::is_move_assignable<ConstructibleArrayType>::value ||
 std::is_copy_assignable<ConstructibleArrayType>::value)&&
is_detected<value_type_t, ConstructibleArrayType>::value&&
is_detected<iterator_t, ConstructibleArrayType>::value&&
is_complete_type <
detected_t<value_type_t, ConstructibleArrayType >>::value >> (line 3314) | struct is_constructible_array_type_impl <
      type is_constructible_array_type (line 3343) | struct is_constructible_array_type
      type is_compatible_integer_type_impl (line 3348) | struct is_compatible_integer_type_impl : std::false_type {}
      type is_compatible_integer_type_impl <
    RealIntegerType, CompatibleNumberIntegerType,
    enable_if_t < std::is_integral<RealIntegerType>::value&&
    std::is_integral<CompatibleNumberIntegerType>::value&&
    !std::is_same<bool, CompatibleNumberIntegerType>::value >> (line 3351) | struct is_compatible_integer_type_impl <
      type is_compatible_integer_type (line 3369) | struct is_compatible_integer_type
      type is_compatible_type_impl (line 3374) | struct is_compatible_type_impl: std::false_type {}
      type is_compatible_type_impl <
    BasicJsonType, CompatibleType,
    enable_if_t<is_complete_type<CompatibleType>::value >> (line 3377) | struct is_compatible_type_impl <
      type is_compatible_type (line 3386) | struct is_compatible_type
      type conjunction (line 3390) | struct conjunction : std::true_type { }
      type conjunction<B1> (line 3391) | struct conjunction<B1> : B1 { }
      type is_constructible_tuple (line 3397) | struct is_constructible_tuple : std::false_type {}
      type value_t (line 3444) | enum class value_t : std::uint8_t
      function from_json (line 3493) | void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
      function get_arithmetic_value (line 3507) | void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
      function from_json (line 3533) | void from_json(const BasicJsonType& j, typename BasicJsonType::boole...
      function from_json (line 3543) | void from_json(const BasicJsonType& j, typename BasicJsonType::strin...
      function from_json (line 3559) | void from_json(const BasicJsonType& j, ConstructibleStringType& s)
      function from_json (line 3570) | void from_json(const BasicJsonType& j, typename BasicJsonType::numbe...
      function from_json (line 3576) | void from_json(const BasicJsonType& j, typename BasicJsonType::numbe...
      function from_json (line 3582) | void from_json(const BasicJsonType& j, typename BasicJsonType::numbe...
      function from_json (line 3589) | void from_json(const BasicJsonType& j, EnumType& e)
      function from_json (line 3599) | void from_json(const BasicJsonType& j, std::forward_list<T, Allocato...
      function from_json (line 3616) | void from_json(const BasicJsonType& j, std::valarray<T>& l)
      function from_json (line 3631) | auto from_json(const BasicJsonType& j, T (&arr)[N])
      function from_json_array_impl (line 3641) | void from_json_array_impl(const BasicJsonType& j, typename BasicJson...
      function from_json_array_impl (line 3647) | auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& ...
      function from_json_array_impl (line 3658) | auto from_json_array_impl(const BasicJsonType& j, ConstructibleArray...
      function from_json_array_impl (line 3679) | void from_json_array_impl(const BasicJsonType& j, ConstructibleArray...
      function from_json (line 3704) | auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
      function from_json (line 3719) | void from_json(const BasicJsonType& j, typename BasicJsonType::binar...
      function from_json (line 3731) | void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
      function from_json (line 3763) | void from_json(const BasicJsonType& j, ArithmeticType& val)
      function from_json (line 3794) | void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
      function from_json_tuple_impl (line 3800) | void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_se...
      function from_json (line 3806) | void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
      function from_json (line 3814) | void from_json(const BasicJsonType& j, std::map<Key, Value, Compare,...
      function from_json (line 3834) | void from_json(const BasicJsonType& j, std::unordered_map<Key, Value...
      type from_json_fn (line 3851) | struct from_json_fn
      function int_to_string (line 3902) | void int_to_string( string_type& target, std::size_t value )
      class iteration_proxy_value (line 3908) | class iteration_proxy_value
        method iteration_proxy_value (line 3931) | explicit iteration_proxy_value(IteratorType it) noexcept : anchor(...
        method iteration_proxy_value (line 3934) | iteration_proxy_value& operator*()
        method iteration_proxy_value (line 3940) | iteration_proxy_value& operator++()
        method string_type (line 3961) | const string_type& key() const
        method value (line 3989) | typename IteratorType::reference value() const
      class iteration_proxy (line 3996) | class iteration_proxy
        method iteration_proxy (line 4004) | explicit iteration_proxy(typename IteratorType::reference cont) no...
        method begin (line 4008) | iteration_proxy_value<IteratorType> begin() noexcept
        method end (line 4014) | iteration_proxy_value<IteratorType> end() noexcept
      function get (line 4023) | auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>...
      function get (line 4031) | auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>...
      type external_constructor (line 4081) | struct external_constructor
      type external_constructor<value_t::boolean> (line 4084) | struct external_constructor<value_t::boolean>
        method construct (line 4087) | static void construct(BasicJsonType& j, typename BasicJsonType::bo...
      type external_constructor<value_t::string> (line 4096) | struct external_constructor<value_t::string>
        method construct (line 4099) | static void construct(BasicJsonType& j, const typename BasicJsonTy...
        method construct (line 4107) | static void construct(BasicJsonType& j, typename BasicJsonType::st...
        method construct (line 4117) | static void construct(BasicJsonType& j, const CompatibleStringType...
      type external_constructor<value_t::binary> (line 4126) | struct external_constructor<value_t::binary>
        method construct (line 4129) | static void construct(BasicJsonType& j, const typename BasicJsonTy...
        method construct (line 4138) | static void construct(BasicJsonType& j, typename BasicJsonType::bi...
      type external_constructor<value_t::number_float> (line 4148) | struct external_constructor<value_t::number_float>
        method construct (line 4151) | static void construct(BasicJsonType& j, typename BasicJsonType::nu...
      type external_constructor<value_t::number_unsigned> (line 4160) | struct external_constructor<value_t::number_unsigned>
        method construct (line 4163) | static void construct(BasicJsonType& j, typename BasicJsonType::nu...
      type external_constructor<value_t::number_integer> (line 4172) | struct external_constructor<value_t::number_integer>
        method construct (line 4175) | static void construct(BasicJsonType& j, typename BasicJsonType::nu...
      type external_constructor<value_t::array> (line 4184) | struct external_constructor<value_t::array>
        method construct (line 4187) | static void construct(BasicJsonType& j, const typename BasicJsonTy...
        method construct (line 4195) | static void construct(BasicJsonType& j, typename BasicJsonType::ar...
        method construct (line 4205) | static void construct(BasicJsonType& j, const CompatibleArrayType&...
        method construct (line 4215) | static void construct(BasicJsonType& j, const std::vector<bool>& arr)
        method construct (line 4229) | static void construct(BasicJsonType& j, const std::valarray<T>& arr)
      type external_constructor<value_t::object> (line 4243) | struct external_constructor<value_t::object>
        method construct (line 4246) | static void construct(BasicJsonType& j, const typename BasicJsonTy...
        method construct (line 4254) | static void construct(BasicJsonType& j, typename BasicJsonType::ob...
        method construct (line 4263) | static void construct(BasicJsonType& j, const CompatibleObjectType...
      function to_json (line 4280) | void to_json(BasicJsonType& j, T b) noexcept
      function to_json (line 4287) | void to_json(BasicJsonType& j, const CompatibleString& s)
      function to_json (line 4293) | void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
      function to_json (line 4300) | void to_json(BasicJsonType& j, FloatType val) noexcept
      function to_json (line 4307) | void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noe...
      function to_json (line 4314) | void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noex...
      function to_json (line 4321) | void to_json(BasicJsonType& j, EnumType e) noexcept
      function to_json (line 4328) | void to_json(BasicJsonType& j, const std::vector<bool>& e)
      function to_json (line 4341) | void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
      function to_json (line 4347) | void to_json(BasicJsonType& j, const typename BasicJsonType::binary_...
      function to_json (line 4354) | void to_json(BasicJsonType& j, const std::valarray<T>& arr)
      function to_json (line 4360) | void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
      function to_json (line 4367) | void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
      function to_json (line 4373) | void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
      function to_json (line 4383) | void to_json(BasicJsonType& j, const T(&arr)[N])
      function to_json (line 4389) | void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
      function to_json (line 4397) | void to_json(BasicJsonType& j, const T& b)
      function to_json_tuple_impl (line 4403) | void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequ...
      function to_json (line 4409) | void to_json(BasicJsonType& j, const T& t)
      type to_json_fn (line 4414) | struct to_json_fn
      function combine (line 4662) | inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
      function hash (line 4680) | std::size_t hash(const BasicJsonType& j)
      type input_format_t (line 4812) | enum class input_format_t { json, cbor, msgpack, ubjson, bson }
      class file_input_adapter (line 4822) | class file_input_adapter
        method file_input_adapter (line 4828) | explicit file_input_adapter(std::FILE* f) noexcept
        method file_input_adapter (line 4833) | file_input_adapter(const file_input_adapter&) = delete;
        method file_input_adapter (line 4834) | file_input_adapter(file_input_adapter&&) = default;
        method file_input_adapter (line 4835) | file_input_adapter& operator=(const file_input_adapter&) = delete;
        method file_input_adapter (line 4836) | file_input_adapter& operator=(file_input_adapter&&) = delete;
        method get_character (line 4838) | std::char_traits<char>::int_type get_character() noexcept
      class input_stream_adapter (line 4858) | class input_stream_adapter
        method input_stream_adapter (line 4873) | explicit input_stream_adapter(std::istream& i)
        method input_stream_adapter (line 4878) | input_stream_adapter(const input_stream_adapter&) = delete;
        method input_stream_adapter (line 4879) | input_stream_adapter& operator=(input_stream_adapter&) = delete;
        method input_stream_adapter (line 4880) | input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
        method input_stream_adapter (line 4882) | input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs...
        method get_character (line 4891) | std::char_traits<char>::int_type get_character()
      class iterator_input_adapter (line 4911) | class iterator_input_adapter
        method iterator_input_adapter (line 4916) | iterator_input_adapter(IteratorType first, IteratorType last)
        method get_character (line 4919) | typename std::char_traits<char_type>::int_type get_character()
        method empty (line 4940) | bool empty() const
      type wide_string_input_helper (line 4949) | struct wide_string_input_helper
      type wide_string_input_helper<BaseInputAdapter, 4> (line 4952) | struct wide_string_input_helper<BaseInputAdapter, 4>
        method fill_buffer (line 4955) | static void fill_buffer(BaseInputAdapter& input,
      type wide_string_input_helper<BaseInputAdapter, 2> (line 5010) | struct wide_string_input_helper<BaseInputAdapter, 2>
        method fill_buffer (line 5013) | static void fill_buffer(BaseInputAdapter& input,
      class wide_string_input_adapter (line 5073) | class wide_string_input_adapter
        method wide_string_input_adapter (line 5078) | wide_string_input_adapter(BaseInputAdapter base)
        method get_character (line 5081) | typename std::char_traits<char>::int_type get_character() noexcept
        method fill_buffer (line 5102) | void fill_buffer()
      type iterator_input_adapter_factory (line 5118) | struct iterator_input_adapter_factory
        method adapter_type (line 5124) | static adapter_type create(IteratorType first, IteratorType last)
      type is_iterator_of_multibyte (line 5131) | struct is_iterator_of_multibyte
      type iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>> (line 5141) | struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_i...
        method adapter_type (line 5148) | static adapter_type create(IteratorType first, IteratorType last)
      function input_adapter (line 5156) | typename iterator_input_adapter_factory<IteratorType>::adapter_type ...
      function input_adapter (line 5164) | auto input_adapter(const ContainerType& container) -> decltype(input...
      function file_input_adapter (line 5174) | inline file_input_adapter input_adapter(std::FILE* file)
        method file_input_adapter (line 4828) | explicit file_input_adapter(std::FILE* f) noexcept
        method file_input_adapter (line 4833) | file_input_adapter(const file_input_adapter&) = delete;
        method file_input_adapter (line 4834) | file_input_adapter(file_input_adapter&&) = default;
        method file_input_adapter (line 4835) | file_input_adapter& operator=(const file_input_adapter&) = delete;
        method file_input_adapter (line 4836) | file_input_adapter& operator=(file_input_adapter&&) = delete;
        method get_character (line 4838) | std::char_traits<char>::int_type get_character() noexcept
      function input_stream_adapter (line 5179) | inline input_stream_adapter input_adapter(std::istream& stream)
        method input_stream_adapter (line 4873) | explicit input_stream_adapter(std::istream& i)
        method input_stream_adapter (line 4878) | input_stream_adapter(const input_stream_adapter&) = delete;
        method input_stream_adapter (line 4879) | input_stream_adapter& operator=(input_stream_adapter&) = delete;
        method input_stream_adapter (line 4880) | input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
        method input_stream_adapter (line 4882) | input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs...
        method get_character (line 4891) | std::char_traits<char>::int_type get_character()
      function input_stream_adapter (line 5184) | inline input_stream_adapter input_adapter(std::istream&& stream)
        method input_stream_adapter (line 4873) | explicit input_stream_adapter(std::istream& i)
        method input_stream_adapter (line 4878) | input_stream_adapter(const input_stream_adapter&) = delete;
        method input_stream_adapter (line 4879) | input_stream_adapter& operator=(input_stream_adapter&) = delete;
        method input_stream_adapter (line 4880) | input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
        method input_stream_adapter (line 4882) | input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs...
        method get_character (line 4891) | std::char_traits<char>::int_type get_character()
      function contiguous_bytes_input_adapter (line 5199) | contiguous_bytes_input_adapter input_adapter(CharT b)
      function input_adapter (line 5207) | auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, a...
      class span_input_adapter (line 5215) | class span_input_adapter
        method span_input_adapter (line 5224) | span_input_adapter(CharT b, std::size_t l)
        method span_input_adapter (line 5231) | span_input_adapter(IteratorType first, IteratorType last)
        method contiguous_bytes_input_adapter (line 5234) | contiguous_bytes_input_adapter&& get()
      class json_sax_dom_parser (line 5396) | class json_sax_dom_parser
        method json_sax_dom_parser (line 5410) | explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_ex...
        method json_sax_dom_parser (line 5415) | json_sax_dom_parser(const json_sax_dom_parser&) = delete;
        method json_sax_dom_parser (line 5416) | json_sax_dom_parser(json_sax_dom_parser&&) = default;
        method json_sax_dom_parser (line 5417) | json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
        method json_sax_dom_parser (line 5418) | json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
        method null (line 5421) | bool null()
        method boolean (line 5427) | bool boolean(bool val)
        method number_integer (line 5433) | bool number_integer(number_integer_t val)
        method number_unsigned (line 5439) | bool number_unsigned(number_unsigned_t val)
        method number_float (line 5445) | bool number_float(number_float_t val, const string_t& /*unused*/)
        method string (line 5451) | bool string(string_t& val)
        method binary (line 5457) | bool binary(binary_t& val)
        method start_object (line 5463) | bool start_object(std::size_t len)
        method key (line 5476) | bool key(string_t& val)
        method end_object (line 5483) | bool end_object()
        method start_array (line 5489) | bool start_array(std::size_t len)
        method end_array (line 5502) | bool end_array()
        method parse_error (line 5509) | bool parse_error(std::size_t /*unused*/, const std::string& /*unus...
        method is_errored (line 5521) | constexpr bool is_errored() const
        method JSON_HEDLEY_RETURNS_NON_NULL (line 5534) | JSON_HEDLEY_RETURNS_NON_NULL
      class json_sax_dom_callback_parser (line 5570) | class json_sax_dom_callback_parser
        method json_sax_dom_callback_parser (line 5581) | json_sax_dom_callback_parser(BasicJsonType& r,
        method json_sax_dom_callback_parser (line 5590) | json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) ...
        method json_sax_dom_callback_parser (line 5591) | json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = def...
        method json_sax_dom_callback_parser (line 5592) | json_sax_dom_callback_parser& operator=(const json_sax_dom_callbac...
        method json_sax_dom_callback_parser (line 5593) | json_sax_dom_callback_parser& operator=(json_sax_dom_callback_pars...
        method null (line 5596) | bool null()
        method boolean (line 5602) | bool boolean(bool val)
        method number_integer (line 5608) | bool number_integer(number_integer_t val)
        method number_unsigned (line 5614) | bool number_unsigned(number_unsigned_t val)
        method number_float (line 5620) | bool number_float(number_float_t val, const string_t& /*unused*/)
        method string (line 5626) | bool string(string_t& val)
        method binary (line 5632) | bool binary(binary_t& val)
        method start_object (line 5638) | bool start_object(std::size_t len)
        method key (line 5656) | bool key(string_t& val)
        method end_object (line 5673) | bool end_object()
        method start_array (line 5702) | bool start_array(std::size_t len)
        method end_array (line 5719) | bool end_array()
        method parse_error (line 5748) | bool parse_error(std::size_t /*unused*/, const std::string& /*unus...
        method is_errored (line 5760) | constexpr bool is_errored() const
        method handle_value (line 5782) | std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool...
      class json_sax_acceptor (line 5866) | class json_sax_acceptor
        method null (line 5875) | bool null()
        method boolean (line 5880) | bool boolean(bool /*unused*/)
        method number_integer (line 5885) | bool number_integer(number_integer_t /*unused*/)
        method number_unsigned (line 5890) | bool number_unsigned(number_unsigned_t /*unused*/)
        method number_float (line 5895) | bool number_float(number_float_t /*unused*/, const string_t& /*unu...
        method string (line 5900) | bool string(string_t& /*unused*/)
        method binary (line 5905) | bool binary(binary_t& /*unused*/)
        method start_object (line 5910) | bool start_object(std::size_t /*unused*/ = std::size_t(-1))
        method key (line 5915) | bool key(string_t& /*unused*/)
        method end_object (line 5920) | bool end_object()
        method start_array (line 5925) | bool start_array(std::size_t /*unused*/ = std::size_t(-1))
        method end_array (line 5930) | bool end_array()
        method parse_error (line 5935) | bool parse_error(std::size_t /*unused*/, const std::string& /*unus...
      class lexer_base (line 5973) | class lexer_base
        type token_type (line 5977) | enum class token_type
      class lexer (line 6050) | class lexer : public lexer_base<BasicJsonType>
        method lexer (line 6062) | explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ =...
        method lexer (line 6069) | lexer(const lexer&) = delete;
        method lexer (line 6070) | lexer(lexer&&) = default;
        method lexer (line 6071) | lexer& operator=(lexer&) = delete;
        method lexer (line 6072) | lexer& operator=(lexer&&) = default;
        method JSON_HEDLEY_PURE (line 6081) | JSON_HEDLEY_PURE
        method get_codepoint (line 6108) | int get_codepoint()
        method next_byte_in_range (line 6156) | bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
        method token_type (line 6193) | token_type scan_string()
        method scan_comment (line 6783) | bool scan_comment()
        method strtof (line 6851) | static void strtof(float& f, const char* str, char** endptr) noexcept
        method strtof (line 6857) | static void strtof(double& f, const char* str, char** endptr) noex...
        method strtof (line 6863) | static void strtof(long double& f, const char* str, char** endptr)...
        method token_type (line 6908) | token_type scan_number()  // lgtm [cpp/use-of-goto]
      type is_sax (line 7641) | struct is_sax
      type is_sax_static_asserts (line 7672) | struct is_sax_static_asserts
      type cbor_tag_handler_t (line 7736) | enum class cbor_tag_handler_t
      function little_endianess (line 7749) | static inline bool little_endianess(int num = 1) noexcept
      class binary_reader (line 7763) | class binary_reader
        method binary_reader (line 7780) | explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(...
        method binary_reader (line 7786) | binary_reader(const binary_reader&) = delete;
        method binary_reader (line 7787) | binary_reader(binary_reader&&) = default;
        method binary_reader (line 7788) | binary_reader& operator=(const binary_reader&) = delete;
        method binary_reader (line 7789) | binary_reader& operator=(binary_reader&&) = default;
        method JSON_HEDLEY_NON_NULL (line 7800) | JSON_HEDLEY_NON_NULL(3)
        method parse_bson_internal (line 7862) | bool parse_bson_internal()
        method get_bson_cstr (line 7887) | bool get_bson_cstr(string_t& result)
        method get_bson_string (line 7917) | bool get_bson_string(const NumberType len, string_t& result)
        method get_bson_binary (line 7938) | bool get_bson_binary(const NumberType len, binary_t& result)
        method parse_bson_element_internal (line 7964) | bool parse_bson_element_internal(const char_int_type element_type,
        method parse_bson_element_list (line 8042) | bool parse_bson_element_list(const bool is_array)
        method parse_bson_array (line 8080) | bool parse_bson_array()
        method parse_cbor_internal (line 8110) | bool parse_cbor_internal(const bool get_char,
        method get_cbor_string (line 8556) | bool get_cbor_string(string_t& result)
        method get_cbor_binary (line 8651) | bool get_cbor_binary(binary_t& result)
        method get_cbor_array (line 8745) | bool get_cbor_array(const std::size_t len,
        method get_cbor_object (line 8783) | bool get_cbor_object(const std::size_t len,
        method parse_msgpack_internal (line 8836) | bool parse_msgpack_internal()
        method get_msgpack_string (line 9216) | bool get_msgpack_string(string_t& result)
        method get_msgpack_binary (line 9298) | bool get_msgpack_binary(binary_t& result)
        method get_msgpack_array (line 9409) | bool get_msgpack_array(const std::size_t len)
        method get_msgpack_object (line 9431) | bool get_msgpack_object(const std::size_t len)
        method parse_ubjson_internal (line 9468) | bool parse_ubjson_internal(const bool get_char = true)
        method get_ubjson_string (line 9487) | bool get_ubjson_string(string_t& result, const bool get_char = true)
        method get_ubjson_size_value (line 9541) | bool get_ubjson_size_value(std::size_t& result)
        method get_ubjson_size_type (line 9618) | bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& r...
        method get_ubjson_value (line 9659) | bool get_ubjson_value(const char_int_type prefix)
        method get_ubjson_array (line 9760) | bool get_ubjson_array()
        method get_ubjson_object (line 9822) | bool get_ubjson_object()
        method get_ubjson_high_precision_number (line 9897) | bool get_ubjson_high_precision_number()
        method char_int_type (line 9959) | char_int_type get()
        method char_int_type (line 9968) | char_int_type get_ignore_noop()
        method get_number (line 9993) | bool get_number(const input_format_t format, NumberType& result)
        method get_string (line 10036) | bool get_string(const input_format_t format,
        method get_binary (line 10069) | bool get_binary(const input_format_t format,
        method JSON_HEDLEY_NON_NULL (line 10092) | JSON_HEDLEY_NON_NULL(3)
        method get_token_string (line 10106) | std::string get_token_string() const
        method exception_message (line 10119) | std::string exception_message(const input_format_t format,
      type parse_event_t (line 10206) | enum class parse_event_t : uint8_t
      class parser (line 10232) | class parser
        method parser (line 10243) | explicit parser(InputAdapterType&& adapter,
        method parse (line 10265) | void parse(const bool strict, BasicJsonType& result)
        method accept (line 10326) | bool accept(const bool strict = true)
        method sax_parse (line 10334) | bool sax_parse(SAX* sax, const bool strict = true)
        method sax_parse_internal (line 10354) | bool sax_parse_internal(SAX* sax)
        method token_type (line 10636) | token_type get_token()
        method exception_message (line 10641) | std::string exception_message(const token_type expected, const std...
      class primitive_iterator_t (line 10705) | class primitive_iterator_t
        method difference_type (line 10717) | constexpr difference_type get_value() const noexcept
        method set_begin (line 10723) | void set_begin() noexcept
        method set_end (line 10729) | void set_end() noexcept
        method is_begin (line 10735) | constexpr bool is_begin() const noexcept
        method is_end (line 10741) | constexpr bool is_end() const noexcept
        method primitive_iterator_t (line 10756) | primitive_iterator_t operator+(difference_type n) noexcept
        method difference_type (line 10763) | constexpr difference_type operator-(primitive_iterator_t lhs, prim...
        method primitive_iterator_t (line 10768) | primitive_iterator_t& operator++() noexcept
        method primitive_iterator_t (line 10774) | primitive_iterator_t const operator++(int) noexcept
        method primitive_iterator_t (line 10781) | primitive_iterator_t& operator--() noexcept
        method primitive_iterator_t (line 10787) | primitive_iterator_t const operator--(int) noexcept
        method primitive_iterator_t (line 10794) | primitive_iterator_t& operator+=(difference_type n) noexcept
        method primitive_iterator_t (line 10800) | primitive_iterator_t& operator-=(difference_type n) noexcept
      type internal_iterator (line 10820) | struct internal_iterator
      class iteration_proxy (line 10858) | class iteration_proxy
        method iteration_proxy (line 4004) | explicit iteration_proxy(typename IteratorType::reference cont) no...
        method begin (line 4008) | iteration_proxy_value<IteratorType> begin() noexcept
        method end (line 4014) | iteration_proxy_value<IteratorType> end() noexcept
      class iteration_proxy_value (line 10859) | class iteration_proxy_value
        method iteration_proxy_value (line 3931) | explicit iteration_proxy_value(IteratorType it) noexcept : anchor(...
        method iteration_proxy_value (line 3934) | iteration_proxy_value& operator*()
        method iteration_proxy_value (line 3940) | iteration_proxy_value& operator++()
        method string_type (line 3961) | const string_type& key() const
        method value (line 3989) | typename IteratorType::reference value() const
      function set_end (line 10878) | class iter_impl
      class json_reverse_iterator (line 11514) | class json_reverse_iterator : public std::reverse_iterator<Base>
        method json_reverse_iterator (line 11524) | explicit json_reverse_iterator(const typename base_iterator::itera...
        method json_reverse_iterator (line 11528) | explicit json_reverse_iterator(const base_iterator& it) noexcept :...
        method json_reverse_iterator (line 11531) | json_reverse_iterator const operator++(int)
        method json_reverse_iterator (line 11537) | json_reverse_iterator& operator++()
        method json_reverse_iterator (line 11543) | json_reverse_iterator const operator--(int)
        method json_reverse_iterator (line 11549) | json_reverse_iterator& operator--()
        method json_reverse_iterator (line 11555) | json_reverse_iterator& operator+=(difference_type i)
        method json_reverse_iterator (line 11561) | json_reverse_iterator operator+(difference_type i) const
        method json_reverse_iterator (line 11567) | json_reverse_iterator operator-(difference_type i) const
        method difference_type (line 11573) | difference_type operator-(const json_reverse_iterator& other) const
        method reference (line 11579) | reference operator[](difference_type n) const
        method key (line 11585) | auto key() const -> decltype(std::declval<Base>().key())
        method reference (line 11592) | reference value() const
      class json_ref (line 12601) | class json_ref
        method json_ref (line 12606) | json_ref(value_type&& value)
        method json_ref (line 12612) | json_ref(const value_type& value)
        method json_ref (line 12617) | json_ref(std::initializer_list<json_ref> init)
        method json_ref (line 12626) | json_ref(Args && ... args)
        method json_ref (line 12633) | json_ref(json_ref&&) = default;
        method json_ref (line 12634) | json_ref(const json_ref&) = delete;
        method json_ref (line 12635) | json_ref& operator=(const json_ref&) = delete;
        method json_ref (line 12636) | json_ref& operator=(json_ref&&) = delete;
        method value_type (line 12639) | value_type moved_or_copied() const
        method value_type (line 12648) | value_type const& operator*() const
        method value_type (line 12653) | value_type const* operator->() const
      type output_adapter_protocol (line 12706) | struct output_adapter_protocol
      class output_vector_adapter (line 12719) | class output_vector_adapter : public output_adapter_protocol<CharType>
        method output_vector_adapter (line 12722) | explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
        method write_character (line 12726) | void write_character(CharType c) override
        method JSON_HEDLEY_NON_NULL (line 12731) | JSON_HEDLEY_NON_NULL(2)
      class output_stream_adapter (line 12743) | class output_stream_adapter : public output_adapter_protocol<CharType>
        method output_stream_adapter (line 12746) | explicit output_stream_adapter(std::basic_ostream<CharType>& s) no...
        method write_character (line 12750) | void write_character(CharType c) override
        method JSON_HEDLEY_NON_NULL (line 12755) | JSON_HEDLEY_NON_NULL(2)
      class output_string_adapter (line 12767) | class output_string_adapter : public output_adapter_protocol<CharType>
        method output_string_adapter (line 12770) | explicit output_string_adapter(StringType& s) noexcept
        method write_character (line 12774) | void write_character(CharType c) override
        method JSON_HEDLEY_NON_NULL (line 12779) | JSON_HEDLEY_NON_NULL(2)
      class output_adapter (line 12790) | class output_adapter
        method output_adapter (line 12793) | output_adapter(std::vector<CharType>& vec)
        method output_adapter (line 12796) | output_adapter(std::basic_ostream<CharType>& s)
        method output_adapter (line 12799) | output_adapter(StringType& s)
      class binary_writer (line 12826) | class binary_writer
        method binary_writer (line 12838) | explicit binary_writer(output_adapter_t<CharType> adapter) : oa(ad...
        method write_bson (line 12847) | void write_bson(const BasicJsonType& j)
        method write_cbor (line 12867) | void write_cbor(const BasicJsonType& j)
        method write_msgpack (line 13172) | void write_msgpack(const BasicJsonType& j)
        method write_ubjson (line 13496) | void write_ubjson(const BasicJsonType& j, const bool use_count,
        method calc_bson_entry_header_size (line 13703) | static std::size_t calc_bson_entry_header_size(const string_t& name)
        method write_bson_entry_header (line 13718) | void write_bson_entry_header(const string_t& name,
        method write_bson_boolean (line 13730) | void write_bson_boolean(const string_t& name,
        method write_bson_double (line 13740) | void write_bson_double(const string_t& name,
        method calc_bson_string_size (line 13750) | static std::size_t calc_bson_string_size(const string_t& value)
        method write_bson_string (line 13758) | void write_bson_string(const string_t& name,
        method write_bson_null (line 13772) | void write_bson_null(const string_t& name)
        method calc_bson_integer_size (line 13780) | static std::size_t calc_bson_integer_size(const std::int64_t value)
        method write_bson_integer (line 13790) | void write_bson_integer(const string_t& name,
        method calc_bson_unsigned_size (line 13808) | static constexpr std::size_t calc_bson_unsigned_size(const std::ui...
        method write_bson_unsigned (line 13818) | void write_bson_unsigned(const string_t& name,
        method write_bson_object_entry (line 13840) | void write_bson_object_entry(const string_t& name,
        method calc_bson_array_size (line 13850) | static std::size_t calc_bson_array_size(const typename BasicJsonTy...
        method calc_bson_binary_size (line 13865) | static std::size_t calc_bson_binary_size(const typename BasicJsonT...
        method write_bson_array (line 13873) | void write_bson_array(const string_t& name,
        method write_bson_binary (line 13892) | void write_bson_binary(const string_t& name,
        method calc_bson_element_size (line 13907) | static std::size_t calc_bson_element_size(const string_t& name,
        method write_bson_element (line 13955) | void write_bson_element(const string_t& name,
        method calc_bson_object_size (line 14001) | static std::size_t calc_bson_object_size(const typename BasicJsonT...
        method write_bson_object (line 14016) | void write_bson_object(const typename BasicJsonType::object_t& value)
        method CharType (line 14032) | static constexpr CharType get_cbor_float_prefix(float /*unused*/)
        method CharType (line 14037) | static constexpr CharType get_cbor_float_prefix(double /*unused*/)
        method CharType (line 14046) | static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
        method CharType (line 14051) | static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
        method write_number_with_ubjson_prefix (line 14063) | void write_number_with_ubjson_prefix(const NumberType n,
        method write_number_with_ubjson_prefix (line 14076) | void write_number_with_ubjson_prefix(const NumberType n,
        method write_number_with_ubjson_prefix (line 14139) | void write_number_with_ubjson_prefix(const NumberType n,
        method CharType (line 14203) | CharType ubjson_prefix(const BasicJsonType& j) const noexcept
        method CharType (line 14283) | static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
        method CharType (line 14288) | static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
        method write_number (line 14309) | void write_number(const NumberType n)
        method write_compact_float (line 14325) | void write_compact_float(const number_float_t n, detail::input_for...
        method CharType (line 14352) | static constexpr CharType to_char_type(std::uint8_t x) noexcept
        method CharType (line 14359) | static CharType to_char_type(std::uint8_t x) noexcept
        method CharType (line 14370) | static constexpr CharType to_char_type(std::uint8_t x) noexcept
        method CharType (line 14381) | static constexpr CharType to_char_type(InputCharType x) noexcept
      type dtoa_impl (line 14450) | namespace dtoa_impl
        function Target (line 14454) | Target reinterpret_bits(const Source source)
        type diyfp (line 14463) | struct diyfp // f * 2^e
          method diyfp (line 14470) | constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_...
          method diyfp (line 14476) | static diyfp sub(const diyfp& x, const diyfp& y) noexcept
          method diyfp (line 14488) | static diyfp mul(const diyfp& x, const diyfp& y) noexcept
          method diyfp (line 14553) | static diyfp normalize(diyfp x) noexcept
          method diyfp (line 14570) | static diyfp normalize_to(const diyfp& x, const int target_expon...
        type boundaries (line 14581) | struct boundaries
        function boundaries (line 14595) | boundaries compute_boundaries(FloatType value)
        type cached_power (line 14720) | struct cached_power // c = f * 2^e ~= 10^k
        function cached_power (line 14734) | inline cached_power get_cached_power_for_binary_exponent(int e)
        function find_largest_pow10 (line 14898) | inline int find_largest_pow10(const std::uint32_t n, std::uint32_t...
        function grisu2_round (line 14954) | inline void grisu2_round(char* buf, int len, std::uint64_t dist, s...
        function grisu2_digit_gen (line 14995) | inline void grisu2_digit_gen(char* buffer, int& length, int& decim...
        function grisu2 (line 15236) | inline void grisu2(char* buf, int& len, int& decimal_exponent,
        function JSON_HEDLEY_NON_NULL (line 15295) | JSON_HEDLEY_NON_NULL(1)
      type error_handler_t (line 15543) | enum class error_handler_t
      class serializer (line 15551) | class serializer
        method serializer (line 15567) | serializer(output_adapter_t<char> s, const char ichar,
        method serializer (line 15579) | serializer(const serializer&) = delete;
        method serializer (line 15580) | serializer& operator=(const serializer&) = delete;
        method serializer (line 15581) | serializer(serializer&&) = delete;
        method serializer (line 15582) | serializer& operator=(serializer&&) = delete;
        method dump (line 15607) | void dump(const BasicJsonType& val,
        method switch (line 15905) | switch (decode(state, codepoint, byte))
    type detail (line 2742) | namespace detail
      type position_t (line 86) | struct position_t
      class exception (line 2419) | class exception : public std::exception
        method JSON_HEDLEY_RETURNS_NON_NULL (line 2423) | JSON_HEDLEY_RETURNS_NON_NULL
        method JSON_HEDLEY_NON_NULL (line 2433) | JSON_HEDLEY_NON_NULL(3)
        method name (line 2436) | static std::string name(const std::string& ename, int id_)
      class parse_error (line 2491) | class parse_error : public exception
        method parse_error (line 2503) | static parse_error create(int id_, const position_t& pos, const st...
        method parse_error (line 2510) | static parse_error create(int id_, std::size_t byte_, const std::s...
        method parse_error (line 2530) | parse_error(int id_, std::size_t byte_, const char* what_arg)
        method position_string (line 2533) | static std::string position_string(const position_t& pos)
      class invalid_iterator (line 2577) | class invalid_iterator : public exception
        method invalid_iterator (line 2580) | static invalid_iterator create(int id_, const std::string& what_arg)
        method JSON_HEDLEY_NON_NULL (line 2587) | JSON_HEDLEY_NON_NULL(3)
      class type_error (line 2631) | class type_error : public exception
        method type_error (line 2634) | static type_error create(int id_, const std::string& what_arg)
        method JSON_HEDLEY_NON_NULL (line 2641) | JSON_HEDLEY_NON_NULL(3)
      class out_of_range (line 2678) | class out_of_range : public exception
        method out_of_range (line 2681) | static out_of_range create(int id_, const std::string& what_arg)
        method JSON_HEDLEY_NON_NULL (line 2688) | JSON_HEDLEY_NON_NULL(3)
      class other_error (line 2716) | class other_error : public exception
        method other_error (line 2719) | static other_error create(int id_, const std::string& what_arg)
        method JSON_HEDLEY_NON_NULL (line 2726) | JSON_HEDLEY_NON_NULL(3)
      type index_sequence (line 2754) | struct index_sequence
        method size (line 2758) | static constexpr std::size_t size() noexcept
      type merge_and_renumber (line 2765) | struct merge_and_renumber
      type make_index_sequence (line 2772) | struct make_index_sequence
      type make_index_sequence<0> (line 2776) | struct make_index_sequence<0> : index_sequence<> {}
      type make_index_sequence<1> (line 2777) | struct make_index_sequence<1> : index_sequence<0> {}
      type priority_tag (line 2783) | struct priority_tag : priority_tag < N - 1 > {}
      type priority_tag<0> (line 2784) | struct priority_tag<0> {}
      type static_const (line 2788) | struct static_const
      type make_void (line 2817) | struct make_void
      type iterator_types (line 2833) | struct iterator_types {}
      type iterator_types <
    It,
    void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
    typename It::reference, typename It::iterator_category >> (line 2836) | struct iterator_types <
      type iterator_traits (line 2851) | struct iterator_traits
      type iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >> (line 2856) | struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
      type iterator_traits<T*, enable_if_t<std::is_object<T>::value>> (line 2862) | struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
      type nonesuch (line 2890) | struct nonesuch
        method nonesuch (line 2892) | nonesuch() = delete;
        method nonesuch (line 2894) | nonesuch(nonesuch const&) = delete;
        method nonesuch (line 2895) | nonesuch(nonesuch const&&) = delete;
      type detector (line 2904) | struct detector
      type is_basic_json (line 3044) | struct is_basic_json : std::false_type {}
      class json_ref (line 3054) | class json_ref
        method json_ref (line 12606) | json_ref(value_type&& value)
        method json_ref (line 12612) | json_ref(const value_type& value)
        method json_ref (line 12617) | json_ref(std::initializer_list<json_ref> init)
        method json_ref (line 12626) | json_ref(Args && ... args)
        method json_ref (line 12633) | json_ref(json_ref&&) = default;
        method json_ref (line 12634) | json_ref(const json_ref&) = delete;
        method json_ref (line 12635) | json_ref& operator=(const json_ref&) = delete;
        method json_ref (line 12636) | json_ref& operator=(json_ref&&) = delete;
        method value_type (line 12639) | value_type moved_or_copied() const
        method value_type (line 12648) | value_type const& operator*() const
        method value_type (line 12653) | value_type const* operator->() const
      type is_json_ref (line 3057) | struct is_json_ref : std::false_type {}
      type is_json_ref<json_ref<T>> (line 3060) | struct is_json_ref<json_ref<T>> : std::true_type {}
      type has_from_json (line 3101) | struct has_from_json : std::false_type {}
      type is_getable (line 3108) | struct is_getable
      type has_from_json < BasicJsonType, T,
           enable_if_t < !is_basic_json<T>::value >> (line 3114) | struct has_from_json < BasicJsonType, T,
      type has_non_default_from_json (line 3127) | struct has_non_default_from_json : std::false_type {}
      type has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >> (line 3130) | struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !...
      type has_to_json (line 3142) | struct has_to_json : std::false_type {}
      type has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >> (line 3145) | struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<...
      type is_iterator_traits (line 3160) | struct is_iterator_traits : std::false_type {}
      type is_iterator_traits<iterator_traits<T>> (line 3163) | struct is_iterator_traits<iterator_traits<T>>
      type is_complete_type (line 3180) | struct is_complete_type : std::false_type {}
      type is_complete_type<T, decltype(void(sizeof(T)))> (line 3183) | struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_ty...
      type is_compatible_object_type_impl (line 3187) | struct is_compatible_object_type_impl : std::false_type {}
      type is_compatible_object_type_impl <
    BasicJsonType, CompatibleObjectType,
    enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
    is_detected<key_type_t, CompatibleObjectType>::value >> (line 3190) | struct is_compatible_object_type_impl <
      type is_compatible_object_type (line 3207) | struct is_compatible_object_type
      type is_constructible_object_type_impl (line 3212) | struct is_constructible_object_type_impl : std::false_type {}
      type is_constructible_object_type_impl <
    BasicJsonType, ConstructibleObjectType,
    enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
    is_detected<key_type_t, ConstructibleObjectType>::value >> (line 3215) | struct is_constructible_object_type_impl <
      type is_constructible_object_type (line 3239) | struct is_constructible_object_type
      type is_compatible_string_type_impl (line 3245) | struct is_compatible_string_type_impl : std::false_type {}
      type is_compatible_string_type_impl <
    BasicJsonType, CompatibleStringType,
    enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
    value_type_t, CompatibleStringType>::value >> (line 3248) | struct is_compatible_string_type_impl <
      type is_compatible_string_type (line 3258) | struct is_compatible_string_type
      type is_constructible_string_type_impl (line 3263) | struct is_constructible_string_type_impl : std::false_type {}
      type is_constructible_string_type_impl <
    BasicJsonType, ConstructibleStringType,
    enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
    value_type_t, ConstructibleStringType>::value >> (line 3266) | struct is_constructible_string_type_impl <
      type is_constructible_string_type (line 3277) | struct is_constructible_string_type
      type is_compatible_array_type_impl (line 3281) | struct is_compatible_array_type_impl : std::false_type {}
      type is_compatible_array_type (line 3300) | struct is_compatible_array_type
      type is_constructible_array_type_impl (line 3304) | struct is_constructible_array_type_impl : std::false_type {}
      type is_constructible_array_type_impl <
    BasicJsonType, ConstructibleArrayType,
    enable_if_t<std::is_same<ConstructibleArrayType,
    typename BasicJsonType::value_type>::value >> (line 3307) | struct is_constructible_array_type_impl <
      type is_constructible_array_type_impl <
    BasicJsonType, ConstructibleArrayType,
    enable_if_t < !std::is_same<ConstructibleArrayType,
    typename BasicJsonType::value_type>::value&&
    std::is_default_constructible<ConstructibleArrayType>::value&&
(std::is_move_assignable<ConstructibleArrayType>::value ||
 std::is_copy_assignable<ConstructibleArrayType>::value)&&
is_detected<value_type_t, ConstructibleArrayType>::value&&
is_detected<iterator_t, ConstructibleArrayType>::value&&
is_complete_type <
detected_t<value_type_t, ConstructibleArrayType >>::value >> (line 3314) | struct is_constructible_array_type_impl <
      type is_constructible_array_type (line 3343) | struct is_constructible_array_type
      type is_compatible_integer_type_impl (line 3348) | struct is_compatible_integer_type_impl : std::false_type {}
      type is_compatible_integer_type_impl <
    RealIntegerType, CompatibleNumberIntegerType,
    enable_if_t < std::is_integral<RealIntegerType>::value&&
    std::is_integral<CompatibleNumberIntegerType>::value&&
    !std::is_same<bool, CompatibleNumberIntegerType>::value >> (line 3351) | struct is_compatible_integer_type_impl <
      type is_compatible_integer_type (line 3369) | struct is_compatible_integer_type
      type is_compatible_type_impl (line 3374) | struct is_compatible_type_impl: std::false_type {}
      type is_compatible_type_impl <
    BasicJsonType, CompatibleType,
    enable_if_t<is_complete_type<CompatibleType>::value >> (line 3377) | struct is_compatible_type_impl <
      type is_compatible_type (line 3386) | struct is_compatible_type
      type conjunction (line 3390) | struct conjunction : std::true_type { }
      type conjunction<B1> (line 3391) | struct conjunction<B1> : B1 { }
      type is_constructible_tuple (line 3397) | struct is_constructible_tuple : std::false_type {}
      type value_t (line 3444) | enum class value_t : std::uint8_t
      function from_json (line 3493) | void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
      function get_arithmetic_value (line 3507) | void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
      function from_json (line 3533) | void from_json(const BasicJsonType& j, typename BasicJsonType::boole...
      function from_json (line 3543) | void from_json(const BasicJsonType& j, typename BasicJsonType::strin...
      function from_json (line 3559) | void from_json(const BasicJsonType& j, ConstructibleStringType& s)
      function from_json (line 3570) | void from_json(const BasicJsonType& j, typename BasicJsonType::numbe...
      function from_json (line 3576) | void from_json(const BasicJsonType& j, typename BasicJsonType::numbe...
      function from_json (line 3582) | void from_json(const BasicJsonType& j, typename BasicJsonType::numbe...
      function from_json (line 3589) | void from_json(const BasicJsonType& j, EnumType& e)
      function from_json (line 3599) | void from_json(const BasicJsonType& j, std::forward_list<T, Allocato...
      function from_json (line 3616) | void from_json(const BasicJsonType& j, std::valarray<T>& l)
      function from_json (line 3631) | auto from_json(const BasicJsonType& j, T (&arr)[N])
      function from_json_array_impl (line 3641) | void from_json_array_impl(const BasicJsonType& j, typename BasicJson...
      function from_json_array_impl (line 3647) | auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& ...
      function from_json_array_impl (line 3658) | auto from_json_array_impl(const BasicJsonType& j, ConstructibleArray...
      function from_json_array_impl (line 3679) | void from_json_array_impl(const BasicJsonType& j, ConstructibleArray...
      function from_json (line 3704) | auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
      function from_json (line 3719) | void from_json(const BasicJsonType& j, typename BasicJsonType::binar...
      function from_json (line 3731) | void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
      function from_json (line 3763) | void from_json(const BasicJsonType& j, ArithmeticType& val)
      function from_json (line 3794) | void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
      function from_json_tuple_impl (line 3800) | void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_se...
      function from_json (line 3806) | void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
      function from_json (line 3814) | void from_json(const BasicJsonType& j, std::map<Key, Value, Compare,...
      function from_json (line 3834) | void from_json(const BasicJsonType& j, std::unordered_map<Key, Value...
      type from_json_fn (line 3851) | struct from_json_fn
      function int_to_string (line 3902) | void int_to_string( string_type& target, std::size_t value )
      class iteration_proxy_value (line 3908) | class iteration_proxy_value
        method iteration_proxy_value (line 3931) | explicit iteration_proxy_value(IteratorType it) noexcept : anchor(...
        method iteration_proxy_value (line 3934) | iteration_proxy_value& operator*()
        method iteration_proxy_value (line 3940) | iteration_proxy_value& operator++()
        method string_type (line 3961) | const string_type& key() const
        method value (line 3989) | typename IteratorType::reference value() const
      class iteration_proxy (line 3996) | class iteration_proxy
        method iteration_proxy (line 4004) | explicit iteration_proxy(typename IteratorType::reference cont) no...
        method begin (line 4008) | iteration_proxy_value<IteratorType> begin() noexcept
        method end (line 4014) | iteration_proxy_value<IteratorType> end() noexcept
      function get (line 4023) | auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>...
      function get (line 4031) | auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>...
      type external_constructor (line 4081) | struct external_constructor
      type external_constructor<value_t::boolean> (line 4084) | struct external_constructor<value_t::boolean>
        method construct (line 4087) | static void construct(BasicJsonType& j, typename BasicJsonType::bo...
      type external_constructor<value_t::string> (line 4096) | struct external_constructor<value_t::string>
        method construct (line 4099) | static void construct(BasicJsonType& j, const typename BasicJsonTy...
        method construct (line 4107) | static void construct(BasicJsonType& j, typename BasicJsonType::st...
        method construct (line 4117) | static void construct(BasicJsonType& j, const CompatibleStringType...
      type external_constructor<value_t::binary> (line 4126) | struct external_constructor<value_t::binary>
        method construct (line 4129) | static void construct(BasicJsonType& j, const typename BasicJsonTy...
        method construct (line 4138) | static void construct(BasicJsonType& j, typename BasicJsonType::bi...
      type external_constructor<value_t::number_float> (line 4148) | struct external_constructor<value_t::number_float>
        method construct (line 4151) | static void construct(BasicJsonType& j, typename BasicJsonType::nu...
      type external_constructor<value_t::number_unsigned> (line 4160) | struct external_constructor<value_t::number_unsigned>
        method construct (line 4163) | static void construct(BasicJsonType& j, typename BasicJsonType::nu...
      type external_constructor<value_t::number_integer> (line 4172) | struct external_constructor<value_t::number_integer>
        method construct (line 4175) | static void construct(BasicJsonType& j, typename BasicJsonType::nu...
      type external_constructor<value_t::array> (line 4184) | struct external_constructor<value_t::array>
        method construct (line 4187) | static void construct(BasicJsonType& j, const typename BasicJsonTy...
        method construct (line 4195) | static void construct(BasicJsonType& j, typename BasicJsonType::ar...
        method construct (line 4205) | static void construct(BasicJsonType& j, const CompatibleArrayType&...
        method construct (line 4215) | static void construct(BasicJsonType& j, const std::vector<bool>& arr)
        method construct (line 4229) | static void construct(BasicJsonType& j, const std::valarray<T>& arr)
      type external_constructor<value_t::object> (line 4243) | struct external_constructor<value_t::object>
        method construct (line 4246) | static void construct(BasicJsonType& j, const typename BasicJsonTy...
        method construct (line 4254) | static void construct(BasicJsonType& j, typename BasicJsonType::ob...
        method construct (line 4263) | static void construct(BasicJsonType& j, const CompatibleObjectType...
      function to_json (line 4280) | void to_json(BasicJsonType& j, T b) noexcept
      function to_json (line 4287) | void to_json(BasicJsonType& j, const CompatibleString& s)
      function to_json (line 4293) | void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
      function to_json (line 4300) | void to_json(BasicJsonType& j, FloatType val) noexcept
      function to_json (line 4307) | void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noe...
      function to_json (line 4314) | void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noex...
      function to_json (line 4321) | void to_json(BasicJsonType& j, EnumType e) noexcept
      function to_json (line 4328) | void to_json(BasicJsonType& j, const std::vector<bool>& e)
      function to_json (line 4341) | void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
      function to_json (line 4347) | void to_json(BasicJsonType& j, const typename BasicJsonType::binary_...
      function to_json (line 4354) | void to_json(BasicJsonType& j, const std::valarray<T>& arr)
      function to_json (line 4360) | void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
      function to_json (line 4367) | void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
      function to_json (line 4373) | void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
      function to_json (line 4383) | void to_json(BasicJsonType& j, const T(&arr)[N])
      function to_json (line 4389) | void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
      function to_json (line 4397) | void to_json(BasicJsonType& j, const T& b)
      function to_json_tuple_impl (line 4403) | void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequ...
      function to_json (line 4409) | void to_json(BasicJsonType& j, const T& t)
      type to_json_fn (line 4414) | struct to_json_fn
      function combine (line 4662) | inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
      function hash (line 4680) | std::size_t hash(const BasicJsonType& j)
      type input_format_t (line 4812) | enum class input_format_t { json, cbor, msgpack, ubjson, bson }
      class file_input_adapter (line 4822) | class file_input_adapter
        method file_input_adapter (line 4828) | explicit file_input_adapter(std::FILE* f) noexcept
        method file_input_adapter (line 4833) | file_input_adapter(const file_input_adapter&) = delete;
        method file_input_adapter (line 4834) | file_input_adapter(file_input_adapter&&) = default;
        method file_input_adapter (line 4835) | file_input_adapter& operator=(const file_input_adapter&) = delete;
        method file_input_adapter (line 4836) | file_input_adapter& operator=(file_input_adapter&&) = delete;
        method get_character (line 4838) | std::char_traits<char>::int_type get_character() noexcept
      class input_stream_adapter (line 4858) | class input_stream_adapter
        method input_stream_adapter (line 4873) | explicit input_stream_adapter(std::istream& i)
        method input_stream_adapter (line 4878) | input_stream_adapter(const input_stream_adapter&) = delete;
        method input_stream_adapter (line 4879) | input_stream_adapter& operator=(input_stream_adapter&) = delete;
        method input_stream_adapter (line 4880) | input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
        method input_stream_adapter (line 4882) | input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs...
        method get_character (line 4891) | std::char_traits<char>::int_type get_character()
      class iterator_input_adapter (line 4911) | class iterator_input_adapter
        method iterator_input_adapter (line 4916) | iterator_input_adapter(IteratorType first, IteratorType last)
        method get_character (line 4919) | typename std::char_traits<char_type>::int_type get_character()
        method empty (line 4940) | bool empty() const
      type wide_string_input_helper (line 4949) | struct wide_string_input_helper
      type wide_string_input_helper<BaseInputAdapter, 4> (line 4952) | struct wide_string_input_helper<BaseInputAdapter, 4>
        method fill_buffer (line 4955) | static void fill_buffer(BaseInputAdapter& input,
      type wide_string_input_helper<BaseInputAdapter, 2> (line 5010) | struct wide_string_input_helper<BaseInputAdapter, 2>
        method fill_buffer (line 5013) | static void fill_buffer(BaseInputAdapter& input,
      class wide_string_input_adapter (line 5073) | class wide_string_input_adapter
        method wide_string_input_adapter (line 5078) | wide_string_input_adapter(BaseInputAdapter base)
        method get_character (line 5081) | typename std::char_traits<char>::int_type get_character() noexcept
        method fill_buffer (line 5102) | void fill_buffer()
      type iterator_input_adapter_factory (line 5118) | struct iterator_input_adapter_factory
        method adapter_type (line 5124) | static adapter_type create(IteratorType first, IteratorType last)
      type is_iterator_of_multibyte (line 5131) | struct is_iterator_of_multibyte
      type iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>> (line 5141) | struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_i...
        method adapter_type (line 5148) | static adapter_type create(IteratorType first, IteratorType last)
      function input_adapter (line 5156) | typename iterator_input_adapter_factory<IteratorType>::adapter_type ...
      function input_adapter (line 5164) | auto input_adapter(const ContainerType& container) -> decltype(input...
      function file_input_adapter (line 5174) | inline file_input_adapter input_adapter(std::FILE* file)
        method file_input_adapter (line 4828) | explicit file_input_adapter(std::FILE* f) noexcept
        method file_input_adapter (line 4833) | file_input_adapter(const file_input_adapter&) = delete;
        method file_input_adapter (line 4834) | file_input_adapter(file_input_adapter&&) = default;
        method file_input_adapter (line 4835) | file_input_adapter& operator=(const file_input_adapter&) = delete;
        method file_input_adapter (line 4836) | file_input_adapter& operator=(file_input_adapter&&) = delete;
        method get_character (line 4838) | std::char_traits<char>::int_type get_character() noexcept
      function input_stream_adapter (line 5179) | inline input_stream_adapter input_adapter(std::istream& stream)
        method input_stream_adapter (line 4873) | explicit input_stream_adapter(std::istream& i)
        method input_stream_adapter (line 4878) | input_stream_adapter(const input_stream_adapter&) = delete;
        method input_stream_adapter (line 4879) | input_stream_adapter& operator=(input_stream_adapter&) = delete;
        method input_stream_adapter (line 4880) | input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
        method input_stream_adapter (line 4882) | input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs...
        method get_character (line 4891) | std::char_traits<char>::int_type get_character()
      function input_stream_adapter (line 5184) | inline input_stream_adapter input_adapter(std::istream&& stream)
        method input_stream_adapter (line 4873) | explicit input_stream_adapter(std::istream& i)
        method input_stream_adapter (line 4878) | input_stream_adapter(const input_stream_adapter&) = delete;
        method input_stream_adapter (line 4879) | input_stream_adapter& operator=(input_stream_adapter&) = delete;
        method input_stream_adapter (line 4880) | input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
        method input_stream_adapter (line 4882) | input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs...
        method get_character (line 4891) | std::char_traits<char>::int_type get_character()
      function contiguous_bytes_input_adapter (line 5199) | contiguous_bytes_input_adapter input_adapter(CharT b)
      function input_adapter (line 5207) | auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, a...
      class span_input_adapter (line 5215) | class span_input_adapter
        method span_input_adapter (line 5224) | span_input_adapter(CharT b, std::size_t l)
        method span_input_adapter (line 5231) | span_input_adapter(IteratorType first, IteratorType last)
        method contiguous_bytes_input_adapter (line 5234) | contiguous_bytes_input_adapter&& get()
      class json_sax_dom_parser (line 5396) | class json_sax_dom_parser
        method json_sax_dom_parser (line 5410) | explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_ex...
        method json_sax_dom_parser (line 5415) | json_sax_dom_parser(const json_sax_dom_parser&) = delete;
        method json_sax_dom_parser (line 5416) | json_sax_dom_parser(json_sax_dom_parser&&) = default;
        method json_sax_dom_parser (line 5417) | json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
        method json_sax_dom_parser (line 5418) | json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
        method null (line 5421) | bool null()
        method boolean (line 5427) | bool boolean(bool val)
        method number_integer (line 5433) | bool number_integer(number_integer_t val)
        method number_unsigned (line 5439) | bool number_unsigned(number_unsigned_t val)
        method number_float (line 5445) | bool number_float(number_float_t val, const string_t& /*unused*/)
        method string (line 5451) | bool string(string_t& val)
        method binary (line 5457) | bool binary(binary_t& val)
        method start_object (line 5463) | bool start_object(std::size_t len)
        method key (line 5476) | bool key(string_t& val)
        method end_object (line 5483) | bool end_object()
        method start_array (line 5489) | bool start_array(std::size_t len)
        method end_array (line 5502) | bool end_array()
        method parse_error (line 5509) | bool parse_error(std::size_t /*unused*/, const std::string& /*unus...
        method is_errored (line 5521) | constexpr bool is_errored() const
        method JSON_HEDLEY_RETURNS_NON_NULL (line 5534) | JSON_HEDLEY_RETURNS_NON_NULL
      class json_sax_dom_callback_parser (line 5570) | class json_sax_dom_callback_parser
        method json_sax_dom_callback_parser (line 5581) | json_sax_dom_callback_parser(BasicJsonType& r,
        method json_sax_dom_callback_parser (line 5590) | json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) ...
        method json_sax_dom_callback_parser (line 5591) | json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = def...
        method json_sax_dom_callback_parser (line 5592) | json_sax_dom_callback_parser& operator=(const json_sax_dom_callbac...
        method json_sax_dom_callback_parser (line 5593) | json_sax_dom_callback_parser& operator=(json_sax_dom_callback_pars...
        method null (line 5596) | bool null()
        method boolean (line 5602) | bool boolean(bool val)
        method number_integer (line 5608) | bool number_integer(number_integer_t val)
        method number_unsigned (line 5614) | bool number_unsigned(number_unsigned_t val)
        method number_float (line 5620) | bool number_float(number_float_t val, const string_t& /*unused*/)
        method string (line 5626) | bool string(string_t& val)
        method binary (line 5632) | bool binary(binary_t& val)
        method start_object (line 5638) | bool start_object(std::size_t len)
        method key (line 5656) | bool key(string_t& val)
        method end_object (line 5673) | bool end_object()
        method start_array (line 5702) | bool start_array(std::size_t len)
        method end_array (line 5719) | bool end_array()
        method parse_error (line 5748) | bool parse_error(std::size_t /*unused*/, const std::string& /*unus...
        method is_errored (line 5760) | constexpr bool is_errored() const
        method handle_value (line 5782) | std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool...
      class json_sax_acceptor (line 5866) | class json_sax_acceptor
        method null (line 5875) | bool null()
        method boolean (line 5880) | bool boolean(bool /*unused*/)
        method number_integer (line 5885) | bool number_integer(number_integer_t /*unused*/)
        method number_unsigned (line 5890) | bool number_unsigned(number_unsigned_t /*unused*/)
        method number_float (line 5895) | bool number_float(number_float_t /*unused*/, const string_t& /*unu...
        method string (line 5900) | bool string(string_t& /*unused*/)
        method binary (line 5905) | bool binary(binary_t& /*unused*/)
        method start_object (line 5910) | bool start_object(std::size_t /*unused*/ = std::size_t(-1))
        method key (line 5915) | bool key(string_t& /*unused*/)
        method end_object (line 5920) | bool end_object()
        method start_array (line 5925) | bool start_array(std::size_t /*unused*/ = std::size_t(-1))
        method end_array (line 5930) | bool end_array()
        method parse_error (line 5935) | bool parse_error(std::size_t /*unused*/, const std::string& /*unus...
      class lexer_base (line 5973) | class lexer_base
        type token_type (line 5977) | enum class token_type
      class lexer (line 6050) | class lexer : public lexer_base<BasicJsonType>
        method lexer (line 6062) | explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ =...
        method lexer (line 6069) | lexer(const lexer&) = delete;
        method lexer (line 6070) | lexer(lexer&&) = default;
        method lexer (line 6071) | lexer& operator=(lexer&) = delete;
        method lexer (line 6072) | lexer& operator=(lexer&&) = default;
        method JSON_HEDLEY_PURE (line 6081) | JSON_HEDLEY_PURE
        method get_codepoint (line 6108) | int get_codepoint()
        method next_byte_in_range (line 6156) | bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
        method token_type (line 6193) | token_type scan_string()
        method scan_comment (line 6783) | bool scan_comment()
        method strtof (line 6851) | static void strtof(float& f, const char* str, char** endptr) noexcept
        method strtof (line 6857) | static void strtof(double& f, const char* str, char** endptr) noex...
        method strtof (line 6863) | static void strtof(long double& f, const char* str, char** endptr)...
        method token_type (line 6908) | token_type scan_number()  // lgtm [cpp/use-of-goto]
      type is_sax (line 7641) | struct is_sax
      type is_sax_static_asserts (line 7672) | struct is_sax_static_asserts
      type cbor_tag_handler_t (line 7736) | enum class cbor_tag_handler_t
      function little_endianess (line 7749) | static inline bool little_endianess(int num = 1) noexcept
      class binary_reader (line 7763) | class binary_reader
        method binary_reader (line 7780) | explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(...
        method binary_reader (line 7786) | binary_reader(const binary_reader&) = delete;
        method binary_reader (line 7787) | binary_reader(binary_reader&&) = default;
        method binary_reader (line 7788) | binary_reader& operator=(const binary_reader&) = delete;
        method binary_reader (line 7789) | binary_reader& operator=(binary_reader&&) = default;
        method JSON_HEDLEY_NON_NULL (line 7800) | JSON_HEDLEY_NON_NULL(3)
        method parse_bson_internal (line 7862) | bool parse_bson_internal()
        method get_bson_cstr (line 7887) | bool get_bson_cstr(string_t& result)
        method get_bson_string (line 7917) | bool get_bson_string(const NumberType len, string_t& result)
        method get_bson_binary (line 7938) | bool get_bson_binary(const NumberType len, binary_t& result)
        method parse_bson_element_internal (line 7964) | bool parse_bson_element_internal(const char_int_type element_type,
        method parse_bson_element_list (line 8042) | bool parse_bson_element_list(const bool is_array)
        method parse_bson_array (line 8080) | bool parse_bson_array()
        method parse_cbor_internal (line 8110) | bool parse_cbor_internal(const bool get_char,
        method get_cbor_string (line 8556) | bool get_cbor_string(string_t& result)
        method get_cbor_binary (line 8651) | bool get_cbor_binary(binary_t& result)
        method get_cbor_array (line 8745) | bool get_cbor_array(const std::size_t len,
        method get_cbor_object (line 8783) | bool get_cbor_object(const std::size_t len,
        method parse_msgpack_internal (line 8836) | bool parse_msgpack_internal()
        method get_msgpack_string (line 9216) | bool get_msgpack_string(string_t& result)
        method get_msgpack_binary (line 9298) | bool get_msgpack_binary(binary_t& result)
        method get_msgpack_array (line 9409) | bool get_msgpack_array(const std::size_t len)
        method get_msgpack_object (line 9431) | bool get_msgpack_object(const std::size_t len)
        method parse_ubjson_internal (line 9468) | bool parse_ubjson_internal(const bool get_char = true)
        method get_ubjson_string (line 9487) | bool get_ubjson_string(string_t& result, const bool get_char = true)
        method get_ubjson_size_value (line 9541) | bool get_ubjson_size_value(std::size_t& result)
        method get_ubjson_size_type (line 9618) | bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& r...
        method get_ubjson_value (line 9659) | bool get_ubjson_value(const char_int_type prefix)
        method get_ubjson_array (line 9760) | bool get_ubjson_array()
        method get_ubjson_object (line 9822) | bool get_ubjson_object()
        method get_ubjson_high_precision_number (line 9897) | bool get_ubjson_high_precision_number()
        method char_int_type (line 9959) | char_int_type get()
        method char_int_type (line 9968) | char_int_type get_ignore_noop()
        method get_number (line 9993) | bool get_number(const input_format_t format, NumberType& result)
        method get_string (line 10036) | bool get_string(const input_format_t format,
        method get_binary (line 10069) | bool get_binary(const input_format_t format,
        method JSON_HEDLEY_NON_NULL (line 10092) | JSON_HEDLEY_NON_NULL(3)
        method get_token_string (line 10106) | std::string get_token_string() const
        method exception_message (line 10119) | std::string exception_message(const input_format_t format,
      type parse_event_t (line 10206) | enum class parse_event_t : uint8_t
      class parser (line 10232) | class parser
        method parser (line 10243) | explicit parser(InputAdapterType&& adapter,
        method parse (line 10265) | void parse(const bool strict, BasicJsonType& result)
        method accept (line 10326) | bool accept(const bool strict = true)
        method sax_parse (line 10334) | bool sax_parse(SAX* sax, const bool strict = true)
        method sax_parse_internal (line 10354) | bool sax_parse_internal(SAX* sax)
        method token_type (line 10636) | token_type get_token()
        method exception_message (line 10641) | std::string exception_message(const token_type expected, const std...
      class primitive_iterator_t (line 10705) | class primitive_iterator_t
        method difference_type (line 10717) | constexpr difference_type get_value() const noexcept
        method set_begin (line 10723) | void set_begin() noexcept
        method set_end (line 10729) | void set_end() noexcept
        method is_begin (line 10735) | constexpr bool is_begin() const noexcept
        method is_end (line 10741) | constexpr bool is_end() const noexcept
        method primitive_iterator_t (line 10756) | primitive_iterator_t operator+(difference_type n) noexcept
        method difference_type (line 10763) | constexpr difference_type operator-(primitive_iterator_t lhs, prim...
        method primitive_iterator_t (line 10768) | primitive_iterator_t& operator++() noexcept
        method primitive_iterator_t (line 10774) | primitive_iterator_t const operator++(int) noexcept
        method primitive_iterator_t (line 10781) | primitive_iterator_t& operator--() noexcept
        method primitive_iterator_t (line 10787) | primitive_iterator_t const operator--(int) noexcept
        method primitive_iterator_t (line 10794) | primitive_iterator_t& operator+=(difference_type n) noexcept
        method primitive_iterator_t (line 10800) | primitive_iterator_t& operator-=(difference_type n) noexcept
      type internal_iterator (line 10820) | struct internal_iterator
      class iteration_proxy (line 10858) | class iteration_proxy
        method iteration_proxy (line 4004) | explicit iteration_proxy(typename IteratorType::reference cont) no...
        method begin (line 4008) | iteration_proxy_value<IteratorType> begin() noexcept
        method end (line 4014) | iteration_proxy_value<IteratorType> end() noexcept
      class iteration_proxy_value (line 10859) | class iteration_proxy_value
        method iteration_proxy_value (line 3931) | explicit iteration_proxy_value(IteratorType it) noexcept : anchor(...
        method iteration_proxy_value (line 3934) | iteration_proxy_value& operator*()
        method iteration_proxy_value (line 3940) | iteration_proxy_value& operator++()
        method string_type (line 3961) | const string_type& key() const
        method value (line 3989) | typename IteratorType::reference value() const
      function set_end (line 10878) | class iter_impl
      class json_reverse_iterator (line 11514) | class json_reverse_iterator : public std::reverse_iterator<Base>
        method json_reverse_iterator (line 11524) | explicit json_reverse_iterator(const typename base_iterator::itera...
        method json_reverse_iterator (line 11528) | explicit json_reverse_iterator(const base_iterator& it) noexcept :...
        method json_reverse_iterator (line 11531) | json_reverse_iterator const operator++(int)
        method json_reverse_iterator (line 11537) | json_reverse_iterator& operator++()
        method json_reverse_iterator (line 11543) | json_reverse_iterator const operator--(int)
        method json_reverse_iterator (line 11549) | json_reverse_iterator& operator--()
        method json_reverse_iterator (line 11555) | json_reverse_iterator& operator+=(difference_type i)
        method json_reverse_iterator (line 11561) | json_reverse_iterator operator+(difference_type i) const
        method json_reverse_iterator (line 11567) | json_reverse_iterator operator-(difference_type i) const
        method difference_type (line 11573) | difference_type operator-(const json_reverse_iterator& other) const
        method reference (line 11579) | reference operator[](difference_type n) const
        method key (line 11585) | auto key() const -> decltype(std::declval<Base>().key())
        method reference (line 11592) | reference value() const
      class json_ref (line 12601) | class json_ref
        method json_ref (line 12606) | json_ref(value_type&& value)
        method json_ref (line 12612) | json_ref(const value_type& value)
        method json_ref (line 12617) | json_ref(std::initializer_list<json_ref> init)
        method json_ref (line 12626) | json_ref(Args && ... args)
        method json_ref (line 12633) | json_ref(json_ref&&) = default;
        method json_ref (line 12634) | json_ref(const json_ref&) = delete;
        method json_ref (line 12635) | json_ref& operator=(const json_ref&) = delete;
        method json_ref (line 12636) | json_ref& operator=(json_ref&&) = delete;
        method value_type (line 12639) | value_type moved_or_copied() const
        method value_type (line 12648) | value_type const& operator*() const
        method value_type (line 12653) | value_type const* operator->() const
      type output_adapter_protocol (line 12706) | struct output_adapter_protocol
      class output_vector_adapter (line 12719) | class output_vector_adapter : public output_adapter_protocol<CharType>
        method output_vector_adapter (line 12722) | explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
        method write_character (line 12726) | void write_character(CharType c) override
        method JSON_HEDLEY_NON_NULL (line 12731) | JSON_HEDLEY_NON_NULL(2)
      class output_stream_adapter (line 12743) | class output_stream_adapter : public output_adapter_protocol<CharType>
        method output_stream_adapter (line 12746) | explicit output_stream_adapter(std::basic_ostream<CharType>& s) no...
        method write_character (line 12750) | void write_character(CharType c) override
        method JSON_HEDLEY_NON_NULL (line 12755) | JSON_HEDLEY_NON_NULL(2)
      class output_string_adapter (line 12767) | class output_string_adapter : public output_adapter_protocol<CharType>
        method output_string_adapter (line 12770) | explicit output_string_adapter(StringType& s) noexcept
        method write_character (line 12774) | void write_character(CharType c) override
        method JSON_HEDLEY_NON_NULL (line 12779) | JSON_HEDLEY_NON_NULL(2)
      class output_adapter (line 12790) | class output_adapter
        method output_adapter (line 12793) | output_adapter(std::vector<CharType>& vec)
        method output_adapter (line 12796) | output_adapter(std::basic_ostream<CharType>& s)
        method output_adapter (line 12799) | output_adapter(StringType& s)
      class binary_writer (line 12826) | class binary_writer
        method binary_writer (line 12838) | explicit binary_writer(output_adapter_t<CharType> adapter) : oa(ad...
        method write_bson (line 12847) | void write_bson(const BasicJsonType& j)
        method write_cbor (line 12867) | void write_cbor(const BasicJsonType& j)
        method write_msgpack (line 13172) | void write_msgpack(const BasicJsonType& j)
        method write_ubjson (line 13496) | void write_ubjson(const BasicJsonType& j, const bool use_count,
        method calc_bson_entry_header_size (line 13703) | static std::size_t calc_bson_entry_header_size(const string_t& name)
        method write_bson_entry_header (line 13718) | void write_bson_entry_header(const string_t& name,
        method write_bson_boolean (line 13730) | void write_bson_boolean(const string_t& name,
        method write_bson_double (line 13740) | void write_bson_double(const string_t& name,
        method calc_bson_string_size (line 13750) | static std::size_t calc_bson_string_size(const string_t& value)
        method write_bson_string (line 13758) | void write_bson_string(const string_t& name,
        method write_bson_null (line 13772) | void write_bson_null(const string_t& name)
        method calc_bson_integer_size (line 13780) | static std::size_t calc_bson_integer_size(const std::int64_t value)
        method write_bson_integer (line 13790) | void write_bson_integer(const string_t& name,
        method calc_bson_unsigned_size (line 13808) | static constexpr std::size_t calc_bson_unsigned_size(const std::ui...
        method write_bson_unsigned (line 13818) | void write_bson_unsigned(const string_t& name,
        method write_bson_object_entry (line 13840) | void write_bson_object_entry(const string_t& name,
        method calc_bson_array_size (line 13850) | static std::size_t calc_bson_array_size(const typename BasicJsonTy...
        method calc_bson_binary_size (line 13865) | static std::size_t calc_bson_binary_size(const typename BasicJsonT...
        method write_bson_array (line 13873) | void write_bson_array(const string_t& name,
        method write_bson_binary (line 13892) | void write_bson_binary(const string_t& name,
        method calc_bson_element_size (line 13907) | static std::size_t calc_bson_element_size(const string_t& name,
        method write_bson_element (line 13955) | void write_bson_element(const string_t& name,
        method calc_bson_object_size (line 14001) | static std::size_t calc_bson_object_size(const typename BasicJsonT...
        method write_bson_object (line 14016) | void write_bson_object(const typename BasicJsonType::object_t& value)
        method CharType (line 14032) | static constexpr CharType get_cbor_float_prefix(float /*unused*/)
        method CharType (line 14037) | static constexpr CharType get_cbor_float_prefix(double /*unused*/)
        method CharType (line 14046) | static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
        method CharType (line 14051) | static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
        method write_number_with_ubjson_prefix (line 14063) | void write_number_with_ubjson_prefix(const NumberType n,
        method write_number_with_ubjson_prefix (line 14076) | void write_number_with_ubjson_prefix(const NumberType n,
        method write_number_with_ubjson_prefix (line 14139) | void write_number_with_ubjson_prefix(const NumberType n,
        method CharType (line 14203) | CharType ubjson_prefix(const BasicJsonType& j) const noexcept
        method CharType (line 14283) | static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
        method CharType (line 14288) | static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
        method write_number (line 14309) | void write_number(const NumberType n)
        method write_compact_float (line 14325) | void write_compact_float(const number_float_t n, detail::input_for...
        method CharType (line 14352) | static constexpr CharType to_char_type(std::uint8_t x) noexcept
        method CharType (line 14359) | static CharType to_char_type(std::uint8_t x) noexcept
        method CharType (line 14370) | static constexpr CharType to_char_type(std::uint8_t x) noexcept
        method CharType (line 14381) | static constexpr CharType to_char_type(InputCharType x) noexcept
      type dtoa_impl (line 14450) | namespace dtoa_impl
        function Target (line 14454) | Target reinterpret_bits(const Source source)
        type diyfp (line 14463) | struct diyfp // f * 2^e
          method diyfp (line 14470) | constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_...
          method diyfp (line 14476) | static diyfp sub(const diyfp& x, const diyfp& y) noexcept
          method diyfp (line 14488) | static diyfp mul(const diyfp& x, const diyfp& y) noexcept
          method diyfp (line 14553) | static diyfp normalize(diyfp x) noexcept
          method diyfp (line 14570) | static diyfp normalize_to(const diyfp& x, const int target_expon...
        type boundaries (line 14581) | struct boundaries
        function boundaries (line 14595) | boundaries compute_boundaries(FloatType value)
        type cached_power (line 14720) | struct cached_power // c = f * 2^e ~= 10^k
        function cached_power (line 14734) | inline cached_power get_cached_power_for_binary_exponent(int e)
        function find_largest_pow10 (line 14898) | inline int find_largest_pow10(const std::uint32_t n, std::uint32_t...
        function grisu2_round (line 14954) | inline void grisu2_round(char* buf, int len, std::uint64_t dist, s...
        function grisu2_digit_gen (line 14995) | inline void grisu2_digit_gen(char* buffer, int& length, int& decim...
        function grisu2 (line 15236) | inline void grisu2(char* buf, int& len, int& decimal_exponent,
        function JSON_HEDLEY_NON_NULL (line 15295) | JSON_HEDLEY_NON_NULL(1)
      type error_handler_t (line 15543) | enum class error_handler_t
      class serializer (line 15551) | class serializer
        method serializer (line 15567) | serializer(output_adapter_t<char> s, const char ichar,
        method serializer (line 15579) | serializer(const serializer&) = delete;
        method serializer (line 15580) | serializer& operator=(const serializer&) = delete;
        method serializer (line 15581) | serializer(serializer&&) = delete;
        method serializer (line 15582) | serializer& operator=(serializer&&) = delete;
        method dump (line 15607) | void dump(const BasicJsonType& val,
        method switch (line 15905) | switch (decode(state, codepoint, byte))
    type detail (line 2815) | namespace detail
      type position_t (line 86) | struct position_t
      class exception (line 2419) | class exception : public std::exception
        method JSON_HEDLEY_RETURNS_NON_NULL (line 2423) | JSON_HEDLEY_RETURNS_NON_NULL
        method JSON_HEDLEY_NON_NULL (line 2433) | JSON_HEDLEY_NON_NULL(3)
        method name (line 2436) | static std::string name(const std::string& ename, int id_)
      class parse_error (line 2491) | class parse_error : public exception
        method parse_error (line 2503) | static parse_error create(int id_, const position_t& pos, const st...
        method parse_error (line 2510) | static parse_error create(int id_, std::size_t byte_, const std::s...
        method parse_error (line 2530) | parse_error(int id_, std::size_t byte_, const char* what_arg)
        method position_string (line 2533) | static std::string position_string(const position_t& pos)
      class invalid_iterator (line 2577) | class invalid_iterator : public exception
        method invalid_iterator (line 2580) | static invalid_iterator create(int id_, const std::string& what_arg)
        method JSON_HEDLEY_NON_NULL (line 2587) | JSON_HEDLEY_NON_NULL(3)
      class type_error (line 2631) | class type_error : public exception
        method type_error (line 2634) | static type_error create(int id_, const std::string& what_arg)
        method JSON_HEDLEY_NON_NULL (line 2641) | JSON_HEDLEY_NON_NULL(3)
      class out_of_range (line 2678) | class out_of_range : public exception
        method out_of_range (line 2681) | static out_of_range create(int id_, const std::string& what_arg)
        method JSON_HEDLEY_NON_NULL (line 2688) | JSON_HEDLEY_NON_NULL(3)
      class other_error (line 2716) | class other_error : public exception
        method other_error (line 2719) | static other_error create(int id_, const std::string& what_arg)
        method JSON_HEDLEY_NON_NULL (line 2726) | JSON_HEDLEY_NON_NULL(3)
      type index_sequence (line 2754) | struct index_sequence
        method size (line 2758) | static constexpr std::size_t size() noexcept
      type merge_and_renumber (line 2765) | struct merge_and_renumber
      type make_index_sequence (line 2772) | struct make_index_sequence
      type make_index_sequence<0> (line 2776) | struct make_index_sequence<0> : index_sequence<> {}
      type make_index_sequence<1> (line 2777) | struct make_index_sequence<1> : index_sequence<0> {}
      type priority_tag (line 2783) | struct priority_tag : priority_tag < N - 1 > {}
      type priority_tag<0> (line 2784) | struct priority_tag<0> {}
      type static_const (line 2788) | struct static_const
      type make_void (line 2817) | struct make_void
      type iterator_types (line 2833) | struct iterator_types {}
      type iterator_types <
    It,
    void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
    typename It::reference, typename It::iterator_category >> (line 2836) | struct iterator_types <
      type iterator_traits (line 2851) | struct iterator_traits
      type iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >> (line 2856) | struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
      type iterator_traits<T*, enable_if_t<std::is_object<T>::value>> (line 2862) | struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
      type nonesuch (line 2890) | struct nonesuch
        method nonesuch (line 2892) | nonesuch() = delete;
        method nonesuch (line 2894) | nonesuch(nonesuch const&) = delete;
        method nonesuch (line 2895) | nonesuch(nonesuch const&&) = delete;
      type detector (line 2904) | struct detector
      type is_basic_json (line 3044) | struct is_basic_json : std::false_type {}
      class json_ref (line 3054) | class json_ref
        method json_ref (line 12606) | json_ref(value_type&& value)
        method json_ref (line 12612) | json_ref(const value_type& value)
        method json_ref (line 12617) | json_ref(std::initializer_list<json_ref> init)
        method json_ref (line 12626) | json_ref(Args && ... args)
        method json_ref (line 12633) | json_ref(json_ref&&) = default;
        method json_ref (line 12634) | json_ref(const json_ref&) = delete;
        method json_ref (line 12635) | json_ref& operator=(const json_ref&) = delete;
        method json_ref (line 12636) | json_ref& operator=(json_ref&&) = delete;
        method value_type (line 12639) | value_type moved_or_copied() const
        method value_type (line 12648) | value_type const& operator*() const
        method value_type (line 12653) | value_type const* operator->() const
      type is_json_ref (line 3057) | struct is_json_ref : std::false_type {}
      type is_json_ref<json_ref<T>> (line 3060) | struct is_json_ref<json_ref<T>> : std::true_type {}
      type has_from_json (line 3101) | struct has_from_json : std::false_type {}
      type is_getable (line 3108) | struct is_getable
      type has_from_json < BasicJsonType, T,
           enable_if_t < !is_basic_json<T>::value >> (line 3114) | struct has_from_json < BasicJsonType, T,
      type has_non_default_from_json (line 3127) | struct has_non_default_from_json : std::false_type {}
      type has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >> (line 3130) | struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !...
      type has_to_json (line 3142) | struct has_to_json : std::false_type {}
      type has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >> (line 3145) | struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<...
      type is_iterator_traits (line 3160) | struct is_iterator_traits : std::false_type {}
      type is_iterator_traits<iterator_traits<T>> (line 3163) | struct is_iterator_traits<iterator_traits<T>>
      type is_complete_type (line 3180) | struct is_complete_type : std::false_type {}
      type is_complete_type<T, decltype(void(sizeof(T)))> (line 3183) | struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_ty...
      type is_compatible_object_type_impl (line 3187) | struct is_compatible_object_type_impl : std::false_type {}
      type is_compatible_object_type_impl <
    BasicJsonType, CompatibleObjectType,
    enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
    is_detected<key_type_t, CompatibleObjectType>::value >> (line 3190) | struct is_compatible_object_type_impl <
      type is_compatible_object_type (line 3207) | struct is_compatible_object_type
      type is_constructible_object_type_impl (line 3212) | struct is_constructible_object_type_impl : std::false_type {}
      type is_constructible_object_type_impl <
    BasicJsonType, ConstructibleObjectType,
    enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
    is_detected<key_type_t, ConstructibleObjectType>::value >> (line 3215) | struct is_constructible_object_type_impl <
      type is_constructible_object_type (line 3239) | struct is_constructible_object_type
      type is_compatible_string_type_impl (line 3245) | struct is_compatible_string_type_impl : std::false_type {}
      type is_compatible_string_type_impl <
    BasicJsonType, CompatibleStringType,
    enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
    value_type_t, CompatibleStringType>::value >> (line 3248) | struct is_compatible_string_type_impl <
      type is_compatible_string_type (line 3258) | struct is_compatible_string_type
      type is_constructible_string_type_impl (line 3263) | struct is_constructible_string_type_impl : std::false_type {}
      type is_constructible_string_type_impl <
    BasicJsonType, ConstructibleStringType,
    enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
    value_type_t, ConstructibleStringType>::value >> (line 3266) | struct is_constructible_string_type_impl <
      type is_constructible_string_type (line 3277) | struct is_constructible_string_type
      type is_compatible_array_type_impl (line 3281) | struct is_compatible_array_type_impl : std::false_type {}
      type is_compatible_array_type (line 3300) | struct is_compatible_array_type
      type is_constructible_array_type_impl (line 3304) | struct is_constructible_array_type_impl : std::false_type {}
      type is_constructible_array_type_impl <
    BasicJsonType, ConstructibleArrayType,
    enable_if_t<std::is_same<ConstructibleArrayType,
    typename BasicJsonType::value_type>::value >> (line 3307) | struct is_constructible_array_type_impl <
      type is_constructible_array_type_impl <
    BasicJsonType, ConstructibleArrayType,
    enable_if_t < !std::is_same<ConstructibleArrayType,
    typename BasicJsonType::value_type>::value&&
    std::is_default_constructible<ConstructibleArrayType>::value&&
(std::is_move_assignable<ConstructibleArrayType>::value ||
 std::is_copy_assignable<ConstructibleArrayType>::value)&&
is_detected<value_type_t, ConstructibleArrayType>::value&&
is_detected<iterator_t, ConstructibleArrayType>::value&&
is_complete_type <
detected_t<value_type_t, ConstructibleArrayType >>::value >> (line 3314) | struct is_constructible_array_type_impl <
      type is_constructible_array_type (line 3343) | struct is_constructible_array_type
      type is_compatible_integer_type_impl (line 3348) | struct is_compatible_integer_type_impl : std::false_type {}
      type is_compatible_integer_type_impl <
    RealIntegerType, CompatibleNumberIntegerType,
    enable_if_t < std::is_integral<RealIntegerType>::value&&
    std::is_integral<CompatibleNumberIntegerType>::value&&
    !std::is_same<bool, CompatibleNumberIntegerType>::value >> (line 3351) | struct is_compatible_integer_type_impl <
      type is_compatible_integer_type (line 3369) | struct is_compatible_integer_type
      type is_compatible_type_impl (line 3374) | struct is_compatible_type_impl: std::false_type {}
      type is_compatible_type_impl <
    BasicJsonType, CompatibleType,
    enable_if_t<is_complete_type<CompatibleType>::value >> (line 3377) | struct is_compatible_type_impl <
      type is_compatible_type (line 3386) | struct is_compatible_type
      type conjunction (line 3390) | struct conjunction : std::true_type { }
      type conjunction<B1> (line 3391) | struct conjunction<B1> : B1 { }
      type is_constructible_tuple (line 3397) | struct is_constructible_tuple : std::false_type {}
      type value_t (line 3444) | enum class value_t : std::uint8_t
      function from_json (line 3493) | void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
      function get_arithmetic_value (line 3507) | void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
      function from_json (line 3533) | void from_json(const BasicJsonType& j, typename BasicJsonType::boole...
      function from_json (line 3543) | void from_json(const BasicJsonType& j, typename BasicJsonType::strin...
      function from_json (line 3559) | void from_json(const BasicJsonType& j, ConstructibleStringType& s)
      function from_json (line 3570) | void from_json(const BasicJsonType& j, typename BasicJsonType::numbe...
      function from_json (line 3576) | void from_json(const BasicJsonType& j, typename BasicJsonType::numbe...
      function from_json (line 3582) | void from_json(const BasicJsonType& j, typename BasicJsonType::numbe...
      function from_json (line 3589) | void from_json(const BasicJsonType& j, EnumType& e)
      function from_json (line 3599) | void from_json(const BasicJsonType& j, std::forward_list<T, Allocato...
      function from_json (line 3616) | void from_json(const BasicJsonType& j, std::valarray<T>& l)
      function from_json (line 3631) | auto from_json(const BasicJsonType& j, T (&arr)[N])
      function from_json_array_impl (line 3641) | void from_json_array_impl(const BasicJsonType& j, typename BasicJson...
      function from_json_array_impl (line 3647) | auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& ...
      function from_json_array_impl (line 3658) | auto from_json_array_impl(const BasicJsonType& j, ConstructibleArray...
      function from_json_array_impl (line 3679) | void from_json_array_impl(const BasicJsonType& j, ConstructibleArray...
      function from_json (line 3704) | auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
      function from_json (line 3719) | void from_json(const BasicJsonType& j, typename BasicJsonType::binar...
      function from_json (line 3731) | void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
      function from_json (line 3763) | void from_json(const BasicJsonType& j, ArithmeticType& val)
      function from_json (line 3794) | void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
      function from_json_tuple_impl (line 3800) | void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_se...
      function from_json (line 3806) | void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
      function from_json (line 3814) | void from_json(const BasicJsonType& j, std::map<Key, Value, Compare,...
      function from_json (line 3834) | void from_json(const BasicJsonType& j, std::unordered_map<Key, Value...
      type from_json_fn (line 3851) | struct from_json_fn
      function int_to_string (line 3902) | void int_to_string( string_type& target, std::size_t value )
      class iteration_proxy_value (line 3908) | class iteration_proxy_value
        method iteration_proxy_value (line 3931) | explicit iteration_proxy_value(IteratorType it) noexcept : anchor(...
        method iteration_proxy_value (line 3934) | iteration_proxy_value& operator*()
        method iteration_proxy_value (line 3940) | iteration_proxy_value& operator++()
        method string_type (line 3961) | const string_type& key() const
        method value (line 3989) | typename IteratorType::reference value() const
      class iteration_proxy (line 3996) | class iteration_proxy
        method iteration_proxy (line 4004) | explicit iteration_proxy(typename IteratorType::reference cont) no...
        method begin (line 4008) | iteration_proxy_value<IteratorType> begin() noexcept
        method end (line 4014) | iteration_proxy_value<IteratorType> end() noexcept
      function get (line 4023) | auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>...
      function get (line 4031) | auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>...
      type external_constructor (line 4081) | struct external_constructor
      type external_constructor<value_t::boolean> (line 4084) | struct external_constructor<value_t::boolean>
        method construct (line 4087) | static void construct(BasicJsonType& j, typename BasicJsonType::bo...
      type external_constructor<value_t::string> (line 4096) | struct external_constructor<value_t::string>
        method construct (line 4099) | static void construct(BasicJsonType& j, const typename BasicJsonTy...
        method construct (line 4107) | static void construct(BasicJsonType& j, typename BasicJsonType::st...
        method construct (line 4117) | static void construct(BasicJsonType& j, const CompatibleStringType...
      type external_constructor<value_t::binary> (line 4126) | struct external_constructor<value_t::binary>
        method construct (line 4129) | static void construct(BasicJsonType& j, const typename BasicJsonTy...
        method construct (line 4138) | static void construct(BasicJsonType& j, typename BasicJsonType::bi...
      type external_constructor<value_t::number_float> (line 4148) | struct external_constructor<value_t::number_float>
        method construct (line 4151) | static void construct(BasicJsonType& j, typename BasicJsonType::nu...
      type external_constructor<value_t::number_unsigned> (line 4160) | struct external_constructor<value_t::number_unsigned>
        method construct (line 4163) | static void construct(BasicJsonType& j, typename BasicJsonType::nu...
      type external_constructor<value_t::number_integer> (line 4172) | struct external_constructor<value_t::number_integer>
        method construct (line 4175) | static void construct(BasicJsonType& j, typename BasicJsonType::nu...
      type external_constructor<value_t::array> (line 4184) | struct external_constructor<value_t::array>
        method construct (line 4187) | static void construct(BasicJsonType& j, const typename BasicJsonTy...
        method construct (line 4195) | static void construct(BasicJsonType& j, typename BasicJsonType::ar...
        method construct (line 4205) | static void construct(BasicJsonType& j, const CompatibleArrayType&...
        method construct (line 4215) | static void construct(BasicJsonType& j, const std::vector<bool>& arr)
        method construct (line 4229) | static void construct(BasicJsonType& j, const std::valarray<T>& arr)
      type external_constructor<value_t::object> (line 4243) | struct external_constructor<value_t::object>
        method construct (line 4246) | static void construct(BasicJsonType& j, const typename BasicJsonTy...
        method construct (line 4254) | static void construct(BasicJsonType& j, typename BasicJsonType::ob...
        method construct (line 4263) | static void construct(BasicJsonType& j, const CompatibleObjectType...
      function to_json (line 4280) | void to_json(BasicJsonType& j, T b) noexcept
      function to_json (line 4287) | void to_json(BasicJsonType& j, const CompatibleString& s)
      function to_json (line 4293) | void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
      function to_json (line 4300) | void to_json(BasicJsonType& j, FloatType val) noexcept
      function to_json (line 4307) | void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noe...
      function to_json (line 4314) | void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noex...
      function to_json (line 4321) | void to_json(BasicJsonType& j, EnumType e) noexcept
      function to_json (line 4328) | void to_json(BasicJsonType& j, const std::vector<bool>& e)
      function to_json (line 4341) | void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
      function to_json (line 4347) | void to_json(BasicJsonType& j, const typename BasicJsonType::binary_...
      function to_json (line 4354) | void to_json(BasicJsonType& j, const std::valarray<T>& arr)
      function to_json (line 4360) | void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
      function to_json (line 4367) | void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
      function to_json (line 4373) | void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
      function to_json (line 4383) | void to_json(BasicJsonType& j, const T(&arr)[N])
      function to_json (line 4389) | void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
      function to_json (line 4397) | void to_json(BasicJsonType& j, const T& b)
      function to_json_tuple_impl (line 4403) | void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequ...
      function to_json (line 4409) | void to_json(BasicJsonType& j, const T& t)
      type to_json_fn (line 4414) | struct to_json_fn
      function combine (line 4662) | inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
      function hash (line 4680) | std::size_t hash(const BasicJsonType& j)
      type input_format_t (line 4812) | enum class input_format_t { json, cbor, msgpack, ubjson, bson }
      class file_input_adapter (line 4822) | class file_input_adapter
        method file_input_adapter (line 4828) | explicit file_input_adapter(std::FILE* f) noexcept
        method file_input_adapter (line 4833) | file_input_adapter(const file_input_adapter&) = delete;
        method file_input_adapter (line 4834) | file_input_adapter(file_input_adapter&&) = default;
        method file_input_adapter (line 4835) | file_input_adapter& operator=(const file_input_adapter&) = delete;
        method file_input_adapter (line 4836) | file_input_adapter& operator=(file_input_adapter&&) = delete;
        method get_character (line 4838) | std::char_traits<char>::int_type get_character() noexcept
      class input_stream_adapter (line 4858) | class input_stream_adapter
        method input_stream_adapter (line 4873) | explicit input_stream_adapter(std::istream& i)
        method input_stream_adapter (line 4878) | input_stream_adapter(const input_stream_adapter&) = delete;
        method input_stream_adapter (line 4879) | input_stream_adapter& operator=(input_stream_adapter&) = delete;
        method input_stream_adapter (line 4880) | input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
        method input_stream_adapter (line 4882) | input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs...
        method get_character (line 4891) | std::char_traits<char>::int_type get_character()
      class iterator_input_adapter (line 4911) | class iterator_input_adapter
        method iterator_input_adapter (line 4916) | iterator_input_adapter(IteratorType first, IteratorType last)
        method get_character (line 4919) | typename std::char_traits<char_type>::int_type get_character()
        method empty (line 4940) | bool empty() const
      type wide_string_input_helper (line 4949) | struct wide_string_input_helper
      type wide_string_input_helper<BaseInputAdapter, 4> (line 4952) | struct wide_string_input_helper<BaseInputAdapter, 4>
        method fill_buffer (line 4955) | static void fill_buffer(BaseInputAdapter& input,
      type wide_string_input_helper<BaseInputAdapter, 2> (line 5010) | struct wide_string_input_helper<BaseInputAdapter, 2>
        method fill_buffer (line 5013) | static void fill_buffer(BaseInputAdapter& input,
      class wide_string_input_adapter (line 5073) | class wide_string_input_adapter
        method wide_string_input_adapter (line 5078) | wide_string_input_adapter(BaseInputAdapter base)
        method get_character (line 5081) | typename std::char_traits<char>::int_type get_character() noexcept
        method fill_buffer (line 5102) | void fill_buffer()
      type iterator_input_adapter_factory (line 5118) | struct iterator_input_adapter_factory
        method adapter_type (line 5124) | static adapter_type create(IteratorType first, IteratorType last)
      type is_iterator_of_multibyte (line 5131) | struct is_iterator_of_multibyte
      type iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>> (line 5141) | struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_i...
        method adapter_type (line 5148) | static adapter_type create(IteratorType first, IteratorType last)
      function input_adapter (line 5156) | typename iterator_input_adapter_factory<IteratorType>::adapter_type ...
      function input_adapter (line 5164) | auto input_adapter(const ContainerType& container) -> decltype(input...
      function file_input_adapter (line 5174) | inline file_input_adapter input_adapter(std::FILE* file)
        method file_input_adapter (line 4828) | explicit file_input_adapter(std::FILE* f) noexcept
        method file_input_adapter (line 4833) | file_input_adapter(const file_input_adapter&) = delete;
        method file_input_adapter (line 4834) | file_input_adapter(file_input_adapter&&) = default;
        method file_input_adapter (line 4835) | file_input_adapter& operator=(const file_input_adapter&) = delete;
        method file_input_adapter (line 4836) | file_input_adapter& operator=(file_input_adapter&&) = delete;
        method get_character (line 4838) | std::char_traits<char>::int_type get_character() noexcept
      function input_stream_adapter (line 5179) | inline input_stream_adapter input_adapter(std::istream& stream)
        method input_stream_adapter (line 4873) | explicit input_stream_adapter(std::istream& i)
        method input_stream_adapter (line 4878) | input_stream_adapter(const input_stream_adapter&) = delete;
        method input_stream_adapter (line 4879) | input_stream_adapter& operator=(input_stream_adapter&) = delete;
        method input_stream_adapter (line 4880) | input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
        method input_stream_adapter (line 4882) | input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs...
        method get_character (line 4891) | std::char_traits<char>::int_type get_character()
      function input_stream_adapter (line 5184) | inline input_stream_adapter input_adapter(std::istream&& stream)
        method input_stream_adapter (line 4873) | explicit input_stream_adapter(std::istream& i)
        method input_stream_adapter (line 4878) | input_stream_adapter(const input_stream_adapter&) = delete;
        method input_stream_adapter (line 4879) | input_stream_adapter& operator=(input_stream_adapter&) = delete;
        method input_stream_adapter (line 4880) | input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
        method input_stream_adapter (line 4882) | input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs...
        method get_character (line 4891) | std::char_traits<char>::int_type get_character()
      function contiguous_bytes_input_adapter (line 5199) | contiguous_bytes_input_adapter input_adapter(CharT b)
      function input_adapter (line 5207) | auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, a...
      class span_input_adapter (line 5215) | class span_input_adapter
        method span_input_adapter (line 5224) | span_input_adapter(CharT b, std::size_t l)
        method span_input_adapter (line 5231) | span_input_adapter(IteratorType first, IteratorType last)
        method contiguous_bytes_input_adapter (line 5234) | contiguous_bytes_input_adapter&& get()
      class json_sax_dom_parser (line 5396) | class json_sax_dom_parser
        method json_sax_dom_parser (line 5410) | explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_ex...
        method json_sax_dom_parser (line 5415) | json_sax_dom_parser(const json_sax_dom_parser&) = delete;
        method json_sax_dom_parser (line 5416) | json_sax_dom_parser(json_sax_dom_parser&&) = default;
        method json_sax_dom_parser (line 5417) | json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
        method json_sax_dom_parser (line 5418) | json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
        method null (line 5421) | bool null()
        method boolean (line 5427) | bool boolean(bool val)
        method number_integer (line 5433) | bool number_integer(number_integer_t val)
        method number_unsigned (line 5439) | bool number_unsigned(number_unsigned_t val)
        method number_float (line 5445) | bool number_float(number_float_t val, const string_t& /*unused*/)
        method string (line 5451) | bool string(string_t& val)
        method binary (line 5457) | bool binary(binary_t& val)
        method start_object (line 5463) | bool start_object(std::size_t len)
        method key (line 5476) | bool key(string_t& val)
        method end_object (line 5483) | bool end_object()
        method start_array (line 5489) | bool start_array(std::size_t len)
        method end_array (line 5502) | bool end_array()
        method parse_error (line 5509) | bool parse_error(std::size_t /*unused*/, const std::string& /*unus...
        method is_errored (line 5521) | constexpr bool is_errored() const
        method JSON_HEDLEY_RETURNS_NON_NULL (line 5534) | JSON_HEDLEY_RETURNS_NON_NULL
      class json_sax_dom_callback_parser (line 5570) | class json_sax_dom_callback_parser
        method json_sax_dom_callback_parser (line 5581) | json_sax_dom_callback_parser(BasicJsonType& r,
        method json_sax_dom_callback_parser (line 5590) | json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) ...
        method json_sax_dom_callback_parser (line 5591) | json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = def...
        method json_sax_dom_callback_parser (line 5592) | json_sax_dom_callback_parser& operator=(const json_sax_dom_callbac...
        method json_sax_dom_callback_parser (line 5593) | json_sax_dom_callback_parser& operator=(json_sax_dom_callback_pars...
        method null (line 5596) | bool null()
        method boolean (line 5602) | bool boolean(bool val)
        method number_integer (line 5608) | bool number_integer(number_integer_t val)
        method number_unsigned (line 5614) | bool number_unsigned(number_unsigned_t val)
        method number_float (line 5620) | bool number_float(number_float_t val, const string_t& /*unused*/)
        method string (line 5626) | bool string(string_t& val)
        method binary (line 5632) | bool binary(binary_t& val)
        method start_object (line 5638) | bool start_object(std::size_t len)
        method key (line 5656) | bool key(string_t& val)
        method end_object (line 5673) | bool end_object()
        method start_array (line 5702) | bool start_array(std::size_t len)
        method end_array (line 5719) | bool end_array()
        method parse_error (line 5748) | bool parse_error(std::size_t /*unused*/, const std::string& /*unus...
        method is_errored (line 5760) | constexpr bool is_errored() const
        method handle_value (line 5782) | std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool...
      class json_sax_acceptor (line 5866) | class json_sax_acceptor
        method null (line 5875) | bool null()
        method boolean (line 5880) | bool boolean(bool /*unused*/)
        method number_integer (line 5885) | bool number_integer(number_integer_t /*unused*/)
        method number_unsigned (line 5890) | bool number_unsigned(number_unsigned_t /*unused*/)
        method number_float (line 5895) | bool number_float(number_float_t /*unused*/, const string_t& /*unu...
        method string (line 5900) | bool string(string_t& /*unused*/)
        method binary (line 5905) | bool binary(binary_t& /*unused*/)
        method start_object (line 5910) | bool start_object(std::size_t /*unused*/ = std::size_t(-1))
        method key (line 5915) | bool key(string_t& /*unused*/)
        method end_object (line 5920) | bool end_object()
        method start_array (line 5925) | bool start_array(std::size_t /*unused*/ = std::size_t(-1))
        method end_array (line 5930) | bool end_array()
        method parse_error (line 5935) | bool parse_error(std::size_t /*unused*/, const std::string& /*unus...
      class lexer_base (line 5973) | class lexer_base
        type token_type (line 5977) | enum class token_type
      class lexer (line 6050) | class lexer : public lexer_base<BasicJsonType>
        method lexer (line 6062) | explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ =...
        method lexer (line 6069) | lexer(const lexer&) = delete;
        method lexer (line 6070) | lexer(lexer&&) = default;
        method lexer (line 6071) | lexer& operator=(lexer&) = delete;
        method lexer (line 6072) | lexer& operator=(lexer&&) = default;
        method JSON_HEDLEY_PURE (line 6081) | JSON_HEDLEY_PURE
        method get_codepoint (line 6108) | int get_codepoint()
        method next_byte_in_range (line 6156) | bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
        method token_type (line 6193) | token_type scan_string()
        method scan_comment (line 6783) | bool scan_comment()
        method strtof (line 6851) | static void strtof(float& f, const char* str, char** endptr) noexcept
        method strtof (line 6857) | static void strtof(double& f, const char* str, char** endptr) noex...
        method strtof (line 6863) | static void strtof(long double& f, const char* str, char** endptr)...
        method token_type (line 6908) | token_type scan_number()  // lgtm [cpp/use-of-goto]
      type is_sax (line 7641) | struct is_sax
      type is_sax_static_asserts (line 7672) | struct is_sax_static_asserts
      type cbor_tag_handler_t (line 7736) | enum class cbor_tag_handler_t
      function little_endianess (line 7749) | static inline bool little_endianess(int num = 1) noexcept
      class binary_reader (line 7763) | class binary_reader
        method binary_reader (line 7780) | explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(...
        method binary_reader (line 7786) | binary_reader(const binary_reader&) = delete;
        method binary_reader (line 7787) | binary_reader(binary_reader&&) = default;
        method binary_reader (line 7788) | binary_reader& operator=(const binary_reader&) = delete;
        method binary_reader (line 7789) | binary_reader& operator=(binary_reader&&) = default;
        method JSON_HEDLEY_NON_NULL (line 7800) | JSON_HEDLEY_NON_NULL(3)
        method parse_bson_internal (line 7862) | bool parse_bson_internal()
        method get_bson_cstr (line 7887) | bool get_bson_cstr(string_t& result)
        method get_bson_string (line 7917) | bool get_bson_string(const NumberType len, string_t& result)
        method get_bson_binary (line 7938) | bool get_bson_binary(const NumberType len, binary_t& result)
        method parse_bson_element_internal (line 7964) | bool parse_bson_element_internal(const char_int_type element_type,
        method parse_bson_element_list (line 8042) | bool parse_bson_element_list(const bool is_array)
        method parse_bson_array (line 8080) | bool parse_bson_array()
        method parse_cbor_internal (line 8110) | bool parse_cbor_internal(const bool get_char,
        method get_cbor_string (line 8556) | bool get_cbor_string(string_t& result)
        method get_cbor_binary (line 8651) | bool get_cbor_binary(binary_t& result)
        method get_cbor_array (line 8745) | bool get_cbor_array(const std::size_t len,
        method get_cbor_object (line 8783) | bool get_cbor_object(const std::size_t len,
        method parse_msgpack_internal (line 8836) | bool parse_msgpack_internal()
        method get_msgpack_string (line 9216) | bool get_msgpack_string(string_t& result)
        method get_msgpack_binary (line 9298) | bool get_msgpack_binary(binary_t& result)
        method get_msgpack_array (line 9409) | bool get_msgpack_array(const std::size_t len)
        method get_msgpack_object (line 9431) | bool get_msgpack_object(const std::size_t len)
        method parse_ubjson_internal (line 9468) | bool parse_ubjson_internal(const bool get_char = true)
        method get_ubjson_string (line 9487) | bool get_ubjson_string(string_t& result, const bool get_char = true)
        method get_ubjson_size_value (line 9541) | bool get_ubjson_size_value(std::size_t& result)
        method get_ubjson_size_type (line 9618) | bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& r...
        method get_ubjson_value (line 9659) | bool get_ubjson_value(const char_int_type prefix)
        method get_ubjson_array (line 9760) | bool get_ubjson_array()
        method get_ubjson_object (line 9822) | bool get_ubjson_object()
        method get_ubjson_high_precision_number (line 9897) | bool get_ubjson_high_precision_number()
        method char_int_type (line 9959) | char_int_type get()
        method char_int_type (line 9968) | char_int_type get_ignore_noop()
        method get_number (line 9993) | bool get_number(const input_format_t format, NumberType& result)
        method get_string (line 10036) | bool get_string(const input_format_t format,
        method get_binary (line 10069) | bool get_binary(const input_format_t format,
        method JSON_HEDLEY_NON_NULL (line 10092) | JSON_HEDLEY_NON_NULL(3)
        method get_token_string (line 10106) | std::string get_token_string() const
        method exception_message (line 10119) | std::string exception_message(const input_format_t format,
      type parse_event_t (line 10206) | enum class parse_event_t : uint8_t
      class parser (line 10232) | class parser
        method parser (line 10243) | explicit parser(InputAdapterType&& adapter,
        method parse (line 10265) | void parse(const bool strict, BasicJsonType& result)
        method accept (line 10326) | bool accept(const bool strict = true)
        method sax_parse (line 10334) | bool sax_parse(SAX* sax, const bool strict = true)
        method sax_parse_internal (line 10354) | bool sax_parse_internal(SAX* sax)
        method token_type (line 10636) | token_type get_token()
        method exception_message (line 10641) | std::string exception_message(const token_type expected, const std...
      class primitive_iterator_t (line 10705) | class primitive_iterator_t
        method difference_type (line 10717) | constexpr difference_type get_value() const noexcept
        method set_begin (line 10723) | void set_begin() noexcept
        method set_end (line 10729) | void set_end() noexcept
        method is_begin (line 10735) | constexpr bool is_begin() const noexcept
        method is_end (line 10741) | constexpr bool is_end() const noexcept
        method primitive_iterator_t (line 10756) | primitive_iterator_t operator+(difference_type n) noexcept
        method difference_type (line 10763) | constexpr difference_type operator-(primitive_iterator_t lhs, prim...
        method primitive_iterator_t (line 10768) | primitive_iterator_t& operator++() noexcept
        method primitive_iterator_t (line 10774) | primitive_iterator_t const operator++(int) noexcept
        method primitive_iterator_t (line 10781) | primitive_iterator_t& operator--() noexcept
        method primitive_iterator_t (line 10787) | primitive_iterator_t const operator--(int) noexcept
        method primitive_iterator_t (line 10794) | primitive_iterator_t& operator+=(difference_type n) noexcept
        method primitive_iterator_t (line 10800) | primitive_iterator_t& operator-=(difference_type n) noexcept
      type internal_iterator (line 10820) | struct internal_iterator
      class iteration_proxy (line 10858) | class iteration_proxy
        method iteration_proxy (line 4004) | explicit iteration_proxy(typename IteratorType::reference cont) no...
        method begin (line 4008) | iteration_proxy_value<IteratorType> begin() noexcept
        method end (line 4014) | iteration_proxy_value<IteratorType> end() noexcept
      class iteration_proxy_value (line 10859) | class iteration_proxy_value
        method iteration_proxy_value (line 3931) | explicit iteration_proxy_value(IteratorType it) noexcept : anchor(...
        method iteration_proxy_value (line 3934) | iteration_proxy_value& operator*()
        method iteration_proxy_value (line 3940) | iteration_proxy_value& operator++()
        method string_type (line 3961) | const string_type& key() const
        method value (line 3989) | typename IteratorType::reference value() const
      function set_end (line 10878) | class iter_impl
      class json_re
Copy disabled (too large) Download .json
Condensed preview — 284 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (18,171K chars).
[
  {
    "path": ".gitignore",
    "chars": 34,
    "preview": "**/__pycache__\nbuild/\npython/dist\n"
  },
  {
    "path": "CMakeLists.txt",
    "chars": 571,
    "preview": "cmake_minimum_required(VERSION 3.10)\nproject(GraphFuzz VERSION 1.0)\n\nset(CMAKE_CXX_STANDARD 17)\nset(CMAKE_CXX_STANDARD_R"
  },
  {
    "path": "LICENSE",
    "chars": 1054,
    "preview": "Copyright 2022 Harrison Green\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this soft"
  },
  {
    "path": "README.md",
    "chars": 13634,
    "preview": "# GraphFuzz: _Library API Fuzzing with Lifetime-aware Dataflow Graphs_\n\nGraphFuzz is an experimental framework for build"
  },
  {
    "path": "cli/README.md",
    "chars": 278,
    "preview": "# Graphfuzz command line interface\n\n## Usage:\n\n## Crash minimization\n\n```sh\n$ gfuzz min <fuzzer> <crash>\n```\n\n## Doxygen"
  },
  {
    "path": "cli/gfuzz/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "cli/gfuzz/api.py",
    "chars": 1078,
    "preview": "\nimport os\nimport yaml\n\nfrom parser import parse_sig\n\n\nclass API(object):\n    def __init__(self, fpath):\n        self.fp"
  },
  {
    "path": "cli/gfuzz/cli.py",
    "chars": 516,
    "preview": "\nimport argparse\n\n\nfrom .commands import COMMANDS\n\n\ndef main():\n    parser = argparse.ArgumentParser(description='GraphF"
  },
  {
    "path": "cli/gfuzz/commands/__init__.py",
    "chars": 202,
    "preview": "\nfrom .minimizer import MinAPI\nfrom .doxygen.extractor import DoxygenAPI\nfrom .schema import SchemaAPI\nfrom .gen.gen imp"
  },
  {
    "path": "cli/gfuzz/commands/cliopt.py",
    "chars": 550,
    "preview": "\nclass CLIOpt(object):\n    def __init__(self, name, help_str, register_fn, execute_fn):\n        self._name = name\n      "
  },
  {
    "path": "cli/gfuzz/commands/doxygen/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "cli/gfuzz/commands/doxygen/docker/Dockerfile",
    "chars": 176,
    "preview": "\nFROM ubuntu:20.04\n\nRUN apt-get -y update && \\\n    apt-get -y upgrade && \\\n    apt-get -y install doxygen git python3\n\nW"
  },
  {
    "path": "cli/gfuzz/commands/doxygen/docker/in/Doxyfile.template",
    "chars": 319,
    "preview": "EXTRACT_ALL = YES\nEXTRACT_STATIC = YES\nEXTRACT_LOCAL_CLASSES = YES\nEXTRACT_LOCAL_METHODS = YES\n\nINPUT = {input}\nRECURSIV"
  },
  {
    "path": "cli/gfuzz/commands/doxygen/docker/in/run.py",
    "chars": 573,
    "preview": "#!/usr/bin/python3\n\nimport argparse\nimport os\nimport subprocess\n\n\ndef _run_doxygen(inputs):\n    template = open('/src/in"
  },
  {
    "path": "cli/gfuzz/commands/doxygen/extractor.py",
    "chars": 1334,
    "preview": "\nimport argparse\nimport os\nimport pathlib\nimport subprocess\n\n\nfrom ... import docker_util\nfrom ..cliopt import CLIOpt\n\n\n"
  },
  {
    "path": "cli/gfuzz/commands/gen/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "cli/gfuzz/commands/gen/cpp/README.md",
    "chars": 1732,
    "preview": "\n\n# C++ harness generation\n\n## Overview\n\nA C++ schema can be broken down into two components: `types` and `scopes`.\n\nA `"
  },
  {
    "path": "cli/gfuzz/commands/gen/cpp/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "cli/gfuzz/commands/gen/cpp/base_schema.yaml",
    "chars": 1340,
    "preview": "simple_int:\n  type: simple\n  context_size: 4\n  name: int\nsimple_float:\n  type: simple\n  context_size: 4\n  name: float\nsi"
  },
  {
    "path": "cli/gfuzz/commands/gen/cpp/cpp_sig.py",
    "chars": 6451,
    "preview": "\"\"\"\nUtilities for parsing Cpp-like signatures.\n\"\"\"\nfrom dataclasses import dataclass\nfrom typing import Set, Optional, L"
  },
  {
    "path": "cli/gfuzz/commands/gen/cpp/gen_cpp.py",
    "chars": 44063,
    "preview": "\nimport enum\nimport pathlib\nfrom typing import List, Tuple, Set, Dict\nimport json\nimport re\nimport yaml\n\nfrom gfuzz.comm"
  },
  {
    "path": "cli/gfuzz/commands/gen/cpp/test_cpp_sig.py",
    "chars": 4197,
    "preview": "\nimport unittest\n\nfrom .cpp_sig import parse_signature, CPPArgument, CPPTypeModifier, CPPBaseType, CPPArgName\n\n\n\nclass T"
  },
  {
    "path": "cli/gfuzz/commands/gen/gen.py",
    "chars": 493,
    "preview": "\nfrom ..cliopt import CLIOpt\nfrom .cpp.gen_cpp import GenCppAPI\n\n\nCOMMANDS = [\n    GenCppAPI\n]\n\nOPTIONS = {\n    k._name:"
  },
  {
    "path": "cli/gfuzz/commands/minimizer.py",
    "chars": 2853,
    "preview": "\nimport subprocess\nimport random\n\nfrom .cliopt import CLIOpt\n\n\ndef template_for(word):\n    if word.startswith('0x'):\n   "
  },
  {
    "path": "cli/gfuzz/commands/schema.py",
    "chars": 4723,
    "preview": "\nimport pathlib\nfrom typing import Tuple\nimport yaml\n\n\nimport bs4\nfrom bs4 import BeautifulSoup as BS\nimport tqdm\n\n\nfrom"
  },
  {
    "path": "cli/gfuzz/docker_util.py",
    "chars": 1064,
    "preview": "\nimport pathlib\nimport subprocess\n\n\ndef check_docker():\n    \"\"\"Check if docker is available as a shell command.\"\"\"\n    r"
  },
  {
    "path": "cli/gfuzz/schema.py",
    "chars": 2724,
    "preview": "\nfrom typing import Set\nimport yaml\n\n\ndef _validate_obj(name: str, obj: dict, orig_path: str) -> dict:\n    if not 'type'"
  },
  {
    "path": "cli/pyproject.toml",
    "chars": 460,
    "preview": "[tool.poetry]\nname = \"gfuzz\"\nversion = \"1.0.0\"\ndescription = \"\"\nauthors = [\"hgarrereyn\"]\n\n[tool.poetry.dependencies]\npyt"
  },
  {
    "path": "core/build_tests.sh",
    "chars": 179,
    "preview": "\nclang++ -o schemaTest \\\n    schemaTest.cpp \\\n    -pthread \\\n    -lgtest\n\nclang++ -o graphTest \\\n    graphTest.cpp \\\n   "
  },
  {
    "path": "core/graph.hpp",
    "chars": 29745,
    "preview": "\n#include <algorithm>\n#include <fstream>\n#include <iostream>\n#include <setjmp.h>\n#include <signal.h>\n#include <sstream>\n"
  },
  {
    "path": "core/graph.proto",
    "chars": 2346,
    "preview": "\nsyntax = \"proto3\";\n\n// A NodeRef identifies a doubly-linked connection between neighboring nodes.\n//\n// For example, gi"
  },
  {
    "path": "core/graphTest.cpp",
    "chars": 2808,
    "preview": "\n#include \"graph.hpp\"\n\n#include <gtest/gtest.h>\n\n\nTEST(graph, fillTerminal) {\n    Schema schema = Schema::FromString(R\"("
  },
  {
    "path": "core/harness.cpp",
    "chars": 14510,
    "preview": "\n#include \"graph.hpp\"\n\n#include <sys/types.h>\n#include <unistd.h>\n#include <time.h>\n\n#ifdef TRACE_MUTATIONS\n#include <op"
  },
  {
    "path": "core/ignorelist.txt",
    "chars": 63,
    "preview": "\n# Ignore GraphFuzz core files\nsrc:.*graphfuzz/src/harness.cpp\n"
  },
  {
    "path": "core/json.hpp",
    "chars": 929927,
    "preview": "/*\n    __ _____ _____ _____\n __|  |   __|     |   | |  JSON for Modern C++\n|  |  |__   |  |  | | | |  version 3.9.1\n|___"
  },
  {
    "path": "core/schema.hpp",
    "chars": 23257,
    "preview": "\n#include <algorithm>\n#include <fstream>\n#include <iostream>\n#include <setjmp.h>\n#include <signal.h>\n#include <sstream>\n"
  },
  {
    "path": "core/schemaTest.cpp",
    "chars": 8242,
    "preview": "\n#include \"schema.hpp\"\n#include <gtest/gtest.h>\n\n\nTEST(schema, simple_valid) {\n    Schema schema = Schema::FromString(R\""
  },
  {
    "path": "docs/.nojekyll",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/README.md",
    "chars": 13546,
    "preview": "# GraphFuzz: _Library API Fuzzing with Lifetime-aware Dataflow Graphs_\n\nGraphFuzz is an experimental framework for build"
  },
  {
    "path": "docs/_sidebar.md",
    "chars": 309,
    "preview": "* GraphFuzz\n    * [Overview](/)\n* Quick Start\n    * [0. Installation](quick_start/installation.md)\n    * [1. Basic Usage"
  },
  {
    "path": "docs/experiments/overview.md",
    "chars": 2021,
    "preview": "\n# Experiments\n\nWe have created a collection of experiments that demonstrate how to use GraphFuzz with toy examples and "
  },
  {
    "path": "docs/index.html",
    "chars": 1012,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>GraphFuzz</title>\n  <meta http-equiv=\"X-UA-Com"
  },
  {
    "path": "docs/quick_start/basic_usage.md",
    "chars": 17733,
    "preview": "\n# Basic Usage\n\n> Follow along with the `hello_graphfuzz` experiment. See [experiments/overview.md](experiments/overview"
  },
  {
    "path": "docs/quick_start/endpoints.md",
    "chars": 4623,
    "preview": "\n# Endpoints\n\nEndpoints are the fundamental building block of a GraphFuzz harness. In the previous section, we used some"
  },
  {
    "path": "docs/quick_start/installation.md",
    "chars": 796,
    "preview": "\n# Installation\n\n## Package managers\n\nTODO\n\n## Build from source:\n\nClone the repository:\n\n```bash\ngit clone https://gith"
  },
  {
    "path": "docs/schema_format.md",
    "chars": 4247,
    "preview": "\n# Schema Format\n\nA GraphFuzz schema is a key-value mapping of schema objects written in YAML:\n\n```yaml\nobject1:\n    typ"
  },
  {
    "path": "experiments/README.md",
    "chars": 575,
    "preview": "\n# GraphFuzz Experiments\n\nAll images are built on the `graphfuzz_base` image described in `./base/Dockerfile`.\n\nRun `./b"
  },
  {
    "path": "experiments/base/Dockerfile",
    "chars": 776,
    "preview": "FROM ubuntu:18.04\nENV TERM xterm-256color\n\nRUN apt-get update && \\\n    apt-get -y upgrade && \\\n    apt-get -y install \\\n"
  },
  {
    "path": "experiments/build",
    "chars": 808,
    "preview": "#!/usr/bin/env python3\nimport argparse\nfrom pathlib import Path\nimport subprocess\nfrom typing import List\n\ndef run(args)"
  },
  {
    "path": "experiments/custom_endpoints/Dockerfile",
    "chars": 254,
    "preview": "FROM graphfuzz_base\n\nRUN apt-get -y update && apt-get -y install clang++-10\n\nCOPY in /harness/in\nWORKDIR /harness/in\n\nen"
  },
  {
    "path": "experiments/custom_endpoints/in/build.sh",
    "chars": 239,
    "preview": "\ngfuzz gen cpp schema.yaml .\n\nclang++-10 \\\n    -o fuzz_exec \\\n    fuzz_exec.cpp \\\n    -fsanitize=fuzzer \\\n    -lprotobuf"
  },
  {
    "path": "experiments/custom_endpoints/in/lib.h",
    "chars": 435,
    "preview": "\n#include <cstring>\n#include <vector>\n\nclass Foo {\npublic:\n    Foo(): buffer(0) {}\n\n    void write(char val) {\n        b"
  },
  {
    "path": "experiments/custom_endpoints/in/schema.yaml",
    "chars": 127,
    "preview": "\n\nFoo:\n  type: struct\n  name: Foo\n  headers: [lib.h]\n  methods:\n  - Foo()\n  - ~Foo()\n  - void write(char val)\n  - void c"
  },
  {
    "path": "experiments/eigen/Dockerfile",
    "chars": 320,
    "preview": "FROM graphfuzz_base\n\nRUN apt-get -y update && apt-get -y install clang++-10\n\nWORKDIR /src\nRUN git clone https://gitlab.c"
  },
  {
    "path": "experiments/eigen/in/build.sh",
    "chars": 397,
    "preview": "# Usage: ./build.sh <fuzzer>\n\necho \"Building $1 exec...\"\nclang++-10 -g \\\n    -std=c++17 \\\n    $1/fuzz_exec.cpp \\\n    -I/"
  },
  {
    "path": "experiments/eigen/in/f1/fuzz_exec.cpp",
    "chars": 18364,
    "preview": "#include <Eigen/Dense>\n\n\n#include <string.h>\n#include <stdlib.h>\n#include <cstdint>\n\nextern \"C\" int graphfuzz_try();\next"
  },
  {
    "path": "experiments/eigen/in/f1/fuzz_write.cpp",
    "chars": 31319,
    "preview": "\n\n#include <string.h>\n#include <string>\n#include <iostream>\n\nunsigned long CURR_ID = 0;\n\nextern \"C\" void __attribute__(("
  },
  {
    "path": "experiments/eigen/in/f1/schema.json",
    "chars": 4701,
    "preview": "{\"types\": [{\"id\": 0, \"name\": \"Eigen::MatrixXf\"}, {\"id\": 1, \"name\": \"Eigen::VectorXf\"}], \"scopes\": [{\"name\": \"set\", \"inpu"
  },
  {
    "path": "experiments/eigen/in/f1/schema.yaml",
    "chars": 1713,
    "preview": "\n\nstruct_MatrixXf:\n  headers:\n  - <Eigen/Dense>\n  default_destructor: true\n  type: struct\n  name: Eigen::MatrixXf\n  meth"
  },
  {
    "path": "experiments/eigen/in/test.sh",
    "chars": 219,
    "preview": "./build.sh f1\n\ncd f1 && \\\nmkdir -p artifacts && mkdir -p corpus && \\\n./fuzz_exec --graphfuzz_init_corpus ./corpus && \\\n."
  },
  {
    "path": "experiments/ex_array_demo/Dockerfile",
    "chars": 191,
    "preview": "FROM graphfuzz_base\n\nCOPY in /harness/in\nWORKDIR /harness/in\n\nRUN ./build_lib.sh && ./build.sh\n\nENV ASAN_OPTIONS=detect_"
  },
  {
    "path": "experiments/ex_array_demo/in/build.sh",
    "chars": 291,
    "preview": "\ncd fuzz\n\nclang++ \\\n    fuzz_exec.cpp \\\n    -I../lib -L../lib \\\n    -ltest -lgraphfuzz -lprotobuf \\\n    -fsanitize=fuzze"
  },
  {
    "path": "experiments/ex_array_demo/in/build_lib.sh",
    "chars": 58,
    "preview": "\ncd lib\nclang++ -c lib.cpp\nllvm-ar-6.0 rc libtest.a lib.o\n"
  },
  {
    "path": "experiments/ex_array_demo/in/fuzz/fuzz_exec.cpp",
    "chars": 1951,
    "preview": "#include \"lib.h\"\n\n\n#include <string.h>\n#include <stdlib.h>\n#include <cstdint>\n\nextern \"C\" int graphfuzz_try();\n\nextern \""
  },
  {
    "path": "experiments/ex_array_demo/in/fuzz/fuzz_write.cpp",
    "chars": 4155,
    "preview": "\n\n#include <string.h>\n#include <string>\n#include <iostream>\n\nunsigned long CURR_ID = 0;\n\nextern \"C\" void __attribute__(("
  },
  {
    "path": "experiments/ex_array_demo/in/fuzz/schema.json",
    "chars": 338,
    "preview": "{\"types\": [{\"id\": 0, \"name\": \"Test\"}], \"scopes\": [{\"name\": \"fuzz1\", \"inputs\": [0], \"outputs\": [0], \"context\": 16}, {\"nam"
  },
  {
    "path": "experiments/ex_array_demo/in/fuzz/schema.yaml",
    "chars": 410,
    "preview": "\nstruct_Test:\n  type: struct\n  name: Test\n  default_destructor: true\n  headers:\n  - lib.h\n  methods:\n  - Test()\n  - fuzz"
  },
  {
    "path": "experiments/ex_array_demo/in/lib/lib.cpp",
    "chars": 18,
    "preview": "\n#include \"lib.h\"\n"
  },
  {
    "path": "experiments/ex_array_demo/in/lib/lib.h",
    "chars": 168,
    "preview": "\n\nclass Test {\npublic:\n    Test() {}\n    void fuzz1(int a[4]) {\n        if (a[2] == 3 && a[3] == 4) __builtin_trap();\n  "
  },
  {
    "path": "experiments/ex_auto_cpp/Dockerfile",
    "chars": 189,
    "preview": "FROM graphfuzz_base\n\nCOPY in /harness/in\n\nRUN cd /harness/in && \\\n    ./build_lib.sh && \\\n    ./build.sh\n\nWORKDIR /harne"
  },
  {
    "path": "experiments/ex_auto_cpp/README.md",
    "chars": 2168,
    "preview": "\n# Auto C++ example\n\nThis folder contains an example of using the gfuzz doxygen extractor to automatically generate a C+"
  },
  {
    "path": "experiments/ex_auto_cpp/in/auto_schema.yaml",
    "chars": 729,
    "preview": "enum_PointType:\n  headers:\n  - point.h\n  name: PointType\n  type: enum\n  values:\n  - POINT_SMALL\n  - POINT_LARGE\n  - POIN"
  },
  {
    "path": "experiments/ex_auto_cpp/in/build.sh",
    "chars": 291,
    "preview": "\ncd fuzz\n\nclang++ \\\n    fuzz_exec.cpp \\\n    -I../lib -L../lib \\\n    -ltest -lgraphfuzz -lprotobuf \\\n    -fsanitize=fuzze"
  },
  {
    "path": "experiments/ex_auto_cpp/in/build_lib.sh",
    "chars": 54,
    "preview": "\ncd lib\nclang++ -c *.cpp\nllvm-ar-6.0 rc libtest.a *.o\n"
  },
  {
    "path": "experiments/ex_auto_cpp/in/fuzz/fuzz_exec.cpp",
    "chars": 5389,
    "preview": "#include \"point.h\"\n#include \"rect.h\"\n\n\n#include <string.h>\n#include <stdlib.h>\n#include <cstdint>\n\nextern \"C\" int graphf"
  },
  {
    "path": "experiments/ex_auto_cpp/in/fuzz/fuzz_write.cpp",
    "chars": 8632,
    "preview": "\n\n#include <string.h>\n#include <string>\n#include <iostream>\n\nunsigned long CURR_ID = 0;\n\nextern \"C\" void __attribute__(("
  },
  {
    "path": "experiments/ex_auto_cpp/in/fuzz/schema.json",
    "chars": 1197,
    "preview": "{\"types\": [{\"id\": 1, \"name\": \"Point\"}, {\"id\": 2, \"name\": \"Rect\"}], \"scopes\": [{\"name\": \"(auto) Point::Point(point_coord "
  },
  {
    "path": "experiments/ex_auto_cpp/in/lib/point.cpp",
    "chars": 111,
    "preview": "#include \"point.h\"\n\nvoid Point::offset(point_coord _x, point_coord _y) {\n    this->x += x;\n    this->y += y;\n}\n"
  },
  {
    "path": "experiments/ex_auto_cpp/in/lib/point.h",
    "chars": 414,
    "preview": "\n#pragma once\n\ntypedef int point_coord;\n\nenum PointType {\n    POINT_SMALL,\n    POINT_LARGE,\n    POINT_CRASH,\n};\n\nstruct "
  },
  {
    "path": "experiments/ex_auto_cpp/in/lib/rect.cpp",
    "chars": 493,
    "preview": "\n#include <cstdlib>\n#include <cassert>\n#include <iostream>\n\n#include \"rect.h\"\n\n\nvoid Rect::fuzzFunc(int z) {\n    if (z !"
  },
  {
    "path": "experiments/ex_auto_cpp/in/lib/rect.h",
    "chars": 278,
    "preview": "\n#pragma once\n\n#include \"point.h\"\n\nstruct Rect {\nprivate:\n    Point a, b;\n    float val;\n\npublic:\n    Rect(): a(0,0), b("
  },
  {
    "path": "experiments/ex_auto_cpp/make_schema.sh",
    "chars": 534,
    "preview": "#!/bin/bash\n\n# Context is graphfuzz/experiments/ex_auto_cpp\npdir=$( cd \"$(dirname \"${BASH_SOURCE[0]}\")\" ; pwd -P )\ncd \"$"
  },
  {
    "path": "experiments/hello_graphfuzz/Dockerfile",
    "chars": 254,
    "preview": "FROM graphfuzz_base\n\nRUN apt-get -y update && apt-get -y install clang++-10\n\nCOPY in /harness/in\nWORKDIR /harness/in\n\nen"
  },
  {
    "path": "experiments/hello_graphfuzz/in/build.sh",
    "chars": 239,
    "preview": "\ngfuzz gen cpp schema.yaml .\n\nclang++-10 \\\n    -o fuzz_exec \\\n    fuzz_exec.cpp \\\n    -fsanitize=fuzzer \\\n    -lprotobuf"
  },
  {
    "path": "experiments/hello_graphfuzz/in/lib.h",
    "chars": 435,
    "preview": "\n#include <cstring>\n#include <vector>\n\nclass Foo {\npublic:\n    Foo(): buffer(0) {}\n\n    void write(char val) {\n        b"
  },
  {
    "path": "experiments/hello_graphfuzz/in/schema.yaml",
    "chars": 127,
    "preview": "\n\nFoo:\n  type: struct\n  name: Foo\n  headers: [lib.h]\n  methods:\n  - Foo()\n  - ~Foo()\n  - void write(char val)\n  - void c"
  },
  {
    "path": "experiments/hello_graphfuzz/in/schema_verbose.yaml",
    "chars": 473,
    "preview": "\n\nFoo:\n  type: struct\n  name: Foo\n  headers: [lib.h]\n  methods:\n  - Foo():\n      outputs: ['Foo']\n      exec: |\n        "
  },
  {
    "path": "experiments/iowow/Dockerfile",
    "chars": 503,
    "preview": "FROM graphfuzz_base\n\nRUN apt-get -y update && apt-get -y install clang++-10\n\nRUN git clone https://github.com/Softmotion"
  },
  {
    "path": "experiments/iowow/in/bug.sh",
    "chars": 65,
    "preview": "\nclang -g \\\n    $1 \\\n    -liowow -fsanitize=address \\\n    -o out\n"
  },
  {
    "path": "experiments/iowow/in/bugs/bug1.c",
    "chars": 328,
    "preview": "\n#include <iowow/iwkv.h>\n\nint main() {\n    IWKV kv;\n    IWKV_OPTS opts = {\n        .path = \"test.db\",\n        .oflags = "
  },
  {
    "path": "experiments/iowow/in/bugs/bug2.c",
    "chars": 462,
    "preview": "\n#include <iowow/iwkv.h>\n\nint main() {\n    IWKV kv;\n    IWKV_OPTS opts = {\n        .path = \"test.db\",\n        .oflags = "
  },
  {
    "path": "experiments/iowow/in/build.sh",
    "chars": 361,
    "preview": "# Usage: ./build.sh <fuzzer>\n\necho \"Building $1 exec...\"\nclang++-10 -g \\\n    $1/fuzz_exec.cpp \\\n    -I. \\\n    -fsanitize"
  },
  {
    "path": "experiments/iowow/in/db_tracker.h",
    "chars": 684,
    "preview": "\n#include <iowow/iwkv.h>\n#include <vector>\n#include <cstdio>\n#include <string>\n\nusing namespace std;\n\nstatic vector<IWKV"
  },
  {
    "path": "experiments/iowow/in/f1/fuzz_exec.cpp",
    "chars": 6741,
    "preview": "#include \"db_tracker.h\"\n#include <iowow/iwkv.h>\n\n\n#include <string.h>\n#include <stdlib.h>\n#include <cstdint>\n\nextern \"C\""
  },
  {
    "path": "experiments/iowow/in/f1/fuzz_write.cpp",
    "chars": 12514,
    "preview": "\n\n#include <string.h>\n#include <string>\n#include <iostream>\n\nunsigned long CURR_ID = 0;\n\nextern \"C\" void __attribute__(("
  },
  {
    "path": "experiments/iowow/in/f1/schema.json",
    "chars": 1405,
    "preview": "{\"types\": [{\"id\": 3, \"name\": \"IWKV\"}, {\"id\": 4, \"name\": \"IWDB\"}, {\"id\": 5, \"name\": \"IWKV_val\"}, {\"id\": 6, \"name\": \"IWKV_"
  },
  {
    "path": "experiments/iowow/in/f1/schema.yaml",
    "chars": 3169,
    "preview": "\nconfig:\n  type: config\n  finalizer: |\n    close_all();\n\ntypedef_iwkv_opflags:\n  type: typedef\n  value: uint8_t\n  name: "
  },
  {
    "path": "experiments/iowow/in/test.sh",
    "chars": 119,
    "preview": "\n./build.sh f1\n\ncd f1 && \\\nmkdir artifacts && \\\n./fuzz_exec -fork=32 -ignore_crashes=1 -artifact_prefix=\"./artifacts/\"\n"
  },
  {
    "path": "experiments/rdkit/Dockerfile",
    "chars": 857,
    "preview": "FROM graphfuzz_base\n\nWORKDIR /src\nENV CMAKE_VERSION 3.19.2\nRUN apt-get update && apt-get install -y wget sudo && \\\n    w"
  },
  {
    "path": "experiments/rdkit/build_rdkit.sh",
    "chars": 1713,
    "preview": "\nexport SRC=/src\n\n# Build zlib\ngit clone --depth 1 -b master https://github.com/madler/zlib.git $SRC/zlib\ncd $SRC/zlib\nO"
  },
  {
    "path": "experiments/rdkit/in/Fuzz/build.sh",
    "chars": 2060,
    "preview": "\nexport BOOSTHOME=/src/boost_1_69_0/boost\nexport RDBASE=/src/rdkit\n\nexport CPPFLAGS=\"-I${BOOSTHOME} -I${RDBASE}/Code -fs"
  },
  {
    "path": "experiments/rdkit/in/Fuzz/fuzz_exec.cpp",
    "chars": 93833,
    "preview": "#include <Geometry/point.h>\n#include <GraphMol/Atom.h>\n#include <GraphMol/Bond.h>\n#include <GraphMol/Conformer.h>\n#inclu"
  },
  {
    "path": "experiments/rdkit/in/Fuzz/fuzz_write.cpp",
    "chars": 150409,
    "preview": "\n\n#include <string.h>\n#include <string>\n#include <iostream>\n\nunsigned long CURR_ID = 0;\n\nextern \"C\" void __attribute__(("
  },
  {
    "path": "experiments/rdkit/in/Fuzz/schema.json",
    "chars": 21561,
    "preview": "{\"types\": [{\"id\": 5, \"name\": \"bundle<Conformer,ROMol>\"}, {\"id\": 6, \"name\": \"RDKit::ROMol\"}, {\"id\": 7, \"name\": \"bundle<Bo"
  },
  {
    "path": "experiments/rdkit/in/Fuzz/schema.yaml",
    "chars": 17903,
    "preview": "\n\nenum_RDKit::Bond::BondType:\n  type: enum\n  name: RDKit::Bond::BondType\n  values:\n  - UNSPECIFIED\n  - SINGLE\n  - DOUBLE"
  },
  {
    "path": "experiments/rdkit/in/bugs/README.md",
    "chars": 1302,
    "preview": "# Bugs\n\n### bug1: SEGV in RWMol::commitBatchEdit (https://github.com/rdkit/rdkit/issues/4122)\n\n```\nAfter certain sequenc"
  },
  {
    "path": "experiments/rdkit/in/bugs/bug1.cpp",
    "chars": 860,
    "preview": "#include <GraphMol/RWMol.h>\n\n\n#define MAKE(t) static_cast<t *>(calloc(sizeof(t), 1))\n\nstruct GFUZZ_BUNDLE {\npublic:\n    "
  },
  {
    "path": "experiments/rdkit/in/bugs/bug1.py",
    "chars": 121,
    "preview": "\nfrom rdkit.Chem import AllChem as Chem\n\nm = Chem.RWMol()\nm.BeginBatchEdit()\nm.AddAtom(Chem.Atom(1))\nm.CommitBatchEdit()"
  },
  {
    "path": "experiments/rdkit/in/bugs/bug1_min.cpp",
    "chars": 167,
    "preview": "#include <GraphMol/RWMol.h>\n\nint main() {\n    RDKit::RWMol *mol = new RDKit::RWMol();\n    mol->beginBatchEdit();\n    mol"
  },
  {
    "path": "experiments/rdkit/in/bugs/bug2.cpp",
    "chars": 924,
    "preview": "\n#include <GraphMol/RWMol.h>\n#include <GraphMol/Atom.h>\n\n\n#define MAKE(t) static_cast<t *>(calloc(sizeof(t), 1))\n\nstruct"
  },
  {
    "path": "experiments/rdkit/in/bugs/bug2_min.cpp",
    "chars": 425,
    "preview": "\n#include <GraphMol/RWMol.h>\n#include <GraphMol/Atom.h>\n\n#include <iostream>\n\n#define MAKE(t) dynamic_cast<t *>(static_c"
  },
  {
    "path": "experiments/rdkit/in/bugs/bug3.cpp",
    "chars": 1053,
    "preview": "#include <GraphMol/Atom.h>\n#include <GraphMol/Bond.h>\n#include <GraphMol/ROMol.h>\n#include <GraphMol/RWMol.h>\n\n\n#define "
  },
  {
    "path": "experiments/rdkit/in/bugs/bug3_min.cpp",
    "chars": 290,
    "preview": "\n#include <GraphMol/Atom.h>\n#include <GraphMol/Bond.h>\n#include <GraphMol/ROMol.h>\n#include <GraphMol/RWMol.h>\n\n\nint mai"
  },
  {
    "path": "experiments/rdkit/in/bugs/bug4.cpp",
    "chars": 1512,
    "preview": "#include <GraphMol/Atom.h>\n#include <GraphMol/Bond.h>\n#include <GraphMol/ROMol.h>\n#include <GraphMol/RWMol.h>\n\n\n#define "
  },
  {
    "path": "experiments/rdkit/in/bugs/bug4_min.cpp",
    "chars": 482,
    "preview": "#include <GraphMol/Atom.h>\n#include <GraphMol/RWMol.h>\n\nint main() {\n    RDKit::RWMol *mol1 = new RDKit::RWMol();\n    RD"
  },
  {
    "path": "experiments/rdkit/in/bugs/bug4_min2.cpp",
    "chars": 447,
    "preview": "#include <GraphMol/Atom.h>\n#include <GraphMol/Bond.h>\n#include <GraphMol/ROMol.h>\n#include <GraphMol/RWMol.h>\n\n\nvoid foo"
  },
  {
    "path": "experiments/rdkit/in/bugs/bug5.cpp",
    "chars": 928,
    "preview": "#include \"<GraphMol/Atom.h>\"\n#include \"<GraphMol/Bond.h>\"\n#include \"<GraphMol/ROMol.h>\"\n#include \"<GraphMol/RWMol.h>\"\n\n\n"
  },
  {
    "path": "experiments/rdkit/in/bugs/bug5_min.cpp",
    "chars": 188,
    "preview": "#include <GraphMol/Atom.h>\n#include <GraphMol/ROMol.h>\n\nint main() {\n    RDKit::Atom *atom = new RDKit::Atom();\n    RDKi"
  },
  {
    "path": "experiments/rdkit/in/bugs/bug6.cpp",
    "chars": 1202,
    "preview": "#include <GraphMol/Atom.h>\n#include <GraphMol/Bond.h>\n#include <GraphMol/ROMol.h>\n#include <GraphMol/RWMol.h>\n\n\n#define "
  },
  {
    "path": "experiments/rdkit/in/bugs/bug6_min.cpp",
    "chars": 320,
    "preview": "#include <GraphMol/Bond.h>\n#include <GraphMol/RWMol.h>\n\nint main() {\n    RDKit::RWMol *mol = new RDKit::RWMol();\n    RDK"
  },
  {
    "path": "experiments/rdkit/in/bugs/bug7.cpp",
    "chars": 1415,
    "preview": "#include <Geometry/point.h>\n#include <GraphMol/Atom.h>\n#include <GraphMol/Bond.h>\n#include <GraphMol/Conformer.h>\n#inclu"
  },
  {
    "path": "experiments/rdkit/in/bugs/bug7_min.cpp",
    "chars": 1308,
    "preview": "#include <Geometry/point.h>\n#include <GraphMol/Atom.h>\n#include <GraphMol/Bond.h>\n#include <GraphMol/Conformer.h>\n#inclu"
  },
  {
    "path": "experiments/rdkit/in/bugs/bug8.cpp",
    "chars": 1842,
    "preview": "#include \"<Geometry/point.h>\"\n#include \"<GraphMol/Atom.h>\"\n#include \"<GraphMol/Bond.h>\"\n#include \"<GraphMol/Conformer.h>"
  },
  {
    "path": "experiments/rdkit/in/bugs/bug9.cpp",
    "chars": 1888,
    "preview": "#include <Geometry/point.h>\n#include <GraphMol/Atom.h>\n#include <GraphMol/Bond.h>\n#include <GraphMol/Conformer.h>\n#inclu"
  },
  {
    "path": "experiments/rdkit/in/bugs/bug9_min.cpp",
    "chars": 223,
    "preview": "#include <Geometry/point.h>\n#include <GraphMol/Conformer.h>\n\nint main() {\n    RDKit::Conformer *conf = new RDKit::Confor"
  },
  {
    "path": "experiments/rdkit/in/example/build.sh",
    "chars": 1331,
    "preview": "\nexport BOOSTHOME=/src/boost_1_69_0/boost\nexport RDBASE=/src/rdkit\n\nexport CPPFLAGS=\"-I${BOOSTHOME} -I${RDBASE}/Code -fs"
  },
  {
    "path": "experiments/rdkit/in/example/test.cpp",
    "chars": 452,
    "preview": "\n#include <GraphMol/RDKitBase.h>\n#include <GraphMol/SmilesParse/SmilesParse.h>\n#include <GraphMol/SmilesParse/SmilesWrit"
  },
  {
    "path": "experiments/rdkit/in/launch.sh",
    "chars": 38,
    "preview": "nohup ./test.sh ./Fuzz 40 > out.log &\n"
  },
  {
    "path": "experiments/rdkit/in/make.sh",
    "chars": 1324,
    "preview": "\nexport BOOSTHOME=/src/boost_1_69_0/boost\nexport RDBASE=/src/rdkit\n\nexport CPPFLAGS=\"-I${BOOSTHOME} -I${RDBASE}/Code -fs"
  },
  {
    "path": "experiments/rdkit/in/raw_schema.yaml",
    "chars": 780479,
    "preview": "enum_DistanceMethod:\n  headers:\n  - PickerHelpers.h\n  name: DistanceMethod\n  type: enum\n  values:\n  - TANIMOTO\n  - DICE\n"
  },
  {
    "path": "experiments/rdkit/in/test.sh",
    "chars": 220,
    "preview": "\ncd $1\n\n./build.sh\n\nmkdir -p corpus\nmkdir -p artifacts\n\n./fuzz_exec \\\n    --graphfuzz_trace_mutations \\\n    ./corpus \\\n "
  },
  {
    "path": "experiments/rdkit_demo/Dockerfile",
    "chars": 1122,
    "preview": "FROM graphfuzz_base\n\nWORKDIR /src\nENV CMAKE_VERSION 3.19.2\nRUN apt-get update && apt-get install -y wget sudo && \\\n    w"
  },
  {
    "path": "experiments/rdkit_demo/build_rdkit.sh",
    "chars": 1713,
    "preview": "\nexport SRC=/src\n\n# Build zlib\ngit clone --depth 1 -b master https://github.com/madler/zlib.git $SRC/zlib\ncd $SRC/zlib\nO"
  },
  {
    "path": "experiments/rdkit_demo/in/build.sh",
    "chars": 270,
    "preview": "\ngfuzz gen cpp schema.yaml .\n\nsource ./set_flags.sh\n\nclang++ fuzz_exec.cpp -o fuzz_exec ${CPPFLAGS} ${LDFLAGS} -fsanitiz"
  },
  {
    "path": "experiments/rdkit_demo/in/demo.cpp",
    "chars": 653,
    "preview": "\n#include <GraphMol/RWMol.h>\n#include <GraphMol/Atom.h>\n\n#include <iostream>\n\nint main() {\n    RDKit::RWMol mol;\n\n    RD"
  },
  {
    "path": "experiments/rdkit_demo/in/schema.yaml",
    "chars": 834,
    "preview": "\nstruct_RWMol:\n  type: struct\n  name: RDKit::RWMol\n  alloc_with_new: true\n  headers: ['<GraphMol/RWMol.h>']\n  methods:\n "
  },
  {
    "path": "experiments/rdkit_demo/in/set_flags.sh",
    "chars": 1258,
    "preview": "export BOOSTHOME=/src/boost_1_69_0/boost\nexport RDBASE=/src/rdkit\nexport CPPFLAGS=\"-I${BOOSTHOME} -I${RDBASE}/Code -fsan"
  },
  {
    "path": "experiments/run",
    "chars": 513,
    "preview": "#!/usr/bin/env python3\nimport argparse\nfrom pathlib import Path\nimport subprocess\nfrom typing import List\n\ndef run(args)"
  },
  {
    "path": "experiments/skia/Dockerfile",
    "chars": 4010,
    "preview": "FROM graphfuzz_base\n\nRUN apt-get -y update && apt-get -y install \\\n    autoconf libtool libc6-dbg \\\n    ninja-build libl"
  },
  {
    "path": "experiments/skia/README.md",
    "chars": 237,
    "preview": "# Skia\n\nSkia is a graphics library maintained by Google and used in Chromium and Android. In this experiment, we create "
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_image_filter/fuzz_exec.cpp",
    "chars": 240671,
    "preview": "#include \"Sk1DPathEffect.h\"\n#include \"Sk2DPathEffect.h\"\n#include \"SkBlendMode.h\"\n#include \"SkBlurTypes.h\"\n#include \"SkCa"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_image_filter/fuzz_write.cpp",
    "chars": 397648,
    "preview": "\n\n#include <string.h>\n#include <string>\n#include <iostream>\n\nunsigned long CURR_ID = 0;\n\nextern \"C\" void __attribute__(("
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_image_filter/schema.json",
    "chars": 42607,
    "preview": "{\"types\": [{\"id\": 0, \"name\": \"harness\"}, {\"id\": 22, \"name\": \"SkPoint\"}, {\"id\": 23, \"name\": \"SkIRect\"}, {\"id\": 24, \"name\""
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_image_filter/schema.yaml",
    "chars": 382,
    "preview": "include:\n- \"../schema.yaml\"\n\nstruct_harness:\n  type: struct\n  name: harness\n  headers:\n  - SkPaint.h\n  static_methods:\n "
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_mock_gpu_canvas/BUILD.gn",
    "chars": 85556,
    "preview": "# Copyright 2016 Google Inc.\n#\n# Use of this source code is governed by a BSD-style license that can be\n# found in the L"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_mock_gpu_canvas/README.md",
    "chars": 246,
    "preview": "\nI found it difficult to link to the correct gpu dependencies outside of the Skia build system.\n\nTo build this harness, "
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_mock_gpu_canvas/build.sh",
    "chars": 1467,
    "preview": "export CXX=\"/root/clang/bin/clang++\"\n\n\necho \"[*] Reset build tree...\"\nrm -rf /src/skia/graphfuzz\nmkdir /src/skia/graphfu"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_mock_gpu_canvas/fuzz_exec.cpp",
    "chars": 290751,
    "preview": "#include \"Sk1DPathEffect.h\"\n#include \"Sk2DPathEffect.h\"\n#include \"SkBlendMode.h\"\n#include \"SkBlurTypes.h\"\n#include \"SkCa"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_mock_gpu_canvas/fuzz_write.cpp",
    "chars": 478213,
    "preview": "\n\n#include <string.h>\n#include <string>\n#include <iostream>\n\nunsigned long CURR_ID = 0;\n\nextern \"C\" void __attribute__(("
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_mock_gpu_canvas/schema.json",
    "chars": 49611,
    "preview": "{\"types\": [{\"id\": 0, \"name\": \"bundle<SkCanvas,SkSurface>\"}, {\"id\": 1, \"name\": \"foo\"}, {\"id\": 23, \"name\": \"SkPoint\"}, {\"i"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_mock_gpu_canvas/schema.yaml",
    "chars": 1132,
    "preview": "include:\n- \"../schema.yaml\"\n\nbundle<SkCanvas,SkSurface>:\n  type: bundle\n  name: bundle<SkCanvas,SkSurface>\n  active: SkC"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_null_canvas/fuzz_exec.cpp",
    "chars": 290232,
    "preview": "#include \"Sk1DPathEffect.h\"\n#include \"Sk2DPathEffect.h\"\n#include \"SkBlendMode.h\"\n#include \"SkBlurTypes.h\"\n#include \"SkCa"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_null_canvas/fuzz_write.cpp",
    "chars": 477596,
    "preview": "\n\n#include <string.h>\n#include <string>\n#include <iostream>\n\nunsigned long CURR_ID = 0;\n\nextern \"C\" void __attribute__(("
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_null_canvas/schema.json",
    "chars": 49610,
    "preview": "{\"types\": [{\"id\": 0, \"name\": \"bundle<SkCanvas,SkNullCanvas>\"}, {\"id\": 1, \"name\": \"foo\"}, {\"id\": 23, \"name\": \"SkPoint\"}, "
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_null_canvas/schema.yaml",
    "chars": 632,
    "preview": "include:\n- \"../schema.yaml\"\n\nbundle<SkCanvas,SkNullCanvas>:\n  type: bundle\n  name: bundle<SkCanvas,SkNullCanvas>\n  activ"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_raster_n32_canvas/fuzz_exec.cpp",
    "chars": 290231,
    "preview": "#include \"Sk1DPathEffect.h\"\n#include \"Sk2DPathEffect.h\"\n#include \"SkBlendMode.h\"\n#include \"SkBlurTypes.h\"\n#include \"SkCa"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_raster_n32_canvas/fuzz_write.cpp",
    "chars": 477595,
    "preview": "\n\n#include <string.h>\n#include <string>\n#include <iostream>\n\nunsigned long CURR_ID = 0;\n\nextern \"C\" void __attribute__(("
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_raster_n32_canvas/schema.json",
    "chars": 49607,
    "preview": "{\"types\": [{\"id\": 0, \"name\": \"bundle<SkCanvas,SkSurface>\"}, {\"id\": 1, \"name\": \"foo\"}, {\"id\": 23, \"name\": \"SkPoint\"}, {\"i"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_raster_n32_canvas/schema.yaml",
    "chars": 616,
    "preview": "include:\n- \"../schema.yaml\"\n\nbundle<SkCanvas,SkSurface>:\n  type: bundle\n  name: bundle<SkCanvas,SkSurface>\n  active: SkC"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_svg_canvas/fuzz_exec.cpp",
    "chars": 290334,
    "preview": "#include \"Sk1DPathEffect.h\"\n#include \"Sk2DPathEffect.h\"\n#include \"SkBlendMode.h\"\n#include \"SkBlurTypes.h\"\n#include \"SkCa"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_svg_canvas/fuzz_write.cpp",
    "chars": 477714,
    "preview": "\n\n#include <string.h>\n#include <string>\n#include <iostream>\n\nunsigned long CURR_ID = 0;\n\nextern \"C\" void __attribute__(("
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_svg_canvas/schema.json",
    "chars": 49604,
    "preview": "{\"types\": [{\"id\": 0, \"name\": \"bundle<SkCanvas,parent>\"}, {\"id\": 1, \"name\": \"foo\"}, {\"id\": 23, \"name\": \"SkPoint\"}, {\"id\":"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/api_svg_canvas/schema.yaml",
    "chars": 721,
    "preview": "include:\n- \"../schema.yaml\"\n\nbundle<SkCanvas,parent>:\n  type: bundle\n  name: bundle<SkCanvas,parent>\n  active: SkCanvas\n"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/build_baseline.sh",
    "chars": 760,
    "preview": "\necho \"[*] Build baseline fuzzer.\"\n/root/clang/bin/clang++ \\\n    /src/skia/fuzz/FuzzDrawFunctions.cpp \\\n    /src/skia/fu"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/fuzz_exec.cpp",
    "chars": 210882,
    "preview": "#include \"./fuzz_util.h\"\n#include \"Sk1DPathEffect.h\"\n#include \"Sk2DPathEffect.h\"\n#include \"SkBlendMode.h\"\n#include \"SkBl"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/fuzz_util.h",
    "chars": 4629,
    "preview": "\n#include \"SkTypes.h\"\n#include \"include/private/SkTFitsIn.h\"\n#include \"include/core/SkFontTypes.h\"\n#include \"include/pri"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/fuzz_write.cpp",
    "chars": 345577,
    "preview": "\n\n#include <string>\n#include <iostream>\n\nunsigned long CURR_ID = 0;\n\nextern \"C\" void shim_init() {\n    CURR_ID = 0;\n\n   "
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/image_filter_deserialize/fuzz_exec.cpp",
    "chars": 241235,
    "preview": "#include \"Sk1DPathEffect.h\"\n#include \"Sk2DPathEffect.h\"\n#include \"SkBlendMode.h\"\n#include \"SkBlurTypes.h\"\n#include \"SkCa"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/image_filter_deserialize/fuzz_write.cpp",
    "chars": 398996,
    "preview": "\n\n#include <string.h>\n#include <string>\n#include <iostream>\n\nunsigned long CURR_ID = 0;\n\nextern \"C\" void __attribute__(("
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/image_filter_deserialize/schema.json",
    "chars": 42610,
    "preview": "{\"types\": [{\"id\": 0, \"name\": \"harness\"}, {\"id\": 22, \"name\": \"SkPoint\"}, {\"id\": 23, \"name\": \"SkIRect\"}, {\"id\": 24, \"name\""
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/image_filter_deserialize/schema.yaml",
    "chars": 984,
    "preview": "include:\n- \"../schema.yaml\"\n\nstruct_harness:\n  type: struct\n  name: harness\n  headers:\n  - SkPaint.h\n  static_methods:\n "
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/schema.json",
    "chars": 42519,
    "preview": "{\"types\": [{\"id\": 21, \"name\": \"SkPoint\"}, {\"id\": 22, \"name\": \"SkIRect\"}, {\"id\": 23, \"name\": \"SkISize\"}, {\"id\": 24, \"name"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzCanvas/schema.yaml",
    "chars": 44395,
    "preview": "\ntypedef_SkScalar:\n  headers:\n  - SkScalar.h\n  name: SkScalar\n  type: typedef\n  value: float\n\ntypedef_SkColor:\n  headers"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzDrawFunctions/build_baseline.sh",
    "chars": 760,
    "preview": "\necho \"[*] Build baseline fuzzer.\"\n/root/clang/bin/clang++ \\\n    /src/skia/fuzz/FuzzDrawFunctions.cpp \\\n    /src/skia/fu"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzDrawFunctions/fuzz_exec.cpp",
    "chars": 48491,
    "preview": "#include \"SkBitmap.h\"\n#include \"SkBlendMode.h\"\n#include \"SkCanvas.h\"\n#include \"SkClipOp.h\"\n#include \"SkFilterQuality.h\"\n"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzDrawFunctions/fuzz_write.cpp",
    "chars": 75661,
    "preview": "\n\n#include <string.h>\n#include <string>\n#include <iostream>\n\nunsigned long CURR_ID = 0;\n\nextern \"C\" void __attribute__(("
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzDrawFunctions/schema.json",
    "chars": 9650,
    "preview": "{\"types\": [{\"id\": 12, \"name\": \"SkPaint\"}, {\"id\": 13, \"name\": \"SkImageInfo\"}, {\"id\": 14, \"name\": \"SkBitmap\"}, {\"id\": 15, "
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzDrawFunctions/schema.yaml",
    "chars": 9344,
    "preview": "# This schema mirrors the api used in fuzz/FuzzDrawFunctions.cpp\n\nenum_SkBlendMode:\n  headers:\n  - SkBlendMode.h\n  name:"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzPathMeasure/fuzz_exec.cpp",
    "chars": 9714,
    "preview": "#include \"include/core/SkPath.h\"\n#include \"include/core/SkPathMeasure.h\"\n#include \"include/core/SkPoint.h\"\n#include \"inc"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzPathMeasure/fuzz_write.cpp",
    "chars": 15451,
    "preview": "\n\n#include <string.h>\n#include <string>\n#include <iostream>\n\nunsigned long CURR_ID = 0;\n\nextern \"C\" void __attribute__(("
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzPathMeasure/schema.json",
    "chars": 2324,
    "preview": "{\"types\": [{\"id\": 1, \"name\": \"SkPath\"}, {\"id\": 2, \"name\": \"SkPathMeasure\"}, {\"id\": 3, \"name\": \"SkRect\"}, {\"id\": 4, \"name"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzPathMeasure/schema.yaml",
    "chars": 1428,
    "preview": "\ntypedef_SkScalar:\n  headers:\n  - SkScalar.h\n  name: SkScalar\n  type: typedef\n  value: float\n\nstruct_SkPath:\n  type: str"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzPathOp/fuzz_exec.cpp",
    "chars": 11571,
    "preview": "#include \"include/core/SkPath.h\"\n#include \"include/core/SkPathTypes.h\"\n#include \"include/core/SkRect.h\"\n#include \"includ"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzPathOp/fuzz_write.cpp",
    "chars": 18577,
    "preview": "\n\n#include <string.h>\n#include <string>\n#include <iostream>\n\nunsigned long CURR_ID = 0;\n\nextern \"C\" void __attribute__(("
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzPathOp/schema.json",
    "chars": 2528,
    "preview": "{\"types\": [{\"id\": 1, \"name\": \"SkPath\"}, {\"id\": 2, \"name\": \"SkOpBuilder\"}, {\"id\": 3, \"name\": \"SkRect\"}], \"scopes\": [{\"nam"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzPathOp/schema.yaml",
    "chars": 1664,
    "preview": "\n\ntypedef_SkScalar:\n  headers:\n  - SkScalar.h\n  name: SkScalar\n  type: typedef\n  value: float\n\nstruct_SkPath:\n  type: st"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzPolyUtils/fuzz_exec.cpp",
    "chars": 4038,
    "preview": "#include \"poly_util.h\"\n\n\n#include <string.h>\n#include <stdlib.h>\n#include <cstdint>\n\nextern \"C\" int graphfuzz_try();\n\nex"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzPolyUtils/fuzz_write.cpp",
    "chars": 6925,
    "preview": "\n\n#include <string.h>\n#include <string>\n#include <iostream>\n\nunsigned long CURR_ID = 0;\n\nextern \"C\" void __attribute__(("
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzPolyUtils/poly_util.h",
    "chars": 1565,
    "preview": "\n#include \"include/core/SkRect.h\"\n#include \"include/core/SkPoint.h\"\n#include \"include/private/SkTemplates.h\"\n#include \"s"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzPolyUtils/schema.json",
    "chars": 973,
    "preview": "{\"types\": [{\"id\": 1, \"name\": \"PolyTester\"}], \"scopes\": [{\"name\": \"PolyTester(int _count, SkScalar coords[1024], uint16_t"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzPolyUtils/schema.yaml",
    "chars": 706,
    "preview": "\ntypedef_SkScalar:\n  headers:\n  - SkScalar.h\n  name: SkScalar\n  type: typedef\n  value: float\n\nstruct_PolyTester:\n  type:"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzRegionOp/fuzz_exec.cpp",
    "chars": 3947,
    "preview": "#include \"include/core/SkRect.h\"\n#include \"include/core/SkRegion.h\"\n\n\n#include <string.h>\n#include <stdlib.h>\n#include <"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzRegionOp/fuzz_write.cpp",
    "chars": 5972,
    "preview": "\n\n#include <string.h>\n#include <string>\n#include <iostream>\n\nunsigned long CURR_ID = 0;\n\nextern \"C\" void __attribute__(("
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzRegionOp/schema.json",
    "chars": 800,
    "preview": "{\"types\": [{\"id\": 0, \"name\": \"SkRegion\"}, {\"id\": 1, \"name\": \"SkIRect\"}], \"scopes\": [{\"name\": \"(auto) SkRegion::SkRegion("
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzRegionOp/schema.yaml",
    "chars": 617,
    "preview": "\nstruct_SkRegion:\n  type: struct\n  name: SkRegion\n  default_destructor: true\n  headers:\n  - include/core/SkRegion.h\n  me"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzRegionSetPath/fuzz_exec.cpp",
    "chars": 31088,
    "preview": "#include \"SkMatrix.h\"\n#include \"SkPath.h\"\n#include \"SkPathTypes.h\"\n#include \"SkRRect.h\"\n#include \"include/core/SkPath.h\""
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzRegionSetPath/fuzz_write.cpp",
    "chars": 51265,
    "preview": "\n\n#include <string.h>\n#include <string>\n#include <iostream>\n\nunsigned long CURR_ID = 0;\n\nextern \"C\" void __attribute__(("
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzRegionSetPath/schema.json",
    "chars": 6594,
    "preview": "{\"types\": [{\"id\": 3, \"name\": \"SkRect\"}, {\"id\": 4, \"name\": \"SkRRect\"}, {\"id\": 5, \"name\": \"SkMatrix\"}, {\"id\": 6, \"name\": \""
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzRegionSetPath/schema.yaml",
    "chars": 4938,
    "preview": "\ntypedef_SkScalar:\n  headers:\n  - SkScalar.h\n  name: SkScalar\n  type: typedef\n  value: float\n\nenum_SkPathDirection:\n  he"
  },
  {
    "path": "experiments/skia/gf_fuzz/FuzzSkParagraph/build.sh",
    "chars": 2260,
    "preview": "\nexport CXXFLAGS=\"\\\n    -std=c++17 \\\n    -fvisibility-inlines-hidden \\\n    -stdlib=libc++ \\\n    -fno-exceptions \\\n    -W"
  }
]

// ... and 84 more files (download for full content)

About this extraction

This page contains the full source code of the hgarrereyn/GraphFuzz GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 284 files (16.7 MB), approximately 4.4M tokens, and a symbol index with 12217 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!