about summary refs log tree commit diff stats
path: root/Source
diff options
context:
orializer/tree/Source/Puzzle.cpp?id=3ece17f201686342e8aff90148f360245788b234#n48'>48#include "json.hpp" 49nlohmann::json newGrid(int width, int height) { 50 using namespace nlohmann; 51 52 json grid; 53 for (int x=0; x<width; x++) { 54 grid[x] = json::array(); 55 for (int y=0; y<height; y++) { 56 if (x%2 == 1 && y%2 == 1) grid[x][y] = json::object(); 57 else grid[x][y] = {{"type", "line"}, {"color", 0}}; 58 } 59 } 60 return grid; 61} 62 63std::string Puzzle::Serialize() { 64 using namespace nlohmann; 65 66 json puzzle; 67 puzzle["grid"] = {}; 68 for (int x=0; x<width; x++) { 69 puzzle["grid"][x] = json::array(); 70 for (int y=0; y<height; y++) { 71 if (x%2 == 1 && y%2 == 1) puzzle["grid"][x][y] = json::object(); 72 else puzzle["grid"][x][y] = {{"type", "line"}, {"color", 0}}; 73 } 74 } 75 puzzle["pillar"] = pillar; 76 if (symmetry == Symmetry::X) puzzle["symmetry"] = {{"x", true}, {"y", false}}; 77 else if (symmetry == Symmetry::Y) puzzle["symmetry"] = {{"x", false}, {"y", true}}; 78 else if (symmetry == Symmetry::XY) puzzle["symmetry"] = {{"x", true}, {"y", true}}; 79 80 for (int x=0; x<width; x++) { 81 for (int y=0; y<height; y++) { 82 const Cell& cell = grid[x][y]; 83 json j = puzzle["grid"][x][y]; 84 if (cell.dot != Cell::Dot::NONE) { 85 if (cell.dot == Cell::Dot::BLACK) j["dot"] = 1; 86 if (cell.dot == Cell::Dot::BLUE) j["dot"] = 2; 87 if (cell.dot == Cell::Dot::YELLOW) j["dot"] = 3; 88 if (cell.dot == Cell::Dot::INVISIBLE) j["dot"] = 4; 89 } else if (cell.gap != Cell::Gap::NONE) { 90 if (cell.gap == Cell::Gap::BREAK) j["gap"] = 1; 91 if (cell.gap == Cell::Gap::FULL) j["gap"] = 2; 92 } else if (cell.decoration != nullptr) { 93 if (cell.decoration->color == Color::Black) j["color"] = "black"; 94 else if (cell.decoration->color == Color::Blue) j["color"] = "blue"; 95 else if (cell.decoration->color == Color::Cyan) j["color"] = "cyan"; 96 else if (cell.decoration->color == Color::Gray) j["color"] = "gray"; 97 else if (cell.decoration->color == Color::Green) j["color"] = "green"; 98 else if (cell.decoration->color == Color::Orange) j["color"] = "orange"; 99 else if (cell.decoration->color == Color::Pink) j["color"] = "pink"; 100 else if (cell.decoration->color == Color::Purple) j["color"] = "purple"; 101 else if (cell.decoration->color == Color::White) j["color"] = "white"; 102 else if (cell.decoration->color == Color::Yellow) j["color"] = "yellow"; 103 104 if (cell.decoration->type == Type::Stone) { 105 j["type"] = "square"; 106 } else if (cell.decoration->type == Type::Star) { 107 j["type"] = "star"; 108 } else if (cell.decoration->type == Type::Poly) { 109 j["type"] = "poly"; 110 j["polyshape"] = cell.decoration->polyshape; 111 } else if (cell.decoration->type == Type::Ylop) { 112 j["type"] = "ylop"; 113 j["polyshape"] = cell.decoration->polyshape; 114 } else if (cell.decoration->type == Type::Nega) { 115 j["type"] = "nega"; 116 } else if (cell.decoration->type == Type::Triangle) { 117 j["type"] = "triangle"; 118 j["count"] = cell.decoration->count; 119 } 120 } 121 122 if (cell.start) j["start"] = true; 123 if (cell.end != Cell::Dir::NONE) { 124 if (cell.end == Cell::Dir::LEFT) j["end"] = "left"; 125 else if (cell.end == Cell::Dir::RIGHT) j["end"] = "right"; 126 else if (cell.end == Cell::Dir::UP) j["end"] = "top"; 127 else if (cell.end == Cell::Dir::DOWN) j["end"] = "bottom"; 128 } 129 puzzle["grid"][x][y] = j; 130 } 131 } 132 133 return puzzle.dump(); 134} 135 48int Puzzle::Mod(int x) const { 136int Puzzle::Mod(int x) const { 49 if (!pillar) return x; 137 if (!pillar) return x; 50 return (x + width * height * 2) % width; 138 return (x + width * height * 2) % width;
diff --git a/Source/Puzzle.h b/Source/Puzzle.h index c2a8fce..6ba6bc1 100644 --- a/Source/Puzzle.h +++ b/Source/Puzzle.h @@ -45,6 +45,7 @@ struct Cell { 45 std::shared_ptr<Decoration> decoration = nullptr; 45 std::shared_ptr<Decoration> decoration = nullptr; 46 46 47 bool start = false; 47 bool start = false; 48 // TODO: Top/bottom 48 enum class Dir {NONE, LEFT, RIGHT, UP, DOWN}; 49 enum class Dir {NONE, LEFT, RIGHT, UP, DOWN}; 49 Dir end = Dir::NONE; 50 Dir end = Dir::NONE; 50 51@@ -92,6 +93,8 @@ public: 92 void NewGrid(int newWidth, int newHeight); 93 void NewGrid(int newWidth, int newHeight); 93 Pos GetSymmetricalPos(int x, int y) const; 94 Pos GetSymmetricalPos(int x, int y) const; 94 95 96 std::string Serialize(); 97 95// private: 98// private: 96 std::vector<std::vector<Cell>> grid; 99 std::vector<std::vector<Cell>> grid; 97 100
diff --git a/Source/PuzzleSerializer.cpp b/Source/PuzzleSerializer.cpp index 3732db8..e316216 100644 --- a/Source/PuzzleSerializer.cpp +++ b/Source/PuzzleSerializer.cpp @@ -179,6 +179,7 @@ void PuzzleSerializer::ReadExtras(Puzzle& p) { 179 179 180void PuzzleSerializer::ReadDecorations(Puzzle& p, int id) { 180void PuzzleSerializer::ReadDecorations(Puzzle& p, int id) { 181 int numDecorations = _memory->ReadEntityData<int>(id, NUM_DECORATIONS, 1)[0]; 181 int numDecorations = _memory->ReadEntityData<int>(id, NUM_DECORATIONS, 1)[0]; 182 if (numDecorations == 0) return; 182 std::vector<int> decorations = _memory->ReadArray<int>(id, DECORATIONS, numDecorations); 183 std::vector<int> decorations = _memory->ReadArray<int>(id, DECORATIONS, numDecorations); 183 if (numDecorations > 0) p.hasDecorations = true; 184 if (numDecorations > 0) p.hasDecorations = true; 184 185@@ -203,6 +204,7 @@ void PuzzleSerializer::ReadDecorations(Puzzle& p, int id) { 203 204 204void PuzzleSerializer::ReadSequence(Puzzle& p, int id) { 205void PuzzleSerializer::ReadSequence(Puzzle& p, int id) { 205 int sequenceLength = _memory->ReadEntityData<int>(id, SEQUENCE_LEN, 1)[0]; 206 int sequenceLength = _memory->ReadEntityData<int>(id, SEQUENCE_LEN, 1)[0]; 207 if (sequenceLength == 0) return; 206 std::vector<int> sequence = _memory->ReadArray<int>(id, SEQUENCE, sequenceLength); 208 std::vector<int> sequence = _memory->ReadArray<int>(id, SEQUENCE, sequenceLength); 207 209 208 for (int location : sequence) { 210 for (int location : sequence) {@@ -545,6 +547,8 @@ std::tuple<int, int> PuzzleSerializer::loc_to_xy(const Puzzle& p, int location) 545 547 546 int x = 2 * (location % width2); 548 int x = 2 * (location % width2); 547 int y = 2 * (height2 - location / width2); 549 int y = 2 * (height2 - location / width2); 550 assert(x >= 0 && x < p.width); 551 assert(y >= 0 && y < p.height); 548 return {x, y}; 552 return {x, y}; 549} 553} 550 554
diff --git a/Source/Random.h b/Source/Random.h index 36b6dc1..e3737ed 100644 --- a/Source/Random.h +++ b/Source/Random.h @@ -17,6 +17,7 @@ public: 17 set[index] = set[setSize-1]; 17 set[index] = set[setSize-1]; 18 setSize--; 18 setSize--; 19 } 19 } 20 assert(selection.size() == count); 20 return selection; 21 return selection; 21 } 22 } 22 23
diff --git a/Source/Randomizer.cpp b/Source/Randomizer.cpp index 01d1e2e..72072a8 100644 --- a/Source/Randomizer.cpp +++ b/Source/Randomizer.cpp @@ -97,6 +97,7 @@ Things to do for V2: 97#include "Panels.h" 97#include "Panels.h" 98#include "Random.h" 98#include "Random.h" 99 99 100 100template <class T> 101template <class T> 101int find(const std::vector<T> &data, T search, size_t startIndex = 0) { 102int find(const std::vector<T> &data, T search, size_t startIndex = 0) { 102 for (size_t i=startIndex ; i<data.size(); i++) { 103 for (size_t i=startIndex ; i<data.size(); i++) {
diff --git a/Source/Source.vcxproj b/Source/Source.vcxproj index 76fdcef..78b5f00 100644 --- a/Source/Source.vcxproj +++ b/Source/Source.vcxproj @@ -162,6 +162,7 @@ 162 </ItemDefinitionGroup> 162 </ItemDefinitionGroup> 163 <ItemGroup> 163 <ItemGroup> 164 <ClInclude Include="ChallengeRandomizer.h" /> 164 <ClInclude Include="ChallengeRandomizer.h" /> 165 <ClInclude Include="json.hpp" /> 165 <ClInclude Include="Memory.h" /> 166 <ClInclude Include="Memory.h" /> 166 <ClInclude Include="MemoryException.h" /> 167 <ClInclude Include="MemoryException.h" /> 167 <ClInclude Include="pch.h" /> 168 <ClInclude Include="pch.h" />
diff --git a/Source/json.hpp b/Source/json.hpp new file mode 100644 index 0000000..06da815 --- /dev/null +++ b/Source/json.hpp @@ -0,0 +1,22875 @@ 1/* 2 __ _____ _____ _____ 3 __| | __| | | | JSON for Modern C++ 4| | |__ | | | | | | version 3.7.3 5|_____|_____|_____|_|___| https://github.com/nlohmann/json 6 7Licensed under the MIT License <http://opensource.org/licenses/MIT>. 8SPDX-License-Identifier: MIT 9Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>. 10 11Permission is hereby granted, free of charge, to any person obtaining a copy 12of this software and associated documentation files (the "Software"), to deal 13in the Software without restriction, including without limitation the rights 14to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15copies of the Software, and to permit persons to whom the Software is 16furnished to do so, subject to the following conditions: 17 18The above copyright notice and this permission notice shall be included in all 19copies or substantial portions of the Software. 20 21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27SOFTWARE. 28*/ 29 30#ifndef INCLUDE_NLOHMANN_JSON_HPP_ 31#define INCLUDE_NLOHMANN_JSON_HPP_ 32 33#define NLOHMANN_JSON_VERSION_MAJOR 3 34#define NLOHMANN_JSON_VERSION_MINOR 7 35#define NLOHMANN_JSON_VERSION_PATCH 3 36 37#include <algorithm> // all_of, find, for_each 38#include <cassert> // assert 39#include <ciso646> // and, not, or 40#include <cstddef> // nullptr_t, ptrdiff_t, size_t 41#include <functional> // hash, less 42#include <initializer_list> // initializer_list 43#include <iosfwd> // istream, ostream 44#include <iterator> // random_access_iterator_tag 45#include <memory> // unique_ptr 46#include <numeric> // accumulate 47#include <string> // string, stoi, to_string 48#include <utility> // declval, forward, move, pair, swap 49#include <vector> // vector 50 51// #include <nlohmann/adl_serializer.hpp> 52 53 54#include <utility> 55 56// #include <nlohmann/detail/conversions/from_json.hpp> 57 58 59#include <algorithm> // transform 60#include <array> // array 61#include <ciso646> // and, not 62#include <forward_list> // forward_list 63#include <iterator> // inserter, front_inserter, end 64#include <map> // map 65#include <string> // string 66#include <tuple> // tuple, make_tuple 67#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible 68#include <unordered_map> // unordered_map 69#include <utility> // pair, declval 70#include <valarray> // valarray 71 72// #include <nlohmann/detail/exceptions.hpp> 73 74 75#include <exception> // exception 76#include <stdexcept> // runtime_error 77#include <string> // to_string 78 79// #include <nlohmann/detail/input/position_t.hpp> 80 81 82#include <cstddef> // size_t 83 84namespace nlohmann 85{ 86namespace detail 87{ 88/// struct to capture the start position of the current token 89struct position_t 90{ 91 /// the total number of characters read 92 std::size_t chars_read_total = 0; 93 /// the number of characters read in the current line 94 std::size_t chars_read_current_line = 0; 95 /// the number of lines read 96 std::size_t lines_read = 0; 97 98 /// conversion to size_t to preserve SAX interface 99 constexpr operator size_t() const 100 { 101 return chars_read_total; 102 } 103}; 104 105} // namespace detail 106} // namespace nlohmann 107 108// #include <nlohmann/detail/macro_scope.hpp> 109 110 111#include <utility> // pair 112// #include <nlohmann/thirdparty/hedley/hedley.hpp> 113/* Hedley - https://nemequ.github.io/hedley 114 * Created by Evan Nemerson <evan@nemerson.com> 115 * 116 * To the extent possible under law, the author(s) have dedicated all 117 * copyright and related and neighboring rights to this software to 118 * the public domain worldwide. This software is distributed without 119 * any warranty. 120 * 121 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>. 122 * SPDX-License-Identifier: CC0-1.0 123 */ 124 125#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 11) 126#if defined(JSON_HEDLEY_VERSION) 127 #undef JSON_HEDLEY_VERSION 128#endif 129#define JSON_HEDLEY_VERSION 11 130 131#if defined(JSON_HEDLEY_STRINGIFY_EX) 132 #undef JSON_HEDLEY_STRINGIFY_EX 133#endif 134#define JSON_HEDLEY_STRINGIFY_EX(x) #x 135 136#if defined(JSON_HEDLEY_STRINGIFY) 137 #undef JSON_HEDLEY_STRINGIFY 138#endif 139#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x) 140 141#if defined(JSON_HEDLEY_CONCAT_EX) 142 #undef JSON_HEDLEY_CONCAT_EX 143#endif 144#define JSON_HEDLEY_CONCAT_EX(a,b) a##b 145 146#if defined(JSON_HEDLEY_CONCAT) 147 #undef JSON_HEDLEY_CONCAT 148#endif 149#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b) 150 151#if defined(JSON_HEDLEY_VERSION_ENCODE) 152 #undef JSON_HEDLEY_VERSION_ENCODE 153#endif 154#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision)) 155 156#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR) 157 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR 158#endif 159#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000) 160 161#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR) 162 #undef JSON_HEDLEY_VERSION_DECODE_MINOR 163#endif 164#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000) 165 166#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION) 167 #undef JSON_HEDLEY_VERSION_DECODE_REVISION 168#endif 169#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000) 170 171#if defined(JSON_HEDLEY_GNUC_VERSION) 172 #undef JSON_HEDLEY_GNUC_VERSION 173#endif 174#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__) 175 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) 176#elif defined(__GNUC__) 177 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0) 178#endif 179 180#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK) 181 #undef JSON_HEDLEY_GNUC_VERSION_CHECK 182#endif 183#if defined(JSON_HEDLEY_GNUC_VERSION) 184 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) 185#else 186 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0) 187#endif 188 189#if defined(JSON_HEDLEY_MSVC_VERSION) 190 #undef JSON_HEDLEY_MSVC_VERSION 191#endif 192#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) 193 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100) 194#elif defined(_MSC_FULL_VER) 195 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10) 196#elif defined(_MSC_VER) 197 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0) 198#endif 199 200#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK) 201 #undef JSON_HEDLEY_MSVC_VERSION_CHECK 202#endif 203#if !defined(_MSC_VER) 204 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0) 205#elif defined(_MSC_VER) && (_MSC_VER >= 1400) 206 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch))) 207#elif defined(_MSC_VER) && (_MSC_VER >= 1200) 208 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch))) 209#else 210 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor))) 211#endif 212 213#if defined(JSON_HEDLEY_INTEL_VERSION) 214 #undef JSON_HEDLEY_INTEL_VERSION 215#endif 216#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) 217 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE) 218#elif defined(__INTEL_COMPILER) 219 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) 220#endif 221 222#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK) 223 #undef JSON_HEDLEY_INTEL_VERSION_CHECK 224#endif 225#if defined(JSON_HEDLEY_INTEL_VERSION) 226 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) 227#else 228 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0) 229#endif 230 231#if defined(JSON_HEDLEY_PGI_VERSION) 232 #undef JSON_HEDLEY_PGI_VERSION 233#endif 234#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__) 235 #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__) 236#endif 237 238#if defined(JSON_HEDLEY_PGI_VERSION_CHECK) 239 #undef JSON_HEDLEY_PGI_VERSION_CHECK 240#endif 241#if defined(JSON_HEDLEY_PGI_VERSION) 242 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) 243#else 244 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0) 245#endif 246 247#if defined(JSON_HEDLEY_SUNPRO_VERSION) 248 #undef JSON_HEDLEY_SUNPRO_VERSION 249#endif 250#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000) 251 #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) 252#elif defined(__SUNPRO_C) 253 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf) 254#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000) 255 #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) 256#elif defined(__SUNPRO_CC) 257 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf) 258#endif 259 260#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK) 261 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK 262#endif 263#if defined(JSON_HEDLEY_SUNPRO_VERSION) 264 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) 265#else 266 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0) 267#endif 268 269#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) 270 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION 271#endif 272#if defined(__EMSCRIPTEN__) 273 #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__) 274#endif 275 276#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK) 277 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK 278#endif 279#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) 280 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) 281#else 282 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0) 283#endif 284 285#if defined(JSON_HEDLEY_ARM_VERSION) 286 #undef JSON_HEDLEY_ARM_VERSION 287#endif 288#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION) 289 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100) 290#elif defined(__CC_ARM) && defined(__ARMCC_VERSION) 291 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100) 292#endif 293 294#if defined(JSON_HEDLEY_ARM_VERSION_CHECK) 295 #undef JSON_HEDLEY_ARM_VERSION_CHECK 296#endif 297#if defined(JSON_HEDLEY_ARM_VERSION) 298 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) 299#else 300 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0) 301#endif 302 303#if defined(JSON_HEDLEY_IBM_VERSION) 304 #undef JSON_HEDLEY_IBM_VERSION 305#endif 306#if defined(__ibmxl__) 307 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__) 308#elif defined(__xlC__) && defined(__xlC_ver__) 309 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff) 310#elif defined(__xlC__) 311 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0) 312#endif 313 314#if defined(JSON_HEDLEY_IBM_VERSION_CHECK) 315 #undef JSON_HEDLEY_IBM_VERSION_CHECK 316#endif 317#if defined(JSON_HEDLEY_IBM_VERSION) 318 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) 319#else 320 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0) 321#endif 322 323#if defined(JSON_HEDLEY_TI_VERSION) 324 #undef JSON_HEDLEY_TI_VERSION 325#endif 326#if defined(__TI_COMPILER_VERSION__) 327 #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) 328#endif 329 330#if defined(JSON_HEDLEY_TI_VERSION_CHECK) 331 #undef JSON_HEDLEY_TI_VERSION_CHECK 332#endif 333#if defined(JSON_HEDLEY_TI_VERSION) 334 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) 335#else 336 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0) 337#endif 338 339#if defined(JSON_HEDLEY_CRAY_VERSION) 340 #undef JSON_HEDLEY_CRAY_VERSION 341#endif 342#if defined(_CRAYC) 343 #if defined(_RELEASE_PATCHLEVEL) 344 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL) 345 #else 346 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0) 347 #endif 348#endif 349 350#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK) 351 #undef JSON_HEDLEY_CRAY_VERSION_CHECK 352#endif 353#if defined(JSON_HEDLEY_CRAY_VERSION) 354 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) 355#else 356 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0) 357#endif 358 359#if defined(JSON_HEDLEY_IAR_VERSION) 360 #undef JSON_HEDLEY_IAR_VERSION 361#endif 362#if defined(__IAR_SYSTEMS_ICC__) 363 #if __VER__ > 1000 364 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000)) 365 #else 366 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(VER / 100, __VER__ % 100, 0) 367 #endif 368#endif 369 370#if defined(JSON_HEDLEY_IAR_VERSION_CHECK) 371 #undef JSON_HEDLEY_IAR_VERSION_CHECK 372#endif 373#if defined(JSON_HEDLEY_IAR_VERSION) 374 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) 375#else 376 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0) 377#endif 378 379#if defined(JSON_HEDLEY_TINYC_VERSION) 380 #undef JSON_HEDLEY_TINYC_VERSION 381#endif 382#if defined(__TINYC__) 383 #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100) 384#endif 385 386#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK) 387 #undef JSON_HEDLEY_TINYC_VERSION_CHECK 388#endif 389#if defined(JSON_HEDLEY_TINYC_VERSION) 390 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) 391#else 392 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0) 393#endif 394 395#if defined(JSON_HEDLEY_DMC_VERSION) 396 #undef JSON_HEDLEY_DMC_VERSION 397#endif 398#if defined(__DMC__) 399 #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf) 400#endif 401 402#if defined(JSON_HEDLEY_DMC_VERSION_CHECK) 403 #undef JSON_HEDLEY_DMC_VERSION_CHECK 404#endif 405#if defined(JSON_HEDLEY_DMC_VERSION) 406 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) 407#else 408 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0) 409#endif 410 411#if defined(JSON_HEDLEY_COMPCERT_VERSION) 412 #undef JSON_HEDLEY_COMPCERT_VERSION 413#endif 414#if defined(__COMPCERT_VERSION__) 415 #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100) 416#endif 417 418#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK) 419 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK 420#endif 421#if defined(JSON_HEDLEY_COMPCERT_VERSION) 422 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) 423#else 424 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0) 425#endif 426 427#if defined(JSON_HEDLEY_PELLES_VERSION) 428 #undef JSON_HEDLEY_PELLES_VERSION 429#endif 430#if defined(__POCC__) 431 #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0) 432#endif 433 434#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK) 435 #undef JSON_HEDLEY_PELLES_VERSION_CHECK 436#endif 437#if defined(JSON_HEDLEY_PELLES_VERSION) 438 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) 439#else 440 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0) 441#endif 442 443#if defined(JSON_HEDLEY_GCC_VERSION) 444 #undef JSON_HEDLEY_GCC_VERSION 445#endif 446#if \ 447 defined(JSON_HEDLEY_GNUC_VERSION) && \ 448 !defined(__clang__) && \ 449 !defined(JSON_HEDLEY_INTEL_VERSION) && \ 450 !defined(JSON_HEDLEY_PGI_VERSION) && \ 451 !defined(JSON_HEDLEY_ARM_VERSION) && \ 452 !defined(JSON_HEDLEY_TI_VERSION) && \ 453 !defined(__COMPCERT__) 454 #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION 455#endif 456 457#if defined(JSON_HEDLEY_GCC_VERSION_CHECK) 458 #undef JSON_HEDLEY_GCC_VERSION_CHECK 459#endif 460#if defined(JSON_HEDLEY_GCC_VERSION) 461 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) 462#else 463 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0) 464#endif 465 466#if defined(JSON_HEDLEY_HAS_ATTRIBUTE) 467 #undef JSON_HEDLEY_HAS_ATTRIBUTE 468#endif 469#if defined(__has_attribute) 470 #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute) 471#else 472 #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0) 473#endif 474 475#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE) 476 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE 477#endif 478#if defined(__has_attribute) 479 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute) 480#else 481 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) 482#endif 483 484#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE) 485 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE 486#endif 487#if defined(__has_attribute) 488 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute) 489#else 490 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) 491#endif 492 493#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE) 494 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE 495#endif 496#if \ 497 defined(__has_cpp_attribute) && \ 498 defined(__cplusplus) && \ 499 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) 500 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute) 501#else 502 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0) 503#endif 504 505#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS) 506 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS 507#endif 508#if !defined(__cplusplus) || !defined(__has_cpp_attribute) 509 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) 510#elif \ 511 !defined(JSON_HEDLEY_PGI_VERSION) && \ 512 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \ 513 (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0)) 514 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute) 515#else 516 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) 517#endif 518 519#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE) 520 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE 521#endif 522#if defined(__has_cpp_attribute) && defined(__cplusplus) 523 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) 524#else 525 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) 526#endif 527 528#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE) 529 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE 530#endif 531#if defined(__has_cpp_attribute) && defined(__cplusplus) 532 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) 533#else 534 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) 535#endif 536 537#if defined(JSON_HEDLEY_HAS_BUILTIN) 538 #undef JSON_HEDLEY_HAS_BUILTIN 539#endif 540#if defined(__has_builtin) 541 #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin) 542#else 543 #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0) 544#endif 545 546#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN) 547 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN 548#endif 549#if defined(__has_builtin) 550 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) 551#else 552 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) 553#endif 554 555#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN) 556 #undef JSON_HEDLEY_GCC_HAS_BUILTIN 557#endif 558#if defined(__has_builtin) 559 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) 560#else 561 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) 562#endif 563 564#if defined(JSON_HEDLEY_HAS_FEATURE) 565 #undef JSON_HEDLEY_HAS_FEATURE 566#endif 567#if defined(__has_feature) 568 #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature) 569#else 570 #define JSON_HEDLEY_HAS_FEATURE(feature) (0) 571#endif 572 573#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE) 574 #undef JSON_HEDLEY_GNUC_HAS_FEATURE 575#endif 576#if defined(__has_feature) 577 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) 578#else 579 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) 580#endif 581 582#if defined(JSON_HEDLEY_GCC_HAS_FEATURE) 583 #undef JSON_HEDLEY_GCC_HAS_FEATURE 584#endif 585#if defined(__has_feature) 586 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) 587#else 588 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) 589#endif 590 591#if defined(JSON_HEDLEY_HAS_EXTENSION) 592 #undef JSON_HEDLEY_HAS_EXTENSION 593#endif 594#if defined(__has_extension) 595 #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension) 596#else 597 #define JSON_HEDLEY_HAS_EXTENSION(extension) (0) 598#endif 599 600#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION) 601 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION 602#endif 603#if defined(__has_extension) 604 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) 605#else 606 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) 607#endif 608 609#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION) 610 #undef JSON_HEDLEY_GCC_HAS_EXTENSION 611#endif 612#if defined(__has_extension) 613 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) 614#else 615 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) 616#endif 617 618#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE) 619 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE 620#endif 621#if defined(__has_declspec_attribute) 622 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute) 623#else 624 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0) 625#endif 626 627#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE) 628 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE 629#endif 630#if defined(__has_declspec_attribute) 631 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) 632#else 633 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) 634#endif 635 636#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE) 637 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE 638#endif 639#if defined(__has_declspec_attribute) 640 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) 641#else 642 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) 643#endif 644 645#if defined(JSON_HEDLEY_HAS_WARNING) 646 #undef JSON_HEDLEY_HAS_WARNING 647#endif 648#if defined(__has_warning) 649 #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning) 650#else 651 #define JSON_HEDLEY_HAS_WARNING(warning) (0) 652#endif 653 654#if defined(JSON_HEDLEY_GNUC_HAS_WARNING) 655 #undef JSON_HEDLEY_GNUC_HAS_WARNING 656#endif 657#if defined(__has_warning) 658 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) 659#else 660 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) 661#endif 662 663#if defined(JSON_HEDLEY_GCC_HAS_WARNING) 664 #undef JSON_HEDLEY_GCC_HAS_WARNING 665#endif 666#if defined(__has_warning) 667 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) 668#else 669 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) 670#endif 671 672/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for 673 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ 674#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) 675 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ 676#endif 677#if defined(__cplusplus) && JSON_HEDLEY_HAS_WARNING("-Wc++98-compat") 678# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ 679 JSON_HEDLEY_DIAGNOSTIC_PUSH \ 680 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ 681 xpr \ 682 JSON_HEDLEY_DIAGNOSTIC_POP 683#else 684# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x 685#endif 686 687#if \ 688 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ 689 defined(__clang__) || \ 690 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ 691 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ 692 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ 693 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ 694 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ 695 JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) || \ 696 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \ 697 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \ 698 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \ 699 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR)) 700 #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value) 701#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) 702 #define JSON_HEDLEY_PRAGMA(value) __pragma(value) 703#else 704 #define JSON_HEDLEY_PRAGMA(value) 705#endif 706 707#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH) 708 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH 709#endif 710#if defined(JSON_HEDLEY_DIAGNOSTIC_POP) 711 #undef JSON_HEDLEY_DIAGNOSTIC_POP 712#endif 713#if defined(__clang__) 714 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") 715 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") 716#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) 717 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") 718 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") 719#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) 720 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") 721 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") 722#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) 723 #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push)) 724 #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop)) 725#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) 726 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push") 727 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop") 728#elif JSON_HEDLEY_TI_VERSION_CHECK(8,1,0) 729 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push") 730 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop") 731#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) 732 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") 733 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") 734#else 735 #define JSON_HEDLEY_DIAGNOSTIC_PUSH 736 #define JSON_HEDLEY_DIAGNOSTIC_POP 737#endif 738 739#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED) 740 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED 741#endif 742#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations") 743 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") 744#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) 745 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)") 746#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) 747 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") 748#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) 749 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") 750#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) 751 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996)) 752#elif JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) 753 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718") 754#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus) 755 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)") 756#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus) 757 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)") 758#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) 759 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215") 760#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) 761 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)") 762#else 763 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED 764#endif 765 766#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS) 767 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS 768#endif 769#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") 770 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") 771#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) 772 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)") 773#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) 774 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675") 775#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) 776 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") 777#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) 778 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068)) 779#elif JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) 780 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") 781#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) 782 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161") 783#else 784 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS 785#endif 786 787#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES) 788 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES 789#endif 790#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes") 791 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"") 792#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) 793 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") 794#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) 795 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)") 796#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0) 797 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030)) 798#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) 799 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") 800#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus) 801 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)") 802#elif JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) 803 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173") 804#else 805 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES 806#endif 807 808#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL) 809 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL 810#endif 811#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual") 812 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"") 813#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) 814 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)") 815#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) 816 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") 817#else 818 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL 819#endif 820 821#if defined(JSON_HEDLEY_DEPRECATED) 822 #undef JSON_HEDLEY_DEPRECATED 823#endif 824#if defined(JSON_HEDLEY_DEPRECATED_FOR) 825 #undef JSON_HEDLEY_DEPRECATED_FOR 826#endif 827#if defined(__cplusplus) && (__cplusplus >= 201402L) 828 #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]]) 829 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]]) 830#elif \ 831 JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) || \ 832 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ 833 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ 834 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ 835 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \ 836 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ 837 JSON_HEDLEY_TI_VERSION_CHECK(8,3,0) 838 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since))) 839 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement))) 840#elif \ 841 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \ 842 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ 843 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ 844 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ 845 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) 846 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__)) 847 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__)) 848#elif JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) 849 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since)) 850 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement)) 851#elif \ 852 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ 853 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) 854 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated) 855 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated) 856#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) 857 #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated") 858 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated") 859#else 860 #define JSON_HEDLEY_DEPRECATED(since) 861 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) 862#endif 863 864#if defined(JSON_HEDLEY_UNAVAILABLE) 865 #undef JSON_HEDLEY_UNAVAILABLE 866#endif 867#if \ 868 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \ 869 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \ 870 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) 871 #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since))) 872#else 873 #define JSON_HEDLEY_UNAVAILABLE(available_since) 874#endif 875 876#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT) 877 #undef JSON_HEDLEY_WARN_UNUSED_RESULT 878#endif 879#if defined(__cplusplus) && (__cplusplus >= 201703L) 880 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) 881#elif \ 882 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \ 883 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ 884 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ 885 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ 886 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ 887 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ 888 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) 889 #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) 890#elif defined(_Check_return_) /* SAL */ 891 #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_ 892#else 893 #define JSON_HEDLEY_WARN_UNUSED_RESULT 894#endif 895 896#if defined(JSON_HEDLEY_SENTINEL) 897 #undef JSON_HEDLEY_SENTINEL 898#endif 899#if \ 900 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \ 901 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ 902 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ 903 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) 904 #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position))) 905#else 906 #define JSON_HEDLEY_SENTINEL(position) 907#endif 908 909#if defined(JSON_HEDLEY_NO_RETURN) 910 #undef JSON_HEDLEY_NO_RETURN 911#endif 912#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) 913 #define JSON_HEDLEY_NO_RETURN __noreturn 914#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) 915 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) 916#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L 917 #define JSON_HEDLEY_NO_RETURN _Noreturn 918#elif defined(__cplusplus) && (__cplusplus >= 201103L) 919 #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]]) 920#elif \ 921 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \ 922 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \ 923 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ 924 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ 925 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ 926 JSON_HEDLEY_TI_VERSION_CHECK(18,0,0) || \ 927 (JSON_HEDLEY_TI_VERSION_CHECK(17,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) 928 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) 929#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) 930 #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return") 931#elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) 932 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) 933#elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus) 934 #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;") 935#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) 936 #define JSON_HEDLEY_NO_RETURN __attribute((noreturn)) 937#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) 938 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) 939#else 940 #define JSON_HEDLEY_NO_RETURN 941#endif 942 943#if defined(JSON_HEDLEY_NO_ESCAPE) 944 #undef JSON_HEDLEY_NO_ESCAPE 945#endif 946#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape) 947 #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__)) 948#else 949 #define JSON_HEDLEY_NO_ESCAPE 950#endif 951 952#if defined(JSON_HEDLEY_UNREACHABLE) 953 #undef JSON_HEDLEY_UNREACHABLE 954#endif 955#if defined(JSON_HEDLEY_UNREACHABLE_RETURN) 956 #undef JSON_HEDLEY_UNREACHABLE_RETURN 957#endif 958#if \ 959 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \ 960 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ 961 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ 962 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) 963 #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable() 964#elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) 965 #define JSON_HEDLEY_UNREACHABLE() __assume(0) 966#elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) 967 #if defined(__cplusplus) 968 #define JSON_HEDLEY_UNREACHABLE() std::_nassert(0) 969 #else 970 #define JSON_HEDLEY_UNREACHABLE() _nassert(0) 971 #endif 972 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return value 973#elif defined(EXIT_FAILURE) 974 #define JSON_HEDLEY_UNREACHABLE() abort() 975#else 976 #define JSON_HEDLEY_UNREACHABLE() 977 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return value 978#endif 979#if !defined(JSON_HEDLEY_UNREACHABLE_RETURN) 980 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE() 981#endif 982 983#if defined(JSON_HEDLEY_ASSUME) 984 #undef JSON_HEDLEY_ASSUME 985#endif 986#if \ 987 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ 988 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) 989 #define JSON_HEDLEY_ASSUME(expr) __assume(expr) 990#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume) 991 #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr) 992#elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) 993 #if defined(__cplusplus) 994 #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr) 995 #else 996 #define JSON_HEDLEY_ASSUME(expr) _nassert(expr) 997 #endif 998#elif \ 999 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && !defined(JSON_HEDLEY_ARM_VERSION)) || \ 1000 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ 1001 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ 1002 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) 1003 #define JSON_HEDLEY_ASSUME(expr) ((void) ((expr) ? 1 : (__builtin_unreachable(), 1))) 1004#else 1005 #define JSON_HEDLEY_ASSUME(expr) ((void) (expr)) 1006#endif 1007 1008JSON_HEDLEY_DIAGNOSTIC_PUSH 1009#if JSON_HEDLEY_HAS_WARNING("-Wpedantic") 1010 #pragma clang diagnostic ignored "-Wpedantic" 1011#endif 1012#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus) 1013 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic" 1014#endif 1015#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0) 1016 #if defined(__clang__) 1017 #pragma clang diagnostic ignored "-Wvariadic-macros" 1018 #elif defined(JSON_HEDLEY_GCC_VERSION) 1019 #pragma GCC diagnostic ignored "-Wvariadic-macros" 1020 #endif 1021#endif 1022#if defined(JSON_HEDLEY_NON_NULL) 1023 #undef JSON_HEDLEY_NON_NULL 1024#endif 1025#if \ 1026 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \ 1027 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ 1028 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ 1029 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) 1030 #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__))) 1031#else 1032 #define JSON_HEDLEY_NON_NULL(...) 1033#endif 1034JSON_HEDLEY_DIAGNOSTIC_POP 1035 1036#if defined(JSON_HEDLEY_PRINTF_FORMAT) 1037 #undef JSON_HEDLEY_PRINTF_FORMAT 1038#endif 1039#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO) 1040 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check))) 1041#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO) 1042 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check))) 1043#elif \ 1044 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \ 1045 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ 1046 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ 1047 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ 1048 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ 1049 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ 1050 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) 1051 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check))) 1052#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0) 1053 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check)) 1054#else 1055 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) 1056#endif 1057 1058#if defined(JSON_HEDLEY_CONSTEXPR) 1059 #undef JSON_HEDLEY_CONSTEXPR 1060#endif 1061#if defined(__cplusplus) 1062 #if __cplusplus >= 201103L 1063 #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr) 1064 #endif 1065#endif 1066#if !defined(JSON_HEDLEY_CONSTEXPR) 1067 #define JSON_HEDLEY_CONSTEXPR 1068#endif 1069 1070#if defined(JSON_HEDLEY_PREDICT) 1071 #undef JSON_HEDLEY_PREDICT 1072#endif 1073#if defined(JSON_HEDLEY_LIKELY) 1074 #undef JSON_HEDLEY_LIKELY 1075#endif 1076#if defined(JSON_HEDLEY_UNLIKELY) 1077 #undef JSON_HEDLEY_UNLIKELY 1078#endif 1079#if defined(JSON_HEDLEY_UNPREDICTABLE) 1080 #undef JSON_HEDLEY_UNPREDICTABLE 1081#endif 1082#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable) 1083 #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable(!!(expr)) 1084#endif 1085#if \ 1086 JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) || \ 1087 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) 1088# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability(expr, value, probability) 1089# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1, probability) 1090# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0, probability) 1091# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) 1092# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) 1093#if !defined(JSON_HEDLEY_BUILTIN_UNPREDICTABLE) 1094 #define JSON_HEDLEY_BUILTIN_UNPREDICTABLE(expr) __builtin_expect_with_probability(!!(expr), 1, 0.5) 1095#endif 1096#elif \ 1097 JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) || \ 1098 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ 1099 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ 1100 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ 1101 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ 1102 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ 1103 JSON_HEDLEY_TI_VERSION_CHECK(6,1,0) || \ 1104 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) 1105# define JSON_HEDLEY_PREDICT(expr, expected, probability) \ 1106 (((probability) >= 0.9) ? __builtin_expect(!!(expr), (expected)) : (((void) (expected)), !!(expr))) 1107# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \ 1108 (__extension__ ({ \ 1109 JSON_HEDLEY_CONSTEXPR double hedley_probability_ = (probability); \ 1110 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \ 1111 })) 1112# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \ 1113 (__extension__ ({ \ 1114 JSON_HEDLEY_CONSTEXPR double hedley_probability_ = (probability); \ 1115 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \ 1116 })) 1117# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) 1118# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) 1119#else 1120# define JSON_HEDLEY_PREDICT(expr, expected, probability) (((void) (expected)), !!(expr)) 1121# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr)) 1122# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr)) 1123# define JSON_HEDLEY_LIKELY(expr) (!!(expr)) 1124# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr)) 1125#endif 1126#if !defined(JSON_HEDLEY_UNPREDICTABLE) 1127 #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5) 1128#endif 1129 1130#if defined(JSON_HEDLEY_MALLOC) 1131 #undef JSON_HEDLEY_MALLOC 1132#endif 1133#if \ 1134 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \ 1135 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ 1136 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ 1137 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ 1138 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ 1139 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ 1140 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ 1141 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) 1142 #define JSON_HEDLEY_MALLOC __attribute__((__malloc__)) 1143#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) 1144 #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory") 1145#elif JSON_HEDLEY_MSVC_VERSION_CHECK(14, 0, 0) 1146 #define JSON_HEDLEY_MALLOC __declspec(restrict) 1147#else 1148 #define JSON_HEDLEY_MALLOC 1149#endif 1150 1151#if defined(JSON_HEDLEY_PURE) 1152 #undef JSON_HEDLEY_PURE 1153#endif 1154#if \ 1155 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \ 1156 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \ 1157 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ 1158 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ 1159 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ 1160 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ 1161 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ 1162 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ 1163 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) 1164 #define JSON_HEDLEY_PURE __attribute__((__pure__)) 1165#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) 1166 #define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data") 1167#elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus) 1168 #define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;") 1169#else 1170 #define JSON_HEDLEY_PURE 1171#endif 1172 1173#if defined(JSON_HEDLEY_CONST) 1174 #undef JSON_HEDLEY_CONST 1175#endif 1176#if \ 1177 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \ 1178 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \ 1179 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ 1180 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ 1181 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ 1182 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ 1183 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ 1184 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ 1185 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) 1186 #define JSON_HEDLEY_CONST __attribute__((__const__)) 1187#elif \ 1188 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) 1189 #define JSON_HEDLEY_CONST _Pragma("no_side_effect") 1190#else 1191 #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE 1192#endif 1193 1194#if defined(JSON_HEDLEY_RESTRICT) 1195 #undef JSON_HEDLEY_RESTRICT 1196#endif 1197#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus) 1198 #define JSON_HEDLEY_RESTRICT restrict 1199#elif \ 1200 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ 1201 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ 1202 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ 1203 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ 1204 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ 1205 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ 1206 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ 1207 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \ 1208 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ 1209 defined(__clang__) 1210 #define JSON_HEDLEY_RESTRICT __restrict 1211#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus) 1212 #define JSON_HEDLEY_RESTRICT _Restrict 1213#else 1214 #define JSON_HEDLEY_RESTRICT 1215#endif 1216 1217#if defined(JSON_HEDLEY_INLINE) 1218 #undef JSON_HEDLEY_INLINE 1219#endif 1220#if \ 1221 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ 1222 (defined(__cplusplus) && (__cplusplus >= 199711L)) 1223 #define JSON_HEDLEY_INLINE inline 1224#elif \ 1225 defined(JSON_HEDLEY_GCC_VERSION) || \ 1226 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0) 1227 #define JSON_HEDLEY_INLINE __inline__ 1228#elif \ 1229 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ 1230 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ 1231 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) 1232 #define JSON_HEDLEY_INLINE __inline 1233#else 1234 #define JSON_HEDLEY_INLINE 1235#endif 1236 1237#if defined(JSON_HEDLEY_ALWAYS_INLINE) 1238 #undef JSON_HEDLEY_ALWAYS_INLINE 1239#endif 1240#if \ 1241 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \ 1242 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ 1243 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ 1244 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ 1245 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ 1246 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ 1247 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ 1248 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) 1249 #define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE 1250#elif JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) 1251 #define JSON_HEDLEY_ALWAYS_INLINE __forceinline 1252#elif JSON_HEDLEY_TI_VERSION_CHECK(7,0,0) && defined(__cplusplus) 1253 #define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;") 1254#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) 1255 #define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced") 1256#else 1257 #define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE 1258#endif 1259 1260#if defined(JSON_HEDLEY_NEVER_INLINE) 1261 #undef JSON_HEDLEY_NEVER_INLINE 1262#endif 1263#if \ 1264 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \ 1265 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ 1266 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ 1267 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ 1268 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ 1269 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ 1270 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ 1271 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) 1272 #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__)) 1273#elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) 1274 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) 1275#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0) 1276 #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline") 1277#elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus) 1278 #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;") 1279#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) 1280 #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never") 1281#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) 1282 #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline)) 1283#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) 1284 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) 1285#else 1286 #define JSON_HEDLEY_NEVER_INLINE 1287#endif 1288 1289#if defined(JSON_HEDLEY_PRIVATE) 1290 #undef JSON_HEDLEY_PRIVATE 1291#endif 1292#if defined(JSON_HEDLEY_PUBLIC) 1293 #undef JSON_HEDLEY_PUBLIC 1294#endif 1295#if defined(JSON_HEDLEY_IMPORT) 1296 #undef JSON_HEDLEY_IMPORT 1297#endif 1298#if defined(_WIN32) || defined(__CYGWIN__) 1299 #define JSON_HEDLEY_PRIVATE 1300 #define JSON_HEDLEY_PUBLIC __declspec(dllexport) 1301 #define JSON_HEDLEY_IMPORT __declspec(dllimport) 1302#else 1303 #if \ 1304 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \ 1305 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ 1306 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ 1307 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ 1308 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ 1309 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ 1310 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ 1311 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_EABI__) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) 1312 #define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden"))) 1313 #define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default"))) 1314 #else 1315 #define JSON_HEDLEY_PRIVATE 1316 #define JSON_HEDLEY_PUBLIC 1317 #endif 1318 #define JSON_HEDLEY_IMPORT extern 1319#endif 1320 1321#if defined(JSON_HEDLEY_NO_THROW) 1322 #undef JSON_HEDLEY_NO_THROW 1323#endif 1324#if \ 1325 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \ 1326 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ 1327 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) 1328 #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__)) 1329#elif \ 1330 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \ 1331 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) 1332 #define JSON_HEDLEY_NO_THROW __declspec(nothrow) 1333#else 1334 #define JSON_HEDLEY_NO_THROW 1335#endif 1336 1337#if defined(JSON_HEDLEY_FALL_THROUGH) 1338 #undef JSON_HEDLEY_FALL_THROUGH 1339#endif 1340#if JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(fallthrough,7,0,0) && !defined(JSON_HEDLEY_PGI_VERSION) 1341 #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__)) 1342#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough) 1343 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]]) 1344#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough) 1345 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]]) 1346#elif defined(__fallthrough) /* SAL */ 1347 #define JSON_HEDLEY_FALL_THROUGH __fallthrough 1348#else 1349 #define JSON_HEDLEY_FALL_THROUGH 1350#endif 1351 1352#if defined(JSON_HEDLEY_RETURNS_NON_NULL) 1353 #undef JSON_HEDLEY_RETURNS_NON_NULL 1354#endif 1355#if \ 1356 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \ 1357 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) 1358 #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__)) 1359#elif defined(_Ret_notnull_) /* SAL */ 1360 #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_ 1361#else 1362 #define JSON_HEDLEY_RETURNS_NON_NULL 1363#endif 1364 1365#if defined(JSON_HEDLEY_ARRAY_PARAM) 1366 #undef JSON_HEDLEY_ARRAY_PARAM 1367#endif 1368#if \ 1369 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ 1370 !defined(__STDC_NO_VLA__) && \ 1371 !defined(__cplusplus) && \ 1372 !defined(JSON_HEDLEY_PGI_VERSION) && \ 1373 !defined(JSON_HEDLEY_TINYC_VERSION) 1374 #define JSON_HEDLEY_ARRAY_PARAM(name) (name) 1375#else 1376 #define JSON_HEDLEY_ARRAY_PARAM(name) 1377#endif 1378 1379#if defined(JSON_HEDLEY_IS_CONSTANT) 1380 #undef JSON_HEDLEY_IS_CONSTANT 1381#endif 1382#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR) 1383 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR 1384#endif 1385/* JSON_HEDLEY_IS_CONSTEXPR_ is for 1386 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ 1387#if defined(JSON_HEDLEY_IS_CONSTEXPR_) 1388 #undef JSON_HEDLEY_IS_CONSTEXPR_ 1389#endif 1390#if \ 1391 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \ 1392 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ 1393 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ 1394 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \ 1395 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ 1396 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ 1397 JSON_HEDLEY_TI_VERSION_CHECK(6,1,0) || \ 1398 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \ 1399 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) 1400 #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr) 1401#endif 1402#if !defined(__cplusplus) 1403# if \ 1404 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \ 1405 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ 1406 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ 1407 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ 1408 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ 1409 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ 1410 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24) 1411#if defined(__INTPTR_TYPE__) 1412 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*) 1413#else 1414 #include <stdint.h> 1415 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*) 1416#endif 1417# elif \ 1418 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && !defined(JSON_HEDLEY_SUNPRO_VERSION) && !defined(JSON_HEDLEY_PGI_VERSION)) || \ 1419 JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) || \ 1420 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ 1421 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \ 1422 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ 1423 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0) 1424#if defined(__INTPTR_TYPE__) 1425 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0) 1426#else 1427 #include <stdint.h> 1428 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0) 1429#endif 1430# elif \ 1431 defined(JSON_HEDLEY_GCC_VERSION) || \ 1432 defined(JSON_HEDLEY_INTEL_VERSION) || \ 1433 defined(JSON_HEDLEY_TINYC_VERSION) || \ 1434 defined(JSON_HEDLEY_TI_VERSION) || \ 1435 defined(__clang__) 1436# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \ 1437 sizeof(void) != \ 1438 sizeof(*( \ 1439 1 ? \ 1440 ((void*) ((expr) * 0L) ) : \ 1441((struct { char v[sizeof(void) * 2]; } *) 1) \ 1442 ) \ 1443 ) \ 1444 ) 1445# endif 1446#endif 1447#if defined(JSON_HEDLEY_IS_CONSTEXPR_) 1448 #if !defined(JSON_HEDLEY_IS_CONSTANT) 1449 #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr) 1450 #endif 1451 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1)) 1452#else 1453 #if !defined(JSON_HEDLEY_IS_CONSTANT) 1454 #define JSON_HEDLEY_IS_CONSTANT(expr) (0) 1455 #endif 1456 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr) 1457#endif 1458 1459#if defined(JSON_HEDLEY_BEGIN_C_DECLS) 1460 #undef JSON_HEDLEY_BEGIN_C_DECLS 1461#endif 1462#if defined(JSON_HEDLEY_END_C_DECLS) 1463 #undef JSON_HEDLEY_END_C_DECLS 1464#endif 1465#if defined(JSON_HEDLEY_C_DECL) 1466 #undef JSON_HEDLEY_C_DECL 1467#endif 1468#if defined(__cplusplus) 1469 #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" { 1470 #define JSON_HEDLEY_END_C_DECLS } 1471 #define JSON_HEDLEY_C_DECL extern "C" 1472#else 1473 #define JSON_HEDLEY_BEGIN_C_DECLS 1474 #define JSON_HEDLEY_END_C_DECLS 1475 #define JSON_HEDLEY_C_DECL 1476#endif 1477 1478#if defined(JSON_HEDLEY_STATIC_ASSERT) 1479 #undef JSON_HEDLEY_STATIC_ASSERT 1480#endif 1481#if \ 1482 !defined(__cplusplus) && ( \ 1483 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \ 1484 JSON_HEDLEY_HAS_FEATURE(c_static_assert) || \ 1485 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \ 1486 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ 1487 defined(_Static_assert) \ 1488 ) 1489# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message) 1490#elif \ 1491 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \ 1492 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \ 1493 (defined(__cplusplus) && JSON_HEDLEY_TI_VERSION_CHECK(8,3,0)) 1494# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message)) 1495#else 1496# define JSON_HEDLEY_STATIC_ASSERT(expr, message) 1497#endif 1498 1499#if defined(JSON_HEDLEY_CONST_CAST) 1500 #undef JSON_HEDLEY_CONST_CAST 1501#endif 1502#if defined(__cplusplus) 1503# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr)) 1504#elif \ 1505 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \ 1506 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \ 1507 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) 1508# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \ 1509 JSON_HEDLEY_DIAGNOSTIC_PUSH \ 1510 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \ 1511 ((T) (expr)); \ 1512 JSON_HEDLEY_DIAGNOSTIC_POP \ 1513 })) 1514#else 1515# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr)) 1516#endif 1517 1518#if defined(JSON_HEDLEY_REINTERPRET_CAST) 1519 #undef JSON_HEDLEY_REINTERPRET_CAST 1520#endif 1521#if defined(__cplusplus) 1522 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr)) 1523#else 1524 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (*((T*) &(expr))) 1525#endif 1526 1527#if defined(JSON_HEDLEY_STATIC_CAST) 1528 #undef JSON_HEDLEY_STATIC_CAST 1529#endif 1530#if defined(__cplusplus) 1531 #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr)) 1532#else 1533 #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr)) 1534#endif 1535 1536#if defined(JSON_HEDLEY_CPP_CAST) 1537 #undef JSON_HEDLEY_CPP_CAST 1538#endif 1539#if defined(__cplusplus) 1540 #define JSON_HEDLEY_CPP_CAST(T, expr) static_cast<T>(expr) 1541#else 1542 #define JSON_HEDLEY_CPP_CAST(T, expr) (expr) 1543#endif 1544 1545#if defined(JSON_HEDLEY_NULL) 1546 #undef JSON_HEDLEY_NULL 1547#endif 1548#if defined(__cplusplus) 1549 #if __cplusplus >= 201103L 1550 #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr) 1551 #elif defined(NULL) 1552 #define JSON_HEDLEY_NULL NULL 1553 #else 1554 #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0) 1555 #endif 1556#elif defined(NULL) 1557 #define JSON_HEDLEY_NULL NULL 1558#else 1559 #define JSON_HEDLEY_NULL ((void*) 0) 1560#endif 1561 1562#if defined(JSON_HEDLEY_MESSAGE) 1563 #undef JSON_HEDLEY_MESSAGE 1564#endif 1565#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") 1566# define JSON_HEDLEY_MESSAGE(msg) \ 1567 JSON_HEDLEY_DIAGNOSTIC_PUSH \ 1568 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ 1569 JSON_HEDLEY_PRAGMA(message msg) \ 1570 JSON_HEDLEY_DIAGNOSTIC_POP 1571#elif \ 1572 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \ 1573 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) 1574# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg) 1575#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) 1576# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg) 1577#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) 1578# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) 1579#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0) 1580# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) 1581#else 1582# define JSON_HEDLEY_MESSAGE(msg) 1583#endif 1584 1585#if defined(JSON_HEDLEY_WARNING) 1586 #undef JSON_HEDLEY_WARNING 1587#endif 1588#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") 1589# define JSON_HEDLEY_WARNING(msg) \ 1590 JSON_HEDLEY_DIAGNOSTIC_PUSH \ 1591 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ 1592 JSON_HEDLEY_PRAGMA(clang warning msg) \ 1593 JSON_HEDLEY_DIAGNOSTIC_POP 1594#elif \ 1595 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \ 1596 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) 1597# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg) 1598#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) 1599# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg)) 1600#else 1601# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg) 1602#endif 1603 1604#if defined(JSON_HEDLEY_REQUIRE) 1605 #undef JSON_HEDLEY_REQUIRE 1606#endif 1607#if defined(JSON_HEDLEY_REQUIRE_MSG) 1608 #undef JSON_HEDLEY_REQUIRE_MSG 1609#endif 1610#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if) 1611# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat") 1612# define JSON_HEDLEY_REQUIRE(expr) \ 1613 JSON_HEDLEY_DIAGNOSTIC_PUSH \ 1614 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ 1615 __attribute__((diagnose_if(!(expr), #expr, "error"))) \ 1616 JSON_HEDLEY_DIAGNOSTIC_POP 1617# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \ 1618 JSON_HEDLEY_DIAGNOSTIC_PUSH \ 1619 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ 1620 __attribute__((diagnose_if(!(expr), msg, "error"))) \ 1621 JSON_HEDLEY_DIAGNOSTIC_POP 1622# else 1623# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error"))) 1624# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error"))) 1625# endif 1626#else 1627# define JSON_HEDLEY_REQUIRE(expr) 1628# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) 1629#endif 1630 1631#if defined(JSON_HEDLEY_FLAGS) 1632 #undef JSON_HEDLEY_FLAGS 1633#endif 1634#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) 1635 #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__)) 1636#endif 1637 1638#if defined(JSON_HEDLEY_FLAGS_CAST) 1639 #undef JSON_HEDLEY_FLAGS_CAST 1640#endif 1641#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0) 1642# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \ 1643 JSON_HEDLEY_DIAGNOSTIC_PUSH \ 1644 _Pragma("warning(disable:188)") \ 1645 ((T) (expr)); \ 1646 JSON_HEDLEY_DIAGNOSTIC_POP \ 1647 })) 1648#else 1649# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr) 1650#endif 1651 1652#if defined(JSON_HEDLEY_EMPTY_BASES) 1653 #undef JSON_HEDLEY_EMPTY_BASES 1654#endif 1655#if JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0) 1656 #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases) 1657#else 1658 #define JSON_HEDLEY_EMPTY_BASES 1659#endif 1660 1661/* Remaining macros are deprecated. */ 1662 1663#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK) 1664 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK 1665#endif 1666#if defined(__clang__) 1667 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0) 1668#else 1669 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) 1670#endif 1671 1672#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE) 1673 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE 1674#endif 1675#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) 1676 1677#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE) 1678 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE 1679#endif 1680#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) 1681 1682#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN) 1683 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN 1684#endif 1685#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin) 1686 1687#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE) 1688 #undef JSON_HEDLEY_CLANG_HAS_FEATURE 1689#endif 1690#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature) 1691 1692#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION) 1693 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION 1694#endif 1695#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension) 1696 1697#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE) 1698 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE 1699#endif 1700#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) 1701 1702#if defined(JSON_HEDLEY_CLANG_HAS_WARNING) 1703 #undef JSON_HEDLEY_CLANG_HAS_WARNING 1704#endif 1705#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning) 1706 1707#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */ 1708 1709 1710// This file contains all internal macro definitions 1711// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them 1712 1713// exclude unsupported compilers 1714#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) 1715 #if defined(__clang__) 1716 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 1717 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" 1718 #endif 1719 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) 1720 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 1721 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" 1722 #endif 1723 #endif 1724#endif 1725 1726// C++ language standard detection 1727#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 1728 #define JSON_HAS_CPP_17 1729 #define JSON_HAS_CPP_14 1730#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) 1731 #define JSON_HAS_CPP_14 1732#endif 1733 1734// disable float-equal warnings on GCC/clang 1735#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 1736 #pragma GCC diagnostic push 1737 #pragma GCC diagnostic ignored "-Wfloat-equal" 1738#endif 1739 1740// disable documentation warnings on clang 1741#if defined(__clang__) 1742 #pragma GCC diagnostic push 1743 #pragma GCC diagnostic ignored "-Wdocumentation" 1744#endif 1745 1746// allow to disable exceptions 1747#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) 1748 #define JSON_THROW(exception) throw exception 1749 #define JSON_TRY try 1750 #define JSON_CATCH(exception) catch(exception) 1751 #define JSON_INTERNAL_CATCH(exception) catch(exception) 1752#else 1753 #include <cstdlib> 1754 #define JSON_THROW(exception) std::abort() 1755 #define JSON_TRY if(true) 1756 #define JSON_CATCH(exception) if(false) 1757 #define JSON_INTERNAL_CATCH(exception) if(false) 1758#endif 1759 1760// override exception macros 1761#if defined(JSON_THROW_USER) 1762 #undef JSON_THROW 1763 #define JSON_THROW JSON_THROW_USER 1764#endif 1765#if defined(JSON_TRY_USER) 1766 #undef JSON_TRY 1767 #define JSON_TRY JSON_TRY_USER 1768#endif 1769#if defined(JSON_CATCH_USER) 1770 #undef JSON_CATCH 1771 #define JSON_CATCH JSON_CATCH_USER 1772 #undef JSON_INTERNAL_CATCH 1773 #define JSON_INTERNAL_CATCH JSON_CATCH_USER 1774#endif 1775#if defined(JSON_INTERNAL_CATCH_USER) 1776 #undef JSON_INTERNAL_CATCH 1777 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER 1778#endif 1779 1780/*! 1781@brief macro to briefly define a mapping between an enum and JSON 1782@def NLOHMANN_JSON_SERIALIZE_ENUM 1783@since version 3.4.0 1784*/ 1785#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ 1786 template<typename BasicJsonType> \ 1787 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ 1788 { \ 1789 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \ 1790 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \ 1791 auto it = std::find_if(std::begin(m), std::end(m), \ 1792 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \ 1793 { \ 1794 return ej_pair.first == e; \ 1795 }); \ 1796 j = ((it != std::end(m)) ? it : std::begin(m))->second; \ 1797 } \ 1798 template<typename BasicJsonType> \ 1799 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ 1800 { \ 1801 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \ 1802 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \ 1803 auto it = std::find_if(std::begin(m), std::end(m), \ 1804 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \ 1805 { \ 1806 return ej_pair.second == j; \ 1807 }); \ 1808 e = ((it != std::end(m)) ? it : std::begin(m))->first; \ 1809 } 1810 1811// Ugly macros to avoid uglier copy-paste when specializing basic_json. They 1812// may be removed in the future once the class is split. 1813 1814#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ 1815 template<template<typename, typename, typename...> class ObjectType, \ 1816 template<typename, typename...> class ArrayType, \ 1817 class StringType, class BooleanType, class NumberIntegerType, \ 1818 class NumberUnsignedType, class NumberFloatType, \ 1819 template<typename> class AllocatorType, \ 1820 template<typename, typename = void> class JSONSerializer> 1821 1822#define NLOHMANN_BASIC_JSON_TPL \ 1823 basic_json<ObjectType, ArrayType, StringType, BooleanType, \ 1824 NumberIntegerType, NumberUnsignedType, NumberFloatType, \ 1825 AllocatorType, JSONSerializer> 1826 1827 1828namespace nlohmann 1829{ 1830namespace detail 1831{ 1832//////////////// 1833// exceptions // 1834//////////////// 1835 1836/*! 1837@brief general exception of the @ref basic_json class 1838 1839This class is an extension of `std::exception` objects with a member @a id for 1840exception ids. It is used as the base class for all exceptions thrown by the 1841@ref basic_json class. This class can hence be used as "wildcard" to catch 1842exceptions. 1843 1844Subclasses: 1845- @ref parse_error for exceptions indicating a parse error 1846- @ref invalid_iterator for exceptions indicating errors with iterators 1847- @ref type_error for exceptions indicating executing a member function with 1848 a wrong type 1849- @ref out_of_range for exceptions indicating access out of the defined range 1850- @ref other_error for exceptions indicating other library errors 1851 1852@internal 1853@note To have nothrow-copy-constructible exceptions, we internally use 1854 `std::runtime_error` which can cope with arbitrary-length error messages. 1855 Intermediate strings are built with static functions and then passed to 1856 the actual constructor. 1857@endinternal 1858 1859@liveexample{The following code shows how arbitrary library exceptions can be 1860caught.,exception} 1861 1862@since version 3.0.0 1863*/ 1864class exception : public std::exception 1865{ 1866 public: 1867 /// returns the explanatory string 1868 JSON_HEDLEY_RETURNS_NON_NULL 1869 const char* what() const noexcept override 1870 { 1871 return m.what(); 1872 } 1873 1874 /// the id of the exception 1875 const int id; 1876 1877 protected: 1878 JSON_HEDLEY_NON_NULL(3) 1879 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} 1880 1881 static std::string name(const std::string& ename, int id_) 1882 { 1883 return "[json.exception." + ename + "." + std::to_string(id_) + "] "; 1884 } 1885 1886 private: 1887 /// an exception object as storage for error messages 1888 std::runtime_error m; 1889}; 1890 1891/*! 1892@brief exception indicating a parse error 1893 1894This exception is thrown by the library when a parse error occurs. Parse errors 1895can occur during the deserialization of JSON text, CBOR, MessagePack, as well 1896as when using JSON Patch. 1897 1898Member @a byte holds the byte index of the last read character in the input 1899file. 1900 1901Exceptions have ids 1xx. 1902 1903name / id | example message | description 1904------------------------------ | --------------- | ------------------------- 1905json.exception.parse_error.101 | parse error at 2: unexpected end of input; expected string literal | This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member @a byte indicates the error position. 1906json.exception.parse_error.102 | parse error at 14: missing or wrong low surrogate | JSON uses the `\uxxxx` format to describe Unicode characters. Code points above above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point. 1907json.exception.parse_error.103 | parse error: code points above 0x10FFFF are invalid | Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid. 1908json.exception.parse_error.104 | parse error: JSON patch must be an array of objects | [RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects. 1909json.exception.parse_error.105 | parse error: operation must have string member 'op' | An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors. 1910json.exception.parse_error.106 | parse error: array index '01' must not begin with '0' | An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`. 1911json.exception.parse_error.107 | parse error: JSON pointer must be empty or begin with '/' - was: 'foo' | A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character. 1912json.exception.parse_error.108 | parse error: escape character '~' must be followed with '0' or '1' | In a JSON Pointer, only `~0` and `~1` are valid escape sequences. 1913json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number. 1914json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read. 1915json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xF8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read. 1916json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read. 1917json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet). 1918 1919@note For an input with n bytes, 1 is the index of the first character and n+1 1920 is the index of the terminating null byte or the end of file. This also 1921 holds true when reading a byte vector (CBOR or MessagePack). 1922 1923@liveexample{The following code shows how a `parse_error` exception can be 1924caught.,parse_error} 1925 1926@sa - @ref exception for the base class of the library exceptions 1927@sa - @ref invalid_iterator for exceptions indicating errors with iterators 1928@sa - @ref type_error for exceptions indicating executing a member function with 1929 a wrong type 1930@sa - @ref out_of_range for exceptions indicating access out of the defined range 1931@sa - @ref other_error for exceptions indicating other library errors 1932 1933@since version 3.0.0 1934*/ 1935class parse_error : public exception 1936{ 1937 public: 1938 /*! 1939 @brief create a parse error exception 1940 @param[in] id_ the id of the exception 1941 @param[in] pos the position where the error occurred (or with 1942 chars_read_total=0 if the position cannot be 1943 determined) 1944 @param[in] what_arg the explanatory string 1945 @return parse_error object 1946 */ 1947 static parse_error create(int id_, const position_t& pos, const std::string& what_arg) 1948 { 1949 std::string w = exception::name("parse_error", id_) + "parse error" + 1950 position_string(pos) + ": " + what_arg; 1951 return parse_error(id_, pos.chars_read_total, w.c_str()); 1952 } 1953 1954 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg) 1955 { 1956 std::string w = exception::name("parse_error", id_) + "parse error" + 1957 (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") + 1958 ": " + what_arg; 1959 return parse_error(id_, byte_, w.c_str()); 1960 } 1961 1962 /*! 1963 @brief byte index of the parse error 1964 1965 The byte index of the last read character in the input file. 1966 1967 @note For an input with n bytes, 1 is the index of the first character and 1968 n+1 is the index of the terminating null byte or the end of file. 1969 This also holds true when reading a byte vector (CBOR or MessagePack). 1970 */ 1971 const std::size_t byte; 1972 1973 private: 1974 parse_error(int id_, std::size_t byte_, const char* what_arg) 1975 : exception(id_, what_arg), byte(byte_) {} 1976 1977 static std::string position_string(const position_t& pos) 1978 { 1979 return " at line " + std::to_string(pos.lines_read + 1) + 1980 ", column " + std::to_string(pos.chars_read_current_line); 1981 } 1982}; 1983 1984/*! 1985@brief exception indicating errors with iterators 1986 1987This exception is thrown if iterators passed to a library function do not match 1988the expected semantics. 1989 1990Exceptions have ids 2xx. 1991 1992name / id | example message | description 1993----------------------------------- | --------------- | ------------------------- 1994json.exception.invalid_iterator.201 | iterators are not compatible | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid. 1995json.exception.invalid_iterator.202 | iterator does not fit current value | In an erase or insert function, the passed iterator @a pos does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion. 1996json.exception.invalid_iterator.203 | iterators do not fit current value | Either iterator passed to function @ref erase(IteratorType first, IteratorType last) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from. 1997json.exception.invalid_iterator.204 | iterators out of range | When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (@ref begin(), @ref end()), because this is the only way the single stored value is expressed. All other ranges are invalid. 1998json.exception.invalid_iterator.205 | iterator out of range | When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the @ref begin() iterator, because it is the only way to address the stored value. All other iterators are invalid. 1999json.exception.invalid_iterator.206 | cannot construct with iterators from null | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range. 2000json.exception.invalid_iterator.207 | cannot use key() for non-object iterators | The key() member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key. 2001json.exception.invalid_iterator.208 | cannot use operator[] for object iterators | The operator[] to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered. 2002json.exception.invalid_iterator.209 | cannot use offsets with object iterators | The offset operators (+, -, +=, -=) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered. 2003json.exception.invalid_iterator.210 | iterators do not fit | The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid. 2004json.exception.invalid_iterator.211 | passed iterators may not belong to container | The iterator range passed to the insert function must not be a subrange of the container to insert to. 2005json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container. 2006json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered. 2007json.exception.invalid_iterator.214 | cannot get value | Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to @ref begin(). 2008 2009@liveexample{The following code shows how an `invalid_iterator` exception can be 2010caught.,invalid_iterator} 2011 2012@sa - @ref exception for the base class of the library exceptions 2013@sa - @ref parse_error for exceptions indicating a parse error 2014@sa - @ref type_error for exceptions indicating executing a member function with 2015 a wrong type 2016@sa - @ref out_of_range for exceptions indicating access out of the defined range 2017@sa - @ref other_error for exceptions indicating other library errors 2018 2019@since version 3.0.0 2020*/ 2021class invalid_iterator : public exception 2022{ 2023 public: 2024 static invalid_iterator create(int id_, const std::string& what_arg) 2025 { 2026 std::string w = exception::name("invalid_iterator", id_) + what_arg; 2027 return invalid_iterator(id_, w.c_str()); 2028 } 2029 2030 private: 2031 JSON_HEDLEY_NON_NULL(3) 2032 invalid_iterator(int id_, const char* what_arg) 2033 : exception(id_, what_arg) {} 2034}; 2035 2036/*! 2037@brief exception indicating executing a member function with a wrong type 2038 2039This exception is thrown in case of a type error; that is, a library function is 2040executed on a JSON value whose type does not match the expected semantics. 2041 2042Exceptions have ids 3xx. 2043 2044name / id | example message | description 2045----------------------------- | --------------- | ------------------------- 2046json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead. 2047json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types. 2048json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t &. 2049json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types. 2050json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types. 2051json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types. 2052json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types. 2053json.exception.type_error.308 | cannot use push_back() with string | The @ref push_back() and @ref operator+= member functions can only be executed for certain JSON types. 2054json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types. 2055json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types. 2056json.exception.type_error.311 | cannot use emplace_back() with string | The @ref emplace_back() member function can only be executed for certain JSON types. 2057json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types. 2058json.exception.type_error.313 | invalid value to unflatten | The @ref unflatten function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well defined. 2059json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers. 2060json.exception.type_error.315 | values in object must be primitive | The @ref unflatten function only works for an object whose keys are JSON Pointers and whose values are primitive. 2061json.exception.type_error.316 | invalid UTF-8 byte at index 10: 0x7E | The @ref dump function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. | 2062json.exception.type_error.317 | JSON value cannot be serialized to requested format | The dynamic type of the object cannot be represented in the requested serialization format (e.g. a raw `true` or `null` JSON object cannot be serialized to BSON) | 2063 2064@liveexample{The following code shows how a `type_error` exception can be 2065caught.,type_error} 2066 2067@sa - @ref exception for the base class of the library exceptions 2068@sa - @ref parse_error for exceptions indicating a parse error 2069@sa - @ref invalid_iterator for exceptions indicating errors with iterators 2070@sa - @ref out_of_range for exceptions indicating access out of the defined range 2071@sa - @ref other_error for exceptions indicating other library errors 2072 2073@since version 3.0.0 2074*/ 2075class type_error : public exception 2076{ 2077 public: 2078 static type_error create(int id_, const std::string& what_arg) 2079 { 2080 std::string w = exception::name("type_error", id_) + what_arg; 2081 return type_error(id_, w.c_str()); 2082 } 2083 2084 private: 2085 JSON_HEDLEY_NON_NULL(3) 2086 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {} 2087}; 2088 2089/*! 2090@brief exception indicating access out of the defined range 2091 2092This exception is thrown in case a library function is called on an input 2093parameter that exceeds the expected range, for instance in case of array 2094indices or nonexisting object keys. 2095 2096Exceptions have ids 4xx. 2097 2098name / id | example message | description 2099------------------------------- | --------------- | ------------------------- 2100json.exception.out_of_range.401 | array index 3 is out of range | The provided array index @a i is larger than @a size-1. 2101json.exception.out_of_range.402 | array index '-' (3) is out of range | The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it. 2102json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object. 2103json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved. 2104json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value. 2105json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF. 2106json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. | 2107json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. | 2108json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 (at byte 2) | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string | 2109 2110@liveexample{The following code shows how an `out_of_range` exception can be 2111caught.,out_of_range} 2112 2113@sa - @ref exception for the base class of the library exceptions 2114@sa - @ref parse_error for exceptions indicating a parse error 2115@sa - @ref invalid_iterator for exceptions indicating errors with iterators 2116@sa - @ref type_error for exceptions indicating executing a member function with 2117 a wrong type 2118@sa - @ref other_error for exceptions indicating other library errors 2119 2120@since version 3.0.0 2121*/ 2122class out_of_range : public exception 2123{ 2124 public: 2125 static out_of_range create(int id_, const std::string& what_arg) 2126 { 2127 std::string w = exception::name("out_of_range", id_) + what_arg; 2128 return out_of_range(id_, w.c_str()); 2129 } 2130 2131 private: 2132 JSON_HEDLEY_NON_NULL(3) 2133 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {} 2134}; 2135 2136/*! 2137@brief exception indicating other library errors 2138 2139This exception is thrown in case of errors that cannot be classified with the 2140other exception types. 2141 2142Exceptions have ids 5xx. 2143 2144name / id | example message | description 2145------------------------------ | --------------- | ------------------------- 2146json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed. 2147 2148@sa - @ref exception for the base class of the library exceptions 2149@sa - @ref parse_error for exceptions indicating a parse error 2150@sa - @ref invalid_iterator for exceptions indicating errors with iterators 2151@sa - @ref type_error for exceptions indicating executing a member function with 2152 a wrong type 2153@sa - @ref out_of_range for exceptions indicating access out of the defined range 2154 2155@liveexample{The following code shows how an `other_error` exception can be 2156caught.,other_error} 2157 2158@since version 3.0.0 2159*/ 2160class other_error : public exception 2161{ 2162 public: 2163 static other_error create(int id_, const std::string& what_arg) 2164 { 2165 std::string w = exception::name("other_error", id_) + what_arg; 2166 return other_error(id_, w.c_str()); 2167 } 2168 2169 private: 2170 JSON_HEDLEY_NON_NULL(3) 2171 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {} 2172}; 2173} // namespace detail 2174} // namespace nlohmann 2175 2176// #include <nlohmann/detail/macro_scope.hpp> 2177 2178// #include <nlohmann/detail/meta/cpp_future.hpp> 2179 2180 2181#include <ciso646> // not 2182#include <cstddef> // size_t 2183#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type 2184 2185namespace nlohmann 2186{ 2187namespace detail 2188{ 2189// alias templates to reduce boilerplate 2190template<bool B, typename T = void> 2191using enable_if_t = typename std::enable_if<B, T>::type; 2192 2193template<typename T> 2194using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type; 2195 2196// implementation of C++14 index_sequence and affiliates 2197// source: https://stackoverflow.com/a/32223343 2198template<std::size_t... Ints> 2199struct index_sequence 2200{ 2201 using type = index_sequence; 2202 using value_type = std::size_t; 2203 static constexpr std::size_t size() noexcept 2204 { 2205 return sizeof...(Ints); 2206 } 2207}; 2208 2209template<class Sequence1, class Sequence2> 2210struct merge_and_renumber; 2211 2212template<std::size_t... I1, std::size_t... I2> 2213struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>> 2214 : index_sequence < I1..., (sizeof...(I1) + I2)... > {}; 2215 2216template<std::size_t N> 2217struct make_index_sequence 2218 : merge_and_renumber < typename make_index_sequence < N / 2 >::type, 2219 typename make_index_sequence < N - N / 2 >::type > {}; 2220 2221template<> struct make_index_sequence<0> : index_sequence<> {}; 2222template<> struct make_index_sequence<1> : index_sequence<0> {}; 2223 2224template<typename... Ts> 2225using index_sequence_for = make_index_sequence<sizeof...(Ts)>; 2226 2227// dispatch utility (taken from ranges-v3) 2228template<unsigned N> struct priority_tag : priority_tag < N - 1 > {}; 2229template<> struct priority_tag<0> {}; 2230 2231// taken from ranges-v3 2232template<typename T> 2233struct static_const 2234{ 2235 static constexpr T value{}; 2236}; 2237 2238template<typename T> 2239constexpr T static_const<T>::value; 2240} // namespace detail 2241} // namespace nlohmann 2242 2243// #include <nlohmann/detail/meta/type_traits.hpp> 2244 2245 2246#include <ciso646> // not 2247#include <limits> // numeric_limits 2248#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type 2249#include <utility> // declval 2250 2251// #include <nlohmann/detail/iterators/iterator_traits.hpp> 2252 2253 2254#include <iterator> // random_access_iterator_tag 2255 2256// #include <nlohmann/detail/meta/void_t.hpp> 2257 2258 2259namespace nlohmann 2260{ 2261namespace detail 2262{ 2263template <typename ...Ts> struct make_void 2264{ 2265 using type = void; 2266}; 2267template <typename ...Ts> using void_t = typename make_void<Ts...>::type; 2268} // namespace detail 2269} // namespace nlohmann 2270 2271// #include <nlohmann/detail/meta/cpp_future.hpp> 2272 2273 2274namespace nlohmann 2275{ 2276namespace detail 2277{ 2278template <typename It, typename = void> 2279struct iterator_types {}; 2280 2281template <typename It> 2282struct iterator_types < 2283 It, 2284 void_t<typename It::difference_type, typename It::value_type, typename It::pointer, 2285 typename It::reference, typename It::iterator_category >> 2286{ 2287 using difference_type = typename It::difference_type; 2288 using value_type = typename It::value_type; 2289 using pointer = typename It::pointer; 2290 using reference = typename It::reference; 2291 using iterator_category = typename It::iterator_category; 2292}; 2293 2294// This is required as some compilers implement std::iterator_traits in a way that 2295// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. 2296template <typename T, typename = void> 2297struct iterator_traits 2298{ 2299}; 2300 2301template <typename T> 2302struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >> 2303 : iterator_types<T> 2304{ 2305}; 2306 2307template <typename T> 2308struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>> 2309{ 2310 using iterator_category = std::random_access_iterator_tag; 2311 using value_type = T; 2312 using difference_type = ptrdiff_t; 2313 using pointer = T*; 2314 using reference = T&; 2315}; 2316} // namespace detail 2317} // namespace nlohmann 2318 2319// #include <nlohmann/detail/macro_scope.hpp> 2320 2321// #include <nlohmann/detail/meta/cpp_future.hpp> 2322 2323// #include <nlohmann/detail/meta/detected.hpp> 2324 2325 2326#include <type_traits> 2327 2328// #include <nlohmann/detail/meta/void_t.hpp> 2329 2330 2331// http://en.cppreference.com/w/cpp/experimental/is_detected 2332namespace nlohmann 2333{ 2334namespace detail 2335{ 2336struct nonesuch 2337{ 2338 nonesuch() = delete; 2339 ~nonesuch() = delete; 2340 nonesuch(nonesuch const&) = delete; 2341 nonesuch(nonesuch const&&) = delete; 2342 void operator=(nonesuch const&) = delete; 2343 void operator=(nonesuch&&) = delete; 2344}; 2345 2346template <class Default, 2347 class AlwaysVoid, 2348 template <class...> class Op, 2349 class... Args> 2350struct detector 2351{ 2352 using value_t = std::false_type; 2353 using type = Default; 2354}; 2355 2356template <class Default, template <class...> class Op, class... Args> 2357struct detector<Default, void_t<Op<Args...>>, Op, Args...> 2358{ 2359 using value_t = std::true_type; 2360 using type = Op<Args...>; 2361}; 2362 2363template <template <class...> class Op, class... Args> 2364using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t; 2365 2366template <template <class...> class Op, class... Args> 2367using detected_t = typename detector<nonesuch, void, Op, Args...>::type; 2368 2369template <class Default, template <class...> class Op, class... Args> 2370using detected_or = detector<Default, void, Op, Args...>; 2371 2372template <class Default, template <class...> class Op, class... Args> 2373using detected_or_t = typename detected_or<Default, Op, Args...>::type; 2374 2375template <class Expected, template <class...> class Op, class... Args> 2376using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>; 2377 2378template <class To, template <class...> class Op, class... Args> 2379using is_detected_convertible = 2380 std::is_convertible<detected_t<Op, Args...>, To>; 2381} // namespace detail 2382} // namespace nlohmann 2383 2384// #include <nlohmann/json_fwd.hpp> 2385#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ 2386#define INCLUDE_NLOHMANN_JSON_FWD_HPP_ 2387 2388#include <cstdint> // int64_t, uint64_t 2389#include <map> // map 2390#include <memory> // allocator 2391#include <string> // string 2392#include <vector> // vector 2393 2394/*! 2395@brief namespace for Niels Lohmann 2396@see https://github.com/nlohmann 2397@since version 1.0.0 2398*/ 2399namespace nlohmann 2400{ 2401/*! 2402@brief default JSONSerializer template argument 2403 2404This serializer ignores the template arguments and uses ADL 2405([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) 2406for serialization. 2407*/ 2408template<typename T = void, typename SFINAE = void> 2409struct adl_serializer; 2410 2411template<template<typename U, typename V, typename... Args> class ObjectType = 2412 std::map, 2413 template<typename U, typename... Args> class ArrayType = std::vector, 2414 class StringType = std::string, class BooleanType = bool, 2415 class NumberIntegerType = std::int64_t, 2416 class NumberUnsignedType = std::uint64_t, 2417 class NumberFloatType = double, 2418 template<typename U> class AllocatorType = std::allocator, 2419 template<typename T, typename SFINAE = void> class JSONSerializer = 2420 adl_serializer> 2421class basic_json; 2422 2423/*! 2424@brief JSON Pointer 2425 2426A JSON pointer defines a string syntax for identifying a specific value 2427within a JSON document. It can be used with functions `at` and 2428`operator[]`. Furthermore, JSON pointers are the base for JSON patches. 2429 2430@sa [RFC 6901](https://tools.ietf.org/html/rfc6901) 2431 2432@since version 2.0.0 2433*/ 2434template<typename BasicJsonType> 2435class json_pointer; 2436 2437/*! 2438@brief default JSON class 2439 2440This type is the default specialization of the @ref basic_json class which 2441uses the standard template types. 2442 2443@since version 1.0.0 2444*/ 2445using json = basic_json<>; 2446} // namespace nlohmann 2447 2448#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ 2449 2450 2451namespace nlohmann 2452{ 2453/*! 2454@brief detail namespace with internal helper functions 2455 2456This namespace collects functions that should not be exposed, 2457implementations of some @ref basic_json methods, and meta-programming helpers. 2458 2459@since version 2.1.0 2460*/ 2461namespace detail 2462{ 2463///////////// 2464// helpers // 2465///////////// 2466 2467// Note to maintainers: 2468// 2469// Every trait in this file expects a non CV-qualified type. 2470// The only exceptions are in the 'aliases for detected' section 2471// (i.e. those of the form: decltype(T::member_function(std::declval<T>()))) 2472// 2473// In this case, T has to be properly CV-qualified to constraint the function arguments 2474// (e.g. to_json(BasicJsonType&, const T&)) 2475 2476template<typename> struct is_basic_json : std::false_type {}; 2477 2478NLOHMANN_BASIC_JSON_TPL_DECLARATION 2479struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {}; 2480 2481////////////////////////// 2482// aliases for detected // 2483////////////////////////// 2484 2485template <typename T> 2486using mapped_type_t = typename T::mapped_type; 2487 2488template <typename T> 2489using key_type_t = typename T::key_type; 2490 2491template <typename T> 2492using value_type_t = typename T::value_type; 2493 2494template <typename T> 2495using difference_type_t = typename T::difference_type; 2496 2497template <typename T> 2498using pointer_t = typename T::pointer; 2499 2500template <typename T> 2501using reference_t = typename T::reference; 2502 2503template <typename T> 2504using iterator_category_t = typename T::iterator_category; 2505 2506template <typename T> 2507using iterator_t = typename T::iterator; 2508 2509template <typename T, typename... Args> 2510using to_json_function = decltype(T::to_json(std::declval<Args>()...)); 2511 2512template <typename T, typename... Args> 2513using from_json_function = decltype(T::from_json(std::declval<Args>()...)); 2514 2515template <typename T, typename U> 2516using get_template_function = decltype(std::declval<T>().template get<U>()); 2517 2518// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists 2519template <typename BasicJsonType, typename T, typename = void> 2520struct has_from_json : std::false_type {}; 2521 2522template <typename BasicJsonType, typename T> 2523struct has_from_json<BasicJsonType, T, 2524 enable_if_t<not is_basic_json<T>::value>> 2525{ 2526 using serializer = typename BasicJsonType::template json_serializer<T, void>; 2527 2528 static constexpr bool value = 2529 is_detected_exact<void, from_json_function, serializer, 2530 const BasicJsonType&, T&>::value; 2531}; 2532 2533// This trait checks if JSONSerializer<T>::from_json(json const&) exists 2534// this overload is used for non-default-constructible user-defined-types 2535template <typename BasicJsonType, typename T, typename = void> 2536struct has_non_default_from_json : std::false_type {}; 2537 2538template<typename BasicJsonType, typename T> 2539struct has_non_default_from_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>> 2540{ 2541 using serializer = typename BasicJsonType::template json_serializer<T, void>; 2542 2543 static constexpr bool value = 2544 is_detected_exact<T, from_json_function, serializer, 2545 const BasicJsonType&>::value; 2546}; 2547 2548// This trait checks if BasicJsonType::json_serializer<T>::to_json exists 2549// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion. 2550template <typename BasicJsonType, typename T, typename = void> 2551struct has_to_json : std::false_type {}; 2552 2553template <typename BasicJsonType, typename T> 2554struct has_to_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>> 2555{ 2556 using serializer = typename BasicJsonType::template json_serializer<T, void>; 2557 2558 static constexpr bool value = 2559 is_detected_exact<void, to_json_function, serializer, BasicJsonType&, 2560 T>::value; 2561}; 2562 2563 2564/////////////////// 2565// is_ functions // 2566/////////////////// 2567 2568template <typename T, typename = void> 2569struct is_iterator_traits : std::false_type {}; 2570 2571template <typename T> 2572struct is_iterator_traits<iterator_traits<T>> 2573{ 2574 private: 2575 using traits = iterator_traits<T>; 2576 2577 public: 2578 static constexpr auto value = 2579 is_detected<value_type_t, traits>::value && 2580 is_detected<difference_type_t, traits>::value && 2581 is_detected<pointer_t, traits>::value && 2582 is_detected<iterator_category_t, traits>::value && 2583 is_detected<reference_t, traits>::value; 2584}; 2585 2586// source: https://stackoverflow.com/a/37193089/4116453 2587 2588template <typename T, typename = void> 2589struct is_complete_type : std::false_type {}; 2590 2591template <typename T> 2592struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {}; 2593 2594template <typename BasicJsonType, typename CompatibleObjectType, 2595 typename = void> 2596struct is_compatible_object_type_impl : std::false_type {}; 2597 2598template <typename BasicJsonType, typename CompatibleObjectType> 2599struct is_compatible_object_type_impl < 2600 BasicJsonType, CompatibleObjectType, 2601 enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value and 2602 is_detected<key_type_t, CompatibleObjectType>::value >> 2603{ 2604 2605 using object_t = typename BasicJsonType::object_t; 2606 2607 // macOS's is_constructible does not play well with nonesuch... 2608 static constexpr bool value = 2609 std::is_constructible<typename object_t::key_type, 2610 typename CompatibleObjectType::key_type>::value and 2611 std::is_constructible<typename object_t::mapped_type, 2612 typename CompatibleObjectType::mapped_type>::value; 2613}; 2614 2615template <typename BasicJsonType, typename CompatibleObjectType> 2616struct is_compatible_object_type 2617 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {}; 2618 2619template <typename BasicJsonType, typename ConstructibleObjectType, 2620 typename = void> 2621struct is_constructible_object_type_impl : std::false_type {}; 2622 2623template <typename BasicJsonType, typename ConstructibleObjectType> 2624struct is_constructible_object_type_impl < 2625 BasicJsonType, ConstructibleObjectType, 2626 enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value and 2627 is_detected<key_type_t, ConstructibleObjectType>::value >> 2628{ 2629 using object_t = typename BasicJsonType::object_t; 2630 2631 static constexpr bool value = 2632 (std::is_default_constructible<ConstructibleObjectType>::value and 2633 (std::is_move_assignable<ConstructibleObjectType>::value or 2634 std::is_copy_assignable<ConstructibleObjectType>::value) and 2635 (std::is_constructible<typename ConstructibleObjectType::key_type, 2636 typename object_t::key_type>::value and 2637 std::is_same < 2638 typename object_t::mapped_type, 2639 typename ConstructibleObjectType::mapped_type >::value)) or 2640 (has_from_json<BasicJsonType, 2641 typename ConstructibleObjectType::mapped_type>::value or 2642 has_non_default_from_json < 2643 BasicJsonType, 2644 typename ConstructibleObjectType::mapped_type >::value); 2645}; 2646 2647template <typename BasicJsonType, typename ConstructibleObjectType> 2648struct is_constructible_object_type 2649 : is_constructible_object_type_impl<BasicJsonType, 2650 ConstructibleObjectType> {}; 2651 2652template <typename BasicJsonType, typename CompatibleStringType, 2653 typename = void> 2654struct is_compatible_string_type_impl : std::false_type {}; 2655 2656template <typename BasicJsonType, typename CompatibleStringType> 2657struct is_compatible_string_type_impl < 2658 BasicJsonType, CompatibleStringType, 2659 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type, 2660 value_type_t, CompatibleStringType>::value >> 2661{ 2662 static constexpr auto value = 2663 std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value; 2664}; 2665 2666template <typename BasicJsonType, typename ConstructibleStringType> 2667struct is_compatible_string_type 2668 : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {}; 2669 2670template <typename BasicJsonType, typename ConstructibleStringType, 2671 typename = void> 2672struct is_constructible_string_type_impl : std::false_type {}; 2673 2674template <typename BasicJsonType, typename ConstructibleStringType> 2675struct is_constructible_string_type_impl < 2676 BasicJsonType, ConstructibleStringType, 2677 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type, 2678 value_type_t, ConstructibleStringType>::value >> 2679{ 2680 static constexpr auto value = 2681 std::is_constructible<ConstructibleStringType, 2682 typename BasicJsonType::string_t>::value; 2683}; 2684 2685template <typename BasicJsonType, typename ConstructibleStringType> 2686struct is_constructible_string_type 2687 : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {}; 2688 2689template <typename BasicJsonType, typename CompatibleArrayType, typename = void> 2690struct is_compatible_array_type_impl : std::false_type {}; 2691 2692template <typename BasicJsonType, typename CompatibleArrayType> 2693struct is_compatible_array_type_impl < 2694 BasicJsonType, CompatibleArrayType, 2695 enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value and 2696 is_detected<iterator_t, CompatibleArrayType>::value and 2697// This is needed because json_reverse_iterator has a ::iterator type... 2698// Therefore it is detected as a CompatibleArrayType. 2699// The real fix would be to have an Iterable concept. 2700 not is_iterator_traits< 2701 iterator_traits<CompatibleArrayType>>::value >> 2702{ 2703 static constexpr bool value = 2704 std::is_constructible<BasicJsonType, 2705 typename CompatibleArrayType::value_type>::value; 2706}; 2707 2708template <typename BasicJsonType, typename CompatibleArrayType> 2709struct is_compatible_array_type 2710 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {}; 2711 2712template <typename BasicJsonType, typename ConstructibleArrayType, typename = void> 2713struct is_constructible_array_type_impl : std::false_type {}; 2714 2715template <typename BasicJsonType, typename ConstructibleArrayType> 2716struct is_constructible_array_type_impl < 2717 BasicJsonType, ConstructibleArrayType, 2718 enable_if_t<std::is_same<ConstructibleArrayType, 2719 typename BasicJsonType::value_type>::value >> 2720 : std::true_type {}; 2721 2722template <typename BasicJsonType, typename ConstructibleArrayType> 2723struct is_constructible_array_type_impl < 2724 BasicJsonType, ConstructibleArrayType, 2725 enable_if_t<not std::is_same<ConstructibleArrayType, 2726 typename BasicJsonType::value_type>::value and 2727 std::is_default_constructible<ConstructibleArrayType>::value and 2728(std::is_move_assignable<ConstructibleArrayType>::value or 2729 std::is_copy_assignable<ConstructibleArrayType>::value) and 2730is_detected<value_type_t, ConstructibleArrayType>::value and 2731is_detected<iterator_t, ConstructibleArrayType>::value and 2732is_complete_type< 2733detected_t<value_type_t, ConstructibleArrayType>>::value >> 2734{ 2735 static constexpr bool value = 2736 // This is needed because json_reverse_iterator has a ::iterator type, 2737 // furthermore, std::back_insert_iterator (and other iterators) have a 2738 // base class `iterator`... Therefore it is detected as a 2739 // ConstructibleArrayType. The real fix would be to have an Iterable 2740 // concept. 2741 not is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value and 2742 2743 (std::is_same<typename ConstructibleArrayType::value_type, 2744 typename BasicJsonType::array_t::value_type>::value or 2745 has_from_json<BasicJsonType, 2746 typename ConstructibleArrayType::value_type>::value or 2747 has_non_default_from_json < 2748 BasicJsonType, typename ConstructibleArrayType::value_type >::value); 2749}; 2750 2751template <typename BasicJsonType, typename ConstructibleArrayType> 2752struct is_constructible_array_type 2753 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {}; 2754 2755template <typename RealIntegerType, typename CompatibleNumberIntegerType, 2756 typename = void> 2757struct is_compatible_integer_type_impl : std::false_type {}; 2758 2759template <typename RealIntegerType, typename CompatibleNumberIntegerType> 2760struct is_compatible_integer_type_impl < 2761 RealIntegerType, CompatibleNumberIntegerType, 2762 enable_if_t<std::is_integral<RealIntegerType>::value and 2763 std::is_integral<CompatibleNumberIntegerType>::value and 2764 not std::is_same<bool, CompatibleNumberIntegerType>::value >> 2765{ 2766 // is there an assert somewhere on overflows? 2767 using RealLimits = std::numeric_limits<RealIntegerType>; 2768 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>; 2769 2770 static constexpr auto value = 2771 std::is_constructible<RealIntegerType, 2772 CompatibleNumberIntegerType>::value and 2773 CompatibleLimits::is_integer and 2774 RealLimits::is_signed == CompatibleLimits::is_signed; 2775}; 2776 2777template <typename RealIntegerType, typename CompatibleNumberIntegerType> 2778struct is_compatible_integer_type 2779 : is_compatible_integer_type_impl<RealIntegerType, 2780 CompatibleNumberIntegerType> {}; 2781 2782template <typename BasicJsonType, typename CompatibleType, typename = void> 2783struct is_compatible_type_impl: std::false_type {}; 2784 2785template <typename BasicJsonType, typename CompatibleType> 2786struct is_compatible_type_impl < 2787 BasicJsonType, CompatibleType, 2788 enable_if_t<is_complete_type<CompatibleType>::value >> 2789{ 2790 static constexpr bool value = 2791 has_to_json<BasicJsonType, CompatibleType>::value; 2792}; 2793 2794template <typename BasicJsonType, typename CompatibleType> 2795struct is_compatible_type 2796 : is_compatible_type_impl<BasicJsonType, CompatibleType> {}; 2797 2798// https://en.cppreference.com/w/cpp/types/conjunction 2799template<class...> struct conjunction : std::true_type { }; 2800template<class B1> struct conjunction<B1> : B1 { }; 2801template<class B1, class... Bn> 2802struct conjunction<B1, Bn...> 2803: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {}; 2804 2805template <typename T1, typename T2> 2806struct is_constructible_tuple : std::false_type {}; 2807 2808template <typename T1, typename... Args> 2809struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {}; 2810} // namespace detail 2811} // namespace nlohmann 2812 2813// #include <nlohmann/detail/value_t.hpp> 2814 2815 2816#include <array> // array 2817#include <ciso646> // and 2818#include <cstddef> // size_t 2819#include <cstdint> // uint8_t 2820#include <string> // string 2821 2822namespace nlohmann 2823{ 2824namespace detail 2825{ 2826/////////////////////////// 2827// JSON type enumeration // 2828/////////////////////////// 2829 2830/*! 2831@brief the JSON type enumeration 2832 2833This enumeration collects the different JSON types. It is internally used to 2834distinguish the stored values, and the functions @ref basic_json::is_null(), 2835@ref basic_json::is_object(), @ref basic_json::is_array(), 2836@ref basic_json::is_string(), @ref basic_json::is_boolean(), 2837@ref basic_json::is_number() (with @ref basic_json::is_number_integer(), 2838@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()), 2839@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and 2840@ref basic_json::is_structured() rely on it. 2841 2842@note There are three enumeration entries (number_integer, number_unsigned, and 2843number_float), because the library distinguishes these three types for numbers: 2844@ref basic_json::number_unsigned_t is used for unsigned integers, 2845@ref basic_json::number_integer_t is used for signed integers, and 2846@ref basic_json::number_float_t is used for floating-point numbers or to 2847approximate integers which do not fit in the limits of their respective type. 2848 2849@sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON 2850value with the default value for a given type 2851 2852@since version 1.0.0 2853*/ 2854enum class value_t : std::uint8_t 2855{ 2856 null, ///< null value 2857 object, ///< object (unordered set of name/value pairs) 2858 array, ///< array (ordered collection of values) 2859 string, ///< string value 2860 boolean, ///< boolean value 2861 number_integer, ///< number value (signed integer) 2862 number_unsigned, ///< number value (unsigned integer) 2863 number_float, ///< number value (floating-point) 2864 discarded ///< discarded by the the parser callback function 2865}; 2866 2867/*! 2868@brief comparison operator for JSON types 2869 2870Returns an ordering that is similar to Python: 2871- order: null < boolean < number < object < array < string 2872- furthermore, each type is not smaller than itself 2873- discarded values are not comparable 2874 2875@since version 1.0.0 2876*/ 2877inline bool operator<(const value_t lhs, const value_t rhs) noexcept 2878{ 2879 static constexpr std::array<std::uint8_t, 8> order = {{ 2880 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */, 2881 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */ 2882 } 2883 }; 2884 2885 const auto l_index = static_cast<std::size_t>(lhs); 2886 const auto r_index = static_cast<std::size_t>(rhs); 2887 return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index]; 2888} 2889} // namespace detail 2890} // namespace nlohmann 2891 2892 2893namespace nlohmann 2894{ 2895namespace detail 2896{ 2897template<typename BasicJsonType> 2898void from_json(const BasicJsonType& j, typename std::nullptr_t& n) 2899{ 2900 if (JSON_HEDLEY_UNLIKELY(not j.is_null())) 2901 { 2902 JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()))); 2903 } 2904 n = nullptr; 2905} 2906 2907// overloads for basic_json template parameters 2908template<typename BasicJsonType, typename ArithmeticType, 2909 enable_if_t<std::is_arithmetic<ArithmeticType>::value and 2910 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value, 2911 int> = 0> 2912void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val) 2913{ 2914 switch (static_cast<value_t>(j)) 2915 { 2916 case value_t::number_unsigned: 2917 { 2918 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>()); 2919 break; 2920 } 2921 case value_t::number_integer: 2922 { 2923 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>()); 2924 break; 2925 } 2926 case value_t::number_float: 2927 { 2928 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>()); 2929 break; 2930 } 2931 2932 default: 2933 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()))); 2934 } 2935} 2936 2937template<typename BasicJsonType> 2938void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b) 2939{ 2940 if (JSON_HEDLEY_UNLIKELY(not j.is_boolean())) 2941 { 2942 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()))); 2943 } 2944 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>(); 2945} 2946 2947template<typename BasicJsonType> 2948void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s) 2949{ 2950 if (JSON_HEDLEY_UNLIKELY(not j.is_string())) 2951 { 2952 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()))); 2953 } 2954 s = *j.template get_ptr<const typename BasicJsonType::string_t*>(); 2955} 2956 2957template < 2958 typename BasicJsonType, typename ConstructibleStringType, 2959 enable_if_t < 2960 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value and 2961 not std::is_same<typename BasicJsonType::string_t, 2962 ConstructibleStringType>::value, 2963 int > = 0 > 2964void from_json(const BasicJsonType& j, ConstructibleStringType& s) 2965{ 2966 if (JSON_HEDLEY_UNLIKELY(not j.is_string())) 2967 { 2968 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()))); 2969 } 2970 2971 s = *j.template get_ptr<const typename BasicJsonType::string_t*>(); 2972} 2973 2974template<typename BasicJsonType> 2975void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val) 2976{ 2977 get_arithmetic_value(j, val); 2978} 2979 2980template<typename BasicJsonType> 2981void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val) 2982{ 2983 get_arithmetic_value(j, val); 2984} 2985 2986template<typename BasicJsonType> 2987void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val) 2988{ 2989 get_arithmetic_value(j, val); 2990} 2991 2992template<typename BasicJsonType, typename EnumType, 2993 enable_if_t<std::is_enum<EnumType>::value, int> = 0> 2994void from_json(const BasicJsonType& j, EnumType& e) 2995{ 2996 typename std::underlying_type<EnumType>::type val; 2997 get_arithmetic_value(j, val); 2998 e = static_cast<EnumType>(val); 2999} 3000 3001// forward_list doesn't have an insert method 3002template<typename BasicJsonType, typename T, typename Allocator, 3003 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0> 3004void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l) 3005{ 3006 if (JSON_HEDLEY_UNLIKELY(not j.is_array())) 3007 { 3008 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); 3009 } 3010 l.clear(); 3011 std::transform(j.rbegin(), j.rend(), 3012 std::front_inserter(l), [](const BasicJsonType & i) 3013 { 3014 return i.template get<T>(); 3015 }); 3016} 3017 3018// valarray doesn't have an insert method 3019template<typename BasicJsonType, typename T, 3020 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0> 3021void from_json(const BasicJsonType& j, std::valarray<T>& l) 3022{ 3023 if (JSON_HEDLEY_UNLIKELY(not j.is_array())) 3024 { 3025 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); 3026 } 3027 l.resize(j.size()); 3028 std::copy(j.begin(), j.end(), std::begin(l)); 3029} 3030 3031template <typename BasicJsonType, typename T, std::size_t N> 3032auto from_json(const BasicJsonType& j, T (&arr)[N]) 3033-> decltype(j.template get<T>(), void()) 3034{ 3035 for (std::size_t i = 0; i < N; ++i) 3036 { 3037 arr[i] = j.at(i).template get<T>(); 3038 } 3039} 3040 3041template<typename BasicJsonType> 3042void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/) 3043{ 3044 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>(); 3045} 3046 3047template <typename BasicJsonType, typename T, std::size_t N> 3048auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr, 3049 priority_tag<2> /*unused*/) 3050-> decltype(j.template get<T>(), void()) 3051{ 3052 for (std::size_t i = 0; i < N; ++i) 3053 { 3054 arr[i] = j.at(i).template get<T>(); 3055 } 3056} 3057 3058template<typename BasicJsonType, typename ConstructibleArrayType> 3059auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/) 3060-> decltype( 3061 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()), 3062 j.template get<typename ConstructibleArrayType::value_type>(), 3063 void()) 3064{ 3065 using std::end; 3066 3067 ConstructibleArrayType ret; 3068 ret.reserve(j.size()); 3069 std::transform(j.begin(), j.end(), 3070 std::inserter(ret, end(ret)), [](const BasicJsonType & i) 3071 { 3072 // get<BasicJsonType>() returns *this, this won't call a from_json 3073 // method when value_type is BasicJsonType 3074 return i.template get<typename ConstructibleArrayType::value_type>(); 3075 }); 3076 arr = std::move(ret); 3077} 3078 3079template <typename BasicJsonType, typename ConstructibleArrayType> 3080void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, 3081 priority_tag<0> /*unused*/) 3082{ 3083 using std::end; 3084 3085 ConstructibleArrayType ret; 3086 std::transform( 3087 j.begin(), j.end(), std::inserter(ret, end(ret)), 3088 [](const BasicJsonType & i) 3089 { 3090 // get<BasicJsonType>() returns *this, this won't call a from_json 3091 // method when value_type is BasicJsonType 3092 return i.template get<typename ConstructibleArrayType::value_type>(); 3093 }); 3094 arr = std::move(ret); 3095} 3096 3097template <typename BasicJsonType, typename ConstructibleArrayType, 3098 enable_if_t < 3099 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and 3100 not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and 3101 not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and 3102 not is_basic_json<ConstructibleArrayType>::value, 3103 int > = 0 > 3104 3105auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr) 3106-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}), 3107j.template get<typename ConstructibleArrayType::value_type>(), 3108void()) 3109{ 3110 if (JSON_HEDLEY_UNLIKELY(not j.is_array())) 3111 { 3112 JSON_THROW(type_error::create(302, "type must be array, but is " + 3113 std::string(j.type_name()))); 3114 } 3115 3116 from_json_array_impl(j, arr, priority_tag<3> {}); 3117} 3118 3119template<typename BasicJsonType, typename ConstructibleObjectType, 3120 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0> 3121void from_json(const BasicJsonType& j, ConstructibleObjectType& obj) 3122{ 3123 if (JSON_HEDLEY_UNLIKELY(not j.is_object())) 3124 { 3125 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()))); 3126 } 3127 3128 ConstructibleObjectType ret; 3129 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>(); 3130 using value_type = typename ConstructibleObjectType::value_type; 3131 std::transform( 3132 inner_object->begin(), inner_object->end(), 3133 std::inserter(ret, ret.begin()), 3134 [](typename BasicJsonType::object_t::value_type const & p) 3135 { 3136 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>()); 3137 }); 3138 obj = std::move(ret); 3139} 3140 3141// overload for arithmetic types, not chosen for basic_json template arguments 3142// (BooleanType, etc..); note: Is it really necessary to provide explicit 3143// overloads for boolean_t etc. in case of a custom BooleanType which is not 3144// an arithmetic type? 3145template<typename BasicJsonType, typename ArithmeticType, 3146 enable_if_t < 3147 std::is_arithmetic<ArithmeticType>::value and 3148 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and 3149 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and 3150 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and 3151 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value, 3152 int> = 0> 3153void from_json(const BasicJsonType& j, ArithmeticType& val) 3154{ 3155 switch (static_cast<value_t>(j)) 3156 { 3157 case value_t::number_unsigned: 3158 { 3159 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>()); 3160 break; 3161 } 3162 case value_t::number_integer: 3163 { 3164 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>()); 3165 break; 3166 } 3167 case value_t::number_float: 3168 { 3169 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>()); 3170 break; 3171 } 3172 case value_t::boolean: 3173 { 3174 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>()); 3175 break; 3176 } 3177 3178 default: 3179 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()))); 3180 } 3181} 3182 3183template<typename BasicJsonType, typename A1, typename A2> 3184void from_json(const BasicJsonType& j, std::pair<A1, A2>& p) 3185{ 3186 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()}; 3187} 3188 3189template<typename BasicJsonType, typename Tuple, std::size_t... Idx> 3190void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/) 3191{ 3192 t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...); 3193} 3194 3195template<typename BasicJsonType, typename... Args> 3196void from_json(const BasicJsonType& j, std::tuple<Args...>& t) 3197{ 3198 from_json_tuple_impl(j, t, index_sequence_for<Args...> {}); 3199} 3200 3201template <typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator, 3202 typename = enable_if_t<not std::is_constructible< 3203 typename BasicJsonType::string_t, Key>::value>> 3204void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m) 3205{ 3206 if (JSON_HEDLEY_UNLIKELY(not j.is_array())) 3207 { 3208 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); 3209 } 3210 m.clear(); 3211 for (const auto& p : j) 3212 { 3213 if (JSON_HEDLEY_UNLIKELY(not p.is_array())) 3214 { 3215 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()))); 3216 } 3217 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>()); 3218 } 3219} 3220 3221template <typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator, 3222 typename = enable_if_t<not std::is_constructible< 3223 typename BasicJsonType::string_t, Key>::value>> 3224void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m) 3225{ 3226 if (JSON_HEDLEY_UNLIKELY(not j.is_array())) 3227 { 3228 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); 3229 } 3230 m.clear(); 3231 for (const auto& p : j) 3232 { 3233 if (JSON_HEDLEY_UNLIKELY(not p.is_array())) 3234 { 3235 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()))); 3236 } 3237 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>()); 3238 } 3239} 3240 3241struct from_json_fn 3242{ 3243 template<typename BasicJsonType, typename T> 3244 auto operator()(const BasicJsonType& j, T& val) const 3245 noexcept(noexcept(from_json(j, val))) 3246 -> decltype(from_json(j, val), void()) 3247 { 3248 return from_json(j, val); 3249 } 3250}; 3251} // namespace detail 3252 3253/// namespace to hold default `from_json` function 3254/// to see why this is required: 3255/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html 3256namespace 3257{ 3258constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; 3259} // namespace 3260} // namespace nlohmann 3261 3262// #include <nlohmann/detail/conversions/to_json.hpp> 3263 3264 3265#include <algorithm> // copy 3266#include <ciso646> // or, and, not 3267#include <iterator> // begin, end 3268#include <string> // string 3269#include <tuple> // tuple, get 3270#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type 3271#include <utility> // move, forward, declval, pair 3272#include <valarray> // valarray 3273#include <vector> // vector 3274 3275// #include <nlohmann/detail/iterators/iteration_proxy.hpp> 3276 3277 3278#include <cstddef> // size_t 3279#include <iterator> // input_iterator_tag 3280#include <string> // string, to_string 3281#include <tuple> // tuple_size, get, tuple_element 3282 3283// #include <nlohmann/detail/meta/type_traits.hpp> 3284 3285// #include <nlohmann/detail/value_t.hpp> 3286 3287 3288namespace nlohmann 3289{ 3290namespace detail 3291{ 3292template<typename string_type> 3293void int_to_string( string_type& target, std::size_t value ) 3294{ 3295 target = std::to_string(value); 3296} 3297template <typename IteratorType> class iteration_proxy_value 3298{ 3299 public: 3300 using difference_type = std::ptrdiff_t; 3301 using value_type = iteration_proxy_value; 3302 using pointer = value_type * ; 3303 using reference = value_type & ; 3304 using iterator_category = std::input_iterator_tag; 3305 using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type; 3306 3307 private: 3308 /// the iterator 3309 IteratorType anchor; 3310 /// an index for arrays (used to create key names) 3311 std::size_t array_index = 0; 3312 /// last stringified array index 3313 mutable std::size_t array_index_last = 0; 3314 /// a string representation of the array index 3315 mutable string_type array_index_str = "0"; 3316 /// an empty string (to return a reference for primitive values) 3317 const string_type empty_str = ""; 3318 3319 public: 3320 explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {} 3321 3322 /// dereference operator (needed for range-based for) 3323 iteration_proxy_value& operator*() 3324 { 3325 return *this; 3326 } 3327 3328 /// increment operator (needed for range-based for) 3329 iteration_proxy_value& operator++() 3330 { 3331 ++anchor; 3332 ++array_index; 3333 3334 return *this; 3335 } 3336 3337 /// equality operator (needed for InputIterator) 3338 bool operator==(const iteration_proxy_value& o) const 3339 { 3340 return anchor == o.anchor; 3341 } 3342 3343 /// inequality operator (needed for range-based for) 3344 bool operator!=(const iteration_proxy_value& o) const 3345 { 3346 return anchor != o.anchor; 3347 } 3348 3349 /// return key of the iterator 3350 const string_type& key() const 3351 { 3352 assert(anchor.m_object != nullptr); 3353 3354 switch (anchor.m_object->type()) 3355 { 3356 // use integer array index as key 3357 case value_t::array: 3358 { 3359 if (array_index != array_index_last) 3360 { 3361 int_to_string( array_index_str, array_index ); 3362 array_index_last = array_index; 3363 } 3364 return array_index_str; 3365 } 3366 3367 // use key from the object 3368 case value_t::object: 3369 return anchor.key(); 3370 3371 // use an empty key for all primitive types 3372 default: 3373 return empty_str; 3374 } 3375 } 3376 3377 /// return value of the iterator 3378 typename IteratorType::reference value() const 3379 { 3380 return anchor.value(); 3381 } 3382}; 3383 3384/// proxy class for the items() function 3385template<typename IteratorType> class iteration_proxy 3386{ 3387 private: 3388 /// the container to iterate 3389 typename IteratorType::reference container; 3390 3391 public: 3392 /// construct iteration proxy from a container 3393 explicit iteration_proxy(typename IteratorType::reference cont) noexcept 3394 : container(cont) {} 3395 3396 /// return iterator begin (needed for range-based for) 3397 iteration_proxy_value<IteratorType> begin() noexcept 3398 { 3399 return iteration_proxy_value<IteratorType>(container.begin()); 3400 } 3401 3402 /// return iterator end (needed for range-based for) 3403 iteration_proxy_value<IteratorType> end() noexcept 3404 { 3405 return iteration_proxy_value<IteratorType>(container.end()); 3406 } 3407}; 3408// Structured Bindings Support 3409// For further reference see https://blog.tartanllama.xyz/structured-bindings/ 3410// And see https://github.com/nlohmann/json/pull/1391 3411template <std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0> 3412auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key()) 3413{ 3414 return i.key(); 3415} 3416// Structured Bindings Support 3417// For further reference see https://blog.tartanllama.xyz/structured-bindings/ 3418// And see https://github.com/nlohmann/json/pull/1391 3419template <std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0> 3420auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value()) 3421{ 3422 return i.value(); 3423} 3424} // namespace detail 3425} // namespace nlohmann 3426 3427// The Addition to the STD Namespace is required to add 3428// Structured Bindings Support to the iteration_proxy_value class 3429// For further reference see https://blog.tartanllama.xyz/structured-bindings/ 3430// And see https://github.com/nlohmann/json/pull/1391 3431namespace std 3432{ 3433#if defined(__clang__) 3434 // Fix: https://github.com/nlohmann/json/issues/1401 3435 #pragma clang diagnostic push 3436 #pragma clang diagnostic ignored "-Wmismatched-tags" 3437#endif 3438template <typename IteratorType> 3439class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> 3440 : public std::integral_constant<std::size_t, 2> {}; 3441 3442template <std::size_t N, typename IteratorType> 3443class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >> 3444{ 3445 public: 3446 using type = decltype( 3447 get<N>(std::declval < 3448 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ())); 3449}; 3450#if defined(__clang__) 3451 #pragma clang diagnostic pop 3452#endif 3453} // namespace std 3454 3455// #include <nlohmann/detail/meta/cpp_future.hpp> 3456 3457// #include <nlohmann/detail/meta/type_traits.hpp> 3458 3459// #include <nlohmann/detail/value_t.hpp> 3460 3461 3462namespace nlohmann 3463{ 3464namespace detail 3465{ 3466////////////////// 3467// constructors // 3468////////////////// 3469 3470template<value_t> struct external_constructor; 3471 3472template<> 3473struct external_constructor<value_t::boolean> 3474{ 3475 template<typename BasicJsonType> 3476 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept 3477 { 3478 j.m_type = value_t::boolean; 3479 j.m_value = b; 3480 j.assert_invariant(); 3481 } 3482}; 3483 3484template<> 3485struct external_constructor<value_t::string> 3486{ 3487 template<typename BasicJsonType> 3488 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s) 3489 { 3490 j.m_type = value_t::string; 3491 j.m_value = s; 3492 j.assert_invariant(); 3493 } 3494 3495 template<typename BasicJsonType> 3496 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s) 3497 { 3498 j.m_type = value_t::string; 3499 j.m_value = std::move(s); 3500 j.assert_invariant(); 3501 } 3502 3503 template<typename BasicJsonType, typename CompatibleStringType, 3504 enable_if_t<not std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value, 3505 int> = 0> 3506 static void construct(BasicJsonType& j, const CompatibleStringType& str) 3507 { 3508 j.m_type = value_t::string; 3509 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str); 3510 j.assert_invariant(); 3511 } 3512}; 3513 3514template<> 3515struct external_constructor<value_t::number_float> 3516{ 3517 template<typename BasicJsonType> 3518 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept 3519 { 3520 j.m_type = value_t::number_float; 3521 j.m_value = val; 3522 j.assert_invariant(); 3523 } 3524}; 3525 3526template<> 3527struct external_constructor<value_t::number_unsigned> 3528{ 3529 template<typename BasicJsonType> 3530 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept 3531 { 3532 j.m_type = value_t::number_unsigned; 3533 j.m_value = val; 3534 j.assert_invariant(); 3535 } 3536}; 3537 3538template<> 3539struct external_constructor<value_t::number_integer> 3540{ 3541 template<typename BasicJsonType> 3542 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept 3543 { 3544 j.m_type = value_t::number_integer; 3545 j.m_value = val; 3546 j.assert_invariant(); 3547 } 3548}; 3549 3550template<> 3551struct external_constructor<value_t::array> 3552{ 3553 template<typename BasicJsonType> 3554 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr) 3555 { 3556 j.m_type = value_t::array; 3557 j.m_value = arr; 3558 j.assert_invariant(); 3559 } 3560 3561 template<typename BasicJsonType> 3562 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr) 3563 { 3564 j.m_type = value_t::array; 3565 j.m_value = std::move(arr); 3566 j.assert_invariant(); 3567 } 3568 3569 template<typename BasicJsonType, typename CompatibleArrayType, 3570 enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value, 3571 int> = 0> 3572 static void construct(BasicJsonType& j, const CompatibleArrayType& arr) 3573 { 3574 using std::begin; 3575 using std::end; 3576 j.m_type = value_t::array; 3577 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr)); 3578 j.assert_invariant(); 3579 } 3580 3581 template<typename BasicJsonType> 3582 static void construct(BasicJsonType& j, const std::vector<bool>& arr) 3583 { 3584 j.m_type = value_t::array; 3585 j.m_value = value_t::array; 3586 j.m_value.array->reserve(arr.size()); 3587 for (const bool x : arr) 3588 { 3589 j.m_value.array->push_back(x); 3590 } 3591 j.assert_invariant(); 3592 } 3593 3594 template<typename BasicJsonType, typename T, 3595 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0> 3596 static void construct(BasicJsonType& j, const std::valarray<T>& arr) 3597 { 3598 j.m_type = value_t::array; 3599 j.m_value = value_t::array; 3600 j.m_value.array->resize(arr.size()); 3601 if (arr.size() > 0) 3602 { 3603 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin()); 3604 } 3605 j.assert_invariant(); 3606 } 3607}; 3608 3609template<> 3610struct external_constructor<value_t::object> 3611{ 3612 template<typename BasicJsonType> 3613 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj) 3614 { 3615 j.m_type = value_t::object; 3616 j.m_value = obj; 3617 j.assert_invariant(); 3618 } 3619 3620 template<typename BasicJsonType> 3621 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj) 3622 { 3623 j.m_type = value_t::object; 3624 j.m_value = std::move(obj); 3625 j.assert_invariant(); 3626 } 3627 3628 template<typename BasicJsonType, typename CompatibleObjectType, 3629 enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0> 3630 static void construct(BasicJsonType& j, const CompatibleObjectType& obj) 3631 { 3632 using std::begin; 3633 using std::end; 3634 3635 j.m_type = value_t::object; 3636 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj)); 3637 j.assert_invariant(); 3638 } 3639}; 3640 3641///////////// 3642// to_json // 3643///////////// 3644 3645template<typename BasicJsonType, typename T, 3646 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0> 3647void to_json(BasicJsonType& j, T b) noexcept 3648{ 3649 external_constructor<value_t::boolean>::construct(j, b); 3650} 3651 3652template<typename BasicJsonType, typename CompatibleString, 3653 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0> 3654void to_json(BasicJsonType& j, const CompatibleString& s) 3655{ 3656 external_constructor<value_t::string>::construct(j, s); 3657} 3658 3659template<typename BasicJsonType> 3660void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s) 3661{ 3662 external_constructor<value_t::string>::construct(j, std::move(s)); 3663} 3664 3665template<typename BasicJsonType, typename FloatType, 3666 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0> 3667void to_json(BasicJsonType& j, FloatType val) noexcept 3668{ 3669 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val)); 3670} 3671 3672template<typename BasicJsonType, typename CompatibleNumberUnsignedType, 3673 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0> 3674void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept 3675{ 3676 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val)); 3677} 3678 3679template<typename BasicJsonType, typename CompatibleNumberIntegerType, 3680 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0> 3681void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept 3682{ 3683 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val)); 3684} 3685 3686template<typename BasicJsonType, typename EnumType, 3687 enable_if_t<std::is_enum<EnumType>::value, int> = 0> 3688void to_json(BasicJsonType& j, EnumType e) noexcept 3689{ 3690 using underlying_type = typename std::underlying_type<EnumType>::type; 3691 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e)); 3692} 3693 3694template<typename BasicJsonType> 3695void to_json(BasicJsonType& j, const std::vector<bool>& e) 3696{ 3697 external_constructor<value_t::array>::construct(j, e); 3698} 3699 3700template <typename BasicJsonType, typename CompatibleArrayType, 3701 enable_if_t<is_compatible_array_type<BasicJsonType, 3702 CompatibleArrayType>::value and 3703 not is_compatible_object_type< 3704 BasicJsonType, CompatibleArrayType>::value and 3705 not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and 3706 not is_basic_json<CompatibleArrayType>::value, 3707 int> = 0> 3708void to_json(BasicJsonType& j, const CompatibleArrayType& arr) 3709{ 3710 external_constructor<value_t::array>::construct(j, arr); 3711} 3712 3713template<typename BasicJsonType, typename T, 3714 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0> 3715void to_json(BasicJsonType& j, const std::valarray<T>& arr) 3716{ 3717 external_constructor<value_t::array>::construct(j, std::move(arr)); 3718} 3719 3720template<typename BasicJsonType> 3721void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr) 3722{ 3723 external_constructor<value_t::array>::construct(j, std::move(arr)); 3724} 3725 3726template<typename BasicJsonType, typename CompatibleObjectType, 3727 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value and not is_basic_json<CompatibleObjectType>::value, int> = 0> 3728void to_json(BasicJsonType& j, const CompatibleObjectType& obj) 3729{ 3730 external_constructor<value_t::object>::construct(j, obj); 3731} 3732 3733template<typename BasicJsonType> 3734void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj) 3735{ 3736 external_constructor<value_t::object>::construct(j, std::move(obj)); 3737} 3738 3739template < 3740 typename BasicJsonType, typename T, std::size_t N, 3741 enable_if_t<not std::is_constructible<typename BasicJsonType::string_t, 3742 const T(&)[N]>::value, 3743 int> = 0 > 3744void to_json(BasicJsonType& j, const T(&arr)[N]) 3745{ 3746 external_constructor<value_t::array>::construct(j, arr); 3747} 3748 3749template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 > 3750void to_json(BasicJsonType& j, const std::pair<T1, T2>& p) 3751{ 3752 j = { p.first, p.second }; 3753} 3754 3755// for https://github.com/nlohmann/json/pull/1134 3756template < typename BasicJsonType, typename T, 3757 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0> 3758void to_json(BasicJsonType& j, const T& b) 3759{ 3760 j = { {b.key(), b.value()} }; 3761} 3762 3763template<typename BasicJsonType, typename Tuple, std::size_t... Idx> 3764void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/) 3765{ 3766 j = { std::get<Idx>(t)... }; 3767} 3768 3769template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0> 3770void to_json(BasicJsonType& j, const T& t) 3771{ 3772 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {}); 3773} 3774 3775struct to_json_fn 3776{ 3777 template<typename BasicJsonType, typename T> 3778 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val)))) 3779 -> decltype(to_json(j, std::forward<T>(val)), void()) 3780 { 3781 return to_json(j, std::forward<T>(val)); 3782 } 3783}; 3784} // namespace detail 3785 3786/// namespace to hold default `to_json` function 3787namespace 3788{ 3789constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; 3790} // namespace 3791} // namespace nlohmann 3792 3793 3794namespace nlohmann 3795{ 3796 3797template<typename, typename> 3798struct adl_serializer 3799{ 3800 /*! 3801 @brief convert a JSON value to any value type 3802 3803 This function is usually called by the `get()` function of the 3804 @ref basic_json class (either explicit or via conversion operators). 3805 3806 @param[in] j JSON value to read from 3807 @param[in,out] val value to write to 3808 */ 3809 template<typename BasicJsonType, typename ValueType> 3810 static auto from_json(BasicJsonType&& j, ValueType& val) noexcept( 3811 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val))) 3812 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void()) 3813 { 3814 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val); 3815 } 3816 3817 /*! 3818 @brief convert any value type to a JSON value 3819 3820 This function is usually called by the constructors of the @ref basic_json 3821 class. 3822 3823 @param[in,out] j JSON value to write to 3824 @param[in] val value to read from 3825 */ 3826 template <typename BasicJsonType, typename ValueType> 3827 static auto to_json(BasicJsonType& j, ValueType&& val) noexcept( 3828 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val)))) 3829 -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void()) 3830 { 3831 ::nlohmann::to_json(j, std::forward<ValueType>(val)); 3832 } 3833}; 3834 3835} // namespace nlohmann 3836 3837// #include <nlohmann/detail/conversions/from_json.hpp> 3838 3839// #include <nlohmann/detail/conversions/to_json.hpp> 3840 3841// #include <nlohmann/detail/exceptions.hpp> 3842 3843// #include <nlohmann/detail/input/binary_reader.hpp> 3844 3845 3846#include <algorithm> // generate_n 3847#include <array> // array 3848#include <cassert> // assert 3849#include <cmath> // ldexp 3850#include <cstddef> // size_t 3851#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t 3852#include <cstdio> // snprintf 3853#include <cstring> // memcpy 3854#include <iterator> // back_inserter 3855#include <limits> // numeric_limits 3856#include <string> // char_traits, string 3857#include <utility> // make_pair, move 3858 3859// #include <nlohmann/detail/exceptions.hpp> 3860 3861// #include <nlohmann/detail/input/input_adapters.hpp> 3862 3863 3864#include <array> // array 3865#include <cassert> // assert 3866#include <cstddef> // size_t 3867#include <cstdio> //FILE * 3868#include <cstring> // strlen 3869#include <istream> // istream 3870#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next 3871#include <memory> // shared_ptr, make_shared, addressof 3872#include <numeric> // accumulate 3873#include <string> // string, char_traits 3874#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer 3875#include <utility> // pair, declval 3876 3877// #include <nlohmann/detail/iterators/iterator_traits.hpp> 3878 3879// #include <nlohmann/detail/macro_scope.hpp> 3880 3881 3882namespace nlohmann 3883{ 3884namespace detail 3885{ 3886/// the supported input formats 3887enum class input_format_t { json, cbor, msgpack, ubjson, bson }; 3888 3889//////////////////// 3890// input adapters // 3891//////////////////// 3892 3893/*! 3894@brief abstract input adapter interface 3895 3896Produces a stream of std::char_traits<char>::int_type characters from a 3897std::istream, a buffer, or some other input type. Accepts the return of 3898exactly one non-EOF character for future input. The int_type characters 3899returned consist of all valid char values as positive values (typically 3900unsigned char), plus an EOF value outside that range, specified by the value 3901of the function std::char_traits<char>::eof(). This value is typically -1, but 3902could be any arbitrary value which is not a valid char value. 3903*/ 3904struct input_adapter_protocol 3905{ 3906 /// get a character [0,255] or std::char_traits<char>::eof(). 3907 virtual std::char_traits<char>::int_type get_character() = 0; 3908 virtual ~input_adapter_protocol() = default; 3909}; 3910 3911/// a type to simplify interfaces 3912using input_adapter_t = std::shared_ptr<input_adapter_protocol>; 3913 3914/*! 3915Input adapter for stdio file access. This adapter read only 1 byte and do not use any 3916 buffer. This adapter is a very low level adapter. 3917*/ 3918class file_input_adapter : public input_adapter_protocol 3919{ 3920 public: 3921 JSON_HEDLEY_NON_NULL(2) 3922 explicit file_input_adapter(std::FILE* f) noexcept 3923 : m_file(f) 3924 {} 3925 3926 // make class move-only 3927 file_input_adapter(const file_input_adapter&) = delete; 3928 file_input_adapter(file_input_adapter&&) = default; 3929 file_input_adapter& operator=(const file_input_adapter&) = delete; 3930 file_input_adapter& operator=(file_input_adapter&&) = default; 3931 ~file_input_adapter() override = default; 3932 3933 std::char_traits<char>::int_type get_character() noexcept override 3934 { 3935 return std::fgetc(m_file); 3936 } 3937 3938 private: 3939 /// the file pointer to read from 3940 std::FILE* m_file; 3941}; 3942 3943 3944/*! 3945Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at 3946beginning of input. Does not support changing the underlying std::streambuf 3947in mid-input. Maintains underlying std::istream and std::streambuf to support 3948subsequent use of standard std::istream operations to process any input 3949characters following those used in parsing the JSON input. Clears the 3950std::istream flags; any input errors (e.g., EOF) will be detected by the first 3951subsequent call for input from the std::istream. 3952*/ 3953class input_stream_adapter : public input_adapter_protocol 3954{ 3955 public: 3956 ~input_stream_adapter() override 3957 { 3958 // clear stream flags; we use underlying streambuf I/O, do not 3959 // maintain ifstream flags, except eof 3960 is.clear(is.rdstate() & std::ios::eofbit); 3961 } 3962 3963 explicit input_stream_adapter(std::istream& i) 3964 : is(i), sb(*i.rdbuf()) 3965 {} 3966 3967 // delete because of pointer members 3968 input_stream_adapter(const input_stream_adapter&) = delete; 3969 input_stream_adapter& operator=(input_stream_adapter&) = delete; 3970 input_stream_adapter(input_stream_adapter&&) = delete; 3971 input_stream_adapter& operator=(input_stream_adapter&&) = delete; 3972 3973 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to 3974 // ensure that std::char_traits<char>::eof() and the character 0xFF do not 3975 // end up as the same value, eg. 0xFFFFFFFF. 3976 std::char_traits<char>::int_type get_character() override 3977 { 3978 auto res = sb.sbumpc(); 3979 // set eof manually, as we don't use the istream interface. 3980 if (res == EOF) 3981 { 3982 is.clear(is.rdstate() | std::ios::eofbit); 3983 } 3984 return res; 3985 } 3986 3987 private: 3988 /// the associated input stream 3989 std::istream& is; 3990 std::streambuf& sb; 3991}; 3992 3993/// input adapter for buffer input 3994class input_buffer_adapter : public input_adapter_protocol 3995{ 3996 public: 3997 input_buffer_adapter(const char* b, const std::size_t l) noexcept 3998 : cursor(b), limit(b == nullptr ? nullptr : (b + l)) 3999 {} 4000 4001 // delete because of pointer members 4002 input_buffer_adapter(const input_buffer_adapter&) = delete; 4003 input_buffer_adapter& operator=(input_buffer_adapter&) = delete; 4004 input_buffer_adapter(input_buffer_adapter&&) = delete; 4005 input_buffer_adapter& operator=(input_buffer_adapter&&) = delete; 4006 ~input_buffer_adapter() override = default; 4007 4008 std::char_traits<char>::int_type get_character() noexcept override 4009 { 4010 if (JSON_HEDLEY_LIKELY(cursor < limit)) 4011 { 4012 assert(cursor != nullptr and limit != nullptr); 4013 return std::char_traits<char>::to_int_type(*(cursor++)); 4014 } 4015 4016 return std::char_traits<char>::eof(); 4017 } 4018 4019 private: 4020 /// pointer to the current character 4021 const char* cursor; 4022 /// pointer past the last character 4023 const char* const limit; 4024}; 4025 4026template<typename WideStringType, size_t T> 4027struct wide_string_input_helper 4028{ 4029 // UTF-32 4030 static void fill_buffer(const WideStringType& str, 4031 size_t& current_wchar, 4032 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes, 4033 size_t& utf8_bytes_index, 4034 size_t& utf8_bytes_filled) 4035 { 4036 utf8_bytes_index = 0; 4037 4038 if (current_wchar == str.size()) 4039 { 4040 utf8_bytes[0] = std::char_traits<char>::eof(); 4041 utf8_bytes_filled = 1; 4042 } 4043 else 4044 { 4045 // get the current character 4046 const auto wc = static_cast<unsigned int>(str[current_wchar++]); 4047 4048 // UTF-32 to UTF-8 encoding 4049 if (wc < 0x80) 4050 { 4051 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc); 4052 utf8_bytes_filled = 1; 4053 } 4054 else if (wc <= 0x7FF) 4055 { 4056 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u) & 0x1Fu)); 4057 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu)); 4058 utf8_bytes_filled = 2; 4059 } 4060 else if (wc <= 0xFFFF) 4061 { 4062 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u) & 0x0Fu)); 4063 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu)); 4064 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu)); 4065 utf8_bytes_filled = 3; 4066 } 4067 else if (wc <= 0x10FFFF) 4068 { 4069 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((wc >> 18u) & 0x07u)); 4070 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 12u) & 0x3Fu)); 4071 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu)); 4072 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu)); 4073 utf8_bytes_filled = 4; 4074 } 4075 else 4076 { 4077 // unknown character 4078 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc); 4079 utf8_bytes_filled = 1; 4080 } 4081 } 4082 } 4083}; 4084 4085template<typename WideStringType> 4086struct wide_string_input_helper<WideStringType, 2> 4087{ 4088 // UTF-16 4089 static void fill_buffer(const WideStringType& str, 4090 size_t& current_wchar, 4091 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes, 4092 size_t& utf8_bytes_index, 4093 size_t& utf8_bytes_filled) 4094 { 4095 utf8_bytes_index = 0; 4096 4097 if (current_wchar == str.size()) 4098 { 4099 utf8_bytes[0] = std::char_traits<char>::eof(); 4100 utf8_bytes_filled = 1; 4101 } 4102 else 4103 { 4104 // get the current character 4105 const auto wc = static_cast<unsigned int>(str[current_wchar++]); 4106 4107 // UTF-16 to UTF-8 encoding 4108 if (wc < 0x80) 4109 { 4110 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc); 4111 utf8_bytes_filled = 1; 4112 } 4113 else if (wc <= 0x7FF) 4114 { 4115 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u))); 4116 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu)); 4117 utf8_bytes_filled = 2; 4118 } 4119 else if (0xD800 > wc or wc >= 0xE000) 4120 { 4121 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u))); 4122 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu)); 4123 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu)); 4124 utf8_bytes_filled = 3; 4125 } 4126 else 4127 { 4128 if (current_wchar < str.size()) 4129 { 4130 const auto wc2 = static_cast<unsigned int>(str[current_wchar++]); 4131 const auto charcode = 0x10000u + (((wc & 0x3FFu) << 10u) | (wc2 & 0x3FFu)); 4132 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u)); 4133 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu)); 4134 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu)); 4135 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu)); 4136 utf8_bytes_filled = 4; 4137 } 4138 else 4139 { 4140 // unknown character 4141 ++current_wchar; 4142 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc); 4143 utf8_bytes_filled = 1; 4144 } 4145 } 4146 } 4147 } 4148}; 4149 4150template<typename WideStringType> 4151class wide_string_input_adapter : public input_adapter_protocol 4152{ 4153 public: 4154 explicit wide_string_input_adapter(const WideStringType& w) noexcept 4155 : str(w) 4156 {} 4157 4158 std::char_traits<char>::int_type get_character() noexcept override 4159 { 4160 // check if buffer needs to be filled 4161 if (utf8_bytes_index == utf8_bytes_filled) 4162 { 4163 fill_buffer<sizeof(typename WideStringType::value_type)>(); 4164 4165 assert(utf8_bytes_filled > 0); 4166 assert(utf8_bytes_index == 0); 4167 } 4168 4169 // use buffer 4170 assert(utf8_bytes_filled > 0); 4171 assert(utf8_bytes_index < utf8_bytes_filled); 4172 return utf8_bytes[utf8_bytes_index++]; 4173 } 4174 4175 private: 4176 template<size_t T> 4177 void fill_buffer() 4178 { 4179 wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled); 4180 } 4181 4182 /// the wstring to process 4183 const WideStringType& str; 4184 4185 /// index of the current wchar in str 4186 std::size_t current_wchar = 0; 4187 4188 /// a buffer for UTF-8 bytes 4189 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}}; 4190 4191 /// index to the utf8_codes array for the next valid byte 4192 std::size_t utf8_bytes_index = 0; 4193 /// number of valid bytes in the utf8_codes array 4194 std::size_t utf8_bytes_filled = 0; 4195}; 4196 4197class input_adapter 4198{ 4199 public: 4200 // native support 4201 JSON_HEDLEY_NON_NULL(2) 4202 input_adapter(std::FILE* file) 4203 : ia(std::make_shared<file_input_adapter>(file)) {} 4204 /// input adapter for input stream 4205 input_adapter(std::istream& i) 4206 : ia(std::make_shared<input_stream_adapter>(i)) {} 4207 4208 /// input adapter for input stream 4209 input_adapter(std::istream&& i) 4210 : ia(std::make_shared<input_stream_adapter>(i)) {} 4211 4212 input_adapter(const std::wstring& ws) 4213 : ia(std::make_shared<wide_string_input_adapter<std::wstring>>(ws)) {} 4214 4215 input_adapter(const std::u16string& ws) 4216 : ia(std::make_shared<wide_string_input_adapter<std::u16string>>(ws)) {} 4217 4218 input_adapter(const std::u32string& ws) 4219 : ia(std::make_shared<wide_string_input_adapter<std::u32string>>(ws)) {} 4220 4221 /// input adapter for buffer 4222 template<typename CharT, 4223 typename std::enable_if< 4224 std::is_pointer<CharT>::value and 4225 std::is_integral<typename std::remove_pointer<CharT>::type>::value and 4226 sizeof(typename std::remove_pointer<CharT>::type) == 1, 4227 int>::type = 0> 4228 input_adapter(CharT b, std::size_t l) 4229 : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {} 4230 4231 // derived support 4232 4233 /// input adapter for string literal 4234 template<typename CharT, 4235 typename std::enable_if< 4236 std::is_pointer<CharT>::value and 4237 std::is_integral<typename std::remove_pointer<CharT>::type>::value and 4238 sizeof(typename std::remove_pointer<CharT>::type) == 1, 4239 int>::type = 0> 4240 input_adapter(CharT b) 4241 : input_adapter(reinterpret_cast<const char*>(b), 4242 std::strlen(reinterpret_cast<const char*>(b))) {} 4243 4244 /// input adapter for iterator range with contiguous storage 4245 template<class IteratorType, 4246 typename std::enable_if< 4247 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value, 4248 int>::type = 0> 4249 input_adapter(IteratorType first, IteratorType last) 4250 { 4251#ifndef NDEBUG 4252 // assertion to check that the iterator range is indeed contiguous, 4253 // see http://stackoverflow.com/a/35008842/266378 for more discussion 4254 const auto is_contiguous = std::accumulate( 4255 first, last, std::pair<bool, int>(true, 0), 4256 [&first](std::pair<bool, int> res, decltype(*first) val) 4257 { 4258 res.first &= (val == *(std::next(std::addressof(*first), res.second++))); 4259 return res; 4260 }).first; 4261 assert(is_contiguous); 4262#endif 4263 4264 // assertion to check that each element is 1 byte long 4265 static_assert( 4266 sizeof(typename iterator_traits<IteratorType>::value_type) == 1, 4267 "each element in the iterator range must have the size of 1 byte"); 4268 4269 const auto len = static_cast<size_t>(std::distance(first, last)); 4270 if (JSON_HEDLEY_LIKELY(len > 0)) 4271 { 4272 // there is at least one element: use the address of first 4273 ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len); 4274 } 4275 else 4276 { 4277 // the address of first cannot be used: use nullptr 4278 ia = std::make_shared<input_buffer_adapter>(nullptr, len); 4279 } 4280 } 4281 4282 /// input adapter for array 4283 template<class T, std::size_t N> 4284 input_adapter(T (&array)[N]) 4285 : input_adapter(std::begin(array), std::end(array)) {} 4286 4287 /// input adapter for contiguous container 4288 template<class ContiguousContainer, typename 4289 std::enable_if<not std::is_pointer<ContiguousContainer>::value and 4290 std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value, 4291 int>::type = 0> 4292 input_adapter(const ContiguousContainer& c) 4293 : input_adapter(std::begin(c), std::end(c)) {} 4294 4295 operator input_adapter_t() 4296 { 4297 return ia; 4298 } 4299 4300 private: 4301 /// the actual adapter 4302 input_adapter_t ia = nullptr; 4303}; 4304} // namespace detail 4305} // namespace nlohmann 4306 4307// #include <nlohmann/detail/input/json_sax.hpp> 4308 4309 4310#include <cassert> // assert 4311#include <cstddef> 4312#include <string> // string 4313#include <utility> // move 4314#include <vector> // vector 4315 4316// #include <nlohmann/detail/exceptions.hpp> 4317 4318// #include <nlohmann/detail/macro_scope.hpp> 4319 4320 4321namespace nlohmann 4322{ 4323 4324/*! 4325@brief SAX interface 4326 4327This class describes the SAX interface used by @ref nlohmann::json::sax_parse. 4328Each function is called in different situations while the input is parsed. The 4329boolean return value informs the parser whether to continue processing the 4330input. 4331*/ 4332template<typename BasicJsonType> 4333struct json_sax 4334{ 4335 /// type for (signed) integers 4336 using number_integer_t = typename BasicJsonType::number_integer_t; 4337 /// type for unsigned integers 4338 using number_unsigned_t = typename BasicJsonType::number_unsigned_t; 4339 /// type for floating-point numbers 4340 using number_float_t = typename BasicJsonType::number_float_t; 4341 /// type for strings 4342 using string_t = typename BasicJsonType::string_t; 4343 4344 /*! 4345 @brief a null value was read 4346 @return whether parsing should proceed 4347 */ 4348 virtual bool null() = 0; 4349 4350 /*! 4351 @brief a boolean value was read 4352 @param[in] val boolean value 4353 @return whether parsing should proceed 4354 */ 4355 virtual bool boolean(bool val) = 0; 4356 4357 /*! 4358 @brief an integer number was read 4359 @param[in] val integer value 4360 @return whether parsing should proceed 4361 */ 4362 virtual bool number_integer(number_integer_t val) = 0; 4363 4364 /*! 4365 @brief an unsigned integer number was read 4366 @param[in] val unsigned integer value 4367 @return whether parsing should proceed 4368 */ 4369 virtual bool number_unsigned(number_unsigned_t val) = 0; 4370 4371 /*! 4372 @brief an floating-point number was read 4373 @param[in] val floating-point value 4374 @param[in] s raw token value 4375 @return whether parsing should proceed 4376 */ 4377 virtual bool number_float(number_float_t val, const string_t& s) = 0; 4378 4379 /*! 4380 @brief a string was read 4381 @param[in] val string value 4382 @return whether parsing should proceed 4383 @note It is safe to move the passed string. 4384 */ 4385 virtual bool string(string_t& val) = 0; 4386 4387 /*! 4388 @brief the beginning of an object was read 4389 @param[in] elements number of object elements or -1 if unknown 4390 @return whether parsing should proceed 4391 @note binary formats may report the number of elements 4392 */ 4393 virtual bool start_object(std::size_t elements) = 0; 4394 4395 /*! 4396 @brief an object key was read 4397 @param[in] val object key 4398 @return whether parsing should proceed 4399 @note It is safe to move the passed string. 4400 */ 4401 virtual bool key(string_t& val) = 0; 4402 4403 /*! 4404 @brief the end of an object was read 4405 @return whether parsing should proceed 4406 */ 4407 virtual bool end_object() = 0; 4408 4409 /*! 4410 @brief the beginning of an array was read 4411 @param[in] elements number of array elements or -1 if unknown 4412 @return whether parsing should proceed 4413 @note binary formats may report the number of elements 4414 */ 4415 virtual bool start_array(std::size_t elements) = 0; 4416 4417 /*! 4418 @brief the end of an array was read 4419 @return whether parsing should proceed 4420 */ 4421 virtual bool end_array() = 0; 4422 4423 /*! 4424 @brief a parse error occurred 4425 @param[in] position the position in the input where the error occurs 4426 @param[in] last_token the last read token 4427 @param[in] ex an exception object describing the error 4428 @return whether parsing should proceed (must return false) 4429 */ 4430 virtual bool parse_error(std::size_t position, 4431 const std::string& last_token, 4432 const detail::exception& ex) = 0; 4433 4434 virtual ~json_sax() = default; 4435}; 4436 4437 4438namespace detail 4439{ 4440/*! 4441@brief SAX implementation to create a JSON value from SAX events 4442 4443This class implements the @ref json_sax interface and processes the SAX events 4444to create a JSON value which makes it basically a DOM parser. The structure or 4445hierarchy of the JSON value is managed by the stack `ref_stack` which contains 4446a pointer to the respective array or object for each recursion depth. 4447 4448After successful parsing, the value that is passed by reference to the 4449constructor contains the parsed value. 4450 4451@tparam BasicJsonType the JSON type 4452*/ 4453template<typename BasicJsonType> 4454class json_sax_dom_parser 4455{ 4456 public: 4457 using number_integer_t = typename BasicJsonType::number_integer_t; 4458 using number_unsigned_t = typename BasicJsonType::number_unsigned_t; 4459 using number_float_t = typename BasicJsonType::number_float_t; 4460 using string_t = typename BasicJsonType::string_t; 4461 4462 /*! 4463 @param[in, out] r reference to a JSON value that is manipulated while 4464 parsing 4465 @param[in] allow_exceptions_ whether parse errors yield exceptions 4466 */ 4467 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true) 4468 : root(r), allow_exceptions(allow_exceptions_) 4469 {} 4470 4471 // make class move-only 4472 json_sax_dom_parser(const json_sax_dom_parser&) = delete; 4473 json_sax_dom_parser(json_sax_dom_parser&&) = default; 4474 json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete; 4475 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; 4476 ~json_sax_dom_parser() = default; 4477 4478 bool null() 4479 { 4480 handle_value(nullptr); 4481 return true; 4482 } 4483 4484 bool boolean(bool val) 4485 { 4486 handle_value(val); 4487 return true; 4488 } 4489 4490 bool number_integer(number_integer_t val) 4491 { 4492 handle_value(val); 4493 return true; 4494 } 4495 4496 bool number_unsigned(number_unsigned_t val) 4497 { 4498 handle_value(val); 4499 return true; 4500 } 4501 4502 bool number_float(number_float_t val, const string_t& /*unused*/) 4503 { 4504 handle_value(val); 4505 return true; 4506 } 4507 4508 bool string(string_t& val) 4509 { 4510 handle_value(val); 4511 return true; 4512 } 4513 4514 bool start_object(std::size_t len) 4515 { 4516 ref_stack.push_back(handle_value(BasicJsonType::value_t::object)); 4517 4518 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size())) 4519 { 4520 JSON_THROW(out_of_range::create(408, 4521 "excessive object size: " + std::to_string(len))); 4522 } 4523 4524 return true; 4525 } 4526 4527 bool key(string_t& val) 4528 { 4529 // add null at given key and store the reference for later 4530 object_element = &(ref_stack.back()->m_value.object->operator[](val)); 4531 return true; 4532 } 4533 4534 bool end_object() 4535 { 4536 ref_stack.pop_back(); 4537 return true; 4538 } 4539 4540 bool start_array(std::size_t len) 4541 { 4542 ref_stack.push_back(handle_value(BasicJsonType::value_t::array)); 4543 4544 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size())) 4545 { 4546 JSON_THROW(out_of_range::create(408, 4547 "excessive array size: " + std::to_string(len))); 4548 } 4549 4550 return true; 4551 } 4552 4553 bool end_array() 4554 { 4555 ref_stack.pop_back(); 4556 return true; 4557 } 4558 4559 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, 4560 const detail::exception& ex) 4561 { 4562 errored = true; 4563 if (allow_exceptions) 4564 { 4565 // determine the proper exception type from the id 4566 switch ((ex.id / 100) % 100) 4567 { 4568 case 1: 4569 JSON_THROW(*static_cast<const detail::parse_error*>(&ex)); 4570 case 4: 4571 JSON_THROW(*static_cast<const detail::out_of_range*>(&ex)); 4572 // LCOV_EXCL_START 4573 case 2: 4574 JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex)); 4575 case 3: 4576 JSON_THROW(*static_cast<const detail::type_error*>(&ex)); 4577 case 5: 4578 JSON_THROW(*static_cast<const detail::other_error*>(&ex)); 4579 default: 4580 assert(false); 4581 // LCOV_EXCL_STOP 4582 } 4583 } 4584 return false; 4585 } 4586 4587 constexpr bool is_errored() const 4588 { 4589 return errored; 4590 } 4591 4592 private: 4593 /*! 4594 @invariant If the ref stack is empty, then the passed value will be the new 4595 root. 4596 @invariant If the ref stack contains a value, then it is an array or an 4597 object to which we can add elements 4598 */ 4599 template<typename Value> 4600 JSON_HEDLEY_RETURNS_NON_NULL 4601 BasicJsonType* handle_value(Value&& v) 4602 { 4603 if (ref_stack.empty()) 4604 { 4605 root = BasicJsonType(std::forward<Value>(v)); 4606 return &root; 4607 } 4608 4609 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object()); 4610 4611 if (ref_stack.back()->is_array()) 4612 { 4613 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v)); 4614 return &(ref_stack.back()->m_value.array->back()); 4615 } 4616 4617 assert(ref_stack.back()->is_object()); 4618 assert(object_element); 4619 *object_element = BasicJsonType(std::forward<Value>(v)); 4620 return object_element; 4621 } 4622 4623 /// the parsed JSON value 4624 BasicJsonType& root; 4625 /// stack to model hierarchy of values 4626 std::vector<BasicJsonType*> ref_stack {}; 4627 /// helper to hold the reference for the next object element 4628 BasicJsonType* object_element = nullptr; 4629 /// whether a syntax error occurred 4630 bool errored = false; 4631 /// whether to throw exceptions in case of errors 4632 const bool allow_exceptions = true; 4633}; 4634 4635template<typename BasicJsonType> 4636class json_sax_dom_callback_parser 4637{ 4638 public: 4639 using number_integer_t = typename BasicJsonType::number_integer_t; 4640 using number_unsigned_t = typename BasicJsonType::number_unsigned_t; 4641 using number_float_t = typename BasicJsonType::number_float_t; 4642 using string_t = typename BasicJsonType::string_t; 4643 using parser_callback_t = typename BasicJsonType::parser_callback_t; 4644 using parse_event_t = typename BasicJsonType::parse_event_t; 4645 4646 json_sax_dom_callback_parser(BasicJsonType& r, 4647 const parser_callback_t cb, 4648 const bool allow_exceptions_ = true) 4649 : root(r), callback(cb), allow_exceptions(allow_exceptions_) 4650 { 4651 keep_stack.push_back(true); 4652 } 4653 4654 // make class move-only 4655 json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete; 4656 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; 4657 json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete; 4658 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; 4659 ~json_sax_dom_callback_parser() = default; 4660 4661 bool null() 4662 { 4663 handle_value(nullptr); 4664 return true; 4665 } 4666 4667 bool boolean(bool val) 4668 { 4669 handle_value(val); 4670 return true; 4671 } 4672 4673 bool number_integer(number_integer_t val) 4674 { 4675 handle_value(val); 4676 return true; 4677 } 4678 4679 bool number_unsigned(number_unsigned_t val) 4680 { 4681 handle_value(val); 4682 return true; 4683 } 4684 4685 bool number_float(number_float_t val, const string_t& /*unused*/) 4686 { 4687 handle_value(val); 4688 return true; 4689 } 4690 4691 bool string(string_t& val) 4692 { 4693 handle_value(val); 4694 return true; 4695 } 4696 4697 bool start_object(std::size_t len) 4698 { 4699 // check callback for object start 4700 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded); 4701 keep_stack.push_back(keep); 4702 4703 auto val = handle_value(BasicJsonType::value_t::object, true); 4704 ref_stack.push_back(val.second); 4705 4706 // check object limit 4707 if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size())) 4708 { 4709 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len))); 4710 } 4711 4712 return true; 4713 } 4714 4715 bool key(string_t& val) 4716 { 4717 BasicJsonType k = BasicJsonType(val); 4718 4719 // check callback for key 4720 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k); 4721 key_keep_stack.push_back(keep); 4722 4723 // add discarded value at given key and store the reference for later 4724 if (keep and ref_stack.back()) 4725 { 4726 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded); 4727 } 4728 4729 return true; 4730 } 4731 4732 bool end_object() 4733 { 4734 if (ref_stack.back() and not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back())) 4735 { 4736 // discard object 4737 *ref_stack.back() = discarded; 4738 } 4739 4740 assert(not ref_stack.empty()); 4741 assert(not keep_stack.empty()); 4742 ref_stack.pop_back(); 4743 keep_stack.pop_back(); 4744 4745 if (not ref_stack.empty() and ref_stack.back() and ref_stack.back()->is_object()) 4746 { 4747 // remove discarded value 4748 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it) 4749 { 4750 if (it->is_discarded()) 4751 { 4752 ref_stack.back()->erase(it); 4753 break; 4754 } 4755 } 4756 } 4757 4758 return true; 4759 } 4760 4761 bool start_array(std::size_t len) 4762 { 4763 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded); 4764 keep_stack.push_back(keep); 4765 4766 auto val = handle_value(BasicJsonType::value_t::array, true); 4767 ref_stack.push_back(val.second); 4768 4769 // check array limit 4770 if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size())) 4771 { 4772 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len))); 4773 } 4774 4775 return true; 4776 } 4777 4778 bool end_array() 4779 { 4780 bool keep = true; 4781 4782 if (ref_stack.back()) 4783 { 4784 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back()); 4785 if (not keep) 4786 { 4787 // discard array 4788 *ref_stack.back() = discarded; 4789 } 4790 } 4791 4792 assert(not ref_stack.empty()); 4793 assert(not keep_stack.empty()); 4794 ref_stack.pop_back(); 4795 keep_stack.pop_back(); 4796 4797 // remove discarded value 4798 if (not keep and not ref_stack.empty() and ref_stack.back()->is_array()) 4799 { 4800 ref_stack.back()->m_value.array->pop_back(); 4801 } 4802 4803 return true; 4804 } 4805 4806 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, 4807 const detail::exception& ex) 4808 { 4809 errored = true; 4810 if (allow_exceptions) 4811 { 4812 // determine the proper exception type from the id 4813 switch ((ex.id / 100) % 100) 4814 { 4815 case 1: 4816 JSON_THROW(*static_cast<const detail::parse_error*>(&ex)); 4817 case 4: 4818 JSON_THROW(*static_cast<const detail::out_of_range*>(&ex)); 4819 // LCOV_EXCL_START 4820 case 2: 4821 JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex)); 4822 case 3: 4823 JSON_THROW(*static_cast<const detail::type_error*>(&ex)); 4824 case 5: 4825 JSON_THROW(*static_cast<const detail::other_error*>(&ex)); 4826 default: 4827 assert(false); 4828 // LCOV_EXCL_STOP 4829 } 4830 } 4831 return false; 4832 } 4833 4834 constexpr bool is_errored() const 4835 { 4836 return errored; 4837 } 4838 4839 private: 4840 /*! 4841 @param[in] v value to add to the JSON value we build during parsing 4842 @param[in] skip_callback whether we should skip calling the callback 4843 function; this is required after start_array() and 4844 start_object() SAX events, because otherwise we would call the 4845 callback function with an empty array or object, respectively. 4846 4847 @invariant If the ref stack is empty, then the passed value will be the new 4848 root. 4849 @invariant If the ref stack contains a value, then it is an array or an 4850 object to which we can add elements 4851 4852 @return pair of boolean (whether value should be kept) and pointer (to the 4853 passed value in the ref_stack hierarchy; nullptr if not kept) 4854 */ 4855 template<typename Value> 4856 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false) 4857 { 4858 assert(not keep_stack.empty()); 4859 4860 // do not handle this value if we know it would be added to a discarded 4861 // container 4862 if (not keep_stack.back()) 4863 { 4864 return {false, nullptr}; 4865 } 4866 4867 // create value 4868 auto value = BasicJsonType(std::forward<Value>(v)); 4869 4870 // check callback 4871 const bool keep = skip_callback or callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value); 4872 4873 // do not handle this value if we just learnt it shall be discarded 4874 if (not keep) 4875 { 4876 return {false, nullptr}; 4877 } 4878 4879 if (ref_stack.empty()) 4880 { 4881 root = std::move(value); 4882 return {true, &root}; 4883 } 4884 4885 // skip this value if we already decided to skip the parent 4886 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360) 4887 if (not ref_stack.back()) 4888 { 4889 return {false, nullptr}; 4890 } 4891 4892 // we now only expect arrays and objects 4893 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object()); 4894 4895 // array 4896 if (ref_stack.back()->is_array()) 4897 { 4898 ref_stack.back()->m_value.array->push_back(std::move(value)); 4899 return {true, &(ref_stack.back()->m_value.array->back())}; 4900 } 4901 4902 // object 4903 assert(ref_stack.back()->is_object()); 4904 // check if we should store an element for the current key 4905 assert(not key_keep_stack.empty()); 4906 const bool store_element = key_keep_stack.back(); 4907 key_keep_stack.pop_back(); 4908 4909 if (not store_element) 4910 { 4911 return {false, nullptr}; 4912 } 4913 4914 assert(object_element); 4915 *object_element = std::move(value); 4916 return {true, object_element}; 4917 } 4918 4919 /// the parsed JSON value 4920 BasicJsonType& root; 4921 /// stack to model hierarchy of values 4922 std::vector<BasicJsonType*> ref_stack {}; 4923 /// stack to manage which values to keep 4924 std::vector<bool> keep_stack {}; 4925 /// stack to manage which object keys to keep 4926 std::vector<bool> key_keep_stack {}; 4927 /// helper to hold the reference for the next object element 4928 BasicJsonType* object_element = nullptr; 4929 /// whether a syntax error occurred 4930 bool errored = false; 4931 /// callback function 4932 const parser_callback_t callback = nullptr; 4933 /// whether to throw exceptions in case of errors 4934 const bool allow_exceptions = true; 4935 /// a discarded value for the callback 4936 BasicJsonType discarded = BasicJsonType::value_t::discarded; 4937}; 4938 4939template<typename BasicJsonType> 4940class json_sax_acceptor 4941{ 4942 public: 4943 using number_integer_t = typename BasicJsonType::number_integer_t; 4944 using number_unsigned_t = typename BasicJsonType::number_unsigned_t; 4945 using number_float_t = typename BasicJsonType::number_float_t; 4946 using string_t = typename BasicJsonType::string_t; 4947 4948 bool null() 4949 { 4950 return true; 4951 } 4952 4953 bool boolean(bool /*unused*/) 4954 { 4955 return true; 4956 } 4957 4958 bool number_integer(number_integer_t /*unused*/) 4959 { 4960 return true; 4961 } 4962 4963 bool number_unsigned(number_unsigned_t /*unused*/) 4964 { 4965 return true; 4966 } 4967 4968 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/) 4969 { 4970 return true; 4971 } 4972 4973 bool string(string_t& /*unused*/) 4974 { 4975 return true; 4976 } 4977 4978 bool start_object(std::size_t /*unused*/ = std::size_t(-1)) 4979 { 4980 return true; 4981 } 4982 4983 bool key(string_t& /*unused*/) 4984 { 4985 return true; 4986 } 4987 4988 bool end_object() 4989 { 4990 return true; 4991 } 4992 4993 bool start_array(std::size_t /*unused*/ = std::size_t(-1)) 4994 { 4995 return true; 4996 } 4997 4998 bool end_array() 4999 { 5000 return true; 5001 } 5002 5003 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/) 5004 { 5005 return false; 5006 } 5007}; 5008} // namespace detail 5009 5010} // namespace nlohmann 5011 5012// #include <nlohmann/detail/macro_scope.hpp> 5013 5014// #include <nlohmann/detail/meta/is_sax.hpp> 5015 5016 5017#include <cstdint> // size_t 5018#include <utility> // declval 5019#include <string> // string 5020 5021// #include <nlohmann/detail/meta/detected.hpp> 5022 5023// #include <nlohmann/detail/meta/type_traits.hpp> 5024 5025 5026namespace nlohmann 5027{ 5028namespace detail 5029{ 5030template <typename T> 5031using null_function_t = decltype(std::declval<T&>().null()); 5032 5033template <typename T> 5034using boolean_function_t = 5035 decltype(std::declval<T&>().boolean(std::declval<bool>())); 5036 5037template <typename T, typename Integer> 5038using number_integer_function_t = 5039 decltype(std::declval<T&>().number_integer(std::declval<Integer>())); 5040 5041template <typename T, typename Unsigned> 5042using number_unsigned_function_t = 5043 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>())); 5044 5045template <typename T, typename Float, typename String> 5046using number_float_function_t = decltype(std::declval<T&>().number_float( 5047 std::declval<Float>(), std::declval<const String&>())); 5048 5049template <typename T, typename String> 5050using string_function_t = 5051 decltype(std::declval<T&>().string(std::declval<String&>())); 5052 5053template <typename T> 5054using start_object_function_t = 5055 decltype(std::declval<T&>().start_object(std::declval<std::size_t>())); 5056 5057template <typename T, typename String> 5058using key_function_t = 5059 decltype(std::declval<T&>().key(std::declval<String&>())); 5060 5061template <typename T> 5062using end_object_function_t = decltype(std::declval<T&>().end_object()); 5063 5064template <typename T> 5065using start_array_function_t = 5066 decltype(std::declval<T&>().start_array(std::declval<std::size_t>())); 5067 5068template <typename T> 5069using end_array_function_t = decltype(std::declval<T&>().end_array()); 5070 5071template <typename T, typename Exception> 5072using parse_error_function_t = decltype(std::declval<T&>().parse_error( 5073 std::declval<std::size_t>(), std::declval<const std::string&>(), 5074 std::declval<const Exception&>())); 5075 5076template <typename SAX, typename BasicJsonType> 5077struct is_sax 5078{ 5079 private: 5080 static_assert(is_basic_json<BasicJsonType>::value, 5081 "BasicJsonType must be of type basic_json<...>"); 5082 5083 using number_integer_t = typename BasicJsonType::number_integer_t; 5084 using number_unsigned_t = typename BasicJsonType::number_unsigned_t; 5085 using number_float_t = typename BasicJsonType::number_float_t; 5086 using string_t = typename BasicJsonType::string_t; 5087 using exception_t = typename BasicJsonType::exception; 5088 5089 public: 5090 static constexpr bool value = 5091 is_detected_exact<bool, null_function_t, SAX>::value && 5092 is_detected_exact<bool, boolean_function_t, SAX>::value && 5093 is_detected_exact<bool, number_integer_function_t, SAX, 5094 number_integer_t>::value && 5095 is_detected_exact<bool, number_unsigned_function_t, SAX, 5096 number_unsigned_t>::value && 5097 is_detected_exact<bool, number_float_function_t, SAX, number_float_t, 5098 string_t>::value && 5099 is_detected_exact<bool, string_function_t, SAX, string_t>::value && 5100 is_detected_exact<bool, start_object_function_t, SAX>::value && 5101 is_detected_exact<bool, key_function_t, SAX, string_t>::value && 5102 is_detected_exact<bool, end_object_function_t, SAX>::value && 5103 is_detected_exact<bool, start_array_function_t, SAX>::value && 5104 is_detected_exact<bool, end_array_function_t, SAX>::value && 5105 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value; 5106}; 5107 5108template <typename SAX, typename BasicJsonType> 5109struct is_sax_static_asserts 5110{ 5111 private: 5112 static_assert(is_basic_json<BasicJsonType>::value, 5113 "BasicJsonType must be of type basic_json<...>"); 5114 5115 using number_integer_t = typename BasicJsonType::number_integer_t; 5116 using number_unsigned_t = typename BasicJsonType::number_unsigned_t; 5117 using number_float_t = typename BasicJsonType::number_float_t; 5118 using string_t = typename BasicJsonType::string_t; 5119 using exception_t = typename BasicJsonType::exception; 5120 5121 public: 5122 static_assert(is_detected_exact<bool, null_function_t, SAX>::value, 5123 "Missing/invalid function: bool null()"); 5124 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value, 5125 "Missing/invalid function: bool boolean(bool)"); 5126 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value, 5127 "Missing/invalid function: bool boolean(bool)"); 5128 static_assert( 5129 is_detected_exact<bool, number_integer_function_t, SAX, 5130 number_integer_t>::value, 5131 "Missing/invalid function: bool number_integer(number_integer_t)"); 5132 static_assert( 5133 is_detected_exact<bool, number_unsigned_function_t, SAX, 5134 number_unsigned_t>::value, 5135 "Missing/invalid function: bool number_unsigned(number_unsigned_t)"); 5136 static_assert(is_detected_exact<bool, number_float_function_t, SAX, 5137 number_float_t, string_t>::value, 5138 "Missing/invalid function: bool number_float(number_float_t, const string_t&)"); 5139 static_assert( 5140 is_detected_exact<bool, string_function_t, SAX, string_t>::value, 5141 "Missing/invalid function: bool string(string_t&)"); 5142 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value, 5143 "Missing/invalid function: bool start_object(std::size_t)"); 5144 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value, 5145 "Missing/invalid function: bool key(string_t&)"); 5146 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value, 5147 "Missing/invalid function: bool end_object()"); 5148 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value, 5149 "Missing/invalid function: bool start_array(std::size_t)"); 5150 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value, 5151 "Missing/invalid function: bool end_array()"); 5152 static_assert( 5153 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value, 5154 "Missing/invalid function: bool parse_error(std::size_t, const " 5155 "std::string&, const exception&)"); 5156}; 5157} // namespace detail 5158} // namespace nlohmann 5159 5160// #include <nlohmann/detail/value_t.hpp> 5161 5162 5163namespace nlohmann 5164{ 5165namespace detail 5166{ 5167/////////////////// 5168// binary reader // 5169/////////////////// 5170 5171/*! 5172@brief deserialization of CBOR, MessagePack, and UBJSON values 5173*/ 5174template<typename BasicJsonType, typename SAX = json_sax_dom_parser<BasicJsonType>> 5175class binary_reader 5176{ 5177 using number_integer_t = typename BasicJsonType::number_integer_t; 5178 using number_unsigned_t = typename BasicJsonType::number_unsigned_t; 5179 using number_float_t = typename BasicJsonType::number_float_t; 5180 using string_t = typename BasicJsonType::string_t; 5181 using json_sax_t = SAX; 5182 5183 public: 5184 /*! 5185 @brief create a binary reader 5186 5187 @param[in] adapter input adapter to read from 5188 */ 5189 explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter)) 5190 { 5191 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {}; 5192 assert(ia); 5193 } 5194 5195 // make class move-only 5196 binary_reader(const binary_reader&) = delete; 5197 binary_reader(binary_reader&&) = default; 5198 binary_reader& operator=(const binary_reader&) = delete; 5199 binary_reader& operator=(binary_reader&&) = default; 5200 ~binary_reader() = default; 5201 5202 /*! 5203 @param[in] format the binary format to parse 5204 @param[in] sax_ a SAX event processor 5205 @param[in] strict whether to expect the input to be consumed completed 5206 5207 @return 5208 */ 5209 JSON_HEDLEY_NON_NULL(3) 5210 bool sax_parse(const input_format_t format, 5211 json_sax_t* sax_, 5212 const bool strict = true) 5213 { 5214 sax = sax_; 5215 bool result = false; 5216 5217 switch (format) 5218 { 5219 case input_format_t::bson: 5220 result = parse_bson_internal(); 5221 break; 5222 5223 case input_format_t::cbor: 5224 result = parse_cbor_internal(); 5225 break; 5226 5227 case input_format_t::msgpack: 5228 result = parse_msgpack_internal(); 5229 break; 5230 5231 case input_format_t::ubjson: 5232 result = parse_ubjson_internal(); 5233 break; 5234 5235 default: // LCOV_EXCL_LINE 5236 assert(false); // LCOV_EXCL_LINE 5237 } 5238 5239 // strict mode: next byte must be EOF 5240 if (result and strict) 5241 { 5242 if (format == input_format_t::ubjson) 5243 { 5244 get_ignore_noop(); 5245 } 5246 else 5247 { 5248 get(); 5249 } 5250 5251 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char>::eof())) 5252 { 5253 return sax->parse_error(chars_read, get_token_string(), 5254 parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"))); 5255 } 5256 } 5257 5258 return result; 5259 } 5260 5261 /*! 5262 @brief determine system byte order 5263 5264 @return true if and only if system's byte order is little endian 5265 5266 @note from http://stackoverflow.com/a/1001328/266378 5267 */ 5268 static constexpr bool little_endianess(int num = 1) noexcept 5269 { 5270 return *reinterpret_cast<char*>(&num) == 1; 5271 } 5272 5273 private: 5274 ////////// 5275 // BSON // 5276 ////////// 5277 5278 /*! 5279 @brief Reads in a BSON-object and passes it to the SAX-parser. 5280 @return whether a valid BSON-value was passed to the SAX parser 5281 */ 5282 bool parse_bson_internal() 5283 { 5284 std::int32_t document_size; 5285 get_number<std::int32_t, true>(input_format_t::bson, document_size); 5286 5287 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1)))) 5288 { 5289 return false; 5290 } 5291 5292 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(/*is_array*/false))) 5293 { 5294 return false; 5295 } 5296 5297 return sax->end_object(); 5298 } 5299 5300 /*! 5301 @brief Parses a C-style string from the BSON input. 5302 @param[in, out] result A reference to the string variable where the read 5303 string is to be stored. 5304 @return `true` if the \x00-byte indicating the end of the string was 5305 encountered before the EOF; false` indicates an unexpected EOF. 5306 */ 5307 bool get_bson_cstr(string_t& result) 5308 { 5309 auto out = std::back_inserter(result); 5310 while (true) 5311 { 5312 get(); 5313 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "cstring"))) 5314 { 5315 return false; 5316 } 5317 if (current == 0x00) 5318 { 5319 return true; 5320 } 5321 *out++ = static_cast<char>(current); 5322 } 5323 5324 return true; 5325 } 5326 5327 /*! 5328 @brief Parses a zero-terminated string of length @a len from the BSON 5329 input. 5330 @param[in] len The length (including the zero-byte at the end) of the 5331 string to be read. 5332 @param[in, out] result A reference to the string variable where the read 5333 string is to be stored. 5334 @tparam NumberType The type of the length @a len 5335 @pre len >= 1 5336 @return `true` if the string was successfully parsed 5337 */ 5338 template<typename NumberType> 5339 bool get_bson_string(const NumberType len, string_t& result) 5340 { 5341 if (JSON_HEDLEY_UNLIKELY(len < 1)) 5342 { 5343 auto last_token = get_token_string(); 5344 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string"))); 5345 } 5346 5347 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) and get() != std::char_traits<char>::eof(); 5348 } 5349 5350 /*! 5351 @brief Read a BSON document element of the given @a element_type. 5352 @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html 5353 @param[in] element_type_parse_position The position in the input stream, 5354 where the `element_type` was read. 5355 @warning Not all BSON element types are supported yet. An unsupported 5356 @a element_type will give rise to a parse_error.114: 5357 Unsupported BSON record type 0x... 5358 @return whether a valid BSON-object/array was passed to the SAX parser 5359 */ 5360 bool parse_bson_element_internal(const int element_type, 5361 const std::size_t element_type_parse_position) 5362 { 5363 switch (element_type) 5364 { 5365 case 0x01: // double 5366 { 5367 double number; 5368 return get_number<double, true>(input_format_t::bson, number) and sax->number_float(static_cast<number_float_t>(number), ""); 5369 } 5370 5371 case 0x02: // string 5372 { 5373 std::int32_t len; 5374 string_t value; 5375 return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value); 5376 } 5377 5378 case 0x03: // object 5379 { 5380 return parse_bson_internal(); 5381 } 5382 5383 case 0x04: // array 5384 { 5385 return parse_bson_array(); 5386 } 5387 5388 case 0x08: // boolean 5389 { 5390 return sax->boolean(get() != 0); 5391 } 5392 5393 case 0x0A: // null 5394 { 5395 return sax->null(); 5396 } 5397 5398 case 0x10: // int32 5399 { 5400 std::int32_t value; 5401 return get_number<std::int32_t, true>(input_format_t::bson, value) and sax->number_integer(value); 5402 } 5403 5404 case 0x12: // int64 5405 { 5406 std::int64_t value; 5407 return get_number<std::int64_t, true>(input_format_t::bson, value) and sax->number_integer(value); 5408 } 5409 5410 default: // anything else not supported (yet) 5411 { 5412 std::array<char, 3> cr{{}}; 5413 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type)); 5414 return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data()))); 5415 } 5416 } 5417 } 5418 5419 /*! 5420 @brief Read a BSON element list (as specified in the BSON-spec) 5421 5422 The same binary layout is used for objects and arrays, hence it must be 5423 indicated with the argument @a is_array which one is expected 5424 (true --> array, false --> object). 5425 5426 @param[in] is_array Determines if the element list being read is to be 5427 treated as an object (@a is_array == false), or as an 5428 array (@a is_array == true). 5429 @return whether a valid BSON-object/array was passed to the SAX parser 5430 */ 5431 bool parse_bson_element_list(const bool is_array) 5432 { 5433 string_t key; 5434 while (int element_type = get()) 5435 { 5436 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list"))) 5437 { 5438 return false; 5439 } 5440 5441 const std::size_t element_type_parse_position = chars_read; 5442 if (JSON_HEDLEY_UNLIKELY(not get_bson_cstr(key))) 5443 { 5444 return false; 5445 } 5446 5447 if (not is_array and not sax->key(key)) 5448 { 5449 return false; 5450 } 5451 5452 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position))) 5453 { 5454 return false; 5455 } 5456 5457 // get_bson_cstr only appends 5458 key.clear(); 5459 } 5460 5461 return true; 5462 } 5463 5464 /*! 5465 @brief Reads an array from the BSON input and passes it to the SAX-parser. 5466 @return whether a valid BSON-array was passed to the SAX parser 5467 */ 5468 bool parse_bson_array() 5469 { 5470 std::int32_t document_size; 5471 get_number<std::int32_t, true>(input_format_t::bson, document_size); 5472 5473 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1)))) 5474 { 5475 return false; 5476 } 5477 5478 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(/*is_array*/true))) 5479 { 5480 return false; 5481 } 5482 5483 return sax->end_array(); 5484 } 5485 5486 ////////// 5487 // CBOR // 5488 ////////// 5489 5490 /*! 5491 @param[in] get_char whether a new character should be retrieved from the 5492 input (true, default) or whether the last read 5493 character should be considered instead 5494 5495 @return whether a valid CBOR value was passed to the SAX parser 5496 */ 5497 bool parse_cbor_internal(const bool get_char = true) 5498 { 5499 switch (get_char ? get() : current) 5500 { 5501 // EOF 5502 case std::char_traits<char>::eof(): 5503 return unexpect_eof(input_format_t::cbor, "value"); 5504 5505 // Integer 0x00..0x17 (0..23) 5506 case 0x00: 5507 case 0x01: 5508 case 0x02: 5509 case 0x03: 5510 case 0x04: 5511 case 0x05: 5512 case 0x06: 5513 case 0x07: 5514 case 0x08: 5515 case 0x09: 5516 case 0x0A: 5517 case 0x0B: 5518 case 0x0C: 5519 case 0x0D: 5520 case 0x0E: 5521 case 0x0F: 5522 case 0x10: 5523 case 0x11: 5524 case 0x12: 5525 case 0x13: 5526 case 0x14: 5527 case 0x15: 5528 case 0x16: 5529 case 0x17: 5530 return sax->number_unsigned(static_cast<number_unsigned_t>(current)); 5531 5532 case 0x18: // Unsigned integer (one-byte uint8_t follows) 5533 { 5534 std::uint8_t number; 5535 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number); 5536 } 5537 5538 case 0x19: // Unsigned integer (two-byte uint16_t follows) 5539 { 5540 std::uint16_t number; 5541 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number); 5542 } 5543 5544 case 0x1A: // Unsigned integer (four-byte uint32_t follows) 5545 { 5546 std::uint32_t number; 5547 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number); 5548 } 5549 5550 case 0x1B: // Unsigned integer (eight-byte uint64_t follows) 5551 { 5552 std::uint64_t number; 5553 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number); 5554 } 5555 5556 // Negative integer -1-0x00..-1-0x17 (-1..-24) 5557 case 0x20: 5558 case 0x21: 5559 case 0x22: 5560 case 0x23: 5561 case 0x24: 5562 case 0x25: 5563 case 0x26: 5564 case 0x27: 5565 case 0x28: 5566 case 0x29: 5567 case 0x2A: 5568 case 0x2B: 5569 case 0x2C: 5570 case 0x2D: 5571 case 0x2E: 5572 case 0x2F: 5573 case 0x30: 5574 case 0x31: 5575 case 0x32: 5576 case 0x33: 5577 case 0x34: 5578 case 0x35: 5579 case 0x36: 5580 case 0x37: 5581 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current)); 5582 5583 case 0x38: // Negative integer (one-byte uint8_t follows) 5584 { 5585 std::uint8_t number; 5586 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number); 5587 } 5588 5589 case 0x39: // Negative integer -1-n (two-byte uint16_t follows) 5590 { 5591 std::uint16_t number; 5592 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number); 5593 } 5594 5595 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows) 5596 { 5597 std::uint32_t number; 5598 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number); 5599 } 5600 5601 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows) 5602 { 5603 std::uint64_t number; 5604 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) 5605 - static_cast<number_integer_t>(number)); 5606 } 5607 5608 // UTF-8 string (0x00..0x17 bytes follow) 5609 case 0x60: 5610 case 0x61: 5611 case 0x62: 5612 case 0x63: 5613 case 0x64: 5614 case 0x65: 5615 case 0x66: 5616 case 0x67: 5617 case 0x68: 5618 case 0x69: 5619 case 0x6A: 5620 case 0x6B: 5621 case 0x6C: 5622 case 0x6D: 5623 case 0x6E: 5624 case 0x6F: 5625 case 0x70: 5626 case 0x71: 5627 case 0x72: 5628 case 0x73: 5629 case 0x74: 5630 case 0x75: 5631 case 0x76: 5632 case 0x77: 5633 case 0x78: // UTF-8 string (one-byte uint8_t for n follows) 5634 case 0x79: // UTF-8 string (two-byte uint16_t for n follow) 5635 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow) 5636 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow) 5637 case 0x7F: // UTF-8 string (indefinite length) 5638 { 5639 string_t s; 5640 return get_cbor_string(s) and sax->string(s); 5641 } 5642 5643 // array (0x00..0x17 data items follow) 5644 case 0x80: 5645 case 0x81: 5646 case 0x82: 5647 case 0x83: 5648 case 0x84: 5649 case 0x85: 5650 case 0x86: 5651 case 0x87: 5652 case 0x88: 5653 case 0x89: 5654 case 0x8A: 5655 case 0x8B: 5656 case 0x8C: 5657 case 0x8D: 5658 case 0x8E: 5659 case 0x8F: 5660 case 0x90: 5661 case 0x91: 5662 case 0x92: 5663 case 0x93: 5664 case 0x94: 5665 case 0x95: 5666 case 0x96: 5667 case 0x97: 5668 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu)); 5669 5670 case 0x98: // array (one-byte uint8_t for n follows) 5671 { 5672 std::uint8_t len; 5673 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len)); 5674 } 5675 5676 case 0x99: // array (two-byte uint16_t for n follow) 5677 { 5678 std::uint16_t len; 5679 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len)); 5680 } 5681 5682 case 0x9A: // array (four-byte uint32_t for n follow) 5683 { 5684 std::uint32_t len; 5685 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len)); 5686 } 5687 5688 case 0x9B: // array (eight-byte uint64_t for n follow) 5689 { 5690 std::uint64_t len; 5691 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len)); 5692 } 5693 5694 case 0x9F: // array (indefinite length) 5695 return get_cbor_array(std::size_t(-1)); 5696 5697 // map (0x00..0x17 pairs of data items follow) 5698 case 0xA0: 5699 case 0xA1: 5700 case 0xA2: 5701 case 0xA3: 5702 case 0xA4: 5703 case 0xA5: 5704 case 0xA6: 5705 case 0xA7: 5706 case 0xA8: 5707 case 0xA9: 5708 case 0xAA: 5709 case 0xAB: 5710 case 0xAC: 5711 case 0xAD: 5712 case 0xAE: 5713 case 0xAF: 5714 case 0xB0: 5715 case 0xB1: 5716 case 0xB2: 5717 case 0xB3: 5718 case 0xB4: 5719 case 0xB5: 5720 case 0xB6: 5721 case 0xB7: 5722 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu)); 5723 5724 case 0xB8: // map (one-byte uint8_t for n follows) 5725 { 5726 std::uint8_t len; 5727 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len)); 5728 } 5729 5730 case 0xB9: // map (two-byte uint16_t for n follow) 5731 { 5732 std::uint16_t len; 5733 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len)); 5734 } 5735 5736 case 0xBA: // map (four-byte uint32_t for n follow) 5737 { 5738 std::uint32_t len; 5739 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len)); 5740 } 5741 5742 case 0xBB: // map (eight-byte uint64_t for n follow) 5743 { 5744 std::uint64_t len; 5745 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len)); 5746 } 5747 5748 case 0xBF: // map (indefinite length) 5749 return get_cbor_object(std::size_t(-1)); 5750 5751 case 0xF4: // false 5752 return sax->boolean(false); 5753 5754 case 0xF5: // true 5755 return sax->boolean(true); 5756 5757 case 0xF6: // null 5758 return sax->null(); 5759 5760 case 0xF9: // Half-Precision Float (two-byte IEEE 754) 5761 { 5762 const int byte1_raw = get(); 5763 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number"))) 5764 { 5765 return false; 5766 } 5767 const int byte2_raw = get(); 5768 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number"))) 5769 { 5770 return false; 5771 } 5772 5773 const auto byte1 = static_cast<unsigned char>(byte1_raw); 5774 const auto byte2 = static_cast<unsigned char>(byte2_raw); 5775 5776 // code from RFC 7049, Appendix D, Figure 3: 5777 // As half-precision floating-point numbers were only added 5778 // to IEEE 754 in 2008, today's programming platforms often 5779 // still only have limited support for them. It is very 5780 // easy to include at least decoding support for them even 5781 // without such support. An example of a small decoder for 5782 // half-precision floating-point numbers in the C language 5783 // is shown in Fig. 3. 5784 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2); 5785 const double val = [&half] 5786 { 5787 const int exp = (half >> 10u) & 0x1Fu; 5788 const unsigned int mant = half & 0x3FFu; 5789 assert(0 <= exp and exp <= 32); 5790 assert(mant <= 1024); 5791 switch (exp) 5792 { 5793 case 0: 5794 return std::ldexp(mant, -24); 5795 case 31: 5796 return (mant == 0) 5797 ? std::numeric_limits<double>::infinity() 5798 : std::numeric_limits<double>::quiet_NaN(); 5799 default: 5800 return std::ldexp(mant + 1024, exp - 25); 5801 } 5802 }(); 5803 return sax->number_float((half & 0x8000u) != 0 5804 ? static_cast<number_float_t>(-val) 5805 : static_cast<number_float_t>(val), ""); 5806 } 5807 5808 case 0xFA: // Single-Precision Float (four-byte IEEE 754) 5809 { 5810 float number; 5811 return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), ""); 5812 } 5813 5814 case 0xFB: // Double-Precision Float (eight-byte IEEE 754) 5815 { 5816 double number; 5817 return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), ""); 5818 } 5819 5820 default: // anything else (0xFF is handled inside the other types) 5821 { 5822 auto last_token = get_token_string(); 5823 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"))); 5824 } 5825 } 5826 } 5827 5828 /*! 5829 @brief reads a CBOR string 5830 5831 This function first reads starting bytes to determine the expected 5832 string length and then copies this number of bytes into a string. 5833 Additionally, CBOR's strings with indefinite lengths are supported. 5834 5835 @param[out] result created string 5836 5837 @return whether string creation completed 5838 */ 5839 bool get_cbor_string(string_t& result) 5840 { 5841 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "string"))) 5842 { 5843 return false; 5844 } 5845 5846 switch (current) 5847 { 5848 // UTF-8 string (0x00..0x17 bytes follow) 5849 case 0x60: 5850 case 0x61: 5851 case 0x62: 5852 case 0x63: 5853 case 0x64: 5854 case 0x65: 5855 case 0x66: 5856 case 0x67: 5857 case 0x68: 5858 case 0x69: 5859 case 0x6A: 5860 case 0x6B: 5861 case 0x6C: 5862 case 0x6D: 5863 case 0x6E: 5864 case 0x6F: 5865 case 0x70: 5866 case 0x71: 5867 case 0x72: 5868 case 0x73: 5869 case 0x74: 5870 case 0x75: 5871 case 0x76: 5872 case 0x77: 5873 { 5874 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result); 5875 } 5876 5877 case 0x78: // UTF-8 string (one-byte uint8_t for n follows) 5878 { 5879 std::uint8_t len; 5880 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result); 5881 } 5882 5883 case 0x79: // UTF-8 string (two-byte uint16_t for n follow) 5884 { 5885 std::uint16_t len; 5886 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result); 5887 } 5888 5889 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow) 5890 { 5891 std::uint32_t len; 5892 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result); 5893 } 5894 5895 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow) 5896 { 5897 std::uint64_t len; 5898 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result); 5899 } 5900 5901 case 0x7F: // UTF-8 string (indefinite length) 5902 { 5903 while (get() != 0xFF) 5904 { 5905 string_t chunk; 5906 if (not get_cbor_string(chunk)) 5907 { 5908 return false; 5909 } 5910 result.append(chunk); 5911 } 5912 return true; 5913 } 5914 5915 default: 5916 { 5917 auto last_token = get_token_string(); 5918 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string"))); 5919 } 5920 } 5921 } 5922 5923 /*! 5924 @param[in] len the length of the array or std::size_t(-1) for an 5925 array of indefinite size 5926 @return whether array creation completed 5927 */ 5928 bool get_cbor_array(const std::size_t len) 5929 { 5930 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len))) 5931 { 5932 return false; 5933 } 5934 5935 if (len != std::size_t(-1)) 5936 { 5937 for (std::size_t i = 0; i < len; ++i) 5938 { 5939 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal())) 5940 { 5941 return false; 5942 } 5943 } 5944 } 5945 else 5946 { 5947 while (get() != 0xFF) 5948 { 5949 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal(false))) 5950 { 5951 return false; 5952 } 5953 } 5954 } 5955 5956 return sax->end_array(); 5957 } 5958 5959 /*! 5960 @param[in] len the length of the object or std::size_t(-1) for an 5961 object of indefinite size 5962 @return whether object creation completed 5963 */ 5964 bool get_cbor_object(const std::size_t len) 5965 { 5966 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len))) 5967 { 5968 return false; 5969 } 5970 5971 string_t key; 5972 if (len != std::size_t(-1)) 5973 { 5974 for (std::size_t i = 0; i < len; ++i) 5975 { 5976 get(); 5977 if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key))) 5978 { 5979 return false; 5980 } 5981 5982 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal())) 5983 { 5984 return false; 5985 } 5986 key.clear(); 5987 } 5988 } 5989 else 5990 { 5991 while (get() != 0xFF) 5992 { 5993 if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key))) 5994 { 5995 return false; 5996 } 5997 5998 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal())) 5999 { 6000 return false; 6001 } 6002 key.clear(); 6003 } 6004 } 6005 6006 return sax->end_object(); 6007 } 6008 6009 ///////////// 6010 // MsgPack // 6011 ///////////// 6012 6013 /*! 6014 @return whether a valid MessagePack value was passed to the SAX parser 6015 */ 6016 bool parse_msgpack_internal() 6017 { 6018 switch (get()) 6019 { 6020 // EOF 6021 case std::char_traits<char>::eof(): 6022 return unexpect_eof(input_format_t::msgpack, "value"); 6023 6024 // positive fixint 6025 case 0x00: 6026 case 0x01: 6027 case 0x02: 6028 case 0x03: 6029 case 0x04: 6030 case 0x05: 6031 case 0x06: 6032 case 0x07: 6033 case 0x08: 6034 case 0x09: 6035 case 0x0A: 6036 case 0x0B: 6037 case 0x0C: 6038 case 0x0D: 6039 case 0x0E: 6040 case 0x0F: 6041 case 0x10: 6042 case 0x11: 6043 case 0x12: 6044 case 0x13: 6045 case 0x14: 6046 case 0x15: 6047 case 0x16: 6048 case 0x17: 6049 case 0x18: 6050 case 0x19: 6051 case 0x1A: 6052 case 0x1B: 6053 case 0x1C: 6054 case 0x1D: 6055 case 0x1E: 6056 case 0x1F: 6057 case 0x20: 6058 case 0x21: 6059 case 0x22: 6060 case 0x23: 6061 case 0x24: 6062 case 0x25: 6063 case 0x26: 6064 case 0x27: 6065 case 0x28: 6066 case 0x29: 6067 case 0x2A: 6068 case 0x2B: 6069 case 0x2C: 6070 case 0x2D: 6071 case 0x2E: 6072 case 0x2F: 6073 case 0x30: 6074 case 0x31: 6075 case 0x32: 6076 case 0x33: 6077 case 0x34: 6078 case 0x35: 6079 case 0x36: 6080 case 0x37: 6081 case 0x38: 6082 case 0x39: 6083 case 0x3A: 6084 case 0x3B: 6085 case 0x3C: 6086 case 0x3D: 6087 case 0x3E: 6088 case 0x3F: 6089 case 0x40: 6090 case 0x41: 6091 case 0x42: 6092 case 0x43: 6093 case 0x44: 6094 case 0x45: 6095 case 0x46: 6096 case 0x47: 6097 case 0x48: 6098 case 0x49: 6099 case 0x4A: 6100 case 0x4B: 6101 case 0x4C: 6102 case 0x4D: 6103 case 0x4E: 6104 case 0x4F: 6105 case 0x50: 6106 case 0x51: 6107 case 0x52: 6108 case 0x53: 6109 case 0x54: 6110 case 0x55: 6111 case 0x56: 6112 case 0x57: 6113 case 0x58: 6114 case 0x59: 6115 case 0x5A: 6116 case 0x5B: 6117 case 0x5C: 6118 case 0x5D: 6119 case 0x5E: 6120 case 0x5F: 6121 case 0x60: 6122 case 0x61: 6123 case 0x62: 6124 case 0x63: 6125 case 0x64: 6126 case 0x65: 6127 case 0x66: 6128 case 0x67: 6129 case 0x68: 6130 case 0x69: 6131 case 0x6A: 6132 case 0x6B: 6133 case 0x6C: 6134 case 0x6D: 6135 case 0x6E: 6136 case 0x6F: 6137 case 0x70: 6138 case 0x71: 6139 case 0x72: 6140 case 0x73: 6141 case 0x74: 6142 case 0x75: 6143 case 0x76: 6144 case 0x77: 6145 case 0x78: 6146 case 0x79: 6147 case 0x7A: 6148 case 0x7B: 6149 case 0x7C: 6150 case 0x7D: 6151 case 0x7E: 6152 case 0x7F: 6153 return sax->number_unsigned(static_cast<number_unsigned_t>(current)); 6154 6155 // fixmap 6156 case 0x80: 6157 case 0x81: 6158 case 0x82: 6159 case 0x83: 6160 case 0x84: 6161 case 0x85: 6162 case 0x86: 6163 case 0x87: 6164 case 0x88: 6165 case 0x89: 6166 case 0x8A: 6167 case 0x8B: 6168 case 0x8C: 6169 case 0x8D: 6170 case 0x8E: 6171 case 0x8F: 6172 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu)); 6173 6174 // fixarray 6175 case 0x90: 6176 case 0x91: 6177 case 0x92: 6178 case 0x93: 6179 case 0x94: 6180 case 0x95: 6181 case 0x96: 6182 case 0x97: 6183 case 0x98: 6184 case 0x99: 6185 case 0x9A: 6186 case 0x9B: 6187 case 0x9C: 6188 case 0x9D: 6189 case 0x9E: 6190 case 0x9F: 6191 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu)); 6192 6193 // fixstr 6194 case 0xA0: 6195 case 0xA1: 6196 case 0xA2: 6197 case 0xA3: 6198 case 0xA4: 6199 case 0xA5: 6200 case 0xA6: 6201 case 0xA7: 6202 case 0xA8: 6203 case 0xA9: 6204 case 0xAA: 6205 case 0xAB: 6206 case 0xAC: 6207 case 0xAD: 6208 case 0xAE: 6209 case 0xAF: 6210 case 0xB0: 6211 case 0xB1: 6212 case 0xB2: 6213 case 0xB3: 6214 case 0xB4: 6215 case 0xB5: 6216 case 0xB6: 6217 case 0xB7: 6218 case 0xB8: 6219 case 0xB9: 6220 case 0xBA: 6221 case 0xBB: 6222 case 0xBC: 6223 case 0xBD: 6224 case 0xBE: 6225 case 0xBF: 6226 case 0xD9: // str 8 6227 case 0xDA: // str 16 6228 case 0xDB: // str 32 6229 { 6230 string_t s; 6231 return get_msgpack_string(s) and sax->string(s); 6232 } 6233 6234 case 0xC0: // nil 6235 return sax->null(); 6236 6237 case 0xC2: // false 6238 return sax->boolean(false); 6239 6240 case 0xC3: // true 6241 return sax->boolean(true); 6242 6243 case 0xCA: // float 32 6244 { 6245 float number; 6246 return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), ""); 6247 } 6248 6249 case 0xCB: // float 64 6250 { 6251 double number; 6252 return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), ""); 6253 } 6254 6255 case 0xCC: // uint 8 6256 { 6257 std::uint8_t number; 6258 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number); 6259 } 6260 6261 case 0xCD: // uint 16 6262 { 6263 std::uint16_t number; 6264 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number); 6265 } 6266 6267 case 0xCE: // uint 32 6268 { 6269 std::uint32_t number; 6270 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number); 6271 } 6272 6273 case 0xCF: // uint 64 6274 { 6275 std::uint64_t number; 6276 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number); 6277 } 6278 6279 case 0xD0: // int 8 6280 { 6281 std::int8_t number; 6282 return get_number(input_format_t::msgpack, number) and sax->number_integer(number); 6283 } 6284 6285 case 0xD1: // int 16 6286 { 6287 std::int16_t number; 6288 return get_number(input_format_t::msgpack, number) and sax->number_integer(number); 6289 } 6290 6291 case 0xD2: // int 32 6292 { 6293 std::int32_t number; 6294 return get_number(input_format_t::msgpack, number) and sax->number_integer(number); 6295 } 6296 6297 case 0xD3: // int 64 6298 { 6299 std::int64_t number; 6300 return get_number(input_format_t::msgpack, number) and sax->number_integer(number); 6301 } 6302 6303 case 0xDC: // array 16 6304 { 6305 std::uint16_t len; 6306 return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len)); 6307 } 6308 6309 case 0xDD: // array 32 6310 { 6311 std::uint32_t len; 6312 return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len)); 6313 } 6314 6315 case 0xDE: // map 16 6316 { 6317 std::uint16_t len; 6318 return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len)); 6319 } 6320 6321 case 0xDF: // map 32 6322 { 6323 std::uint32_t len; 6324 return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len)); 6325 } 6326 6327 // negative fixint 6328 case 0xE0: 6329 case 0xE1: 6330 case 0xE2: 6331 case 0xE3: 6332 case 0xE4: 6333 case 0xE5: 6334 case 0xE6: 6335 case 0xE7: 6336 case 0xE8: 6337 case 0xE9: 6338 case 0xEA: 6339 case 0xEB: 6340 case 0xEC: 6341 case 0xED: 6342 case 0xEE: 6343 case 0xEF: 6344 case 0xF0: 6345 case 0xF1: 6346 case 0xF2: 6347 case 0xF3: 6348 case 0xF4: 6349 case 0xF5: 6350 case 0xF6: 6351 case 0xF7: 6352 case 0xF8: 6353 case 0xF9: 6354 case 0xFA: 6355 case 0xFB: 6356 case 0xFC: 6357 case 0xFD: 6358 case 0xFE: 6359 case 0xFF: 6360 return sax->number_integer(static_cast<std::int8_t>(current)); 6361 6362 default: // anything else 6363 { 6364 auto last_token = get_token_string(); 6365 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value"))); 6366 } 6367 } 6368 } 6369 6370 /*! 6371 @brief reads a MessagePack string 6372 6373 This function first reads starting bytes to determine the expected 6374 string length and then copies this number of bytes into a string. 6375 6376 @param[out] result created string 6377 6378 @return whether string creation completed 6379 */ 6380 bool get_msgpack_string(string_t& result) 6381 { 6382 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string"))) 6383 { 6384 return false; 6385 } 6386 6387 switch (current) 6388 { 6389 // fixstr 6390 case 0xA0: 6391 case 0xA1: 6392 case 0xA2: 6393 case 0xA3: 6394 case 0xA4: 6395 case 0xA5: 6396 case 0xA6: 6397 case 0xA7: 6398 case 0xA8: 6399 case 0xA9: 6400 case 0xAA: 6401 case 0xAB: 6402 case 0xAC: 6403 case 0xAD: 6404 case 0xAE: 6405 case 0xAF: 6406 case 0xB0: 6407 case 0xB1: 6408 case 0xB2: 6409 case 0xB3: 6410 case 0xB4: 6411 case 0xB5: 6412 case 0xB6: 6413 case 0xB7: 6414 case 0xB8: 6415 case 0xB9: 6416 case 0xBA: 6417 case 0xBB: 6418 case 0xBC: 6419 case 0xBD: 6420 case 0xBE: 6421 case 0xBF: 6422 { 6423 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result); 6424 } 6425 6426 case 0xD9: // str 8 6427 { 6428 std::uint8_t len; 6429 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result); 6430 } 6431 6432 case 0xDA: // str 16 6433 { 6434 std::uint16_t len; 6435 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result); 6436 } 6437 6438 case 0xDB: // str 32 6439 { 6440 std::uint32_t len; 6441 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result); 6442 } 6443 6444 default: 6445 { 6446 auto last_token = get_token_string(); 6447 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string"))); 6448 } 6449 } 6450 } 6451 6452 /*! 6453 @param[in] len the length of the array 6454 @return whether array creation completed 6455 */ 6456 bool get_msgpack_array(const std::size_t len) 6457 { 6458 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len))) 6459 { 6460 return false; 6461 } 6462 6463 for (std::size_t i = 0; i < len; ++i) 6464 { 6465 if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal())) 6466 { 6467 return false; 6468 } 6469 } 6470 6471 return sax->end_array(); 6472 } 6473 6474 /*! 6475 @param[in] len the length of the object 6476 @return whether object creation completed 6477 */ 6478 bool get_msgpack_object(const std::size_t len) 6479 { 6480 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len))) 6481 { 6482 return false; 6483 } 6484 6485 string_t key; 6486 for (std::size_t i = 0; i < len; ++i) 6487 { 6488 get(); 6489 if (JSON_HEDLEY_UNLIKELY(not get_msgpack_string(key) or not sax->key(key))) 6490 { 6491 return false; 6492 } 6493 6494 if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal())) 6495 { 6496 return false; 6497 } 6498 key.clear(); 6499 } 6500 6501 return sax->end_object(); 6502 } 6503 6504 //////////// 6505 // UBJSON // 6506 //////////// 6507 6508 /*! 6509 @param[in] get_char whether a new character should be retrieved from the 6510 input (true, default) or whether the last read 6511 character should be considered instead 6512 6513 @return whether a valid UBJSON value was passed to the SAX parser 6514 */ 6515 bool parse_ubjson_internal(const bool get_char = true) 6516 { 6517 return get_ubjson_value(get_char ? get_ignore_noop() : current); 6518 } 6519 6520 /*! 6521 @brief reads a UBJSON string 6522 6523 This function is either called after reading the 'S' byte explicitly 6524 indicating a string, or in case of an object key where the 'S' byte can be 6525 left out. 6526 6527 @param[out] result created string 6528 @param[in] get_char whether a new character should be retrieved from the 6529 input (true, default) or whether the last read 6530 character should be considered instead 6531 6532 @return whether string creation completed 6533 */ 6534 bool get_ubjson_string(string_t& result, const bool get_char = true) 6535 { 6536 if (get_char) 6537 { 6538 get(); // TODO(niels): may we ignore N here? 6539 } 6540 6541 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value"))) 6542 { 6543 return false; 6544 } 6545 6546 switch (current) 6547 { 6548 case 'U': 6549 { 6550 std::uint8_t len; 6551 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result); 6552 } 6553 6554 case 'i': 6555 { 6556 std::int8_t len; 6557 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result); 6558 } 6559 6560 case 'I': 6561 { 6562 std::int16_t len; 6563 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result); 6564 } 6565 6566 case 'l': 6567 { 6568 std::int32_t len; 6569 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result); 6570 } 6571 6572 case 'L': 6573 { 6574 std::int64_t len; 6575 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result); 6576 } 6577 6578 default: 6579 auto last_token = get_token_string(); 6580 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string"))); 6581 } 6582 } 6583 6584 /*! 6585 @param[out] result determined size 6586 @return whether size determination completed 6587 */ 6588 bool get_ubjson_size_value(std::size_t& result) 6589 { 6590 switch (get_ignore_noop()) 6591 { 6592 case 'U': 6593 { 6594 std::uint8_t number; 6595 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number))) 6596 { 6597 return false; 6598 } 6599 result = static_cast<std::size_t>(number); 6600 return true; 6601 } 6602 6603 case 'i': 6604 { 6605 std::int8_t number; 6606 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number))) 6607 { 6608 return false; 6609 } 6610 result = static_cast<std::size_t>(number); 6611 return true; 6612 } 6613 6614 case 'I': 6615 { 6616 std::int16_t number; 6617 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number))) 6618 { 6619 return false; 6620 } 6621 result = static_cast<std::size_t>(number); 6622 return true; 6623 } 6624 6625 case 'l': 6626 { 6627 std::int32_t number; 6628 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number))) 6629 { 6630 return false; 6631 } 6632 result = static_cast<std::size_t>(number); 6633 return true; 6634 } 6635 6636 case 'L': 6637 { 6638 std::int64_t number; 6639 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number))) 6640 { 6641 return false; 6642 } 6643 result = static_cast<std::size_t>(number); 6644 return true; 6645 } 6646 6647 default: 6648 { 6649 auto last_token = get_token_string(); 6650 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size"))); 6651 } 6652 } 6653 } 6654 6655 /*! 6656 @brief determine the type and size for a container 6657 6658 In the optimized UBJSON format, a type and a size can be provided to allow 6659 for a more compact representation. 6660 6661 @param[out] result pair of the size and the type 6662 6663 @return whether pair creation completed 6664 */ 6665 bool get_ubjson_size_type(std::pair<std::size_t, int>& result) 6666 { 6667 result.first = string_t::npos; // size 6668 result.second = 0; // type 6669 6670 get_ignore_noop(); 6671 6672 if (current == '$') 6673 { 6674 result.second = get(); // must not ignore 'N', because 'N' maybe the type 6675 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "type"))) 6676 { 6677 return false; 6678 } 6679 6680 get_ignore_noop(); 6681 if (JSON_HEDLEY_UNLIKELY(current != '#')) 6682 { 6683 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value"))) 6684 { 6685 return false; 6686 } 6687 auto last_token = get_token_string(); 6688 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size"))); 6689 } 6690 6691 return get_ubjson_size_value(result.first); 6692 } 6693 6694 if (current == '#') 6695 { 6696 return get_ubjson_size_value(result.first); 6697 } 6698 6699 return true; 6700 } 6701 6702 /*! 6703 @param prefix the previously read or set type prefix 6704 @return whether value creation completed 6705 */ 6706 bool get_ubjson_value(const int prefix) 6707 { 6708 switch (prefix) 6709 { 6710 case std::char_traits<char>::eof(): // EOF 6711 return unexpect_eof(input_format_t::ubjson, "value"); 6712 6713 case 'T': // true 6714 return sax->boolean(true); 6715 case 'F': // false 6716 return sax->boolean(false); 6717 6718 case 'Z': // null 6719 return sax->null(); 6720 6721 case 'U': 6722 { 6723 std::uint8_t number; 6724 return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number); 6725 } 6726 6727 case 'i': 6728 { 6729 std::int8_t number; 6730 return get_number(input_format_t::ubjson, number) and sax->number_integer(number); 6731 } 6732 6733 case 'I': 6734 { 6735 std::int16_t number; 6736 return get_number(input_format_t::ubjson, number) and sax->number_integer(number); 6737 } 6738 6739 case 'l': 6740 { 6741 std::int32_t number; 6742 return get_number(input_format_t::ubjson, number) and sax->number_integer(number); 6743 } 6744 6745 case 'L': 6746 { 6747 std::int64_t number; 6748 return get_number(input_format_t::ubjson, number) and sax->number_integer(number); 6749 } 6750 6751 case 'd': 6752 { 6753 float number; 6754 return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), ""); 6755 } 6756 6757 case 'D': 6758 { 6759 double number; 6760 return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), ""); 6761 } 6762 6763 case 'C': // char 6764 { 6765 get(); 6766 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char"))) 6767 { 6768 return false; 6769 } 6770 if (JSON_HEDLEY_UNLIKELY(current > 127)) 6771 { 6772 auto last_token = get_token_string(); 6773 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char"))); 6774 } 6775 string_t s(1, static_cast<char>(current)); 6776 return sax->string(s); 6777 } 6778 6779 case 'S': // string 6780 { 6781 string_t s; 6782 return get_ubjson_string(s) and sax->string(s); 6783 } 6784 6785 case '[': // array 6786 return get_ubjson_array(); 6787 6788 case '{': // object 6789 return get_ubjson_object(); 6790 6791 default: // anything else 6792 { 6793 auto last_token = get_token_string(); 6794 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value"))); 6795 } 6796 } 6797 } 6798 6799 /*! 6800 @return whether array creation completed 6801 */ 6802 bool get_ubjson_array() 6803 { 6804 std::pair<std::size_t, int> size_and_type; 6805 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type))) 6806 { 6807 return false; 6808 } 6809 6810 if (size_and_type.first != string_t::npos) 6811 { 6812 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(size_and_type.first))) 6813 { 6814 return false; 6815 } 6816 6817 if (size_and_type.second != 0) 6818 { 6819 if (size_and_type.second != 'N') 6820 { 6821 for (std::size_t i = 0; i < size_and_type.first; ++i) 6822 { 6823 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second))) 6824 { 6825 return false; 6826 } 6827 } 6828 } 6829 } 6830 else 6831 { 6832 for (std::size_t i = 0; i < size_and_type.first; ++i) 6833 { 6834 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal())) 6835 { 6836 return false; 6837 } 6838 } 6839 } 6840 } 6841 else 6842 { 6843 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1)))) 6844 { 6845 return false; 6846 } 6847 6848 while (current != ']') 6849 { 6850 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal(false))) 6851 { 6852 return false; 6853 } 6854 get_ignore_noop(); 6855 } 6856 } 6857 6858 return sax->end_array(); 6859 } 6860 6861 /*! 6862 @return whether object creation completed 6863 */ 6864 bool get_ubjson_object() 6865 { 6866 std::pair<std::size_t, int> size_and_type; 6867 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type))) 6868 { 6869 return false; 6870 } 6871 6872 string_t key; 6873 if (size_and_type.first != string_t::npos) 6874 { 6875 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(size_and_type.first))) 6876 { 6877 return false; 6878 } 6879 6880 if (size_and_type.second != 0) 6881 { 6882 for (std::size_t i = 0; i < size_and_type.first; ++i) 6883 { 6884 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key))) 6885 { 6886 return false; 6887 } 6888 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second))) 6889 { 6890 return false; 6891 } 6892 key.clear(); 6893 } 6894 } 6895 else 6896 { 6897 for (std::size_t i = 0; i < size_and_type.first; ++i) 6898 { 6899 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key))) 6900 { 6901 return false; 6902 } 6903 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal())) 6904 { 6905 return false; 6906 } 6907 key.clear(); 6908 } 6909 } 6910 } 6911 else 6912 { 6913 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1)))) 6914 { 6915 return false; 6916 } 6917 6918 while (current != '}') 6919 { 6920 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key, false) or not sax->key(key))) 6921 { 6922 return false; 6923 } 6924 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal())) 6925 { 6926 return false; 6927 } 6928 get_ignore_noop(); 6929 key.clear(); 6930 } 6931 } 6932 6933 return sax->end_object(); 6934 } 6935 6936 /////////////////////// 6937 // Utility functions // 6938 /////////////////////// 6939 6940 /*! 6941 @brief get next character from the input 6942 6943 This function provides the interface to the used input adapter. It does 6944 not throw in case the input reached EOF, but returns a -'ve valued 6945 `std::char_traits<char>::eof()` in that case. 6946 6947 @return character read from the input 6948 */ 6949 int get() 6950 { 6951 ++chars_read; 6952 return current = ia->get_character(); 6953 } 6954 6955 /*! 6956 @return character read from the input after ignoring all 'N' entries 6957 */ 6958 int get_ignore_noop() 6959 { 6960 do 6961 { 6962 get(); 6963 } 6964 while (current == 'N'); 6965 6966 return current; 6967 } 6968 6969 /* 6970 @brief read a number from the input 6971 6972 @tparam NumberType the type of the number 6973 @param[in] format the current format (for diagnostics) 6974 @param[out] result number of type @a NumberType 6975 6976 @return whether conversion completed 6977 6978 @note This function needs to respect the system's endianess, because 6979 bytes in CBOR, MessagePack, and UBJSON are stored in network order 6980 (big endian) and therefore need reordering on little endian systems. 6981 */ 6982 template<typename NumberType, bool InputIsLittleEndian = false> 6983 bool get_number(const input_format_t format, NumberType& result) 6984 { 6985 // step 1: read input into array with system's byte order 6986 std::array<std::uint8_t, sizeof(NumberType)> vec; 6987 for (std::size_t i = 0; i < sizeof(NumberType); ++i) 6988 { 6989 get(); 6990 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "number"))) 6991 { 6992 return false; 6993 } 6994 6995 // reverse byte order prior to conversion if necessary 6996 if (is_little_endian != InputIsLittleEndian) 6997 { 6998 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current); 6999 } 7000 else 7001 { 7002 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE 7003 } 7004 } 7005 7006 // step 2: convert array into number of type T and return 7007 std::memcpy(&result, vec.data(), sizeof(NumberType)); 7008 return true; 7009 } 7010 7011 /*! 7012 @brief create a string by reading characters from the input 7013 7014 @tparam NumberType the type of the number 7015 @param[in] format the current format (for diagnostics) 7016 @param[in] len number of characters to read 7017 @param[out] result string created by reading @a len bytes 7018 7019 @return whether string creation completed 7020 7021 @note We can not reserve @a len bytes for the result, because @a len 7022 may be too large. Usually, @ref unexpect_eof() detects the end of 7023 the input before we run out of string memory. 7024 */ 7025 template<typename NumberType> 7026 bool get_string(const input_format_t format, 7027 const NumberType len, 7028 string_t& result) 7029 { 7030 bool success = true; 7031 std::generate_n(std::back_inserter(result), len, [this, &success, &format]() 7032 { 7033 get(); 7034 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "string"))) 7035 { 7036 success = false; 7037 } 7038 return static_cast<char>(current); 7039 }); 7040 return success; 7041 } 7042 7043 /*! 7044 @param[in] format the current format (for diagnostics) 7045 @param[in] context further context information (for diagnostics) 7046 @return whether the last read character is not EOF 7047 */ 7048 JSON_HEDLEY_NON_NULL(3) 7049 bool unexpect_eof(const input_format_t format, const char* context) const 7050 { 7051 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char>::eof())) 7052 { 7053 return sax->parse_error(chars_read, "<end of file>", 7054 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context))); 7055 } 7056 return true; 7057 } 7058 7059 /*! 7060 @return a string representation of the last read byte 7061 */ 7062 std::string get_token_string() const 7063 { 7064 std::array<char, 3> cr{{}}; 7065 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current)); 7066 return std::string{cr.data()}; 7067 } 7068 7069 /*! 7070 @param[in] format the current format 7071 @param[in] detail a detailed error message 7072 @param[in] context further context information 7073 @return a message string to use in the parse_error exceptions 7074 */ 7075 std::string exception_message(const input_format_t format, 7076 const std::string& detail, 7077 const std::string& context) const 7078 { 7079 std::string error_msg = "syntax error while parsing "; 7080 7081 switch (format) 7082 { 7083 case input_format_t::cbor: 7084 error_msg += "CBOR"; 7085 break; 7086 7087 case input_format_t::msgpack: 7088 error_msg += "MessagePack"; 7089 break; 7090 7091 case input_format_t::ubjson: 7092 error_msg += "UBJSON"; 7093 break; 7094 7095 case input_format_t::bson: 7096 error_msg += "BSON"; 7097 break; 7098 7099 default: // LCOV_EXCL_LINE 7100 assert(false); // LCOV_EXCL_LINE 7101 } 7102 7103 return error_msg + " " + context + ": " + detail; 7104 } 7105 7106 private: 7107 /// input adapter 7108 input_adapter_t ia = nullptr; 7109 7110 /// the current character 7111 int current = std::char_traits<char>::eof(); 7112 7113 /// the number of characters read 7114 std::size_t chars_read = 0; 7115 7116 /// whether we can assume little endianess 7117 const bool is_little_endian = little_endianess(); 7118 7119 /// the SAX parser 7120 json_sax_t* sax = nullptr; 7121}; 7122} // namespace detail 7123} // namespace nlohmann 7124 7125// #include <nlohmann/detail/input/input_adapters.hpp> 7126 7127// #include <nlohmann/detail/input/lexer.hpp> 7128 7129 7130#include <array> // array 7131#include <clocale> // localeconv 7132#include <cstddef> // size_t 7133#include <cstdio> // snprintf 7134#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull 7135#include <initializer_list> // initializer_list 7136#include <string> // char_traits, string 7137#include <utility> // move 7138#include <vector> // vector 7139 7140// #include <nlohmann/detail/input/input_adapters.hpp> 7141 7142// #include <nlohmann/detail/input/position_t.hpp> 7143 7144// #include <nlohmann/detail/macro_scope.hpp> 7145 7146 7147namespace nlohmann 7148{ 7149namespace detail 7150{ 7151/////////// 7152// lexer // 7153/////////// 7154 7155/*! 7156@brief lexical analysis 7157 7158This class organizes the lexical analysis during JSON deserialization. 7159*/ 7160template<typename BasicJsonType> 7161class lexer 7162{ 7163 using number_integer_t = typename BasicJsonType::number_integer_t; 7164 using number_unsigned_t = typename BasicJsonType::number_unsigned_t; 7165 using number_float_t = typename BasicJsonType::number_float_t; 7166 using string_t = typename BasicJsonType::string_t; 7167 7168 public: 7169 /// token types for the parser 7170 enum class token_type 7171 { 7172 uninitialized, ///< indicating the scanner is uninitialized 7173 literal_true, ///< the `true` literal 7174 literal_false, ///< the `false` literal 7175 literal_null, ///< the `null` literal 7176 value_string, ///< a string -- use get_string() for actual value 7177 value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value 7178 value_integer, ///< a signed integer -- use get_number_integer() for actual value 7179 value_float, ///< an floating point number -- use get_number_float() for actual value 7180 begin_array, ///< the character for array begin `[` 7181 begin_object, ///< the character for object begin `{` 7182 end_array, ///< the character for array end `]` 7183 end_object, ///< the character for object end `}` 7184 name_separator, ///< the name separator `:` 7185 value_separator, ///< the value separator `,` 7186 parse_error, ///< indicating a parse error 7187 end_of_input, ///< indicating the end of the input buffer 7188 literal_or_value ///< a literal or the begin of a value (only for diagnostics) 7189 }; 7190 7191 /// return name of values of type token_type (only used for errors) 7192 JSON_HEDLEY_RETURNS_NON_NULL 7193 JSON_HEDLEY_CONST 7194 static const char* token_type_name(const token_type t) noexcept 7195 { 7196 switch (t) 7197 { 7198 case token_type::uninitialized: 7199 return "<uninitialized>"; 7200 case token_type::literal_true: 7201 return "true literal"; 7202 case token_type::literal_false: 7203 return "false literal"; 7204 case token_type::literal_null: 7205 return "null literal"; 7206 case token_type::value_string: 7207 return "string literal"; 7208 case lexer::token_type::value_unsigned: 7209 case lexer::token_type::value_integer: 7210 case lexer::token_type::value_float: 7211 return "number literal"; 7212 case token_type::begin_array: 7213 return "'['"; 7214 case token_type::begin_object: 7215 return "'{'"; 7216 case token_type::end_array: 7217 return "']'"; 7218 case token_type::end_object: 7219 return "'}'"; 7220 case token_type::name_separator: 7221 return "':'"; 7222 case token_type::value_separator: 7223 return "','"; 7224 case token_type::parse_error: 7225 return "<parse error>"; 7226 case token_type::end_of_input: 7227 return "end of input"; 7228 case token_type::literal_or_value: 7229 return "'[', '{', or a literal"; 7230 // LCOV_EXCL_START 7231 default: // catch non-enum values 7232 return "unknown token"; 7233 // LCOV_EXCL_STOP 7234 } 7235 } 7236 7237 explicit lexer(detail::input_adapter_t&& adapter) 7238 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {} 7239 7240 // delete because of pointer members 7241 lexer(const lexer&) = delete; 7242 lexer(lexer&&) = delete; 7243 lexer& operator=(lexer&) = delete; 7244 lexer& operator=(lexer&&) = delete; 7245 ~lexer() = default; 7246 7247 private: 7248 ///////////////////// 7249 // locales 7250 ///////////////////// 7251 7252 /// return the locale-dependent decimal point 7253 JSON_HEDLEY_PURE 7254 static char get_decimal_point() noexcept 7255 { 7256 const auto loc = localeconv(); 7257 assert(loc != nullptr); 7258 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point); 7259 } 7260 7261 ///////////////////// 7262 // scan functions 7263 ///////////////////// 7264 7265 /*! 7266 @brief get codepoint from 4 hex characters following `\u` 7267 7268 For input "\u c1 c2 c3 c4" the codepoint is: 7269 (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4 7270 = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0) 7271 7272 Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f' 7273 must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The 7274 conversion is done by subtracting the offset (0x30, 0x37, and 0x57) 7275 between the ASCII value of the character and the desired integer value. 7276 7277 @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or 7278 non-hex character) 7279 */ 7280 int get_codepoint() 7281 { 7282 // this function only makes sense after reading `\u` 7283 assert(current == 'u'); 7284 int codepoint = 0; 7285 7286 const auto factors = { 12u, 8u, 4u, 0u }; 7287 for (const auto factor : factors) 7288 { 7289 get(); 7290 7291 if (current >= '0' and current <= '9') 7292 { 7293 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor); 7294 } 7295 else if (current >= 'A' and current <= 'F') 7296 { 7297 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor); 7298 } 7299 else if (current >= 'a' and current <= 'f') 7300 { 7301 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor); 7302 } 7303 else 7304 { 7305 return -1; 7306 } 7307 } 7308 7309 assert(0x0000 <= codepoint and codepoint <= 0xFFFF); 7310 return codepoint; 7311 } 7312 7313 /*! 7314 @brief check if the next byte(s) are inside a given range 7315 7316 Adds the current byte and, for each passed range, reads a new byte and 7317 checks if it is inside the range. If a violation was detected, set up an 7318 error message and return false. Otherwise, return true. 7319 7320 @param[in] ranges list of integers; interpreted as list of pairs of 7321 inclusive lower and upper bound, respectively 7322 7323 @pre The passed list @a ranges must have 2, 4, or 6 elements; that is, 7324 1, 2, or 3 pairs. This precondition is enforced by an assertion. 7325 7326 @return true if and only if no range violation was detected 7327 */ 7328 bool next_byte_in_range(std::initializer_list<int> ranges) 7329 { 7330 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6); 7331 add(current); 7332 7333 for (auto range = ranges.begin(); range != ranges.end(); ++range) 7334 { 7335 get(); 7336 if (JSON_HEDLEY_LIKELY(*range <= current and current <= *(++range))) 7337 { 7338 add(current); 7339 } 7340 else 7341 { 7342 error_message = "invalid string: ill-formed UTF-8 byte"; 7343 return false; 7344 } 7345 } 7346 7347 return true; 7348 } 7349 7350 /*! 7351 @brief scan a string literal 7352 7353 This function scans a string according to Sect. 7 of RFC 7159. While 7354 scanning, bytes are escaped and copied into buffer token_buffer. Then the 7355 function returns successfully, token_buffer is *not* null-terminated (as it 7356 may contain \0 bytes), and token_buffer.size() is the number of bytes in the 7357 string. 7358 7359 @return token_type::value_string if string could be successfully scanned, 7360 token_type::parse_error otherwise 7361 7362 @note In case of errors, variable error_message contains a textual 7363 description. 7364 */ 7365 token_type scan_string() 7366 { 7367 // reset token_buffer (ignore opening quote) 7368 reset(); 7369 7370 // we entered the function by reading an open quote 7371 assert(current == '\"'); 7372 7373 while (true) 7374 { 7375 // get next character 7376 switch (get()) 7377 { 7378 // end of file while parsing string 7379 case std::char_traits<char>::eof(): 7380 { 7381 error_message = "invalid string: missing closing quote"; 7382 return token_type::parse_error; 7383 } 7384 7385 // closing quote 7386 case '\"': 7387 { 7388 return token_type::value_string; 7389 } 7390 7391 // escapes 7392 case '\\': 7393 { 7394 switch (get()) 7395 { 7396 // quotation mark 7397 case '\"': 7398 add('\"'); 7399 break; 7400 // reverse solidus 7401 case '\\': 7402 add('\\'); 7403 break; 7404 // solidus 7405 case '/': 7406 add('/'); 7407 break; 7408 // backspace 7409 case 'b': 7410 add('\b'); 7411 break; 7412 // form feed 7413 case 'f': 7414 add('\f'); 7415 break; 7416 // line feed 7417 case 'n': 7418 add('\n'); 7419 break; 7420 // carriage return 7421 case 'r': 7422 add('\r'); 7423 break; 7424 // tab 7425 case 't': 7426 add('\t'); 7427 break; 7428 7429 // unicode escapes 7430 case 'u': 7431 { 7432 const int codepoint1 = get_codepoint(); 7433 int codepoint = codepoint1; // start with codepoint1 7434 7435 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1)) 7436 { 7437 error_message = "invalid string: '\\u' must be followed by 4 hex digits"; 7438 return token_type::parse_error; 7439 } 7440 7441 // check if code point is a high surrogate 7442 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF) 7443 { 7444 // expect next \uxxxx entry 7445 if (JSON_HEDLEY_LIKELY(get() == '\\' and get() == 'u')) 7446 { 7447 const int codepoint2 = get_codepoint(); 7448 7449 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1)) 7450 { 7451 error_message = "invalid string: '\\u' must be followed by 4 hex digits"; 7452 return token_type::parse_error; 7453 } 7454 7455 // check if codepoint2 is a low surrogate 7456 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF)) 7457 { 7458 // overwrite codepoint 7459 codepoint = static_cast<int>( 7460 // high surrogate occupies the most significant 22 bits 7461 (static_cast<unsigned int>(codepoint1) << 10u) 7462 // low surrogate occupies the least significant 15 bits 7463 + static_cast<unsigned int>(codepoint2) 7464 // there is still the 0xD800, 0xDC00 and 0x10000 noise 7465 // in the result so we have to subtract with: 7466 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00 7467 - 0x35FDC00u); 7468 } 7469 else 7470 { 7471 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF"; 7472 return token_type::parse_error; 7473 } 7474 } 7475 else 7476 { 7477 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF"; 7478 return token_type::parse_error; 7479 } 7480 } 7481 else 7482 { 7483 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF)) 7484 { 7485 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF"; 7486 return token_type::parse_error; 7487 } 7488 } 7489 7490 // result of the above calculation yields a proper codepoint 7491 assert(0x00 <= codepoint and codepoint <= 0x10FFFF); 7492 7493 // translate codepoint into bytes 7494 if (codepoint < 0x80) 7495 { 7496 // 1-byte characters: 0xxxxxxx (ASCII) 7497 add(codepoint); 7498 } 7499 else if (codepoint <= 0x7FF) 7500 { 7501 // 2-byte characters: 110xxxxx 10xxxxxx 7502 add(static_cast<int>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u))); 7503 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu))); 7504 } 7505 else if (codepoint <= 0xFFFF) 7506 { 7507 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx 7508 add(static_cast<int>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u))); 7509 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu))); 7510 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu))); 7511 } 7512 else 7513 { 7514 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 7515 add(static_cast<int>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u))); 7516 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu))); 7517 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu))); 7518 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu))); 7519 } 7520 7521 break; 7522 } 7523 7524 // other characters after escape 7525 default: 7526 error_message = "invalid string: forbidden character after backslash"; 7527 return token_type::parse_error; 7528 } 7529 7530 break; 7531 } 7532 7533 // invalid control characters 7534 case 0x00: 7535 { 7536 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000"; 7537 return token_type::parse_error; 7538 } 7539 7540 case 0x01: 7541 { 7542 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001"; 7543 return token_type::parse_error; 7544 } 7545 7546 case 0x02: 7547 { 7548 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002"; 7549 return token_type::parse_error; 7550 } 7551 7552 case 0x03: 7553 { 7554 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003"; 7555 return token_type::parse_error; 7556 } 7557 7558 case 0x04: 7559 { 7560 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004"; 7561 return token_type::parse_error; 7562 } 7563 7564 case 0x05: 7565 { 7566 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005"; 7567 return token_type::parse_error; 7568 } 7569 7570 case 0x06: 7571 { 7572 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006"; 7573 return token_type::parse_error; 7574 } 7575 7576 case 0x07: 7577 { 7578 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007"; 7579 return token_type::parse_error; 7580 } 7581 7582 case 0x08: 7583 { 7584 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b"; 7585 return token_type::parse_error; 7586 } 7587 7588 case 0x09: 7589 { 7590 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t"; 7591 return token_type::parse_error; 7592 } 7593 7594 case 0x0A: 7595 { 7596 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n"; 7597 return token_type::parse_error; 7598 } 7599 7600 case 0x0B: 7601 { 7602 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B"; 7603 return token_type::parse_error; 7604 } 7605 7606 case 0x0C: 7607 { 7608 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f"; 7609 return token_type::parse_error; 7610 } 7611 7612 case 0x0D: 7613 { 7614 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r"; 7615 return token_type::parse_error; 7616 } 7617 7618 case 0x0E: 7619 { 7620 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E"; 7621 return token_type::parse_error; 7622 } 7623 7624 case 0x0F: 7625 { 7626 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F"; 7627 return token_type::parse_error; 7628 } 7629 7630 case 0x10: 7631 { 7632 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010"; 7633 return token_type::parse_error; 7634 } 7635 7636 case 0x11: 7637 { 7638 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011"; 7639 return token_type::parse_error; 7640 } 7641 7642 case 0x12: 7643 { 7644 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012"; 7645 return token_type::parse_error; 7646 } 7647 7648 case 0x13: 7649 { 7650 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013"; 7651 return token_type::parse_error; 7652 } 7653 7654 case 0x14: 7655 { 7656 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014"; 7657 return token_type::parse_error; 7658 } 7659 7660 case 0x15: 7661 { 7662 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015"; 7663 return token_type::parse_error; 7664 } 7665 7666 case 0x16: 7667 { 7668 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016"; 7669 return token_type::parse_error; 7670 } 7671 7672 case 0x17: 7673 { 7674 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017"; 7675 return token_type::parse_error; 7676 } 7677 7678 case 0x18: 7679 { 7680 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018"; 7681 return token_type::parse_error; 7682 } 7683 7684 case 0x19: 7685 { 7686 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019"; 7687 return token_type::parse_error; 7688 } 7689 7690 case 0x1A: 7691 { 7692 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A"; 7693 return token_type::parse_error; 7694 } 7695 7696 case 0x1B: 7697 { 7698 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B"; 7699 return token_type::parse_error; 7700 } 7701 7702 case 0x1C: 7703 { 7704 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C"; 7705 return token_type::parse_error; 7706 } 7707 7708 case 0x1D: 7709 { 7710 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D"; 7711 return token_type::parse_error; 7712 } 7713 7714 case 0x1E: 7715 { 7716 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E"; 7717 return token_type::parse_error; 7718 } 7719 7720 case 0x1F: 7721 { 7722 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F"; 7723 return token_type::parse_error; 7724 } 7725 7726 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace)) 7727 case 0x20: 7728 case 0x21: 7729 case 0x23: 7730 case 0x24: 7731 case 0x25: 7732 case 0x26: 7733 case 0x27: 7734 case 0x28: 7735 case 0x29: 7736 case 0x2A: 7737 case 0x2B: 7738 case 0x2C: 7739 case 0x2D: 7740 case 0x2E: 7741 case 0x2F: 7742 case 0x30: 7743 case 0x31: 7744 case 0x32: 7745 case 0x33: 7746 case 0x34: 7747 case 0x35: 7748 case 0x36: 7749 case 0x37: 7750 case 0x38: 7751 case 0x39: 7752 case 0x3A: 7753 case 0x3B: 7754 case 0x3C: 7755 case 0x3D: 7756 case 0x3E: 7757 case 0x3F: 7758 case 0x40: 7759 case 0x41: 7760 case 0x42: 7761 case 0x43: 7762 case 0x44: 7763 case 0x45: 7764 case 0x46: 7765 case 0x47: 7766 case 0x48: 7767 case 0x49: 7768 case 0x4A: 7769 case 0x4B: 7770 case 0x4C: 7771 case 0x4D: 7772 case 0x4E: 7773 case 0x4F: 7774 case 0x50: 7775 case 0x51: 7776 case 0x52: 7777 case 0x53: 7778 case 0x54: 7779 case 0x55: 7780 case 0x56: 7781 case 0x57: 7782 case 0x58: 7783 case 0x59: 7784 case 0x5A: 7785 case 0x5B: 7786 case 0x5D: 7787 case 0x5E: 7788 case 0x5F: 7789 case 0x60: 7790 case 0x61: 7791 case 0x62: 7792 case 0x63: 7793 case 0x64: 7794 case 0x65: 7795 case 0x66: 7796 case 0x67: 7797 case 0x68: 7798 case 0x69: 7799 case 0x6A: 7800 case 0x6B: 7801 case 0x6C: 7802 case 0x6D: 7803 case 0x6E: 7804 case 0x6F: 7805 case 0x70: 7806 case 0x71: 7807 case 0x72: 7808 case 0x73: 7809 case 0x74: 7810 case 0x75: 7811 case 0x76: 7812 case 0x77: 7813 case 0x78: 7814 case 0x79: 7815 case 0x7A: 7816 case 0x7B: 7817 case 0x7C: 7818 case 0x7D: 7819 case 0x7E: 7820 case 0x7F: 7821 { 7822 add(current); 7823 break; 7824 } 7825 7826 // U+0080..U+07FF: bytes C2..DF 80..BF 7827 case 0xC2: 7828 case 0xC3: 7829 case 0xC4: 7830 case 0xC5: 7831 case 0xC6: 7832 case 0xC7: 7833 case 0xC8: 7834 case 0xC9: 7835 case 0xCA: 7836 case 0xCB: 7837 case 0xCC: 7838 case 0xCD: 7839 case 0xCE: 7840 case 0xCF: 7841 case 0xD0: 7842 case 0xD1: 7843 case 0xD2: 7844 case 0xD3: 7845 case 0xD4: 7846 case 0xD5: 7847 case 0xD6: 7848 case 0xD7: 7849 case 0xD8: 7850 case 0xD9: 7851 case 0xDA: 7852 case 0xDB: 7853 case 0xDC: 7854 case 0xDD: 7855 case 0xDE: 7856 case 0xDF: 7857 { 7858 if (JSON_HEDLEY_UNLIKELY(not next_byte_in_range({0x80, 0xBF}))) 7859 { 7860 return token_type::parse_error; 7861 } 7862 break; 7863 } 7864 7865 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF 7866 case 0xE0: 7867 { 7868 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF})))) 7869 { 7870 return token_type::parse_error; 7871 } 7872 break; 7873 } 7874 7875 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF 7876 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF 7877 case 0xE1: 7878 case 0xE2: 7879 case 0xE3: 7880 case 0xE4: 7881 case 0xE5: 7882 case 0xE6: 7883 case 0xE7: 7884 case 0xE8: 7885 case 0xE9: 7886 case 0xEA: 7887 case 0xEB: 7888 case 0xEC: 7889 case 0xEE: 7890 case 0xEF: 7891 { 7892 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF})))) 7893 { 7894 return token_type::parse_error; 7895 } 7896 break; 7897 } 7898 7899 // U+D000..U+D7FF: bytes ED 80..9F 80..BF 7900 case 0xED: 7901 { 7902 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF})))) 7903 { 7904 return token_type::parse_error; 7905 } 7906 break; 7907 } 7908 7909 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF 7910 case 0xF0: 7911 { 7912 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) 7913 { 7914 return token_type::parse_error; 7915 } 7916 break; 7917 } 7918 7919 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF 7920 case 0xF1: 7921 case 0xF2: 7922 case 0xF3: 7923 { 7924 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) 7925 { 7926 return token_type::parse_error; 7927 } 7928 break; 7929 } 7930 7931 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF 7932 case 0xF4: 7933 { 7934 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF})))) 7935 { 7936 return token_type::parse_error; 7937 } 7938 break; 7939 } 7940 7941 // remaining bytes (80..C1 and F5..FF) are ill-formed 7942 default: 7943 { 7944 error_message = "invalid string: ill-formed UTF-8 byte"; 7945 return token_type::parse_error; 7946 } 7947 } 7948 } 7949 } 7950 7951 JSON_HEDLEY_NON_NULL(2) 7952 static void strtof(float& f, const char* str, char** endptr) noexcept 7953 { 7954 f = std::strtof(str, endptr); 7955 } 7956 7957 JSON_HEDLEY_NON_NULL(2) 7958 static void strtof(double& f, const char* str, char** endptr) noexcept 7959 { 7960 f = std::strtod(str, endptr); 7961 } 7962 7963 JSON_HEDLEY_NON_NULL(2) 7964 static void strtof(long double& f, const char* str, char** endptr) noexcept 7965 { 7966 f = std::strtold(str, endptr); 7967 } 7968 7969 /*! 7970 @brief scan a number literal 7971 7972 This function scans a string according to Sect. 6 of RFC 7159. 7973 7974 The function is realized with a deterministic finite state machine derived 7975 from the grammar described in RFC 7159. Starting in state "init", the 7976 input is read and used to determined the next state. Only state "done" 7977 accepts the number. State "error" is a trap state to model errors. In the 7978 table below, "anything" means any character but the ones listed before. 7979 7980 state | 0 | 1-9 | e E | + | - | . | anything 7981 ---------|----------|----------|----------|---------|---------|----------|----------- 7982 init | zero | any1 | [error] | [error] | minus | [error] | [error] 7983 minus | zero | any1 | [error] | [error] | [error] | [error] | [error] 7984 zero | done | done | exponent | done | done | decimal1 | done 7985 any1 | any1 | any1 | exponent | done | done | decimal1 | done 7986 decimal1 | decimal2 | [error] | [error] | [error] | [error] | [error] | [error] 7987 decimal2 | decimal2 | decimal2 | exponent | done | done | done | done 7988 exponent | any2 | any2 | [error] | sign | sign | [error] | [error] 7989 sign | any2 | any2 | [error] | [error] | [error] | [error] | [error] 7990 any2 | any2 | any2 | done | done | done | done | done 7991 7992 The state machine is realized with one label per state (prefixed with 7993 "scan_number_") and `goto` statements between them. The state machine 7994 contains cycles, but any cycle can be left when EOF is read. Therefore, 7995 the function is guaranteed to terminate. 7996 7997 During scanning, the read bytes are stored in token_buffer. This string is 7998 then converted to a signed integer, an unsigned integer, or a 7999 floating-point number. 8000 8001 @return token_type::value_unsigned, token_type::value_integer, or 8002 token_type::value_float if number could be successfully scanned, 8003 token_type::parse_error otherwise 8004 8005 @note The scanner is independent of the current locale. Internally, the 8006 locale's decimal point is used instead of `.` to work with the 8007 locale-dependent converters. 8008 */ 8009 token_type scan_number() // lgtm [cpp/use-of-goto] 8010 { 8011 // reset token_buffer to store the number's bytes 8012 reset(); 8013 8014 // the type of the parsed number; initially set to unsigned; will be 8015 // changed if minus sign, decimal point or exponent is read 8016 token_type number_type = token_type::value_unsigned; 8017 8018 // state (init): we just found out we need to scan a number 8019 switch (current) 8020 { 8021 case '-': 8022 { 8023 add(current); 8024 goto scan_number_minus; 8025 } 8026 8027 case '0': 8028 { 8029 add(current); 8030 goto scan_number_zero; 8031 } 8032 8033 case '1': 8034 case '2': 8035 case '3': 8036 case '4': 8037 case '5': 8038 case '6': 8039 case '7': 8040 case '8': 8041 case '9': 8042 { 8043 add(current); 8044 goto scan_number_any1; 8045 } 8046 8047 // all other characters are rejected outside scan_number() 8048 default: // LCOV_EXCL_LINE 8049 assert(false); // LCOV_EXCL_LINE 8050 } 8051 8052scan_number_minus: 8053 // state: we just parsed a leading minus sign 8054 number_type = token_type::value_integer; 8055 switch (get()) 8056 { 8057 case '0': 8058 { 8059 add(current); 8060 goto scan_number_zero; 8061 } 8062 8063 case '1': 8064 case '2': 8065 case '3': 8066 case '4': 8067 case '5': 8068 case '6': 8069 case '7': 8070 case '8': 8071 case '9': 8072 { 8073 add(current); 8074 goto scan_number_any1; 8075 } 8076 8077 default: 8078 { 8079 error_message = "invalid number; expected digit after '-'"; 8080 return token_type::parse_error; 8081 } 8082 } 8083 8084scan_number_zero: 8085 // state: we just parse a zero (maybe with a leading minus sign) 8086 switch (get()) 8087 { 8088 case '.': 8089 { 8090 add(decimal_point_char); 8091 goto scan_number_decimal1; 8092 } 8093 8094 case 'e': 8095 case 'E': 8096 { 8097 add(current); 8098 goto scan_number_exponent; 8099 } 8100 8101 default: 8102 goto scan_number_done; 8103 } 8104 8105scan_number_any1: 8106 // state: we just parsed a number 0-9 (maybe with a leading minus sign) 8107 switch (get()) 8108 { 8109 case '0': 8110 case '1': 8111 case '2': 8112 case '3': 8113 case '4': 8114 case '5': 8115 case '6': 8116 case '7': 8117 case '8': 8118 case '9': 8119 { 8120 add(current); 8121 goto scan_number_any1; 8122 } 8123 8124 case '.': 8125 { 8126 add(decimal_point_char); 8127 goto scan_number_decimal1; 8128 } 8129 8130 case 'e': 8131 case 'E': 8132 { 8133 add(current); 8134 goto scan_number_exponent; 8135 } 8136 8137 default: 8138 goto scan_number_done; 8139 } 8140 8141scan_number_decimal1: 8142 // state: we just parsed a decimal point 8143 number_type = token_type::value_float; 8144 switch (get()) 8145 { 8146 case '0': 8147 case '1': 8148 case '2': 8149 case '3': 8150 case '4': 8151 case '5': 8152 case '6': 8153 case '7': 8154 case '8': 8155 case '9': 8156 { 8157 add(current); 8158 goto scan_number_decimal2; 8159 } 8160 8161 default: 8162 { 8163 error_message = "invalid number; expected digit after '.'"; 8164 return token_type::parse_error; 8165 } 8166 } 8167 8168scan_number_decimal2: 8169 // we just parsed at least one number after a decimal point 8170 switch (get()) 8171 { 8172 case '0': 8173 case '1': 8174 case '2': 8175 case '3': 8176 case '4': 8177 case '5': 8178 case '6': 8179 case '7': 8180 case '8': 8181 case '9': 8182 { 8183 add(current); 8184 goto scan_number_decimal2; 8185 } 8186 8187 case 'e': 8188 case 'E': 8189 { 8190 add(current); 8191 goto scan_number_exponent; 8192 } 8193 8194 default: 8195 goto scan_number_done; 8196 } 8197 8198scan_number_exponent: 8199 // we just parsed an exponent 8200 number_type = token_type::value_float; 8201 switch (get()) 8202 { 8203 case '+': 8204 case '-': 8205 { 8206 add(current); 8207 goto scan_number_sign; 8208 } 8209 8210 case '0': 8211 case '1': 8212 case '2': 8213 case '3': 8214 case '4': 8215 case '5': 8216 case '6': 8217 case '7': 8218 case '8': 8219 case '9': 8220 { 8221 add(current); 8222 goto scan_number_any2; 8223 } 8224 8225 default: 8226 { 8227 error_message = 8228 "invalid number; expected '+', '-', or digit after exponent"; 8229 return token_type::parse_error; 8230 } 8231 } 8232 8233scan_number_sign: 8234 // we just parsed an exponent sign 8235 switch (get()) 8236 { 8237 case '0': 8238 case '1': 8239 case '2': 8240 case '3': 8241 case '4': 8242 case '5': 8243 case '6': 8244 case '7': 8245 case '8': 8246 case '9': 8247 { 8248 add(current); 8249 goto scan_number_any2; 8250 } 8251 8252 default: 8253 { 8254 error_message = "invalid number; expected digit after exponent sign"; 8255 return token_type::parse_error; 8256 } 8257 } 8258 8259scan_number_any2: 8260 // we just parsed a number after the exponent or exponent sign 8261 switch (get()) 8262 { 8263 case '0': 8264 case '1': 8265 case '2': 8266 case '3': 8267 case '4': 8268 case '5': 8269 case '6': 8270 case '7': 8271 case '8': 8272 case '9': 8273 { 8274 add(current); 8275 goto scan_number_any2; 8276 } 8277 8278 default: 8279 goto scan_number_done; 8280 } 8281 8282scan_number_done: 8283 // unget the character after the number (we only read it to know that 8284 // we are done scanning a number) 8285 unget(); 8286 8287 char* endptr = nullptr; 8288 errno = 0; 8289 8290 // try to parse integers first and fall back to floats 8291 if (number_type == token_type::value_unsigned) 8292 { 8293 const auto x = std::strtoull(token_buffer.data(), &endptr, 10); 8294 8295 // we checked the number format before 8296 assert(endptr == token_buffer.data() + token_buffer.size()); 8297 8298 if (errno == 0) 8299 { 8300 value_unsigned = static_cast<number_unsigned_t>(x); 8301 if (value_unsigned == x) 8302 { 8303 return token_type::value_unsigned; 8304 } 8305 } 8306 } 8307 else if (number_type == token_type::value_integer) 8308 { 8309 const auto x = std::strtoll(token_buffer.data(), &endptr, 10); 8310 8311 // we checked the number format before 8312 assert(endptr == token_buffer.data() + token_buffer.size()); 8313 8314 if (errno == 0) 8315 { 8316 value_integer = static_cast<number_integer_t>(x); 8317 if (value_integer == x) 8318 { 8319 return token_type::value_integer; 8320 } 8321 } 8322 } 8323 8324 // this code is reached if we parse a floating-point number or if an 8325 // integer conversion above failed 8326 strtof(value_float, token_buffer.data(), &endptr); 8327 8328 // we checked the number format before 8329 assert(endptr == token_buffer.data() + token_buffer.size()); 8330 8331 return token_type::value_float; 8332 } 8333 8334 /*! 8335 @param[in] literal_text the literal text to expect 8336 @param[in] length the length of the passed literal text 8337 @param[in] return_type the token type to return on success 8338 */ 8339 JSON_HEDLEY_NON_NULL(2) 8340 token_type scan_literal(const char* literal_text, const std::size_t length, 8341 token_type return_type) 8342 { 8343 assert(current == literal_text[0]); 8344 for (std::size_t i = 1; i < length; ++i) 8345 { 8346 if (JSON_HEDLEY_UNLIKELY(get() != literal_text[i])) 8347 { 8348 error_message = "invalid literal"; 8349 return token_type::parse_error; 8350 } 8351 } 8352 return return_type; 8353 } 8354 8355 ///////////////////// 8356 // input management 8357 ///////////////////// 8358 8359 /// reset token_buffer; current character is beginning of token 8360 void reset() noexcept 8361 { 8362 token_buffer.clear(); 8363 token_string.clear(); 8364 token_string.push_back(std::char_traits<char>::to_char_type(current)); 8365 } 8366 8367 /* 8368 @brief get next character from the input 8369 8370 This function provides the interface to the used input adapter. It does 8371 not throw in case the input reached EOF, but returns a 8372 `std::char_traits<char>::eof()` in that case. Stores the scanned characters 8373 for use in error messages. 8374 8375 @return character read from the input 8376 */ 8377 std::char_traits<char>::int_type get() 8378 { 8379 ++position.chars_read_total; 8380 ++position.chars_read_current_line; 8381 8382 if (next_unget) 8383 { 8384 // just reset the next_unget variable and work with current 8385 next_unget = false; 8386 } 8387 else 8388 { 8389 current = ia->get_character(); 8390 } 8391 8392 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char>::eof())) 8393 { 8394 token_string.push_back(std::char_traits<char>::to_char_type(current)); 8395 } 8396 8397 if (current == '\n') 8398 { 8399 ++position.lines_read; 8400 position.chars_read_current_line = 0; 8401 } 8402 8403 return current; 8404 } 8405 8406 /*! 8407 @brief unget current character (read it again on next get) 8408 8409 We implement unget by setting variable next_unget to true. The input is not 8410 changed - we just simulate ungetting by modifying chars_read_total, 8411 chars_read_current_line, and token_string. The next call to get() will 8412 behave as if the unget character is read again. 8413 */ 8414 void unget() 8415 { 8416 next_unget = true; 8417 8418 --position.chars_read_total; 8419 8420 // in case we "unget" a newline, we have to also decrement the lines_read 8421 if (position.chars_read_current_line == 0) 8422 { 8423 if (position.lines_read > 0) 8424 { 8425 --position.lines_read; 8426 } 8427 } 8428 else 8429 { 8430 --position.chars_read_current_line; 8431 } 8432 8433 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char>::eof())) 8434 { 8435 assert(not token_string.empty()); 8436 token_string.pop_back(); 8437 } 8438 } 8439 8440 /// add a character to token_buffer 8441 void add(int c) 8442 { 8443 token_buffer.push_back(std::char_traits<char>::to_char_type(c)); 8444 } 8445 8446 public: 8447 ///////////////////// 8448 // value getters 8449 ///////////////////// 8450 8451 /// return integer value 8452 constexpr number_integer_t get_number_integer() const noexcept 8453 { 8454 return value_integer; 8455 } 8456 8457 /// return unsigned integer value 8458 constexpr number_unsigned_t get_number_unsigned() const noexcept 8459 { 8460 return value_unsigned; 8461 } 8462 8463 /// return floating-point value 8464 constexpr number_float_t get_number_float() const noexcept 8465 { 8466 return value_float; 8467 } 8468 8469 /// return current string value (implicitly resets the token; useful only once) 8470 string_t& get_string() 8471 { 8472 return token_buffer; 8473 } 8474 8475 ///////////////////// 8476 // diagnostics 8477 ///////////////////// 8478 8479 /// return position of last read token 8480 constexpr position_t get_position() const noexcept 8481 { 8482 return position; 8483 } 8484 8485 /// return the last read token (for errors only). Will never contain EOF 8486 /// (an arbitrary value that is not a valid char value, often -1), because 8487 /// 255 may legitimately occur. May contain NUL, which should be escaped. 8488 std::string get_token_string() const 8489 { 8490 // escape control characters 8491 std::string result; 8492 for (const auto c : token_string) 8493 { 8494 if ('\x00' <= c and c <= '\x1F') 8495 { 8496 // escape control characters 8497 std::array<char, 9> cs{{}}; 8498 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c)); 8499 result += cs.data(); 8500 } 8501 else 8502 { 8503 // add character as is 8504 result.push_back(c); 8505 } 8506 } 8507 8508 return result; 8509 } 8510 8511 /// return syntax error message 8512 JSON_HEDLEY_RETURNS_NON_NULL 8513 constexpr const char* get_error_message() const noexcept 8514 { 8515 return error_message; 8516 } 8517 8518 ///////////////////// 8519 // actual scanner 8520 ///////////////////// 8521 8522 /*! 8523 @brief skip the UTF-8 byte order mark 8524 @return true iff there is no BOM or the correct BOM has been skipped 8525 */ 8526 bool skip_bom() 8527 { 8528 if (get() == 0xEF) 8529 { 8530 // check if we completely parse the BOM 8531 return get() == 0xBB and get() == 0xBF; 8532 } 8533 8534 // the first character is not the beginning of the BOM; unget it to 8535 // process is later 8536 unget(); 8537 return true; 8538 } 8539 8540 token_type scan() 8541 { 8542 // initially, skip the BOM 8543 if (position.chars_read_total == 0 and not skip_bom()) 8544 { 8545 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given"; 8546 return token_type::parse_error; 8547 } 8548 8549 // read next character and ignore whitespace 8550 do 8551 { 8552 get(); 8553 } 8554 while (current == ' ' or current == '\t' or current == '\n' or current == '\r'); 8555 8556 switch (current) 8557 { 8558 // structural characters 8559 case '[': 8560 return token_type::begin_array; 8561 case ']': 8562 return token_type::end_array; 8563 case '{': 8564 return token_type::begin_object; 8565 case '}': 8566 return token_type::end_object; 8567 case ':': 8568 return token_type::name_separator; 8569 case ',': 8570 return token_type::value_separator; 8571 8572 // literals 8573 case 't': 8574 return scan_literal("true", 4, token_type::literal_true); 8575 case 'f': 8576 return scan_literal("false", 5, token_type::literal_false); 8577 case 'n': 8578 return scan_literal("null", 4, token_type::literal_null); 8579 8580 // string 8581 case '\"': 8582 return scan_string(); 8583 8584 // number 8585 case '-': 8586 case '0': 8587 case '1': 8588 case '2': 8589 case '3': 8590 case '4': 8591 case '5': 8592 case '6': 8593 case '7': 8594 case '8': 8595 case '9': 8596 return scan_number(); 8597 8598 // end of input (the null byte is needed when parsing from 8599 // string literals) 8600 case '\0': 8601 case std::char_traits<char>::eof(): 8602 return token_type::end_of_input; 8603 8604 // error 8605 default: 8606 error_message = "invalid literal"; 8607 return token_type::parse_error; 8608 } 8609 } 8610 8611 private: 8612 /// input adapter 8613 detail::input_adapter_t ia = nullptr; 8614 8615 /// the current character 8616 std::char_traits<char>::int_type current = std::char_traits<char>::eof(); 8617 8618 /// whether the next get() call should just return current 8619 bool next_unget = false; 8620 8621 /// the start position of the current token 8622 position_t position {}; 8623 8624 /// raw input token string (for error messages) 8625 std::vector<char> token_string {}; 8626 8627 /// buffer for variable-length tokens (numbers, strings) 8628 string_t token_buffer {}; 8629 8630 /// a description of occurred lexer errors 8631 const char* error_message = ""; 8632 8633 // number values 8634 number_integer_t value_integer = 0; 8635 number_unsigned_t value_unsigned = 0; 8636 number_float_t value_float = 0; 8637 8638 /// the decimal point 8639 const char decimal_point_char = '.'; 8640}; 8641} // namespace detail 8642} // namespace nlohmann 8643 8644// #include <nlohmann/detail/input/parser.hpp> 8645 8646 8647#include <cassert> // assert 8648#include <cmath> // isfinite 8649#include <cstdint> // uint8_t 8650#include <functional> // function 8651#include <string> // string 8652#include <utility> // move 8653#include <vector> // vector 8654 8655// #include <nlohmann/detail/exceptions.hpp> 8656 8657// #include <nlohmann/detail/input/input_adapters.hpp> 8658 8659// #include <nlohmann/detail/input/json_sax.hpp> 8660 8661// #include <nlohmann/detail/input/lexer.hpp> 8662 8663// #include <nlohmann/detail/macro_scope.hpp> 8664 8665// #include <nlohmann/detail/meta/is_sax.hpp> 8666 8667// #include <nlohmann/detail/value_t.hpp> 8668 8669 8670namespace nlohmann 8671{ 8672namespace detail 8673{ 8674//////////// 8675// parser // 8676//////////// 8677 8678/*! 8679@brief syntax analysis 8680 8681This class implements a recursive decent parser. 8682*/ 8683template<typename BasicJsonType> 8684class parser 8685{ 8686 using number_integer_t = typename BasicJsonType::number_integer_t; 8687 using number_unsigned_t = typename BasicJsonType::number_unsigned_t; 8688 using number_float_t = typename BasicJsonType::number_float_t; 8689 using string_t = typename BasicJsonType::string_t; 8690 using lexer_t = lexer<BasicJsonType>; 8691 using token_type = typename lexer_t::token_type; 8692 8693 public: 8694 enum class parse_event_t : uint8_t 8695 { 8696 /// the parser read `{` and started to process a JSON object 8697 object_start, 8698 /// the parser read `}` and finished processing a JSON object 8699 object_end, 8700 /// the parser read `[` and started to process a JSON array 8701 array_start, 8702 /// the parser read `]` and finished processing a JSON array 8703 array_end, 8704 /// the parser read a key of a value in an object 8705 key, 8706 /// the parser finished reading a JSON value 8707 value 8708 }; 8709 8710 using parser_callback_t = 8711 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>; 8712 8713 /// a parser reading from an input adapter 8714 explicit parser(detail::input_adapter_t&& adapter, 8715 const parser_callback_t cb = nullptr, 8716 const bool allow_exceptions_ = true) 8717 : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_) 8718 { 8719 // read first token 8720 get_token(); 8721 } 8722 8723 /*! 8724 @brief public parser interface 8725 8726 @param[in] strict whether to expect the last token to be EOF 8727 @param[in,out] result parsed JSON value 8728 8729 @throw parse_error.101 in case of an unexpected token 8730 @throw parse_error.102 if to_unicode fails or surrogate error 8731 @throw parse_error.103 if to_unicode fails 8732 */ 8733 void parse(const bool strict, BasicJsonType& result) 8734 { 8735 if (callback) 8736 { 8737 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions); 8738 sax_parse_internal(&sdp); 8739 result.assert_invariant(); 8740 8741 // in strict mode, input must be completely read 8742 if (strict and (get_token() != token_type::end_of_input)) 8743 { 8744 sdp.parse_error(m_lexer.get_position(), 8745 m_lexer.get_token_string(), 8746 parse_error::create(101, m_lexer.get_position(), 8747 exception_message(token_type::end_of_input, "value"))); 8748 } 8749 8750 // in case of an error, return discarded value 8751 if (sdp.is_errored()) 8752 { 8753 result = value_t::discarded; 8754 return; 8755 } 8756 8757 // set top-level value to null if it was discarded by the callback 8758 // function 8759 if (result.is_discarded()) 8760 { 8761 result = nullptr; 8762 } 8763 } 8764 else 8765 { 8766 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions); 8767 sax_parse_internal(&sdp); 8768 result.assert_invariant(); 8769 8770 // in strict mode, input must be completely read 8771 if (strict and (get_token() != token_type::end_of_input)) 8772 { 8773 sdp.parse_error(m_lexer.get_position(), 8774 m_lexer.get_token_string(), 8775 parse_error::create(101, m_lexer.get_position(), 8776 exception_message(token_type::end_of_input, "value"))); 8777 } 8778 8779 // in case of an error, return discarded value 8780 if (sdp.is_errored()) 8781 { 8782 result = value_t::discarded; 8783 return; 8784 } 8785 } 8786 } 8787 8788 /*! 8789 @brief public accept interface 8790 8791 @param[in] strict whether to expect the last token to be EOF 8792 @return whether the input is a proper JSON text 8793 */ 8794 bool accept(const bool strict = true) 8795 { 8796 json_sax_acceptor<BasicJsonType> sax_acceptor; 8797 return sax_parse(&sax_acceptor, strict); 8798 } 8799 8800 template <typename SAX> 8801 JSON_HEDLEY_NON_NULL(2) 8802 bool sax_parse(SAX* sax, const bool strict = true) 8803 { 8804 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {}; 8805 const bool result = sax_parse_internal(sax); 8806 8807 // strict mode: next byte must be EOF 8808 if (result and strict and (get_token() != token_type::end_of_input)) 8809 { 8810 return sax->parse_error(m_lexer.get_position(), 8811 m_lexer.get_token_string(), 8812 parse_error::create(101, m_lexer.get_position(), 8813 exception_message(token_type::end_of_input, "value"))); 8814 } 8815 8816 return result; 8817 } 8818 8819 private: 8820 template <typename SAX> 8821 JSON_HEDLEY_NON_NULL(2) 8822 bool sax_parse_internal(SAX* sax) 8823 { 8824 // stack to remember the hierarchy of structured values we are parsing 8825 // true = array; false = object 8826 std::vector<bool> states; 8827 // value to avoid a goto (see comment where set to true) 8828 bool skip_to_state_evaluation = false; 8829 8830 while (true) 8831 { 8832 if (not skip_to_state_evaluation) 8833 { 8834 // invariant: get_token() was called before each iteration 8835 switch (last_token) 8836 { 8837 case token_type::begin_object: 8838 { 8839 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1)))) 8840 { 8841 return false; 8842 } 8843 8844 // closing } -> we are done 8845 if (get_token() == token_type::end_object) 8846 { 8847 if (JSON_HEDLEY_UNLIKELY(not sax->end_object())) 8848 { 8849 return false; 8850 } 8851 break; 8852 } 8853 8854 // parse key 8855 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string)) 8856 { 8857 return sax->parse_error(m_lexer.get_position(), 8858 m_lexer.get_token_string(), 8859 parse_error::create(101, m_lexer.get_position(), 8860 exception_message(token_type::value_string, "object key"))); 8861 } 8862 if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string()))) 8863 { 8864 return false; 8865 } 8866 8867 // parse separator (:) 8868 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) 8869 { 8870 return sax->parse_error(m_lexer.get_position(), 8871 m_lexer.get_token_string(), 8872 parse_error::create(101, m_lexer.get_position(), 8873 exception_message(token_type::name_separator, "object separator"))); 8874 } 8875 8876 // remember we are now inside an object 8877 states.push_back(false); 8878 8879 // parse values 8880 get_token(); 8881 continue; 8882 } 8883 8884 case token_type::begin_array: 8885 { 8886 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1)))) 8887 { 8888 return false; 8889 } 8890 8891 // closing ] -> we are done 8892 if (get_token() == token_type::end_array) 8893 { 8894 if (JSON_HEDLEY_UNLIKELY(not sax->end_array())) 8895 { 8896 return false; 8897 } 8898 break; 8899 } 8900 8901 // remember we are now inside an array 8902 states.push_back(true); 8903 8904 // parse values (no need to call get_token) 8905 continue; 8906 } 8907 8908 case token_type::value_float: 8909 { 8910 const auto res = m_lexer.get_number_float(); 8911 8912 if (JSON_HEDLEY_UNLIKELY(not std::isfinite(res))) 8913 { 8914 return sax->parse_error(m_lexer.get_position(), 8915 m_lexer.get_token_string(), 8916 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'")); 8917 } 8918 8919 if (JSON_HEDLEY_UNLIKELY(not sax->number_float(res, m_lexer.get_string()))) 8920 { 8921 return false; 8922 } 8923 8924 break; 8925 } 8926 8927 case token_type::literal_false: 8928 { 8929 if (JSON_HEDLEY_UNLIKELY(not sax->boolean(false))) 8930 { 8931 return false; 8932 } 8933 break; 8934 } 8935 8936 case token_type::literal_null: 8937 { 8938 if (JSON_HEDLEY_UNLIKELY(not sax->null())) 8939 { 8940 return false; 8941 } 8942 break; 8943 } 8944 8945 case token_type::literal_true: 8946 { 8947 if (JSON_HEDLEY_UNLIKELY(not sax->boolean(true))) 8948 { 8949 return false; 8950 } 8951 break; 8952 } 8953 8954 case token_type::value_integer: 8955 { 8956 if (JSON_HEDLEY_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer()))) 8957 { 8958 return false; 8959 } 8960 break; 8961 } 8962 8963 case token_type::value_string: 8964 { 8965 if (JSON_HEDLEY_UNLIKELY(not sax->string(m_lexer.get_string()))) 8966 { 8967 return false; 8968 } 8969 break; 8970 } 8971 8972 case token_type::value_unsigned: 8973 { 8974 if (JSON_HEDLEY_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned()))) 8975 { 8976 return false; 8977 } 8978 break; 8979 } 8980 8981 case token_type::parse_error: 8982 { 8983 // using "uninitialized" to avoid "expected" message 8984 return sax->parse_error(m_lexer.get_position(), 8985 m_lexer.get_token_string(), 8986 parse_error::create(101, m_lexer.get_position(), 8987 exception_message(token_type::uninitialized, "value"))); 8988 } 8989 8990 default: // the last token was unexpected 8991 { 8992 return sax->parse_error(m_lexer.get_position(), 8993 m_lexer.get_token_string(), 8994 parse_error::create(101, m_lexer.get_position(), 8995 exception_message(token_type::literal_or_value, "value"))); 8996 } 8997 } 8998 } 8999 else 9000 { 9001 skip_to_state_evaluation = false; 9002 } 9003 9004 // we reached this line after we successfully parsed a value 9005 if (states.empty()) 9006 { 9007 // empty stack: we reached the end of the hierarchy: done 9008 return true; 9009 } 9010 9011 if (states.back()) // array 9012 { 9013 // comma -> next value 9014 if (get_token() == token_type::value_separator) 9015 { 9016 // parse a new value 9017 get_token(); 9018 continue; 9019 } 9020 9021 // closing ] 9022 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array)) 9023 { 9024 if (JSON_HEDLEY_UNLIKELY(not sax->end_array())) 9025 { 9026 return false; 9027 } 9028 9029 // We are done with this array. Before we can parse a 9030 // new value, we need to evaluate the new state first. 9031 // By setting skip_to_state_evaluation to false, we 9032 // are effectively jumping to the beginning of this if. 9033 assert(not states.empty()); 9034 states.pop_back(); 9035 skip_to_state_evaluation = true; 9036 continue; 9037 } 9038 9039 return sax->parse_error(m_lexer.get_position(), 9040 m_lexer.get_token_string(), 9041 parse_error::create(101, m_lexer.get_position(), 9042 exception_message(token_type::end_array, "array"))); 9043 } 9044 else // object 9045 { 9046 // comma -> next value 9047 if (get_token() == token_type::value_separator) 9048 { 9049 // parse key 9050 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string)) 9051 { 9052 return sax->parse_error(m_lexer.get_position(), 9053 m_lexer.get_token_string(), 9054 parse_error::create(101, m_lexer.get_position(), 9055 exception_message(token_type::value_string, "object key"))); 9056 } 9057 9058 if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string()))) 9059 { 9060 return false; 9061 } 9062 9063 // parse separator (:) 9064 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) 9065 { 9066 return sax->parse_error(m_lexer.get_position(), 9067 m_lexer.get_token_string(), 9068 parse_error::create(101, m_lexer.get_position(), 9069 exception_message(token_type::name_separator, "object separator"))); 9070 } 9071 9072 // parse values 9073 get_token(); 9074 continue; 9075 } 9076 9077 // closing } 9078 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object)) 9079 { 9080 if (JSON_HEDLEY_UNLIKELY(not sax->end_object())) 9081 { 9082 return false; 9083 } 9084 9085 // We are done with this object. Before we can parse a 9086 // new value, we need to evaluate the new state first. 9087 // By setting skip_to_state_evaluation to false, we 9088 // are effectively jumping to the beginning of this if. 9089 assert(not states.empty()); 9090 states.pop_back(); 9091 skip_to_state_evaluation = true; 9092 continue; 9093 } 9094 9095 return sax->parse_error(m_lexer.get_position(), 9096 m_lexer.get_token_string(), 9097 parse_error::create(101, m_lexer.get_position(), 9098 exception_message(token_type::end_object, "object"))); 9099 } 9100 } 9101 } 9102 9103 /// get next token from lexer 9104 token_type get_token() 9105 { 9106 return last_token = m_lexer.scan(); 9107 } 9108 9109 std::string exception_message(const token_type expected, const std::string& context) 9110 { 9111 std::string error_msg = "syntax error "; 9112 9113 if (not context.empty()) 9114 { 9115 error_msg += "while parsing " + context + " "; 9116 } 9117 9118 error_msg += "- "; 9119 9120 if (last_token == token_type::parse_error) 9121 { 9122 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" + 9123 m_lexer.get_token_string() + "'"; 9124 } 9125 else 9126 { 9127 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token)); 9128 } 9129 9130 if (expected != token_type::uninitialized) 9131 { 9132 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected)); 9133 } 9134 9135 return error_msg; 9136 } 9137 9138 private: 9139 /// callback function 9140 const parser_callback_t callback = nullptr; 9141 /// the type of the last read token 9142 token_type last_token = token_type::uninitialized; 9143 /// the lexer 9144 lexer_t m_lexer; 9145 /// whether to throw exceptions in case of errors 9146 const bool allow_exceptions = true; 9147}; 9148} // namespace detail 9149} // namespace nlohmann 9150 9151// #include <nlohmann/detail/iterators/internal_iterator.hpp> 9152 9153 9154// #include <nlohmann/detail/iterators/primitive_iterator.hpp> 9155 9156 9157#include <cstddef> // ptrdiff_t 9158#include <limits> // numeric_limits 9159 9160namespace nlohmann 9161{ 9162namespace detail 9163{ 9164/* 9165@brief an iterator for primitive JSON types 9166 9167This class models an iterator for primitive JSON types (boolean, number, 9168string). It's only purpose is to allow the iterator/const_iterator classes 9169to "iterate" over primitive values. Internally, the iterator is modeled by 9170a `difference_type` variable. Value begin_value (`0`) models the begin, 9171end_value (`1`) models past the end. 9172*/ 9173class primitive_iterator_t 9174{ 9175 private: 9176 using difference_type = std::ptrdiff_t; 9177 static constexpr difference_type begin_value = 0; 9178 static constexpr difference_type end_value = begin_value + 1; 9179 9180 /// iterator as signed integer type 9181 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)(); 9182 9183 public: 9184 constexpr difference_type get_value() const noexcept 9185 { 9186 return m_it; 9187 } 9188 9189 /// set iterator to a defined beginning 9190 void set_begin() noexcept 9191 { 9192 m_it = begin_value; 9193 } 9194 9195 /// set iterator to a defined past the end 9196 void set_end() noexcept 9197 { 9198 m_it = end_value; 9199 } 9200 9201 /// return whether the iterator can be dereferenced 9202 constexpr bool is_begin() const noexcept 9203 { 9204 return m_it == begin_value; 9205 } 9206 9207 /// return whether the iterator is at end 9208 constexpr bool is_end() const noexcept 9209 { 9210 return m_it == end_value; 9211 } 9212 9213 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept 9214 { 9215 return lhs.m_it == rhs.m_it; 9216 } 9217 9218 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept 9219 { 9220 return lhs.m_it < rhs.m_it; 9221 } 9222 9223 primitive_iterator_t operator+(difference_type n) noexcept 9224 { 9225 auto result = *this; 9226 result += n; 9227 return result; 9228 } 9229 9230 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept 9231 { 9232 return lhs.m_it - rhs.m_it; 9233 } 9234 9235 primitive_iterator_t& operator++() noexcept 9236 { 9237 ++m_it; 9238 return *this; 9239 } 9240 9241 primitive_iterator_t const operator++(int) noexcept 9242 { 9243 auto result = *this; 9244 ++m_it; 9245 return result; 9246 } 9247 9248 primitive_iterator_t& operator--() noexcept 9249 { 9250 --m_it; 9251 return *this; 9252 } 9253 9254 primitive_iterator_t const operator--(int) noexcept 9255 { 9256 auto result = *this; 9257 --m_it; 9258 return result; 9259 } 9260 9261 primitive_iterator_t& operator+=(difference_type n) noexcept 9262 { 9263 m_it += n; 9264 return *this; 9265 } 9266 9267 primitive_iterator_t& operator-=(difference_type n) noexcept 9268 { 9269 m_it -= n; 9270 return *this; 9271 } 9272}; 9273} // namespace detail 9274} // namespace nlohmann 9275 9276 9277namespace nlohmann 9278{ 9279namespace detail 9280{ 9281/*! 9282@brief an iterator value 9283 9284@note This structure could easily be a union, but MSVC currently does not allow 9285unions members with complex constructors, see https://github.com/nlohmann/json/pull/105. 9286*/ 9287template<typename BasicJsonType> struct internal_iterator 9288{ 9289 /// iterator for JSON objects 9290 typename BasicJsonType::object_t::iterator object_iterator {}; 9291 /// iterator for JSON arrays 9292 typename BasicJsonType::array_t::iterator array_iterator {}; 9293 /// generic iterator for all other types 9294 primitive_iterator_t primitive_iterator {}; 9295}; 9296} // namespace detail 9297} // namespace nlohmann 9298 9299// #include <nlohmann/detail/iterators/iter_impl.hpp> 9300 9301 9302#include <ciso646> // not 9303#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next 9304#include <type_traits> // conditional, is_const, remove_const 9305 9306// #include <nlohmann/detail/exceptions.hpp> 9307 9308// #include <nlohmann/detail/iterators/internal_iterator.hpp> 9309 9310// #include <nlohmann/detail/iterators/primitive_iterator.hpp> 9311 9312// #include <nlohmann/detail/macro_scope.hpp> 9313 9314// #include <nlohmann/detail/meta/cpp_future.hpp> 9315 9316// #include <nlohmann/detail/meta/type_traits.hpp> 9317 9318// #include <nlohmann/detail/value_t.hpp> 9319 9320 9321namespace nlohmann 9322{ 9323namespace detail 9324{ 9325// forward declare, to be able to friend it later on 9326template<typename IteratorType> class iteration_proxy; 9327template<typename IteratorType> class iteration_proxy_value; 9328 9329/*! 9330@brief a template for a bidirectional iterator for the @ref basic_json class 9331This class implements a both iterators (iterator and const_iterator) for the 9332@ref basic_json class. 9333@note An iterator is called *initialized* when a pointer to a JSON value has 9334 been set (e.g., by a constructor or a copy assignment). If the iterator is 9335 default-constructed, it is *uninitialized* and most methods are undefined. 9336 **The library uses assertions to detect calls on uninitialized iterators.** 9337@requirement The class satisfies the following concept requirements: 9338- 9339[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator): 9340 The iterator that can be moved can be moved in both directions (i.e. 9341 incremented and decremented). 9342@since version 1.0.0, simplified in version 2.0.9, change to bidirectional 9343 iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593) 9344*/ 9345template<typename BasicJsonType> 9346class iter_impl 9347{ 9348 /// allow basic_json to access private members 9349 friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>; 9350 friend BasicJsonType; 9351 friend iteration_proxy<iter_impl>; 9352 friend iteration_proxy_value<iter_impl>; 9353 9354 using object_t = typename BasicJsonType::object_t; 9355 using array_t = typename BasicJsonType::array_t; 9356 // make sure BasicJsonType is basic_json or const basic_json 9357 static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value, 9358 "iter_impl only accepts (const) basic_json"); 9359 9360 public: 9361 9362 /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17. 9363 /// The C++ Standard has never required user-defined iterators to derive from std::iterator. 9364 /// A user-defined iterator should provide publicly accessible typedefs named 9365 /// iterator_category, value_type, difference_type, pointer, and reference. 9366 /// Note that value_type is required to be non-const, even for constant iterators. 9367 using iterator_category = std::bidirectional_iterator_tag; 9368 9369 /// the type of the values when the iterator is dereferenced 9370 using value_type = typename BasicJsonType::value_type; 9371 /// a type to represent differences between iterators 9372 using difference_type = typename BasicJsonType::difference_type; 9373 /// defines a pointer to the type iterated over (value_type) 9374 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value, 9375 typename BasicJsonType::const_pointer, 9376 typename BasicJsonType::pointer>::type; 9377 /// defines a reference to the type iterated over (value_type) 9378 using reference = 9379 typename std::conditional<std::is_const<BasicJsonType>::value, 9380 typename BasicJsonType::const_reference, 9381 typename BasicJsonType::reference>::type; 9382 9383 /// default constructor 9384 iter_impl() = default; 9385 9386 /*! 9387 @brief constructor for a given JSON instance 9388 @param[in] object pointer to a JSON object for this iterator 9389 @pre object != nullptr 9390 @post The iterator is initialized; i.e. `m_object != nullptr`. 9391 */ 9392 explicit iter_impl(pointer object) noexcept : m_object(object) 9393 { 9394 assert(m_object != nullptr); 9395 9396 switch (m_object->m_type) 9397 { 9398 case value_t::object: 9399 { 9400 m_it.object_iterator = typename object_t::iterator(); 9401 break; 9402 } 9403 9404 case value_t::array: 9405 { 9406 m_it.array_iterator = typename array_t::iterator(); 9407 break; 9408 } 9409 9410 default: 9411 { 9412 m_it.primitive_iterator = primitive_iterator_t(); 9413 break; 9414 } 9415 } 9416 } 9417 9418 /*! 9419 @note The conventional copy constructor and copy assignment are implicitly 9420 defined. Combined with the following converting constructor and 9421 assignment, they support: (1) copy from iterator to iterator, (2) 9422 copy from const iterator to const iterator, and (3) conversion from 9423 iterator to const iterator. However conversion from const iterator 9424 to iterator is not defined. 9425 */ 9426 9427 /*! 9428 @brief const copy constructor 9429 @param[in] other const iterator to copy from 9430 @note This copy constructor had to be defined explicitly to circumvent a bug 9431 occurring on msvc v19.0 compiler (VS 2015) debug build. For more 9432 information refer to: https://github.com/nlohmann/json/issues/1608 9433 */ 9434 iter_impl(const iter_impl<const BasicJsonType>& other) noexcept 9435 : m_object(other.m_object), m_it(other.m_it) 9436 {} 9437 9438 /*! 9439 @brief converting assignment 9440 @param[in] other const iterator to copy from 9441 @return const/non-const iterator 9442 @note It is not checked whether @a other is initialized. 9443 */ 9444 iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept 9445 { 9446 m_object = other.m_object; 9447 m_it = other.m_it; 9448 return *this; 9449 } 9450 9451 /*! 9452 @brief converting constructor 9453 @param[in] other non-const iterator to copy from 9454 @note It is not checked whether @a other is initialized. 9455 */ 9456 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept 9457 : m_object(other.m_object), m_it(other.m_it) 9458 {} 9459 9460 /*! 9461 @brief converting assignment 9462 @param[in] other non-const iterator to copy from 9463 @return const/non-const iterator 9464 @note It is not checked whether @a other is initialized. 9465 */ 9466 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept 9467 { 9468 m_object = other.m_object; 9469 m_it = other.m_it; 9470 return *this; 9471 } 9472 9473 private: 9474 /*! 9475 @brief set the iterator to the first value 9476 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9477 */ 9478 void set_begin() noexcept 9479 { 9480 assert(m_object != nullptr); 9481 9482 switch (m_object->m_type) 9483 { 9484 case value_t::object: 9485 { 9486 m_it.object_iterator = m_object->m_value.object->begin(); 9487 break; 9488 } 9489 9490 case value_t::array: 9491 { 9492 m_it.array_iterator = m_object->m_value.array->begin(); 9493 break; 9494 } 9495 9496 case value_t::null: 9497 { 9498 // set to end so begin()==end() is true: null is empty 9499 m_it.primitive_iterator.set_end(); 9500 break; 9501 } 9502 9503 default: 9504 { 9505 m_it.primitive_iterator.set_begin(); 9506 break; 9507 } 9508 } 9509 } 9510 9511 /*! 9512 @brief set the iterator past the last value 9513 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9514 */ 9515 void set_end() noexcept 9516 { 9517 assert(m_object != nullptr); 9518 9519 switch (m_object->m_type) 9520 { 9521 case value_t::object: 9522 { 9523 m_it.object_iterator = m_object->m_value.object->end(); 9524 break; 9525 } 9526 9527 case value_t::array: 9528 { 9529 m_it.array_iterator = m_object->m_value.array->end(); 9530 break; 9531 } 9532 9533 default: 9534 { 9535 m_it.primitive_iterator.set_end(); 9536 break; 9537 } 9538 } 9539 } 9540 9541 public: 9542 /*! 9543 @brief return a reference to the value pointed to by the iterator 9544 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9545 */ 9546 reference operator*() const 9547 { 9548 assert(m_object != nullptr); 9549 9550 switch (m_object->m_type) 9551 { 9552 case value_t::object: 9553 { 9554 assert(m_it.object_iterator != m_object->m_value.object->end()); 9555 return m_it.object_iterator->second; 9556 } 9557 9558 case value_t::array: 9559 { 9560 assert(m_it.array_iterator != m_object->m_value.array->end()); 9561 return *m_it.array_iterator; 9562 } 9563 9564 case value_t::null: 9565 JSON_THROW(invalid_iterator::create(214, "cannot get value")); 9566 9567 default: 9568 { 9569 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin())) 9570 { 9571 return *m_object; 9572 } 9573 9574 JSON_THROW(invalid_iterator::create(214, "cannot get value")); 9575 } 9576 } 9577 } 9578 9579 /*! 9580 @brief dereference the iterator 9581 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9582 */ 9583 pointer operator->() const 9584 { 9585 assert(m_object != nullptr); 9586 9587 switch (m_object->m_type) 9588 { 9589 case value_t::object: 9590 { 9591 assert(m_it.object_iterator != m_object->m_value.object->end()); 9592 return &(m_it.object_iterator->second); 9593 } 9594 9595 case value_t::array: 9596 { 9597 assert(m_it.array_iterator != m_object->m_value.array->end()); 9598 return &*m_it.array_iterator; 9599 } 9600 9601 default: 9602 { 9603 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin())) 9604 { 9605 return m_object; 9606 } 9607 9608 JSON_THROW(invalid_iterator::create(214, "cannot get value")); 9609 } 9610 } 9611 } 9612 9613 /*! 9614 @brief post-increment (it++) 9615 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9616 */ 9617 iter_impl const operator++(int) 9618 { 9619 auto result = *this; 9620 ++(*this); 9621 return result; 9622 } 9623 9624 /*! 9625 @brief pre-increment (++it) 9626 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9627 */ 9628 iter_impl& operator++() 9629 { 9630 assert(m_object != nullptr); 9631 9632 switch (m_object->m_type) 9633 { 9634 case value_t::object: 9635 { 9636 std::advance(m_it.object_iterator, 1); 9637 break; 9638 } 9639 9640 case value_t::array: 9641 { 9642 std::advance(m_it.array_iterator, 1); 9643 break; 9644 } 9645 9646 default: 9647 { 9648 ++m_it.primitive_iterator; 9649 break; 9650 } 9651 } 9652 9653 return *this; 9654 } 9655 9656 /*! 9657 @brief post-decrement (it--) 9658 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9659 */ 9660 iter_impl const operator--(int) 9661 { 9662 auto result = *this; 9663 --(*this); 9664 return result; 9665 } 9666 9667 /*! 9668 @brief pre-decrement (--it) 9669 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9670 */ 9671 iter_impl& operator--() 9672 { 9673 assert(m_object != nullptr); 9674 9675 switch (m_object->m_type) 9676 { 9677 case value_t::object: 9678 { 9679 std::advance(m_it.object_iterator, -1); 9680 break; 9681 } 9682 9683 case value_t::array: 9684 { 9685 std::advance(m_it.array_iterator, -1); 9686 break; 9687 } 9688 9689 default: 9690 { 9691 --m_it.primitive_iterator; 9692 break; 9693 } 9694 } 9695 9696 return *this; 9697 } 9698 9699 /*! 9700 @brief comparison: equal 9701 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9702 */ 9703 bool operator==(const iter_impl& other) const 9704 { 9705 // if objects are not the same, the comparison is undefined 9706 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) 9707 { 9708 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers")); 9709 } 9710 9711 assert(m_object != nullptr); 9712 9713 switch (m_object->m_type) 9714 { 9715 case value_t::object: 9716 return (m_it.object_iterator == other.m_it.object_iterator); 9717 9718 case value_t::array: 9719 return (m_it.array_iterator == other.m_it.array_iterator); 9720 9721 default: 9722 return (m_it.primitive_iterator == other.m_it.primitive_iterator); 9723 } 9724 } 9725 9726 /*! 9727 @brief comparison: not equal 9728 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9729 */ 9730 bool operator!=(const iter_impl& other) const 9731 { 9732 return not operator==(other); 9733 } 9734 9735 /*! 9736 @brief comparison: smaller 9737 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9738 */ 9739 bool operator<(const iter_impl& other) const 9740 { 9741 // if objects are not the same, the comparison is undefined 9742 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) 9743 { 9744 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers")); 9745 } 9746 9747 assert(m_object != nullptr); 9748 9749 switch (m_object->m_type) 9750 { 9751 case value_t::object: 9752 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators")); 9753 9754 case value_t::array: 9755 return (m_it.array_iterator < other.m_it.array_iterator); 9756 9757 default: 9758 return (m_it.primitive_iterator < other.m_it.primitive_iterator); 9759 } 9760 } 9761 9762 /*! 9763 @brief comparison: less than or equal 9764 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9765 */ 9766 bool operator<=(const iter_impl& other) const 9767 { 9768 return not other.operator < (*this); 9769 } 9770 9771 /*! 9772 @brief comparison: greater than 9773 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9774 */ 9775 bool operator>(const iter_impl& other) const 9776 { 9777 return not operator<=(other); 9778 } 9779 9780 /*! 9781 @brief comparison: greater than or equal 9782 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9783 */ 9784 bool operator>=(const iter_impl& other) const 9785 { 9786 return not operator<(other); 9787 } 9788 9789 /*! 9790 @brief add to iterator 9791 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9792 */ 9793 iter_impl& operator+=(difference_type i) 9794 { 9795 assert(m_object != nullptr); 9796 9797 switch (m_object->m_type) 9798 { 9799 case value_t::object: 9800 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators")); 9801 9802 case value_t::array: 9803 { 9804 std::advance(m_it.array_iterator, i); 9805 break; 9806 } 9807 9808 default: 9809 { 9810 m_it.primitive_iterator += i; 9811 break; 9812 } 9813 } 9814 9815 return *this; 9816 } 9817 9818 /*! 9819 @brief subtract from iterator 9820 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9821 */ 9822 iter_impl& operator-=(difference_type i) 9823 { 9824 return operator+=(-i); 9825 } 9826 9827 /*! 9828 @brief add to iterator 9829 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9830 */ 9831 iter_impl operator+(difference_type i) const 9832 { 9833 auto result = *this; 9834 result += i; 9835 return result; 9836 } 9837 9838 /*! 9839 @brief addition of distance and iterator 9840 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9841 */ 9842 friend iter_impl operator+(difference_type i, const iter_impl& it) 9843 { 9844 auto result = it; 9845 result += i; 9846 return result; 9847 } 9848 9849 /*! 9850 @brief subtract from iterator 9851 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9852 */ 9853 iter_impl operator-(difference_type i) const 9854 { 9855 auto result = *this; 9856 result -= i; 9857 return result; 9858 } 9859 9860 /*! 9861 @brief return difference 9862 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9863 */ 9864 difference_type operator-(const iter_impl& other) const 9865 { 9866 assert(m_object != nullptr); 9867 9868 switch (m_object->m_type) 9869 { 9870 case value_t::object: 9871 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators")); 9872 9873 case value_t::array: 9874 return m_it.array_iterator - other.m_it.array_iterator; 9875 9876 default: 9877 return m_it.primitive_iterator - other.m_it.primitive_iterator; 9878 } 9879 } 9880 9881 /*! 9882 @brief access to successor 9883 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9884 */ 9885 reference operator[](difference_type n) const 9886 { 9887 assert(m_object != nullptr); 9888 9889 switch (m_object->m_type) 9890 { 9891 case value_t::object: 9892 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators")); 9893 9894 case value_t::array: 9895 return *std::next(m_it.array_iterator, n); 9896 9897 case value_t::null: 9898 JSON_THROW(invalid_iterator::create(214, "cannot get value")); 9899 9900 default: 9901 { 9902 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n)) 9903 { 9904 return *m_object; 9905 } 9906 9907 JSON_THROW(invalid_iterator::create(214, "cannot get value")); 9908 } 9909 } 9910 } 9911 9912 /*! 9913 @brief return the key of an object iterator 9914 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9915 */ 9916 const typename object_t::key_type& key() const 9917 { 9918 assert(m_object != nullptr); 9919 9920 if (JSON_HEDLEY_LIKELY(m_object->is_object())) 9921 { 9922 return m_it.object_iterator->first; 9923 } 9924 9925 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators")); 9926 } 9927 9928 /*! 9929 @brief return the value of an iterator 9930 @pre The iterator is initialized; i.e. `m_object != nullptr`. 9931 */ 9932 reference value() const 9933 { 9934 return operator*(); 9935 } 9936 9937 private: 9938 /// associated JSON instance 9939 pointer m_object = nullptr; 9940 /// the actual iterator of the associated instance 9941 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {}; 9942}; 9943} // namespace detail 9944} // namespace nlohmann 9945 9946// #include <nlohmann/detail/iterators/iteration_proxy.hpp> 9947 9948// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp> 9949 9950 9951#include <cstddef> // ptrdiff_t 9952#include <iterator> // reverse_iterator 9953#include <utility> // declval 9954 9955namespace nlohmann 9956{ 9957namespace detail 9958{ 9959////////////////////// 9960// reverse_iterator // 9961////////////////////// 9962 9963/*! 9964@brief a template for a reverse iterator class 9965 9966@tparam Base the base iterator type to reverse. Valid types are @ref 9967iterator (to create @ref reverse_iterator) and @ref const_iterator (to 9968create @ref const_reverse_iterator). 9969 9970@requirement The class satisfies the following concept requirements: 9971- 9972[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator): 9973 The iterator that can be moved can be moved in both directions (i.e. 9974 incremented and decremented). 9975- [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator): 9976 It is possible to write to the pointed-to element (only if @a Base is 9977 @ref iterator). 9978 9979@since version 1.0.0 9980*/ 9981template<typename Base> 9982class json_reverse_iterator : public std::reverse_iterator<Base> 9983{ 9984 public: 9985 using difference_type = std::ptrdiff_t; 9986 /// shortcut to the reverse iterator adapter 9987 using base_iterator = std::reverse_iterator<Base>; 9988 /// the reference type for the pointed-to element 9989 using reference = typename Base::reference; 9990 9991 /// create reverse iterator from iterator 9992 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept 9993 : base_iterator(it) {} 9994 9995 /// create reverse iterator from base class 9996 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {} 9997 9998 /// post-increment (it++) 9999 json_reverse_iterator const operator++(int) 10000 { 10001 return static_cast<json_reverse_iterator>(base_iterator::operator++(1)); 10002 } 10003 10004 /// pre-increment (++it) 10005 json_reverse_iterator& operator++() 10006 { 10007 return static_cast<json_reverse_iterator&>(base_iterator::operator++()); 10008 } 10009 10010 /// post-decrement (it--) 10011 json_reverse_iterator const operator--(int) 10012 { 10013 return static_cast<json_reverse_iterator>(base_iterator::operator--(1)); 10014 } 10015 10016 /// pre-decrement (--it) 10017 json_reverse_iterator& operator--() 10018 { 10019 return static_cast<json_reverse_iterator&>(base_iterator::operator--()); 10020 } 10021 10022 /// add to iterator 10023 json_reverse_iterator& operator+=(difference_type i) 10024 { 10025 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i)); 10026 } 10027 10028 /// add to iterator 10029 json_reverse_iterator operator+(difference_type i) const 10030 { 10031 return static_cast<json_reverse_iterator>(base_iterator::operator+(i)); 10032 } 10033 10034 /// subtract from iterator 10035 json_reverse_iterator operator-(difference_type i) const 10036 { 10037 return static_cast<json_reverse_iterator>(base_iterator::operator-(i)); 10038 } 10039 10040 /// return difference 10041 difference_type operator-(const json_reverse_iterator& other) const 10042 { 10043 return base_iterator(*this) - base_iterator(other); 10044 } 10045 10046 /// access to successor 10047 reference operator[](difference_type n) const 10048 { 10049 return *(this->operator+(n)); 10050 } 10051 10052 /// return the key of an object iterator 10053 auto key() const -> decltype(std::declval<Base>().key()) 10054 { 10055 auto it = --this->base(); 10056 return it.key(); 10057 } 10058 10059 /// return the value of an iterator 10060 reference value() const 10061 { 10062 auto it = --this->base(); 10063 return it.operator * (); 10064 } 10065}; 10066} // namespace detail 10067} // namespace nlohmann 10068 10069// #include <nlohmann/detail/iterators/primitive_iterator.hpp> 10070 10071// #include <nlohmann/detail/json_pointer.hpp> 10072 10073 10074#include <algorithm> // all_of 10075#include <cassert> // assert 10076#include <cctype> // isdigit 10077#include <numeric> // accumulate 10078#include <string> // string 10079#include <utility> // move 10080#include <vector> // vector 10081 10082// #include <nlohmann/detail/exceptions.hpp> 10083 10084// #include <nlohmann/detail/macro_scope.hpp> 10085 10086// #include <nlohmann/detail/value_t.hpp> 10087 10088 10089namespace nlohmann 10090{ 10091template<typename BasicJsonType> 10092class json_pointer 10093{ 10094 // allow basic_json to access private members 10095 NLOHMANN_BASIC_JSON_TPL_DECLARATION 10096 friend class basic_json; 10097 10098 public: 10099 /*! 10100 @brief create JSON pointer 10101 10102 Create a JSON pointer according to the syntax described in 10103 [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3). 10104 10105 @param[in] s string representing the JSON pointer; if omitted, the empty 10106 string is assumed which references the whole JSON value 10107 10108 @throw parse_error.107 if the given JSON pointer @a s is nonempty and does 10109 not begin with a slash (`/`); see example below 10110 10111 @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is 10112 not followed by `0` (representing `~`) or `1` (representing `/`); see 10113 example below 10114 10115 @liveexample{The example shows the construction several valid JSON pointers 10116 as well as the exceptional behavior.,json_pointer} 10117 10118 @since version 2.0.0 10119 */ 10120 explicit json_pointer(const std::string& s = "") 10121 : reference_tokens(split(s)) 10122 {} 10123 10124 /*! 10125 @brief return a string representation of the JSON pointer 10126 10127 @invariant For each JSON pointer `ptr`, it holds: 10128 @code {.cpp} 10129 ptr == json_pointer(ptr.to_string()); 10130 @endcode 10131 10132 @return a string representation of the JSON pointer 10133 10134 @liveexample{The example shows the result of `to_string`.,json_pointer__to_string} 10135 10136 @since version 2.0.0 10137 */ 10138 std::string to_string() const 10139 { 10140 return std::accumulate(reference_tokens.begin(), reference_tokens.end(), 10141 std::string{}, 10142 [](const std::string & a, const std::string & b) 10143 { 10144 return a + "/" + escape(b); 10145 }); 10146 } 10147 10148 /// @copydoc to_string() 10149 operator std::string() const 10150 { 10151 return to_string(); 10152 } 10153 10154 /*! 10155 @brief append another JSON pointer at the end of this JSON pointer 10156 10157 @param[in] ptr JSON pointer to append 10158 @return JSON pointer with @a ptr appended 10159 10160 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add} 10161 10162 @complexity Linear in the length of @a ptr. 10163 10164 @sa @ref operator/=(std::string) to append a reference token 10165 @sa @ref operator/=(std::size_t) to append an array index 10166 @sa @ref operator/(const json_pointer&, const json_pointer&) for a binary operator 10167 10168 @since version 3.6.0 10169 */ 10170 json_pointer& operator/=(const json_pointer& ptr) 10171 { 10172 reference_tokens.insert(reference_tokens.end(), 10173 ptr.reference_tokens.begin(), 10174 ptr.reference_tokens.end()); 10175 return *this; 10176 } 10177 10178 /*! 10179 @brief append an unescaped reference token at the end of this JSON pointer 10180 10181 @param[in] token reference token to append 10182 @return JSON pointer with @a token appended without escaping @a token 10183 10184 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add} 10185 10186 @complexity Amortized constant. 10187 10188 @sa @ref operator/=(const json_pointer&) to append a JSON pointer 10189 @sa @ref operator/=(std::size_t) to append an array index 10190 @sa @ref operator/(const json_pointer&, std::size_t) for a binary operator 10191 10192 @since version 3.6.0 10193 */ 10194 json_pointer& operator/=(std::string token) 10195 { 10196 push_back(std::move(token)); 10197 return *this; 10198 } 10199 10200 /*! 10201 @brief append an array index at the end of this JSON pointer 10202 10203 @param[in] array_index array index to append 10204 @return JSON pointer with @a array_index appended 10205 10206 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add} 10207 10208 @complexity Amortized constant. 10209 10210 @sa @ref operator/=(const json_pointer&) to append a JSON pointer 10211 @sa @ref operator/=(std::string) to append a reference token 10212 @sa @ref operator/(const json_pointer&, std::string) for a binary operator 10213 10214 @since version 3.6.0 10215 */ 10216 json_pointer& operator/=(std::size_t array_index) 10217 { 10218 return *this /= std::to_string(array_index); 10219 } 10220 10221 /*! 10222 @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer 10223 10224 @param[in] lhs JSON pointer 10225 @param[in] rhs JSON pointer 10226 @return a new JSON pointer with @a rhs appended to @a lhs 10227 10228 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary} 10229 10230 @complexity Linear in the length of @a lhs and @a rhs. 10231 10232 @sa @ref operator/=(const json_pointer&) to append a JSON pointer 10233 10234 @since version 3.6.0 10235 */ 10236 friend json_pointer operator/(const json_pointer& lhs, 10237 const json_pointer& rhs) 10238 { 10239 return json_pointer(lhs) /= rhs; 10240 } 10241 10242 /*! 10243 @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer 10244 10245 @param[in] ptr JSON pointer 10246 @param[in] token reference token 10247 @return a new JSON pointer with unescaped @a token appended to @a ptr 10248 10249 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary} 10250 10251 @complexity Linear in the length of @a ptr. 10252 10253 @sa @ref operator/=(std::string) to append a reference token 10254 10255 @since version 3.6.0 10256 */ 10257 friend json_pointer operator/(const json_pointer& ptr, std::string token) 10258 { 10259 return json_pointer(ptr) /= std::move(token); 10260 } 10261 10262 /*! 10263 @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer 10264 10265 @param[in] ptr JSON pointer 10266 @param[in] array_index array index 10267 @return a new JSON pointer with @a array_index appended to @a ptr 10268 10269 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary} 10270 10271 @complexity Linear in the length of @a ptr. 10272 10273 @sa @ref operator/=(std::size_t) to append an array index 10274 10275 @since version 3.6.0 10276 */ 10277 friend json_pointer operator/(const json_pointer& ptr, std::size_t array_index) 10278 { 10279 return json_pointer(ptr) /= array_index; 10280 } 10281 10282 /*! 10283 @brief returns the parent of this JSON pointer 10284 10285 @return parent of this JSON pointer; in case this JSON pointer is the root, 10286 the root itself is returned 10287 10288 @complexity Linear in the length of the JSON pointer. 10289 10290 @liveexample{The example shows the result of `parent_pointer` for different 10291 JSON Pointers.,json_pointer__parent_pointer} 10292 10293 @since version 3.6.0 10294 */ 10295 json_pointer parent_pointer() const 10296 { 10297 if (empty()) 10298 { 10299 return *this; 10300 } 10301 10302 json_pointer res = *this; 10303 res.pop_back(); 10304 return res; 10305 } 10306 10307 /*! 10308 @brief remove last reference token 10309 10310 @pre not `empty()` 10311 10312 @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back} 10313 10314 @complexity Constant. 10315 10316 @throw out_of_range.405 if JSON pointer has no parent 10317 10318 @since version 3.6.0 10319 */ 10320 void pop_back() 10321 { 10322 if (JSON_HEDLEY_UNLIKELY(empty())) 10323 { 10324 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent")); 10325 } 10326 10327 reference_tokens.pop_back(); 10328 } 10329 10330 /*! 10331 @brief return last reference token 10332 10333 @pre not `empty()` 10334 @return last reference token 10335 10336 @liveexample{The example shows the usage of `back`.,json_pointer__back} 10337 10338 @complexity Constant. 10339 10340 @throw out_of_range.405 if JSON pointer has no parent 10341 10342 @since version 3.6.0 10343 */ 10344 const std::string& back() const 10345 { 10346 if (JSON_HEDLEY_UNLIKELY(empty())) 10347 { 10348 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent")); 10349 } 10350 10351 return reference_tokens.back(); 10352 } 10353 10354 /*! 10355 @brief append an unescaped token at the end of the reference pointer 10356 10357 @param[in] token token to add 10358 10359 @complexity Amortized constant. 10360 10361 @liveexample{The example shows the result of `push_back` for different 10362 JSON Pointers.,json_pointer__push_back} 10363 10364 @since version 3.6.0 10365 */ 10366 void push_back(const std::string& token) 10367 { 10368 reference_tokens.push_back(token); 10369 } 10370 10371 /// @copydoc push_back(const std::string&) 10372 void push_back(std::string&& token) 10373 { 10374 reference_tokens.push_back(std::move(token)); 10375 } 10376 10377 /*! 10378 @brief return whether pointer points to the root document 10379 10380 @return true iff the JSON pointer points to the root document 10381 10382 @complexity Constant. 10383 10384 @exceptionsafety No-throw guarantee: this function never throws exceptions. 10385 10386 @liveexample{The example shows the result of `empty` for different JSON 10387 Pointers.,json_pointer__empty} 10388 10389 @since version 3.6.0 10390 */ 10391 bool empty() const noexcept 10392 { 10393 return reference_tokens.empty(); 10394 } 10395 10396 private: 10397 /*! 10398 @param[in] s reference token to be converted into an array index 10399 10400 @return integer representation of @a s 10401 10402 @throw out_of_range.404 if string @a s could not be converted to an integer 10403 */ 10404 static int array_index(const std::string& s) 10405 { 10406 std::size_t processed_chars = 0; 10407 const int res = std::stoi(s, &processed_chars); 10408 10409 // check if the string was completely read 10410 if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size())) 10411 { 10412 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'")); 10413 } 10414 10415 return res; 10416 } 10417 10418 json_pointer top() const 10419 { 10420 if (JSON_HEDLEY_UNLIKELY(empty())) 10421 { 10422 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent")); 10423 } 10424 10425 json_pointer result = *this; 10426 result.reference_tokens = {reference_tokens[0]}; 10427 return result; 10428 } 10429 10430 /*! 10431 @brief create and return a reference to the pointed to value 10432 10433 @complexity Linear in the number of reference tokens. 10434 10435 @throw parse_error.109 if array index is not a number 10436 @throw type_error.313 if value cannot be unflattened 10437 */ 10438 BasicJsonType& get_and_create(BasicJsonType& j) const 10439 { 10440 using size_type = typename BasicJsonType::size_type; 10441 auto result = &j; 10442 10443 // in case no reference tokens exist, return a reference to the JSON value 10444 // j which will be overwritten by a primitive value 10445 for (const auto& reference_token : reference_tokens) 10446 { 10447 switch (result->type()) 10448 { 10449 case detail::value_t::null: 10450 { 10451 if (reference_token == "0") 10452 { 10453 // start a new array if reference token is 0 10454 result = &result->operator[](0); 10455 } 10456 else 10457 { 10458 // start a new object otherwise 10459 result = &result->operator[](reference_token); 10460 } 10461 break; 10462 } 10463 10464 case detail::value_t::object: 10465 { 10466 // create an entry in the object 10467 result = &result->operator[](reference_token); 10468 break; 10469 } 10470 10471 case detail::value_t::array: 10472 { 10473 // create an entry in the array 10474 JSON_TRY 10475 { 10476 result = &result->operator[](static_cast<size_type>(array_index(reference_token))); 10477 } 10478 JSON_CATCH(std::invalid_argument&) 10479 { 10480 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number")); 10481 } 10482 break; 10483 } 10484 10485 /* 10486 The following code is only reached if there exists a reference 10487 token _and_ the current value is primitive. In this case, we have 10488 an error situation, because primitive values may only occur as 10489 single value; that is, with an empty list of reference tokens. 10490 */ 10491 default: 10492 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten")); 10493 } 10494 } 10495 10496 return *result; 10497 } 10498 10499 /*! 10500 @brief return a reference to the pointed to value 10501 10502 @note This version does not throw if a value is not present, but tries to 10503 create nested values instead. For instance, calling this function 10504 with pointer `"/this/that"` on a null value is equivalent to calling 10505 `operator[]("this").operator[]("that")` on that value, effectively 10506 changing the null value to an object. 10507 10508 @param[in] ptr a JSON value 10509 10510 @return reference to the JSON value pointed to by the JSON pointer 10511 10512 @complexity Linear in the length of the JSON pointer. 10513 10514 @throw parse_error.106 if an array index begins with '0' 10515 @throw parse_error.109 if an array index was not a number 10516 @throw out_of_range.404 if the JSON pointer can not be resolved 10517 */ 10518 BasicJsonType& get_unchecked(BasicJsonType* ptr) const 10519 { 10520 using size_type = typename BasicJsonType::size_type; 10521 for (const auto& reference_token : reference_tokens) 10522 { 10523 // convert null values to arrays or objects before continuing 10524 if (ptr->is_null()) 10525 { 10526 // check if reference token is a number 10527 const bool nums = 10528 std::all_of(reference_token.begin(), reference_token.end(), 10529 [](const unsigned char x) 10530 { 10531 return std::isdigit(x); 10532 }); 10533 10534 // change value to array for numbers or "-" or to object otherwise 10535 *ptr = (nums or reference_token == "-") 10536 ? detail::value_t::array 10537 : detail::value_t::object; 10538 } 10539 10540 switch (ptr->type()) 10541 { 10542 case detail::value_t::object: 10543 { 10544 // use unchecked object access 10545 ptr = &ptr->operator[](reference_token); 10546 break; 10547 } 10548 10549 case detail::value_t::array: 10550 { 10551 // error condition (cf. RFC 6901, Sect. 4) 10552 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) 10553 { 10554 JSON_THROW(detail::parse_error::create(106, 0, 10555 "array index '" + reference_token + 10556 "' must not begin with '0'")); 10557 } 10558 10559 if (reference_token == "-") 10560 { 10561 // explicitly treat "-" as index beyond the end 10562 ptr = &ptr->operator[](ptr->m_value.array->size()); 10563 } 10564 else 10565 { 10566 // convert array index to number; unchecked access 10567 JSON_TRY 10568 { 10569 ptr = &ptr->operator[]( 10570 static_cast<size_type>(array_index(reference_token))); 10571 } 10572 JSON_CATCH(std::invalid_argument&) 10573 { 10574 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number")); 10575 } 10576 } 10577 break; 10578 } 10579 10580 default: 10581 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'")); 10582 } 10583 } 10584 10585 return *ptr; 10586 } 10587 10588 /*! 10589 @throw parse_error.106 if an array index begins with '0' 10590 @throw parse_error.109 if an array index was not a number 10591 @throw out_of_range.402 if the array index '-' is used 10592 @throw out_of_range.404 if the JSON pointer can not be resolved 10593 */ 10594 BasicJsonType& get_checked(BasicJsonType* ptr) const 10595 { 10596 using size_type = typename BasicJsonType::size_type; 10597 for (const auto& reference_token : reference_tokens) 10598 { 10599 switch (ptr->type()) 10600 { 10601 case detail::value_t::object: 10602 { 10603 // note: at performs range check 10604 ptr = &ptr->at(reference_token); 10605 break; 10606 } 10607 10608 case detail::value_t::array: 10609 { 10610 if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) 10611 { 10612 // "-" always fails the range check 10613 JSON_THROW(detail::out_of_range::create(402, 10614 "array index '-' (" + std::to_string(ptr->m_value.array->size()) + 10615 ") is out of range")); 10616 } 10617 10618 // error condition (cf. RFC 6901, Sect. 4) 10619 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) 10620 { 10621 JSON_THROW(detail::parse_error::create(106, 0, 10622 "array index '" + reference_token + 10623 "' must not begin with '0'")); 10624 } 10625 10626 // note: at performs range check 10627 JSON_TRY 10628 { 10629 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token))); 10630 } 10631 JSON_CATCH(std::invalid_argument&) 10632 { 10633 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number")); 10634 } 10635 break; 10636 } 10637 10638 default: 10639 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'")); 10640 } 10641 } 10642 10643 return *ptr; 10644 } 10645 10646 /*! 10647 @brief return a const reference to the pointed to value 10648 10649 @param[in] ptr a JSON value 10650 10651 @return const reference to the JSON value pointed to by the JSON 10652 pointer 10653 10654 @throw parse_error.106 if an array index begins with '0' 10655 @throw parse_error.109 if an array index was not a number 10656 @throw out_of_range.402 if the array index '-' is used 10657 @throw out_of_range.404 if the JSON pointer can not be resolved 10658 */ 10659 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const 10660 { 10661 using size_type = typename BasicJsonType::size_type; 10662 for (const auto& reference_token : reference_tokens) 10663 { 10664 switch (ptr->type()) 10665 { 10666 case detail::value_t::object: 10667 { 10668 // use unchecked object access 10669 ptr = &ptr->operator[](reference_token); 10670 break; 10671 } 10672 10673 case detail::value_t::array: 10674 { 10675 if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) 10676 { 10677 // "-" cannot be used for const access 10678 JSON_THROW(detail::out_of_range::create(402, 10679 "array index '-' (" + std::to_string(ptr->m_value.array->size()) + 10680 ") is out of range")); 10681 } 10682 10683 // error condition (cf. RFC 6901, Sect. 4) 10684 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) 10685 { 10686 JSON_THROW(detail::parse_error::create(106, 0, 10687 "array index '" + reference_token + 10688 "' must not begin with '0'")); 10689 } 10690 10691 // use unchecked array access 10692 JSON_TRY 10693 { 10694 ptr = &ptr->operator[]( 10695 static_cast<size_type>(array_index(reference_token))); 10696 } 10697 JSON_CATCH(std::invalid_argument&) 10698 { 10699 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number")); 10700 } 10701 break; 10702 } 10703 10704 default: 10705 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'")); 10706 } 10707 } 10708 10709 return *ptr; 10710 } 10711 10712 /*! 10713 @throw parse_error.106 if an array index begins with '0' 10714 @throw parse_error.109 if an array index was not a number 10715 @throw out_of_range.402 if the array index '-' is used 10716 @throw out_of_range.404 if the JSON pointer can not be resolved 10717 */ 10718 const BasicJsonType& get_checked(const BasicJsonType* ptr) const 10719 { 10720 using size_type = typename BasicJsonType::size_type; 10721 for (const auto& reference_token : reference_tokens) 10722 { 10723 switch (ptr->type()) 10724 { 10725 case detail::value_t::object: 10726 { 10727 // note: at performs range check 10728 ptr = &ptr->at(reference_token); 10729 break; 10730 } 10731 10732 case detail::value_t::array: 10733 { 10734 if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) 10735 { 10736 // "-" always fails the range check 10737 JSON_THROW(detail::out_of_range::create(402, 10738 "array index '-' (" + std::to_string(ptr->m_value.array->size()) + 10739 ") is out of range")); 10740 } 10741 10742 // error condition (cf. RFC 6901, Sect. 4) 10743 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) 10744 { 10745 JSON_THROW(detail::parse_error::create(106, 0, 10746 "array index '" + reference_token + 10747 "' must not begin with '0'")); 10748 } 10749 10750 // note: at performs range check 10751 JSON_TRY 10752 { 10753 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token))); 10754 } 10755 JSON_CATCH(std::invalid_argument&) 10756 { 10757 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number")); 10758 } 10759 break; 10760 } 10761 10762 default: 10763 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'")); 10764 } 10765 } 10766 10767 return *ptr; 10768 } 10769 10770 /*! 10771 @throw parse_error.106 if an array index begins with '0' 10772 @throw parse_error.109 if an array index was not a number 10773 */ 10774 bool contains(const BasicJsonType* ptr) const 10775 { 10776 using size_type = typename BasicJsonType::size_type; 10777 for (const auto& reference_token : reference_tokens) 10778 { 10779 switch (ptr->type()) 10780 { 10781 case detail::value_t::object: 10782 { 10783 if (not ptr->contains(reference_token)) 10784 { 10785 // we did not find the key in the object 10786 return false; 10787 } 10788 10789 ptr = &ptr->operator[](reference_token); 10790 break; 10791 } 10792 10793 case detail::value_t::array: 10794 { 10795 if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) 10796 { 10797 // "-" always fails the range check 10798 return false; 10799 } 10800 10801 // error condition (cf. RFC 6901, Sect. 4) 10802 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) 10803 { 10804 JSON_THROW(detail::parse_error::create(106, 0, 10805 "array index '" + reference_token + 10806 "' must not begin with '0'")); 10807 } 10808 10809 JSON_TRY 10810 { 10811 const auto idx = static_cast<size_type>(array_index(reference_token)); 10812 if (idx >= ptr->size()) 10813 { 10814 // index out of range 10815 return false; 10816 } 10817 10818 ptr = &ptr->operator[](idx); 10819 break; 10820 } 10821 JSON_CATCH(std::invalid_argument&) 10822 { 10823 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number")); 10824 } 10825 break; 10826 } 10827 10828 default: 10829 { 10830 // we do not expect primitive values if there is still a 10831 // reference token to process 10832 return false; 10833 } 10834 } 10835 } 10836 10837 // no reference token left means we found a primitive value 10838 return true; 10839 } 10840 10841 /*! 10842 @brief split the string input to reference tokens 10843 10844 @note This function is only called by the json_pointer constructor. 10845 All exceptions below are documented there. 10846 10847 @throw parse_error.107 if the pointer is not empty or begins with '/' 10848 @throw parse_error.108 if character '~' is not followed by '0' or '1' 10849 */ 10850 static std::vector<std::string> split(const std::string& reference_string) 10851 { 10852 std::vector<std::string> result; 10853 10854 // special case: empty reference string -> no reference tokens 10855 if (reference_string.empty()) 10856 { 10857 return result; 10858 } 10859 10860 // check if nonempty reference string begins with slash 10861 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/')) 10862 { 10863 JSON_THROW(detail::parse_error::create(107, 1, 10864 "JSON pointer must be empty or begin with '/' - was: '" + 10865 reference_string + "'")); 10866 } 10867 10868 // extract the reference tokens: 10869 // - slash: position of the last read slash (or end of string) 10870 // - start: position after the previous slash 10871 for ( 10872 // search for the first slash after the first character 10873 std::size_t slash = reference_string.find_first_of('/', 1), 10874 // set the beginning of the first reference token 10875 start = 1; 10876 // we can stop if start == 0 (if slash == std::string::npos) 10877 start != 0; 10878 // set the beginning of the next reference token 10879 // (will eventually be 0 if slash == std::string::npos) 10880 start = (slash == std::string::npos) ? 0 : slash + 1, 10881 // find next slash 10882 slash = reference_string.find_first_of('/', start)) 10883 { 10884 // use the text between the beginning of the reference token 10885 // (start) and the last slash (slash). 10886 auto reference_token = reference_string.substr(start, slash - start); 10887 10888 // check reference tokens are properly escaped 10889 for (std::size_t pos = reference_token.find_first_of('~'); 10890 pos != std::string::npos; 10891 pos = reference_token.find_first_of('~', pos + 1)) 10892 { 10893 assert(reference_token[pos] == '~'); 10894 10895 // ~ must be followed by 0 or 1 10896 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 or 10897 (reference_token[pos + 1] != '0' and 10898 reference_token[pos + 1] != '1'))) 10899 { 10900 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'")); 10901 } 10902 } 10903 10904 // finally, store the reference token 10905 unescape(reference_token); 10906 result.push_back(reference_token); 10907 } 10908 10909 return result; 10910 } 10911 10912 /*! 10913 @brief replace all occurrences of a substring by another string 10914 10915 @param[in,out] s the string to manipulate; changed so that all 10916 occurrences of @a f are replaced with @a t 10917 @param[in] f the substring to replace with @a t 10918 @param[in] t the string to replace @a f 10919 10920 @pre The search string @a f must not be empty. **This precondition is 10921 enforced with an assertion.** 10922 10923 @since version 2.0.0 10924 */ 10925 static void replace_substring(std::string& s, const std::string& f, 10926 const std::string& t) 10927 { 10928 assert(not f.empty()); 10929 for (auto pos = s.find(f); // find first occurrence of f 10930 pos != std::string::npos; // make sure f was found 10931 s.replace(pos, f.size(), t), // replace with t, and 10932 pos = s.find(f, pos + t.size())) // find next occurrence of f 10933 {} 10934 } 10935 10936 /// escape "~" to "~0" and "/" to "~1" 10937 static std::string escape(std::string s) 10938 { 10939 replace_substring(s, "~", "~0"); 10940 replace_substring(s, "/", "~1"); 10941 return s; 10942 } 10943 10944 /// unescape "~1" to tilde and "~0" to slash (order is important!) 10945 static void unescape(std::string& s) 10946 { 10947 replace_substring(s, "~1", "/"); 10948 replace_substring(s, "~0", "~"); 10949 } 10950 10951 /*! 10952 @param[in] reference_string the reference string to the current value 10953 @param[in] value the value to consider 10954 @param[in,out] result the result object to insert values to 10955 10956 @note Empty objects or arrays are flattened to `null`. 10957 */ 10958 static void flatten(const std::string& reference_string, 10959 const BasicJsonType& value, 10960 BasicJsonType& result) 10961 { 10962 switch (value.type()) 10963 { 10964 case detail::value_t::array: 10965 { 10966 if (value.m_value.array->empty()) 10967 { 10968 // flatten empty array as null 10969 result[reference_string] = nullptr; 10970 } 10971 else 10972 { 10973 // iterate array and use index as reference string 10974 for (std::size_t i = 0; i < value.m_value.array->size(); ++i) 10975 { 10976 flatten(reference_string + "/" + std::to_string(i), 10977 value.m_value.array->operator[](i), result); 10978 } 10979 } 10980 break; 10981 } 10982 10983 case detail::value_t::object: 10984 { 10985 if (value.m_value.object->empty()) 10986 { 10987 // flatten empty object as null 10988 result[reference_string] = nullptr; 10989 } 10990 else 10991 { 10992 // iterate object and use keys as reference string 10993 for (const auto& element : *value.m_value.object) 10994 { 10995 flatten(reference_string + "/" + escape(element.first), element.second, result); 10996 } 10997 } 10998 break; 10999 } 11000 11001 default: 11002 { 11003 // add primitive value with its reference string 11004 result[reference_string] = value; 11005 break; 11006 } 11007 } 11008 } 11009 11010 /*! 11011 @param[in] value flattened JSON 11012 11013 @return unflattened JSON 11014 11015 @throw parse_error.109 if array index is not a number 11016 @throw type_error.314 if value is not an object 11017 @throw type_error.315 if object values are not primitive 11018 @throw type_error.313 if value cannot be unflattened 11019 */ 11020 static BasicJsonType 11021 unflatten(const BasicJsonType& value) 11022 { 11023 if (JSON_HEDLEY_UNLIKELY(not value.is_object())) 11024 { 11025 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened")); 11026 } 11027 11028 BasicJsonType result; 11029 11030 // iterate the JSON object values 11031 for (const auto& element : *value.m_value.object) 11032 { 11033 if (JSON_HEDLEY_UNLIKELY(not element.second.is_primitive())) 11034 { 11035 JSON_THROW(detail::type_error::create(315, "values in object must be primitive")); 11036 } 11037 11038 // assign value to reference pointed to by JSON pointer; Note that if 11039 // the JSON pointer is "" (i.e., points to the whole value), function 11040 // get_and_create returns a reference to result itself. An assignment 11041 // will then create a primitive value. 11042 json_pointer(element.first).get_and_create(result) = element.second; 11043 } 11044 11045 return result; 11046 } 11047 11048 /*! 11049 @brief compares two JSON pointers for equality 11050 11051 @param[in] lhs JSON pointer to compare 11052 @param[in] rhs JSON pointer to compare 11053 @return whether @a lhs is equal to @a rhs 11054 11055 @complexity Linear in the length of the JSON pointer 11056 11057 @exceptionsafety No-throw guarantee: this function never throws exceptions. 11058 */ 11059 friend bool operator==(json_pointer const& lhs, 11060 json_pointer const& rhs) noexcept 11061 { 11062 return lhs.reference_tokens == rhs.reference_tokens; 11063 } 11064 11065 /*! 11066 @brief compares two JSON pointers for inequality 11067 11068 @param[in] lhs JSON pointer to compare 11069 @param[in] rhs JSON pointer to compare 11070 @return whether @a lhs is not equal @a rhs 11071 11072 @complexity Linear in the length of the JSON pointer 11073 11074 @exceptionsafety No-throw guarantee: this function never throws exceptions. 11075 */ 11076 friend bool operator!=(json_pointer const& lhs, 11077 json_pointer const& rhs) noexcept 11078 { 11079 return not (lhs == rhs); 11080 } 11081 11082 /// the reference tokens 11083 std::vector<std::string> reference_tokens; 11084}; 11085} // namespace nlohmann 11086 11087// #include <nlohmann/detail/json_ref.hpp> 11088 11089 11090#include <initializer_list> 11091#include <utility> 11092 11093// #include <nlohmann/detail/meta/type_traits.hpp> 11094 11095 11096namespace nlohmann 11097{ 11098namespace detail 11099{ 11100template<typename BasicJsonType> 11101class json_ref 11102{ 11103 public: 11104 using value_type = BasicJsonType; 11105 11106 json_ref(value_type&& value) 11107 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true) 11108 {} 11109 11110 json_ref(const value_type& value) 11111 : value_ref(const_cast<value_type*>(&value)), is_rvalue(false) 11112 {} 11113 11114 json_ref(std::initializer_list<json_ref> init) 11115 : owned_value(init), value_ref(&owned_value), is_rvalue(true) 11116 {} 11117 11118 template < 11119 class... Args, 11120 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 > 11121 json_ref(Args && ... args) 11122 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value), 11123 is_rvalue(true) {} 11124 11125 // class should be movable only 11126 json_ref(json_ref&&) = default; 11127 json_ref(const json_ref&) = delete; 11128 json_ref& operator=(const json_ref&) = delete; 11129 json_ref& operator=(json_ref&&) = delete; 11130 ~json_ref() = default; 11131 11132 value_type moved_or_copied() const 11133 { 11134 if (is_rvalue) 11135 { 11136 return std::move(*value_ref); 11137 } 11138 return *value_ref; 11139 } 11140 11141 value_type const& operator*() const 11142 { 11143 return *static_cast<value_type const*>(value_ref); 11144 } 11145 11146 value_type const* operator->() const 11147 { 11148 return static_cast<value_type const*>(value_ref); 11149 } 11150 11151 private: 11152 mutable value_type owned_value = nullptr; 11153 value_type* value_ref = nullptr; 11154 const bool is_rvalue; 11155}; 11156} // namespace detail 11157} // namespace nlohmann 11158 11159// #include <nlohmann/detail/macro_scope.hpp> 11160 11161// #include <nlohmann/detail/meta/cpp_future.hpp> 11162 11163// #include <nlohmann/detail/meta/type_traits.hpp> 11164 11165// #include <nlohmann/detail/output/binary_writer.hpp> 11166 11167 11168#include <algorithm> // reverse 11169#include <array> // array 11170#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t 11171#include <cstring> // memcpy 11172#include <limits> // numeric_limits 11173#include <string> // string 11174 11175// #include <nlohmann/detail/input/binary_reader.hpp> 11176 11177// #include <nlohmann/detail/macro_scope.hpp> 11178 11179// #include <nlohmann/detail/output/output_adapters.hpp> 11180 11181 11182#include <algorithm> // copy 11183#include <cstddef> // size_t 11184#include <ios> // streamsize 11185#include <iterator> // back_inserter 11186#include <memory> // shared_ptr, make_shared 11187#include <ostream> // basic_ostream 11188#include <string> // basic_string 11189#include <vector> // vector 11190// #include <nlohmann/detail/macro_scope.hpp> 11191 11192 11193namespace nlohmann 11194{ 11195namespace detail 11196{ 11197/// abstract output adapter interface 11198template<typename CharType> struct output_adapter_protocol 11199{ 11200 virtual void write_character(CharType c) = 0; 11201 virtual void write_characters(const CharType* s, std::size_t length) = 0; 11202 virtual ~output_adapter_protocol() = default; 11203}; 11204 11205/// a type to simplify interfaces 11206template<typename CharType> 11207using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>; 11208 11209/// output adapter for byte vectors 11210template<typename CharType> 11211class output_vector_adapter : public output_adapter_protocol<CharType> 11212{ 11213 public: 11214 explicit output_vector_adapter(std::vector<CharType>& vec) noexcept 11215 : v(vec) 11216 {} 11217 11218 void write_character(CharType c) override 11219 { 11220 v.push_back(c); 11221 } 11222 11223 JSON_HEDLEY_NON_NULL(2) 11224 void write_characters(const CharType* s, std::size_t length) override 11225 { 11226 std::copy(s, s + length, std::back_inserter(v)); 11227 } 11228 11229 private: 11230 std::vector<CharType>& v; 11231}; 11232 11233/// output adapter for output streams 11234template<typename CharType> 11235class output_stream_adapter : public output_adapter_protocol<CharType> 11236{ 11237 public: 11238 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept 11239 : stream(s) 11240 {} 11241 11242 void write_character(CharType c) override 11243 { 11244 stream.put(c); 11245 } 11246 11247 JSON_HEDLEY_NON_NULL(2) 11248 void write_characters(const CharType* s, std::size_t length) override 11249 { 11250 stream.write(s, static_cast<std::streamsize>(length)); 11251 } 11252 11253 private: 11254 std::basic_ostream<CharType>& stream; 11255}; 11256 11257/// output adapter for basic_string 11258template<typename CharType, typename StringType = std::basic_string<CharType>> 11259class output_string_adapter : public output_adapter_protocol<CharType> 11260{ 11261 public: 11262 explicit output_string_adapter(StringType& s) noexcept 11263 : str(s) 11264 {} 11265 11266 void write_character(CharType c) override 11267 { 11268 str.push_back(c); 11269 } 11270 11271 JSON_HEDLEY_NON_NULL(2) 11272 void write_characters(const CharType* s, std::size_t length) override 11273 { 11274 str.append(s, length); 11275 } 11276 11277 private: 11278 StringType& str; 11279}; 11280 11281template<typename CharType, typename StringType = std::basic_string<CharType>> 11282class output_adapter 11283{ 11284 public: 11285 output_adapter(std::vector<CharType>& vec) 11286 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {} 11287 11288 output_adapter(std::basic_ostream<CharType>& s) 11289 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {} 11290 11291 output_adapter(StringType& s) 11292 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {} 11293 11294 operator output_adapter_t<CharType>() 11295 { 11296 return oa; 11297 } 11298 11299 private: 11300 output_adapter_t<CharType> oa = nullptr; 11301}; 11302} // namespace detail 11303} // namespace nlohmann 11304 11305 11306namespace nlohmann 11307{ 11308namespace detail 11309{ 11310/////////////////// 11311// binary writer // 11312/////////////////// 11313 11314/*! 11315@brief serialization to CBOR and MessagePack values 11316*/ 11317template<typename BasicJsonType, typename CharType> 11318class binary_writer 11319{ 11320 using string_t = typename BasicJsonType::string_t; 11321 11322 public: 11323 /*! 11324 @brief create a binary writer 11325 11326 @param[in] adapter output adapter to write to 11327 */ 11328 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter) 11329 { 11330 assert(oa); 11331 } 11332 11333 /*! 11334 @param[in] j JSON value to serialize 11335 @pre j.type() == value_t::object 11336 */ 11337 void write_bson(const BasicJsonType& j) 11338 { 11339 switch (j.type()) 11340 { 11341 case value_t::object: 11342 { 11343 write_bson_object(*j.m_value.object); 11344 break; 11345 } 11346 11347 default: 11348 { 11349 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()))); 11350 } 11351 } 11352 } 11353 11354 /*! 11355 @param[in] j JSON value to serialize 11356 */ 11357 void write_cbor(const BasicJsonType& j) 11358 { 11359 switch (j.type()) 11360 { 11361 case value_t::null: 11362 { 11363 oa->write_character(to_char_type(0xF6)); 11364 break; 11365 } 11366 11367 case value_t::boolean: 11368 { 11369 oa->write_character(j.m_value.boolean 11370 ? to_char_type(0xF5) 11371 : to_char_type(0xF4)); 11372 break; 11373 } 11374 11375 case value_t::number_integer: 11376 { 11377 if (j.m_value.number_integer >= 0) 11378 { 11379 // CBOR does not differentiate between positive signed 11380 // integers and unsigned integers. Therefore, we used the 11381 // code from the value_t::number_unsigned case here. 11382 if (j.m_value.number_integer <= 0x17) 11383 { 11384 write_number(static_cast<std::uint8_t>(j.m_value.number_integer)); 11385 } 11386 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)()) 11387 { 11388 oa->write_character(to_char_type(0x18)); 11389 write_number(static_cast<std::uint8_t>(j.m_value.number_integer)); 11390 } 11391 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()) 11392 { 11393 oa->write_character(to_char_type(0x19)); 11394 write_number(static_cast<std::uint16_t>(j.m_value.number_integer)); 11395 } 11396 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()) 11397 { 11398 oa->write_character(to_char_type(0x1A)); 11399 write_number(static_cast<std::uint32_t>(j.m_value.number_integer)); 11400 } 11401 else 11402 { 11403 oa->write_character(to_char_type(0x1B)); 11404 write_number(static_cast<std::uint64_t>(j.m_value.number_integer)); 11405 } 11406 } 11407 else 11408 { 11409 // The conversions below encode the sign in the first 11410 // byte, and the value is converted to a positive number. 11411 const auto positive_number = -1 - j.m_value.number_integer; 11412 if (j.m_value.number_integer >= -24) 11413 { 11414 write_number(static_cast<std::uint8_t>(0x20 + positive_number)); 11415 } 11416 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)()) 11417 { 11418 oa->write_character(to_char_type(0x38)); 11419 write_number(static_cast<std::uint8_t>(positive_number)); 11420 } 11421 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)()) 11422 { 11423 oa->write_character(to_char_type(0x39)); 11424 write_number(static_cast<std::uint16_t>(positive_number)); 11425 } 11426 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)()) 11427 { 11428 oa->write_character(to_char_type(0x3A)); 11429 write_number(static_cast<std::uint32_t>(positive_number)); 11430 } 11431 else 11432 { 11433 oa->write_character(to_char_type(0x3B)); 11434 write_number(static_cast<std::uint64_t>(positive_number)); 11435 } 11436 } 11437 break; 11438 } 11439 11440 case value_t::number_unsigned: 11441 { 11442 if (j.m_value.number_unsigned <= 0x17) 11443 { 11444 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned)); 11445 } 11446 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)()) 11447 { 11448 oa->write_character(to_char_type(0x18)); 11449 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned)); 11450 } 11451 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)()) 11452 { 11453 oa->write_character(to_char_type(0x19)); 11454 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned)); 11455 } 11456 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)()) 11457 { 11458 oa->write_character(to_char_type(0x1A)); 11459 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned)); 11460 } 11461 else 11462 { 11463 oa->write_character(to_char_type(0x1B)); 11464 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned)); 11465 } 11466 break; 11467 } 11468 11469 case value_t::number_float: 11470 { 11471 oa->write_character(get_cbor_float_prefix(j.m_value.number_float)); 11472 write_number(j.m_value.number_float); 11473 break; 11474 } 11475 11476 case value_t::string: 11477 { 11478 // step 1: write control byte and the string length 11479 const auto N = j.m_value.string->size(); 11480 if (N <= 0x17) 11481 { 11482 write_number(static_cast<std::uint8_t>(0x60 + N)); 11483 } 11484 else if (N <= (std::numeric_limits<std::uint8_t>::max)()) 11485 { 11486 oa->write_character(to_char_type(0x78)); 11487 write_number(static_cast<std::uint8_t>(N)); 11488 } 11489 else if (N <= (std::numeric_limits<std::uint16_t>::max)()) 11490 { 11491 oa->write_character(to_char_type(0x79)); 11492 write_number(static_cast<std::uint16_t>(N)); 11493 } 11494 else if (N <= (std::numeric_limits<std::uint32_t>::max)()) 11495 { 11496 oa->write_character(to_char_type(0x7A)); 11497 write_number(static_cast<std::uint32_t>(N)); 11498 } 11499 // LCOV_EXCL_START 11500 else if (N <= (std::numeric_limits<std::uint64_t>::max)()) 11501 { 11502 oa->write_character(to_char_type(0x7B)); 11503 write_number(static_cast<std::uint64_t>(N)); 11504 } 11505 // LCOV_EXCL_STOP 11506 11507 // step 2: write the string 11508 oa->write_characters( 11509 reinterpret_cast<const CharType*>(j.m_value.string->c_str()), 11510 j.m_value.string->size()); 11511 break; 11512 } 11513 11514 case value_t::array: 11515 { 11516 // step 1: write control byte and the array size 11517 const auto N = j.m_value.array->size(); 11518 if (N <= 0x17) 11519 { 11520 write_number(static_cast<std::uint8_t>(0x80 + N)); 11521 } 11522 else if (N <= (std::numeric_limits<std::uint8_t>::max)()) 11523 { 11524 oa->write_character(to_char_type(0x98)); 11525 write_number(static_cast<std::uint8_t>(N)); 11526 } 11527 else if (N <= (std::numeric_limits<std::uint16_t>::max)()) 11528 { 11529 oa->write_character(to_char_type(0x99)); 11530 write_number(static_cast<std::uint16_t>(N)); 11531 } 11532 else if (N <= (std::numeric_limits<std::uint32_t>::max)()) 11533 { 11534 oa->write_character(to_char_type(0x9A)); 11535 write_number(static_cast<std::uint32_t>(N)); 11536 } 11537 // LCOV_EXCL_START 11538 else if (N <= (std::numeric_limits<std::uint64_t>::max)()) 11539 { 11540 oa->write_character(to_char_type(0x9B)); 11541 write_number(static_cast<std::uint64_t>(N)); 11542 } 11543 // LCOV_EXCL_STOP 11544 11545 // step 2: write each element 11546 for (const auto& el : *j.m_value.array) 11547 { 11548 write_cbor(el); 11549 } 11550 break; 11551 } 11552 11553 case value_t::object: 11554 { 11555 // step 1: write control byte and the object size 11556 const auto N = j.m_value.object->size(); 11557 if (N <= 0x17) 11558 { 11559 write_number(static_cast<std::uint8_t>(0xA0 + N)); 11560 } 11561 else if (N <= (std::numeric_limits<std::uint8_t>::max)()) 11562 { 11563 oa->write_character(to_char_type(0xB8)); 11564 write_number(static_cast<std::uint8_t>(N)); 11565 } 11566 else if (N <= (std::numeric_limits<std::uint16_t>::max)()) 11567 { 11568 oa->write_character(to_char_type(0xB9)); 11569 write_number(static_cast<std::uint16_t>(N)); 11570 } 11571 else if (N <= (std::numeric_limits<std::uint32_t>::max)()) 11572 { 11573 oa->write_character(to_char_type(0xBA)); 11574 write_number(static_cast<std::uint32_t>(N)); 11575 } 11576 // LCOV_EXCL_START 11577 else if (N <= (std::numeric_limits<std::uint64_t>::max)()) 11578 { 11579 oa->write_character(to_char_type(0xBB)); 11580 write_number(static_cast<std::uint64_t>(N)); 11581 } 11582 // LCOV_EXCL_STOP 11583 11584 // step 2: write each element 11585 for (const auto& el : *j.m_value.object) 11586 { 11587 write_cbor(el.first); 11588 write_cbor(el.second); 11589 } 11590 break; 11591 } 11592 11593 default: 11594 break; 11595 } 11596 } 11597 11598 /*! 11599 @param[in] j JSON value to serialize 11600 */ 11601 void write_msgpack(const BasicJsonType& j) 11602 { 11603 switch (j.type()) 11604 { 11605 case value_t::null: // nil 11606 { 11607 oa->write_character(to_char_type(0xC0)); 11608 break; 11609 } 11610 11611 case value_t::boolean: // true and false 11612 { 11613 oa->write_character(j.m_value.boolean 11614 ? to_char_type(0xC3) 11615 : to_char_type(0xC2)); 11616 break; 11617 } 11618 11619 case value_t::number_integer: 11620 { 11621 if (j.m_value.number_integer >= 0) 11622 { 11623 // MessagePack does not differentiate between positive 11624 // signed integers and unsigned integers. Therefore, we used 11625 // the code from the value_t::number_unsigned case here. 11626 if (j.m_value.number_unsigned < 128) 11627 { 11628 // positive fixnum 11629 write_number(static_cast<std::uint8_t>(j.m_value.number_integer)); 11630 } 11631 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)()) 11632 { 11633 // uint 8 11634 oa->write_character(to_char_type(0xCC)); 11635 write_number(static_cast<std::uint8_t>(j.m_value.number_integer)); 11636 } 11637 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)()) 11638 { 11639 // uint 16 11640 oa->write_character(to_char_type(0xCD)); 11641 write_number(static_cast<std::uint16_t>(j.m_value.number_integer)); 11642 } 11643 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)()) 11644 { 11645 // uint 32 11646 oa->write_character(to_char_type(0xCE)); 11647 write_number(static_cast<std::uint32_t>(j.m_value.number_integer)); 11648 } 11649 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)()) 11650 { 11651 // uint 64 11652 oa->write_character(to_char_type(0xCF)); 11653 write_number(static_cast<std::uint64_t>(j.m_value.number_integer)); 11654 } 11655 } 11656 else 11657 { 11658 if (j.m_value.number_integer >= -32) 11659 { 11660 // negative fixnum 11661 write_number(static_cast<std::int8_t>(j.m_value.number_integer)); 11662 } 11663 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() and 11664 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)()) 11665 { 11666 // int 8 11667 oa->write_character(to_char_type(0xD0)); 11668 write_number(static_cast<std::int8_t>(j.m_value.number_integer)); 11669 } 11670 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() and 11671 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)()) 11672 { 11673 // int 16 11674 oa->write_character(to_char_type(0xD1)); 11675 write_number(static_cast<std::int16_t>(j.m_value.number_integer)); 11676 } 11677 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() and 11678 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)()) 11679 { 11680 // int 32 11681 oa->write_character(to_char_type(0xD2)); 11682 write_number(static_cast<std::int32_t>(j.m_value.number_integer)); 11683 } 11684 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() and 11685 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)()) 11686 { 11687 // int 64 11688 oa->write_character(to_char_type(0xD3)); 11689 write_number(static_cast<std::int64_t>(j.m_value.number_integer)); 11690 } 11691 } 11692 break; 11693 } 11694 11695 case value_t::number_unsigned: 11696 { 11697 if (j.m_value.number_unsigned < 128) 11698 { 11699 // positive fixnum 11700 write_number(static_cast<std::uint8_t>(j.m_value.number_integer)); 11701 } 11702 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)()) 11703 { 11704 // uint 8 11705 oa->write_character(to_char_type(0xCC)); 11706 write_number(static_cast<std::uint8_t>(j.m_value.number_integer)); 11707 } 11708 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)()) 11709 { 11710 // uint 16 11711 oa->write_character(to_char_type(0xCD)); 11712 write_number(static_cast<std::uint16_t>(j.m_value.number_integer)); 11713 } 11714 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)()) 11715 { 11716 // uint 32 11717 oa->write_character(to_char_type(0xCE)); 11718 write_number(static_cast<std::uint32_t>(j.m_value.number_integer)); 11719 } 11720 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)()) 11721 { 11722 // uint 64 11723 oa->write_character(to_char_type(0xCF)); 11724 write_number(static_cast<std::uint64_t>(j.m_value.number_integer)); 11725 } 11726 break; 11727 } 11728 11729 case value_t::number_float: 11730 { 11731 oa->write_character(get_msgpack_float_prefix(j.m_value.number_float)); 11732 write_number(j.m_value.number_float); 11733 break; 11734 } 11735 11736 case value_t::string: 11737 { 11738 // step 1: write control byte and the string length 11739 const auto N = j.m_value.string->size(); 11740 if (N <= 31) 11741 { 11742 // fixstr 11743 write_number(static_cast<std::uint8_t>(0xA0 | N)); 11744 } 11745 else if (N <= (std::numeric_limits<std::uint8_t>::max)()) 11746 { 11747 // str 8 11748 oa->write_character(to_char_type(0xD9)); 11749 write_number(static_cast<std::uint8_t>(N)); 11750 } 11751 else if (N <= (std::numeric_limits<std::uint16_t>::max)()) 11752 { 11753 // str 16 11754 oa->write_character(to_char_type(0xDA)); 11755 write_number(static_cast<std::uint16_t>(N)); 11756 } 11757 else if (N <= (std::numeric_limits<std::uint32_t>::max)()) 11758 { 11759 // str 32 11760 oa->write_character(to_char_type(0xDB)); 11761 write_number(static_cast<std::uint32_t>(N)); 11762 } 11763 11764 // step 2: write the string 11765 oa->write_characters( 11766 reinterpret_cast<const CharType*>(j.m_value.string->c_str()), 11767 j.m_value.string->size()); 11768 break; 11769 } 11770 11771 case value_t::array: 11772 { 11773 // step 1: write control byte and the array size 11774 const auto N = j.m_value.array->size(); 11775 if (N <= 15) 11776 { 11777 // fixarray 11778 write_number(static_cast<std::uint8_t>(0x90 | N)); 11779 } 11780 else if (N <= (std::numeric_limits<std::uint16_t>::max)()) 11781 { 11782 // array 16 11783 oa->write_character(to_char_type(0xDC)); 11784 write_number(static_cast<std::uint16_t>(N)); 11785 } 11786 else if (N <= (std::numeric_limits<std::uint32_t>::max)()) 11787 { 11788 // array 32 11789 oa->write_character(to_char_type(0xDD)); 11790 write_number(static_cast<std::uint32_t>(N)); 11791 } 11792 11793 // step 2: write each element 11794 for (const auto& el : *j.m_value.array) 11795 { 11796 write_msgpack(el); 11797 } 11798 break; 11799 } 11800 11801 case value_t::object: 11802 { 11803 // step 1: write control byte and the object size 11804 const auto N = j.m_value.object->size(); 11805 if (N <= 15) 11806 { 11807 // fixmap 11808 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF))); 11809 } 11810 else if (N <= (std::numeric_limits<std::uint16_t>::max)()) 11811 { 11812 // map 16 11813 oa->write_character(to_char_type(0xDE)); 11814 write_number(static_cast<std::uint16_t>(N)); 11815 } 11816 else if (N <= (std::numeric_limits<std::uint32_t>::max)()) 11817 { 11818 // map 32 11819 oa->write_character(to_char_type(0xDF)); 11820 write_number(static_cast<std::uint32_t>(N)); 11821 } 11822 11823 // step 2: write each element 11824 for (const auto& el : *j.m_value.object) 11825 { 11826 write_msgpack(el.first); 11827 write_msgpack(el.second); 11828 } 11829 break; 11830 } 11831 11832 default: 11833 break; 11834 } 11835 } 11836 11837 /*! 11838 @param[in] j JSON value to serialize 11839 @param[in] use_count whether to use '#' prefixes (optimized format) 11840 @param[in] use_type whether to use '$' prefixes (optimized format) 11841 @param[in] add_prefix whether prefixes need to be used for this value 11842 */ 11843 void write_ubjson(const BasicJsonType& j, const bool use_count, 11844 const bool use_type, const bool add_prefix = true) 11845 { 11846 switch (j.type()) 11847 { 11848 case value_t::null: 11849 { 11850 if (add_prefix) 11851 { 11852 oa->write_character(to_char_type('Z')); 11853 } 11854 break; 11855 } 11856 11857 case value_t::boolean: 11858 { 11859 if (add_prefix) 11860 { 11861 oa->write_character(j.m_value.boolean 11862 ? to_char_type('T') 11863 : to_char_type('F')); 11864 } 11865 break; 11866 } 11867 11868 case value_t::number_integer: 11869 { 11870 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix); 11871 break; 11872 } 11873 11874 case value_t::number_unsigned: 11875 { 11876 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix); 11877 break; 11878 } 11879 11880 case value_t::number_float: 11881 { 11882 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix); 11883 break; 11884 } 11885 11886 case value_t::string: 11887 { 11888 if (add_prefix) 11889 { 11890 oa->write_character(to_char_type('S')); 11891 } 11892 write_number_with_ubjson_prefix(j.m_value.string->size(), true); 11893 oa->write_characters( 11894 reinterpret_cast<const CharType*>(j.m_value.string->c_str()), 11895 j.m_value.string->size()); 11896 break; 11897 } 11898 11899 case value_t::array: 11900 { 11901 if (add_prefix) 11902 { 11903 oa->write_character(to_char_type('[')); 11904 } 11905 11906 bool prefix_required = true; 11907 if (use_type and not j.m_value.array->empty()) 11908 { 11909 assert(use_count); 11910 const CharType first_prefix = ubjson_prefix(j.front()); 11911 const bool same_prefix = std::all_of(j.begin() + 1, j.end(), 11912 [this, first_prefix](const BasicJsonType & v) 11913 { 11914 return ubjson_prefix(v) == first_prefix; 11915 }); 11916 11917 if (same_prefix) 11918 { 11919 prefix_required = false; 11920 oa->write_character(to_char_type('$')); 11921 oa->write_character(first_prefix); 11922 } 11923 } 11924 11925 if (use_count) 11926 { 11927 oa->write_character(to_char_type('#')); 11928 write_number_with_ubjson_prefix(j.m_value.array->size(), true); 11929 } 11930 11931 for (const auto& el : *j.m_value.array) 11932 { 11933 write_ubjson(el, use_count, use_type, prefix_required); 11934 } 11935 11936 if (not use_count) 11937 { 11938 oa->write_character(to_char_type(']')); 11939 } 11940 11941 break; 11942 } 11943 11944 case value_t::object: 11945 { 11946 if (add_prefix) 11947 { 11948 oa->write_character(to_char_type('{')); 11949 } 11950 11951 bool prefix_required = true; 11952 if (use_type and not j.m_value.object->empty()) 11953 { 11954 assert(use_count); 11955 const CharType first_prefix = ubjson_prefix(j.front()); 11956 const bool same_prefix = std::all_of(j.begin(), j.end(), 11957 [this, first_prefix](const BasicJsonType & v) 11958 { 11959 return ubjson_prefix(v) == first_prefix; 11960 }); 11961 11962 if (same_prefix) 11963 { 11964 prefix_required = false; 11965 oa->write_character(to_char_type('$')); 11966 oa->write_character(first_prefix); 11967 } 11968 } 11969 11970 if (use_count) 11971 { 11972 oa->write_character(to_char_type('#')); 11973 write_number_with_ubjson_prefix(j.m_value.object->size(), true); 11974 } 11975 11976 for (const auto& el : *j.m_value.object) 11977 { 11978 write_number_with_ubjson_prefix(el.first.size(), true); 11979 oa->write_characters( 11980 reinterpret_cast<const CharType*>(el.first.c_str()), 11981 el.first.size()); 11982 write_ubjson(el.second, use_count, use_type, prefix_required); 11983 } 11984 11985 if (not use_count) 11986 { 11987 oa->write_character(to_char_type('}')); 11988 } 11989 11990 break; 11991 } 11992 11993 default: 11994 break; 11995 } 11996 } 11997 11998 private: 11999 ////////// 12000 // BSON // 12001 ////////// 12002 12003 /*! 12004 @return The size of a BSON document entry header, including the id marker 12005 and the entry name size (and its null-terminator). 12006 */ 12007 static std::size_t calc_bson_entry_header_size(const string_t& name) 12008 { 12009 const auto it = name.find(static_cast<typename string_t::value_type>(0)); 12010 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos)) 12011 { 12012 JSON_THROW(out_of_range::create(409, 12013 "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")")); 12014 } 12015 12016 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u; 12017 } 12018 12019 /*! 12020 @brief Writes the given @a element_type and @a name to the output adapter 12021 */ 12022 void write_bson_entry_header(const string_t& name, 12023 const std::uint8_t element_type) 12024 { 12025 oa->write_character(to_char_type(element_type)); // boolean 12026 oa->write_characters( 12027 reinterpret_cast<const CharType*>(name.c_str()), 12028 name.size() + 1u); 12029 } 12030 12031 /*! 12032 @brief Writes a BSON element with key @a name and boolean value @a value 12033 */ 12034 void write_bson_boolean(const string_t& name, 12035 const bool value) 12036 { 12037 write_bson_entry_header(name, 0x08); 12038 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00)); 12039 } 12040 12041 /*! 12042 @brief Writes a BSON element with key @a name and double value @a value 12043 */ 12044 void write_bson_double(const string_t& name, 12045 const double value) 12046 { 12047 write_bson_entry_header(name, 0x01); 12048 write_number<double, true>(value); 12049 } 12050 12051 /*! 12052 @return The size of the BSON-encoded string in @a value 12053 */ 12054 static std::size_t calc_bson_string_size(const string_t& value) 12055 { 12056 return sizeof(std::int32_t) + value.size() + 1ul; 12057 } 12058 12059 /*! 12060 @brief Writes a BSON element with key @a name and string value @a value 12061 */ 12062 void write_bson_string(const string_t& name, 12063 const string_t& value) 12064 { 12065 write_bson_entry_header(name, 0x02); 12066 12067 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul)); 12068 oa->write_characters( 12069 reinterpret_cast<const CharType*>(value.c_str()), 12070 value.size() + 1); 12071 } 12072 12073 /*! 12074 @brief Writes a BSON element with key @a name and null value 12075 */ 12076 void write_bson_null(const string_t& name) 12077 { 12078 write_bson_entry_header(name, 0x0A); 12079 } 12080 12081 /*! 12082 @return The size of the BSON-encoded integer @a value 12083 */ 12084 static std::size_t calc_bson_integer_size(const std::int64_t value) 12085 { 12086 return (std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)() 12087 ? sizeof(std::int32_t) 12088 : sizeof(std::int64_t); 12089 } 12090 12091 /*! 12092 @brief Writes a BSON element with key @a name and integer @a value 12093 */ 12094 void write_bson_integer(const string_t& name, 12095 const std::int64_t value) 12096 { 12097 if ((std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)()) 12098 { 12099 write_bson_entry_header(name, 0x10); // int32 12100 write_number<std::int32_t, true>(static_cast<std::int32_t>(value)); 12101 } 12102 else 12103 { 12104 write_bson_entry_header(name, 0x12); // int64 12105 write_number<std::int64_t, true>(static_cast<std::int64_t>(value)); 12106 } 12107 } 12108 12109 /*! 12110 @return The size of the BSON-encoded unsigned integer in @a j 12111 */ 12112 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept 12113 { 12114 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)())) 12115 ? sizeof(std::int32_t) 12116 : sizeof(std::int64_t); 12117 } 12118 12119 /*! 12120 @brief Writes a BSON element with key @a name and unsigned @a value 12121 */ 12122 void write_bson_unsigned(const string_t& name, 12123 const std::uint64_t value) 12124 { 12125 if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)())) 12126 { 12127 write_bson_entry_header(name, 0x10 /* int32 */); 12128 write_number<std::int32_t, true>(static_cast<std::int32_t>(value)); 12129 } 12130 else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)())) 12131 { 12132 write_bson_entry_header(name, 0x12 /* int64 */); 12133 write_number<std::int64_t, true>(static_cast<std::int64_t>(value)); 12134 } 12135 else 12136 { 12137 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64")); 12138 } 12139 } 12140 12141 /*! 12142 @brief Writes a BSON element with key @a name and object @a value 12143 */ 12144 void write_bson_object_entry(const string_t& name, 12145 const typename BasicJsonType::object_t& value) 12146 { 12147 write_bson_entry_header(name, 0x03); // object 12148 write_bson_object(value); 12149 } 12150 12151 /*! 12152 @return The size of the BSON-encoded array @a value 12153 */ 12154 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value) 12155 { 12156 std::size_t array_index = 0ul; 12157 12158 const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), 0ul, [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el) 12159 { 12160 return result + calc_bson_element_size(std::to_string(array_index++), el); 12161 }); 12162 12163 return sizeof(std::int32_t) + embedded_document_size + 1ul; 12164 } 12165 12166 /*! 12167 @brief Writes a BSON element with key @a name and array @a value 12168 */ 12169 void write_bson_array(const string_t& name, 12170 const typename BasicJsonType::array_t& value) 12171 { 12172 write_bson_entry_header(name, 0x04); // array 12173 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value))); 12174 12175 std::size_t array_index = 0ul; 12176 12177 for (const auto& el : value) 12178 { 12179 write_bson_element(std::to_string(array_index++), el); 12180 } 12181 12182 oa->write_character(to_char_type(0x00)); 12183 } 12184 12185 /*! 12186 @brief Calculates the size necessary to serialize the JSON value @a j with its @a name 12187 @return The calculated size for the BSON document entry for @a j with the given @a name. 12188 */ 12189 static std::size_t calc_bson_element_size(const string_t& name, 12190 const BasicJsonType& j) 12191 { 12192 const auto header_size = calc_bson_entry_header_size(name); 12193 switch (j.type()) 12194 { 12195 case value_t::object: 12196 return header_size + calc_bson_object_size(*j.m_value.object); 12197 12198 case value_t::array: 12199 return header_size + calc_bson_array_size(*j.m_value.array); 12200 12201 case value_t::boolean: 12202 return header_size + 1ul; 12203 12204 case value_t::number_float: 12205 return header_size + 8ul; 12206 12207 case value_t::number_integer: 12208 return header_size + calc_bson_integer_size(j.m_value.number_integer); 12209 12210 case value_t::number_unsigned: 12211 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned); 12212 12213 case value_t::string: 12214 return header_size + calc_bson_string_size(*j.m_value.string); 12215 12216 case value_t::null: 12217 return header_size + 0ul; 12218 12219 // LCOV_EXCL_START 12220 default: 12221 assert(false); 12222 return 0ul; 12223 // LCOV_EXCL_STOP 12224 } 12225 } 12226 12227 /*! 12228 @brief Serializes the JSON value @a j to BSON and associates it with the 12229 key @a name. 12230 @param name The name to associate with the JSON entity @a j within the 12231 current BSON document 12232 @return The size of the BSON entry 12233 */ 12234 void write_bson_element(const string_t& name, 12235 const BasicJsonType& j) 12236 { 12237 switch (j.type()) 12238 { 12239 case value_t::object: 12240 return write_bson_object_entry(name, *j.m_value.object); 12241 12242 case value_t::array: 12243 return write_bson_array(name, *j.m_value.array); 12244 12245 case value_t::boolean: 12246 return write_bson_boolean(name, j.m_value.boolean); 12247 12248 case value_t::number_float: 12249 return write_bson_double(name, j.m_value.number_float); 12250 12251 case value_t::number_integer: 12252 return write_bson_integer(name, j.m_value.number_integer); 12253 12254 case value_t::number_unsigned: 12255 return write_bson_unsigned(name, j.m_value.number_unsigned); 12256 12257 case value_t::string: 12258 return write_bson_string(name, *j.m_value.string); 12259 12260 case value_t::null: 12261 return write_bson_null(name); 12262 12263 // LCOV_EXCL_START 12264 default: 12265 assert(false); 12266 return; 12267 // LCOV_EXCL_STOP 12268 } 12269 } 12270 12271 /*! 12272 @brief Calculates the size of the BSON serialization of the given 12273 JSON-object @a j. 12274 @param[in] j JSON value to serialize 12275 @pre j.type() == value_t::object 12276 */ 12277 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value) 12278 { 12279 std::size_t document_size = std::accumulate(value.begin(), value.end(), 0ul, 12280 [](size_t result, const typename BasicJsonType::object_t::value_type & el) 12281 { 12282 return result += calc_bson_element_size(el.first, el.second); 12283 }); 12284 12285 return sizeof(std::int32_t) + document_size + 1ul; 12286 } 12287 12288 /*! 12289 @param[in] j JSON value to serialize 12290 @pre j.type() == value_t::object 12291 */ 12292 void write_bson_object(const typename BasicJsonType::object_t& value) 12293 { 12294 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value))); 12295 12296 for (const auto& el : value) 12297 { 12298 write_bson_element(el.first, el.second); 12299 } 12300 12301 oa->write_character(to_char_type(0x00)); 12302 } 12303 12304 ////////// 12305 // CBOR // 12306 ////////// 12307 12308 static constexpr CharType get_cbor_float_prefix(float /*unused*/) 12309 { 12310 return to_char_type(0xFA); // Single-Precision Float 12311 } 12312 12313 static constexpr CharType get_cbor_float_prefix(double /*unused*/) 12314 { 12315 return to_char_type(0xFB); // Double-Precision Float 12316 } 12317 12318 ///////////// 12319 // MsgPack // 12320 ///////////// 12321 12322 static constexpr CharType get_msgpack_float_prefix(float /*unused*/) 12323 { 12324 return to_char_type(0xCA); // float 32 12325 } 12326 12327 static constexpr CharType get_msgpack_float_prefix(double /*unused*/) 12328 { 12329 return to_char_type(0xCB); // float 64 12330 } 12331 12332 //////////// 12333 // UBJSON // 12334 //////////// 12335 12336 // UBJSON: write number (floating point) 12337 template<typename NumberType, typename std::enable_if< 12338 std::is_floating_point<NumberType>::value, int>::type = 0> 12339 void write_number_with_ubjson_prefix(const NumberType n, 12340 const bool add_prefix) 12341 { 12342 if (add_prefix) 12343 { 12344 oa->write_character(get_ubjson_float_prefix(n)); 12345 } 12346 write_number(n); 12347 } 12348 12349 // UBJSON: write number (unsigned integer) 12350 template<typename NumberType, typename std::enable_if< 12351 std::is_unsigned<NumberType>::value, int>::type = 0> 12352 void write_number_with_ubjson_prefix(const NumberType n, 12353 const bool add_prefix) 12354 { 12355 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)())) 12356 { 12357 if (add_prefix) 12358 { 12359 oa->write_character(to_char_type('i')); // int8 12360 } 12361 write_number(static_cast<std::uint8_t>(n)); 12362 } 12363 else if (n <= (std::numeric_limits<std::uint8_t>::max)()) 12364 { 12365 if (add_prefix) 12366 { 12367 oa->write_character(to_char_type('U')); // uint8 12368 } 12369 write_number(static_cast<std::uint8_t>(n)); 12370 } 12371 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)())) 12372 { 12373 if (add_prefix) 12374 { 12375 oa->write_character(to_char_type('I')); // int16 12376 } 12377 write_number(static_cast<std::int16_t>(n)); 12378 } 12379 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)())) 12380 { 12381 if (add_prefix) 12382 { 12383 oa->write_character(to_char_type('l')); // int32 12384 } 12385 write_number(static_cast<std::int32_t>(n)); 12386 } 12387 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)())) 12388 { 12389 if (add_prefix) 12390 { 12391 oa->write_character(to_char_type('L')); // int64 12392 } 12393 write_number(static_cast<std::int64_t>(n)); 12394 } 12395 else 12396 { 12397 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64")); 12398 } 12399 } 12400 12401 // UBJSON: write number (signed integer) 12402 template<typename NumberType, typename std::enable_if< 12403 std::is_signed<NumberType>::value and 12404 not std::is_floating_point<NumberType>::value, int>::type = 0> 12405 void write_number_with_ubjson_prefix(const NumberType n, 12406 const bool add_prefix) 12407 { 12408 if ((std::numeric_limits<std::int8_t>::min)() <= n and n <= (std::numeric_limits<std::int8_t>::max)()) 12409 { 12410 if (add_prefix) 12411 { 12412 oa->write_character(to_char_type('i')); // int8 12413 } 12414 write_number(static_cast<std::int8_t>(n)); 12415 } 12416 else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n and n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)())) 12417 { 12418 if (add_prefix) 12419 { 12420 oa->write_character(to_char_type('U')); // uint8 12421 } 12422 write_number(static_cast<std::uint8_t>(n)); 12423 } 12424 else if ((std::numeric_limits<std::int16_t>::min)() <= n and n <= (std::numeric_limits<std::int16_t>::max)()) 12425 { 12426 if (add_prefix) 12427 { 12428 oa->write_character(to_char_type('I')); // int16 12429 } 12430 write_number(static_cast<std::int16_t>(n)); 12431 } 12432 else if ((std::numeric_limits<std::int32_t>::min)() <= n and n <= (std::numeric_limits<std::int32_t>::max)()) 12433 { 12434 if (add_prefix) 12435 { 12436 oa->write_character(to_char_type('l')); // int32 12437 } 12438 write_number(static_cast<std::int32_t>(n)); 12439 } 12440 else if ((std::numeric_limits<std::int64_t>::min)() <= n and n <= (std::numeric_limits<std::int64_t>::max)()) 12441 { 12442 if (add_prefix) 12443 { 12444 oa->write_character(to_char_type('L')); // int64 12445 } 12446 write_number(static_cast<std::int64_t>(n)); 12447 } 12448 // LCOV_EXCL_START 12449 else 12450 { 12451 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64")); 12452 } 12453 // LCOV_EXCL_STOP 12454 } 12455 12456 /*! 12457 @brief determine the type prefix of container values 12458 12459 @note This function does not need to be 100% accurate when it comes to 12460 integer limits. In case a number exceeds the limits of int64_t, 12461 this will be detected by a later call to function 12462 write_number_with_ubjson_prefix. Therefore, we return 'L' for any 12463 value that does not fit the previous limits. 12464 */ 12465 CharType ubjson_prefix(const BasicJsonType& j) const noexcept 12466 { 12467 switch (j.type()) 12468 { 12469 case value_t::null: 12470 return 'Z'; 12471 12472 case value_t::boolean: 12473 return j.m_value.boolean ? 'T' : 'F'; 12474 12475 case value_t::number_integer: 12476 { 12477 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)()) 12478 { 12479 return 'i'; 12480 } 12481 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)()) 12482 { 12483 return 'U'; 12484 } 12485 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)()) 12486 { 12487 return 'I'; 12488 } 12489 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)()) 12490 { 12491 return 'l'; 12492 } 12493 // no check and assume int64_t (see note above) 12494 return 'L'; 12495 } 12496 12497 case value_t::number_unsigned: 12498 { 12499 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)())) 12500 { 12501 return 'i'; 12502 } 12503 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)())) 12504 { 12505 return 'U'; 12506 } 12507 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)())) 12508 { 12509 return 'I'; 12510 } 12511 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)())) 12512 { 12513 return 'l'; 12514 } 12515 // no check and assume int64_t (see note above) 12516 return 'L'; 12517 } 12518 12519 case value_t::number_float: 12520 return get_ubjson_float_prefix(j.m_value.number_float); 12521 12522 case value_t::string: 12523 return 'S'; 12524 12525 case value_t::array: 12526 return '['; 12527 12528 case value_t::object: 12529 return '{'; 12530 12531 default: // discarded values 12532 return 'N'; 12533 } 12534 } 12535 12536 static constexpr CharType get_ubjson_float_prefix(float /*unused*/) 12537 { 12538 return 'd'; // float 32 12539 } 12540 12541 static constexpr CharType get_ubjson_float_prefix(double /*unused*/) 12542 { 12543 return 'D'; // float 64 12544 } 12545 12546 /////////////////////// 12547 // Utility functions // 12548 /////////////////////// 12549 12550 /* 12551 @brief write a number to output input 12552 @param[in] n number of type @a NumberType 12553 @tparam NumberType the type of the number 12554 @tparam OutputIsLittleEndian Set to true if output data is 12555 required to be little endian 12556 12557 @note This function needs to respect the system's endianess, because bytes 12558 in CBOR, MessagePack, and UBJSON are stored in network order (big 12559 endian) and therefore need reordering on little endian systems. 12560 */ 12561 template<typename NumberType, bool OutputIsLittleEndian = false> 12562 void write_number(const NumberType n) 12563 { 12564 // step 1: write number to array of length NumberType 12565 std::array<CharType, sizeof(NumberType)> vec; 12566 std::memcpy(vec.data(), &n, sizeof(NumberType)); 12567 12568 // step 2: write array to output (with possible reordering) 12569 if (is_little_endian != OutputIsLittleEndian) 12570 { 12571 // reverse byte order prior to conversion if necessary 12572 std::reverse(vec.begin(), vec.end()); 12573 } 12574 12575 oa->write_characters(vec.data(), sizeof(NumberType)); 12576 } 12577 12578 public: 12579 // The following to_char_type functions are implement the conversion 12580 // between uint8_t and CharType. In case CharType is not unsigned, 12581 // such a conversion is required to allow values greater than 128. 12582 // See <https://github.com/nlohmann/json/issues/1286> for a discussion. 12583 template < typename C = CharType, 12584 enable_if_t < std::is_signed<C>::value and std::is_signed<char>::value > * = nullptr > 12585 static constexpr CharType to_char_type(std::uint8_t x) noexcept 12586 { 12587 return *reinterpret_cast<char*>(&x); 12588 } 12589 12590 template < typename C = CharType, 12591 enable_if_t < std::is_signed<C>::value and std::is_unsigned<char>::value > * = nullptr > 12592 static CharType to_char_type(std::uint8_t x) noexcept 12593 { 12594 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t"); 12595 static_assert(std::is_pod<CharType>::value, "CharType must be POD"); 12596 CharType result; 12597 std::memcpy(&result, &x, sizeof(x)); 12598 return result; 12599 } 12600 12601 template<typename C = CharType, 12602 enable_if_t<std::is_unsigned<C>::value>* = nullptr> 12603 static constexpr CharType to_char_type(std::uint8_t x) noexcept 12604 { 12605 return x; 12606 } 12607 12608 template < typename InputCharType, typename C = CharType, 12609 enable_if_t < 12610 std::is_signed<C>::value and 12611 std::is_signed<char>::value and 12612 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value 12613 > * = nullptr > 12614 static constexpr CharType to_char_type(InputCharType x) noexcept 12615 { 12616 return x; 12617 } 12618 12619 private: 12620 /// whether we can assume little endianess 12621 const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess(); 12622 12623 /// the output 12624 output_adapter_t<CharType> oa = nullptr; 12625}; 12626} // namespace detail 12627} // namespace nlohmann 12628 12629// #include <nlohmann/detail/output/output_adapters.hpp> 12630 12631// #include <nlohmann/detail/output/serializer.hpp> 12632 12633 12634#include <algorithm> // reverse, remove, fill, find, none_of 12635#include <array> // array 12636#include <cassert> // assert 12637#include <ciso646> // and, or 12638#include <clocale> // localeconv, lconv 12639#include <cmath> // labs, isfinite, isnan, signbit 12640#include <cstddef> // size_t, ptrdiff_t 12641#include <cstdint> // uint8_t 12642#include <cstdio> // snprintf 12643#include <limits> // numeric_limits 12644#include <string> // string 12645#include <type_traits> // is_same 12646#include <utility> // move 12647 12648// #include <nlohmann/detail/conversions/to_chars.hpp> 12649 12650 12651#include <array> // array 12652#include <cassert> // assert 12653#include <ciso646> // or, and, not 12654#include <cmath> // signbit, isfinite 12655#include <cstdint> // intN_t, uintN_t 12656#include <cstring> // memcpy, memmove 12657#include <limits> // numeric_limits 12658#include <type_traits> // conditional 12659// #include <nlohmann/detail/macro_scope.hpp> 12660 12661 12662namespace nlohmann 12663{ 12664namespace detail 12665{ 12666 12667/*! 12668@brief implements the Grisu2 algorithm for binary to decimal floating-point 12669conversion. 12670 12671This implementation is a slightly modified version of the reference 12672implementation which may be obtained from 12673http://florian.loitsch.com/publications (bench.tar.gz). 12674 12675The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch. 12676 12677For a detailed description of the algorithm see: 12678 12679[1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with 12680 Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming 12681 Language Design and Implementation, PLDI 2010 12682[2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately", 12683 Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language 12684 Design and Implementation, PLDI 1996 12685*/ 12686namespace dtoa_impl 12687{ 12688 12689template <typename Target, typename Source> 12690Target reinterpret_bits(const Source source) 12691{ 12692 static_assert(sizeof(Target) == sizeof(Source), "size mismatch"); 12693 12694 Target target; 12695 std::memcpy(&target, &source, sizeof(Source)); 12696 return target; 12697} 12698 12699struct diyfp // f * 2^e 12700{ 12701 static constexpr int kPrecision = 64; // = q 12702 12703 std::uint64_t f = 0; 12704 int e = 0; 12705 12706 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {} 12707 12708 /*! 12709 @brief returns x - y 12710 @pre x.e == y.e and x.f >= y.f 12711 */ 12712 static diyfp sub(const diyfp& x, const diyfp& y) noexcept 12713 { 12714 assert(x.e == y.e); 12715 assert(x.f >= y.f); 12716 12717 return {x.f - y.f, x.e}; 12718 } 12719 12720 /*! 12721 @brief returns x * y 12722 @note The result is rounded. (Only the upper q bits are returned.) 12723 */ 12724 static diyfp mul(const diyfp& x, const diyfp& y) noexcept 12725 { 12726 static_assert(kPrecision == 64, "internal error"); 12727 12728 // Computes: 12729 // f = round((x.f * y.f) / 2^q) 12730 // e = x.e + y.e + q 12731 12732 // Emulate the 64-bit * 64-bit multiplication: 12733 // 12734 // p = u * v 12735 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi) 12736 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi ) 12737 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 ) 12738 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 ) 12739 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3) 12740 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H ) 12741 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H ) 12742 // 12743 // (Since Q might be larger than 2^32 - 1) 12744 // 12745 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H) 12746 // 12747 // (Q_hi + H does not overflow a 64-bit int) 12748 // 12749 // = p_lo + 2^64 p_hi 12750 12751 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu; 12752 const std::uint64_t u_hi = x.f >> 32u; 12753 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu; 12754 const std::uint64_t v_hi = y.f >> 32u; 12755 12756 const std::uint64_t p0 = u_lo * v_lo; 12757 const std::uint64_t p1 = u_lo * v_hi; 12758 const std::uint64_t p2 = u_hi * v_lo; 12759 const std::uint64_t p3 = u_hi * v_hi; 12760 12761 const std::uint64_t p0_hi = p0 >> 32u; 12762 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu; 12763 const std::uint64_t p1_hi = p1 >> 32u; 12764 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu; 12765 const std::uint64_t p2_hi = p2 >> 32u; 12766 12767 std::uint64_t Q = p0_hi + p1_lo + p2_lo; 12768 12769 // The full product might now be computed as 12770 // 12771 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32) 12772 // p_lo = p0_lo + (Q << 32) 12773 // 12774 // But in this particular case here, the full p_lo is not required. 12775 // Effectively we only need to add the highest bit in p_lo to p_hi (and 12776 // Q_hi + 1 does not overflow). 12777 12778 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up 12779 12780 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u); 12781 12782 return {h, x.e + y.e + 64}; 12783 } 12784 12785 /*! 12786 @brief normalize x such that the significand is >= 2^(q-1) 12787 @pre x.f != 0 12788 */ 12789 static diyfp normalize(diyfp x) noexcept 12790 { 12791 assert(x.f != 0); 12792 12793 while ((x.f >> 63u) == 0) 12794 { 12795 x.f <<= 1u; 12796 x.e--; 12797 } 12798 12799 return x; 12800 } 12801 12802 /*! 12803 @brief normalize x such that the result has the exponent E 12804 @pre e >= x.e and the upper e - x.e bits of x.f must be zero. 12805 */ 12806 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept 12807 { 12808 const int delta = x.e - target_exponent; 12809 12810 assert(delta >= 0); 12811 assert(((x.f << delta) >> delta) == x.f); 12812 12813 return {x.f << delta, target_exponent}; 12814 } 12815}; 12816 12817struct boundaries 12818{ 12819 diyfp w; 12820 diyfp minus; 12821 diyfp plus; 12822}; 12823 12824/*! 12825Compute the (normalized) diyfp representing the input number 'value' and its 12826boundaries. 12827 12828@pre value must be finite and positive 12829*/ 12830template <typename FloatType> 12831boundaries compute_boundaries(FloatType value) 12832{ 12833 assert(std::isfinite(value)); 12834 assert(value > 0); 12835 12836 // Convert the IEEE representation into a diyfp. 12837 // 12838 // If v is denormal: 12839 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1)) 12840 // If v is normalized: 12841 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1)) 12842 12843 static_assert(std::numeric_limits<FloatType>::is_iec559, 12844 "internal error: dtoa_short requires an IEEE-754 floating-point implementation"); 12845 12846 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit) 12847 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1); 12848 constexpr int kMinExp = 1 - kBias; 12849 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1) 12850 12851 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type; 12852 12853 const std::uint64_t bits = reinterpret_bits<bits_type>(value); 12854 const std::uint64_t E = bits >> (kPrecision - 1); 12855 const std::uint64_t F = bits & (kHiddenBit - 1); 12856 12857 const bool is_denormal = E == 0; 12858 const diyfp v = is_denormal 12859 ? diyfp(F, kMinExp) 12860 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias); 12861 12862 // Compute the boundaries m- and m+ of the floating-point value 12863 // v = f * 2^e. 12864 // 12865 // Determine v- and v+, the floating-point predecessor and successor if v, 12866 // respectively. 12867 // 12868 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A) 12869 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B) 12870 // 12871 // v+ = v + 2^e 12872 // 12873 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_ 12874 // between m- and m+ round to v, regardless of how the input rounding 12875 // algorithm breaks ties. 12876 // 12877 // ---+-------------+-------------+-------------+-------------+--- (A) 12878 // v- m- v m+ v+ 12879 // 12880 // -----------------+------+------+-------------+-------------+--- (B) 12881 // v- m- v m+ v+ 12882 12883 const bool lower_boundary_is_closer = F == 0 and E > 1; 12884 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1); 12885 const diyfp m_minus = lower_boundary_is_closer 12886 ? diyfp(4 * v.f - 1, v.e - 2) // (B) 12887 : diyfp(2 * v.f - 1, v.e - 1); // (A) 12888 12889 // Determine the normalized w+ = m+. 12890 const diyfp w_plus = diyfp::normalize(m_plus); 12891 12892 // Determine w- = m- such that e_(w-) = e_(w+). 12893 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e); 12894 12895 return {diyfp::normalize(v), w_minus, w_plus}; 12896} 12897 12898// Given normalized diyfp w, Grisu needs to find a (normalized) cached 12899// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies 12900// within a certain range [alpha, gamma] (Definition 3.2 from [1]) 12901// 12902// alpha <= e = e_c + e_w + q <= gamma 12903// 12904// or 12905// 12906// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q 12907// <= f_c * f_w * 2^gamma 12908// 12909// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies 12910// 12911// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma 12912// 12913// or 12914// 12915// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma) 12916// 12917// The choice of (alpha,gamma) determines the size of the table and the form of 12918// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well 12919// in practice: 12920// 12921// The idea is to cut the number c * w = f * 2^e into two parts, which can be 12922// processed independently: An integral part p1, and a fractional part p2: 12923// 12924// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e 12925// = (f div 2^-e) + (f mod 2^-e) * 2^e 12926// = p1 + p2 * 2^e 12927// 12928// The conversion of p1 into decimal form requires a series of divisions and 12929// modulos by (a power of) 10. These operations are faster for 32-bit than for 12930// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be 12931// achieved by choosing 12932// 12933// -e >= 32 or e <= -32 := gamma 12934// 12935// In order to convert the fractional part 12936// 12937// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ... 12938// 12939// into decimal form, the fraction is repeatedly multiplied by 10 and the digits 12940// d[-i] are extracted in order: 12941// 12942// (10 * p2) div 2^-e = d[-1] 12943// (10 * p2) mod 2^-e = d[-2] / 10^1 + ... 12944// 12945// The multiplication by 10 must not overflow. It is sufficient to choose 12946// 12947// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64. 12948// 12949// Since p2 = f mod 2^-e < 2^-e, 12950// 12951// -e <= 60 or e >= -60 := alpha 12952 12953constexpr int kAlpha = -60; 12954constexpr int kGamma = -32; 12955 12956struct cached_power // c = f * 2^e ~= 10^k 12957{ 12958 std::uint64_t f; 12959 int e; 12960 int k; 12961}; 12962 12963/*! 12964For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached 12965power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c 12966satisfies (Definition 3.2 from [1]) 12967 12968 alpha <= e_c + e + q <= gamma. 12969*/ 12970inline cached_power get_cached_power_for_binary_exponent(int e) 12971{ 12972 // Now 12973 // 12974 // alpha <= e_c + e + q <= gamma (1) 12975 // ==> f_c * 2^alpha <= c * 2^e * 2^q 12976 // 12977 // and since the c's are normalized, 2^(q-1) <= f_c, 12978 // 12979 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q) 12980 // ==> 2^(alpha - e - 1) <= c 12981 // 12982 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as 12983 // 12984 // k = ceil( log_10( 2^(alpha - e - 1) ) ) 12985 // = ceil( (alpha - e - 1) * log_10(2) ) 12986 // 12987 // From the paper: 12988 // "In theory the result of the procedure could be wrong since c is rounded, 12989 // and the computation itself is approximated [...]. In practice, however, 12990 // this simple function is sufficient." 12991 // 12992 // For IEEE double precision floating-point numbers converted into 12993 // normalized diyfp's w = f * 2^e, with q = 64, 12994 // 12995 // e >= -1022 (min IEEE exponent) 12996 // -52 (p - 1) 12997 // -52 (p - 1, possibly normalize denormal IEEE numbers) 12998 // -11 (normalize the diyfp) 12999 // = -1137 13000 // 13001 // and 13002 // 13003 // e <= +1023 (max IEEE exponent) 13004 // -52 (p - 1) 13005 // -11 (normalize the diyfp) 13006 // = 960 13007 // 13008 // This binary exponent range [-1137,960] results in a decimal exponent 13009 // range [-307,324]. One does not need to store a cached power for each 13010 // k in this range. For each such k it suffices to find a cached power 13011 // such that the exponent of the product lies in [alpha,gamma]. 13012 // This implies that the difference of the decimal exponents of adjacent 13013 // table entries must be less than or equal to 13014 // 13015 // floor( (gamma - alpha) * log_10(2) ) = 8. 13016 // 13017 // (A smaller distance gamma-alpha would require a larger table.) 13018 13019 // NB: 13020 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34. 13021 13022 constexpr int kCachedPowersMinDecExp = -300; 13023 constexpr int kCachedPowersDecStep = 8; 13024 13025 static constexpr std::array<cached_power, 79> kCachedPowers = 13026 { 13027 { 13028 { 0xAB70FE17C79AC6CA, -1060, -300 }, 13029 { 0xFF77B1FCBEBCDC4F, -1034, -292 }, 13030 { 0xBE5691EF416BD60C, -1007, -284 }, 13031 { 0x8DD01FAD907FFC3C, -980, -276 }, 13032 { 0xD3515C2831559A83, -954, -268 }, 13033 { 0x9D71AC8FADA6C9B5, -927, -260 }, 13034 { 0xEA9C227723EE8BCB, -901, -252 }, 13035 { 0xAECC49914078536D, -874, -244 }, 13036 { 0x823C12795DB6CE57, -847, -236 }, 13037 { 0xC21094364DFB5637, -821, -228 }, 13038 { 0x9096EA6F3848984F, -794, -220 }, 13039 { 0xD77485CB25823AC7, -768, -212 }, 13040 { 0xA086CFCD97BF97F4, -741, -204 }, 13041 { 0xEF340A98172AACE5, -715, -196 }, 13042 { 0xB23867FB2A35B28E, -688, -188 }, 13043 { 0x84C8D4DFD2C63F3B, -661, -180 }, 13044 { 0xC5DD44271AD3CDBA, -635, -172 }, 13045 { 0x936B9FCEBB25C996, -608, -164 }, 13046 { 0xDBAC6C247D62A584, -582, -156 }, 13047 { 0xA3AB66580D5FDAF6, -555, -148 }, 13048 { 0xF3E2F893DEC3F126, -529, -140 }, 13049 { 0xB5B5ADA8AAFF80B8, -502, -132 }, 13050 { 0x87625F056C7C4A8B, -475, -124 }, 13051 { 0xC9BCFF6034C13053, -449, -116 }, 13052 { 0x964E858C91BA2655, -422, -108 }, 13053 { 0xDFF9772470297EBD, -396, -100 }, 13054 { 0xA6DFBD9FB8E5B88F, -369, -92 }, 13055 { 0xF8A95FCF88747D94, -343, -84 }, 13056 { 0xB94470938FA89BCF, -316, -76 }, 13057 { 0x8A08F0F8BF0F156B, -289, -68 }, 13058 { 0xCDB02555653131B6, -263, -60 }, 13059 { 0x993FE2C6D07B7FAC, -236, -52 }, 13060 { 0xE45C10C42A2B3B06, -210, -44 }, 13061 { 0xAA242499697392D3, -183, -36 }, 13062 { 0xFD87B5F28300CA0E, -157, -28 }, 13063 { 0xBCE5086492111AEB, -130, -20 }, 13064 { 0x8CBCCC096F5088CC, -103, -12 }, 13065 { 0xD1B71758E219652C, -77, -4 }, 13066 { 0x9C40000000000000, -50, 4 }, 13067 { 0xE8D4A51000000000, -24, 12 }, 13068 { 0xAD78EBC5AC620000, 3, 20 }, 13069 { 0x813F3978F8940984, 30, 28 }, 13070 { 0xC097CE7BC90715B3, 56, 36 }, 13071 { 0x8F7E32CE7BEA5C70, 83, 44 }, 13072 { 0xD5D238A4ABE98068, 109, 52 }, 13073 { 0x9F4F2726179A2245, 136, 60 }, 13074 { 0xED63A231D4C4FB27, 162, 68 }, 13075 { 0xB0DE65388CC8ADA8, 189, 76 }, 13076 { 0x83C7088E1AAB65DB, 216, 84 }, 13077 { 0xC45D1DF942711D9A, 242, 92 }, 13078 { 0x924D692CA61BE758, 269, 100 }, 13079 { 0xDA01EE641A708DEA, 295, 108 }, 13080 { 0xA26DA3999AEF774A, 322, 116 }, 13081 { 0xF209787BB47D6B85, 348, 124 }, 13082 { 0xB454E4A179DD1877, 375, 132 }, 13083 { 0x865B86925B9BC5C2, 402, 140 }, 13084 { 0xC83553C5C8965D3D, 428, 148 }, 13085 { 0x952AB45CFA97A0B3, 455, 156 }, 13086 { 0xDE469FBD99A05FE3, 481, 164 }, 13087 { 0xA59BC234DB398C25, 508, 172 }, 13088 { 0xF6C69A72A3989F5C, 534, 180 }, 13089 { 0xB7DCBF5354E9BECE, 561, 188 }, 13090 { 0x88FCF317F22241E2, 588, 196 }, 13091 { 0xCC20CE9BD35C78A5, 614, 204 }, 13092 { 0x98165AF37B2153DF, 641, 212 }, 13093 { 0xE2A0B5DC971F303A, 667, 220 }, 13094 { 0xA8D9D1535CE3B396, 694, 228 }, 13095 { 0xFB9B7CD9A4A7443C, 720, 236 }, 13096 { 0xBB764C4CA7A44410, 747, 244 }, 13097 { 0x8BAB8EEFB6409C1A, 774, 252 }, 13098 { 0xD01FEF10A657842C, 800, 260 }, 13099 { 0x9B10A4E5E9913129, 827, 268 }, 13100 { 0xE7109BFBA19C0C9D, 853, 276 }, 13101 { 0xAC2820D9623BF429, 880, 284 }, 13102 { 0x80444B5E7AA7CF85, 907, 292 }, 13103 { 0xBF21E44003ACDD2D, 933, 300 }, 13104 { 0x8E679C2F5E44FF8F, 960, 308 }, 13105 { 0xD433179D9C8CB841, 986, 316 }, 13106 { 0x9E19DB92B4E31BA9, 1013, 324 }, 13107 } 13108 }; 13109 13110 // This computation gives exactly the same results for k as 13111 // k = ceil((kAlpha - e - 1) * 0.30102999566398114) 13112 // for |e| <= 1500, but doesn't require floating-point operations. 13113 // NB: log_10(2) ~= 78913 / 2^18 13114 assert(e >= -1500); 13115 assert(e <= 1500); 13116 const int f = kAlpha - e - 1; 13117 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0); 13118 13119 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep; 13120 assert(index >= 0); 13121 assert(static_cast<std::size_t>(index) < kCachedPowers.size()); 13122 13123 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)]; 13124 assert(kAlpha <= cached.e + e + 64); 13125 assert(kGamma >= cached.e + e + 64); 13126 13127 return cached; 13128} 13129 13130/*! 13131For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k. 13132For n == 0, returns 1 and sets pow10 := 1. 13133*/ 13134inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10) 13135{ 13136 // LCOV_EXCL_START 13137 if (n >= 1000000000) 13138 { 13139 pow10 = 1000000000; 13140 return 10; 13141 } 13142 // LCOV_EXCL_STOP 13143 else if (n >= 100000000) 13144 { 13145 pow10 = 100000000; 13146 return 9; 13147 } 13148 else if (n >= 10000000) 13149 { 13150 pow10 = 10000000; 13151 return 8; 13152 } 13153 else if (n >= 1000000) 13154 { 13155 pow10 = 1000000; 13156 return 7; 13157 } 13158 else if (n >= 100000) 13159 { 13160 pow10 = 100000; 13161 return 6; 13162 } 13163 else if (n >= 10000) 13164 { 13165 pow10 = 10000; 13166 return 5; 13167 } 13168 else if (n >= 1000) 13169 { 13170 pow10 = 1000; 13171 return 4; 13172 } 13173 else if (n >= 100) 13174 { 13175 pow10 = 100; 13176 return 3; 13177 } 13178 else if (n >= 10) 13179 { 13180 pow10 = 10; 13181 return 2; 13182 } 13183 else 13184 { 13185 pow10 = 1; 13186 return 1; 13187 } 13188} 13189 13190inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta, 13191 std::uint64_t rest, std::uint64_t ten_k) 13192{ 13193 assert(len >= 1); 13194 assert(dist <= delta); 13195 assert(rest <= delta); 13196 assert(ten_k > 0); 13197 13198 // <--------------------------- delta ----> 13199 // <---- dist ---------> 13200 // --------------[------------------+-------------------]-------------- 13201 // M- w M+ 13202 // 13203 // ten_k 13204 // <------> 13205 // <---- rest ----> 13206 // --------------[------------------+----+--------------]-------------- 13207 // w V 13208 // = buf * 10^k 13209 // 13210 // ten_k represents a unit-in-the-last-place in the decimal representation 13211 // stored in buf. 13212 // Decrement buf by ten_k while this takes buf closer to w. 13213 13214 // The tests are written in this order to avoid overflow in unsigned 13215 // integer arithmetic. 13216 13217 while (rest < dist 13218 and delta - rest >= ten_k 13219 and (rest + ten_k < dist or dist - rest > rest + ten_k - dist)) 13220 { 13221 assert(buf[len - 1] != '0'); 13222 buf[len - 1]--; 13223 rest += ten_k; 13224 } 13225} 13226 13227/*! 13228Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+. 13229M- and M+ must be normalized and share the same exponent -60 <= e <= -32. 13230*/ 13231inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent, 13232 diyfp M_minus, diyfp w, diyfp M_plus) 13233{ 13234 static_assert(kAlpha >= -60, "internal error"); 13235 static_assert(kGamma <= -32, "internal error"); 13236 13237 // Generates the digits (and the exponent) of a decimal floating-point 13238 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's 13239 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma. 13240 // 13241 // <--------------------------- delta ----> 13242 // <---- dist ---------> 13243 // --------------[------------------+-------------------]-------------- 13244 // M- w M+ 13245 // 13246 // Grisu2 generates the digits of M+ from left to right and stops as soon as 13247 // V is in [M-,M+]. 13248 13249 assert(M_plus.e >= kAlpha); 13250 assert(M_plus.e <= kGamma); 13251 13252 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e) 13253 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e) 13254 13255 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0): 13256 // 13257 // M+ = f * 2^e 13258 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e 13259 // = ((p1 ) * 2^-e + (p2 )) * 2^e 13260 // = p1 + p2 * 2^e 13261 13262 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e); 13263 13264 auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.) 13265 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e 13266 13267 // 1) 13268 // 13269 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0] 13270 13271 assert(p1 > 0); 13272 13273 std::uint32_t pow10; 13274 const int k = find_largest_pow10(p1, pow10); 13275 13276 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1) 13277 // 13278 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1)) 13279 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1)) 13280 // 13281 // M+ = p1 + p2 * 2^e 13282 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e 13283 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e 13284 // = d[k-1] * 10^(k-1) + ( rest) * 2^e 13285 // 13286 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0) 13287 // 13288 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0] 13289 // 13290 // but stop as soon as 13291 // 13292 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e 13293 13294 int n = k; 13295 while (n > 0) 13296 { 13297 // Invariants: 13298 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k) 13299 // pow10 = 10^(n-1) <= p1 < 10^n 13300 // 13301 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1) 13302 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1) 13303 // 13304 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e 13305 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e) 13306 // 13307 assert(d <= 9); 13308 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d 13309 // 13310 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e) 13311 // 13312 p1 = r; 13313 n--; 13314 // 13315 // M+ = buffer * 10^n + (p1 + p2 * 2^e) 13316 // pow10 = 10^n 13317 // 13318 13319 // Now check if enough digits have been generated. 13320 // Compute 13321 // 13322 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e 13323 // 13324 // Note: 13325 // Since rest and delta share the same exponent e, it suffices to 13326 // compare the significands. 13327 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2; 13328 if (rest <= delta) 13329 { 13330 // V = buffer * 10^n, with M- <= V <= M+. 13331 13332 decimal_exponent += n; 13333 13334 // We may now just stop. But instead look if the buffer could be 13335 // decremented to bring V closer to w. 13336 // 13337 // pow10 = 10^n is now 1 ulp in the decimal representation V. 13338 // The rounding procedure works with diyfp's with an implicit 13339 // exponent of e. 13340 // 13341 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e 13342 // 13343 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e; 13344 grisu2_round(buffer, length, dist, delta, rest, ten_n); 13345 13346 return; 13347 } 13348 13349 pow10 /= 10; 13350 // 13351 // pow10 = 10^(n-1) <= p1 < 10^n 13352 // Invariants restored. 13353 } 13354 13355 // 2) 13356 // 13357 // The digits of the integral part have been generated: 13358 // 13359 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e 13360 // = buffer + p2 * 2^e 13361 // 13362 // Now generate the digits of the fractional part p2 * 2^e. 13363 // 13364 // Note: 13365 // No decimal point is generated: the exponent is adjusted instead. 13366 // 13367 // p2 actually represents the fraction 13368 // 13369 // p2 * 2^e 13370 // = p2 / 2^-e 13371 // = d[-1] / 10^1 + d[-2] / 10^2 + ... 13372 // 13373 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...) 13374 // 13375 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m 13376 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...) 13377 // 13378 // using 13379 // 13380 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e) 13381 // = ( d) * 2^-e + ( r) 13382 // 13383 // or 13384 // 10^m * p2 * 2^e = d + r * 2^e 13385 // 13386 // i.e. 13387 // 13388 // M+ = buffer + p2 * 2^e 13389 // = buffer + 10^-m * (d + r * 2^e) 13390 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e 13391 // 13392 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e 13393 13394 assert(p2 > delta); 13395 13396 int m = 0; 13397 for (;;) 13398 { 13399 // Invariant: 13400 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e 13401 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e 13402 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e 13403 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e 13404 // 13405 assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10); 13406 p2 *= 10; 13407 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e 13408 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e 13409 // 13410 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e 13411 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e)) 13412 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e 13413 // 13414 assert(d <= 9); 13415 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d 13416 // 13417 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e 13418 // 13419 p2 = r; 13420 m++; 13421 // 13422 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e 13423 // Invariant restored. 13424 13425 // Check if enough digits have been generated. 13426 // 13427 // 10^-m * p2 * 2^e <= delta * 2^e 13428 // p2 * 2^e <= 10^m * delta * 2^e 13429 // p2 <= 10^m * delta 13430 delta *= 10; 13431 dist *= 10; 13432 if (p2 <= delta) 13433 { 13434 break; 13435 } 13436 } 13437 13438 // V = buffer * 10^-m, with M- <= V <= M+. 13439 13440 decimal_exponent -= m; 13441 13442 // 1 ulp in the decimal representation is now 10^-m. 13443 // Since delta and dist are now scaled by 10^m, we need to do the 13444 // same with ulp in order to keep the units in sync. 13445 // 13446 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e 13447 // 13448 const std::uint64_t ten_m = one.f; 13449 grisu2_round(buffer, length, dist, delta, p2, ten_m); 13450 13451 // By construction this algorithm generates the shortest possible decimal 13452 // number (Loitsch, Theorem 6.2) which rounds back to w. 13453 // For an input number of precision p, at least 13454 // 13455 // N = 1 + ceil(p * log_10(2)) 13456 // 13457 // decimal digits are sufficient to identify all binary floating-point 13458 // numbers (Matula, "In-and-Out conversions"). 13459 // This implies that the algorithm does not produce more than N decimal 13460 // digits. 13461 // 13462 // N = 17 for p = 53 (IEEE double precision) 13463 // N = 9 for p = 24 (IEEE single precision) 13464} 13465 13466/*! 13467v = buf * 10^decimal_exponent 13468len is the length of the buffer (number of decimal digits) 13469The buffer must be large enough, i.e. >= max_digits10. 13470*/ 13471JSON_HEDLEY_NON_NULL(1) 13472inline void grisu2(char* buf, int& len, int& decimal_exponent, 13473 diyfp m_minus, diyfp v, diyfp m_plus) 13474{ 13475 assert(m_plus.e == m_minus.e); 13476 assert(m_plus.e == v.e); 13477 13478 // --------(-----------------------+-----------------------)-------- (A) 13479 // m- v m+ 13480 // 13481 // --------------------(-----------+-----------------------)-------- (B) 13482 // m- v m+ 13483 // 13484 // First scale v (and m- and m+) such that the exponent is in the range 13485 // [alpha, gamma]. 13486 13487 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e); 13488 13489 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k 13490 13491 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma] 13492 const diyfp w = diyfp::mul(v, c_minus_k); 13493 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k); 13494 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k); 13495 13496 // ----(---+---)---------------(---+---)---------------(---+---)---- 13497 // w- w w+ 13498 // = c*m- = c*v = c*m+ 13499 // 13500 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and 13501 // w+ are now off by a small amount. 13502 // In fact: 13503 // 13504 // w - v * 10^k < 1 ulp 13505 // 13506 // To account for this inaccuracy, add resp. subtract 1 ulp. 13507 // 13508 // --------+---[---------------(---+---)---------------]---+-------- 13509 // w- M- w M+ w+ 13510 // 13511 // Now any number in [M-, M+] (bounds included) will round to w when input, 13512 // regardless of how the input rounding algorithm breaks ties. 13513 // 13514 // And digit_gen generates the shortest possible such number in [M-, M+]. 13515 // Note that this does not mean that Grisu2 always generates the shortest 13516 // possible number in the interval (m-, m+). 13517 const diyfp M_minus(w_minus.f + 1, w_minus.e); 13518 const diyfp M_plus (w_plus.f - 1, w_plus.e ); 13519 13520 decimal_exponent = -cached.k; // = -(-k) = k 13521 13522 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus); 13523} 13524 13525/*! 13526v = buf * 10^decimal_exponent 13527len is the length of the buffer (number of decimal digits) 13528The buffer must be large enough, i.e. >= max_digits10. 13529*/ 13530template <typename FloatType> 13531JSON_HEDLEY_NON_NULL(1) 13532void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value) 13533{ 13534 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3, 13535 "internal error: not enough precision"); 13536 13537 assert(std::isfinite(value)); 13538 assert(value > 0); 13539 13540 // If the neighbors (and boundaries) of 'value' are always computed for double-precision 13541 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting 13542 // decimal representations are not exactly "short". 13543 // 13544 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars) 13545 // says "value is converted to a string as if by std::sprintf in the default ("C") locale" 13546 // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars' 13547 // does. 13548 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the 13549 // representation using the corresponding std::from_chars function recovers value exactly". That 13550 // indicates that single precision floating-point numbers should be recovered using 13551 // 'std::strtof'. 13552 // 13553 // NB: If the neighbors are computed for single-precision numbers, there is a single float 13554 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision 13555 // value is off by 1 ulp. 13556#if 0 13557 const boundaries w = compute_boundaries(static_cast<double>(value)); 13558#else 13559 const boundaries w = compute_boundaries(value); 13560#endif 13561 13562 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus); 13563} 13564 13565/*! 13566@brief appends a decimal representation of e to buf 13567@return a pointer to the element following the exponent. 13568@pre -1000 < e < 1000 13569*/ 13570JSON_HEDLEY_NON_NULL(1) 13571JSON_HEDLEY_RETURNS_NON_NULL 13572inline char* append_exponent(char* buf, int e) 13573{ 13574 assert(e > -1000); 13575 assert(e < 1000); 13576 13577 if (e < 0) 13578 { 13579 e = -e; 13580 *buf++ = '-'; 13581 } 13582 else 13583 { 13584 *buf++ = '+'; 13585 } 13586 13587 auto k = static_cast<std::uint32_t>(e); 13588 if (k < 10) 13589 { 13590 // Always print at least two digits in the exponent. 13591 // This is for compatibility with printf("%g"). 13592 *buf++ = '0'; 13593 *buf++ = static_cast<char>('0' + k); 13594 } 13595 else if (k < 100) 13596 { 13597 *buf++ = static_cast<char>('0' + k / 10); 13598 k %= 10; 13599 *buf++ = static_cast<char>('0' + k); 13600 } 13601 else 13602 { 13603 *buf++ = static_cast<char>('0' + k / 100); 13604 k %= 100; 13605 *buf++ = static_cast<char>('0' + k / 10); 13606 k %= 10; 13607 *buf++ = static_cast<char>('0' + k); 13608 } 13609 13610 return buf; 13611} 13612 13613/*! 13614@brief prettify v = buf * 10^decimal_exponent 13615 13616If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point 13617notation. Otherwise it will be printed in exponential notation. 13618 13619@pre min_exp < 0 13620@pre max_exp > 0 13621*/ 13622JSON_HEDLEY_NON_NULL(1) 13623JSON_HEDLEY_RETURNS_NON_NULL 13624inline char* format_buffer(char* buf, int len, int decimal_exponent, 13625 int min_exp, int max_exp) 13626{ 13627 assert(min_exp < 0); 13628 assert(max_exp > 0); 13629 13630 const int k = len; 13631 const int n = len + decimal_exponent; 13632 13633 // v = buf * 10^(n-k) 13634 // k is the length of the buffer (number of decimal digits) 13635 // n is the position of the decimal point relative to the start of the buffer. 13636 13637 if (k <= n and n <= max_exp) 13638 { 13639 // digits[000] 13640 // len <= max_exp + 2 13641 13642 std::memset(buf + k, '0', static_cast<size_t>(n - k)); 13643 // Make it look like a floating-point number (#362, #378) 13644 buf[n + 0] = '.'; 13645 buf[n + 1] = '0'; 13646 return buf + (n + 2); 13647 } 13648 13649 if (0 < n and n <= max_exp) 13650 { 13651 // dig.its 13652 // len <= max_digits10 + 1 13653 13654 assert(k > n); 13655 13656 std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n)); 13657 buf[n] = '.'; 13658 return buf + (k + 1); 13659 } 13660 13661 if (min_exp < n and n <= 0) 13662 { 13663 // 0.[000]digits 13664 // len <= 2 + (-min_exp - 1) + max_digits10 13665 13666 std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k)); 13667 buf[0] = '0'; 13668 buf[1] = '.'; 13669 std::memset(buf + 2, '0', static_cast<size_t>(-n)); 13670 return buf + (2 + (-n) + k); 13671 } 13672 13673 if (k == 1) 13674 { 13675 // dE+123 13676 // len <= 1 + 5 13677 13678 buf += 1; 13679 } 13680 else 13681 { 13682 // d.igitsE+123 13683 // len <= max_digits10 + 1 + 5 13684 13685 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1)); 13686 buf[1] = '.'; 13687 buf += 1 + k; 13688 } 13689 13690 *buf++ = 'e'; 13691 return append_exponent(buf, n - 1); 13692} 13693 13694} // namespace dtoa_impl 13695 13696/*! 13697@brief generates a decimal representation of the floating-point number value in [first, last). 13698 13699The format of the resulting decimal representation is similar to printf's %g 13700format. Returns an iterator pointing past-the-end of the decimal representation. 13701 13702@note The input number must be finite, i.e. NaN's and Inf's are not supported. 13703@note The buffer must be large enough. 13704@note The result is NOT null-terminated. 13705*/ 13706template <typename FloatType> 13707JSON_HEDLEY_NON_NULL(1, 2) 13708JSON_HEDLEY_RETURNS_NON_NULL 13709char* to_chars(char* first, const char* last, FloatType value) 13710{ 13711 static_cast<void>(last); // maybe unused - fix warning 13712 assert(std::isfinite(value)); 13713 13714 // Use signbit(value) instead of (value < 0) since signbit works for -0. 13715 if (std::signbit(value)) 13716 { 13717 value = -value; 13718 *first++ = '-'; 13719 } 13720 13721 if (value == 0) // +-0 13722 { 13723 *first++ = '0'; 13724 // Make it look like a floating-point number (#362, #378) 13725 *first++ = '.'; 13726 *first++ = '0'; 13727 return first; 13728 } 13729 13730 assert(last - first >= std::numeric_limits<FloatType>::max_digits10); 13731 13732 // Compute v = buffer * 10^decimal_exponent. 13733 // The decimal digits are stored in the buffer, which needs to be interpreted 13734 // as an unsigned decimal integer. 13735 // len is the length of the buffer, i.e. the number of decimal digits. 13736 int len = 0; 13737 int decimal_exponent = 0; 13738 dtoa_impl::grisu2(first, len, decimal_exponent, value); 13739 13740 assert(len <= std::numeric_limits<FloatType>::max_digits10); 13741 13742 // Format the buffer like printf("%.*g", prec, value) 13743 constexpr int kMinExp = -4; 13744 // Use digits10 here to increase compatibility with version 2. 13745 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10; 13746 13747 assert(last - first >= kMaxExp + 2); 13748 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10); 13749 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6); 13750 13751 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp); 13752} 13753 13754} // namespace detail 13755} // namespace nlohmann 13756 13757// #include <nlohmann/detail/exceptions.hpp> 13758 13759// #include <nlohmann/detail/macro_scope.hpp> 13760 13761// #include <nlohmann/detail/meta/cpp_future.hpp> 13762 13763// #include <nlohmann/detail/output/binary_writer.hpp> 13764 13765// #include <nlohmann/detail/output/output_adapters.hpp> 13766 13767// #include <nlohmann/detail/value_t.hpp> 13768 13769 13770namespace nlohmann 13771{ 13772namespace detail 13773{ 13774/////////////////// 13775// serialization // 13776/////////////////// 13777 13778/// how to treat decoding errors 13779enum class error_handler_t 13780{ 13781 strict, ///< throw a type_error exception in case of invalid UTF-8 13782 replace, ///< replace invalid UTF-8 sequences with U+FFFD 13783 ignore ///< ignore invalid UTF-8 sequences 13784}; 13785 13786template<typename BasicJsonType> 13787class serializer 13788{ 13789 using string_t = typename BasicJsonType::string_t; 13790 using number_float_t = typename BasicJsonType::number_float_t; 13791 using number_integer_t = typename BasicJsonType::number_integer_t; 13792 using number_unsigned_t = typename BasicJsonType::number_unsigned_t; 13793 static constexpr std::uint8_t UTF8_ACCEPT = 0; 13794 static constexpr std::uint8_t UTF8_REJECT = 1; 13795 13796 public: 13797 /*! 13798 @param[in] s output stream to serialize to 13799 @param[in] ichar indentation character to use 13800 @param[in] error_handler_ how to react on decoding errors 13801 */ 13802 serializer(output_adapter_t<char> s, const char ichar, 13803 error_handler_t error_handler_ = error_handler_t::strict) 13804 : o(std::move(s)) 13805 , loc(std::localeconv()) 13806 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : * (loc->thousands_sep)) 13807 , decimal_point(loc->decimal_point == nullptr ? '\0' : * (loc->decimal_point)) 13808 , indent_char(ichar) 13809 , indent_string(512, indent_char) 13810 , error_handler(error_handler_) 13811 {} 13812 13813 // delete because of pointer members 13814 serializer(const serializer&) = delete; 13815 serializer& operator=(const serializer&) = delete; 13816 serializer(serializer&&) = delete; 13817 serializer& operator=(serializer&&) = delete; 13818 ~serializer() = default; 13819 13820 /*! 13821 @brief internal implementation of the serialization function 13822 13823 This function is called by the public member function dump and organizes 13824 the serialization internally. The indentation level is propagated as 13825 additional parameter. In case of arrays and objects, the function is 13826 called recursively. 13827 13828 - strings and object keys are escaped using `escape_string()` 13829 - integer numbers are converted implicitly via `operator<<` 13830 - floating-point numbers are converted to a string using `"%g"` format 13831 13832 @param[in] val value to serialize 13833 @param[in] pretty_print whether the output shall be pretty-printed 13834 @param[in] indent_step the indent level 13835 @param[in] current_indent the current indent level (only used internally) 13836 */ 13837 void dump(const BasicJsonType& val, const bool pretty_print, 13838 const bool ensure_ascii, 13839 const unsigned int indent_step, 13840 const unsigned int current_indent = 0) 13841 { 13842 switch (val.m_type) 13843 { 13844 case value_t::object: 13845 { 13846 if (val.m_value.object->empty()) 13847 { 13848 o->write_characters("{}", 2); 13849 return; 13850 } 13851 13852 if (pretty_print) 13853 { 13854 o->write_characters("{\n", 2); 13855 13856 // variable to hold indentation for recursive calls 13857 const auto new_indent = current_indent + indent_step; 13858 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) 13859 { 13860 indent_string.resize(indent_string.size() * 2, ' '); 13861 } 13862 13863 // first n-1 elements 13864 auto i = val.m_value.object->cbegin(); 13865 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i) 13866 { 13867 o->write_characters(indent_string.c_str(), new_indent); 13868 o->write_character('\"'); 13869 dump_escaped(i->first, ensure_ascii); 13870 o->write_characters("\": ", 3); 13871 dump(i->second, true, ensure_ascii, indent_step, new_indent); 13872 o->write_characters(",\n", 2); 13873 } 13874 13875 // last element 13876 assert(i != val.m_value.object->cend()); 13877 assert(std::next(i) == val.m_value.object->cend()); 13878 o->write_characters(indent_string.c_str(), new_indent); 13879 o->write_character('\"'); 13880 dump_escaped(i->first, ensure_ascii); 13881 o->write_characters("\": ", 3); 13882 dump(i->second, true, ensure_ascii, indent_step, new_indent); 13883 13884 o->write_character('\n'); 13885 o->write_characters(indent_string.c_str(), current_indent); 13886 o->write_character('}'); 13887 } 13888 else 13889 { 13890 o->write_character('{'); 13891 13892 // first n-1 elements 13893 auto i = val.m_value.object->cbegin(); 13894 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i) 13895 { 13896 o->write_character('\"'); 13897 dump_escaped(i->first, ensure_ascii); 13898 o->write_characters("\":", 2); 13899 dump(i->second, false, ensure_ascii, indent_step, current_indent); 13900 o->write_character(','); 13901 } 13902 13903 // last element 13904 assert(i != val.m_value.object->cend()); 13905 assert(std::next(i) == val.m_value.object->cend()); 13906 o->write_character('\"'); 13907 dump_escaped(i->first, ensure_ascii); 13908 o->write_characters("\":", 2); 13909 dump(i->second, false, ensure_ascii, indent_step, current_indent); 13910 13911 o->write_character('}'); 13912 } 13913 13914 return; 13915 } 13916 13917 case value_t::array: 13918 { 13919 if (val.m_value.array->empty()) 13920 { 13921 o->write_characters("[]", 2); 13922 return; 13923 } 13924 13925 if (pretty_print) 13926 { 13927 o->write_characters("[\n", 2); 13928 13929 // variable to hold indentation for recursive calls 13930 const auto new_indent = current_indent + indent_step; 13931 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) 13932 { 13933 indent_string.resize(indent_string.size() * 2, ' '); 13934 } 13935 13936 // first n-1 elements 13937 for (auto i = val.m_value.array->cbegin(); 13938 i != val.m_value.array->cend() - 1; ++i) 13939 { 13940 o->write_characters(indent_string.c_str(), new_indent); 13941 dump(*i, true, ensure_ascii, indent_step, new_indent); 13942 o->write_characters(",\n", 2); 13943 } 13944 13945 // last element 13946 assert(not val.m_value.array->empty()); 13947 o->write_characters(indent_string.c_str(), new_indent); 13948 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent); 13949 13950 o->write_character('\n'); 13951 o->write_characters(indent_string.c_str(), current_indent); 13952 o->write_character(']'); 13953 } 13954 else 13955 { 13956 o->write_character('['); 13957 13958 // first n-1 elements 13959 for (auto i = val.m_value.array->cbegin(); 13960 i != val.m_value.array->cend() - 1; ++i) 13961 { 13962 dump(*i, false, ensure_ascii, indent_step, current_indent); 13963 o->write_character(','); 13964 } 13965 13966 // last element 13967 assert(not val.m_value.array->empty()); 13968 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent); 13969 13970 o->write_character(']'); 13971 } 13972 13973 return; 13974 } 13975 13976 case value_t::string: 13977 { 13978 o->write_character('\"'); 13979 dump_escaped(*val.m_value.string, ensure_ascii); 13980 o->write_character('\"'); 13981 return; 13982 } 13983 13984 case value_t::boolean: 13985 { 13986 if (val.m_value.boolean) 13987 { 13988 o->write_characters("true", 4); 13989 } 13990 else 13991 { 13992 o->write_characters("false", 5); 13993 } 13994 return; 13995 } 13996 13997 case value_t::number_integer: 13998 { 13999 dump_integer(val.m_value.number_integer); 14000 return; 14001 } 14002 14003 case value_t::number_unsigned: 14004 { 14005 dump_integer(val.m_value.number_unsigned); 14006 return; 14007 } 14008 14009 case value_t::number_float: 14010 { 14011 dump_float(val.m_value.number_float); 14012 return; 14013 } 14014 14015 case value_t::discarded: 14016 { 14017 o->write_characters("<discarded>", 11); 14018 return; 14019 } 14020 14021 case value_t::null: 14022 { 14023 o->write_characters("null", 4); 14024 return; 14025 } 14026 14027 default: // LCOV_EXCL_LINE 14028 assert(false); // LCOV_EXCL_LINE 14029 } 14030 } 14031 14032 private: 14033 /*! 14034 @brief dump escaped string 14035 14036 Escape a string by replacing certain special characters by a sequence of an 14037 escape character (backslash) and another character and other control 14038 characters by a sequence of "\u" followed by a four-digit hex 14039 representation. The escaped string is written to output stream @a o. 14040 14041 @param[in] s the string to escape 14042 @param[in] ensure_ascii whether to escape non-ASCII characters with 14043 \uXXXX sequences 14044 14045 @complexity Linear in the length of string @a s. 14046 */ 14047 void dump_escaped(const string_t& s, const bool ensure_ascii) 14048 { 14049 std::uint32_t codepoint; 14050 std::uint8_t state = UTF8_ACCEPT; 14051 std::size_t bytes = 0; // number of bytes written to string_buffer 14052 14053 // number of bytes written at the point of the last valid byte 14054 std::size_t bytes_after_last_accept = 0; 14055 std::size_t undumped_chars = 0; 14056 14057 for (std::size_t i = 0; i < s.size(); ++i) 14058 { 14059 const auto byte = static_cast<uint8_t>(s[i]); 14060 14061 switch (decode(state, codepoint, byte)) 14062 { 14063 case UTF8_ACCEPT: // decode found a new code point 14064 { 14065 switch (codepoint) 14066 { 14067 case 0x08: // backspace 14068 { 14069 string_buffer[bytes++] = '\\'; 14070 string_buffer[bytes++] = 'b'; 14071 break; 14072 } 14073 14074 case 0x09: // horizontal tab 14075 { 14076 string_buffer[bytes++] = '\\'; 14077 string_buffer[bytes++] = 't'; 14078 break; 14079 } 14080 14081 case 0x0A: // newline 14082 { 14083 string_buffer[bytes++] = '\\'; 14084 string_buffer[bytes++] = 'n'; 14085 break; 14086 } 14087 14088 case 0x0C: // formfeed 14089 { 14090 string_buffer[bytes++] = '\\'; 14091 string_buffer[bytes++] = 'f'; 14092 break; 14093 } 14094 14095 case 0x0D: // carriage return 14096 { 14097 string_buffer[bytes++] = '\\'; 14098 string_buffer[bytes++] = 'r'; 14099 break; 14100 } 14101 14102 case 0x22: // quotation mark 14103 { 14104 string_buffer[bytes++] = '\\'; 14105 string_buffer[bytes++] = '\"'; 14106 break; 14107 } 14108 14109 case 0x5C: // reverse solidus 14110 { 14111 string_buffer[bytes++] = '\\'; 14112 string_buffer[bytes++] = '\\'; 14113 break; 14114 } 14115 14116 default: 14117 { 14118 // escape control characters (0x00..0x1F) or, if 14119 // ensure_ascii parameter is used, non-ASCII characters 14120 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F))) 14121 { 14122 if (codepoint <= 0xFFFF) 14123 { 14124 (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x", 14125 static_cast<std::uint16_t>(codepoint)); 14126 bytes += 6; 14127 } 14128 else 14129 { 14130 (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x", 14131 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)), 14132 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))); 14133 bytes += 12; 14134 } 14135 } 14136 else 14137 { 14138 // copy byte to buffer (all previous bytes 14139 // been copied have in default case above) 14140 string_buffer[bytes++] = s[i]; 14141 } 14142 break; 14143 } 14144 } 14145 14146 // write buffer and reset index; there must be 13 bytes 14147 // left, as this is the maximal number of bytes to be 14148 // written ("\uxxxx\uxxxx\0") for one code point 14149 if (string_buffer.size() - bytes < 13) 14150 { 14151 o->write_characters(string_buffer.data(), bytes); 14152 bytes = 0; 14153 } 14154 14155 // remember the byte position of this accept 14156 bytes_after_last_accept = bytes; 14157 undumped_chars = 0; 14158 break; 14159 } 14160 14161 case UTF8_REJECT: // decode found invalid UTF-8 byte 14162 { 14163 switch (error_handler) 14164 { 14165 case error_handler_t::strict: 14166 { 14167 std::string sn(3, '\0'); 14168 (std::snprintf)(&sn[0], sn.size(), "%.2X", byte); 14169 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn)); 14170 } 14171 14172 case error_handler_t::ignore: 14173 case error_handler_t::replace: 14174 { 14175 // in case we saw this character the first time, we 14176 // would like to read it again, because the byte 14177 // may be OK for itself, but just not OK for the 14178 // previous sequence 14179 if (undumped_chars > 0) 14180 { 14181 --i; 14182 } 14183 14184 // reset length buffer to the last accepted index; 14185 // thus removing/ignoring the invalid characters 14186 bytes = bytes_after_last_accept; 14187 14188 if (error_handler == error_handler_t::replace) 14189 { 14190 // add a replacement character 14191 if (ensure_ascii) 14192 { 14193 string_buffer[bytes++] = '\\'; 14194 string_buffer[bytes++] = 'u'; 14195 string_buffer[bytes++] = 'f'; 14196 string_buffer[bytes++] = 'f'; 14197 string_buffer[bytes++] = 'f'; 14198 string_buffer[bytes++] = 'd'; 14199 } 14200 else 14201 { 14202 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF'); 14203 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF'); 14204 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD'); 14205 } 14206 14207 // write buffer and reset index; there must be 13 bytes 14208 // left, as this is the maximal number of bytes to be 14209 // written ("\uxxxx\uxxxx\0") for one code point 14210 if (string_buffer.size() - bytes < 13) 14211 { 14212 o->write_characters(string_buffer.data(), bytes); 14213 bytes = 0; 14214 } 14215 14216 bytes_after_last_accept = bytes; 14217 } 14218 14219 undumped_chars = 0; 14220 14221 // continue processing the string 14222 state = UTF8_ACCEPT; 14223 break; 14224 } 14225 14226 default: // LCOV_EXCL_LINE 14227 assert(false); // LCOV_EXCL_LINE 14228 } 14229 break; 14230 } 14231 14232 default: // decode found yet incomplete multi-byte code point 14233 { 14234 if (not ensure_ascii) 14235 { 14236 // code point will not be escaped - copy byte to buffer 14237 string_buffer[bytes++] = s[i]; 14238 } 14239 ++undumped_chars; 14240 break; 14241 } 14242 } 14243 } 14244 14245 // we finished processing the string 14246 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT)) 14247 { 14248 // write buffer 14249 if (bytes > 0) 14250 { 14251 o->write_characters(string_buffer.data(), bytes); 14252 } 14253 } 14254 else 14255 { 14256 // we finish reading, but do not accept: string was incomplete 14257 switch (error_handler) 14258 { 14259 case error_handler_t::strict: 14260 { 14261 std::string sn(3, '\0'); 14262 (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back())); 14263 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn)); 14264 } 14265 14266 case error_handler_t::ignore: 14267 { 14268 // write all accepted bytes 14269 o->write_characters(string_buffer.data(), bytes_after_last_accept); 14270 break; 14271 } 14272 14273 case error_handler_t::replace: 14274 { 14275 // write all accepted bytes 14276 o->write_characters(string_buffer.data(), bytes_after_last_accept); 14277 // add a replacement character 14278 if (ensure_ascii) 14279 { 14280 o->write_characters("\\ufffd", 6); 14281 } 14282 else 14283 { 14284 o->write_characters("\xEF\xBF\xBD", 3); 14285 } 14286 break; 14287 } 14288 14289 default: // LCOV_EXCL_LINE 14290 assert(false); // LCOV_EXCL_LINE 14291 } 14292 } 14293 } 14294 14295 /*! 14296 @brief count digits 14297 14298 Count the number of decimal (base 10) digits for an input unsigned integer. 14299 14300 @param[in] x unsigned integer number to count its digits 14301 @return number of decimal digits 14302 */ 14303 inline unsigned int count_digits(number_unsigned_t x) noexcept 14304 { 14305 unsigned int n_digits = 1; 14306 for (;;) 14307 { 14308 if (x < 10) 14309 { 14310 return n_digits; 14311 } 14312 if (x < 100) 14313 { 14314 return n_digits + 1; 14315 } 14316 if (x < 1000) 14317 { 14318 return n_digits + 2; 14319 } 14320 if (x < 10000) 14321 { 14322 return n_digits + 3; 14323 } 14324 x = x / 10000u; 14325 n_digits += 4; 14326 } 14327 } 14328 14329 /*! 14330 @brief dump an integer 14331 14332 Dump a given integer to output stream @a o. Works internally with 14333 @a number_buffer. 14334 14335 @param[in] x integer number (signed or unsigned) to dump 14336 @tparam NumberType either @a number_integer_t or @a number_unsigned_t 14337 */ 14338 template<typename NumberType, detail::enable_if_t< 14339 std::is_same<NumberType, number_unsigned_t>::value or 14340 std::is_same<NumberType, number_integer_t>::value, 14341 int> = 0> 14342 void dump_integer(NumberType x) 14343 { 14344 static constexpr std::array<std::array<char, 2>, 100> digits_to_99 14345 { 14346 { 14347 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}}, 14348 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}}, 14349 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}}, 14350 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}}, 14351 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}}, 14352 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}}, 14353 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}}, 14354 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}}, 14355 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}}, 14356 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}}, 14357 } 14358 }; 14359 14360 // special case for "0" 14361 if (x == 0) 14362 { 14363 o->write_character('0'); 14364 return; 14365 } 14366 14367 // use a pointer to fill the buffer 14368 auto buffer_ptr = number_buffer.begin(); 14369 14370 const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not(x >= 0); // see issue #755 14371 number_unsigned_t abs_value; 14372 14373 unsigned int n_chars; 14374 14375 if (is_negative) 14376 { 14377 *buffer_ptr = '-'; 14378 abs_value = remove_sign(x); 14379 14380 // account one more byte for the minus sign 14381 n_chars = 1 + count_digits(abs_value); 14382 } 14383 else 14384 { 14385 abs_value = static_cast<number_unsigned_t>(x); 14386 n_chars = count_digits(abs_value); 14387 } 14388 14389 // spare 1 byte for '\0' 14390 assert(n_chars < number_buffer.size() - 1); 14391 14392 // jump to the end to generate the string from backward 14393 // so we later avoid reversing the result 14394 buffer_ptr += n_chars; 14395 14396 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu 14397 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg 14398 while (abs_value >= 100) 14399 { 14400 const auto digits_index = static_cast<unsigned>((abs_value % 100)); 14401 abs_value /= 100; 14402 *(--buffer_ptr) = digits_to_99[digits_index][1]; 14403 *(--buffer_ptr) = digits_to_99[digits_index][0]; 14404 } 14405 14406 if (abs_value >= 10) 14407 { 14408 const auto digits_index = static_cast<unsigned>(abs_value); 14409 *(--buffer_ptr) = digits_to_99[digits_index][1]; 14410 *(--buffer_ptr) = digits_to_99[digits_index][0]; 14411 } 14412 else 14413 { 14414 *(--buffer_ptr) = static_cast<char>('0' + abs_value); 14415 } 14416 14417 o->write_characters(number_buffer.data(), n_chars); 14418 } 14419 14420 /*! 14421 @brief dump a floating-point number 14422 14423 Dump a given floating-point number to output stream @a o. Works internally 14424 with @a number_buffer. 14425 14426 @param[in] x floating-point number to dump 14427 */ 14428 void dump_float(number_float_t x) 14429 { 14430 // NaN / inf 14431 if (not std::isfinite(x)) 14432 { 14433 o->write_characters("null", 4); 14434 return; 14435 } 14436 14437 // If number_float_t is an IEEE-754 single or double precision number, 14438 // use the Grisu2 algorithm to produce short numbers which are 14439 // guaranteed to round-trip, using strtof and strtod, resp. 14440 // 14441 // NB: The test below works if <long double> == <double>. 14442 static constexpr bool is_ieee_single_or_double 14443 = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 24 and std::numeric_limits<number_float_t>::max_exponent == 128) or 14444 (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 53 and std::numeric_limits<number_float_t>::max_exponent == 1024); 14445 14446 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>()); 14447 } 14448 14449 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/) 14450 { 14451 char* begin = number_buffer.data(); 14452 char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x); 14453 14454 o->write_characters(begin, static_cast<size_t>(end - begin)); 14455 } 14456 14457 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/) 14458 { 14459 // get number of digits for a float -> text -> float round-trip 14460 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10; 14461 14462 // the actual conversion 14463 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x); 14464 14465 // negative value indicates an error 14466 assert(len > 0); 14467 // check if buffer was large enough 14468 assert(static_cast<std::size_t>(len) < number_buffer.size()); 14469 14470 // erase thousands separator 14471 if (thousands_sep != '\0') 14472 { 14473 const auto end = std::remove(number_buffer.begin(), 14474 number_buffer.begin() + len, thousands_sep); 14475 std::fill(end, number_buffer.end(), '\0'); 14476 assert((end - number_buffer.begin()) <= len); 14477 len = (end - number_buffer.begin()); 14478 } 14479 14480 // convert decimal point to '.' 14481 if (decimal_point != '\0' and decimal_point != '.') 14482 { 14483 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point); 14484 if (dec_pos != number_buffer.end()) 14485 { 14486 *dec_pos = '.'; 14487 } 14488 } 14489 14490 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len)); 14491 14492 // determine if need to append ".0" 14493 const bool value_is_int_like = 14494 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1, 14495 [](char c) 14496 { 14497 return c == '.' or c == 'e'; 14498 }); 14499 14500 if (value_is_int_like) 14501 { 14502 o->write_characters(".0", 2); 14503 } 14504 } 14505 14506 /*! 14507 @brief check whether a string is UTF-8 encoded 14508 14509 The function checks each byte of a string whether it is UTF-8 encoded. The 14510 result of the check is stored in the @a state parameter. The function must 14511 be called initially with state 0 (accept). State 1 means the string must 14512 be rejected, because the current byte is not allowed. If the string is 14513 completely processed, but the state is non-zero, the string ended 14514 prematurely; that is, the last byte indicated more bytes should have 14515 followed. 14516 14517 @param[in,out] state the state of the decoding 14518 @param[in,out] codep codepoint (valid only if resulting state is UTF8_ACCEPT) 14519 @param[in] byte next byte to decode 14520 @return new state 14521 14522 @note The function has been edited: a std::array is used. 14523 14524 @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de> 14525 @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ 14526 */ 14527 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept 14528 { 14529 static const std::array<std::uint8_t, 400> utf8d = 14530 { 14531 { 14532 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, // 00..1F 14533 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, // 20..3F 14534 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, // 40..5F 14535 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, // 60..7F 14536 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F 14537 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF 14538 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF 14539 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF 14540 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF 14541 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0 14542 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2 14543 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4 14544 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6 14545 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8 14546 } 14547 }; 14548 14549 const std::uint8_t type = utf8d[byte]; 14550 14551 codep = (state != UTF8_ACCEPT) 14552 ? (byte & 0x3fu) | (codep << 6u) 14553 : (0xFFu >> type) & (byte); 14554 14555 state = utf8d[256u + state * 16u + type]; 14556 return state; 14557 } 14558 14559 /* 14560 * Overload to make the compiler happy while it is instantiating 14561 * dump_integer for number_unsigned_t. 14562 * Must never be called. 14563 */ 14564 number_unsigned_t remove_sign(number_unsigned_t x) 14565 { 14566 assert(false); // LCOV_EXCL_LINE 14567 return x; // LCOV_EXCL_LINE 14568 } 14569 14570 /* 14571 * Helper function for dump_integer 14572 * 14573 * This function takes a negative signed integer and returns its absolute 14574 * value as unsigned integer. The plus/minus shuffling is necessary as we can 14575 * not directly remove the sign of an arbitrary signed integer as the 14576 * absolute values of INT_MIN and INT_MAX are usually not the same. See 14577 * #1708 for details. 14578 */ 14579 inline number_unsigned_t remove_sign(number_integer_t x) noexcept 14580 { 14581 assert(x < 0 and x < (std::numeric_limits<number_integer_t>::max)()); 14582 return static_cast<number_unsigned_t>(-(x + 1)) + 1; 14583 } 14584 14585 private: 14586 /// the output of the serializer 14587 output_adapter_t<char> o = nullptr; 14588 14589 /// a (hopefully) large enough character buffer 14590 std::array<char, 64> number_buffer{{}}; 14591 14592 /// the locale 14593 const std::lconv* loc = nullptr; 14594 /// the locale's thousand separator character 14595 const char thousands_sep = '\0'; 14596 /// the locale's decimal point character 14597 const char decimal_point = '\0'; 14598 14599 /// string buffer 14600 std::array<char, 512> string_buffer{{}}; 14601 14602 /// the indentation character 14603 const char indent_char; 14604 /// the indentation string 14605 string_t indent_string; 14606 14607 /// error_handler how to react on decoding errors 14608 const error_handler_t error_handler; 14609}; 14610} // namespace detail 14611} // namespace nlohmann 14612 14613// #include <nlohmann/detail/value_t.hpp> 14614 14615// #include <nlohmann/json_fwd.hpp> 14616 14617 14618/*! 14619@brief namespace for Niels Lohmann 14620@see https://github.com/nlohmann 14621@since version 1.0.0 14622*/ 14623namespace nlohmann 14624{ 14625 14626/*! 14627@brief a class to store JSON values 14628 14629@tparam ObjectType type for JSON objects (`std::map` by default; will be used 14630in @ref object_t) 14631@tparam ArrayType type for JSON arrays (`std::vector` by default; will be used 14632in @ref array_t) 14633@tparam StringType type for JSON strings and object keys (`std::string` by 14634default; will be used in @ref string_t) 14635@tparam BooleanType type for JSON booleans (`bool` by default; will be used 14636in @ref boolean_t) 14637@tparam NumberIntegerType type for JSON integer numbers (`int64_t` by 14638default; will be used in @ref number_integer_t) 14639@tparam NumberUnsignedType type for JSON unsigned integer numbers (@c 14640`uint64_t` by default; will be used in @ref number_unsigned_t) 14641@tparam NumberFloatType type for JSON floating-point numbers (`double` by 14642default; will be used in @ref number_float_t) 14643@tparam AllocatorType type of the allocator to use (`std::allocator` by 14644default) 14645@tparam JSONSerializer the serializer to resolve internal calls to `to_json()` 14646and `from_json()` (@ref adl_serializer by default) 14647 14648@requirement The class satisfies the following concept requirements: 14649- Basic 14650 - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible): 14651 JSON values can be default constructed. The result will be a JSON null 14652 value. 14653 - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible): 14654 A JSON value can be constructed from an rvalue argument. 14655 - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible): 14656 A JSON value can be copy-constructed from an lvalue expression. 14657 - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable): 14658 A JSON value van be assigned from an rvalue argument. 14659 - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable): 14660 A JSON value can be copy-assigned from an lvalue expression. 14661 - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible): 14662 JSON values can be destructed. 14663- Layout 14664 - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType): 14665 JSON values have 14666 [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout): 14667 All non-static data members are private and standard layout types, the 14668 class has no virtual functions or (virtual) base classes. 14669- Library-wide 14670 - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable): 14671 JSON values can be compared with `==`, see @ref 14672 operator==(const_reference,const_reference). 14673 - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable): 14674 JSON values can be compared with `<`, see @ref 14675 operator<(const_reference,const_reference). 14676 - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable): 14677 Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of 14678 other compatible types, using unqualified function call @ref swap(). 14679 - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer): 14680 JSON values can be compared against `std::nullptr_t` objects which are used 14681 to model the `null` value. 14682- Container 14683 - [Container](https://en.cppreference.com/w/cpp/named_req/Container): 14684 JSON values can be used like STL containers and provide iterator access. 14685 - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer); 14686 JSON values can be used like STL containers and provide reverse iterator 14687 access. 14688 14689@invariant The member variables @a m_value and @a m_type have the following 14690relationship: 14691- If `m_type == value_t::object`, then `m_value.object != nullptr`. 14692- If `m_type == value_t::array`, then `m_value.array != nullptr`. 14693- If `m_type == value_t::string`, then `m_value.string != nullptr`. 14694The invariants are checked by member function assert_invariant(). 14695 14696@internal 14697@note ObjectType trick from http://stackoverflow.com/a/9860911 14698@endinternal 14699 14700@see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange 14701Format](http://rfc7159.net/rfc7159) 14702 14703@since version 1.0.0 14704 14705@nosubgrouping 14706*/ 14707NLOHMANN_BASIC_JSON_TPL_DECLARATION 14708class basic_json 14709{ 14710 private: 14711 template<detail::value_t> friend struct detail::external_constructor; 14712 friend ::nlohmann::json_pointer<basic_json>; 14713 friend ::nlohmann::detail::parser<basic_json>; 14714 friend ::nlohmann::detail::serializer<basic_json>; 14715 template<typename BasicJsonType> 14716 friend class ::nlohmann::detail::iter_impl; 14717 template<typename BasicJsonType, typename CharType> 14718 friend class ::nlohmann::detail::binary_writer; 14719 template<typename BasicJsonType, typename SAX> 14720 friend class ::nlohmann::detail::binary_reader; 14721 template<typename BasicJsonType> 14722 friend class ::nlohmann::detail::json_sax_dom_parser; 14723 template<typename BasicJsonType> 14724 friend class ::nlohmann::detail::json_sax_dom_callback_parser; 14725 14726 /// workaround type for MSVC 14727 using basic_json_t = NLOHMANN_BASIC_JSON_TPL; 14728 14729 // convenience aliases for types residing in namespace detail; 14730 using lexer = ::nlohmann::detail::lexer<basic_json>; 14731 using parser = ::nlohmann::detail::parser<basic_json>; 14732 14733 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t; 14734 template<typename BasicJsonType> 14735 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>; 14736 template<typename BasicJsonType> 14737 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>; 14738 template<typename Iterator> 14739 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>; 14740 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>; 14741 14742 template<typename CharType> 14743 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>; 14744 14745 using binary_reader = ::nlohmann::detail::binary_reader<basic_json>; 14746 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>; 14747 14748 using serializer = ::nlohmann::detail::serializer<basic_json>; 14749 14750 public: 14751 using value_t = detail::value_t; 14752 /// JSON Pointer, see @ref nlohmann::json_pointer 14753 using json_pointer = ::nlohmann::json_pointer<basic_json>; 14754 template<typename T, typename SFINAE> 14755 using json_serializer = JSONSerializer<T, SFINAE>; 14756 /// how to treat decoding errors 14757 using error_handler_t = detail::error_handler_t; 14758 /// helper type for initializer lists of basic_json values 14759 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>; 14760 14761 using input_format_t = detail::input_format_t; 14762 /// SAX interface type, see @ref nlohmann::json_sax 14763 using json_sax_t = json_sax<basic_json>; 14764 14765 //////////////// 14766 // exceptions // 14767 //////////////// 14768 14769 /// @name exceptions 14770 /// Classes to implement user-defined exceptions. 14771 /// @{ 14772 14773 /// @copydoc detail::exception 14774 using exception = detail::exception; 14775 /// @copydoc detail::parse_error 14776 using parse_error = detail::parse_error; 14777 /// @copydoc detail::invalid_iterator 14778 using invalid_iterator = detail::invalid_iterator; 14779 /// @copydoc detail::type_error 14780 using type_error = detail::type_error; 14781 /// @copydoc detail::out_of_range 14782 using out_of_range = detail::out_of_range; 14783 /// @copydoc detail::other_error 14784 using other_error = detail::other_error; 14785 14786 /// @} 14787 14788 14789 ///////////////////// 14790 // container types // 14791 ///////////////////// 14792 14793 /// @name container types 14794 /// The canonic container types to use @ref basic_json like any other STL 14795 /// container. 14796 /// @{ 14797 14798 /// the type of elements in a basic_json container 14799 using value_type = basic_json; 14800 14801 /// the type of an element reference 14802 using reference = value_type&; 14803 /// the type of an element const reference 14804 using const_reference = const value_type&; 14805 14806 /// a type to represent differences between iterators 14807 using difference_type = std::ptrdiff_t; 14808 /// a type to represent container sizes 14809 using size_type = std::size_t; 14810 14811 /// the allocator type 14812 using allocator_type = AllocatorType<basic_json>; 14813 14814 /// the type of an element pointer 14815 using pointer = typename std::allocator_traits<allocator_type>::pointer; 14816 /// the type of an element const pointer 14817 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer; 14818 14819 /// an iterator for a basic_json container 14820 using iterator = iter_impl<basic_json>; 14821 /// a const iterator for a basic_json container 14822 using const_iterator = iter_impl<const basic_json>; 14823 /// a reverse iterator for a basic_json container 14824 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>; 14825 /// a const reverse iterator for a basic_json container 14826 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>; 14827 14828 /// @} 14829 14830 14831 /*! 14832 @brief returns the allocator associated with the container 14833 */ 14834 static allocator_type get_allocator() 14835 { 14836 return allocator_type(); 14837 } 14838 14839 /*! 14840 @brief returns version information on the library 14841 14842 This function returns a JSON object with information about the library, 14843 including the version number and information on the platform and compiler. 14844 14845 @return JSON object holding version information 14846 key | description 14847 ----------- | --------------- 14848 `compiler` | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version). 14849 `copyright` | The copyright line for the library as string. 14850 `name` | The name of the library as string. 14851 `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`. 14852 `url` | The URL of the project as string. 14853 `version` | The version of the library. It is an object with the following keys: `major`, `minor`, and `patch` as defined by [Semantic Versioning](http://semver.org), and `string` (the version string). 14854 14855 @liveexample{The following code shows an example output of the `meta()` 14856 function.,meta} 14857 14858 @exceptionsafety Strong guarantee: if an exception is thrown, there are no 14859 changes to any JSON value. 14860 14861 @complexity Constant. 14862 14863 @since 2.1.0 14864 */ 14865 JSON_HEDLEY_WARN_UNUSED_RESULT 14866 static basic_json meta() 14867 { 14868 basic_json result; 14869 14870 result["copyright"] = "(C) 2013-2017 Niels Lohmann"; 14871 result["name"] = "JSON for Modern C++"; 14872 result["url"] = "https://github.com/nlohmann/json"; 14873 result["version"]["string"] = 14874 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." + 14875 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." + 14876 std::to_string(NLOHMANN_JSON_VERSION_PATCH); 14877 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR; 14878 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR; 14879 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH; 14880 14881#ifdef _WIN32 14882 result["platform"] = "win32"; 14883#elif defined __linux__ 14884 result["platform"] = "linux"; 14885#elif defined __APPLE__ 14886 result["platform"] = "apple"; 14887#elif defined __unix__ 14888 result["platform"] = "unix"; 14889#else 14890 result["platform"] = "unknown"; 14891#endif 14892 14893#if defined(__ICC) || defined(__INTEL_COMPILER) 14894 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}}; 14895#elif defined(__clang__) 14896 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}}; 14897#elif defined(__GNUC__) || defined(__GNUG__) 14898 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}}; 14899#elif defined(__HP_cc) || defined(__HP_aCC) 14900 result["compiler"] = "hp" 14901#elif defined(__IBMCPP__) 14902 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}}; 14903#elif defined(_MSC_VER) 14904 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}}; 14905#elif defined(__PGI) 14906 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}}; 14907#elif defined(__SUNPRO_CC) 14908 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}}; 14909#else 14910 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}}; 14911#endif 14912 14913#ifdef __cplusplus 14914 result["compiler"]["c++"] = std::to_string(__cplusplus); 14915#else 14916 result["compiler"]["c++"] = "unknown"; 14917#endif 14918 return result; 14919 } 14920 14921 14922 /////////////////////////// 14923 // JSON value data types // 14924 /////////////////////////// 14925 14926 /// @name JSON value data types 14927 /// The data types to store a JSON value. These types are derived from 14928 /// the template arguments passed to class @ref basic_json. 14929 /// @{ 14930 14931#if defined(JSON_HAS_CPP_14) 14932 // Use transparent comparator if possible, combined with perfect forwarding 14933 // on find() and count() calls prevents unnecessary string construction. 14934 using object_comparator_t = std::less<>; 14935#else 14936 using object_comparator_t = std::less<StringType>; 14937#endif 14938 14939 /*! 14940 @brief a type for an object 14941 14942 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows: 14943 > An object is an unordered collection of zero or more name/value pairs, 14944 > where a name is a string and a value is a string, number, boolean, null, 14945 > object, or array. 14946 14947 To store objects in C++, a type is defined by the template parameters 14948 described below. 14949 14950 @tparam ObjectType the container to store objects (e.g., `std::map` or 14951 `std::unordered_map`) 14952 @tparam StringType the type of the keys or names (e.g., `std::string`). 14953 The comparison function `std::less<StringType>` is used to order elements 14954 inside the container. 14955 @tparam AllocatorType the allocator to use for objects (e.g., 14956 `std::allocator`) 14957 14958 #### Default type 14959 14960 With the default values for @a ObjectType (`std::map`), @a StringType 14961 (`std::string`), and @a AllocatorType (`std::allocator`), the default 14962 value for @a object_t is: 14963 14964 @code {.cpp} 14965 std::map< 14966 std::string, // key_type 14967 basic_json, // value_type 14968 std::less<std::string>, // key_compare 14969 std::allocator<std::pair<const std::string, basic_json>> // allocator_type 14970 > 14971 @endcode 14972 14973 #### Behavior 14974 14975 The choice of @a object_t influences the behavior of the JSON class. With 14976 the default type, objects have the following behavior: 14977 14978 - When all names are unique, objects will be interoperable in the sense 14979 that all software implementations receiving that object will agree on 14980 the name-value mappings. 14981 - When the names within an object are not unique, it is unspecified which 14982 one of the values for a given key will be chosen. For instance, 14983 `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or 14984 `{"key": 2}`. 14985 - Internally, name/value pairs are stored in lexicographical order of the 14986 names. Objects will also be serialized (see @ref dump) in this order. 14987 For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored 14988 and serialized as `{"a": 2, "b": 1}`. 14989 - When comparing objects, the order of the name/value pairs is irrelevant. 14990 This makes objects interoperable in the sense that they will not be 14991 affected by these differences. For instance, `{"b": 1, "a": 2}` and 14992 `{"a": 2, "b": 1}` will be treated as equal. 14993 14994 #### Limits 14995 14996 [RFC 7159](http://rfc7159.net/rfc7159) specifies: 14997 > An implementation may set limits on the maximum depth of nesting. 14998 14999 In this class, the object's limit of nesting is not explicitly constrained. 15000 However, a maximum depth of nesting may be introduced by the compiler or 15001 runtime environment. A theoretical limit can be queried by calling the 15002 @ref max_size function of a JSON object. 15003 15004 #### Storage 15005 15006 Objects are stored as pointers in a @ref basic_json type. That is, for any 15007 access to object values, a pointer of type `object_t*` must be 15008 dereferenced. 15009 15010 @sa @ref array_t -- type for an array value 15011 15012 @since version 1.0.0 15013 15014 @note The order name/value pairs are added to the object is *not* 15015 preserved by the library. Therefore, iterating an object may return 15016 name/value pairs in a different order than they were originally stored. In 15017 fact, keys will be traversed in alphabetical order as `std::map` with 15018 `std::less` is used by default. Please note this behavior conforms to [RFC 15019 7159](http://rfc7159.net/rfc7159), because any order implements the 15020 specified "unordered" nature of JSON objects. 15021 */ 15022 using object_t = ObjectType<StringType, 15023 basic_json, 15024 object_comparator_t, 15025 AllocatorType<std::pair<const StringType, 15026 basic_json>>>; 15027 15028 /*! 15029 @brief a type for an array 15030 15031 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows: 15032 > An array is an ordered sequence of zero or more values. 15033 15034 To store objects in C++, a type is defined by the template parameters 15035 explained below. 15036 15037 @tparam ArrayType container type to store arrays (e.g., `std::vector` or 15038 `std::list`) 15039 @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`) 15040 15041 #### Default type 15042 15043 With the default values for @a ArrayType (`std::vector`) and @a 15044 AllocatorType (`std::allocator`), the default value for @a array_t is: 15045 15046 @code {.cpp} 15047 std::vector< 15048 basic_json, // value_type 15049 std::allocator<basic_json> // allocator_type 15050 > 15051 @endcode 15052 15053 #### Limits 15054 15055 [RFC 7159](http://rfc7159.net/rfc7159) specifies: 15056 > An implementation may set limits on the maximum depth of nesting. 15057 15058 In this class, the array's limit of nesting is not explicitly constrained. 15059 However, a maximum depth of nesting may be introduced by the compiler or 15060 runtime environment. A theoretical limit can be queried by calling the 15061 @ref max_size function of a JSON array. 15062 15063 #### Storage 15064 15065 Arrays are stored as pointers in a @ref basic_json type. That is, for any 15066 access to array values, a pointer of type `array_t*` must be dereferenced. 15067 15068 @sa @ref object_t -- type for an object value 15069 15070 @since version 1.0.0 15071 */ 15072 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>; 15073 15074 /*! 15075 @brief a type for a string 15076 15077 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows: 15078 > A string is a sequence of zero or more Unicode characters. 15079 15080 To store objects in C++, a type is defined by the template parameter 15081 described below. Unicode values are split by the JSON class into 15082 byte-sized characters during deserialization. 15083 15084 @tparam StringType the container to store strings (e.g., `std::string`). 15085 Note this container is used for keys/names in objects, see @ref object_t. 15086 15087 #### Default type 15088 15089 With the default values for @a StringType (`std::string`), the default 15090 value for @a string_t is: 15091 15092 @code {.cpp} 15093 std::string 15094 @endcode 15095 15096 #### Encoding 15097 15098 Strings are stored in UTF-8 encoding. Therefore, functions like 15099 `std::string::size()` or `std::string::length()` return the number of 15100 bytes in the string rather than the number of characters or glyphs. 15101 15102 #### String comparison 15103 15104 [RFC 7159](http://rfc7159.net/rfc7159) states: 15105 > Software implementations are typically required to test names of object 15106 > members for equality. Implementations that transform the textual 15107 > representation into sequences of Unicode code units and then perform the 15108 > comparison numerically, code unit by code unit, are interoperable in the 15109 > sense that implementations will agree in all cases on equality or 15110 > inequality of two strings. For example, implementations that compare 15111 > strings with escaped characters unconverted may incorrectly find that 15112 > `"a\\b"` and `"a\u005Cb"` are not equal. 15113 15114 This implementation is interoperable as it does compare strings code unit 15115 by code unit. 15116 15117 #### Storage 15118 15119 String values are stored as pointers in a @ref basic_json type. That is, 15120 for any access to string values, a pointer of type `string_t*` must be 15121 dereferenced. 15122 15123 @since version 1.0.0 15124 */ 15125 using string_t = StringType; 15126 15127 /*! 15128 @brief a type for a boolean 15129 15130 [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a 15131 type which differentiates the two literals `true` and `false`. 15132 15133 To store objects in C++, a type is defined by the template parameter @a 15134 BooleanType which chooses the type to use. 15135 15136 #### Default type 15137 15138 With the default values for @a BooleanType (`bool`), the default value for 15139 @a boolean_t is: 15140 15141 @code {.cpp} 15142 bool 15143 @endcode 15144 15145 #### Storage 15146 15147 Boolean values are stored directly inside a @ref basic_json type. 15148 15149 @since version 1.0.0 15150 */ 15151 using boolean_t = BooleanType; 15152 15153 /*! 15154 @brief a type for a number (integer) 15155 15156 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows: 15157 > The representation of numbers is similar to that used in most 15158 > programming languages. A number is represented in base 10 using decimal 15159 > digits. It contains an integer component that may be prefixed with an 15160 > optional minus sign, which may be followed by a fraction part and/or an 15161 > exponent part. Leading zeros are not allowed. (...) Numeric values that 15162 > cannot be represented in the grammar below (such as Infinity and NaN) 15163 > are not permitted. 15164 15165 This description includes both integer and floating-point numbers. 15166 However, C++ allows more precise storage if it is known whether the number 15167 is a signed integer, an unsigned integer or a floating-point number. 15168 Therefore, three different types, @ref number_integer_t, @ref 15169 number_unsigned_t and @ref number_float_t are used. 15170 15171 To store integer numbers in C++, a type is defined by the template 15172 parameter @a NumberIntegerType which chooses the type to use. 15173 15174 #### Default type 15175 15176 With the default values for @a NumberIntegerType (`int64_t`), the default 15177 value for @a number_integer_t is: 15178 15179 @code {.cpp} 15180 int64_t 15181 @endcode 15182 15183 #### Default behavior 15184 15185 - The restrictions about leading zeros is not enforced in C++. Instead, 15186 leading zeros in integer literals lead to an interpretation as octal 15187 number. Internally, the value will be stored as decimal number. For 15188 instance, the C++ integer literal `010` will be serialized to `8`. 15189 During deserialization, leading zeros yield an error. 15190 - Not-a-number (NaN) values will be serialized to `null`. 15191 15192 #### Limits 15193 15194 [RFC 7159](http://rfc7159.net/rfc7159) specifies: 15195 > An implementation may set limits on the range and precision of numbers. 15196 15197 When the default type is used, the maximal integer number that can be 15198 stored is `9223372036854775807` (INT64_MAX) and the minimal integer number 15199 that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers 15200 that are out of range will yield over/underflow when used in a 15201 constructor. During deserialization, too large or small integer numbers 15202 will be automatically be stored as @ref number_unsigned_t or @ref 15203 number_float_t. 15204 15205 [RFC 7159](http://rfc7159.net/rfc7159) further states: 15206 > Note that when such software is used, numbers that are integers and are 15207 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense 15208 > that implementations will agree exactly on their numeric values. 15209 15210 As this range is a subrange of the exactly supported range [INT64_MIN, 15211 INT64_MAX], this class's integer type is interoperable. 15212 15213 #### Storage 15214 15215 Integer number values are stored directly inside a @ref basic_json type. 15216 15217 @sa @ref number_float_t -- type for number values (floating-point) 15218 15219 @sa @ref number_unsigned_t -- type for number values (unsigned integer) 15220 15221 @since version 1.0.0 15222 */ 15223 using number_integer_t = NumberIntegerType; 15224 15225 /*! 15226 @brief a type for a number (unsigned) 15227 15228 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows: 15229 > The representation of numbers is similar to that used in most 15230 > programming languages. A number is represented in base 10 using decimal 15231 > digits. It contains an integer component that may be prefixed with an 15232 > optional minus sign, which may be followed by a fraction part and/or an 15233 > exponent part. Leading zeros are not allowed. (...) Numeric values that 15234 > cannot be represented in the grammar below (such as Infinity and NaN) 15235 > are not permitted. 15236 15237 This description includes both integer and floating-point numbers. 15238 However, C++ allows more precise storage if it is known whether the number 15239 is a signed integer, an unsigned integer or a floating-point number. 15240 Therefore, three different types, @ref number_integer_t, @ref 15241 number_unsigned_t and @ref number_float_t are used. 15242 15243 To store unsigned integer numbers in C++, a type is defined by the 15244 template parameter @a NumberUnsignedType which chooses the type to use. 15245 15246 #### Default type 15247 15248 With the default values for @a NumberUnsignedType (`uint64_t`), the 15249 default value for @a number_unsigned_t is: 15250 15251 @code {.cpp} 15252 uint64_t 15253 @endcode 15254 15255 #### Default behavior 15256 15257 - The restrictions about leading zeros is not enforced in C++. Instead, 15258 leading zeros in integer literals lead to an interpretation as octal 15259 number. Internally, the value will be stored as decimal number. For 15260 instance, the C++ integer literal `010` will be serialized to `8`. 15261 During deserialization, leading zeros yield an error. 15262 - Not-a-number (NaN) values will be serialized to `null`. 15263 15264 #### Limits 15265 15266 [RFC 7159](http://rfc7159.net/rfc7159) specifies: 15267 > An implementation may set limits on the range and precision of numbers. 15268 15269 When the default type is used, the maximal integer number that can be 15270 stored is `18446744073709551615` (UINT64_MAX) and the minimal integer 15271 number that can be stored is `0`. Integer numbers that are out of range 15272 will yield over/underflow when used in a constructor. During 15273 deserialization, too large or small integer numbers will be automatically 15274 be stored as @ref number_integer_t or @ref number_float_t. 15275 15276 [RFC 7159](http://rfc7159.net/rfc7159) further states: 15277 > Note that when such software is used, numbers that are integers and are 15278 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense 15279 > that implementations will agree exactly on their numeric values. 15280 15281 As this range is a subrange (when considered in conjunction with the 15282 number_integer_t type) of the exactly supported range [0, UINT64_MAX], 15283 this class's integer type is interoperable. 15284 15285 #### Storage 15286 15287 Integer number values are stored directly inside a @ref basic_json type. 15288 15289 @sa @ref number_float_t -- type for number values (floating-point) 15290 @sa @ref number_integer_t -- type for number values (integer) 15291 15292 @since version 2.0.0 15293 */ 15294 using number_unsigned_t = NumberUnsignedType; 15295 15296 /*! 15297 @brief a type for a number (floating-point) 15298 15299 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows: 15300 > The representation of numbers is similar to that used in most 15301 > programming languages. A number is represented in base 10 using decimal 15302 > digits. It contains an integer component that may be prefixed with an 15303 > optional minus sign, which may be followed by a fraction part and/or an 15304 > exponent part. Leading zeros are not allowed. (...) Numeric values that 15305 > cannot be represented in the grammar below (such as Infinity and NaN) 15306 > are not permitted. 15307 15308 This description includes both integer and floating-point numbers. 15309 However, C++ allows more precise storage if it is known whether the number 15310 is a signed integer, an unsigned integer or a floating-point number. 15311 Therefore, three different types, @ref number_integer_t, @ref 15312 number_unsigned_t and @ref number_float_t are used. 15313 15314 To store floating-point numbers in C++, a type is defined by the template 15315 parameter @a NumberFloatType which chooses the type to use. 15316 15317 #### Default type 15318 15319 With the default values for @a NumberFloatType (`double`), the default 15320 value for @a number_float_t is: 15321 15322 @code {.cpp} 15323 double 15324 @endcode 15325 15326 #### Default behavior 15327 15328 - The restrictions about leading zeros is not enforced in C++. Instead, 15329 leading zeros in floating-point literals will be ignored. Internally, 15330 the value will be stored as decimal number. For instance, the C++ 15331 floating-point literal `01.2` will be serialized to `1.2`. During 15332 deserialization, leading zeros yield an error. 15333 - Not-a-number (NaN) values will be serialized to `null`. 15334 15335 #### Limits 15336 15337 [RFC 7159](http://rfc7159.net/rfc7159) states: 15338 > This specification allows implementations to set limits on the range and 15339 > precision of numbers accepted. Since software that implements IEEE 15340 > 754-2008 binary64 (double precision) numbers is generally available and 15341 > widely used, good interoperability can be achieved by implementations 15342 > that expect no more precision or range than these provide, in the sense 15343 > that implementations will approximate JSON numbers within the expected 15344 > precision. 15345 15346 This implementation does exactly follow this approach, as it uses double 15347 precision floating-point numbers. Note values smaller than 15348 `-1.79769313486232e+308` and values greater than `1.79769313486232e+308` 15349 will be stored as NaN internally and be serialized to `null`. 15350 15351 #### Storage 15352 15353 Floating-point number values are stored directly inside a @ref basic_json 15354 type. 15355 15356 @sa @ref number_integer_t -- type for number values (integer) 15357 15358 @sa @ref number_unsigned_t -- type for number values (unsigned integer) 15359 15360 @since version 1.0.0 15361 */ 15362 using number_float_t = NumberFloatType; 15363 15364 /// @} 15365 15366 private: 15367 15368 /// helper for exception-safe object creation 15369 template<typename T, typename... Args> 15370 JSON_HEDLEY_RETURNS_NON_NULL 15371 static T* create(Args&& ... args) 15372 { 15373 AllocatorType<T> alloc; 15374 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>; 15375 15376 auto deleter = [&](T * object) 15377 { 15378 AllocatorTraits::deallocate(alloc, object, 1); 15379 }; 15380 std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter); 15381 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...); 15382 assert(object != nullptr); 15383 return object.release(); 15384 } 15385 15386 //////////////////////// 15387 // JSON value storage // 15388 //////////////////////// 15389 15390 /*! 15391 @brief a JSON value 15392 15393 The actual storage for a JSON value of the @ref basic_json class. This 15394 union combines the different storage types for the JSON value types 15395 defined in @ref value_t. 15396 15397 JSON type | value_t type | used type 15398 --------- | --------------- | ------------------------ 15399 object | object | pointer to @ref object_t 15400 array | array | pointer to @ref array_t 15401 string | string | pointer to @ref string_t 15402 boolean | boolean | @ref boolean_t 15403 number | number_integer | @ref number_integer_t 15404 number | number_unsigned | @ref number_unsigned_t 15405 number | number_float | @ref number_float_t 15406 null | null | *no value is stored* 15407 15408 @note Variable-length types (objects, arrays, and strings) are stored as 15409 pointers. The size of the union should not exceed 64 bits if the default 15410 value types are used. 15411 15412 @since version 1.0.0 15413 */ 15414 union json_value 15415 { 15416 /// object (stored with pointer to save storage) 15417 object_t* object; 15418 /// array (stored with pointer to save storage) 15419 array_t* array; 15420 /// string (stored with pointer to save storage) 15421 string_t* string; 15422 /// boolean 15423 boolean_t boolean; 15424 /// number (integer) 15425 number_integer_t number_integer; 15426 /// number (unsigned integer) 15427 number_unsigned_t number_unsigned; 15428 /// number (floating-point) 15429 number_float_t number_float; 15430 15431 /// default constructor (for null values) 15432 json_value() = default; 15433 /// constructor for booleans 15434 json_value(boolean_t v) noexcept : boolean(v) {} 15435 /// constructor for numbers (integer) 15436 json_value(number_integer_t v) noexcept : number_integer(v) {} 15437 /// constructor for numbers (unsigned) 15438 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {} 15439 /// constructor for numbers (floating-point) 15440 json_value(number_float_t v) noexcept : number_float(v) {} 15441 /// constructor for empty values of a given type 15442 json_value(value_t t) 15443 { 15444 switch (t) 15445 { 15446 case value_t::object: 15447 { 15448 object = create<object_t>(); 15449 break; 15450 } 15451 15452 case value_t::array: 15453 { 15454 array = create<array_t>(); 15455 break; 15456 } 15457 15458 case value_t::string: 15459 { 15460 string = create<string_t>(""); 15461 break; 15462 } 15463 15464 case value_t::boolean: 15465 { 15466 boolean = boolean_t(false); 15467 break; 15468 } 15469 15470 case value_t::number_integer: 15471 { 15472 number_integer = number_integer_t(0); 15473 break; 15474 } 15475 15476 case value_t::number_unsigned: 15477 { 15478 number_unsigned = number_unsigned_t(0); 15479 break; 15480 } 15481 15482 case value_t::number_float: 15483 { 15484 number_float = number_float_t(0.0); 15485 break; 15486 } 15487 15488 case value_t::null: 15489 { 15490 object = nullptr; // silence warning, see #821 15491 break; 15492 } 15493 15494 default: 15495 { 15496 object = nullptr; // silence warning, see #821 15497 if (JSON_HEDLEY_UNLIKELY(t == value_t::null)) 15498 { 15499 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.7.3")); // LCOV_EXCL_LINE 15500 } 15501 break; 15502 } 15503 } 15504 } 15505 15506 /// constructor for strings 15507 json_value(const string_t& value) 15508 { 15509 string = create<string_t>(value); 15510 } 15511 15512 /// constructor for rvalue strings 15513 json_value(string_t&& value) 15514 { 15515 string = create<string_t>(std::move(value)); 15516 } 15517 15518 /// constructor for objects 15519 json_value(const object_t& value) 15520 { 15521 object = create<object_t>(value); 15522 } 15523 15524 /// constructor for rvalue objects 15525 json_value(object_t&& value) 15526 { 15527 object = create<object_t>(std::move(value)); 15528 } 15529 15530 /// constructor for arrays 15531 json_value(const array_t& value) 15532 { 15533 array = create<array_t>(value); 15534 } 15535 15536 /// constructor for rvalue arrays 15537 json_value(array_t&& value) 15538 { 15539 array = create<array_t>(std::move(value)); 15540 } 15541 15542 void destroy(value_t t) noexcept 15543 { 15544 // flatten the current json_value to a heap-allocated stack 15545 std::vector<basic_json> stack; 15546 15547 // move the top-level items to stack 15548 if (t == value_t::array) 15549 { 15550 stack.reserve(array->size()); 15551 std::move(array->begin(), array->end(), std::back_inserter(stack)); 15552 } 15553 else if (t == value_t::object) 15554 { 15555 stack.reserve(object->size()); 15556 for (auto&& it : *object) 15557 { 15558 stack.push_back(std::move(it.second)); 15559 } 15560 } 15561 15562 while (not stack.empty()) 15563 { 15564 // move the last item to local variable to be processed 15565 basic_json current_item(std::move(stack.back())); 15566 stack.pop_back(); 15567 15568 // if current_item is array/object, move 15569 // its children to the stack to be processed later 15570 if (current_item.is_array()) 15571 { 15572 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), 15573 std::back_inserter(stack)); 15574 15575 current_item.m_value.array->clear(); 15576 } 15577 else if (current_item.is_object()) 15578 { 15579 for (auto&& it : *current_item.m_value.object) 15580 { 15581 stack.push_back(std::move(it.second)); 15582 } 15583 15584 current_item.m_value.object->clear(); 15585 } 15586 15587 // it's now safe that current_item get destructed 15588 // since it doesn't have any children 15589 } 15590 15591 switch (t) 15592 { 15593 case value_t::object: 15594 { 15595 AllocatorType<object_t> alloc; 15596 std::allocator_traits<decltype(alloc)>::destroy(alloc, object); 15597 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1); 15598 break; 15599 } 15600 15601 case value_t::array: 15602 { 15603 AllocatorType<array_t> alloc; 15604 std::allocator_traits<decltype(alloc)>::destroy(alloc, array); 15605 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1); 15606 break; 15607 } 15608 15609 case value_t::string: 15610 { 15611 AllocatorType<string_t> alloc; 15612 std::allocator_traits<decltype(alloc)>::destroy(alloc, string); 15613 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1); 15614 break; 15615 } 15616 15617 default: 15618 { 15619 break; 15620 } 15621 } 15622 } 15623 }; 15624 15625 /*! 15626 @brief checks the class invariants 15627 15628 This function asserts the class invariants. It needs to be called at the 15629 end of every constructor to make sure that created objects respect the 15630 invariant. Furthermore, it has to be called each time the type of a JSON 15631 value is changed, because the invariant expresses a relationship between 15632 @a m_type and @a m_value. 15633 */ 15634 void assert_invariant() const noexcept 15635 { 15636 assert(m_type != value_t::object or m_value.object != nullptr); 15637 assert(m_type != value_t::array or m_value.array != nullptr); 15638 assert(m_type != value_t::string or m_value.string != nullptr); 15639 } 15640 15641 public: 15642 ////////////////////////// 15643 // JSON parser callback // 15644 ////////////////////////// 15645 15646 /*! 15647 @brief parser event types 15648 15649 The parser callback distinguishes the following events: 15650 - `object_start`: the parser read `{` and started to process a JSON object 15651 - `key`: the parser read a key of a value in an object 15652 - `object_end`: the parser read `}` and finished processing a JSON object 15653 - `array_start`: the parser read `[` and started to process a JSON array 15654 - `array_end`: the parser read `]` and finished processing a JSON array 15655 - `value`: the parser finished reading a JSON value 15656 15657 @image html callback_events.png "Example when certain parse events are triggered" 15658 15659 @sa @ref parser_callback_t for more information and examples 15660 */ 15661 using parse_event_t = typename parser::parse_event_t; 15662 15663 /*! 15664 @brief per-element parser callback type 15665 15666 With a parser callback function, the result of parsing a JSON text can be 15667 influenced. When passed to @ref parse, it is called on certain events 15668 (passed as @ref parse_event_t via parameter @a event) with a set recursion 15669 depth @a depth and context JSON value @a parsed. The return value of the 15670 callback function is a boolean indicating whether the element that emitted 15671 the callback shall be kept or not. 15672 15673 We distinguish six scenarios (determined by the event type) in which the 15674 callback function can be called. The following table describes the values 15675 of the parameters @a depth, @a event, and @a parsed. 15676 15677 parameter @a event | description | parameter @a depth | parameter @a parsed 15678 ------------------ | ----------- | ------------------ | ------------------- 15679 parse_event_t::object_start | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded 15680 parse_event_t::key | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key 15681 parse_event_t::object_end | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object 15682 parse_event_t::array_start | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded 15683 parse_event_t::array_end | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array 15684 parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value 15685 15686 @image html callback_events.png "Example when certain parse events are triggered" 15687 15688 Discarding a value (i.e., returning `false`) has different effects 15689 depending on the context in which function was called: 15690 15691 - Discarded values in structured types are skipped. That is, the parser 15692 will behave as if the discarded value was never read. 15693 - In case a value outside a structured type is skipped, it is replaced 15694 with `null`. This case happens if the top-level element is skipped. 15695 15696 @param[in] depth the depth of the recursion during parsing 15697 15698 @param[in] event an event of type parse_event_t indicating the context in 15699 the callback function has been called 15700 15701 @param[in,out] parsed the current intermediate parse result; note that 15702 writing to this value has no effect for parse_event_t::key events 15703 15704 @return Whether the JSON value which called the function during parsing 15705 should be kept (`true`) or not (`false`). In the latter case, it is either 15706 skipped completely or replaced by an empty discarded object. 15707 15708 @sa @ref parse for examples 15709 15710 @since version 1.0.0 15711 */ 15712 using parser_callback_t = typename parser::parser_callback_t; 15713 15714 ////////////////// 15715 // constructors // 15716 ////////////////// 15717 15718 /// @name constructors and destructors 15719 /// Constructors of class @ref basic_json, copy/move constructor, copy 15720 /// assignment, static functions creating objects, and the destructor. 15721 /// @{ 15722 15723 /*! 15724 @brief create an empty value with a given type 15725 15726 Create an empty JSON value with a given type. The value will be default 15727 initialized with an empty value which depends on the type: 15728 15729 Value type | initial value 15730 ----------- | ------------- 15731 null | `null` 15732 boolean | `false` 15733 string | `""` 15734 number | `0` 15735 object | `{}` 15736 array | `[]` 15737 15738 @param[in] v the type of the value to create 15739 15740 @complexity Constant. 15741 15742 @exceptionsafety Strong guarantee: if an exception is thrown, there are no 15743 changes to any JSON value. 15744 15745 @liveexample{The following code shows the constructor for different @ref 15746 value_t values,basic_json__value_t} 15747 15748 @sa @ref clear() -- restores the postcondition of this constructor 15749 15750 @since version 1.0.0 15751 */ 15752 basic_json(const value_t v) 15753 : m_type(v), m_value(v) 15754 { 15755 assert_invariant(); 15756 } 15757 15758 /*! 15759 @brief create a null object 15760 15761 Create a `null` JSON value. It either takes a null pointer as parameter 15762 (explicitly creating `null`) or no parameter (implicitly creating `null`). 15763 The passed null pointer itself is not read -- it is only used to choose 15764 the right constructor. 15765 15766 @complexity Constant. 15767 15768 @exceptionsafety No-throw guarantee: this constructor never throws 15769 exceptions. 15770 15771 @liveexample{The following code shows the constructor with and without a 15772 null pointer parameter.,basic_json__nullptr_t} 15773 15774 @since version 1.0.0 15775 */ 15776 basic_json(std::nullptr_t = nullptr) noexcept 15777 : basic_json(value_t::null) 15778 { 15779 assert_invariant(); 15780 } 15781 15782 /*! 15783 @brief create a JSON value 15784 15785 This is a "catch all" constructor for all compatible JSON types; that is, 15786 types for which a `to_json()` method exists. The constructor forwards the 15787 parameter @a val to that method (to `json_serializer<U>::to_json` method 15788 with `U = uncvref_t<CompatibleType>`, to be exact). 15789 15790 Template type @a CompatibleType includes, but is not limited to, the 15791 following types: 15792 - **arrays**: @ref array_t and all kinds of compatible containers such as 15793 `std::vector`, `std::deque`, `std::list`, `std::forward_list`, 15794 `std::array`, `std::valarray`, `std::set`, `std::unordered_set`, 15795 `std::multiset`, and `std::unordered_multiset` with a `value_type` from 15796 which a @ref basic_json value can be constructed. 15797 - **objects**: @ref object_t and all kinds of compatible associative 15798 containers such as `std::map`, `std::unordered_map`, `std::multimap`, 15799 and `std::unordered_multimap` with a `key_type` compatible to 15800 @ref string_t and a `value_type` from which a @ref basic_json value can 15801 be constructed. 15802 - **strings**: @ref string_t, string literals, and all compatible string 15803 containers can be used. 15804 - **numbers**: @ref number_integer_t, @ref number_unsigned_t, 15805 @ref number_float_t, and all convertible number types such as `int`, 15806 `size_t`, `int64_t`, `float` or `double` can be used. 15807 - **boolean**: @ref boolean_t / `bool` can be used. 15808 15809 See the examples below. 15810 15811 @tparam CompatibleType a type such that: 15812 - @a CompatibleType is not derived from `std::istream`, 15813 - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move 15814 constructors), 15815 - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments) 15816 - @a CompatibleType is not a @ref basic_json nested type (e.g., 15817 @ref json_pointer, @ref iterator, etc ...) 15818 - @ref @ref json_serializer<U> has a 15819 `to_json(basic_json_t&, CompatibleType&&)` method 15820 15821 @tparam U = `uncvref_t<CompatibleType>` 15822 15823 @param[in] val the value to be forwarded to the respective constructor 15824 15825 @complexity Usually linear in the size of the passed @a val, also 15826 depending on the implementation of the called `to_json()` 15827 method. 15828 15829 @exceptionsafety Depends on the called constructor. For types directly 15830 supported by the library (i.e., all types for which no `to_json()` function 15831 was provided), strong guarantee holds: if an exception is thrown, there are 15832 no changes to any JSON value. 15833 15834 @liveexample{The following code shows the constructor with several 15835 compatible types.,basic_json__CompatibleType} 15836 15837 @since version 2.1.0 15838 */ 15839 template <typename CompatibleType, 15840 typename U = detail::uncvref_t<CompatibleType>, 15841 detail::enable_if_t< 15842 not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value, int> = 0> 15843 basic_json(CompatibleType && val) noexcept(noexcept( 15844 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(), 15845 std::forward<CompatibleType>(val)))) 15846 { 15847 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val)); 15848 assert_invariant(); 15849 } 15850 15851 /*! 15852 @brief create a JSON value from an existing one 15853 15854 This is a constructor for existing @ref basic_json types. 15855 It does not hijack copy/move constructors, since the parameter has different 15856 template arguments than the current ones. 15857 15858 The constructor tries to convert the internal @ref m_value of the parameter. 15859 15860 @tparam BasicJsonType a type such that: 15861 - @a BasicJsonType is a @ref basic_json type. 15862 - @a BasicJsonType has different template arguments than @ref basic_json_t. 15863 15864 @param[in] val the @ref basic_json value to be converted. 15865 15866 @complexity Usually linear in the size of the passed @a val, also 15867 depending on the implementation of the called `to_json()` 15868 method. 15869 15870 @exceptionsafety Depends on the called constructor. For types directly 15871 supported by the library (i.e., all types for which no `to_json()` function 15872 was provided), strong guarantee holds: if an exception is thrown, there are 15873 no changes to any JSON value. 15874 15875 @since version 3.2.0 15876 */ 15877 template <typename BasicJsonType, 15878 detail::enable_if_t< 15879 detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0> 15880 basic_json(const BasicJsonType& val) 15881 { 15882 using other_boolean_t = typename BasicJsonType::boolean_t; 15883 using other_number_float_t = typename BasicJsonType::number_float_t; 15884 using other_number_integer_t = typename BasicJsonType::number_integer_t; 15885 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t; 15886 using other_string_t = typename BasicJsonType::string_t; 15887 using other_object_t = typename BasicJsonType::object_t; 15888 using other_array_t = typename BasicJsonType::array_t; 15889 15890 switch (val.type()) 15891 { 15892 case value_t::boolean: 15893 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>()); 15894 break; 15895 case value_t::number_float: 15896 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>()); 15897 break; 15898 case value_t::number_integer: 15899 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>()); 15900 break; 15901 case value_t::number_unsigned: 15902 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>()); 15903 break; 15904 case value_t::string: 15905 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>()); 15906 break; 15907 case value_t::object: 15908 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>()); 15909 break; 15910 case value_t::array: 15911 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>()); 15912 break; 15913 case value_t::null: 15914 *this = nullptr; 15915 break; 15916 case value_t::discarded: 15917 m_type = value_t::discarded; 15918 break; 15919 default: // LCOV_EXCL_LINE 15920 assert(false); // LCOV_EXCL_LINE 15921 } 15922 assert_invariant(); 15923 } 15924 15925 /*! 15926 @brief create a container (array or object) from an initializer list 15927 15928 Creates a JSON value of type array or object from the passed initializer 15929 list @a init. In case @a type_deduction is `true` (default), the type of 15930 the JSON value to be created is deducted from the initializer list @a init 15931 according to the following rules: 15932 15933 1. If the list is empty, an empty JSON object value `{}` is created. 15934 2. If the list consists of pairs whose first element is a string, a JSON 15935 object value is created where the first elements of the pairs are 15936 treated as keys and the second elements are as values. 15937 3. In all other cases, an array is created. 15938 15939 The rules aim to create the best fit between a C++ initializer list and 15940 JSON values. The rationale is as follows: 15941 15942 1. The empty initializer list is written as `{}` which is exactly an empty 15943 JSON object. 15944 2. C++ has no way of describing mapped types other than to list a list of 15945 pairs. As JSON requires that keys must be of type string, rule 2 is the 15946 weakest constraint one can pose on initializer lists to interpret them 15947 as an object. 15948 3. In all other cases, the initializer list could not be interpreted as 15949 JSON object type, so interpreting it as JSON array type is safe. 15950 15951 With the rules described above, the following JSON values cannot be 15952 expressed by an initializer list: 15953 15954 - the empty array (`[]`): use @ref array(initializer_list_t) 15955 with an empty initializer list in this case 15956 - arrays whose elements satisfy rule 2: use @ref 15957 array(initializer_list_t) with the same initializer list 15958 in this case 15959 15960 @note When used without parentheses around an empty initializer list, @ref 15961 basic_json() is called instead of this function, yielding the JSON null 15962 value. 15963 15964 @param[in] init initializer list with JSON values 15965 15966 @param[in] type_deduction internal parameter; when set to `true`, the type 15967 of the JSON value is deducted from the initializer list @a init; when set 15968 to `false`, the type provided via @a manual_type is forced. This mode is 15969 used by the functions @ref array(initializer_list_t) and 15970 @ref object(initializer_list_t). 15971 15972 @param[in] manual_type internal parameter; when @a type_deduction is set 15973 to `false`, the created JSON value will use the provided type (only @ref 15974 value_t::array and @ref value_t::object are valid); when @a type_deduction 15975 is set to `true`, this parameter has no effect 15976 15977 @throw type_error.301 if @a type_deduction is `false`, @a manual_type is 15978 `value_t::object`, but @a init contains an element which is not a pair 15979 whose first element is a string. In this case, the constructor could not 15980 create an object. If @a type_deduction would have be `true`, an array 15981 would have been created. See @ref object(initializer_list_t) 15982 for an example. 15983 15984 @complexity Linear in the size of the initializer list @a init. 15985 15986 @exceptionsafety Strong guarantee: if an exception is thrown, there are no 15987 changes to any JSON value. 15988 15989 @liveexample{The example below shows how JSON values are created from 15990 initializer lists.,basic_json__list_init_t} 15991 15992 @sa @ref array(initializer_list_t) -- create a JSON array 15993 value from an initializer list 15994 @sa @ref object(initializer_list_t) -- create a JSON object 15995 value from an initializer list 15996 15997 @since version 1.0.0 15998 */ 15999 basic_json(initializer_list_t init, 16000 bool type_deduction = true, 16001 value_t manual_type = value_t::array) 16002 { 16003 // check if each element is an array with two elements whose first 16004 // element is a string 16005 bool is_an_object = std::all_of(init.begin(), init.end(), 16006 [](const detail::json_ref<basic_json>& element_ref) 16007 { 16008 return element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string(); 16009 }); 16010 16011 // adjust type if type deduction is not wanted 16012 if (not type_deduction) 16013 { 16014 // if array is wanted, do not create an object though possible 16015 if (manual_type == value_t::array) 16016 { 16017 is_an_object = false; 16018 } 16019 16020 // if object is wanted but impossible, throw an exception 16021 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object and not is_an_object)) 16022 { 16023 JSON_THROW(type_error::create(301, "cannot create object from initializer list")); 16024 } 16025 } 16026 16027 if (is_an_object) 16028 { 16029 // the initializer list is a list of pairs -> create object 16030 m_type = value_t::object; 16031 m_value = value_t::object; 16032 16033 std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref) 16034 { 16035 auto element = element_ref.moved_or_copied(); 16036 m_value.object->emplace( 16037 std::move(*((*element.m_value.array)[0].m_value.string)), 16038 std::move((*element.m_value.array)[1])); 16039 }); 16040 } 16041 else 16042 { 16043 // the initializer list describes an array -> create array 16044 m_type = value_t::array; 16045 m_value.array = create<array_t>(init.begin(), init.end()); 16046 } 16047 16048 assert_invariant(); 16049 } 16050 16051 /*! 16052 @brief explicitly create an array from an initializer list 16053 16054 Creates a JSON array value from a given initializer list. That is, given a 16055 list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the 16056 initializer list is empty, the empty array `[]` is created. 16057 16058 @note This function is only needed to express two edge cases that cannot 16059 be realized with the initializer list constructor (@ref 16060 basic_json(initializer_list_t, bool, value_t)). These cases 16061 are: 16062 1. creating an array whose elements are all pairs whose first element is a 16063 string -- in this case, the initializer list constructor would create an 16064 object, taking the first elements as keys 16065 2. creating an empty array -- passing the empty initializer list to the 16066 initializer list constructor yields an empty object 16067 16068 @param[in] init initializer list with JSON values to create an array from 16069 (optional) 16070 16071 @return JSON array value 16072 16073 @complexity Linear in the size of @a init. 16074 16075 @exceptionsafety Strong guarantee: if an exception is thrown, there are no 16076 changes to any JSON value. 16077 16078 @liveexample{The following code shows an example for the `array` 16079 function.,array} 16080 16081 @sa @ref basic_json(initializer_list_t, bool, value_t) -- 16082 create a JSON value from an initializer list 16083 @sa @ref object(initializer_list_t) -- create a JSON object 16084 value from an initializer list 16085 16086 @since version 1.0.0 16087 */ 16088 JSON_HEDLEY_WARN_UNUSED_RESULT 16089 static basic_json array(initializer_list_t init = {}) 16090 { 16091 return basic_json(init, false, value_t::array); 16092 } 16093 16094 /*! 16095 @brief explicitly create an object from an initializer list 16096 16097 Creates a JSON object value from a given initializer list. The initializer 16098 lists elements must be pairs, and their first elements must be strings. If 16099 the initializer list is empty, the empty object `{}` is created. 16100 16101 @note This function is only added for symmetry reasons. In contrast to the 16102 related function @ref array(initializer_list_t), there are 16103 no cases which can only be expressed by this function. That is, any 16104 initializer list @a init can also be passed to the initializer list 16105 constructor @ref basic_json(initializer_list_t, bool, value_t). 16106 16107 @param[in] init initializer list to create an object from (optional) 16108 16109 @return JSON object value 16110 16111 @throw type_error.301 if @a init is not a list of pairs whose first 16112 elements are strings. In this case, no object can be created. When such a 16113 value is passed to @ref basic_json(initializer_list_t, bool, value_t), 16114 an array would have been created from the passed initializer list @a init. 16115 See example below. 16116 16117 @complexity Linear in the size of @a init. 16118 16119 @exceptionsafety Strong guarantee: if an exception is thrown, there are no 16120 changes to any JSON value. 16121 16122 @liveexample{The following code shows an example for the `object` 16123 function.,object} 16124 16125 @sa @ref basic_json(initializer_list_t, bool, value_t) -- 16126 create a JSON value from an initializer list 16127 @sa @ref array(initializer_list_t) -- create a JSON array 16128 value from an initializer list 16129 16130 @since version 1.0.0 16131 */ 16132 JSON_HEDLEY_WARN_UNUSED_RESULT 16133 static basic_json object(initializer_list_t init = {}) 16134 { 16135 return basic_json(init, false, value_t::object); 16136 } 16137 16138 /*! 16139 @brief construct an array with count copies of given value 16140 16141 Constructs a JSON array value by creating @a cnt copies of a passed value. 16142 In case @a cnt is `0`, an empty array is created. 16143 16144 @param[in] cnt the number of JSON copies of @a val to create 16145 @param[in] val the JSON value to copy 16146 16147 @post `std::distance(begin(),end()) == cnt` holds. 16148 16149 @complexity Linear in @a cnt. 16150 16151 @exceptionsafety Strong guarantee: if an exception is thrown, there are no 16152 changes to any JSON value. 16153 16154 @liveexample{The following code shows examples for the @ref 16155 basic_json(size_type\, const basic_json&) 16156 constructor.,basic_json__size_type_basic_json} 16157 16158 @since version 1.0.0 16159 */ 16160 basic_json(size_type cnt, const basic_json& val) 16161 : m_type(value_t::array) 16162 { 16163 m_value.array = create<array_t>(cnt, val); 16164 assert_invariant(); 16165 } 16166 16167 /*! 16168 @brief construct a JSON container given an iterator range 16169 16170 Constructs the JSON value with the contents of the range `[first, last)`. 16171 The semantics depends on the different types a JSON value can have: 16172 - In case of a null type, invalid_iterator.206 is thrown. 16173 - In case of other primitive types (number, boolean, or string), @a first 16174 must be `begin()` and @a last must be `end()`. In this case, the value is 16175 copied. Otherwise, invalid_iterator.204 is thrown. 16176 - In case of structured types (array, object), the constructor behaves as 16177 similar versions for `std::vector` or `std::map`; that is, a JSON array 16178 or object is constructed from the values in the range. 16179 16180 @tparam InputIT an input iterator type (@ref iterator or @ref 16181 const_iterator) 16182 16183 @param[in] first begin of the range to copy from (included) 16184 @param[in] last end of the range to copy from (excluded) 16185 16186 @pre Iterators @a first and @a last must be initialized. **This 16187 precondition is enforced with an assertion (see warning).** If 16188 assertions are switched off, a violation of this precondition yields 16189 undefined behavior. 16190 16191 @pre Range `[first, last)` is valid. Usually, this precondition cannot be 16192 checked efficiently. Only certain edge cases are detected; see the 16193 description of the exceptions below. A violation of this precondition 16194 yields undefined behavior. 16195 16196 @warning A precondition is enforced with a runtime assertion that will 16197 result in calling `std::abort` if this precondition is not met. 16198 Assertions can be disabled by defining `NDEBUG` at compile time. 16199 See https://en.cppreference.com/w/cpp/error/assert for more 16200 information. 16201 16202 @throw invalid_iterator.201 if iterators @a first and @a last are not 16203 compatible (i.e., do not belong to the same JSON value). In this case, 16204 the range `[first, last)` is undefined. 16205 @throw invalid_iterator.204 if iterators @a first and @a last belong to a 16206 primitive type (number, boolean, or string), but @a first does not point 16207 to the first element any more. In this case, the range `[first, last)` is 16208 undefined. See example code below. 16209 @throw invalid_iterator.206 if iterators @a first and @a last belong to a 16210 null value. In this case, the range `[first, last)` is undefined. 16211 16212 @complexity Linear in distance between @a first and @a last. 16213 16214 @exceptionsafety Strong guarantee: if an exception is thrown, there are no 16215 changes to any JSON value. 16216 16217 @liveexample{The example below shows several ways to create JSON values by 16218 specifying a subrange with iterators.,basic_json__InputIt_InputIt} 16219 16220 @since version 1.0.0 16221 */ 16222 template<class InputIT, typename std::enable_if< 16223 std::is_same<InputIT, typename basic_json_t::iterator>::value or 16224 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0> 16225 basic_json(InputIT first, InputIT last) 16226 { 16227 assert(first.m_object != nullptr); 16228 assert(last.m_object != nullptr); 16229 16230 // make sure iterator fits the current value 16231 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) 16232 { 16233 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible")); 16234 } 16235 16236 // copy type from first iterator 16237 m_type = first.m_object->m_type; 16238 16239 // check if iterator range is complete for primitive values 16240 switch (m_type) 16241 { 16242 case value_t::boolean: 16243 case value_t::number_float: 16244 case value_t::number_integer: 16245 case value_t::number_unsigned: 16246 case value_t::string: 16247 { 16248 if (JSON_HEDLEY_UNLIKELY(not first.m_it.primitive_iterator.is_begin() 16249 or not last.m_it.primitive_iterator.is_end())) 16250 { 16251 JSON_THROW(invalid_iterator::create(204, "iterators out of range")); 16252 } 16253 break; 16254 } 16255 16256 default: 16257 break; 16258 } 16259 16260 switch (m_type) 16261 { 16262 case value_t::number_integer: 16263 { 16264 m_value.number_integer = first.m_object->m_value.number_integer; 16265 break; 16266 } 16267 16268 case value_t::number_unsigned: 16269 { 16270 m_value.number_unsigned = first.m_object->m_value.number_unsigned; 16271 break; 16272 } 16273 16274 case value_t::number_float: 16275 { 16276 m_value.number_float = first.m_object->m_value.number_float; 16277 break; 16278 } 16279 16280 case value_t::boolean: 16281 { 16282 m_value.boolean = first.m_object->m_value.boolean; 16283 break; 16284 } 16285 16286 case value_t::string: 16287 { 16288 m_value = *first.m_object->m_value.string; 16289 break; 16290 } 16291 16292 case value_t::object: 16293 { 16294 m_value.object = create<object_t>(first.m_it.object_iterator, 16295 last.m_it.object_iterator); 16296 break; 16297 } 16298 16299 case value_t::array: 16300 { 16301 m_value.array = create<array_t>(first.m_it.array_iterator, 16302 last.m_it.array_iterator); 16303 break; 16304 } 16305 16306 default: 16307 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + 16308 std::string(first.m_object->type_name()))); 16309 } 16310 16311 assert_invariant(); 16312 } 16313 16314 16315 /////////////////////////////////////// 16316 // other constructors and destructor // 16317 /////////////////////////////////////// 16318 16319 /// @private 16320 basic_json(const detail::json_ref<basic_json>& ref) 16321 : basic_json(ref.moved_or_copied()) 16322 {} 16323 16324 /*! 16325 @brief copy constructor 16326 16327 Creates a copy of a given JSON value. 16328 16329 @param[in] other the JSON value to copy 16330 16331 @post `*this == other` 16332 16333 @complexity Linear in the size of @a other. 16334 16335 @exceptionsafety Strong guarantee: if an exception is thrown, there are no 16336 changes to any JSON value. 16337 16338 @requirement This function helps `basic_json` satisfying the 16339 [Container](https://en.cppreference.com/w/cpp/named_req/Container) 16340 requirements: 16341 - The complexity is linear. 16342 - As postcondition, it holds: `other == basic_json(other)`. 16343 16344 @liveexample{The following code shows an example for the copy 16345 constructor.,basic_json__basic_json} 16346 16347 @since version 1.0.0 16348 */ 16349 basic_json(const basic_json& other) 16350 : m_type(other.m_type) 16351 { 16352 // check of passed value is valid 16353 other.assert_invariant(); 16354 16355 switch (m_type) 16356 { 16357 case value_t::object: 16358 { 16359 m_value = *other.m_value.object; 16360 break; 16361 } 16362 16363 case value_t::array: 16364 { 16365 m_value = *other.m_value.array; 16366 break; 16367 } 16368 16369 case value_t::string: 16370 { 16371 m_value = *other.m_value.string; 16372 break; 16373 } 16374 16375 case value_t::boolean: 16376 { 16377 m_value = other.m_value.boolean; 16378 break; 16379 } 16380 16381 case value_t::number_integer: 16382 { 16383 m_value = other.m_value.number_integer; 16384 break; 16385 } 16386 16387 case value_t::number_unsigned: 16388 { 16389 m_value = other.m_value.number_unsigned; 16390 break; 16391 } 16392 16393 case value_t::number_float: 16394 { 16395 m_value = other.m_value.number_float; 16396 break; 16397 } 16398 16399 default: 16400 break; 16401 } 16402 16403 assert_invariant(); 16404 } 16405 16406 /*! 16407 @brief move constructor 16408 16409 Move constructor. Constructs a JSON value with the contents of the given 16410 value @a other using move semantics. It "steals" the resources from @a 16411 other and leaves it as JSON null value. 16412 16413 @param[in,out] other value to move to this object 16414 16415 @post `*this` has the same value as @a other before the call. 16416 @post @a other is a JSON null value. 16417 16418 @complexity Constant. 16419 16420 @exceptionsafety No-throw guarantee: this constructor never throws 16421 exceptions. 16422 16423 @requirement This function helps `basic_json` satisfying the 16424 [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible) 16425 requirements. 16426 16427 @liveexample{The code below shows the move constructor explicitly called 16428 via std::move.,basic_json__moveconstructor} 16429 16430 @since version 1.0.0 16431 */ 16432 basic_json(basic_json&& other) noexcept 16433 : m_type(std::move(other.m_type)), 16434 m_value(std::move(other.m_value)) 16435 { 16436 // check that passed value is valid 16437 other.assert_invariant(); 16438 16439 // invalidate payload 16440 other.m_type = value_t::null; 16441 other.m_value = {}; 16442 16443 assert_invariant(); 16444 } 16445 16446 /*! 16447 @brief copy assignment 16448 16449 Copy assignment operator. Copies a JSON value via the "copy and swap" 16450 strategy: It is expressed in terms of the copy constructor, destructor, 16451 and the `swap()` member function. 16452 16453 @param[in] other value to copy from 16454 16455 @complexity Linear. 16456 16457 @requirement This function helps `basic_json` satisfying the 16458 [Container](https://en.cppreference.com/w/cpp/named_req/Container) 16459 requirements: 16460 - The complexity is linear. 16461 16462 @liveexample{The code below shows and example for the copy assignment. It 16463 creates a copy of value `a` which is then swapped with `b`. Finally\, the 16464 copy of `a` (which is the null value after the swap) is 16465 destroyed.,basic_json__copyassignment} 16466 16467 @since version 1.0.0 16468 */ 16469 basic_json& operator=(basic_json other) noexcept ( 16470 std::is_nothrow_move_constructible<value_t>::value and 16471 std::is_nothrow_move_assignable<value_t>::value and 16472 std::is_nothrow_move_constructible<json_value>::value and 16473 std::is_nothrow_move_assignable<json_value>::value 16474 ) 16475 { 16476 // check that passed value is valid 16477 other.assert_invariant(); 16478 16479 using std::swap; 16480 swap(m_type, other.m_type); 16481 swap(m_value, other.m_value); 16482 16483 assert_invariant(); 16484 return *this; 16485 } 16486 16487 /*! 16488 @brief destructor 16489 16490 Destroys the JSON value and frees all allocated memory. 16491 16492 @complexity Linear. 16493 16494 @requirement This function helps `basic_json` satisfying the 16495 [Container](https://en.cppreference.com/w/cpp/named_req/Container) 16496 requirements: 16497 - The complexity is linear. 16498 - All stored elements are destroyed and all memory is freed. 16499 16500 @since version 1.0.0 16501 */ 16502 ~basic_json() noexcept 16503 { 16504 assert_invariant(); 16505 m_value.destroy(m_type); 16506 } 16507 16508 /// @} 16509 16510 public: 16511 /////////////////////// 16512 // object inspection // 16513 /////////////////////// 16514 16515 /// @name object inspection 16516 /// Functions to inspect the type of a JSON value. 16517 /// @{ 16518 16519 /*! 16520 @brief serialization 16521 16522 Serialization function for JSON values. The function tries to mimic 16523 Python's `json.dumps()` function, and currently supports its @a indent 16524 and @a ensure_ascii parameters. 16525 16526 @param[in] indent If indent is nonnegative, then array elements and object 16527 members will be pretty-printed with that indent level. An indent level of 16528 `0` will only insert newlines. `-1` (the default) selects the most compact 16529 representation. 16530 @param[in] indent_char The character to use for indentation if @a indent is 16531 greater than `0`. The default is ` ` (space). 16532 @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters 16533 in the output are escaped with `\uXXXX` sequences, and the result consists 16534 of ASCII characters only. 16535 @param[in] error_handler how to react on decoding errors; there are three 16536 possible values: `strict` (throws and exception in case a decoding error 16537 occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD), 16538 and `ignore` (ignore invalid UTF-8 sequences during serialization). 16539 16540 @return string containing the serialization of the JSON value 16541 16542 @throw type_error.316 if a string stored inside the JSON value is not 16543 UTF-8 encoded 16544 16545 @complexity Linear. 16546 16547 @exceptionsafety Strong guarantee: if an exception is thrown, there are no 16548 changes in the JSON value. 16549 16550 @liveexample{The following example shows the effect of different @a indent\, 16551 @a indent_char\, and @a ensure_ascii parameters to the result of the 16552 serialization.,dump} 16553 16554 @see https://docs.python.org/2/library/json.html#json.dump 16555 16556 @since version 1.0.0; indentation character @a indent_char, option 16557 @a ensure_ascii and exceptions added in version 3.0.0; error 16558 handlers added in version 3.4.0. 16559 */ 16560 string_t dump(const int indent = -1, 16561 const char indent_char = ' ', 16562 const bool ensure_ascii = false, 16563 const error_handler_t error_handler = error_handler_t::strict) const 16564 { 16565 string_t result; 16566 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler); 16567 16568 if (indent >= 0) 16569 { 16570 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent)); 16571 } 16572 else 16573 { 16574 s.dump(*this, false, ensure_ascii, 0); 16575 } 16576 16577 return result; 16578 } 16579 16580 /*! 16581 @brief return the type of the JSON value (explicit) 16582 16583 Return the type of the JSON value as a value from the @ref value_t 16584 enumeration. 16585 16586 @return the type of the JSON value 16587 Value type | return value 16588 ------------------------- | ------------------------- 16589 null | value_t::null 16590 boolean | value_t::boolean 16591 string | value_t::string 16592 number (integer) | value_t::number_integer 16593 number (unsigned integer) | value_t::number_unsigned 16594 number (floating-point) | value_t::number_float 16595 object | value_t::object 16596 array | value_t::array 16597 discarded | value_t::discarded 16598 16599 @complexity Constant. 16600 16601 @exceptionsafety No-throw guarantee: this member function never throws 16602 exceptions. 16603 16604 @liveexample{The following code exemplifies `type()` for all JSON 16605 types.,type} 16606 16607 @sa @ref operator value_t() -- return the type of the JSON value (implicit) 16608 @sa @ref type_name() -- return the type as string 16609 16610 @since version 1.0.0 16611 */ 16612 constexpr value_t type() const noexcept 16613 { 16614 return m_type; 16615 } 16616 16617 /*! 16618 @brief return whether type is primitive 16619 16620 This function returns true if and only if the JSON type is primitive 16621 (string, number, boolean, or null). 16622 16623 @return `true` if type is primitive (string, number, boolean, or null), 16624 `false` otherwise. 16625 16626 @complexity Constant. 16627 16628 @exceptionsafety No-throw guarantee: this member function never throws 16629 exceptions. 16630 16631 @liveexample{The following code exemplifies `is_primitive()` for all JSON 16632 types.,is_primitive} 16633 16634 @sa @ref is_structured() -- returns whether JSON value is structured 16635 @sa @ref is_null() -- returns whether JSON value is `null` 16636 @sa @ref is_string() -- returns whether JSON value is a string 16637 @sa @ref is_boolean() -- returns whether JSON value is a boolean 16638 @sa @ref is_number() -- returns whether JSON value is a number 16639 16640 @since version 1.0.0 16641 */ 16642 constexpr bool is_primitive() const noexcept 16643 { 16644 return is_null() or is_string() or is_boolean() or is_number(); 16645 } 16646 16647 /*! 16648 @brief return whether type is structured 16649 16650 This function returns true if and only if the JSON type is structured 16651 (array or object). 16652 16653 @return `true` if type is structured (array or object), `false` otherwise. 16654 16655 @complexity Constant. 16656 16657 @exceptionsafety No-throw guarantee: this member function never throws 16658 exceptions. 16659 16660 @liveexample{The following code exemplifies `is_structured()` for all JSON 16661 types.,is_structured} 16662 16663 @sa @ref is_primitive() -- returns whether value is primitive 16664 @sa @ref is_array() -- returns whether value is an array 16665 @sa @ref is_object() -- returns whether value is an object 16666 16667 @since version 1.0.0 16668 */ 16669 constexpr bool is_structured() const noexcept 16670 { 16671 return is_array() or is_object(); 16672 } 16673 16674 /*! 16675 @brief return whether value is null 16676 16677 This function returns true if and only if the JSON value is null. 16678 16679 @return `true` if type is null, `false` otherwise. 16680 16681 @complexity Constant. 16682 16683 @exceptionsafety No-throw guarantee: this member function never throws 16684 exceptions. 16685 16686 @liveexample{The following code exemplifies `is_null()` for all JSON 16687 types.,is_null} 16688 16689 @since version 1.0.0 16690 */ 16691 constexpr bool is_null() const noexcept 16692 { 16693 return m_type == value_t::null; 16694 } 16695 16696 /*! 16697 @brief return whether value is a boolean 16698 16699 This function returns true if and only if the JSON value is a boolean. 16700 16701 @return `true` if type is boolean, `false` otherwise. 16702 16703 @complexity Constant. 16704 16705 @exceptionsafety No-throw guarantee: this member function never throws 16706 exceptions. 16707 16708 @liveexample{The following code exemplifies `is_boolean()` for all JSON 16709 types.,is_boolean} 16710 16711 @since version 1.0.0 16712 */ 16713 constexpr bool is_boolean() const noexcept 16714 { 16715 return m_type == value_t::boolean; 16716 } 16717 16718 /*! 16719 @brief return whether value is a number 16720 16721 This function returns true if and only if the JSON value is a number. This 16722 includes both integer (signed and unsigned) and floating-point values. 16723 16724 @return `true` if type is number (regardless whether integer, unsigned 16725 integer or floating-type), `false` otherwise. 16726 16727 @complexity Constant. 16728 16729 @exceptionsafety No-throw guarantee: this member function never throws 16730 exceptions. 16731 16732 @liveexample{The following code exemplifies `is_number()` for all JSON 16733 types.,is_number} 16734 16735 @sa @ref is_number_integer() -- check if value is an integer or unsigned 16736 integer number 16737 @sa @ref is_number_unsigned() -- check if value is an unsigned integer 16738 number 16739 @sa @ref is_number_float() -- check if value is a floating-point number 16740 16741 @since version 1.0.0 16742 */ 16743 constexpr bool is_number() const noexcept 16744 { 16745 return is_number_integer() or is_number_float(); 16746 } 16747 16748 /*! 16749 @brief return whether value is an integer number 16750 16751 This function returns true if and only if the JSON value is a signed or 16752 unsigned integer number. This excludes floating-point values. 16753 16754 @return `true` if type is an integer or unsigned integer number, `false` 16755 otherwise. 16756 16757 @complexity Constant. 16758 16759 @exceptionsafety No-throw guarantee: this member function never throws 16760 exceptions. 16761 16762 @liveexample{The following code exemplifies `is_number_integer()` for all 16763 JSON types.,is_number_integer} 16764 16765 @sa @ref is_number() -- check if value is a number 16766 @sa @ref is_number_unsigned() -- check if value is an unsigned integer 16767 number 16768 @sa @ref is_number_float() -- check if value is a floating-point number 16769 16770 @since version 1.0.0 16771 */ 16772 constexpr bool is_number_integer() const noexcept 16773 { 16774 return m_type == value_t::number_integer or m_type == value_t::number_unsigned; 16775 } 16776 16777 /*! 16778 @brief return whether value is an unsigned integer number 16779 16780 This function returns true if and only if the JSON value is an unsigned 16781 integer number. This excludes floating-point and signed integer values. 16782 16783 @return `true` if type is an unsigned integer number, `false` otherwise. 16784 16785 @complexity Constant. 16786 16787 @exceptionsafety No-throw guarantee: this member function never throws 16788 exceptions. 16789 16790 @liveexample{The following code exemplifies `is_number_unsigned()` for all 16791 JSON types.,is_number_unsigned} 16792 16793 @sa @ref is_number() -- check if value is a number 16794 @sa @ref is_number_integer() -- check if value is an integer or unsigned 16795 integer number 16796 @sa @ref is_number_float() -- check if value is a floating-point number 16797 16798 @since version 2.0.0 16799 */ 16800 constexpr bool is_number_unsigned() const noexcept 16801 { 16802 return m_type == value_t::number_unsigned; 16803 } 16804 16805 /*! 16806 @brief return whether value is a floating-point number 16807 16808 This function returns true if and only if the JSON value is a 16809 floating-point number. This excludes signed and unsigned integer values. 16810 16811 @return `true` if type is a floating-point number, `false` otherwise. 16812 16813 @complexity Constant. 16814 16815 @exceptionsafety No-throw guarantee: this member function never throws 16816 exceptions. 16817 16818 @liveexample{The following code exemplifies `is_number_float()` for all 16819 JSON types.,is_number_float} 16820 16821 @sa @ref is_number() -- check if value is number 16822 @sa @ref is_number_integer() -- check if value is an integer number 16823 @sa @ref is_number_unsigned() -- check if value is an unsigned integer 16824 number 16825 16826 @since version 1.0.0 16827 */ 16828 constexpr bool is_number_float() const noexcept 16829 { 16830 return m_type == value_t::number_float; 16831 } 16832 16833 /*! 16834 @brief return whether value is an object 16835 16836 This function returns true if and only if the JSON value is an object. 16837 16838 @return `true` if type is object, `false` otherwise. 16839 16840 @complexity Constant. 16841 16842 @exceptionsafety No-throw guarantee: this member function never throws 16843 exceptions. 16844 16845 @liveexample{The following code exemplifies `is_object()` for all JSON 16846 types.,is_object} 16847 16848 @since version 1.0.0 16849 */ 16850 constexpr bool is_object() const noexcept 16851 { 16852 return m_type == value_t::object; 16853 } 16854 16855 /*! 16856 @brief return whether value is an array 16857 16858 This function returns true if and only if the JSON value is an array. 16859 16860 @return `true` if type is array, `false` otherwise. 16861 16862 @complexity Constant. 16863 16864 @exceptionsafety No-throw guarantee: this member function never throws 16865 exceptions. 16866 16867 @liveexample{The following code exemplifies `is_array()` for all JSON 16868 types.,is_array} 16869 16870 @since version 1.0.0 16871 */ 16872 constexpr bool is_array() const noexcept 16873 { 16874 return m_type == value_t::array; 16875 } 16876 16877 /*! 16878 @brief return whether value is a string 16879 16880 This function returns true if and only if the JSON value is a string. 16881 16882 @return `true` if type is string, `false` otherwise. 16883 16884 @complexity Constant. 16885 16886 @exceptionsafety No-throw guarantee: this member function never throws 16887 exceptions. 16888 16889 @liveexample{The following code exemplifies `is_string()` for all JSON 16890 types.,is_string} 16891 16892 @since version 1.0.0 16893 */ 16894 constexpr bool is_string() const noexcept 16895 { 16896 return m_type == value_t::string; 16897 } 16898 16899 /*! 16900 @brief return whether value is discarded 16901 16902 This function returns true if and only if the JSON value was discarded 16903 during parsing with a callback function (see @ref parser_callback_t). 16904 16905 @note This function will always be `false` for JSON values after parsing. 16906 That is, discarded values can only occur during parsing, but will be 16907 removed when inside a structured value or replaced by null in other cases. 16908 16909 @return `true` if type is discarded, `false` otherwise. 16910 16911 @complexity Constant. 16912 16913 @exceptionsafety No-throw guarantee: this member function never throws 16914 exceptions. 16915 16916 @liveexample{The following code exemplifies `is_discarded()` for all JSON 16917 types.,is_discarded} 16918 16919 @since version 1.0.0 16920 */ 16921 constexpr bool is_discarded() const noexcept 16922 { 16923 return m_type == value_t::discarded; 16924 } 16925 16926 /*! 16927 @brief return the type of the JSON value (implicit) 16928 16929 Implicitly return the type of the JSON value as a value from the @ref 16930 value_t enumeration. 16931 16932 @return the type of the JSON value 16933 16934 @complexity Constant. 16935 16936 @exceptionsafety No-throw guarantee: this member function never throws 16937 exceptions. 16938 16939 @liveexample{The following code exemplifies the @ref value_t operator for 16940 all JSON types.,operator__value_t} 16941 16942 @sa @ref type() -- return the type of the JSON value (explicit) 16943 @sa @ref type_name() -- return the type as string 16944 16945 @since version 1.0.0 16946 */ 16947 constexpr operator value_t() const noexcept 16948 { 16949 return m_type; 16950 } 16951 16952 /// @} 16953 16954 private: 16955 ////////////////// 16956 // value access // 16957 ////////////////// 16958 16959 /// get a boolean (explicit) 16960 boolean_t get_impl(boolean_t* /*unused*/) const 16961 { 16962 if (JSON_HEDLEY_LIKELY(is_boolean())) 16963 { 16964 return m_value.boolean; 16965 } 16966 16967 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()))); 16968 } 16969 16970 /// get a pointer to the value (object) 16971 object_t* get_impl_ptr(object_t* /*unused*/) noexcept 16972 { 16973 return is_object() ? m_value.object : nullptr; 16974 } 16975 16976 /// get a pointer to the value (object) 16977 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept 16978 { 16979 return is_object() ? m_value.object : nullptr; 16980 } 16981 16982 /// get a pointer to the value (array) 16983 array_t* get_impl_ptr(array_t* /*unused*/) noexcept 16984 { 16985 return is_array() ? m_value.array : nullptr; 16986 } 16987 16988 /// get a pointer to the value (array) 16989 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept 16990 { 16991 return is_array() ? m_value.array : nullptr; 16992 } 16993 16994 /// get a pointer to the value (string) 16995 string_t* get_impl_ptr(string_t* /*unused*/) noexcept 16996 { 16997 return is_string() ? m_value.string : nullptr; 16998 } 16999 17000 /// get a pointer to the value (string) 17001 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept 17002 { 17003 return is_string() ? m_value.string : nullptr; 17004 } 17005 17006 /// get a pointer to the value (boolean) 17007 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept 17008 { 17009 return is_boolean() ? &m_value.boolean : nullptr; 17010 } 17011 17012 /// get a pointer to the value (boolean) 17013 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept 17014 { 17015 return is_boolean() ? &m_value.boolean : nullptr; 17016 } 17017 17018 /// get a pointer to the value (integer number) 17019 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept 17020 { 17021 return is_number_integer() ? &m_value.number_integer : nullptr; 17022 } 17023 17024 /// get a pointer to the value (integer number) 17025 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept 17026 { 17027 return is_number_integer() ? &m_value.number_integer : nullptr; 17028 } 17029 17030 /// get a pointer to the value (unsigned number) 17031 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept 17032 { 17033 return is_number_unsigned() ? &m_value.number_unsigned : nullptr; 17034 } 17035 17036 /// get a pointer to the value (unsigned number) 17037 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept 17038 { 17039 return is_number_unsigned() ? &m_value.number_unsigned : nullptr; 17040 } 17041 17042 /// get a pointer to the value (floating-point number) 17043 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept 17044 { 17045 return is_number_float() ? &m_value.number_float : nullptr; 17046 } 17047 17048 /// get a pointer to the value (floating-point number) 17049 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept 17050 { 17051 return is_number_float() ? &m_value.number_float : nullptr; 17052 } 17053 17054 /*! 17055 @brief helper function to implement get_ref() 17056 17057 This function helps to implement get_ref() without code duplication for 17058 const and non-const overloads 17059 17060 @tparam ThisType will be deduced as `basic_json` or `const basic_json` 17061 17062 @throw type_error.303 if ReferenceType does not match underlying value 17063 type of the current JSON 17064 */ 17065 template<typename ReferenceType, typename ThisType> 17066 static ReferenceType get_ref_impl(ThisType& obj) 17067 { 17068 // delegate the call to get_ptr<>() 17069 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>(); 17070 17071 if (JSON_HEDLEY_LIKELY(ptr != nullptr)) 17072 { 17073 return *ptr; 17074 } 17075 17076 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()))); 17077 } 17078 17079 public: 17080 /// @name value access 17081 /// Direct access to the stored value of a JSON value. 17082 /// @{ 17083 17084 /*! 17085 @brief get special-case overload 17086 17087 This overloads avoids a lot of template boilerplate, it can be seen as the 17088 identity method 17089 17090 @tparam BasicJsonType == @ref basic_json 17091 17092 @return a copy of *this 17093 17094 @complexity Constant. 17095 17096 @since version 2.1.0 17097 */ 17098 template<typename BasicJsonType, detail::enable_if_t< 17099 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value, 17100 int> = 0> 17101 basic_json get() const 17102 { 17103 return *this; 17104 } 17105 17106 /*! 17107 @brief get special-case overload 17108 17109 This overloads converts the current @ref basic_json in a different 17110 @ref basic_json type 17111 17112 @tparam BasicJsonType == @ref basic_json 17113 17114 @return a copy of *this, converted into @tparam BasicJsonType 17115 17116 @complexity Depending on the implementation of the called `from_json()` 17117 method. 17118 17119 @since version 3.2.0 17120 */ 17121 template<typename BasicJsonType, detail::enable_if_t< 17122 not std::is_same<BasicJsonType, basic_json>::value and 17123 detail::is_basic_json<BasicJsonType>::value, int> = 0> 17124 BasicJsonType get() const 17125 { 17126 return *this; 17127 } 17128 17129 /*! 17130 @brief get a value (explicit) 17131 17132 Explicit type conversion between the JSON value and a compatible value 17133 which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) 17134 and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). 17135 The value is converted by calling the @ref json_serializer<ValueType> 17136 `from_json()` method. 17137 17138 The function is equivalent to executing 17139 @code {.cpp} 17140 ValueType ret; 17141 JSONSerializer<ValueType>::from_json(*this, ret); 17142 return ret; 17143 @endcode 17144 17145 This overloads is chosen if: 17146 - @a ValueType is not @ref basic_json, 17147 - @ref json_serializer<ValueType> has a `from_json()` method of the form 17148 `void from_json(const basic_json&, ValueType&)`, and 17149 - @ref json_serializer<ValueType> does not have a `from_json()` method of 17150 the form `ValueType from_json(const basic_json&)` 17151 17152 @tparam ValueTypeCV the provided value type 17153 @tparam ValueType the returned value type 17154 17155 @return copy of the JSON value, converted to @a ValueType 17156 17157 @throw what @ref json_serializer<ValueType> `from_json()` method throws 17158 17159 @liveexample{The example below shows several conversions from JSON values 17160 to other types. There a few things to note: (1) Floating-point numbers can 17161 be converted to integers\, (2) A JSON array can be converted to a standard 17162 `std::vector<short>`\, (3) A JSON object can be converted to C++ 17163 associative containers such as `std::unordered_map<std::string\, 17164 json>`.,get__ValueType_const} 17165 17166 @since version 2.1.0 17167 */ 17168 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>, 17169 detail::enable_if_t < 17170 not detail::is_basic_json<ValueType>::value and 17171 detail::has_from_json<basic_json_t, ValueType>::value and 17172 not detail::has_non_default_from_json<basic_json_t, ValueType>::value, 17173 int> = 0> 17174 ValueType get() const noexcept(noexcept( 17175 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>()))) 17176 { 17177 // we cannot static_assert on ValueTypeCV being non-const, because 17178 // there is support for get<const basic_json_t>(), which is why we 17179 // still need the uncvref 17180 static_assert(not std::is_reference<ValueTypeCV>::value, 17181 "get() cannot be used with reference types, you might want to use get_ref()"); 17182 static_assert(std::is_default_constructible<ValueType>::value, 17183 "types must be DefaultConstructible when used with get()"); 17184 17185 ValueType ret; 17186 JSONSerializer<ValueType>::from_json(*this, ret); 17187 return ret; 17188 } 17189 17190 /*! 17191 @brief get a value (explicit); special case 17192 17193 Explicit type conversion between the JSON value and a compatible value 17194 which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) 17195 and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). 17196 The value is converted by calling the @ref json_serializer<ValueType> 17197 `from_json()` method. 17198 17199 The function is equivalent to executing 17200 @code {.cpp} 17201 return JSONSerializer<ValueTypeCV>::from_json(*this); 17202 @endcode 17203 17204 This overloads is chosen if: 17205 - @a ValueType is not @ref basic_json and 17206 - @ref json_serializer<ValueType> has a `from_json()` method of the form 17207 `ValueType from_json(const basic_json&)` 17208 17209 @note If @ref json_serializer<ValueType> has both overloads of 17210 `from_json()`, this one is chosen. 17211 17212 @tparam ValueTypeCV the provided value type 17213 @tparam ValueType the returned value type 17214 17215 @return copy of the JSON value, converted to @a ValueType 17216 17217 @throw what @ref json_serializer<ValueType> `from_json()` method throws 17218 17219 @since version 2.1.0 17220 */ 17221 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>, 17222 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and 17223 detail::has_non_default_from_json<basic_json_t, ValueType>::value, 17224 int> = 0> 17225 ValueType get() const noexcept(noexcept( 17226 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>()))) 17227 { 17228 static_assert(not std::is_reference<ValueTypeCV>::value, 17229 "get() cannot be used with reference types, you might want to use get_ref()"); 17230 return JSONSerializer<ValueType>::from_json(*this); 17231 } 17232 17233 /*! 17234 @brief get a value (explicit) 17235 17236 Explicit type conversion between the JSON value and a compatible value. 17237 The value is filled into the input parameter by calling the @ref json_serializer<ValueType> 17238 `from_json()` method. 17239 17240 The function is equivalent to executing 17241 @code {.cpp} 17242 ValueType v; 17243 JSONSerializer<ValueType>::from_json(*this, v); 17244 @endcode 17245 17246 This overloads is chosen if: 17247 - @a ValueType is not @ref basic_json, 17248 - @ref json_serializer<ValueType> has a `from_json()` method of the form 17249 `void from_json(const basic_json&, ValueType&)`, and 17250 17251 @tparam ValueType the input parameter type. 17252 17253 @return the input parameter, allowing chaining calls. 17254 17255 @throw what @ref json_serializer<ValueType> `from_json()` method throws 17256 17257 @liveexample{The example below shows several conversions from JSON values 17258 to other types. There a few things to note: (1) Floating-point numbers can 17259 be converted to integers\, (2) A JSON array can be converted to a standard 17260 `std::vector<short>`\, (3) A JSON object can be converted to C++ 17261 associative containers such as `std::unordered_map<std::string\, 17262 json>`.,get_to} 17263 17264 @since version 3.3.0 17265 */ 17266 template<typename ValueType, 17267 detail::enable_if_t < 17268 not detail::is_basic_json<ValueType>::value and 17269 detail::has_from_json<basic_json_t, ValueType>::value, 17270 int> = 0> 17271 ValueType & get_to(ValueType& v) const noexcept(noexcept( 17272 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v))) 17273 { 17274 JSONSerializer<ValueType>::from_json(*this, v); 17275 return v; 17276 } 17277 17278 template < 17279 typename T, std::size_t N, 17280 typename Array = T (&)[N], 17281 detail::enable_if_t < 17282 detail::has_from_json<basic_json_t, Array>::value, int > = 0 > 17283 Array get_to(T (&v)[N]) const 17284 noexcept(noexcept(JSONSerializer<Array>::from_json( 17285 std::declval<const basic_json_t&>(), v))) 17286 { 17287 JSONSerializer<Array>::from_json(*this, v); 17288 return v; 17289 } 17290 17291 17292 /*! 17293 @brief get a pointer value (implicit) 17294 17295 Implicit pointer access to the internally stored JSON value. No copies are 17296 made. 17297 17298 @warning Writing data to the pointee of the result yields an undefined 17299 state. 17300 17301 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref 17302 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, 17303 @ref number_unsigned_t, or @ref number_float_t. Enforced by a static 17304 assertion. 17305 17306 @return pointer to the internally stored JSON value if the requested 17307 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise 17308 17309 @complexity Constant. 17310 17311 @liveexample{The example below shows how pointers to internal values of a 17312 JSON value can be requested. Note that no type conversions are made and a 17313 `nullptr` is returned if the value and the requested pointer type does not 17314 match.,get_ptr} 17315 17316 @since version 1.0.0 17317 */ 17318 template<typename PointerType, typename std::enable_if< 17319 std::is_pointer<PointerType>::value, int>::type = 0> 17320 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>())) 17321 { 17322 // delegate the call to get_impl_ptr<>() 17323 return get_impl_ptr(static_cast<PointerType>(nullptr)); 17324 } 17325 17326 /*! 17327 @brief get a pointer value (implicit) 17328 @copydoc get_ptr() 17329 */ 17330 template<typename PointerType, typename std::enable_if< 17331 std::is_pointer<PointerType>::value and 17332 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0> 17333 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>())) 17334 { 17335 // delegate the call to get_impl_ptr<>() const 17336 return get_impl_ptr(static_cast<PointerType>(nullptr)); 17337 } 17338 17339 /*! 17340 @brief get a pointer value (explicit) 17341 17342 Explicit pointer access to the internally stored JSON value. No copies are 17343 made. 17344 17345 @warning The pointer becomes invalid if the underlying JSON object 17346 changes. 17347 17348 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref 17349 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, 17350 @ref number_unsigned_t, or @ref number_float_t. 17351 17352 @return pointer to the internally stored JSON value if the requested 17353 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise 17354 17355 @complexity Constant. 17356 17357 @liveexample{The example below shows how pointers to internal values of a 17358 JSON value can be requested. Note that no type conversions are made and a 17359 `nullptr` is returned if the value and the requested pointer type does not 17360 match.,get__PointerType} 17361 17362 @sa @ref get_ptr() for explicit pointer-member access 17363 17364 @since version 1.0.0 17365 */ 17366 template<typename PointerType, typename std::enable_if< 17367 std::is_pointer<PointerType>::value, int>::type = 0> 17368 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>()) 17369 { 17370 // delegate the call to get_ptr 17371 return get_ptr<PointerType>(); 17372 } 17373 17374 /*! 17375 @brief get a pointer value (explicit) 17376 @copydoc get() 17377 */ 17378 template<typename PointerType, typename std::enable_if< 17379 std::is_pointer<PointerType>::value, int>::type = 0> 17380 constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>()) 17381 { 17382 // delegate the call to get_ptr 17383 return get_ptr<PointerType>(); 17384 } 17385 17386 /*! 17387 @brief get a reference value (implicit) 17388 17389 Implicit reference access to the internally stored JSON value. No copies 17390 are made. 17391 17392 @warning Writing data to the referee of the result yields an undefined 17393 state. 17394 17395 @tparam ReferenceType reference type; must be a reference to @ref array_t, 17396 @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or 17397 @ref number_float_t. Enforced by static assertion. 17398 17399 @return reference to the internally stored JSON value if the requested 17400 reference type @a ReferenceType fits to the JSON value; throws 17401 type_error.303 otherwise 17402 17403 @throw type_error.303 in case passed type @a ReferenceType is incompatible 17404 with the stored JSON value; see example below 17405 17406 @complexity Constant. 17407 17408 @liveexample{The example shows several calls to `get_ref()`.,get_ref} 17409 17410 @since version 1.1.0 17411 */ 17412 template<typename ReferenceType, typename std::enable_if< 17413 std::is_reference<ReferenceType>::value, int>::type = 0> 17414 ReferenceType get_ref() 17415 { 17416 // delegate call to get_ref_impl 17417 return get_ref_impl<ReferenceType>(*this); 17418 } 17419 17420 /*! 17421 @brief get a reference value (implicit) 17422 @copydoc get_ref() 17423 */ 17424 template<typename ReferenceType, typename std::enable_if< 17425 std::is_reference<ReferenceType>::value and 17426 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0> 17427 ReferenceType get_ref() const 17428 { 17429 // delegate call to get_ref_impl 17430 return get_ref_impl<ReferenceType>(*this); 17431 } 17432 17433 /*! 17434 @brief get a value (implicit) 17435 17436 Implicit type conversion between the JSON value and a compatible value. 17437 The call is realized by calling @ref get() const. 17438 17439 @tparam ValueType non-pointer type compatible to the JSON value, for 17440 instance `int` for JSON integer numbers, `bool` for JSON booleans, or 17441 `std::vector` types for JSON arrays. The character type of @ref string_t 17442 as well as an initializer list of this type is excluded to avoid 17443 ambiguities as these types implicitly convert to `std::string`. 17444 17445 @return copy of the JSON value, converted to type @a ValueType 17446 17447 @throw type_error.302 in case passed type @a ValueType is incompatible 17448 to the JSON value type (e.g., the JSON value is of type boolean, but a 17449 string is requested); see example below 17450 17451 @complexity Linear in the size of the JSON value. 17452 17453 @liveexample{The example below shows several conversions from JSON values 17454 to other types. There a few things to note: (1) Floating-point numbers can 17455 be converted to integers\, (2) A JSON array can be converted to a standard 17456 `std::vector<short>`\, (3) A JSON object can be converted to C++ 17457 associative containers such as `std::unordered_map<std::string\, 17458 json>`.,operator__ValueType} 17459 17460 @since version 1.0.0 17461 */ 17462 template < typename ValueType, typename std::enable_if < 17463 not std::is_pointer<ValueType>::value and 17464 not std::is_same<ValueType, detail::json_ref<basic_json>>::value and 17465 not std::is_same<ValueType, typename string_t::value_type>::value and 17466 not detail::is_basic_json<ValueType>::value 17467 17468#ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015 17469 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value 17470#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) and _MSC_VER <= 1914)) 17471 and not std::is_same<ValueType, typename std::string_view>::value 17472#endif 17473#endif 17474 and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value 17475 , int >::type = 0 > 17476 operator ValueType() const 17477 { 17478 // delegate the call to get<>() const 17479 return get<ValueType>(); 17480 } 17481 17482 /// @} 17483 17484 17485 //////////////////// 17486 // element access // 17487 //////////////////// 17488 17489 /// @name element access 17490 /// Access to the JSON value. 17491 /// @{ 17492 17493 /*! 17494 @brief access specified array element with bounds checking 17495 17496 Returns a reference to the element at specified location @a idx, with 17497 bounds checking. 17498 17499 @param[in] idx index of the element to access 17500 17501 @return reference to the element at index @a idx 17502 17503 @throw type_error.304 if the JSON value is not an array; in this case, 17504 calling `at` with an index makes no sense. See example below. 17505 @throw out_of_range.401 if the index @a idx is out of range of the array; 17506 that is, `idx >= size()`. See example below. 17507 17508 @exceptionsafety Strong guarantee: if an exception is thrown, there are no 17509 changes in the JSON value. 17510 17511 @complexity Constant. 17512 17513 @since version 1.0.0 17514 17515 @liveexample{The example below shows how array elements can be read and 17516 written using `at()`. It also demonstrates the different exceptions that 17517 can be thrown.,at__size_type} 17518 */ 17519 reference at(size_type idx) 17520 { 17521 // at only works for arrays 17522 if (JSON_HEDLEY_LIKELY(is_array())) 17523 { 17524 JSON_TRY 17525 { 17526 return m_value.array->at(idx); 17527 } 17528 JSON_CATCH (std::out_of_range&) 17529 { 17530 // create better exception explanation 17531 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range")); 17532 } 17533 } 17534 else 17535 { 17536 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()))); 17537 } 17538 } 17539 17540 /*! 17541 @brief access specified array element with bounds checking 17542 17543 Returns a const reference to the element at specified location @a idx, 17544 with bounds checking. 17545 17546 @param[in] idx index of the element to access 17547 17548 @return const reference to the element at index @a idx 17549 17550 @throw type_error.304 if the JSON value is not an array; in this case, 17551 calling `at` with an index makes no sense. See example below. 17552 @throw out_of_range.401 if the index @a idx is out of range of the array; 17553 that is, `idx >= size()`. See example below. 17554 17555 @exceptionsafety Strong guarantee: if an exception is thrown, there are no 17556 changes in the JSON value. 17557 17558 @complexity Constant. 17559 17560 @since version 1.0.0 17561 17562 @liveexample{The example below shows how array elements can be read using 17563 `at()`. It also demonstrates the different exceptions that can be thrown., 17564 at__size_type_const} 17565 */ 17566 const_reference at(size_type idx) const 17567 { 17568 // at only works for arrays 17569 if (JSON_HEDLEY_LIKELY(is_array())) 17570 { 17571 JSON_TRY 17572 { 17573 return m_value.array->at(idx); 17574 } 17575 JSON_CATCH (std::out_of_range&) 17576 { 17577 // create better exception explanation 17578 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range")); 17579 } 17580 } 17581 else 17582 { 17583 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()))); 17584 } 17585 } 17586 17587 /*! 17588 @brief access specified object element with bounds checking 17589 17590 Returns a reference to the element at with specified key @a key, with 17591 bounds checking. 17592 17593 @param[in] key key of the element to access 17594 17595 @return reference to the element at key @a key 17596 17597 @throw type_error.304 if the JSON value is not an object; in this case, 17598 calling `at` with a key makes no sense. See example below. 17599 @throw out_of_range.403 if the key @a key is is not stored in the object; 17600 that is, `find(key) == end()`. See example below. 17601 17602 @exceptionsafety Strong guarantee: if an exception is thrown, there are no 17603 changes in the JSON value. 17604 17605 @complexity Logarithmic in the size of the container. 17606 17607 @sa @ref operator[](const typename object_t::key_type&) for unchecked 17608 access by reference 17609 @sa @ref value() for access by value with a default value 17610 17611 @since version 1.0.0 17612 17613 @liveexample{The example below shows how object elements can be read and 17614 written using `at()`. It also demonstrates the different exceptions that 17615 can be thrown.,at__object_t_key_type} 17616 */ 17617 reference at(const typename object_t::key_type& key) 17618 { 17619 // at only works for objects 17620 if (JSON_HEDLEY_LIKELY(is_object())) 17621 { 17622 JSON_TRY 17623 { 17624 return m_value.object->at(key); 17625 } 17626 JSON_CATCH (std::out_of_range&) 17627 { 17628 // create better exception explanation 17629 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found")); 17630 } 17631 } 17632 else 17633 { 17634 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()))); 17635 } 17636 } 17637 17638 /*! 17639 @brief access specified object element with bounds checking 17640 17641 Returns a const reference to the element at with specified key @a key, 17642 with bounds checking. 17643 17644 @param[in] key key of the element to access 17645 17646 @return const reference to the element at key @a key 17647 17648 @throw type_error.304 if the JSON value is not an object; in this case, 17649 calling `at` with a key makes no sense. See example below. 17650 @throw out_of_range.403 if the key @a key is is not stored in the object; 17651 that is, `find(key) == end()`. See example below. 17652 17653 @exceptionsafety Strong guarantee: if an exception is thrown, there are no 17654 changes in the JSON value. 17655 17656 @complexity Logarithmic in the size of the container. 17657 17658 @sa @ref operator[](const typename object_t::key_type&) for unchecked 17659 access by reference 17660 @sa @ref value() for access by value with a default value 17661 17662 @since version 1.0.0 17663 17664 @liveexample{The example below shows how object elements can be read using 17665 `at()`. It also demonstrates the different exceptions that can be thrown., 17666 at__object_t_key_type_const} 17667 */ 17668 const_reference at(const typename object_t::key_type& key) const 17669 { 17670 // at only works for objects 17671 if (JSON_HEDLEY_LIKELY(is_object())) 17672 { 17673 JSON_TRY 17674 { 17675 return m_value.object->at(key); 17676 } 17677 JSON_CATCH (std::out_of_range&) 17678 { 17679 // create better exception explanation 17680 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found")); 17681 } 17682 } 17683 else 17684 { 17685 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()))); 17686 } 17687 } 17688 17689 /*! 17690 @brief access specified array element 17691 17692 Returns a reference to the element at specified location @a idx. 17693 17694 @note If @a idx is beyond the range of the array (i.e., `idx >= size()`), 17695 then the array is silently filled up with `null` values to make `idx` a 17696 valid reference to the last stored element. 17697 17698 @param[in] idx index of the element to access 17699 17700 @return reference to the element at index @a idx 17701 17702 @throw type_error.305 if the JSON value is not an array or null; in that 17703 cases, using the [] operator with an index makes no sense. 17704 17705 @complexity Constant if @a idx is in the range of the array. Otherwise 17706 linear in `idx - size()`. 17707 17708 @liveexample{The example below shows how array elements can be read and 17709 written using `[]` operator. Note the addition of `null` 17710 values.,operatorarray__size_type} 17711 17712 @since version 1.0.0 17713 */ 17714 reference operator[](size_type idx) 17715 { 17716 // implicitly convert null value to an empty array 17717 if (is_null()) 17718 { 17719 m_type = value_t::array; 17720 m_value.array = create<array_t>(); 17721 assert_invariant(); 17722 } 17723 17724 // operator[] only works for arrays 17725 if (JSON_HEDLEY_LIKELY(is_array())) 17726 { 17727 // fill up array with null values if given idx is outside range 17728 if (idx >= m_value.array->size()) 17729 { 17730 m_value.array->insert(m_value.array->end(), 17731 idx - m_value.array->size() + 1, 17732 basic_json()); 17733 } 17734 17735 return m_value.array->operator[](idx); 17736 } 17737 17738 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()))); 17739 } 17740 17741 /*! 17742 @brief access specified array element 17743 17744 Returns a const reference to the element at specified location @a idx. 17745 17746 @param[in] idx index of the element to access 17747 17748 @return const reference to the element at index @a idx 17749 17750 @throw type_error.305 if the JSON value is not an array; in that case, 17751 using the [] operator with an index makes no sense. 17752 17753 @complexity Constant. 17754 17755 @liveexample{The example below shows how array elements can be read using 17756 the `[]` operator.,operatorarray__size_type_const} 17757 17758 @since version 1.0.0 17759 */ 17760 const_reference operator[](size_type idx) const 17761 { 17762 // const operator[] only works for arrays 17763 if (JSON_HEDLEY_LIKELY(is_array())) 17764 { 17765 return m_value.array->operator[](idx); 17766 } 17767 17768 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()))); 17769 } 17770 17771 /*! 17772 @brief access specified object element 17773 17774 Returns a reference to the element at with specified key @a key. 17775 17776 @note If @a key is not found in the object, then it is silently added to 17777 the object and filled with a `null` value to make `key` a valid reference. 17778 In case the value was `null` before, it is converted to an object. 17779 17780 @param[in] key key of the element to access 17781 17782 @return reference to the element at key @a key 17783 17784 @throw type_error.305 if the JSON value is not an object or null; in that 17785 cases, using the [] operator with a key makes no sense. 17786 17787 @complexity Logarithmic in the size of the container. 17788 17789 @liveexample{The example below shows how object elements can be read and 17790 written using the `[]` operator.,operatorarray__key_type} 17791 17792 @sa @ref at(const typename object_t::key_type&) for access by reference 17793 with range checking 17794 @sa @ref value() for access by value with a default value 17795 17796 @since version 1.0.0 17797 */ 17798 reference operator[](const typename object_t::key_type& key) 17799 { 17800 // implicitly convert null value to an empty object 17801 if (is_null()) 17802 { 17803 m_type = value_t::object; 17804 m_value.object = create<object_t>(); 17805 assert_invariant(); 17806 } 17807 17808 // operator[] only works for objects 17809 if (JSON_HEDLEY_LIKELY(is_object())) 17810 { 17811 return m_value.object->operator[](key); 17812 } 17813 17814 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()))); 17815 } 17816 17817 /*! 17818 @brief read-only access specified object element 17819 17820 Returns a const reference to the element at with specified key @a key. No 17821 bounds checking is performed. 17822 17823 @warning If the element with key @a key does not exist, the behavior is 17824 undefined. 17825 17826 @param[in] key key of the element to access 17827 17828 @return const reference to the element at key @a key 17829 17830 @pre The element with key @a key must exist. **This precondition is 17831 enforced with an assertion.** 17832 17833 @throw type_error.305 if the JSON value is not an object; in that case, 17834 using the [] operator with a key makes no sense. 17835 17836 @complexity Logarithmic in the size of the container. 17837 17838 @liveexample{The example below shows how object elements can be read using 17839 the `[]` operator.,operatorarray__key_type_const} 17840 17841 @sa @ref at(const typename object_t::key_type&) for access by reference 17842 with range checking 17843 @sa @ref value() for access by value with a default value 17844 17845 @since version 1.0.0 17846 */ 17847 const_reference operator[](const typename object_t::key_type& key) const 17848 { 17849 // const operator[] only works for objects 17850 if (JSON_HEDLEY_LIKELY(is_object())) 17851 { 17852 assert(m_value.object->find(key) != m_value.object->end()); 17853 return m_value.object->find(key)->second; 17854 } 17855 17856 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()))); 17857 } 17858 17859 /*! 17860 @brief access specified object element 17861 17862 Returns a reference to the element at with specified key @a key. 17863 17864 @note If @a key is not found in the object, then it is silently added to 17865 the object and filled with a `null` value to make `key` a valid reference. 17866 In case the value was `null` before, it is converted to an object. 17867 17868 @param[in] key key of the element to access 17869 17870 @return reference to the element at key @a key 17871 17872 @throw type_error.305 if the JSON value is not an object or null; in that 17873 cases, using the [] operator with a key makes no sense. 17874 17875 @complexity Logarithmic in the size of the container. 17876 17877 @liveexample{The example below shows how object elements can be read and 17878 written using the `[]` operator.,operatorarray__key_type} 17879 17880 @sa @ref at(const typename object_t::key_type&) for access by reference 17881 with range checking 17882 @sa @ref value() for access by value with a default value 17883 17884 @since version 1.1.0 17885 */ 17886 template<typename T> 17887 JSON_HEDLEY_NON_NULL(2) 17888 reference operator[](T* key) 17889 { 17890 // implicitly convert null to object 17891 if (is_null()) 17892 { 17893 m_type = value_t::object; 17894 m_value = value_t::object; 17895 assert_invariant(); 17896 } 17897 17898 // at only works for objects 17899 if (JSON_HEDLEY_LIKELY(is_object())) 17900 { 17901 return m_value.object->operator[](key); 17902 } 17903 17904 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()))); 17905 } 17906 17907 /*! 17908 @brief read-only access specified object element 17909 17910 Returns a const reference to the element at with specified key @a key. No 17911 bounds checking is performed. 17912 17913 @warning If the element with key @a key does not exist, the behavior is 17914 undefined. 17915 17916 @param[in] key key of the element to access 17917 17918 @return const reference to the element at key @a key 17919 17920 @pre The element with key @a key must exist. **This precondition is 17921 enforced with an assertion.** 17922 17923 @throw type_error.305 if the JSON value is not an object; in that case, 17924 using the [] operator with a key makes no sense. 17925 17926 @complexity Logarithmic in the size of the container. 17927 17928 @liveexample{The example below shows how object elements can be read using 17929 the `[]` operator.,operatorarray__key_type_const} 17930 17931 @sa @ref at(const typename object_t::key_type&) for access by reference 17932 with range checking 17933 @sa @ref value() for access by value with a default value 17934 17935 @since version 1.1.0 17936 */ 17937 template<typename T> 17938 JSON_HEDLEY_NON_NULL(2) 17939 const_reference operator[](T* key) const 17940 { 17941 // at only works for objects 17942 if (JSON_HEDLEY_LIKELY(is_object())) 17943 { 17944 assert(m_value.object->find(key) != m_value.object->end()); 17945 return m_value.object->find(key)->second; 17946 } 17947 17948 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()))); 17949 } 17950 17951 /*! 17952 @brief access specified object element with default value 17953 17954 Returns either a copy of an object's element at the specified key @a key 17955 or a given default value if no element with key @a key exists. 17956 17957 The function is basically equivalent to executing 17958 @code {.cpp} 17959 try { 17960 return at(key); 17961 } catch(out_of_range) { 17962 return default_value; 17963 } 17964 @endcode 17965 17966 @note Unlike @ref at(const typename object_t::key_type&), this function 17967 does not throw if the given key @a key was not found. 17968 17969 @note Unlike @ref operator[](const typename object_t::key_type& key), this 17970 function does not implicitly add an element to the position defined by @a 17971 key. This function is furthermore also applicable to const objects. 17972 17973 @param[in] key key of the element to access 17974 @param[in] default_value the value to return if @a key is not found 17975 17976 @tparam ValueType type compatible to JSON values, for instance `int` for 17977 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for 17978 JSON arrays. Note the type of the expected value at @a key and the default 17979 value @a default_value must be compatible. 17980 17981 @return copy of the element at key @a key or @a default_value if @a key 17982 is not found 17983 17984 @throw type_error.302 if @a default_value does not match the type of the 17985 value at @a key 17986 @throw type_error.306 if the JSON value is not an object; in that case, 17987 using `value()` with a key makes no sense. 17988 17989 @complexity Logarithmic in the size of the container. 17990 17991 @liveexample{The example below shows how object elements can be queried 17992 with a default value.,basic_json__value} 17993 17994 @sa @ref at(const typename object_t::key_type&) for access by reference 17995 with range checking 17996 @sa @ref operator[](const typename object_t::key_type&) for unchecked 17997 access by reference 17998 17999 @since version 1.0.0 18000 */ 18001 template<class ValueType, typename std::enable_if< 18002 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0> 18003 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const 18004 { 18005 // at only works for objects 18006 if (JSON_HEDLEY_LIKELY(is_object())) 18007 { 18008 // if key is found, return value and given default value otherwise 18009 const auto it = find(key); 18010 if (it != end()) 18011 { 18012 return *it; 18013 } 18014 18015 return default_value; 18016 } 18017 18018 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()))); 18019 } 18020 18021 /*! 18022 @brief overload for a default value of type const char* 18023 @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const 18024 */ 18025 string_t value(const typename object_t::key_type& key, const char* default_value) const 18026 { 18027 return value(key, string_t(default_value)); 18028 } 18029 18030 /*! 18031 @brief access specified object element via JSON Pointer with default value 18032 18033 Returns either a copy of an object's element at the specified key @a key 18034 or a given default value if no element with key @a key exists. 18035 18036 The function is basically equivalent to executing 18037 @code {.cpp} 18038 try { 18039 return at(ptr); 18040 } catch(out_of_range) { 18041 return default_value; 18042 } 18043 @endcode 18044 18045 @note Unlike @ref at(const json_pointer&), this function does not throw 18046 if the given key @a key was not found. 18047 18048 @param[in] ptr a JSON pointer to the element to access 18049 @param[in] default_value the value to return if @a ptr found no value 18050 18051 @tparam ValueType type compatible to JSON values, for instance `int` for 18052 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for 18053 JSON arrays. Note the type of the expected value at @a key and the default 18054 value @a default_value must be compatible. 18055 18056 @return copy of the element at key @a key or @a default_value if @a key 18057 is not found 18058 18059 @throw type_error.302 if @a default_value does not match the type of the 18060 value at @a ptr 18061 @throw type_error.306 if the JSON value is not an object; in that case, 18062 using `value()` with a key makes no sense. 18063 18064 @complexity Logarithmic in the size of the container. 18065 18066 @liveexample{The example below shows how object elements can be queried 18067 with a default value.,basic_json__value_ptr} 18068 18069 @sa @ref operator[](const json_pointer&) for unchecked access by reference 18070 18071 @since version 2.0.2 18072 */ 18073 template<class ValueType, typename std::enable_if< 18074 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0> 18075 ValueType value(const json_pointer& ptr, const ValueType& default_value) const 18076 { 18077 // at only works for objects 18078 if (JSON_HEDLEY_LIKELY(is_object())) 18079 { 18080 // if pointer resolves a value, return it or use default value 18081 JSON_TRY 18082 { 18083 return ptr.get_checked(this); 18084 } 18085 JSON_INTERNAL_CATCH (out_of_range&) 18086 { 18087 return default_value; 18088 } 18089 } 18090 18091 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()))); 18092 } 18093 18094 /*! 18095 @brief overload for a default value of type const char* 18096 @copydoc basic_json::value(const json_pointer&, ValueType) const 18097 */ 18098 JSON_HEDLEY_NON_NULL(3) 18099 string_t value(const json_pointer& ptr, const char* default_value) const 18100 { 18101 return value(ptr, string_t(default_value)); 18102 } 18103 18104 /*! 18105 @brief access the first element 18106 18107 Returns a reference to the first element in the container. For a JSON 18108 container `c`, the expression `c.front()` is equivalent to `*c.begin()`. 18109 18110 @return In case of a structured type (array or object), a reference to the 18111 first element is returned. In case of number, string, or boolean values, a 18112 reference to the value is returned. 18113 18114 @complexity Constant. 18115 18116 @pre The JSON value must not be `null` (would throw `std::out_of_range`) 18117 or an empty array or object (undefined behavior, **guarded by 18118 assertions**). 18119 @post The JSON value remains unchanged. 18120 18121 @throw invalid_iterator.214 when called on `null` value 18122 18123 @liveexample{The following code shows an example for `front()`.,front} 18124 18125 @sa @ref back() -- access the last element 18126 18127 @since version 1.0.0 18128 */ 18129 reference front() 18130 { 18131 return *begin(); 18132 } 18133 18134 /*! 18135 @copydoc basic_json::front() 18136 */ 18137 const_reference front() const 18138 { 18139 return *cbegin(); 18140 } 18141 18142 /*! 18143 @brief access the last element 18144 18145 Returns a reference to the last element in the container. For a JSON 18146 container `c`, the expression `c.back()` is equivalent to 18147 @code {.cpp} 18148 auto tmp = c.end(); 18149 --tmp; 18150 return *tmp; 18151 @endcode 18152 18153 @return In case of a structured type (array or object), a reference to the 18154 last element is returned. In case of number, string, or boolean values, a 18155 reference to the value is returned. 18156 18157 @complexity Constant. 18158 18159 @pre The JSON value must not be `null` (would throw `std::out_of_range`) 18160 or an empty array or object (undefined behavior, **guarded by 18161 assertions**). 18162 @post The JSON value remains unchanged. 18163 18164 @throw invalid_iterator.214 when called on a `null` value. See example 18165 below. 18166 18167 @liveexample{The following code shows an example for `back()`.,back} 18168 18169 @sa @ref front() -- access the first element 18170 18171 @since version 1.0.0 18172 */ 18173 reference back() 18174 { 18175 auto tmp = end(); 18176 --tmp; 18177 return *tmp; 18178 } 18179 18180 /*! 18181 @copydoc basic_json::back() 18182 */ 18183 const_reference back() const 18184 { 18185 auto tmp = cend(); 18186 --tmp; 18187 return *tmp; 18188 } 18189 18190 /*! 18191 @brief remove element given an iterator 18192 18193 Removes the element specified by iterator @a pos. The iterator @a pos must 18194 be valid and dereferenceable. Thus the `end()` iterator (which is valid, 18195 but is not dereferenceable) cannot be used as a value for @a pos. 18196 18197 If called on a primitive type other than `null`, the resulting JSON value 18198 will be `null`. 18199 18200 @param[in] pos iterator to the element to remove 18201 @return Iterator following the last removed element. If the iterator @a 18202 pos refers to the last element, the `end()` iterator is returned. 18203 18204 @tparam IteratorType an @ref iterator or @ref const_iterator 18205 18206 @post Invalidates iterators and references at or after the point of the 18207 erase, including the `end()` iterator. 18208 18209 @throw type_error.307 if called on a `null` value; example: `"cannot use 18210 erase() with null"` 18211 @throw invalid_iterator.202 if called on an iterator which does not belong 18212 to the current JSON value; example: `"iterator does not fit current 18213 value"` 18214 @throw invalid_iterator.205 if called on a primitive type with invalid 18215 iterator (i.e., any iterator which is not `begin()`); example: `"iterator 18216 out of range"` 18217 18218 @complexity The complexity depends on the type: 18219 - objects: amortized constant 18220 - arrays: linear in distance between @a pos and the end of the container 18221 - strings: linear in the length of the string 18222 - other types: constant 18223 18224 @liveexample{The example shows the result of `erase()` for different JSON 18225 types.,erase__IteratorType} 18226 18227 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in 18228 the given range 18229 @sa @ref erase(const typename object_t::key_type&) -- removes the element 18230 from an object at the given key 18231 @sa @ref erase(const size_type) -- removes the element from an array at 18232 the given index 18233 18234 @since version 1.0.0 18235 */ 18236 template<class IteratorType, typename std::enable_if< 18237 std::is_same<IteratorType, typename basic_json_t::iterator>::value or 18238 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type 18239 = 0> 18240 IteratorType erase(IteratorType pos) 18241 { 18242 // make sure iterator fits the current value 18243 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object)) 18244 { 18245 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value")); 18246 } 18247 18248 IteratorType result = end(); 18249 18250 switch (m_type) 18251 { 18252 case value_t::boolean: 18253 case value_t::number_float: 18254 case value_t::number_integer: 18255 case value_t::number_unsigned: 18256 case value_t::string: 18257 { 18258 if (JSON_HEDLEY_UNLIKELY(not pos.m_it.primitive_iterator.is_begin())) 18259 { 18260 JSON_THROW(invalid_iterator::create(205, "iterator out of range")); 18261 } 18262 18263 if (is_string()) 18264 { 18265 AllocatorType<string_t> alloc; 18266 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string); 18267 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1); 18268 m_value.string = nullptr; 18269 } 18270 18271 m_type = value_t::null; 18272 assert_invariant(); 18273 break; 18274 } 18275 18276 case value_t::object: 18277 { 18278 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator); 18279 break; 18280 } 18281 18282 case value_t::array: 18283 { 18284 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator); 18285 break; 18286 } 18287 18288 default: 18289 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()))); 18290 } 18291 18292 return result; 18293 } 18294 18295 /*! 18296 @brief remove elements given an iterator range 18297 18298 Removes the element specified by the range `[first; last)`. The iterator 18299 @a first does not need to be dereferenceable if `first == last`: erasing 18300 an empty range is a no-op. 18301 18302 If called on a primitive type other than `null`, the resulting JSON value 18303 will be `null`. 18304 18305 @param[in] first iterator to the beginning of the range to remove 18306 @param[in] last iterator past the end of the range to remove 18307 @return Iterator following the last removed element. If the iterator @a 18308 second refers to the last element, the `end()` iterator is returned. 18309 18310 @tparam IteratorType an @ref iterator or @ref const_iterator 18311 18312 @post Invalidates iterators and references at or after the point of the 18313 erase, including the `end()` iterator. 18314 18315 @throw type_error.307 if called on a `null` value; example: `"cannot use 18316 erase() with null"` 18317 @throw invalid_iterator.203 if called on iterators which does not belong 18318 to the current JSON value; example: `"iterators do not fit current value"` 18319 @throw invalid_iterator.204 if called on a primitive type with invalid 18320 iterators (i.e., if `first != begin()` and `last != end()`); example: 18321 `"iterators out of range"` 18322 18323 @complexity The complexity depends on the type: 18324 - objects: `log(size()) + std::distance(first, last)` 18325 - arrays: linear in the distance between @a first and @a last, plus linear 18326 in the distance between @a last and end of the container 18327 - strings: linear in the length of the string 18328 - other types: constant 18329 18330 @liveexample{The example shows the result of `erase()` for different JSON 18331 types.,erase__IteratorType_IteratorType} 18332 18333 @sa @ref erase(IteratorType) -- removes the element at a given position 18334 @sa @ref erase(const typename object_t::key_type&) -- removes the element 18335 from an object at the given key 18336 @sa @ref erase(const size_type) -- removes the element from an array at 18337 the given index 18338 18339 @since version 1.0.0 18340 */ 18341 template<class IteratorType, typename std::enable_if< 18342 std::is_same<IteratorType, typename basic_json_t::iterator>::value or 18343 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type 18344 = 0> 18345 IteratorType erase(IteratorType first, IteratorType last) 18346 { 18347 // make sure iterator fits the current value 18348 if (JSON_HEDLEY_UNLIKELY(this != first.m_object or this != last.m_object)) 18349 { 18350 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value")); 18351 } 18352 18353 IteratorType result = end(); 18354 18355 switch (m_type) 18356 { 18357 case value_t::boolean: 18358 case value_t::number_float: 18359 case value_t::number_integer: 18360 case value_t::number_unsigned: 18361 case value_t::string: 18362 { 18363 if (JSON_HEDLEY_LIKELY(not first.m_it.primitive_iterator.is_begin() 18364 or not last.m_it.primitive_iterator.is_end())) 18365 { 18366 JSON_THROW(invalid_iterator::create(204, "iterators out of range")); 18367 } 18368 18369 if (is_string()) 18370 { 18371 AllocatorType<string_t> alloc; 18372 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string); 18373 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1); 18374 m_value.string = nullptr; 18375 } 18376 18377 m_type = value_t::null; 18378 assert_invariant(); 18379 break; 18380 } 18381 18382 case value_t::object: 18383 { 18384 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator, 18385 last.m_it.object_iterator); 18386 break; 18387 } 18388 18389 case value_t::array: 18390 { 18391 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator, 18392 last.m_it.array_iterator); 18393 break; 18394 } 18395 18396 default: 18397 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()))); 18398 } 18399 18400 return result; 18401 } 18402 18403 /*! 18404 @brief remove element from a JSON object given a key 18405 18406 Removes elements from a JSON object with the key value @a key. 18407 18408 @param[in] key value of the elements to remove 18409 18410 @return Number of elements removed. If @a ObjectType is the default 18411 `std::map` type, the return value will always be `0` (@a key was not 18412 found) or `1` (@a key was found). 18413 18414 @post References and iterators to the erased elements are invalidated. 18415 Other references and iterators are not affected. 18416 18417 @throw type_error.307 when called on a type other than JSON object; 18418 example: `"cannot use erase() with null"` 18419 18420 @complexity `log(size()) + count(key)` 18421 18422 @liveexample{The example shows the effect of `erase()`.,erase__key_type} 18423 18424 @sa @ref erase(IteratorType) -- removes the element at a given position 18425 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in 18426 the given range 18427 @sa @ref erase(const size_type) -- removes the element from an array at 18428 the given index 18429 18430 @since version 1.0.0 18431 */ 18432 size_type erase(const typename object_t::key_type& key) 18433 { 18434 // this erase only works for objects 18435 if (JSON_HEDLEY_LIKELY(is_object())) 18436 { 18437 return m_value.object->erase(key); 18438 } 18439 18440 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()))); 18441 } 18442 18443 /*! 18444 @brief remove element from a JSON array given an index 18445 18446 Removes element from a JSON array at the index @a idx. 18447 18448 @param[in] idx index of the element to remove 18449 18450 @throw type_error.307 when called on a type other than JSON object; 18451 example: `"cannot use erase() with null"` 18452 @throw out_of_range.401 when `idx >= size()`; example: `"array index 17 18453 is out of range"` 18454 18455 @complexity Linear in distance between @a idx and the end of the container. 18456 18457 @liveexample{The example shows the effect of `erase()`.,erase__size_type} 18458 18459 @sa @ref erase(IteratorType) -- removes the element at a given position 18460 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in 18461 the given range 18462 @sa @ref erase(const typename object_t::key_type&) -- removes the element 18463 from an object at the given key 18464 18465 @since version 1.0.0 18466 */ 18467 void erase(const size_type idx) 18468 { 18469 // this erase only works for arrays 18470 if (JSON_HEDLEY_LIKELY(is_array())) 18471 { 18472 if (JSON_HEDLEY_UNLIKELY(idx >= size())) 18473 { 18474 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range")); 18475 } 18476 18477 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx)); 18478 } 18479 else 18480 { 18481 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()))); 18482 } 18483 } 18484 18485 /// @} 18486 18487 18488 //////////// 18489 // lookup // 18490 //////////// 18491 18492 /// @name lookup 18493 /// @{ 18494 18495 /*! 18496 @brief find an element in a JSON object 18497 18498 Finds an element in a JSON object with key equivalent to @a key. If the 18499 element is not found or the JSON value is not an object, end() is 18500 returned. 18501 18502 @note This method always returns @ref end() when executed on a JSON type 18503 that is not an object. 18504 18505 @param[in] key key value of the element to search for. 18506 18507 @return Iterator to an element with key equivalent to @a key. If no such 18508 element is found or the JSON value is not an object, past-the-end (see 18509 @ref end()) iterator is returned. 18510 18511 @complexity Logarithmic in the size of the JSON object. 18512 18513 @liveexample{The example shows how `find()` is used.,find__key_type} 18514 18515 @sa @ref contains(KeyT&&) const -- checks whether a key exists 18516 18517 @since version 1.0.0 18518 */ 18519 template<typename KeyT> 18520 iterator find(KeyT&& key) 18521 { 18522 auto result = end(); 18523 18524 if (is_object()) 18525 { 18526 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key)); 18527 } 18528 18529 return result; 18530 } 18531 18532 /*! 18533 @brief find an element in a JSON object 18534 @copydoc find(KeyT&&) 18535 */ 18536 template<typename KeyT> 18537 const_iterator find(KeyT&& key) const 18538 { 18539 auto result = cend(); 18540 18541 if (is_object()) 18542 { 18543 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key)); 18544 } 18545 18546 return result; 18547 } 18548 18549 /*! 18550 @brief returns the number of occurrences of a key in a JSON object 18551 18552 Returns the number of elements with key @a key. If ObjectType is the 18553 default `std::map` type, the return value will always be `0` (@a key was 18554 not found) or `1` (@a key was found). 18555 18556 @note This method always returns `0` when executed on a JSON type that is 18557 not an object. 18558 18559 @param[in] key key value of the element to count 18560 18561 @return Number of elements with key @a key. If the JSON value is not an 18562 object, the return value will be `0`. 18563 18564 @complexity Logarithmic in the size of the JSON object. 18565 18566 @liveexample{The example shows how `count()` is used.,count} 18567 18568 @since version 1.0.0 18569 */ 18570 template<typename KeyT> 18571 size_type count(KeyT&& key) const 18572 { 18573 // return 0 for all nonobject types 18574 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0; 18575 } 18576 18577 /*! 18578 @brief check the existence of an element in a JSON object 18579 18580 Check whether an element exists in a JSON object with key equivalent to 18581 @a key. If the element is not found or the JSON value is not an object, 18582 false is returned. 18583 18584 @note This method always returns false when executed on a JSON type 18585 that is not an object. 18586 18587 @param[in] key key value to check its existence. 18588 18589 @return true if an element with specified @a key exists. If no such 18590 element with such key is found or the JSON value is not an object, 18591 false is returned. 18592 18593 @complexity Logarithmic in the size of the JSON object. 18594 18595 @liveexample{The following code shows an example for `contains()`.,contains} 18596 18597 @sa @ref find(KeyT&&) -- returns an iterator to an object element 18598 @sa @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer 18599 18600 @since version 3.6.0 18601 */ 18602 template<typename KeyT, typename std::enable_if< 18603 not std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int>::type = 0> 18604 bool contains(KeyT && key) const 18605 { 18606 return is_object() and m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end(); 18607 } 18608 18609 /*! 18610 @brief check the existence of an element in a JSON object given a JSON pointer 18611 18612 Check whether the given JSON pointer @a ptr can be resolved in the current 18613 JSON value. 18614 18615 @note This method can be executed on any JSON value type. 18616 18617 @param[in] ptr JSON pointer to check its existence. 18618 18619 @return true if the JSON pointer can be resolved to a stored value, false 18620 otherwise. 18621 18622 @post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`. 18623 18624 @throw parse_error.106 if an array index begins with '0' 18625 @throw parse_error.109 if an array index was not a number 18626 18627 @complexity Logarithmic in the size of the JSON object. 18628 18629 @liveexample{The following code shows an example for `contains()`.,contains_json_pointer} 18630 18631 @sa @ref contains(KeyT &&) const -- checks the existence of a key 18632 18633 @since version 3.7.0 18634 */ 18635 bool contains(const json_pointer& ptr) const 18636 { 18637 return ptr.contains(this); 18638 } 18639 18640 /// @} 18641 18642 18643 /////////////// 18644 // iterators // 18645 /////////////// 18646 18647 /// @name iterators 18648 /// @{ 18649 18650 /*! 18651 @brief returns an iterator to the first element 18652 18653 Returns an iterator to the first element. 18654 18655 @image html range-begin-end.svg "Illustration from cppreference.com" 18656 18657 @return iterator to the first element 18658 18659 @complexity Constant. 18660 18661 @requirement This function helps `basic_json` satisfying the 18662 [Container](https://en.cppreference.com/w/cpp/named_req/Container) 18663 requirements: 18664 - The complexity is constant. 18665 18666 @liveexample{The following code shows an example for `begin()`.,begin} 18667 18668 @sa @ref cbegin() -- returns a const iterator to the beginning 18669 @sa @ref end() -- returns an iterator to the end 18670 @sa @ref cend() -- returns a const iterator to the end 18671 18672 @since version 1.0.0 18673 */ 18674 iterator begin() noexcept 18675 { 18676 iterator result(this); 18677 result.set_begin(); 18678 return result; 18679 } 18680 18681 /*! 18682 @copydoc basic_json::cbegin() 18683 */ 18684 const_iterator begin() const noexcept 18685 { 18686 return cbegin(); 18687 } 18688 18689 /*! 18690 @brief returns a const iterator to the first element 18691 18692 Returns a const iterator to the first element. 18693 18694 @image html range-begin-end.svg "Illustration from cppreference.com" 18695 18696 @return const iterator to the first element 18697 18698 @complexity Constant. 18699 18700 @requirement This function helps `basic_json` satisfying the 18701 [Container](https://en.cppreference.com/w/cpp/named_req/Container) 18702 requirements: 18703 - The complexity is constant. 18704 - Has the semantics of `const_cast<const basic_json&>(*this).begin()`. 18705 18706 @liveexample{The following code shows an example for `cbegin()`.,cbegin} 18707 18708 @sa @ref begin() -- returns an iterator to the beginning 18709 @sa @ref end() -- returns an iterator to the end 18710 @sa @ref cend() -- returns a const iterator to the end 18711 18712 @since version 1.0.0 18713 */ 18714 const_iterator cbegin() const noexcept 18715 { 18716 const_iterator result(this); 18717 result.set_begin(); 18718 return result; 18719 } 18720 18721 /*! 18722 @brief returns an iterator to one past the last element 18723 18724 Returns an iterator to one past the last element. 18725 18726 @image html range-begin-end.svg "Illustration from cppreference.com" 18727 18728 @return iterator one past the last element 18729 18730 @complexity Constant. 18731 18732 @requirement This function helps `basic_json` satisfying the 18733 [Container](https://en.cppreference.com/w/cpp/named_req/Container) 18734 requirements: 18735 - The complexity is constant. 18736 18737 @liveexample{The following code shows an example for `end()`.,end} 18738 18739 @sa @ref cend() -- returns a const iterator to the end 18740 @sa @ref begin() -- returns an iterator to the beginning 18741 @sa @ref cbegin() -- returns a const iterator to the beginning 18742 18743 @since version 1.0.0 18744 */ 18745 iterator end() noexcept 18746 { 18747 iterator result(this); 18748 result.set_end(); 18749 return result; 18750 } 18751 18752 /*! 18753 @copydoc basic_json::cend() 18754 */ 18755 const_iterator end() const noexcept 18756 { 18757 return cend(); 18758 } 18759 18760 /*! 18761 @brief returns a const iterator to one past the last element 18762 18763 Returns a const iterator to one past the last element. 18764 18765 @image html range-begin-end.svg "Illustration from cppreference.com" 18766 18767 @return const iterator one past the last element 18768 18769 @complexity Constant. 18770 18771 @requirement This function helps `basic_json` satisfying the 18772 [Container](https://en.cppreference.com/w/cpp/named_req/Container) 18773 requirements: 18774 - The complexity is constant. 18775 - Has the semantics of `const_cast<const basic_json&>(*this).end()`. 18776 18777 @liveexample{The following code shows an example for `cend()`.,cend} 18778 18779 @sa @ref end() -- returns an iterator to the end 18780 @sa @ref begin() -- returns an iterator to the beginning 18781 @sa @ref cbegin() -- returns a const iterator to the beginning 18782 18783 @since version 1.0.0 18784 */ 18785 const_iterator cend() const noexcept 18786 { 18787 const_iterator result(this); 18788 result.set_end(); 18789 return result; 18790 } 18791 18792 /*! 18793 @brief returns an iterator to the reverse-beginning 18794 18795 Returns an iterator to the reverse-beginning; that is, the last element. 18796 18797 @image html range-rbegin-rend.svg "Illustration from cppreference.com" 18798 18799 @complexity Constant. 18800 18801 @requirement This function helps `basic_json` satisfying the 18802 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) 18803 requirements: 18804 - The complexity is constant. 18805 - Has the semantics of `reverse_iterator(end())`. 18806 18807 @liveexample{The following code shows an example for `rbegin()`.,rbegin} 18808 18809 @sa @ref crbegin() -- returns a const reverse iterator to the beginning 18810 @sa @ref rend() -- returns a reverse iterator to the end 18811 @sa @ref crend() -- returns a const reverse iterator to the end 18812 18813 @since version 1.0.0 18814 */ 18815 reverse_iterator rbegin() noexcept 18816 { 18817 return reverse_iterator(end()); 18818 } 18819 18820 /*! 18821 @copydoc basic_json::crbegin() 18822 */ 18823 const_reverse_iterator rbegin() const noexcept 18824 { 18825 return crbegin(); 18826 } 18827 18828 /*! 18829 @brief returns an iterator to the reverse-end 18830 18831 Returns an iterator to the reverse-end; that is, one before the first 18832 element. 18833 18834 @image html range-rbegin-rend.svg "Illustration from cppreference.com" 18835 18836 @complexity Constant. 18837 18838 @requirement This function helps `basic_json` satisfying the 18839 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) 18840 requirements: 18841 - The complexity is constant. 18842 - Has the semantics of `reverse_iterator(begin())`. 18843 18844 @liveexample{The following code shows an example for `rend()`.,rend} 18845 18846 @sa @ref crend() -- returns a const reverse iterator to the end 18847 @sa @ref rbegin() -- returns a reverse iterator to the beginning 18848 @sa @ref crbegin() -- returns a const reverse iterator to the beginning 18849 18850 @since version 1.0.0 18851 */ 18852 reverse_iterator rend() noexcept 18853 { 18854 return reverse_iterator(begin()); 18855 } 18856 18857 /*! 18858 @copydoc basic_json::crend() 18859 */ 18860 const_reverse_iterator rend() const noexcept 18861 { 18862 return crend(); 18863 } 18864 18865 /*! 18866 @brief returns a const reverse iterator to the last element 18867 18868 Returns a const iterator to the reverse-beginning; that is, the last 18869 element. 18870 18871 @image html range-rbegin-rend.svg "Illustration from cppreference.com" 18872 18873 @complexity Constant. 18874 18875 @requirement This function helps `basic_json` satisfying the 18876 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) 18877 requirements: 18878 - The complexity is constant. 18879 - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`. 18880 18881 @liveexample{The following code shows an example for `crbegin()`.,crbegin} 18882 18883 @sa @ref rbegin() -- returns a reverse iterator to the beginning 18884 @sa @ref rend() -- returns a reverse iterator to the end 18885 @sa @ref crend() -- returns a const reverse iterator to the end 18886 18887 @since version 1.0.0 18888 */ 18889 const_reverse_iterator crbegin() const noexcept 18890 { 18891 return const_reverse_iterator(cend()); 18892 } 18893 18894 /*! 18895 @brief returns a const reverse iterator to one before the first 18896 18897 Returns a const reverse iterator to the reverse-end; that is, one before 18898 the first element. 18899 18900 @image html range-rbegin-rend.svg "Illustration from cppreference.com" 18901 18902 @complexity Constant. 18903 18904 @requirement This function helps `basic_json` satisfying the 18905 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) 18906 requirements: 18907 - The complexity is constant. 18908 - Has the semantics of `const_cast<const basic_json&>(*this).rend()`. 18909 18910 @liveexample{The following code shows an example for `crend()`.,crend} 18911 18912 @sa @ref rend() -- returns a reverse iterator to the end 18913 @sa @ref rbegin() -- returns a reverse iterator to the beginning 18914 @sa @ref crbegin() -- returns a const reverse iterator to the beginning 18915 18916 @since version 1.0.0 18917 */ 18918 const_reverse_iterator crend() const noexcept 18919 { 18920 return const_reverse_iterator(cbegin()); 18921 } 18922 18923 public: 18924 /*! 18925 @brief wrapper to access iterator member functions in range-based for 18926 18927 This function allows to access @ref iterator::key() and @ref 18928 iterator::value() during range-based for loops. In these loops, a 18929 reference to the JSON values is returned, so there is no access to the 18930 underlying iterator. 18931 18932 For loop without iterator_wrapper: 18933 18934 @code{cpp} 18935 for (auto it = j_object.begin(); it != j_object.end(); ++it) 18936 { 18937 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n'; 18938 } 18939 @endcode 18940 18941 Range-based for loop without iterator proxy: 18942 18943 @code{cpp} 18944 for (auto it : j_object) 18945 { 18946 // "it" is of type json::reference and has no key() member 18947 std::cout << "value: " << it << '\n'; 18948 } 18949 @endcode 18950 18951 Range-based for loop with iterator proxy: 18952 18953 @code{cpp} 18954 for (auto it : json::iterator_wrapper(j_object)) 18955 { 18956 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n'; 18957 } 18958 @endcode 18959 18960 @note When iterating over an array, `key()` will return the index of the 18961 element as string (see example). 18962 18963 @param[in] ref reference to a JSON value 18964 @return iteration proxy object wrapping @a ref with an interface to use in 18965 range-based for loops 18966 18967 @liveexample{The following code shows how the wrapper is used,iterator_wrapper} 18968 18969 @exceptionsafety Strong guarantee: if an exception is thrown, there are no 18970 changes in the JSON value. 18971 18972 @complexity Constant. 18973 18974 @note The name of this function is not yet final and may change in the 18975 future. 18976 18977 @deprecated This stream operator is deprecated and will be removed in 18978 future 4.0.0 of the library. Please use @ref items() instead; 18979 that is, replace `json::iterator_wrapper(j)` with `j.items()`. 18980 */ 18981 JSON_HEDLEY_DEPRECATED(3.1.0) 18982 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept 18983 { 18984 return ref.items(); 18985 } 18986 18987 /*! 18988 @copydoc iterator_wrapper(reference) 18989 */ 18990 JSON_HEDLEY_DEPRECATED(3.1.0) 18991 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept 18992 { 18993 return ref.items(); 18994 } 18995 18996 /*! 18997 @brief helper to access iterator member functions in range-based for 18998 18999 This function allows to access @ref iterator::key() and @ref 19000 iterator::value() during range-based for loops. In these loops, a 19001 reference to the JSON values is returned, so there is no access to the 19002 underlying iterator. 19003 19004 For loop without `items()` function: 19005 19006 @code{cpp} 19007 for (auto it = j_object.begin(); it != j_object.end(); ++it) 19008 { 19009 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n'; 19010 } 19011 @endcode 19012 19013 Range-based for loop without `items()` function: 19014 19015 @code{cpp} 19016 for (auto it : j_object) 19017 { 19018 // "it" is of type json::reference and has no key() member 19019 std::cout << "value: " << it << '\n'; 19020 } 19021 @endcode 19022 19023 Range-based for loop with `items()` function: 19024 19025 @code{cpp} 19026 for (auto& el : j_object.items()) 19027 { 19028 std::cout << "key: " << el.key() << ", value:" << el.value() << '\n'; 19029 } 19030 @endcode 19031 19032 The `items()` function also allows to use 19033 [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding) 19034 (C++17): 19035 19036 @code{cpp} 19037 for (auto& [key, val] : j_object.items()) 19038 { 19039 std::cout << "key: " << key << ", value:" << val << '\n'; 19040 } 19041 @endcode 19042 19043 @note When iterating over an array, `key()` will return the index of the 19044 element as string (see example). For primitive types (e.g., numbers), 19045 `key()` returns an empty string. 19046 19047 @return iteration proxy object wrapping @a ref with an interface to use in 19048 range-based for loops 19049 19050 @liveexample{The following code shows how the function is used.,items} 19051 19052 @exceptionsafety Strong guarantee: if an exception is thrown, there are no 19053 changes in the JSON value. 19054 19055 @complexity Constant. 19056 19057 @since version 3.1.0, structured bindings support since 3.5.0. 19058 */ 19059 iteration_proxy<iterator> items() noexcept 19060 { 19061 return iteration_proxy<iterator>(*this); 19062 } 19063 19064 /*! 19065 @copydoc items() 19066 */ 19067 iteration_proxy<const_iterator> items() const noexcept 19068 { 19069 return iteration_proxy<const_iterator>(*this); 19070 } 19071 19072 /// @} 19073 19074 19075 ////////////// 19076 // capacity // 19077 ////////////// 19078 19079 /// @name capacity 19080 /// @{ 19081 19082 /*! 19083 @brief checks whether the container is empty. 19084 19085 Checks if a JSON value has no elements (i.e. whether its @ref size is `0`). 19086 19087 @return The return value depends on the different types and is 19088 defined as follows: 19089 Value type | return value 19090 ----------- | ------------- 19091 null | `true` 19092 boolean | `false` 19093 string | `false` 19094 number | `false` 19095 object | result of function `object_t::empty()` 19096 array | result of function `array_t::empty()` 19097 19098 @liveexample{The following code uses `empty()` to check if a JSON 19099 object contains any elements.,empty} 19100 19101 @complexity Constant, as long as @ref array_t and @ref object_t satisfy 19102 the Container concept; that is, their `empty()` functions have constant 19103 complexity. 19104 19105 @iterators No changes. 19106 19107 @exceptionsafety No-throw guarantee: this function never throws exceptions. 19108 19109 @note This function does not return whether a string stored as JSON value 19110 is empty - it returns whether the JSON container itself is empty which is 19111 false in the case of a string. 19112 19113 @requirement This function helps `basic_json` satisfying the 19114 [Container](https://en.cppreference.com/w/cpp/named_req/Container) 19115 requirements: 19116 - The complexity is constant. 19117 - Has the semantics of `begin() == end()`. 19118 19119 @sa @ref size() -- returns the number of elements 19120 19121 @since version 1.0.0 19122 */ 19123 bool empty() const noexcept 19124 { 19125 switch (m_type) 19126 { 19127 case value_t::null: 19128 { 19129 // null values are empty 19130 return true; 19131 } 19132 19133 case value_t::array: 19134 { 19135 // delegate call to array_t::empty() 19136 return m_value.array->empty(); 19137 } 19138 19139 case value_t::object: 19140 { 19141 // delegate call to object_t::empty() 19142 return m_value.object->empty(); 19143 } 19144 19145 default: 19146 { 19147 // all other types are nonempty 19148 return false; 19149 } 19150 } 19151 } 19152 19153 /*! 19154 @brief returns the number of elements 19155 19156 Returns the number of elements in a JSON value. 19157 19158 @return The return value depends on the different types and is 19159 defined as follows: 19160 Value type | return value 19161 ----------- | ------------- 19162 null | `0` 19163 boolean | `1` 19164 string | `1` 19165 number | `1` 19166 object | result of function object_t::size() 19167 array | result of function array_t::size() 19168 19169 @liveexample{The following code calls `size()` on the different value 19170 types.,size} 19171 19172 @complexity Constant, as long as @ref array_t and @ref object_t satisfy 19173 the Container concept; that is, their size() functions have constant 19174 complexity. 19175 19176 @iterators No changes. 19177 19178 @exceptionsafety No-throw guarantee: this function never throws exceptions. 19179 19180 @note This function does not return the length of a string stored as JSON 19181 value - it returns the number of elements in the JSON value which is 1 in 19182 the case of a string. 19183 19184 @requirement This function helps `basic_json` satisfying the 19185 [Container](https://en.cppreference.com/w/cpp/named_req/Container) 19186 requirements: 19187 - The complexity is constant. 19188 - Has the semantics of `std::distance(begin(), end())`. 19189 19190 @sa @ref empty() -- checks whether the container is empty 19191 @sa @ref max_size() -- returns the maximal number of elements 19192 19193 @since version 1.0.0 19194 */ 19195 size_type size() const noexcept 19196 { 19197 switch (m_type) 19198 { 19199 case value_t::null: 19200 { 19201 // null values are empty 19202 return 0; 19203 } 19204 19205 case value_t::array: 19206 { 19207 // delegate call to array_t::size() 19208 return m_value.array->size(); 19209 } 19210 19211 case value_t::object: 19212 { 19213 // delegate call to object_t::size() 19214 return m_value.object->size(); 19215 } 19216 19217 default: 19218 { 19219 // all other types have size 1 19220 return 1; 19221 } 19222 } 19223 } 19224 19225 /*! 19226 @brief returns the maximum possible number of elements 19227 19228 Returns the maximum number of elements a JSON value is able to hold due to 19229 system or library implementation limitations, i.e. `std::distance(begin(), 19230 end())` for the JSON value. 19231 19232 @return The return value depends on the different types and is 19233 defined as follows: 19234 Value type | return value 19235 ----------- | ------------- 19236 null | `0` (same as `size()`) 19237 boolean | `1` (same as `size()`) 19238 string | `1` (same as `size()`) 19239 number | `1` (same as `size()`) 19240 object | result of function `object_t::max_size()` 19241 array | result of function `array_t::max_size()` 19242 19243 @liveexample{The following code calls `max_size()` on the different value 19244 types. Note the output is implementation specific.,max_size} 19245 19246 @complexity Constant, as long as @ref array_t and @ref object_t satisfy 19247 the Container concept; that is, their `max_size()` functions have constant 19248 complexity. 19249 19250 @iterators No changes. 19251 19252 @exceptionsafety No-throw guarantee: this function never throws exceptions. 19253 19254 @requirement This function helps `basic_json` satisfying the 19255 [Container](https://en.cppreference.com/w/cpp/named_req/Container) 19256 requirements: 19257 - The complexity is constant. 19258 - Has the semantics of returning `b.size()` where `b` is the largest 19259 possible JSON value. 19260 19261 @sa @ref size() -- returns the number of elements 19262 19263 @since version 1.0.0 19264 */ 19265 size_type max_size() const noexcept 19266 { 19267 switch (m_type) 19268 { 19269 case value_t::array: 19270 { 19271 // delegate call to array_t::max_size() 19272 return m_value.array->max_size(); 19273 } 19274 19275 case value_t::object: 19276 { 19277 // delegate call to object_t::max_size() 19278 return m_value.object->max_size(); 19279 } 19280 19281 default: 19282 { 19283 // all other types have max_size() == size() 19284 return size(); 19285 } 19286 } 19287 } 19288 19289 /// @} 19290 19291 19292 /////////////// 19293 // modifiers // 19294 /////////////// 19295 19296 /// @name modifiers 19297 /// @{ 19298 19299 /*! 19300 @brief clears the contents 19301 19302 Clears the content of a JSON value and resets it to the default value as 19303 if @ref basic_json(value_t) would have been called with the current value 19304 type from @ref type(): 19305 19306 Value type | initial value 19307 ----------- | ------------- 19308 null | `null` 19309 boolean | `false` 19310 string | `""` 19311 number | `0` 19312 object | `{}` 19313 array | `[]` 19314 19315 @post Has the same effect as calling 19316 @code {.cpp} 19317 *this = basic_json(type()); 19318 @endcode 19319 19320 @liveexample{The example below shows the effect of `clear()` to different 19321 JSON types.,clear} 19322 19323 @complexity Linear in the size of the JSON value. 19324 19325 @iterators All iterators, pointers and references related to this container 19326 are invalidated. 19327 19328 @exceptionsafety No-throw guarantee: this function never throws exceptions. 19329 19330 @sa @ref basic_json(value_t) -- constructor that creates an object with the 19331 same value than calling `clear()` 19332 19333 @since version 1.0.0 19334 */ 19335 void clear() noexcept 19336 { 19337 switch (m_type) 19338 { 19339 case value_t::number_integer: 19340 { 19341 m_value.number_integer = 0; 19342 break; 19343 } 19344 19345 case value_t::number_unsigned: 19346 { 19347 m_value.number_unsigned = 0; 19348 break; 19349 } 19350 19351 case value_t::number_float: 19352 { 19353 m_value.number_float = 0.0; 19354 break; 19355 } 19356 19357 case value_t::boolean: 19358 { 19359 m_value.boolean = false; 19360 break; 19361 } 19362 19363 case value_t::string: 19364 { 19365 m_value.string->clear(); 19366 break; 19367 } 19368 19369 case value_t::array: 19370 { 19371 m_value.array->clear(); 19372 break; 19373 } 19374 19375 case value_t::object: 19376 { 19377 m_value.object->clear(); 19378 break; 19379 } 19380 19381 default: 19382 break; 19383 } 19384 } 19385 19386 /*! 19387 @brief add an object to an array 19388 19389 Appends the given element @a val to the end of the JSON value. If the 19390 function is called on a JSON null value, an empty array is created before 19391 appending @a val. 19392 19393 @param[in] val the value to add to the JSON array 19394 19395 @throw type_error.308 when called on a type other than JSON array or 19396 null; example: `"cannot use push_back() with number"` 19397 19398 @complexity Amortized constant. 19399 19400 @liveexample{The example shows how `push_back()` and `+=` can be used to 19401 add elements to a JSON array. Note how the `null` value was silently 19402 converted to a JSON array.,push_back} 19403 19404 @since version 1.0.0 19405 */ 19406 void push_back(basic_json&& val) 19407 { 19408 // push_back only works for null objects or arrays 19409 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array()))) 19410 { 19411 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()))); 19412 } 19413 19414 // transform null object into an array 19415 if (is_null()) 19416 { 19417 m_type = value_t::array; 19418 m_value = value_t::array; 19419 assert_invariant(); 19420 } 19421 19422 // add element to array (move semantics) 19423 m_value.array->push_back(std::move(val)); 19424 // invalidate object: mark it null so we do not call the destructor 19425 // cppcheck-suppress accessMoved 19426 val.m_type = value_t::null; 19427 } 19428 19429 /*! 19430 @brief add an object to an array 19431 @copydoc push_back(basic_json&&) 19432 */ 19433 reference operator+=(basic_json&& val) 19434 { 19435 push_back(std::move(val)); 19436 return *this; 19437 } 19438 19439 /*! 19440 @brief add an object to an array 19441 @copydoc push_back(basic_json&&) 19442 */ 19443 void push_back(const basic_json& val) 19444 { 19445 // push_back only works for null objects or arrays 19446 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array()))) 19447 { 19448 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()))); 19449 } 19450 19451 // transform null object into an array 19452 if (is_null()) 19453 { 19454 m_type = value_t::array; 19455 m_value = value_t::array; 19456 assert_invariant(); 19457 } 19458 19459 // add element to array 19460 m_value.array->push_back(val); 19461 } 19462 19463 /*! 19464 @brief add an object to an array 19465 @copydoc push_back(basic_json&&) 19466 */ 19467 reference operator+=(const basic_json& val) 19468 { 19469 push_back(val); 19470 return *this; 19471 } 19472 19473 /*! 19474 @brief add an object to an object 19475 19476 Inserts the given element @a val to the JSON object. If the function is 19477 called on a JSON null value, an empty object is created before inserting 19478 @a val. 19479 19480 @param[in] val the value to add to the JSON object 19481 19482 @throw type_error.308 when called on a type other than JSON object or 19483 null; example: `"cannot use push_back() with number"` 19484 19485 @complexity Logarithmic in the size of the container, O(log(`size()`)). 19486 19487 @liveexample{The example shows how `push_back()` and `+=` can be used to 19488 add elements to a JSON object. Note how the `null` value was silently 19489 converted to a JSON object.,push_back__object_t__value} 19490 19491 @since version 1.0.0 19492 */ 19493 void push_back(const typename object_t::value_type& val) 19494 { 19495 // push_back only works for null objects or objects 19496 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_object()))) 19497 { 19498 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()))); 19499 } 19500 19501 // transform null object into an object 19502 if (is_null()) 19503 { 19504 m_type = value_t::object; 19505 m_value = value_t::object; 19506 assert_invariant(); 19507 } 19508 19509 // add element to array 19510 m_value.object->insert(val); 19511 } 19512 19513 /*! 19514 @brief add an object to an object 19515 @copydoc push_back(const typename object_t::value_type&) 19516 */ 19517 reference operator+=(const typename object_t::value_type& val) 19518 { 19519 push_back(val); 19520 return *this; 19521 } 19522 19523 /*! 19524 @brief add an object to an object 19525 19526 This function allows to use `push_back` with an initializer list. In case 19527 19528 1. the current value is an object, 19529 2. the initializer list @a init contains only two elements, and 19530 3. the first element of @a init is a string, 19531 19532 @a init is converted into an object element and added using 19533 @ref push_back(const typename object_t::value_type&). Otherwise, @a init 19534 is converted to a JSON value and added using @ref push_back(basic_json&&). 19535 19536 @param[in] init an initializer list 19537 19538 @complexity Linear in the size of the initializer list @a init. 19539 19540 @note This function is required to resolve an ambiguous overload error, 19541 because pairs like `{"key", "value"}` can be both interpreted as 19542 `object_t::value_type` or `std::initializer_list<basic_json>`, see 19543 https://github.com/nlohmann/json/issues/235 for more information. 19544 19545 @liveexample{The example shows how initializer lists are treated as 19546 objects when possible.,push_back__initializer_list} 19547 */ 19548 void push_back(initializer_list_t init) 19549 { 19550 if (is_object() and init.size() == 2 and (*init.begin())->is_string()) 19551 { 19552 basic_json&& key = init.begin()->moved_or_copied(); 19553 push_back(typename object_t::value_type( 19554 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied())); 19555 } 19556 else 19557 { 19558 push_back(basic_json(init)); 19559 } 19560 } 19561 19562 /*! 19563 @brief add an object to an object 19564 @copydoc push_back(initializer_list_t) 19565 */ 19566 reference operator+=(initializer_list_t init) 19567 { 19568 push_back(init); 19569 return *this; 19570 } 19571 19572 /*! 19573 @brief add an object to an array 19574 19575 Creates a JSON value from the passed parameters @a args to the end of the 19576 JSON value. If the function is called on a JSON null value, an empty array 19577 is created before appending the value created from @a args. 19578 19579 @param[in] args arguments to forward to a constructor of @ref basic_json 19580 @tparam Args compatible types to create a @ref basic_json object 19581 19582 @return reference to the inserted element 19583 19584 @throw type_error.311 when called on a type other than JSON array or 19585 null; example: `"cannot use emplace_back() with number"` 19586 19587 @complexity Amortized constant. 19588 19589 @liveexample{The example shows how `push_back()` can be used to add 19590 elements to a JSON array. Note how the `null` value was silently converted 19591 to a JSON array.,emplace_back} 19592 19593 @since version 2.0.8, returns reference since 3.7.0 19594 */ 19595 template<class... Args> 19596 reference emplace_back(Args&& ... args) 19597 { 19598 // emplace_back only works for null objects or arrays 19599 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array()))) 19600 { 19601 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()))); 19602 } 19603 19604 // transform null object into an array 19605 if (is_null()) 19606 { 19607 m_type = value_t::array; 19608 m_value = value_t::array; 19609 assert_invariant(); 19610 } 19611 19612 // add element to array (perfect forwarding) 19613#ifdef JSON_HAS_CPP_17 19614 return m_value.array->emplace_back(std::forward<Args>(args)...); 19615#else 19616 m_value.array->emplace_back(std::forward<Args>(args)...); 19617 return m_value.array->back(); 19618#endif 19619 } 19620 19621 /*! 19622 @brief add an object to an object if key does not exist 19623 19624 Inserts a new element into a JSON object constructed in-place with the 19625 given @a args if there is no element with the key in the container. If the 19626 function is called on a JSON null value, an empty object is created before 19627 appending the value created from @a args. 19628 19629 @param[in] args arguments to forward to a constructor of @ref basic_json 19630 @tparam Args compatible types to create a @ref basic_json object 19631 19632 @return a pair consisting of an iterator to the inserted element, or the 19633 already-existing element if no insertion happened, and a bool 19634 denoting whether the insertion took place. 19635 19636 @throw type_error.311 when called on a type other than JSON object or 19637 null; example: `"cannot use emplace() with number"` 19638 19639 @complexity Logarithmic in the size of the container, O(log(`size()`)). 19640 19641 @liveexample{The example shows how `emplace()` can be used to add elements 19642 to a JSON object. Note how the `null` value was silently converted to a 19643 JSON object. Further note how no value is added if there was already one 19644 value stored with the same key.,emplace} 19645 19646 @since version 2.0.8 19647 */ 19648 template<class... Args> 19649 std::pair<iterator, bool> emplace(Args&& ... args) 19650 { 19651 // emplace only works for null objects or arrays 19652 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_object()))) 19653 { 19654 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()))); 19655 } 19656 19657 // transform null object into an object 19658 if (is_null()) 19659 { 19660 m_type = value_t::object; 19661 m_value = value_t::object; 19662 assert_invariant(); 19663 } 19664 19665 // add element to array (perfect forwarding) 19666 auto res = m_value.object->emplace(std::forward<Args>(args)...); 19667 // create result iterator and set iterator to the result of emplace 19668 auto it = begin(); 19669 it.m_it.object_iterator = res.first; 19670 19671 // return pair of iterator and boolean 19672 return {it, res.second}; 19673 } 19674 19675 /// Helper for insertion of an iterator 19676 /// @note: This uses std::distance to support GCC 4.8, 19677 /// see https://github.com/nlohmann/json/pull/1257 19678 template<typename... Args> 19679 iterator insert_iterator(const_iterator pos, Args&& ... args) 19680 { 19681 iterator result(this); 19682 assert(m_value.array != nullptr); 19683 19684 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator); 19685 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...); 19686 result.m_it.array_iterator = m_value.array->begin() + insert_pos; 19687 19688 // This could have been written as: 19689 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val); 19690 // but the return value of insert is missing in GCC 4.8, so it is written this way instead. 19691 19692 return result; 19693 } 19694 19695 /*! 19696 @brief inserts element 19697 19698 Inserts element @a val before iterator @a pos. 19699 19700 @param[in] pos iterator before which the content will be inserted; may be 19701 the end() iterator 19702 @param[in] val element to insert 19703 @return iterator pointing to the inserted @a val. 19704 19705 @throw type_error.309 if called on JSON values other than arrays; 19706 example: `"cannot use insert() with string"` 19707 @throw invalid_iterator.202 if @a pos is not an iterator of *this; 19708 example: `"iterator does not fit current value"` 19709 19710 @complexity Constant plus linear in the distance between @a pos and end of 19711 the container. 19712 19713 @liveexample{The example shows how `insert()` is used.,insert} 19714 19715 @since version 1.0.0 19716 */ 19717 iterator insert(const_iterator pos, const basic_json& val) 19718 { 19719 // insert only works for arrays 19720 if (JSON_HEDLEY_LIKELY(is_array())) 19721 { 19722 // check if iterator pos fits to this JSON value 19723 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) 19724 { 19725 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value")); 19726 } 19727 19728 // insert to array and return iterator 19729 return insert_iterator(pos, val); 19730 } 19731 19732 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()))); 19733 } 19734 19735 /*! 19736 @brief inserts element 19737 @copydoc insert(const_iterator, const basic_json&) 19738 */ 19739 iterator insert(const_iterator pos, basic_json&& val) 19740 { 19741 return insert(pos, val); 19742 } 19743 19744 /*! 19745 @brief inserts elements 19746 19747 Inserts @a cnt copies of @a val before iterator @a pos. 19748 19749 @param[in] pos iterator before which the content will be inserted; may be 19750 the end() iterator 19751 @param[in] cnt number of copies of @a val to insert 19752 @param[in] val element to insert 19753 @return iterator pointing to the first element inserted, or @a pos if 19754 `cnt==0` 19755 19756 @throw type_error.309 if called on JSON values other than arrays; example: 19757 `"cannot use insert() with string"` 19758 @throw invalid_iterator.202 if @a pos is not an iterator of *this; 19759 example: `"iterator does not fit current value"` 19760 19761 @complexity Linear in @a cnt plus linear in the distance between @a pos 19762 and end of the container. 19763 19764 @liveexample{The example shows how `insert()` is used.,insert__count} 19765 19766 @since version 1.0.0 19767 */ 19768 iterator insert(const_iterator pos, size_type cnt, const basic_json& val) 19769 { 19770 // insert only works for arrays 19771 if (JSON_HEDLEY_LIKELY(is_array())) 19772 { 19773 // check if iterator pos fits to this JSON value 19774 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) 19775 { 19776 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value")); 19777 } 19778 19779 // insert to array and return iterator 19780 return insert_iterator(pos, cnt, val); 19781 } 19782 19783 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()))); 19784 } 19785 19786 /*! 19787 @brief inserts elements 19788 19789 Inserts elements from range `[first, last)` before iterator @a pos. 19790 19791 @param[in] pos iterator before which the content will be inserted; may be 19792 the end() iterator 19793 @param[in] first begin of the range of elements to insert 19794 @param[in] last end of the range of elements to insert 19795 19796 @throw type_error.309 if called on JSON values other than arrays; example: 19797 `"cannot use insert() with string"` 19798 @throw invalid_iterator.202 if @a pos is not an iterator of *this; 19799 example: `"iterator does not fit current value"` 19800 @throw invalid_iterator.210 if @a first and @a last do not belong to the 19801 same JSON value; example: `"iterators do not fit"` 19802 @throw invalid_iterator.211 if @a first or @a last are iterators into 19803 container for which insert is called; example: `"passed iterators may not 19804 belong to container"` 19805 19806 @return iterator pointing to the first element inserted, or @a pos if 19807 `first==last` 19808 19809 @complexity Linear in `std::distance(first, last)` plus linear in the 19810 distance between @a pos and end of the container. 19811 19812 @liveexample{The example shows how `insert()` is used.,insert__range} 19813 19814 @since version 1.0.0 19815 */ 19816 iterator insert(const_iterator pos, const_iterator first, const_iterator last) 19817 { 19818 // insert only works for arrays 19819 if (JSON_HEDLEY_UNLIKELY(not is_array())) 19820 { 19821 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()))); 19822 } 19823 19824 // check if iterator pos fits to this JSON value 19825 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) 19826 { 19827 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value")); 19828 } 19829 19830 // check if range iterators belong to the same JSON object 19831 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) 19832 { 19833 JSON_THROW(invalid_iterator::create(210, "iterators do not fit")); 19834 } 19835 19836 if (JSON_HEDLEY_UNLIKELY(first.m_object == this)) 19837 { 19838 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container")); 19839 } 19840 19841 // insert to array and return iterator 19842 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator); 19843 } 19844 19845 /*! 19846 @brief inserts elements 19847 19848 Inserts elements from initializer list @a ilist before iterator @a pos. 19849 19850 @param[in] pos iterator before which the content will be inserted; may be 19851 the end() iterator 19852 @param[in] ilist initializer list to insert the values from 19853 19854 @throw type_error.309 if called on JSON values other than arrays; example: 19855 `"cannot use insert() with string"` 19856 @throw invalid_iterator.202 if @a pos is not an iterator of *this; 19857 example: `"iterator does not fit current value"` 19858 19859 @return iterator pointing to the first element inserted, or @a pos if 19860 `ilist` is empty 19861 19862 @complexity Linear in `ilist.size()` plus linear in the distance between 19863 @a pos and end of the container. 19864 19865 @liveexample{The example shows how `insert()` is used.,insert__ilist} 19866 19867 @since version 1.0.0 19868 */ 19869 iterator insert(const_iterator pos, initializer_list_t ilist) 19870 { 19871 // insert only works for arrays 19872 if (JSON_HEDLEY_UNLIKELY(not is_array())) 19873 { 19874 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()))); 19875 } 19876 19877 // check if iterator pos fits to this JSON value 19878 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) 19879 { 19880 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value")); 19881 } 19882 19883 // insert to array and return iterator 19884 return insert_iterator(pos, ilist.begin(), ilist.end()); 19885 } 19886 19887 /*! 19888 @brief inserts elements 19889 19890 Inserts elements from range `[first, last)`. 19891 19892 @param[in] first begin of the range of elements to insert 19893 @param[in] last end of the range of elements to insert 19894 19895 @throw type_error.309 if called on JSON values other than objects; example: 19896 `"cannot use insert() with string"` 19897 @throw invalid_iterator.202 if iterator @a first or @a last does does not 19898 point to an object; example: `"iterators first and last must point to 19899 objects"` 19900 @throw invalid_iterator.210 if @a first and @a last do not belong to the 19901 same JSON value; example: `"iterators do not fit"` 19902 19903 @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number 19904 of elements to insert. 19905 19906 @liveexample{The example shows how `insert()` is used.,insert__range_object} 19907 19908 @since version 3.0.0 19909 */ 19910 void insert(const_iterator first, const_iterator last) 19911 { 19912 // insert only works for objects 19913 if (JSON_HEDLEY_UNLIKELY(not is_object())) 19914 { 19915 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()))); 19916 } 19917 19918 // check if range iterators belong to the same JSON object 19919 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) 19920 { 19921 JSON_THROW(invalid_iterator::create(210, "iterators do not fit")); 19922 } 19923 19924 // passed iterators must belong to objects 19925 if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object())) 19926 { 19927 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects")); 19928 } 19929 19930 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator); 19931 } 19932 19933 /*! 19934 @brief updates a JSON object from another object, overwriting existing keys 19935 19936 Inserts all values from JSON object @a j and overwrites existing keys. 19937 19938 @param[in] j JSON object to read values from 19939 19940 @throw type_error.312 if called on JSON values other than objects; example: 19941 `"cannot use update() with string"` 19942 19943 @complexity O(N*log(size() + N)), where N is the number of elements to 19944 insert. 19945 19946 @liveexample{The example shows how `update()` is used.,update} 19947 19948 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update 19949 19950 @since version 3.0.0 19951 */ 19952 void update(const_reference j) 19953 { 19954 // implicitly convert null value to an empty object 19955 if (is_null()) 19956 { 19957 m_type = value_t::object; 19958 m_value.object = create<object_t>(); 19959 assert_invariant(); 19960 } 19961 19962 if (JSON_HEDLEY_UNLIKELY(not is_object())) 19963 { 19964 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()))); 19965 } 19966 if (JSON_HEDLEY_UNLIKELY(not j.is_object())) 19967 { 19968 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()))); 19969 } 19970 19971 for (auto it = j.cbegin(); it != j.cend(); ++it) 19972 { 19973 m_value.object->operator[](it.key()) = it.value(); 19974 } 19975 } 19976 19977 /*! 19978 @brief updates a JSON object from another object, overwriting existing keys 19979 19980 Inserts all values from from range `[first, last)` and overwrites existing 19981 keys. 19982 19983 @param[in] first begin of the range of elements to insert 19984 @param[in] last end of the range of elements to insert 19985 19986 @throw type_error.312 if called on JSON values other than objects; example: 19987 `"cannot use update() with string"` 19988 @throw invalid_iterator.202 if iterator @a first or @a last does does not 19989 point to an object; example: `"iterators first and last must point to 19990 objects"` 19991 @throw invalid_iterator.210 if @a first and @a last do not belong to the 19992 same JSON value; example: `"iterators do not fit"` 19993 19994 @complexity O(N*log(size() + N)), where N is the number of elements to 19995 insert. 19996 19997 @liveexample{The example shows how `update()` is used__range.,update} 19998 19999 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update 20000 20001 @since version 3.0.0 20002 */ 20003 void update(const_iterator first, const_iterator last) 20004 { 20005 // implicitly convert null value to an empty object 20006 if (is_null()) 20007 { 20008 m_type = value_t::object; 20009 m_value.object = create<object_t>(); 20010 assert_invariant(); 20011 } 20012 20013 if (JSON_HEDLEY_UNLIKELY(not is_object())) 20014 { 20015 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()))); 20016 } 20017 20018 // check if range iterators belong to the same JSON object 20019 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) 20020 { 20021 JSON_THROW(invalid_iterator::create(210, "iterators do not fit")); 20022 } 20023 20024 // passed iterators must belong to objects 20025 if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object() 20026 or not last.m_object->is_object())) 20027 { 20028 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects")); 20029 } 20030 20031 for (auto it = first; it != last; ++it) 20032 { 20033 m_value.object->operator[](it.key()) = it.value(); 20034 } 20035 } 20036 20037 /*! 20038 @brief exchanges the values 20039 20040 Exchanges the contents of the JSON value with those of @a other. Does not 20041 invoke any move, copy, or swap operations on individual elements. All 20042 iterators and references remain valid. The past-the-end iterator is 20043 invalidated. 20044 20045 @param[in,out] other JSON value to exchange the contents with 20046 20047 @complexity Constant. 20048 20049 @liveexample{The example below shows how JSON values can be swapped with 20050 `swap()`.,swap__reference} 20051 20052 @since version 1.0.0 20053 */ 20054 void swap(reference other) noexcept ( 20055 std::is_nothrow_move_constructible<value_t>::value and 20056 std::is_nothrow_move_assignable<value_t>::value and 20057 std::is_nothrow_move_constructible<json_value>::value and 20058 std::is_nothrow_move_assignable<json_value>::value 20059 ) 20060 { 20061 std::swap(m_type, other.m_type); 20062 std::swap(m_value, other.m_value); 20063 assert_invariant(); 20064 } 20065 20066 /*! 20067 @brief exchanges the values 20068 20069 Exchanges the contents of a JSON array with those of @a other. Does not 20070 invoke any move, copy, or swap operations on individual elements. All 20071 iterators and references remain valid. The past-the-end iterator is 20072 invalidated. 20073 20074 @param[in,out] other array to exchange the contents with 20075 20076 @throw type_error.310 when JSON value is not an array; example: `"cannot 20077 use swap() with string"` 20078 20079 @complexity Constant. 20080 20081 @liveexample{The example below shows how arrays can be swapped with 20082 `swap()`.,swap__array_t} 20083 20084 @since version 1.0.0 20085 */ 20086 void swap(array_t& other) 20087 { 20088 // swap only works for arrays 20089 if (JSON_HEDLEY_LIKELY(is_array())) 20090 { 20091 std::swap(*(m_value.array), other); 20092 } 20093 else 20094 { 20095 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()))); 20096 } 20097 } 20098 20099 /*! 20100 @brief exchanges the values 20101 20102 Exchanges the contents of a JSON object with those of @a other. Does not 20103 invoke any move, copy, or swap operations on individual elements. All 20104 iterators and references remain valid. The past-the-end iterator is 20105 invalidated. 20106 20107 @param[in,out] other object to exchange the contents with 20108 20109 @throw type_error.310 when JSON value is not an object; example: 20110 `"cannot use swap() with string"` 20111 20112 @complexity Constant. 20113 20114 @liveexample{The example below shows how objects can be swapped with 20115 `swap()`.,swap__object_t} 20116 20117 @since version 1.0.0 20118 */ 20119 void swap(object_t& other) 20120 { 20121 // swap only works for objects 20122 if (JSON_HEDLEY_LIKELY(is_object())) 20123 { 20124 std::swap(*(m_value.object), other); 20125 } 20126 else 20127 { 20128 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()))); 20129 } 20130 } 20131 20132 /*! 20133 @brief exchanges the values 20134 20135 Exchanges the contents of a JSON string with those of @a other. Does not 20136 invoke any move, copy, or swap operations on individual elements. All 20137 iterators and references remain valid. The past-the-end iterator is 20138 invalidated. 20139 20140 @param[in,out] other string to exchange the contents with 20141 20142 @throw type_error.310 when JSON value is not a string; example: `"cannot 20143 use swap() with boolean"` 20144 20145 @complexity Constant. 20146 20147 @liveexample{The example below shows how strings can be swapped with 20148 `swap()`.,swap__string_t} 20149 20150 @since version 1.0.0 20151 */ 20152 void swap(string_t& other) 20153 { 20154 // swap only works for strings 20155 if (JSON_HEDLEY_LIKELY(is_string())) 20156 { 20157 std::swap(*(m_value.string), other); 20158 } 20159 else 20160 { 20161 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()))); 20162 } 20163 } 20164 20165 /// @} 20166 20167 public: 20168 ////////////////////////////////////////// 20169 // lexicographical comparison operators // 20170 ////////////////////////////////////////// 20171 20172 /// @name lexicographical comparison operators 20173 /// @{ 20174 20175 /*! 20176 @brief comparison: equal 20177 20178 Compares two JSON values for equality according to the following rules: 20179 - Two JSON values are equal if (1) they are from the same type and (2) 20180 their stored values are the same according to their respective 20181 `operator==`. 20182 - Integer and floating-point numbers are automatically converted before 20183 comparison. Note than two NaN values are always treated as unequal. 20184 - Two JSON null values are equal. 20185 20186 @note Floating-point inside JSON values numbers are compared with 20187 `json::number_float_t::operator==` which is `double::operator==` by 20188 default. To compare floating-point while respecting an epsilon, an alternative 20189 [comparison function](https://github.com/mariokonrad/marnav/blob/master/src/marnav/math/floatingpoint.hpp#L34-#L39) 20190 could be used, for instance 20191 @code {.cpp} 20192 template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type> 20193 inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept 20194 { 20195 return std::abs(a - b) <= epsilon; 20196 } 20197 @endcode 20198 20199 @note NaN values never compare equal to themselves or to other NaN values. 20200 20201 @param[in] lhs first JSON value to consider 20202 @param[in] rhs second JSON value to consider 20203 @return whether the values @a lhs and @a rhs are equal 20204 20205 @exceptionsafety No-throw guarantee: this function never throws exceptions. 20206 20207 @complexity Linear. 20208 20209 @liveexample{The example demonstrates comparing several JSON 20210 types.,operator__equal} 20211 20212 @since version 1.0.0 20213 */ 20214 friend bool operator==(const_reference lhs, const_reference rhs) noexcept 20215 { 20216 const auto lhs_type = lhs.type(); 20217 const auto rhs_type = rhs.type(); 20218 20219 if (lhs_type == rhs_type) 20220 { 20221 switch (lhs_type) 20222 { 20223 case value_t::array: 20224 return *lhs.m_value.array == *rhs.m_value.array; 20225 20226 case value_t::object: 20227 return *lhs.m_value.object == *rhs.m_value.object; 20228 20229 case value_t::null: 20230 return true; 20231 20232 case value_t::string: 20233 return *lhs.m_value.string == *rhs.m_value.string; 20234 20235 case value_t::boolean: 20236 return lhs.m_value.boolean == rhs.m_value.boolean; 20237 20238 case value_t::number_integer: 20239 return lhs.m_value.number_integer == rhs.m_value.number_integer; 20240 20241 case value_t::number_unsigned: 20242 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned; 20243 20244 case value_t::number_float: 20245 return lhs.m_value.number_float == rhs.m_value.number_float; 20246 20247 default: 20248 return false; 20249 } 20250 } 20251 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float) 20252 { 20253 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float; 20254 } 20255 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer) 20256 { 20257 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer); 20258 } 20259 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float) 20260 { 20261 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float; 20262 } 20263 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned) 20264 { 20265 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned); 20266 } 20267 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer) 20268 { 20269 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer; 20270 } 20271 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned) 20272 { 20273 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned); 20274 } 20275 20276 return false; 20277 } 20278 20279 /*! 20280 @brief comparison: equal 20281 @copydoc operator==(const_reference, const_reference) 20282 */ 20283 template<typename ScalarType, typename std::enable_if< 20284 std::is_scalar<ScalarType>::value, int>::type = 0> 20285 friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept 20286 { 20287 return lhs == basic_json(rhs); 20288 } 20289 20290 /*! 20291 @brief comparison: equal 20292 @copydoc operator==(const_reference, const_reference) 20293 */ 20294 template<typename ScalarType, typename std::enable_if< 20295 std::is_scalar<ScalarType>::value, int>::type = 0> 20296 friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept 20297 { 20298 return basic_json(lhs) == rhs; 20299 } 20300 20301 /*! 20302 @brief comparison: not equal 20303 20304 Compares two JSON values for inequality by calculating `not (lhs == rhs)`. 20305 20306 @param[in] lhs first JSON value to consider 20307 @param[in] rhs second JSON value to consider 20308 @return whether the values @a lhs and @a rhs are not equal 20309 20310 @complexity Linear. 20311 20312 @exceptionsafety No-throw guarantee: this function never throws exceptions. 20313 20314 @liveexample{The example demonstrates comparing several JSON 20315 types.,operator__notequal} 20316 20317 @since version 1.0.0 20318 */ 20319 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept 20320 { 20321 return not (lhs == rhs); 20322 } 20323 20324 /*! 20325 @brief comparison: not equal 20326 @copydoc operator!=(const_reference, const_reference) 20327 */ 20328 template<typename ScalarType, typename std::enable_if< 20329 std::is_scalar<ScalarType>::value, int>::type = 0> 20330 friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept 20331 { 20332 return lhs != basic_json(rhs); 20333 } 20334 20335 /*! 20336 @brief comparison: not equal 20337 @copydoc operator!=(const_reference, const_reference) 20338 */ 20339 template<typename ScalarType, typename std::enable_if< 20340 std::is_scalar<ScalarType>::value, int>::type = 0> 20341 friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept 20342 { 20343 return basic_json(lhs) != rhs; 20344 } 20345 20346 /*! 20347 @brief comparison: less than 20348 20349 Compares whether one JSON value @a lhs is less than another JSON value @a 20350 rhs according to the following rules: 20351 - If @a lhs and @a rhs have the same type, the values are compared using 20352 the default `<` operator. 20353 - Integer and floating-point numbers are automatically converted before 20354 comparison 20355 - In case @a lhs and @a rhs have different types, the values are ignored 20356 and the order of the types is considered, see 20357 @ref operator<(const value_t, const value_t). 20358 20359 @param[in] lhs first JSON value to consider 20360 @param[in] rhs second JSON value to consider 20361 @return whether @a lhs is less than @a rhs 20362 20363 @complexity Linear. 20364 20365 @exceptionsafety No-throw guarantee: this function never throws exceptions. 20366 20367 @liveexample{The example demonstrates comparing several JSON 20368 types.,operator__less} 20369 20370 @since version 1.0.0 20371 */ 20372 friend bool operator<(const_reference lhs, const_reference rhs) noexcept 20373 { 20374 const auto lhs_type = lhs.type(); 20375 const auto rhs_type = rhs.type(); 20376 20377 if (lhs_type == rhs_type) 20378 { 20379 switch (lhs_type) 20380 { 20381 case value_t::array: 20382 // note parentheses are necessary, see 20383 // https://github.com/nlohmann/json/issues/1530 20384 return (*lhs.m_value.array) < (*rhs.m_value.array); 20385 20386 case value_t::object: 20387 return (*lhs.m_value.object) < (*rhs.m_value.object); 20388 20389 case value_t::null: 20390 return false; 20391 20392 case value_t::string: 20393 return (*lhs.m_value.string) < (*rhs.m_value.string); 20394 20395 case value_t::boolean: 20396 return (lhs.m_value.boolean) < (rhs.m_value.boolean); 20397 20398 case value_t::number_integer: 20399 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer); 20400 20401 case value_t::number_unsigned: 20402 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned); 20403 20404 case value_t::number_float: 20405 return (lhs.m_value.number_float) < (rhs.m_value.number_float); 20406 20407 default: 20408 return false; 20409 } 20410 } 20411 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float) 20412 { 20413 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float; 20414 } 20415 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer) 20416 { 20417 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer); 20418 } 20419 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float) 20420 { 20421 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float; 20422 } 20423 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned) 20424 { 20425 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned); 20426 } 20427 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned) 20428 { 20429 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned); 20430 } 20431 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer) 20432 { 20433 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer; 20434 } 20435 20436 // We only reach this line if we cannot compare values. In that case, 20437 // we compare types. Note we have to call the operator explicitly, 20438 // because MSVC has problems otherwise. 20439 return operator<(lhs_type, rhs_type); 20440 } 20441 20442 /*! 20443 @brief comparison: less than 20444 @copydoc operator<(const_reference, const_reference) 20445 */ 20446 template<typename ScalarType, typename std::enable_if< 20447 std::is_scalar<ScalarType>::value, int>::type = 0> 20448 friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept 20449 { 20450 return lhs < basic_json(rhs); 20451 } 20452 20453 /*! 20454 @brief comparison: less than 20455 @copydoc operator<(const_reference, const_reference) 20456 */ 20457 template<typename ScalarType, typename std::enable_if< 20458 std::is_scalar<ScalarType>::value, int>::type = 0> 20459 friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept 20460 { 20461 return basic_json(lhs) < rhs; 20462 } 20463 20464 /*! 20465 @brief comparison: less than or equal 20466 20467 Compares whether one JSON value @a lhs is less than or equal to another 20468 JSON value by calculating `not (rhs < lhs)`. 20469 20470 @param[in] lhs first JSON value to consider 20471 @param[in] rhs second JSON value to consider 20472 @return whether @a lhs is less than or equal to @a rhs 20473 20474 @complexity Linear. 20475 20476 @exceptionsafety No-throw guarantee: this function never throws exceptions. 20477 20478 @liveexample{The example demonstrates comparing several JSON 20479 types.,operator__greater} 20480 20481 @since version 1.0.0 20482 */ 20483 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept 20484 { 20485 return not (rhs < lhs); 20486 } 20487 20488 /*! 20489 @brief comparison: less than or equal 20490 @copydoc operator<=(const_reference, const_reference) 20491 */ 20492 template<typename ScalarType, typename std::enable_if< 20493 std::is_scalar<ScalarType>::value, int>::type = 0> 20494 friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept 20495 { 20496 return lhs <= basic_json(rhs); 20497 } 20498 20499 /*! 20500 @brief comparison: less than or equal 20501 @copydoc operator<=(const_reference, const_reference) 20502 */ 20503 template<typename ScalarType, typename std::enable_if< 20504 std::is_scalar<ScalarType>::value, int>::type = 0> 20505 friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept 20506 { 20507 return basic_json(lhs) <= rhs; 20508 } 20509 20510 /*! 20511 @brief comparison: greater than 20512 20513 Compares whether one JSON value @a lhs is greater than another 20514 JSON value by calculating `not (lhs <= rhs)`. 20515 20516 @param[in] lhs first JSON value to consider 20517 @param[in] rhs second JSON value to consider 20518 @return whether @a lhs is greater than to @a rhs 20519 20520 @complexity Linear. 20521 20522 @exceptionsafety No-throw guarantee: this function never throws exceptions. 20523 20524 @liveexample{The example demonstrates comparing several JSON 20525 types.,operator__lessequal} 20526 20527 @since version 1.0.0 20528 */ 20529 friend bool operator>(const_reference lhs, const_reference rhs) noexcept 20530 { 20531 return not (lhs <= rhs); 20532 } 20533 20534 /*! 20535 @brief comparison: greater than 20536 @copydoc operator>(const_reference, const_reference) 20537 */ 20538 template<typename ScalarType, typename std::enable_if< 20539 std::is_scalar<ScalarType>::value, int>::type = 0> 20540 friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept 20541 { 20542 return lhs > basic_json(rhs); 20543 } 20544 20545 /*! 20546 @brief comparison: greater than 20547 @copydoc operator>(const_reference, const_reference) 20548 */ 20549 template<typename ScalarType, typename std::enable_if< 20550 std::is_scalar<ScalarType>::value, int>::type = 0> 20551 friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept 20552 { 20553 return basic_json(lhs) > rhs; 20554 } 20555 20556 /*! 20557 @brief comparison: greater than or equal 20558 20559 Compares whether one JSON value @a lhs is greater than or equal to another 20560 JSON value by calculating `not (lhs < rhs)`. 20561 20562 @param[in] lhs first JSON value to consider 20563 @param[in] rhs second JSON value to consider 20564 @return whether @a lhs is greater than or equal to @a rhs 20565 20566 @complexity Linear. 20567 20568 @exceptionsafety No-throw guarantee: this function never throws exceptions. 20569 20570 @liveexample{The example demonstrates comparing several JSON 20571 types.,operator__greaterequal} 20572 20573 @since version 1.0.0 20574 */ 20575 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept 20576 { 20577 return not (lhs < rhs); 20578 } 20579 20580 /*! 20581 @brief comparison: greater than or equal 20582 @copydoc operator>=(const_reference, const_reference) 20583 */ 20584 template<typename ScalarType, typename std::enable_if< 20585 std::is_scalar<ScalarType>::value, int>::type = 0> 20586 friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept 20587 { 20588 return lhs >= basic_json(rhs); 20589 } 20590 20591 /*! 20592 @brief comparison: greater than or equal 20593 @copydoc operator>=(const_reference, const_reference) 20594 */ 20595 template<typename ScalarType, typename std::enable_if< 20596 std::is_scalar<ScalarType>::value, int>::type = 0> 20597 friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept 20598 { 20599 return basic_json(lhs) >= rhs; 20600 } 20601 20602 /// @} 20603 20604 /////////////////// 20605 // serialization // 20606 /////////////////// 20607 20608 /// @name serialization 20609 /// @{ 20610 20611 /*! 20612 @brief serialize to stream 20613 20614 Serialize the given JSON value @a j to the output stream @a o. The JSON 20615 value will be serialized using the @ref dump member function. 20616 20617 - The indentation of the output can be controlled with the member variable 20618 `width` of the output stream @a o. For instance, using the manipulator 20619 `std::setw(4)` on @a o sets the indentation level to `4` and the 20620 serialization result is the same as calling `dump(4)`. 20621 20622 - The indentation character can be controlled with the member variable 20623 `fill` of the output stream @a o. For instance, the manipulator 20624 `std::setfill('\\t')` sets indentation to use a tab character rather than 20625 the default space character. 20626 20627 @param[in,out] o stream to serialize to 20628 @param[in] j JSON value to serialize 20629 20630 @return the stream @a o 20631 20632 @throw type_error.316 if a string stored inside the JSON value is not 20633 UTF-8 encoded 20634 20635 @complexity Linear. 20636 20637 @liveexample{The example below shows the serialization with different 20638 parameters to `width` to adjust the indentation level.,operator_serialize} 20639 20640 @since version 1.0.0; indentation character added in version 3.0.0 20641 */ 20642 friend std::ostream& operator<<(std::ostream& o, const basic_json& j) 20643 { 20644 // read width member and use it as indentation parameter if nonzero 20645 const bool pretty_print = o.width() > 0; 20646 const auto indentation = pretty_print ? o.width() : 0; 20647 20648 // reset width to 0 for subsequent calls to this stream 20649 o.width(0); 20650 20651 // do the actual serialization 20652 serializer s(detail::output_adapter<char>(o), o.fill()); 20653 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation)); 20654 return o; 20655 } 20656 20657 /*! 20658 @brief serialize to stream 20659 @deprecated This stream operator is deprecated and will be removed in 20660 future 4.0.0 of the library. Please use 20661 @ref operator<<(std::ostream&, const basic_json&) 20662 instead; that is, replace calls like `j >> o;` with `o << j;`. 20663 @since version 1.0.0; deprecated since version 3.0.0 20664 */ 20665 JSON_HEDLEY_DEPRECATED(3.0.0) 20666 friend std::ostream& operator>>(const basic_json& j, std::ostream& o) 20667 { 20668 return o << j; 20669 } 20670 20671 /// @} 20672 20673 20674 ///////////////////// 20675 // deserialization // 20676 ///////////////////// 20677 20678 /// @name deserialization 20679 /// @{ 20680 20681 /*! 20682 @brief deserialize from a compatible input 20683 20684 This function reads from a compatible input. Examples are: 20685 - an array of 1-byte values 20686 - strings with character/literal type with size of 1 byte 20687 - input streams 20688 - container with contiguous storage of 1-byte values. Compatible container 20689 types include `std::vector`, `std::string`, `std::array`, 20690 `std::valarray`, and `std::initializer_list`. Furthermore, C-style 20691 arrays can be used with `std::begin()`/`std::end()`. User-defined 20692 containers can be used as long as they implement random-access iterators 20693 and a contiguous storage. 20694 20695 @pre Each element of the container has a size of 1 byte. Violating this 20696 precondition yields undefined behavior. **This precondition is enforced 20697 with a static assertion.** 20698 20699 @pre The container storage is contiguous. Violating this precondition 20700 yields undefined behavior. **This precondition is enforced with an 20701 assertion.** 20702 20703 @warning There is no way to enforce all preconditions at compile-time. If 20704 the function is called with a noncompliant container and with 20705 assertions switched off, the behavior is undefined and will most 20706 likely yield segmentation violation. 20707 20708 @param[in] i input to read from 20709 @param[in] cb a parser callback function of type @ref parser_callback_t 20710 which is used to control the deserialization by filtering unwanted values 20711 (optional) 20712 @param[in] allow_exceptions whether to throw exceptions in case of a 20713 parse error (optional, true by default) 20714 20715 @return deserialized JSON value; in case of a parse error and 20716 @a allow_exceptions set to `false`, the return value will be 20717 value_t::discarded. 20718 20719 @throw parse_error.101 if a parse error occurs; example: `""unexpected end 20720 of input; expected string literal""` 20721 @throw parse_error.102 if to_unicode fails or surrogate error 20722 @throw parse_error.103 if to_unicode fails 20723 20724 @complexity Linear in the length of the input. The parser is a predictive 20725 LL(1) parser. The complexity can be higher if the parser callback function 20726 @a cb has a super-linear complexity. 20727 20728 @note A UTF-8 byte order mark is silently ignored. 20729 20730 @liveexample{The example below demonstrates the `parse()` function reading 20731 from an array.,parse__array__parser_callback_t} 20732 20733 @liveexample{The example below demonstrates the `parse()` function with 20734 and without callback function.,parse__string__parser_callback_t} 20735 20736 @liveexample{The example below demonstrates the `parse()` function with 20737 and without callback function.,parse__istream__parser_callback_t} 20738 20739 @liveexample{The example below demonstrates the `parse()` function reading 20740 from a contiguous container.,parse__contiguouscontainer__parser_callback_t} 20741 20742 @since version 2.0.3 (contiguous containers) 20743 */ 20744 JSON_HEDLEY_WARN_UNUSED_RESULT 20745 static basic_json parse(detail::input_adapter&& i, 20746 const parser_callback_t cb = nullptr, 20747 const bool allow_exceptions = true) 20748 { 20749 basic_json result; 20750 parser(i, cb, allow_exceptions).parse(true, result); 20751 return result; 20752 } 20753 20754 static bool accept(detail::input_adapter&& i) 20755 { 20756 return parser(i).accept(true); 20757 } 20758 20759 /*! 20760 @brief generate SAX events 20761 20762 The SAX event lister must follow the interface of @ref json_sax. 20763 20764 This function reads from a compatible input. Examples are: 20765 - an array of 1-byte values 20766 - strings with character/literal type with size of 1 byte 20767 - input streams 20768 - container with contiguous storage of 1-byte values. Compatible container 20769 types include `std::vector`, `std::string`, `std::array`, 20770 `std::valarray`, and `std::initializer_list`. Furthermore, C-style 20771 arrays can be used with `std::begin()`/`std::end()`. User-defined 20772 containers can be used as long as they implement random-access iterators 20773 and a contiguous storage. 20774 20775 @pre Each element of the container has a size of 1 byte. Violating this 20776 precondition yields undefined behavior. **This precondition is enforced 20777 with a static assertion.** 20778 20779 @pre The container storage is contiguous. Violating this precondition 20780 yields undefined behavior. **This precondition is enforced with an 20781 assertion.** 20782 20783 @warning There is no way to enforce all preconditions at compile-time. If 20784 the function is called with a noncompliant container and with 20785 assertions switched off, the behavior is undefined and will most 20786 likely yield segmentation violation. 20787 20788 @param[in] i input to read from 20789 @param[in,out] sax SAX event listener 20790 @param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON) 20791 @param[in] strict whether the input has to be consumed completely 20792 20793 @return return value of the last processed SAX event 20794 20795 @throw parse_error.101 if a parse error occurs; example: `""unexpected end 20796 of input; expected string literal""` 20797 @throw parse_error.102 if to_unicode fails or surrogate error 20798 @throw parse_error.103 if to_unicode fails 20799 20800 @complexity Linear in the length of the input. The parser is a predictive 20801 LL(1) parser. The complexity can be higher if the SAX consumer @a sax has 20802 a super-linear complexity. 20803 20804 @note A UTF-8 byte order mark is silently ignored. 20805 20806 @liveexample{The example below demonstrates the `sax_parse()` function 20807 reading from string and processing the events with a user-defined SAX 20808 event consumer.,sax_parse} 20809 20810 @since version 3.2.0 20811 */ 20812 template <typename SAX> 20813 JSON_HEDLEY_NON_NULL(2) 20814 static bool sax_parse(detail::input_adapter&& i, SAX* sax, 20815 input_format_t format = input_format_t::json, 20816 const bool strict = true) 20817 { 20818 assert(sax); 20819 return format == input_format_t::json 20820 ? parser(std::move(i)).sax_parse(sax, strict) 20821 : detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(format, sax, strict); 20822 } 20823 20824 /*! 20825 @brief deserialize from an iterator range with contiguous storage 20826 20827 This function reads from an iterator range of a container with contiguous 20828 storage of 1-byte values. Compatible container types include 20829 `std::vector`, `std::string`, `std::array`, `std::valarray`, and 20830 `std::initializer_list`. Furthermore, C-style arrays can be used with 20831 `std::begin()`/`std::end()`. User-defined containers can be used as long 20832 as they implement random-access iterators and a contiguous storage. 20833 20834 @pre The iterator range is contiguous. Violating this precondition yields 20835 undefined behavior. **This precondition is enforced with an assertion.** 20836 @pre Each element in the range has a size of 1 byte. Violating this 20837 precondition yields undefined behavior. **This precondition is enforced 20838 with a static assertion.** 20839 20840 @warning There is no way to enforce all preconditions at compile-time. If 20841 the function is called with noncompliant iterators and with 20842 assertions switched off, the behavior is undefined and will most 20843 likely yield segmentation violation. 20844 20845 @tparam IteratorType iterator of container with contiguous storage 20846 @param[in] first begin of the range to parse (included) 20847 @param[in] last end of the range to parse (excluded) 20848 @param[in] cb a parser callback function of type @ref parser_callback_t 20849 which is used to control the deserialization by filtering unwanted values 20850 (optional) 20851 @param[in] allow_exceptions whether to throw exceptions in case of a 20852 parse error (optional, true by default) 20853 20854 @return deserialized JSON value; in case of a parse error and 20855 @a allow_exceptions set to `false`, the return value will be 20856 value_t::discarded. 20857 20858 @throw parse_error.101 in case of an unexpected token 20859 @throw parse_error.102 if to_unicode fails or surrogate error 20860 @throw parse_error.103 if to_unicode fails 20861 20862 @complexity Linear in the length of the input. The parser is a predictive 20863 LL(1) parser. The complexity can be higher if the parser callback function 20864 @a cb has a super-linear complexity. 20865 20866 @note A UTF-8 byte order mark is silently ignored. 20867 20868 @liveexample{The example below demonstrates the `parse()` function reading 20869 from an iterator range.,parse__iteratortype__parser_callback_t} 20870 20871 @since version 2.0.3 20872 */ 20873 template<class IteratorType, typename std::enable_if< 20874 std::is_base_of< 20875 std::random_access_iterator_tag, 20876 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0> 20877 static basic_json parse(IteratorType first, IteratorType last, 20878 const parser_callback_t cb = nullptr, 20879 const bool allow_exceptions = true) 20880 { 20881 basic_json result; 20882 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result); 20883 return result; 20884 } 20885 20886 template<class IteratorType, typename std::enable_if< 20887 std::is_base_of< 20888 std::random_access_iterator_tag, 20889 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0> 20890 static bool accept(IteratorType first, IteratorType last) 20891 { 20892 return parser(detail::input_adapter(first, last)).accept(true); 20893 } 20894 20895 template<class IteratorType, class SAX, typename std::enable_if< 20896 std::is_base_of< 20897 std::random_access_iterator_tag, 20898 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0> 20899 JSON_HEDLEY_NON_NULL(3) 20900 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax) 20901 { 20902 return parser(detail::input_adapter(first, last)).sax_parse(sax); 20903 } 20904 20905 /*! 20906 @brief deserialize from stream 20907 @deprecated This stream operator is deprecated and will be removed in 20908 version 4.0.0 of the library. Please use 20909 @ref operator>>(std::istream&, basic_json&) 20910 instead; that is, replace calls like `j << i;` with `i >> j;`. 20911 @since version 1.0.0; deprecated since version 3.0.0 20912 */ 20913 JSON_HEDLEY_DEPRECATED(3.0.0) 20914 friend std::istream& operator<<(basic_json& j, std::istream& i) 20915 { 20916 return operator>>(i, j); 20917 } 20918 20919 /*! 20920 @brief deserialize from stream 20921 20922 Deserializes an input stream to a JSON value. 20923 20924 @param[in,out] i input stream to read a serialized JSON value from 20925 @param[in,out] j JSON value to write the deserialized input to 20926 20927 @throw parse_error.101 in case of an unexpected token 20928 @throw parse_error.102 if to_unicode fails or surrogate error 20929 @throw parse_error.103 if to_unicode fails 20930 20931 @complexity Linear in the length of the input. The parser is a predictive 20932 LL(1) parser. 20933 20934 @note A UTF-8 byte order mark is silently ignored. 20935 20936 @liveexample{The example below shows how a JSON value is constructed by 20937 reading a serialization from a stream.,operator_deserialize} 20938 20939 @sa parse(std::istream&, const parser_callback_t) for a variant with a 20940 parser callback function to filter values while parsing 20941 20942 @since version 1.0.0 20943 */ 20944 friend std::istream& operator>>(std::istream& i, basic_json& j) 20945 { 20946 parser(detail::input_adapter(i)).parse(false, j); 20947 return i; 20948 } 20949 20950 /// @} 20951 20952 /////////////////////////// 20953 // convenience functions // 20954 /////////////////////////// 20955 20956 /*! 20957 @brief return the type as string 20958 20959 Returns the type name as string to be used in error messages - usually to 20960 indicate that a function was called on a wrong JSON type. 20961 20962 @return a string representation of a the @a m_type member: 20963 Value type | return value 20964 ----------- | ------------- 20965 null | `"null"` 20966 boolean | `"boolean"` 20967 string | `"string"` 20968 number | `"number"` (for all number types) 20969 object | `"object"` 20970 array | `"array"` 20971 discarded | `"discarded"` 20972 20973 @exceptionsafety No-throw guarantee: this function never throws exceptions. 20974 20975 @complexity Constant. 20976 20977 @liveexample{The following code exemplifies `type_name()` for all JSON 20978 types.,type_name} 20979 20980 @sa @ref type() -- return the type of the JSON value 20981 @sa @ref operator value_t() -- return the type of the JSON value (implicit) 20982 20983 @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept` 20984 since 3.0.0 20985 */ 20986 JSON_HEDLEY_RETURNS_NON_NULL 20987 const char* type_name() const noexcept 20988 { 20989 { 20990 switch (m_type) 20991 { 20992 case value_t::null: 20993 return "null"; 20994 case value_t::object: 20995 return "object"; 20996 case value_t::array: 20997 return "array"; 20998 case value_t::string: 20999 return "string"; 21000 case value_t::boolean: 21001 return "boolean"; 21002 case value_t::discarded: 21003 return "discarded"; 21004 default: 21005 return "number"; 21006 } 21007 } 21008 } 21009 21010 21011 private: 21012 ////////////////////// 21013 // member variables // 21014 ////////////////////// 21015 21016 /// the type of the current element 21017 value_t m_type = value_t::null; 21018 21019 /// the value of the current element 21020 json_value m_value = {}; 21021 21022 ////////////////////////////////////////// 21023 // binary serialization/deserialization // 21024 ////////////////////////////////////////// 21025 21026 /// @name binary serialization/deserialization support 21027 /// @{ 21028 21029 public: 21030 /*! 21031 @brief create a CBOR serialization of a given JSON value 21032 21033 Serializes a given JSON value @a j to a byte vector using the CBOR (Concise 21034 Binary Object Representation) serialization format. CBOR is a binary 21035 serialization format which aims to be more compact than JSON itself, yet 21036 more efficient to parse. 21037 21038 The library uses the following mapping from JSON values types to 21039 CBOR types according to the CBOR specification (RFC 7049): 21040 21041 JSON value type | value/range | CBOR type | first byte 21042 --------------- | ------------------------------------------ | ---------------------------------- | --------------- 21043 null | `null` | Null | 0xF6 21044 boolean | `true` | True | 0xF5 21045 boolean | `false` | False | 0xF4 21046 number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B 21047 number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A 21048 number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39 21049 number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38 21050 number_integer | -24..-1 | Negative integer | 0x20..0x37 21051 number_integer | 0..23 | Integer | 0x00..0x17 21052 number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18 21053 number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19 21054 number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A 21055 number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B 21056 number_unsigned | 0..23 | Integer | 0x00..0x17 21057 number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18 21058 number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19 21059 number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A 21060 number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B 21061 number_float | *any value* | Double-Precision Float | 0xFB 21062 string | *length*: 0..23 | UTF-8 string | 0x60..0x77 21063 string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78 21064 string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79 21065 string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A 21066 string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B 21067 array | *size*: 0..23 | array | 0x80..0x97 21068 array | *size*: 23..255 | array (1 byte follow) | 0x98 21069 array | *size*: 256..65535 | array (2 bytes follow) | 0x99 21070 array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A 21071 array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B 21072 object | *size*: 0..23 | map | 0xA0..0xB7 21073 object | *size*: 23..255 | map (1 byte follow) | 0xB8 21074 object | *size*: 256..65535 | map (2 bytes follow) | 0xB9 21075 object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA 21076 object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB 21077 21078 @note The mapping is **complete** in the sense that any JSON value type 21079 can be converted to a CBOR value. 21080 21081 @note If NaN or Infinity are stored inside a JSON number, they are 21082 serialized properly. This behavior differs from the @ref dump() 21083 function which serializes NaN or Infinity to `null`. 21084 21085 @note The following CBOR types are not used in the conversion: 21086 - byte strings (0x40..0x5F) 21087 - UTF-8 strings terminated by "break" (0x7F) 21088 - arrays terminated by "break" (0x9F) 21089 - maps terminated by "break" (0xBF) 21090 - date/time (0xC0..0xC1) 21091 - bignum (0xC2..0xC3) 21092 - decimal fraction (0xC4) 21093 - bigfloat (0xC5) 21094 - tagged items (0xC6..0xD4, 0xD8..0xDB) 21095 - expected conversions (0xD5..0xD7) 21096 - simple values (0xE0..0xF3, 0xF8) 21097 - undefined (0xF7) 21098 - half and single-precision floats (0xF9-0xFA) 21099 - break (0xFF) 21100 21101 @param[in] j JSON value to serialize 21102 @return MessagePack serialization as byte vector 21103 21104 @complexity Linear in the size of the JSON value @a j. 21105 21106 @liveexample{The example shows the serialization of a JSON value to a byte 21107 vector in CBOR format.,to_cbor} 21108 21109 @sa http://cbor.io 21110 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the 21111 analogous deserialization 21112 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format 21113 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the 21114 related UBJSON format 21115 21116 @since version 2.0.9 21117 */ 21118 static std::vector<uint8_t> to_cbor(const basic_json& j) 21119 { 21120 std::vector<uint8_t> result; 21121 to_cbor(j, result); 21122 return result; 21123 } 21124 21125 static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o) 21126 { 21127 binary_writer<uint8_t>(o).write_cbor(j); 21128 } 21129 21130 static void to_cbor(const basic_json& j, detail::output_adapter<char> o) 21131 { 21132 binary_writer<char>(o).write_cbor(j); 21133 } 21134 21135 /*! 21136 @brief create a MessagePack serialization of a given JSON value 21137 21138 Serializes a given JSON value @a j to a byte vector using the MessagePack 21139 serialization format. MessagePack is a binary serialization format which 21140 aims to be more compact than JSON itself, yet more efficient to parse. 21141 21142 The library uses the following mapping from JSON values types to 21143 MessagePack types according to the MessagePack specification: 21144 21145 JSON value type | value/range | MessagePack type | first byte 21146 --------------- | --------------------------------- | ---------------- | ---------- 21147 null | `null` | nil | 0xC0 21148 boolean | `true` | true | 0xC3 21149 boolean | `false` | false | 0xC2 21150 number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3 21151 number_integer | -2147483648..-32769 | int32 | 0xD2 21152 number_integer | -32768..-129 | int16 | 0xD1 21153 number_integer | -128..-33 | int8 | 0xD0 21154 number_integer | -32..-1 | negative fixint | 0xE0..0xFF 21155 number_integer | 0..127 | positive fixint | 0x00..0x7F 21156 number_integer | 128..255 | uint 8 | 0xCC 21157 number_integer | 256..65535 | uint 16 | 0xCD 21158 number_integer | 65536..4294967295 | uint 32 | 0xCE 21159 number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF 21160 number_unsigned | 0..127 | positive fixint | 0x00..0x7F 21161 number_unsigned | 128..255 | uint 8 | 0xCC 21162 number_unsigned | 256..65535 | uint 16 | 0xCD 21163 number_unsigned | 65536..4294967295 | uint 32 | 0xCE 21164 number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF 21165 number_float | *any value* | float 64 | 0xCB 21166 string | *length*: 0..31 | fixstr | 0xA0..0xBF 21167 string | *length*: 32..255 | str 8 | 0xD9 21168 string | *length*: 256..65535 | str 16 | 0xDA 21169 string | *length*: 65536..4294967295 | str 32 | 0xDB 21170 array | *size*: 0..15 | fixarray | 0x90..0x9F 21171 array | *size*: 16..65535 | array 16 | 0xDC 21172 array | *size*: 65536..4294967295 | array 32 | 0xDD 21173 object | *size*: 0..15 | fix map | 0x80..0x8F 21174 object | *size*: 16..65535 | map 16 | 0xDE 21175 object | *size*: 65536..4294967295 | map 32 | 0xDF 21176 21177 @note The mapping is **complete** in the sense that any JSON value type 21178 can be converted to a MessagePack value. 21179 21180 @note The following values can **not** be converted to a MessagePack value: 21181 - strings with more than 4294967295 bytes 21182 - arrays with more than 4294967295 elements 21183 - objects with more than 4294967295 elements 21184 21185 @note The following MessagePack types are not used in the conversion: 21186 - bin 8 - bin 32 (0xC4..0xC6) 21187 - ext 8 - ext 32 (0xC7..0xC9) 21188 - float 32 (0xCA) 21189 - fixext 1 - fixext 16 (0xD4..0xD8) 21190 21191 @note Any MessagePack output created @ref to_msgpack can be successfully 21192 parsed by @ref from_msgpack. 21193 21194 @note If NaN or Infinity are stored inside a JSON number, they are 21195 serialized properly. This behavior differs from the @ref dump() 21196 function which serializes NaN or Infinity to `null`. 21197 21198 @param[in] j JSON value to serialize 21199 @return MessagePack serialization as byte vector 21200 21201 @complexity Linear in the size of the JSON value @a j. 21202 21203 @liveexample{The example shows the serialization of a JSON value to a byte 21204 vector in MessagePack format.,to_msgpack} 21205 21206 @sa http://msgpack.org 21207 @sa @ref from_msgpack for the analogous deserialization 21208 @sa @ref to_cbor(const basic_json& for the related CBOR format 21209 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the 21210 related UBJSON format 21211 21212 @since version 2.0.9 21213 */ 21214 static std::vector<uint8_t> to_msgpack(const basic_json& j) 21215 { 21216 std::vector<uint8_t> result; 21217 to_msgpack(j, result); 21218 return result; 21219 } 21220 21221 static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o) 21222 { 21223 binary_writer<uint8_t>(o).write_msgpack(j); 21224 } 21225 21226 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o) 21227 { 21228 binary_writer<char>(o).write_msgpack(j); 21229 } 21230 21231 /*! 21232 @brief create a UBJSON serialization of a given JSON value 21233 21234 Serializes a given JSON value @a j to a byte vector using the UBJSON 21235 (Universal Binary JSON) serialization format. UBJSON aims to be more compact 21236 than JSON itself, yet more efficient to parse. 21237 21238 The library uses the following mapping from JSON values types to 21239 UBJSON types according to the UBJSON specification: 21240 21241 JSON value type | value/range | UBJSON type | marker 21242 --------------- | --------------------------------- | ----------- | ------ 21243 null | `null` | null | `Z` 21244 boolean | `true` | true | `T` 21245 boolean | `false` | false | `F` 21246 number_integer | -9223372036854775808..-2147483649 | int64 | `L` 21247 number_integer | -2147483648..-32769 | int32 | `l` 21248 number_integer | -32768..-129 | int16 | `I` 21249 number_integer | -128..127 | int8 | `i` 21250 number_integer | 128..255 | uint8 | `U` 21251 number_integer | 256..32767 | int16 | `I` 21252 number_integer | 32768..2147483647 | int32 | `l` 21253 number_integer | 2147483648..9223372036854775807 | int64 | `L` 21254 number_unsigned | 0..127 | int8 | `i` 21255 number_unsigned | 128..255 | uint8 | `U` 21256 number_unsigned | 256..32767 | int16 | `I` 21257 number_unsigned | 32768..2147483647 | int32 | `l` 21258 number_unsigned | 2147483648..9223372036854775807 | int64 | `L` 21259 number_float | *any value* | float64 | `D` 21260 string | *with shortest length indicator* | string | `S` 21261 array | *see notes on optimized format* | array | `[` 21262 object | *see notes on optimized format* | map | `{` 21263 21264 @note The mapping is **complete** in the sense that any JSON value type 21265 can be converted to a UBJSON value. 21266 21267 @note The following values can **not** be converted to a UBJSON value: 21268 - strings with more than 9223372036854775807 bytes (theoretical) 21269 - unsigned integer numbers above 9223372036854775807 21270 21271 @note The following markers are not used in the conversion: 21272 - `Z`: no-op values are not created. 21273 - `C`: single-byte strings are serialized with `S` markers. 21274 21275 @note Any UBJSON output created @ref to_ubjson can be successfully parsed 21276 by @ref from_ubjson. 21277 21278 @note If NaN or Infinity are stored inside a JSON number, they are 21279 serialized properly. This behavior differs from the @ref dump() 21280 function which serializes NaN or Infinity to `null`. 21281 21282 @note The optimized formats for containers are supported: Parameter 21283 @a use_size adds size information to the beginning of a container and 21284 removes the closing marker. Parameter @a use_type further checks 21285 whether all elements of a container have the same type and adds the 21286 type marker to the beginning of the container. The @a use_type 21287 parameter must only be used together with @a use_size = true. Note 21288 that @a use_size = true alone may result in larger representations - 21289 the benefit of this parameter is that the receiving side is 21290 immediately informed on the number of elements of the container. 21291 21292 @param[in] j JSON value to serialize 21293 @param[in] use_size whether to add size annotations to container types 21294 @param[in] use_type whether to add type annotations to container types 21295 (must be combined with @a use_size = true) 21296 @return UBJSON serialization as byte vector 21297 21298 @complexity Linear in the size of the JSON value @a j. 21299 21300 @liveexample{The example shows the serialization of a JSON value to a byte 21301 vector in UBJSON format.,to_ubjson} 21302 21303 @sa http://ubjson.org 21304 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the 21305 analogous deserialization 21306 @sa @ref to_cbor(const basic_json& for the related CBOR format 21307 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format 21308 21309 @since version 3.1.0 21310 */ 21311 static std::vector<uint8_t> to_ubjson(const basic_json& j, 21312 const bool use_size = false, 21313 const bool use_type = false) 21314 { 21315 std::vector<uint8_t> result; 21316 to_ubjson(j, result, use_size, use_type); 21317 return result; 21318 } 21319 21320 static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o, 21321 const bool use_size = false, const bool use_type = false) 21322 { 21323 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type); 21324 } 21325 21326 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o, 21327 const bool use_size = false, const bool use_type = false) 21328 { 21329 binary_writer<char>(o).write_ubjson(j, use_size, use_type); 21330 } 21331 21332 21333 /*! 21334 @brief Serializes the given JSON object `j` to BSON and returns a vector 21335 containing the corresponding BSON-representation. 21336 21337 BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are 21338 stored as a single entity (a so-called document). 21339 21340 The library uses the following mapping from JSON values types to BSON types: 21341 21342 JSON value type | value/range | BSON type | marker 21343 --------------- | --------------------------------- | ----------- | ------ 21344 null | `null` | null | 0x0A 21345 boolean | `true`, `false` | boolean | 0x08 21346 number_integer | -9223372036854775808..-2147483649 | int64 | 0x12 21347 number_integer | -2147483648..2147483647 | int32 | 0x10 21348 number_integer | 2147483648..9223372036854775807 | int64 | 0x12 21349 number_unsigned | 0..2147483647 | int32 | 0x10 21350 number_unsigned | 2147483648..9223372036854775807 | int64 | 0x12 21351 number_unsigned | 9223372036854775808..18446744073709551615| -- | -- 21352 number_float | *any value* | double | 0x01 21353 string | *any value* | string | 0x02 21354 array | *any value* | document | 0x04 21355 object | *any value* | document | 0x03 21356 21357 @warning The mapping is **incomplete**, since only JSON-objects (and things 21358 contained therein) can be serialized to BSON. 21359 Also, integers larger than 9223372036854775807 cannot be serialized to BSON, 21360 and the keys may not contain U+0000, since they are serialized a 21361 zero-terminated c-strings. 21362 21363 @throw out_of_range.407 if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807` 21364 @throw out_of_range.409 if a key in `j` contains a NULL (U+0000) 21365 @throw type_error.317 if `!j.is_object()` 21366 21367 @pre The input `j` is required to be an object: `j.is_object() == true`. 21368 21369 @note Any BSON output created via @ref to_bson can be successfully parsed 21370 by @ref from_bson. 21371 21372 @param[in] j JSON value to serialize 21373 @return BSON serialization as byte vector 21374 21375 @complexity Linear in the size of the JSON value @a j. 21376 21377 @liveexample{The example shows the serialization of a JSON value to a byte 21378 vector in BSON format.,to_bson} 21379 21380 @sa http://bsonspec.org/spec.html 21381 @sa @ref from_bson(detail::input_adapter&&, const bool strict) for the 21382 analogous deserialization 21383 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the 21384 related UBJSON format 21385 @sa @ref to_cbor(const basic_json&) for the related CBOR format 21386 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format 21387 */ 21388 static std::vector<uint8_t> to_bson(const basic_json& j) 21389 { 21390 std::vector<uint8_t> result; 21391 to_bson(j, result); 21392 return result; 21393 } 21394 21395 /*! 21396 @brief Serializes the given JSON object `j` to BSON and forwards the 21397 corresponding BSON-representation to the given output_adapter `o`. 21398 @param j The JSON object to convert to BSON. 21399 @param o The output adapter that receives the binary BSON representation. 21400 @pre The input `j` shall be an object: `j.is_object() == true` 21401 @sa @ref to_bson(const basic_json&) 21402 */ 21403 static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o) 21404 { 21405 binary_writer<uint8_t>(o).write_bson(j); 21406 } 21407 21408 /*! 21409 @copydoc to_bson(const basic_json&, detail::output_adapter<uint8_t>) 21410 */ 21411 static void to_bson(const basic_json& j, detail::output_adapter<char> o) 21412 { 21413 binary_writer<char>(o).write_bson(j); 21414 } 21415 21416 21417 /*! 21418 @brief create a JSON value from an input in CBOR format 21419 21420 Deserializes a given input @a i to a JSON value using the CBOR (Concise 21421 Binary Object Representation) serialization format. 21422 21423 The library maps CBOR types to JSON value types as follows: 21424 21425 CBOR type | JSON value type | first byte 21426 ---------------------- | --------------- | ---------- 21427 Integer | number_unsigned | 0x00..0x17 21428 Unsigned integer | number_unsigned | 0x18 21429 Unsigned integer | number_unsigned | 0x19 21430 Unsigned integer | number_unsigned | 0x1A 21431 Unsigned integer | number_unsigned | 0x1B 21432 Negative integer | number_integer | 0x20..0x37 21433 Negative integer | number_integer | 0x38 21434 Negative integer | number_integer | 0x39 21435 Negative integer | number_integer | 0x3A 21436 Negative integer | number_integer | 0x3B 21437 Negative integer | number_integer | 0x40..0x57 21438 UTF-8 string | string | 0x60..0x77 21439 UTF-8 string | string | 0x78 21440 UTF-8 string | string | 0x79 21441 UTF-8 string | string | 0x7A 21442 UTF-8 string | string | 0x7B 21443 UTF-8 string | string | 0x7F 21444 array | array | 0x80..0x97 21445 array | array | 0x98 21446 array | array | 0x99 21447 array | array | 0x9A 21448 array | array | 0x9B 21449 array | array | 0x9F 21450 map | object | 0xA0..0xB7 21451 map | object | 0xB8 21452 map | object | 0xB9 21453 map | object | 0xBA 21454 map | object | 0xBB 21455 map | object | 0xBF 21456 False | `false` | 0xF4 21457 True | `true` | 0xF5 21458 Null | `null` | 0xF6 21459 Half-Precision Float | number_float | 0xF9 21460 Single-Precision Float | number_float | 0xFA 21461 Double-Precision Float | number_float | 0xFB 21462 21463 @warning The mapping is **incomplete** in the sense that not all CBOR 21464 types can be converted to a JSON value. The following CBOR types 21465 are not supported and will yield parse errors (parse_error.112): 21466 - byte strings (0x40..0x5F) 21467 - date/time (0xC0..0xC1) 21468 - bignum (0xC2..0xC3) 21469 - decimal fraction (0xC4) 21470 - bigfloat (0xC5) 21471 - tagged items (0xC6..0xD4, 0xD8..0xDB) 21472 - expected conversions (0xD5..0xD7) 21473 - simple values (0xE0..0xF3, 0xF8) 21474 - undefined (0xF7) 21475 21476 @warning CBOR allows map keys of any type, whereas JSON only allows 21477 strings as keys in object values. Therefore, CBOR maps with keys 21478 other than UTF-8 strings are rejected (parse_error.113). 21479 21480 @note Any CBOR output created @ref to_cbor can be successfully parsed by 21481 @ref from_cbor. 21482 21483 @param[in] i an input in CBOR format convertible to an input adapter 21484 @param[in] strict whether to expect the input to be consumed until EOF 21485 (true by default) 21486 @param[in] allow_exceptions whether to throw exceptions in case of a 21487 parse error (optional, true by default) 21488 21489 @return deserialized JSON value; in case of a parse error and 21490 @a allow_exceptions set to `false`, the return value will be 21491 value_t::discarded. 21492 21493 @throw parse_error.110 if the given input ends prematurely or the end of 21494 file was not reached when @a strict was set to true 21495 @throw parse_error.112 if unsupported features from CBOR were 21496 used in the given input @a v or if the input is not valid CBOR 21497 @throw parse_error.113 if a string was expected as map key, but not found 21498 21499 @complexity Linear in the size of the input @a i. 21500 21501 @liveexample{The example shows the deserialization of a byte vector in CBOR 21502 format to a JSON value.,from_cbor} 21503 21504 @sa http://cbor.io 21505 @sa @ref to_cbor(const basic_json&) for the analogous serialization 21506 @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for the 21507 related MessagePack format 21508 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the 21509 related UBJSON format 21510 21511 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to 21512 consume input adapters, removed start_index parameter, and added 21513 @a strict parameter since 3.0.0; added @a allow_exceptions parameter 21514 since 3.2.0 21515 */ 21516 JSON_HEDLEY_WARN_UNUSED_RESULT 21517 static basic_json from_cbor(detail::input_adapter&& i, 21518 const bool strict = true, 21519 const bool allow_exceptions = true) 21520 { 21521 basic_json result; 21522 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 21523 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::cbor, &sdp, strict); 21524 return res ? result : basic_json(value_t::discarded); 21525 } 21526 21527 /*! 21528 @copydoc from_cbor(detail::input_adapter&&, const bool, const bool) 21529 */ 21530 template<typename A1, typename A2, 21531 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0> 21532 JSON_HEDLEY_WARN_UNUSED_RESULT 21533 static basic_json from_cbor(A1 && a1, A2 && a2, 21534 const bool strict = true, 21535 const bool allow_exceptions = true) 21536 { 21537 basic_json result; 21538 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 21539 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::cbor, &sdp, strict); 21540 return res ? result : basic_json(value_t::discarded); 21541 } 21542 21543 /*! 21544 @brief create a JSON value from an input in MessagePack format 21545 21546 Deserializes a given input @a i to a JSON value using the MessagePack 21547 serialization format. 21548 21549 The library maps MessagePack types to JSON value types as follows: 21550 21551 MessagePack type | JSON value type | first byte 21552 ---------------- | --------------- | ---------- 21553 positive fixint | number_unsigned | 0x00..0x7F 21554 fixmap | object | 0x80..0x8F 21555 fixarray | array | 0x90..0x9F 21556 fixstr | string | 0xA0..0xBF 21557 nil | `null` | 0xC0 21558 false | `false` | 0xC2 21559 true | `true` | 0xC3 21560 float 32 | number_float | 0xCA 21561 float 64 | number_float | 0xCB 21562 uint 8 | number_unsigned | 0xCC 21563 uint 16 | number_unsigned | 0xCD 21564 uint 32 | number_unsigned | 0xCE 21565 uint 64 | number_unsigned | 0xCF 21566 int 8 | number_integer | 0xD0 21567 int 16 | number_integer | 0xD1 21568 int 32 | number_integer | 0xD2 21569 int 64 | number_integer | 0xD3 21570 str 8 | string | 0xD9 21571 str 16 | string | 0xDA 21572 str 32 | string | 0xDB 21573 array 16 | array | 0xDC 21574 array 32 | array | 0xDD 21575 map 16 | object | 0xDE 21576 map 32 | object | 0xDF 21577 negative fixint | number_integer | 0xE0-0xFF 21578 21579 @warning The mapping is **incomplete** in the sense that not all 21580 MessagePack types can be converted to a JSON value. The following 21581 MessagePack types are not supported and will yield parse errors: 21582 - bin 8 - bin 32 (0xC4..0xC6) 21583 - ext 8 - ext 32 (0xC7..0xC9) 21584 - fixext 1 - fixext 16 (0xD4..0xD8) 21585 21586 @note Any MessagePack output created @ref to_msgpack can be successfully 21587 parsed by @ref from_msgpack. 21588 21589 @param[in] i an input in MessagePack format convertible to an input 21590 adapter 21591 @param[in] strict whether to expect the input to be consumed until EOF 21592 (true by default) 21593 @param[in] allow_exceptions whether to throw exceptions in case of a 21594 parse error (optional, true by default) 21595 21596 @return deserialized JSON value; in case of a parse error and 21597 @a allow_exceptions set to `false`, the return value will be 21598 value_t::discarded. 21599 21600 @throw parse_error.110 if the given input ends prematurely or the end of 21601 file was not reached when @a strict was set to true 21602 @throw parse_error.112 if unsupported features from MessagePack were 21603 used in the given input @a i or if the input is not valid MessagePack 21604 @throw parse_error.113 if a string was expected as map key, but not found 21605 21606 @complexity Linear in the size of the input @a i. 21607 21608 @liveexample{The example shows the deserialization of a byte vector in 21609 MessagePack format to a JSON value.,from_msgpack} 21610 21611 @sa http://msgpack.org 21612 @sa @ref to_msgpack(const basic_json&) for the analogous serialization 21613 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the 21614 related CBOR format 21615 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for 21616 the related UBJSON format 21617 @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for 21618 the related BSON format 21619 21620 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to 21621 consume input adapters, removed start_index parameter, and added 21622 @a strict parameter since 3.0.0; added @a allow_exceptions parameter 21623 since 3.2.0 21624 */ 21625 JSON_HEDLEY_WARN_UNUSED_RESULT 21626 static basic_json from_msgpack(detail::input_adapter&& i, 21627 const bool strict = true, 21628 const bool allow_exceptions = true) 21629 { 21630 basic_json result; 21631 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 21632 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::msgpack, &sdp, strict); 21633 return res ? result : basic_json(value_t::discarded); 21634 } 21635 21636 /*! 21637 @copydoc from_msgpack(detail::input_adapter&&, const bool, const bool) 21638 */ 21639 template<typename A1, typename A2, 21640 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0> 21641 JSON_HEDLEY_WARN_UNUSED_RESULT 21642 static basic_json from_msgpack(A1 && a1, A2 && a2, 21643 const bool strict = true, 21644 const bool allow_exceptions = true) 21645 { 21646 basic_json result; 21647 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 21648 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::msgpack, &sdp, strict); 21649 return res ? result : basic_json(value_t::discarded); 21650 } 21651 21652 /*! 21653 @brief create a JSON value from an input in UBJSON format 21654 21655 Deserializes a given input @a i to a JSON value using the UBJSON (Universal 21656 Binary JSON) serialization format. 21657 21658 The library maps UBJSON types to JSON value types as follows: 21659 21660 UBJSON type | JSON value type | marker 21661 ----------- | --------------------------------------- | ------ 21662 no-op | *no value, next value is read* | `N` 21663 null | `null` | `Z` 21664 false | `false` | `F` 21665 true | `true` | `T` 21666 float32 | number_float | `d` 21667 float64 | number_float | `D` 21668 uint8 | number_unsigned | `U` 21669 int8 | number_integer | `i` 21670 int16 | number_integer | `I` 21671 int32 | number_integer | `l` 21672 int64 | number_integer | `L` 21673 string | string | `S` 21674 char | string | `C` 21675 array | array (optimized values are supported) | `[` 21676 object | object (optimized values are supported) | `{` 21677 21678 @note The mapping is **complete** in the sense that any UBJSON value can 21679 be converted to a JSON value. 21680 21681 @param[in] i an input in UBJSON format convertible to an input adapter 21682 @param[in] strict whether to expect the input to be consumed until EOF 21683 (true by default) 21684 @param[in] allow_exceptions whether to throw exceptions in case of a 21685 parse error (optional, true by default) 21686 21687 @return deserialized JSON value; in case of a parse error and 21688 @a allow_exceptions set to `false`, the return value will be 21689 value_t::discarded. 21690 21691 @throw parse_error.110 if the given input ends prematurely or the end of 21692 file was not reached when @a strict was set to true 21693 @throw parse_error.112 if a parse error occurs 21694 @throw parse_error.113 if a string could not be parsed successfully 21695 21696 @complexity Linear in the size of the input @a i. 21697 21698 @liveexample{The example shows the deserialization of a byte vector in 21699 UBJSON format to a JSON value.,from_ubjson} 21700 21701 @sa http://ubjson.org 21702 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the 21703 analogous serialization 21704 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the 21705 related CBOR format 21706 @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for 21707 the related MessagePack format 21708 @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for 21709 the related BSON format 21710 21711 @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0 21712 */ 21713 JSON_HEDLEY_WARN_UNUSED_RESULT 21714 static basic_json from_ubjson(detail::input_adapter&& i, 21715 const bool strict = true, 21716 const bool allow_exceptions = true) 21717 { 21718 basic_json result; 21719 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 21720 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::ubjson, &sdp, strict); 21721 return res ? result : basic_json(value_t::discarded); 21722 } 21723 21724 /*! 21725 @copydoc from_ubjson(detail::input_adapter&&, const bool, const bool) 21726 */ 21727 template<typename A1, typename A2, 21728 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0> 21729 JSON_HEDLEY_WARN_UNUSED_RESULT 21730 static basic_json from_ubjson(A1 && a1, A2 && a2, 21731 const bool strict = true, 21732 const bool allow_exceptions = true) 21733 { 21734 basic_json result; 21735 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 21736 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::ubjson, &sdp, strict); 21737 return res ? result : basic_json(value_t::discarded); 21738 } 21739 21740 /*! 21741 @brief Create a JSON value from an input in BSON format 21742 21743 Deserializes a given input @a i to a JSON value using the BSON (Binary JSON) 21744 serialization format. 21745 21746 The library maps BSON record types to JSON value types as follows: 21747 21748 BSON type | BSON marker byte | JSON value type 21749 --------------- | ---------------- | --------------------------- 21750 double | 0x01 | number_float 21751 string | 0x02 | string 21752 document | 0x03 | object 21753 array | 0x04 | array 21754 binary | 0x05 | still unsupported 21755 undefined | 0x06 | still unsupported 21756 ObjectId | 0x07 | still unsupported 21757 boolean | 0x08 | boolean 21758 UTC Date-Time | 0x09 | still unsupported 21759 null | 0x0A | null 21760 Regular Expr. | 0x0B | still unsupported 21761 DB Pointer | 0x0C | still unsupported 21762 JavaScript Code | 0x0D | still unsupported 21763 Symbol | 0x0E | still unsupported 21764 JavaScript Code | 0x0F | still unsupported 21765 int32 | 0x10 | number_integer 21766 Timestamp | 0x11 | still unsupported 21767 128-bit decimal float | 0x13 | still unsupported 21768 Max Key | 0x7F | still unsupported 21769 Min Key | 0xFF | still unsupported 21770 21771 @warning The mapping is **incomplete**. The unsupported mappings 21772 are indicated in the table above. 21773 21774 @param[in] i an input in BSON format convertible to an input adapter 21775 @param[in] strict whether to expect the input to be consumed until EOF 21776 (true by default) 21777 @param[in] allow_exceptions whether to throw exceptions in case of a 21778 parse error (optional, true by default) 21779 21780 @return deserialized JSON value; in case of a parse error and 21781 @a allow_exceptions set to `false`, the return value will be 21782 value_t::discarded. 21783 21784 @throw parse_error.114 if an unsupported BSON record type is encountered 21785 21786 @complexity Linear in the size of the input @a i. 21787 21788 @liveexample{The example shows the deserialization of a byte vector in 21789 BSON format to a JSON value.,from_bson} 21790 21791 @sa http://bsonspec.org/spec.html 21792 @sa @ref to_bson(const basic_json&) for the analogous serialization 21793 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the 21794 related CBOR format 21795 @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for 21796 the related MessagePack format 21797 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the 21798 related UBJSON format 21799 */ 21800 JSON_HEDLEY_WARN_UNUSED_RESULT 21801 static basic_json from_bson(detail::input_adapter&& i, 21802 const bool strict = true, 21803 const bool allow_exceptions = true) 21804 { 21805 basic_json result; 21806 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 21807 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::bson, &sdp, strict); 21808 return res ? result : basic_json(value_t::discarded); 21809 } 21810 21811 /*! 21812 @copydoc from_bson(detail::input_adapter&&, const bool, const bool) 21813 */ 21814 template<typename A1, typename A2, 21815 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0> 21816 JSON_HEDLEY_WARN_UNUSED_RESULT 21817 static basic_json from_bson(A1 && a1, A2 && a2, 21818 const bool strict = true, 21819 const bool allow_exceptions = true) 21820 { 21821 basic_json result; 21822 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); 21823 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::bson, &sdp, strict); 21824 return res ? result : basic_json(value_t::discarded); 21825 } 21826 21827 21828 21829 /// @} 21830 21831 ////////////////////////// 21832 // JSON Pointer support // 21833 ////////////////////////// 21834 21835 /// @name JSON Pointer functions 21836 /// @{ 21837 21838 /*! 21839 @brief access specified element via JSON Pointer 21840 21841 Uses a JSON pointer to retrieve a reference to the respective JSON value. 21842 No bound checking is performed. Similar to @ref operator[](const typename 21843 object_t::key_type&), `null` values are created in arrays and objects if 21844 necessary. 21845 21846 In particular: 21847 - If the JSON pointer points to an object key that does not exist, it 21848 is created an filled with a `null` value before a reference to it 21849 is returned. 21850 - If the JSON pointer points to an array index that does not exist, it 21851 is created an filled with a `null` value before a reference to it 21852 is returned. All indices between the current maximum and the given 21853 index are also filled with `null`. 21854 - The special value `-` is treated as a synonym for the index past the 21855 end. 21856 21857 @param[in] ptr a JSON pointer 21858 21859 @return reference to the element pointed to by @a ptr 21860 21861 @complexity Constant. 21862 21863 @throw parse_error.106 if an array index begins with '0' 21864 @throw parse_error.109 if an array index was not a number 21865 @throw out_of_range.404 if the JSON pointer can not be resolved 21866 21867 @liveexample{The behavior is shown in the example.,operatorjson_pointer} 21868 21869 @since version 2.0.0 21870 */ 21871 reference operator[](const json_pointer& ptr) 21872 { 21873 return ptr.get_unchecked(this); 21874 } 21875 21876 /*! 21877 @brief access specified element via JSON Pointer 21878 21879 Uses a JSON pointer to retrieve a reference to the respective JSON value. 21880 No bound checking is performed. The function does not change the JSON 21881 value; no `null` values are created. In particular, the the special value 21882 `-` yields an exception. 21883 21884 @param[in] ptr JSON pointer to the desired element 21885 21886 @return const reference to the element pointed to by @a ptr 21887 21888 @complexity Constant. 21889 21890 @throw parse_error.106 if an array index begins with '0' 21891 @throw parse_error.109 if an array index was not a number 21892 @throw out_of_range.402 if the array index '-' is used 21893 @throw out_of_range.404 if the JSON pointer can not be resolved 21894 21895 @liveexample{The behavior is shown in the example.,operatorjson_pointer_const} 21896 21897 @since version 2.0.0 21898 */ 21899 const_reference operator[](const json_pointer& ptr) const 21900 { 21901 return ptr.get_unchecked(this); 21902 } 21903 21904 /*! 21905 @brief access specified element via JSON Pointer 21906 21907 Returns a reference to the element at with specified JSON pointer @a ptr, 21908 with bounds checking. 21909 21910 @param[in] ptr JSON pointer to the desired element 21911 21912 @return reference to the element pointed to by @a ptr 21913 21914 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr 21915 begins with '0'. See example below. 21916 21917 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr 21918 is not a number. See example below. 21919 21920 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr 21921 is out of range. See example below. 21922 21923 @throw out_of_range.402 if the array index '-' is used in the passed JSON 21924 pointer @a ptr. As `at` provides checked access (and no elements are 21925 implicitly inserted), the index '-' is always invalid. See example below. 21926 21927 @throw out_of_range.403 if the JSON pointer describes a key of an object 21928 which cannot be found. See example below. 21929 21930 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved. 21931 See example below. 21932 21933 @exceptionsafety Strong guarantee: if an exception is thrown, there are no 21934 changes in the JSON value. 21935 21936 @complexity Constant. 21937 21938 @since version 2.0.0 21939 21940 @liveexample{The behavior is shown in the example.,at_json_pointer} 21941 */ 21942 reference at(const json_pointer& ptr) 21943 { 21944 return ptr.get_checked(this); 21945 } 21946 21947 /*! 21948 @brief access specified element via JSON Pointer 21949 21950 Returns a const reference to the element at with specified JSON pointer @a 21951 ptr, with bounds checking. 21952 21953 @param[in] ptr JSON pointer to the desired element 21954 21955 @return reference to the element pointed to by @a ptr 21956 21957 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr 21958 begins with '0'. See example below. 21959 21960 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr 21961 is not a number. See example below. 21962 21963 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr 21964 is out of range. See example below. 21965 21966 @throw out_of_range.402 if the array index '-' is used in the passed JSON 21967 pointer @a ptr. As `at` provides checked access (and no elements are 21968 implicitly inserted), the index '-' is always invalid. See example below. 21969 21970 @throw out_of_range.403 if the JSON pointer describes a key of an object 21971 which cannot be found. See example below. 21972 21973 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved. 21974 See example below. 21975 21976 @exceptionsafety Strong guarantee: if an exception is thrown, there are no 21977 changes in the JSON value. 21978 21979 @complexity Constant. 21980 21981 @since version 2.0.0 21982 21983 @liveexample{The behavior is shown in the example.,at_json_pointer_const} 21984 */ 21985 const_reference at(const json_pointer& ptr) const 21986 { 21987 return ptr.get_checked(this); 21988 } 21989 21990 /*! 21991 @brief return flattened JSON value 21992 21993 The function creates a JSON object whose keys are JSON pointers (see [RFC 21994 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all 21995 primitive. The original JSON value can be restored using the @ref 21996 unflatten() function. 21997 21998 @return an object that maps JSON pointers to primitive values 21999 22000 @note Empty objects and arrays are flattened to `null` and will not be 22001 reconstructed correctly by the @ref unflatten() function. 22002 22003 @complexity Linear in the size the JSON value. 22004 22005 @liveexample{The following code shows how a JSON object is flattened to an 22006 object whose keys consist of JSON pointers.,flatten} 22007 22008 @sa @ref unflatten() for the reverse function 22009 22010 @since version 2.0.0 22011 */ 22012 basic_json flatten() const 22013 { 22014 basic_json result(value_t::object); 22015 json_pointer::flatten("", *this, result); 22016 return result; 22017 } 22018 22019 /*! 22020 @brief unflatten a previously flattened JSON value 22021 22022 The function restores the arbitrary nesting of a JSON value that has been 22023 flattened before using the @ref flatten() function. The JSON value must 22024 meet certain constraints: 22025 1. The value must be an object. 22026 2. The keys must be JSON pointers (see 22027 [RFC 6901](https://tools.ietf.org/html/rfc6901)) 22028 3. The mapped values must be primitive JSON types. 22029 22030 @return the original JSON from a flattened version 22031 22032 @note Empty objects and arrays are flattened by @ref flatten() to `null` 22033 values and can not unflattened to their original type. Apart from 22034 this example, for a JSON value `j`, the following is always true: 22035 `j == j.flatten().unflatten()`. 22036 22037 @complexity Linear in the size the JSON value. 22038 22039 @throw type_error.314 if value is not an object 22040 @throw type_error.315 if object values are not primitive 22041 22042 @liveexample{The following code shows how a flattened JSON object is 22043 unflattened into the original nested JSON object.,unflatten} 22044 22045 @sa @ref flatten() for the reverse function 22046 22047 @since version 2.0.0 22048 */ 22049 basic_json unflatten() const 22050 { 22051 return json_pointer::unflatten(*this); 22052 } 22053 22054 /// @} 22055 22056 ////////////////////////// 22057 // JSON Patch functions // 22058 ////////////////////////// 22059 22060 /// @name JSON Patch functions 22061 /// @{ 22062 22063 /*! 22064 @brief applies a JSON patch 22065 22066 [JSON Patch](http://jsonpatch.com) defines a JSON document structure for 22067 expressing a sequence of operations to apply to a JSON) document. With 22068 this function, a JSON Patch is applied to the current JSON value by 22069 executing all operations from the patch. 22070 22071 @param[in] json_patch JSON patch document 22072 @return patched document 22073 22074 @note The application of a patch is atomic: Either all operations succeed 22075 and the patched document is returned or an exception is thrown. In 22076 any case, the original value is not changed: the patch is applied 22077 to a copy of the value. 22078 22079 @throw parse_error.104 if the JSON patch does not consist of an array of 22080 objects 22081 22082 @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory 22083 attributes are missing); example: `"operation add must have member path"` 22084 22085 @throw out_of_range.401 if an array index is out of range. 22086 22087 @throw out_of_range.403 if a JSON pointer inside the patch could not be 22088 resolved successfully in the current JSON value; example: `"key baz not 22089 found"` 22090 22091 @throw out_of_range.405 if JSON pointer has no parent ("add", "remove", 22092 "move") 22093 22094 @throw other_error.501 if "test" operation was unsuccessful 22095 22096 @complexity Linear in the size of the JSON value and the length of the 22097 JSON patch. As usually only a fraction of the JSON value is affected by 22098 the patch, the complexity can usually be neglected. 22099 22100 @liveexample{The following code shows how a JSON patch is applied to a 22101 value.,patch} 22102 22103 @sa @ref diff -- create a JSON patch by comparing two JSON values 22104 22105 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) 22106 @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901) 22107 22108 @since version 2.0.0 22109 */ 22110 basic_json patch(const basic_json& json_patch) const 22111 { 22112 // make a working copy to apply the patch to 22113 basic_json result = *this; 22114 22115 // the valid JSON Patch operations 22116 enum class patch_operations {add, remove, replace, move, copy, test, invalid}; 22117 22118 const auto get_op = [](const std::string & op) 22119 { 22120 if (op == "add") 22121 { 22122 return patch_operations::add; 22123 } 22124 if (op == "remove") 22125 { 22126 return patch_operations::remove; 22127 } 22128 if (op == "replace") 22129 { 22130 return patch_operations::replace; 22131 } 22132 if (op == "move") 22133 { 22134 return patch_operations::move; 22135 } 22136 if (op == "copy") 22137 { 22138 return patch_operations::copy; 22139 } 22140 if (op == "test") 22141 { 22142 return patch_operations::test; 22143 } 22144 22145 return patch_operations::invalid; 22146 }; 22147 22148 // wrapper for "add" operation; add value at ptr 22149 const auto operation_add = [&result](json_pointer & ptr, basic_json val) 22150 { 22151 // adding to the root of the target document means replacing it 22152 if (ptr.empty()) 22153 { 22154 result = val; 22155 return; 22156 } 22157 22158 // make sure the top element of the pointer exists 22159 json_pointer top_pointer = ptr.top(); 22160 if (top_pointer != ptr) 22161 { 22162 result.at(top_pointer); 22163 } 22164 22165 // get reference to parent of JSON pointer ptr 22166 const auto last_path = ptr.back(); 22167 ptr.pop_back(); 22168 basic_json& parent = result[ptr]; 22169 22170 switch (parent.m_type) 22171 { 22172 case value_t::null: 22173 case value_t::object: 22174 { 22175 // use operator[] to add value 22176 parent[last_path] = val; 22177 break; 22178 } 22179 22180 case value_t::array: 22181 { 22182 if (last_path == "-") 22183 { 22184 // special case: append to back 22185 parent.push_back(val); 22186 } 22187 else 22188 { 22189 const auto idx = json_pointer::array_index(last_path); 22190 if (JSON_HEDLEY_UNLIKELY(static_cast<size_type>(idx) > parent.size())) 22191 { 22192 // avoid undefined behavior 22193 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range")); 22194 } 22195 22196 // default case: insert add offset 22197 parent.insert(parent.begin() + static_cast<difference_type>(idx), val); 22198 } 22199 break; 22200 } 22201 22202 // if there exists a parent it cannot be primitive 22203 default: // LCOV_EXCL_LINE 22204 assert(false); // LCOV_EXCL_LINE 22205 } 22206 }; 22207 22208 // wrapper for "remove" operation; remove value at ptr 22209 const auto operation_remove = [&result](json_pointer & ptr) 22210 { 22211 // get reference to parent of JSON pointer ptr 22212 const auto last_path = ptr.back(); 22213 ptr.pop_back(); 22214 basic_json& parent = result.at(ptr); 22215 22216 // remove child 22217 if (parent.is_object()) 22218 { 22219 // perform range check 22220 auto it = parent.find(last_path); 22221 if (JSON_HEDLEY_LIKELY(it != parent.end())) 22222 { 22223 parent.erase(it); 22224 } 22225 else 22226 { 22227 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found")); 22228 } 22229 } 22230 else if (parent.is_array()) 22231 { 22232 // note erase performs range check 22233 parent.erase(static_cast<size_type>(json_pointer::array_index(last_path))); 22234 } 22235 }; 22236 22237 // type check: top level value must be an array 22238 if (JSON_HEDLEY_UNLIKELY(not json_patch.is_array())) 22239 { 22240 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects")); 22241 } 22242 22243 // iterate and apply the operations 22244 for (const auto& val : json_patch) 22245 { 22246 // wrapper to get a value for an operation 22247 const auto get_value = [&val](const std::string & op, 22248 const std::string & member, 22249 bool string_type) -> basic_json & 22250 { 22251 // find value 22252 auto it = val.m_value.object->find(member); 22253 22254 // context-sensitive error message 22255 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'"; 22256 22257 // check if desired value is present 22258 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end())) 22259 { 22260 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'")); 22261 } 22262 22263 // check if result is of type string 22264 if (JSON_HEDLEY_UNLIKELY(string_type and not it->second.is_string())) 22265 { 22266 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'")); 22267 } 22268 22269 // no error: return value 22270 return it->second; 22271 }; 22272 22273 // type check: every element of the array must be an object 22274 if (JSON_HEDLEY_UNLIKELY(not val.is_object())) 22275 { 22276 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects")); 22277 } 22278 22279 // collect mandatory members 22280 const std::string op = get_value("op", "op", true); 22281 const std::string path = get_value(op, "path", true); 22282 json_pointer ptr(path); 22283 22284 switch (get_op(op)) 22285 { 22286 case patch_operations::add: 22287 { 22288 operation_add(ptr, get_value("add", "value", false)); 22289 break; 22290 } 22291 22292 case patch_operations::remove: 22293 { 22294 operation_remove(ptr); 22295 break; 22296 } 22297 22298 case patch_operations::replace: 22299 { 22300 // the "path" location must exist - use at() 22301 result.at(ptr) = get_value("replace", "value", false); 22302 break; 22303 } 22304 22305 case patch_operations::move: 22306 { 22307 const std::string from_path = get_value("move", "from", true); 22308 json_pointer from_ptr(from_path); 22309 22310 // the "from" location must exist - use at() 22311 basic_json v = result.at(from_ptr); 22312 22313 // The move operation is functionally identical to a 22314 // "remove" operation on the "from" location, followed 22315 // immediately by an "add" operation at the target 22316 // location with the value that was just removed. 22317 operation_remove(from_ptr); 22318 operation_add(ptr, v); 22319 break; 22320 } 22321 22322 case patch_operations::copy: 22323 { 22324 const std::string from_path = get_value("copy", "from", true); 22325 const json_pointer from_ptr(from_path); 22326 22327 // the "from" location must exist - use at() 22328 basic_json v = result.at(from_ptr); 22329 22330 // The copy is functionally identical to an "add" 22331 // operation at the target location using the value 22332 // specified in the "from" member. 22333 operation_add(ptr, v); 22334 break; 22335 } 22336 22337 case patch_operations::test: 22338 { 22339 bool success = false; 22340 JSON_TRY 22341 { 22342 // check if "value" matches the one at "path" 22343 // the "path" location must exist - use at() 22344 success = (result.at(ptr) == get_value("test", "value", false)); 22345 } 22346 JSON_INTERNAL_CATCH (out_of_range&) 22347 { 22348 // ignore out of range errors: success remains false 22349 } 22350 22351 // throw an exception if test fails 22352 if (JSON_HEDLEY_UNLIKELY(not success)) 22353 { 22354 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump())); 22355 } 22356 22357 break; 22358 } 22359 22360 default: 22361 { 22362 // op must be "add", "remove", "replace", "move", "copy", or 22363 // "test" 22364 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid")); 22365 } 22366 } 22367 } 22368 22369 return result; 22370 } 22371 22372 /*! 22373 @brief creates a diff as a JSON patch 22374 22375 Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can 22376 be changed into the value @a target by calling @ref patch function. 22377 22378 @invariant For two JSON values @a source and @a target, the following code 22379 yields always `true`: 22380 @code {.cpp} 22381 source.patch(diff(source, target)) == target; 22382 @endcode 22383 22384 @note Currently, only `remove`, `add`, and `replace` operations are 22385 generated. 22386 22387 @param[in] source JSON value to compare from 22388 @param[in] target JSON value to compare against 22389 @param[in] path helper value to create JSON pointers 22390 22391 @return a JSON patch to convert the @a source to @a target 22392 22393 @complexity Linear in the lengths of @a source and @a target. 22394 22395 @liveexample{The following code shows how a JSON patch is created as a 22396 diff for two JSON values.,diff} 22397 22398 @sa @ref patch -- apply a JSON patch 22399 @sa @ref merge_patch -- apply a JSON Merge Patch 22400 22401 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) 22402 22403 @since version 2.0.0 22404 */ 22405 JSON_HEDLEY_WARN_UNUSED_RESULT 22406 static basic_json diff(const basic_json& source, const basic_json& target, 22407 const std::string& path = "") 22408 { 22409 // the patch 22410 basic_json result(value_t::array); 22411 22412 // if the values are the same, return empty patch 22413 if (source == target) 22414 { 22415 return result; 22416 } 22417 22418 if (source.type() != target.type()) 22419 { 22420 // different types: replace value 22421 result.push_back( 22422 { 22423 {"op", "replace"}, {"path", path}, {"value", target} 22424 }); 22425 return result; 22426 } 22427 22428 switch (source.type()) 22429 { 22430 case value_t::array: 22431 { 22432 // first pass: traverse common elements 22433 std::size_t i = 0; 22434 while (i < source.size() and i < target.size()) 22435 { 22436 // recursive call to compare array values at index i 22437 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i)); 22438 result.insert(result.end(), temp_diff.begin(), temp_diff.end()); 22439 ++i; 22440 } 22441 22442 // i now reached the end of at least one array 22443 // in a second pass, traverse the remaining elements 22444 22445 // remove my remaining elements 22446 const auto end_index = static_cast<difference_type>(result.size()); 22447 while (i < source.size()) 22448 { 22449 // add operations in reverse order to avoid invalid 22450 // indices 22451 result.insert(result.begin() + end_index, object( 22452 { 22453 {"op", "remove"}, 22454 {"path", path + "/" + std::to_string(i)} 22455 })); 22456 ++i; 22457 } 22458 22459 // add other remaining elements 22460 while (i < target.size()) 22461 { 22462 result.push_back( 22463 { 22464 {"op", "add"}, 22465 {"path", path + "/" + std::to_string(i)}, 22466 {"value", target[i]} 22467 }); 22468 ++i; 22469 } 22470 22471 break; 22472 } 22473 22474 case value_t::object: 22475 { 22476 // first pass: traverse this object's elements 22477 for (auto it = source.cbegin(); it != source.cend(); ++it) 22478 { 22479 // escape the key name to be used in a JSON patch 22480 const auto key = json_pointer::escape(it.key()); 22481 22482 if (target.find(it.key()) != target.end()) 22483 { 22484 // recursive call to compare object values at key it 22485 auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key); 22486 result.insert(result.end(), temp_diff.begin(), temp_diff.end()); 22487 } 22488 else 22489 { 22490 // found a key that is not in o -> remove it 22491 result.push_back(object( 22492 { 22493 {"op", "remove"}, {"path", path + "/" + key} 22494 })); 22495 } 22496 } 22497 22498 // second pass: traverse other object's elements 22499 for (auto it = target.cbegin(); it != target.cend(); ++it) 22500 { 22501 if (source.find(it.key()) == source.end()) 22502 { 22503 // found a key that is not in this -> add it 22504 const auto key = json_pointer::escape(it.key()); 22505 result.push_back( 22506 { 22507 {"op", "add"}, {"path", path + "/" + key}, 22508 {"value", it.value()} 22509 }); 22510 } 22511 } 22512 22513 break; 22514 } 22515 22516 default: 22517 { 22518 // both primitive type: replace value 22519 result.push_back( 22520 { 22521 {"op", "replace"}, {"path", path}, {"value", target} 22522 }); 22523 break; 22524 } 22525 } 22526 22527 return result; 22528 } 22529 22530 /// @} 22531 22532 //////////////////////////////// 22533 // JSON Merge Patch functions // 22534 //////////////////////////////// 22535 22536 /// @name JSON Merge Patch functions 22537 /// @{ 22538 22539 /*! 22540 @brief applies a JSON Merge Patch 22541 22542 The merge patch format is primarily intended for use with the HTTP PATCH 22543 method as a means of describing a set of modifications to a target 22544 resource's content. This function applies a merge patch to the current 22545 JSON value. 22546 22547 The function implements the following algorithm from Section 2 of 22548 [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396): 22549 22550 ``` 22551 define MergePatch(Target, Patch): 22552 if Patch is an Object: 22553 if Target is not an Object: 22554 Target = {} // Ignore the contents and set it to an empty Object 22555 for each Name/Value pair in Patch: 22556 if Value is null: 22557 if Name exists in Target: 22558 remove the Name/Value pair from Target 22559 else: 22560 Target[Name] = MergePatch(Target[Name], Value) 22561 return Target 22562 else: 22563 return Patch 22564 ``` 22565 22566 Thereby, `Target` is the current object; that is, the patch is applied to 22567 the current value. 22568 22569 @param[in] apply_patch the patch to apply 22570 22571 @complexity Linear in the lengths of @a patch. 22572 22573 @liveexample{The following code shows how a JSON Merge Patch is applied to 22574 a JSON document.,merge_patch} 22575 22576 @sa @ref patch -- apply a JSON patch 22577 @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396) 22578 22579 @since version 3.0.0 22580 */ 22581 void merge_patch(const basic_json& apply_patch) 22582 { 22583 if (apply_patch.is_object()) 22584 { 22585 if (not is_object()) 22586 { 22587 *this = object(); 22588 } 22589 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it) 22590 { 22591 if (it.value().is_null()) 22592 { 22593 erase(it.key()); 22594 } 22595 else 22596 { 22597 operator[](it.key()).merge_patch(it.value()); 22598 } 22599 } 22600 } 22601 else 22602 { 22603 *this = apply_patch; 22604 } 22605 } 22606 22607 /// @} 22608}; 22609 22610/*! 22611@brief user-defined to_string function for JSON values 22612 22613This function implements a user-defined to_string for JSON objects. 22614 22615@param[in] j a JSON object 22616@return a std::string object 22617*/ 22618 22619NLOHMANN_BASIC_JSON_TPL_DECLARATION 22620std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j) 22621{ 22622 return j.dump(); 22623} 22624} // namespace nlohmann 22625 22626/////////////////////// 22627// nonmember support // 22628/////////////////////// 22629 22630// specialization of std::swap, and std::hash 22631namespace std 22632{ 22633 22634/// hash value for JSON objects 22635template<> 22636struct hash<nlohmann::json> 22637{ 22638 /*! 22639 @brief return a hash value for a JSON object 22640 22641 @since version 1.0.0 22642 */ 22643 std::size_t operator()(const nlohmann::json& j) const 22644 { 22645 // a naive hashing via the string representation 22646 const auto& h = hash<nlohmann::json::string_t>(); 22647 return h(j.dump()); 22648 } 22649}; 22650 22651/// specialization for std::less<value_t> 22652/// @note: do not remove the space after '<', 22653/// see https://github.com/nlohmann/json/pull/679 22654template<> 22655struct less<::nlohmann::detail::value_t> 22656{ 22657 /*! 22658 @brief compare two value_t enum values 22659 @since version 3.0.0 22660 */ 22661 bool operator()(nlohmann::detail::value_t lhs, 22662 nlohmann::detail::value_t rhs) const noexcept 22663 { 22664 return nlohmann::detail::operator<(lhs, rhs); 22665 } 22666}; 22667 22668/*! 22669@brief exchanges the values of two JSON objects 22670 22671@since version 1.0.0 22672*/ 22673template<> 22674inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept( 22675 is_nothrow_move_constructible<nlohmann::json>::value and 22676 is_nothrow_move_assignable<nlohmann::json>::value 22677) 22678{ 22679 j1.swap(j2); 22680} 22681 22682} // namespace std 22683 22684/*! 22685@brief user-defined string literal for JSON values 22686 22687This operator implements a user-defined string literal for JSON objects. It 22688can be used by adding `"_json"` to a string literal and returns a JSON object 22689if no parse error occurred. 22690 22691@param[in] s a string representation of a JSON object 22692@param[in] n the length of string @a s 22693@return a JSON object 22694 22695@since version 1.0.0 22696*/ 22697JSON_HEDLEY_NON_NULL(1) 22698inline nlohmann::json operator "" _json(const char* s, std::size_t n) 22699{ 22700 return nlohmann::json::parse(s, s + n); 22701} 22702 22703/*! 22704@brief user-defined string literal for JSON pointer 22705 22706This operator implements a user-defined string literal for JSON Pointers. It 22707can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer 22708object if no parse error occurred. 22709 22710@param[in] s a string representation of a JSON Pointer 22711@param[in] n the length of string @a s 22712@return a JSON pointer object 22713 22714@since version 2.0.0 22715*/ 22716JSON_HEDLEY_NON_NULL(1) 22717inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n) 22718{ 22719 return nlohmann::json::json_pointer(std::string(s, n)); 22720} 22721 22722// #include <nlohmann/detail/macro_unscope.hpp> 22723 22724 22725// restore GCC/clang diagnostic settings 22726#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 22727 #pragma GCC diagnostic pop 22728#endif 22729#if defined(__clang__) 22730 #pragma GCC diagnostic pop 22731#endif 22732 22733// clean up 22734#undef JSON_INTERNAL_CATCH 22735#undef JSON_CATCH 22736#undef JSON_THROW 22737#undef JSON_TRY 22738#undef JSON_HAS_CPP_14 22739#undef JSON_HAS_CPP_17 22740#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION 22741#undef NLOHMANN_BASIC_JSON_TPL 22742 22743// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp> 22744#undef JSON_HEDLEY_ALWAYS_INLINE 22745#undef JSON_HEDLEY_ARM_VERSION 22746#undef JSON_HEDLEY_ARM_VERSION_CHECK 22747#undef JSON_HEDLEY_ARRAY_PARAM 22748#undef JSON_HEDLEY_ASSUME 22749#undef JSON_HEDLEY_BEGIN_C_DECLS 22750#undef JSON_HEDLEY_C_DECL 22751#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE 22752#undef JSON_HEDLEY_CLANG_HAS_BUILTIN 22753#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE 22754#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE 22755#undef JSON_HEDLEY_CLANG_HAS_EXTENSION 22756#undef JSON_HEDLEY_CLANG_HAS_FEATURE 22757#undef JSON_HEDLEY_CLANG_HAS_WARNING 22758#undef JSON_HEDLEY_COMPCERT_VERSION 22759#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK 22760#undef JSON_HEDLEY_CONCAT 22761#undef JSON_HEDLEY_CONCAT_EX 22762#undef JSON_HEDLEY_CONST 22763#undef JSON_HEDLEY_CONST_CAST 22764#undef JSON_HEDLEY_CONSTEXPR 22765#undef JSON_HEDLEY_CPP_CAST 22766#undef JSON_HEDLEY_CRAY_VERSION 22767#undef JSON_HEDLEY_CRAY_VERSION_CHECK 22768#undef JSON_HEDLEY_DEPRECATED 22769#undef JSON_HEDLEY_DEPRECATED_FOR 22770#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL 22771#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ 22772#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED 22773#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES 22774#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS 22775#undef JSON_HEDLEY_DIAGNOSTIC_POP 22776#undef JSON_HEDLEY_DIAGNOSTIC_PUSH 22777#undef JSON_HEDLEY_DMC_VERSION 22778#undef JSON_HEDLEY_DMC_VERSION_CHECK 22779#undef JSON_HEDLEY_EMPTY_BASES 22780#undef JSON_HEDLEY_EMSCRIPTEN_VERSION 22781#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK 22782#undef JSON_HEDLEY_END_C_DECLS 22783#undef JSON_HEDLEY_FALL_THROUGH 22784#undef JSON_HEDLEY_FLAGS 22785#undef JSON_HEDLEY_FLAGS_CAST 22786#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE 22787#undef JSON_HEDLEY_GCC_HAS_BUILTIN 22788#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE 22789#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE 22790#undef JSON_HEDLEY_GCC_HAS_EXTENSION 22791#undef JSON_HEDLEY_GCC_HAS_FEATURE 22792#undef JSON_HEDLEY_GCC_HAS_WARNING 22793#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK 22794#undef JSON_HEDLEY_GCC_VERSION 22795#undef JSON_HEDLEY_GCC_VERSION_CHECK 22796#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE 22797#undef JSON_HEDLEY_GNUC_HAS_BUILTIN 22798#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE 22799#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE 22800#undef JSON_HEDLEY_GNUC_HAS_EXTENSION 22801#undef JSON_HEDLEY_GNUC_HAS_FEATURE 22802#undef JSON_HEDLEY_GNUC_HAS_WARNING 22803#undef JSON_HEDLEY_GNUC_VERSION 22804#undef JSON_HEDLEY_GNUC_VERSION_CHECK 22805#undef JSON_HEDLEY_HAS_ATTRIBUTE 22806#undef JSON_HEDLEY_HAS_BUILTIN 22807#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE 22808#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS 22809#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE 22810#undef JSON_HEDLEY_HAS_EXTENSION 22811#undef JSON_HEDLEY_HAS_FEATURE 22812#undef JSON_HEDLEY_HAS_WARNING 22813#undef JSON_HEDLEY_IAR_VERSION 22814#undef JSON_HEDLEY_IAR_VERSION_CHECK 22815#undef JSON_HEDLEY_IBM_VERSION 22816#undef JSON_HEDLEY_IBM_VERSION_CHECK 22817#undef JSON_HEDLEY_IMPORT 22818#undef JSON_HEDLEY_INLINE 22819#undef JSON_HEDLEY_INTEL_VERSION 22820#undef JSON_HEDLEY_INTEL_VERSION_CHECK 22821#undef JSON_HEDLEY_IS_CONSTANT 22822#undef JSON_HEDLEY_IS_CONSTEXPR_ 22823#undef JSON_HEDLEY_LIKELY 22824#undef JSON_HEDLEY_MALLOC 22825#undef JSON_HEDLEY_MESSAGE 22826#undef JSON_HEDLEY_MSVC_VERSION 22827#undef JSON_HEDLEY_MSVC_VERSION_CHECK 22828#undef JSON_HEDLEY_NEVER_INLINE 22829#undef JSON_HEDLEY_NO_ESCAPE 22830#undef JSON_HEDLEY_NON_NULL 22831#undef JSON_HEDLEY_NO_RETURN 22832#undef JSON_HEDLEY_NO_THROW 22833#undef JSON_HEDLEY_NULL 22834#undef JSON_HEDLEY_PELLES_VERSION 22835#undef JSON_HEDLEY_PELLES_VERSION_CHECK 22836#undef JSON_HEDLEY_PGI_VERSION 22837#undef JSON_HEDLEY_PGI_VERSION_CHECK 22838#undef JSON_HEDLEY_PREDICT 22839#undef JSON_HEDLEY_PRINTF_FORMAT 22840#undef JSON_HEDLEY_PRIVATE 22841#undef JSON_HEDLEY_PUBLIC 22842#undef JSON_HEDLEY_PURE 22843#undef JSON_HEDLEY_REINTERPRET_CAST 22844#undef JSON_HEDLEY_REQUIRE 22845#undef JSON_HEDLEY_REQUIRE_CONSTEXPR 22846#undef JSON_HEDLEY_REQUIRE_MSG 22847#undef JSON_HEDLEY_RESTRICT 22848#undef JSON_HEDLEY_RETURNS_NON_NULL 22849#undef JSON_HEDLEY_SENTINEL 22850#undef JSON_HEDLEY_STATIC_ASSERT 22851#undef JSON_HEDLEY_STATIC_CAST 22852#undef JSON_HEDLEY_STRINGIFY 22853#undef JSON_HEDLEY_STRINGIFY_EX 22854#undef JSON_HEDLEY_SUNPRO_VERSION 22855#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK 22856#undef JSON_HEDLEY_TINYC_VERSION 22857#undef JSON_HEDLEY_TINYC_VERSION_CHECK 22858#undef JSON_HEDLEY_TI_VERSION 22859#undef JSON_HEDLEY_TI_VERSION_CHECK 22860#undef JSON_HEDLEY_UNAVAILABLE 22861#undef JSON_HEDLEY_UNLIKELY 22862#undef JSON_HEDLEY_UNPREDICTABLE 22863#undef JSON_HEDLEY_UNREACHABLE 22864#undef JSON_HEDLEY_UNREACHABLE_RETURN 22865#undef JSON_HEDLEY_VERSION 22866#undef JSON_HEDLEY_VERSION_DECODE_MAJOR 22867#undef JSON_HEDLEY_VERSION_DECODE_MINOR 22868#undef JSON_HEDLEY_VERSION_DECODE_REVISION 22869#undef JSON_HEDLEY_VERSION_ENCODE 22870#undef JSON_HEDLEY_WARNING 22871#undef JSON_HEDLEY_WARN_UNUSED_RESULT 22872 22873 22874 22875#endif // INCLUDE_NLOHMANN_JSON_HPP_