{"id":15047938,"url":"https://github.com/kimushu/json5pp","last_synced_at":"2025-04-10T01:10:57.793Z","repository":{"id":65532309,"uuid":"171095666","full_name":"kimushu/json5pp","owner":"kimushu","description":"JSON (ECMA-404 and JSON5) parser \u0026 stringifier for C++11","archived":false,"fork":false,"pushed_at":"2023-04-21T05:57:06.000Z","size":53,"stargazers_count":20,"open_issues_count":3,"forks_count":9,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-10T01:10:50.892Z","etag":null,"topics":["cplusplus","cplusplus-11","cpp","cpp11","ecma404","json","json5"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kimushu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-02-17T07:49:46.000Z","updated_at":"2025-02-08T03:01:41.000Z","dependencies_parsed_at":"2025-02-16T06:32:38.615Z","dependency_job_id":"15b72e94-5708-444c-b0f3-0fc58384ac82","html_url":"https://github.com/kimushu/json5pp","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kimushu%2Fjson5pp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kimushu%2Fjson5pp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kimushu%2Fjson5pp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kimushu%2Fjson5pp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kimushu","download_url":"https://codeload.github.com/kimushu/json5pp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248137886,"owners_count":21053775,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cplusplus","cplusplus-11","cpp","cpp11","ecma404","json","json5"],"created_at":"2024-09-24T21:06:09.634Z","updated_at":"2025-04-10T01:10:57.769Z","avatar_url":"https://github.com/kimushu.png","language":"C++","readme":"# json5pp\nJSON (ECMA-404 and JSON5) parser \u0026amp; stringifier written in **C++11**.\n\n# Features\n\n* Easy to embed to your project. Only single file `json5pp.hpp` required.\n* Parse [standard JSON (ECMA-404)](https://www.json.org/) from `std::istream` or `std::string`.\n* Parse [JSON5](https://json5.org/) from `std::istream` or `std::string`.\n* Stringify to `std::ostream` or `std::string` as standard JSON.\n* Stringify to `std::ostream` or `std::string` as JSON5.\n\n# Requirements\n\n* Compilers with C++11 support\n\n# License\n\n* MIT license\n\n# API\n\n## JSON value type\n\n```cpp\nnamespace json5pp {\n  class value {\n  };\n}\n```\n* The class holds a value which is represented in JSON.\n* This class can hold all types in JSON:\n  * `null`\n  * boolean (`true` / `false`)\n  * number\n  * string\n  * array (stored as `std::vector\u003cjson5pp::value\u003e`)\n  * object (stored as `std::map\u003cstd::string, json5pp::value\u003e`)\n* Provides type check with `is_xxx()` method. (`xxx` is one of `null`, `boolean`, `number`, `string`, `array` and `object`)\n* Provides explicit cast to C++ type with `as_xxx()` method. (`xxx` is one of `null`, `boolean`, `number`, `integer`, `string`, `array` and `object`)\n  * If cast failed, throws `std::bad_cast`\n* Accepts implicit cast (by overload of `operator=`) from C++ type (`nullptr_t`, `bool`, `double` | `int`, `std::string` | `const char*`)\n* See [examples](#Examples) for details\n\n## Parse functions\n\n```cpp\nnamespace json5pp {\n  value parse(const std::string\u0026 str);\n}\n```\n* Parse given string.\n* String must be a valid JSON (ECMA-404 standard)\n  * If not valid, throws `json5pp::syntax_error`.\n* String must be a finished (closed) JSON.\n  * i.e. If there are any junk data (except for spaces) after JSON, throws `json5pp::syntax_error`.\n\n```cpp\nnamespace json5pp {\n  value parse(std::istream\u0026 istream, bool finish = true)\n}\n```\n* Parse JSON from given input stream.\n* Stream must have a valid JSON (ECMA-404 standard).\n  * If not valid, throws `json5pp::syntax_error`.\n* If `finish` is true, stream must be closed by eof after JSON.\n\n```cpp\nnamespace json5pp {\n  value parse5(const std::string\u0026 str);\n}\n```\n* JSON5 version of `parse(const std::string\u0026)`\n\n```cpp\nnamespace json5pp {\n  value parse5(std::istream\u0026 istream, bool finish = true);\n}\n```\n* JSON5 version of `parse(std::istream\u0026, bool)`\n\n## Stringify functions\n\n```cpp\nnamespace json5pp {\n  class value {\n    template \u003cclass... T\u003e\n    std::string stringify(T... manip);\n  };\n}\n```\n* Stringify value to ECMA-404 standard JSON.\n* About `T... manip`, see [iostream overloads and manipulators](#iostream-API-and-manipulators)\n\n```cpp\nnamespace json5pp {\n  class value {\n    template \u003cclass... T\u003e\n    std::string stringify5(T... manip);\n  };\n}\n```\n* Stringify value to JSON5.\n* About `T... manip`, see [iostream overloads and manipulators](#iostream-API-and-manipulators)\n\n```cpp\nnamespace json5pp {\n  template \u003cclass... T\u003e\n  std::string stringify(const value\u0026 v, T... manip);\n}\n```\n* Global method version of `json5pp::value::stringify()`\n* Same as `v.stringify(manip...)`\n\n```cpp\nnamespace json5pp {\n  template \u003cclass... T\u003e\n  std::string stringify5(const value\u0026 v, T... manip);\n}\n```\n* Global method version of `json5pp::value::stringify5()`\n* Same as `v.stringify5(manip...)`\n\n## iostream API\n\n### Parse by `operator\u003e\u003e`\n```cpp\nstd::istream\u0026 istream = ...;\njson5pp::value v;\nistream \u003e\u003e v;\n```\n\n### Parse by `operator\u003e\u003e` with manipulators\n```cpp\nstd::istream\u0026 istream = ...;\njson5pp::value v;\nistream \u003e\u003e json5pp::rule::json5() \u003e\u003e v; // Parse as JSON5\n```\n\n### Stringify by `operator\u003c\u003c`\n```cpp\nstd::ostream\u0026 ostream = ...;\nconst json5pp::value\u0026 v = ...;\nostream \u003c\u003c v;\n```\n\n### Stringify by `operator\u003c\u003c` with manipulators\n```cpp\nstd::ostream\u0026 ostream = ...;\nconst json5pp::value\u0026 v = ...;\nostream \u003c\u003c json5pp::rule::tab_indent\u003c1\u003e() \u003c\u003c v;   // Stringify with tab indent\nostream \u003c\u003c json5pp::rule::space_indent\u003c2\u003e() \u003c\u003c v; // Stringify with 2-space indent\n```\n\n## Manipulators\n\n### Comments\n* `json5pp::rule::single_line_comment()`\n* `json5pp::rule::no_single_line_comment()`\n  * Allow/disallow single line comment starts with `//`\n* `json5pp::rule::multi_line_comment()`\n* `json5pp::rule::no_multi_line_comment()`\n  * Allow/disallow multiple line comment starts with `/*` and ends with `*/`\n* `json5pp::rule::comments()`\n* `json5pp::rule::no_comments()`\n  * Combination of `single_line_comment` and `multi_line_comment`\n\n### Numbers\n* `json5pp::rule::explicit_plus_sign()`\n* `json5pp::rule::no_explicit_plus_sign()`\n  * Allow/disallow explicit plus sign (`+`) before non-negative number (ex: `+123`)\n* `json5pp::rule::leading_decimal_point()`\n* `json5pp::rule::no_leading_decimal_point()`\n  * Allow/disallow leading decimal point before number (ex: `.123`)\n* `json5pp::rule::trailing_decimal_point()`\n* `json5pp::rule::no_trailing_decimal_point()`\n  * Allow/disallow trailing decimal point after number (ex: `123.`)\n* `json5pp::rule::decimal_points()`\n* `json5pp::rule::no_decimal_points()`\n  * Combination of `leading_decimal_point` and `trailing_decimal_point`\n* `json5pp::rule::infinity_number()`\n* `json5pp::rule::no_infinity_number()`\n  * Allow/disallow infinity number\n* `json5pp::rule::not_a_number()`\n* `json5pp::rule::no_not_a_number()`\n  * Allow/disallow NaN\n* `json5pp::rule::hexadecimal()`\n* `json5pp::rule::no_hexadecimal()`\n  * Allow/disallow hexadecimal number (ex: `0x123`)\n\n### Strings\n* `json5pp::rule::single_quote()`\n* `json5pp::rule::no_single_quote()`\n  * Allow/disallow single quoted string (ex: `'foobar'`)\n* `json5pp::rule::multi_line_string()`\n* `json5pp::rule::no_multi_line_string()`\n  * Allow/disallow multiple line string escaped by `\\`\n  * Example:\n    ```json\n    \"test\\\n    2nd line\"\n    ```\n\n### Arrays and objects\n* `json5pp::rule::trailing_comma()`\n* `json5pp::rule::no_trailing_comma()`\n  * Allow/disallow trailing comma at the end of arrays or objects.\n  * Example for arrays: `[1,2,3,]`\n  * Example for objects: `{\"a\":123,}`\n\n### Objects\n* `json5pp::rule::unquoted_key()`\n* `json5pp::rule::no_unquoted_key()`\n  * Allow/disallow unquoted keys in objects. (ex: `{a:123}`)\n\n### Rule sets\n* `json5pp::rule::ecma404()`\n  * ECMA-404 standard rule set.\n* `json5pp::rule::json5()`\n  * JSON5 rule set.\n\n### Parse options\n* `json5pp::rule::finished()`\n  * Parse as finished (closed) JSON. If any junk data follows after JSON, parse fails.\n  * Opposite to `json5pp::rule::streaming()`\n* `json5pp::rule::streaming()`\n  * Parse as non-finished (non-closed) JSON. Parse will succeed at the end of JSON.\n  * Opposite to `json5pp::rule::finished()`\n\n### Stringify options\n* `json5pp::rule::lf_newline()`\n  * When indent is enabled, use LF(`\\n`) as new-line code.\n  * Opposite to `json5pp::rule::crlf_newline`\n* `json5pp::rule::crlf_newline()`\n  * When indent is enabled, use CR+LF(`\\r\\n`) as new-line code.\n  * Opposite to `json5pp::rule::lf_newline`\n* `json5pp::rule::no_indent()`\n  * Disable indent. All arrays and objects will be stringified as one-line.\n* `json5pp::rule::tab_indent\u003cL\u003e()`\n  * Enable indent with tab character(s).\n  * `L` means a number of tab (`\\t`) characters for one-level indent.\n  * If `L` is omitted, treat as `L=1`.\n* `json5pp::rule::space_indent\u003cL\u003e()`\n  * Enable indent with space character(s).\n  * `L` means a number of space (` `) characters for one-level indent.\n  * If `L` is omitted, treat as `L=2`.\n\n## Examples\n\n### Constructing `value` object\n\n```cpp\nusing namespace std;\n\n// Construct \"null\" value\njson5pp::value a;               // Default constructor\ncout \u003c\u003c a.is_null() \u003c\u003c endl;    // =\u003e 1\ncout \u003c\u003c a \u003c\u003c endl;              // =\u003e null\n\njson5pp::value b(nullptr);      // Constructor with std::nullptr_t argument\ncout \u003c\u003c b.is_null() \u003c\u003c endl;    // =\u003e 1\ncout \u003c\u003c b \u003c\u003c endl;              // =\u003e null\n\n// json5pp::value c(NULL);      // Compile error\n                                // NULL cannot be used instead of nullptr\n\n// Construct boolean value\njson5pp::value d(true);         // Constructor with bool argument\ncout \u003c\u003c d.is_boolean() \u003c\u003c endl; // =\u003e 1\ncout \u003c\u003c d \u003c\u003c endl;              // =\u003e true\n\n// Construct number value\njson5pp::value e(123.45);       // Constructor with double argument\ncout \u003c\u003c e.is_number() \u003c\u003c endl;  // =\u003e 1\ncout \u003c\u003c e \u003c\u003c endl;              // =\u003e 123.45\n\njson5pp::value f(789);          // Constructor with int argument\ncout \u003c\u003c f.is_number() \u003c\u003c endl;  // =\u003e 1\ncout \u003c\u003c f \u003c\u003c endl;              // =\u003e 789\n\n// Construct string value\nstd::string str(\"foo\");\njson5pp::value g(str);          // Constructor with const std::string\u0026 argument\ncout \u003c\u003c g.is_string() \u003c\u003c endl;  // =\u003e 1\ncout \u003c\u003c g \u003c\u003c endl;              // =\u003e \"foo\"\n\njson5pp::value h(\"bar\");        // Constructor with const char* argument\ncout \u003c\u003c h.is_string() \u003c\u003c endl;  // =\u003e 1\ncout \u003c\u003c h \u003c\u003c endl;              // =\u003e \"bar\"\n\n// Construct array value\njson5pp::value i {1, false, \"baz\", nullptr};\n                                // Construct with std::initializer_list\ncout \u003c\u003c i.is_array() \u003c\u003c endl;   // =\u003e 1\ncout \u003c\u003c i \u003c\u003c endl;              // =\u003e [1,false,\"baz\",null]\n\nauto j = json5pp::array({1, false, \"baz\", nullptr});\n                                // Construct with utility function: json5pp::array()\ncout \u003c\u003c j.is_array() \u003c\u003c endl;   // =\u003e 1\ncout \u003c\u003c j \u003c\u003c endl;              // =\u003e [1,false,\"baz\",null]\n\n// json5pp::value k {{\"foo\", 123}};\n                                // Compile error (*1)\n\n// Construct object value\nauto m = json5pp::object({{\"bar\", 123}, {\"foo\", \"baz\"}});\n                                // Construct with utility function: json5pp::object()\ncout \u003c\u003c m.is_object() \u003c\u003c endl;  // =\u003e 1\ncout \u003c\u003c m \u003c\u003c endl;              // =\u003e {\"bar\":123,\"foo\":\"baz\"}\n\n// json5pp::value n{{\"foo\", 123}};\n                                // Compile error (*1)\n\n// (*1)\n// These forms are rejected because an implicit conversion\n// for arrays and objects makes ambiguousness, for example:\n// json5pp::value x{{\"foo\", 123}};  // Ambiguous!\n//                                  // candidate: [[\"foo\",123]]\n//                                  // candidate: {\"foo\":123}\n//\n// Use utility functions (json5pp::array(),json5pp::object()) to remove\n// ambiguousness.\n```\n\n### Changing `value` object\n```cpp\nusing namespace std;\n\njson5pp::value x;       // Default constructor makes null value\ncout \u003c\u003c x \u003c\u003c endl;      // =\u003e null\nx = false;              // Assign boolean with bool value\ncout \u003c\u003c x \u003c\u003c endl;      // =\u003e false\nx = 123.45;             // Assign number with double value\ncout \u003c\u003c x \u003c\u003c endl;      // =\u003e 123.45\nx = 789;                // Assign number with int value\ncout \u003c\u003c x \u003c\u003c endl;      // =\u003e 789\nstd::string str(\"bar\");\nx = str;                // Assign string with const std::string\u0026 value\ncout \u003c\u003c x \u003c\u003c endl;      // =\u003e \"bar\"\n                        // Because assignment copies the content of string,\n                        // changing a source string does not affect `x`:\nstr += \"123\";\ncout \u003c\u003c x \u003c\u003c endl;      // =\u003e \"bar\" (Contents does NOT change)\nx = \"foo\";              // Assign string with const char* value\ncout \u003c\u003c x \u003c\u003c endl;      // =\u003e \"foo\"\nx = nullptr;            // Assign null with nullptr_t value\ncout \u003c\u003c x \u003c\u003c endl;      // =\u003e null\n\nx = json5pp::array({1});// Assign array with utility function: json5pp::array()\ncout \u003c\u003c x \u003c\u003c endl;      // =\u003e [1]\n\nauto\u0026 a = x.as_array(); // You can get container object by as_array() method\n                        // decltype(a) =\u003e std::vector\u003cjson5pp::value\u003e\u0026\na.push_back(\"foo\");     // Add value at the end of array\ncout \u003c\u003c x \u003c\u003c endl;      // =\u003e [1,\"foo\"]\n\nx = json5pp::object({{\"foo\",\"bar\"}});\n                        // Assign object with utility function: json5pp::object()\ncout \u003c\u003c x \u003c\u003c endl;      // =\u003e {\"foo\":\"bar\"}\n\n// Note: Do not access `a` (array container) after replacing the content of `x`\n//       with a new object.\n\nauto\u0026 o = x.as_object();// You can get container object by as_object() method\n                        // decltype(o) =\u003e std::map\u003cstd::string, json5pp::value\u003e\u0026\n                        // Note: Do not forget `\u0026` when you use `auto` keyword!\no.emplace(\"baz\", 123);  // Add value with key \"baz\"\ncout \u003c\u003c x \u003c\u003c endl;      // =\u003e {\"baz\":123,\"foo\":\"bar\"}\n\njson5pp::value y;\ny = x;                  // You can copy the value by \"=\" operator\ncout \u003c\u003c y \u003c\u003c endl;      // =\u003e {\"baz\":123,\"foo\":\"bar\"}\n\n                        // Because assignment arrays/objects is a deep copy,\n                        // changing a source value `x` does not affect `y`:\no.erase(\"foo\");         // Remove key \"foo\" from the content of `x` object\ncout \u003c\u003c x \u003c\u003c endl;      // =\u003e {\"baz\":123}\ncout \u003c\u003c y \u003c\u003c endl;      // =\u003e {\"baz\":123,\"foo\":\"bar\"} (Contents does NOT change)\n```\n\n### Accessing `value` object\n```cpp\nusing namespace std;\n\n// Access boolean (See also: Truthy/falsy tests)\njson5pp::value a(true);\nauto a_value = a.as_boolean();    // decltype(a_value) =\u003e bool\ncout \u003c\u003c a_value \u003c\u003c endl;          // =\u003e 1\n\n// Access number\njson5pp::value b(123.45);\nauto b_value1 = b.as_number();    // decltype(b_value1) =\u003e double\ncout \u003c\u003c b_value1 \u003c\u003c endl;         // =\u003e 123.45\nauto b_value2 = b.as_integer();   // decltype(b_value2) =\u003e int\ncout \u003c\u003c b_value2 \u003c\u003c endl;         // =\u003e 123\n\n// Access string\njson5pp::value c(\"foo\");\nauto c_value = c.as_string();     // decltype(c_value) =\u003e std::string\ncout \u003c\u003c c_value \u003c\u003c endl;          // =\u003e foo\n\n// Access array\njson5pp::value d{1, \"foo\", false};\nauto\u0026 d_value = d.as_array();     // decltype(d_value) =\u003e std::vector\u003cjson5pp::value\u003e\u0026\ncout \u003c\u003c d_value.size() \u003c\u003c endl;           // =\u003e 3\ncout \u003c\u003c d_value[0].as_number() \u003c\u003c endl;   // =\u003e 1\ncout \u003c\u003c d_value[1].as_string() \u003c\u003c endl;   // =\u003e foo\ncout \u003c\u003c d_value[2].as_boolean() \u003c\u003c endl;  // =\u003e 0\n\n// Access array with indexer\ncout \u003c\u003c d[0].as_number() \u003c\u003c endl;         // =\u003e 1\ncout \u003c\u003c d[1].as_string() \u003c\u003c endl;         // =\u003e foo\ncout \u003c\u003c d[2].as_boolean() \u003c\u003c endl;        // =\u003e 0\n// d[1] = 123;                            // Compile error (indexer is read-only)\n\n// Access object\nauto e = json5pp::object({{\"bar\", 123}, {\"foo\", true}});\nauto\u0026 e_value = e.as_object();    // decltype(e_value) =\u003e std::map\u003cstd::string, json5pp::value\u003e\u0026\ncout \u003c\u003c e_value.size() \u003c\u003c endl;                 // =\u003e 2\ncout \u003c\u003c e_value.at(\"bar\").as_number() \u003c\u003c endl;  // =\u003e 123\ncout \u003c\u003c e_value.at(\"foo\").as_boolean() \u003c\u003c endl; // =\u003e 1\n\n// Access object with indexer\ncout \u003c\u003c e[\"bar\"].as_number() \u003c\u003c endl;     // =\u003e 123\ncout \u003c\u003c e[\"foo\"].as_boolean() \u003c\u003c endl;    // =\u003e 1\n// e[\"baz\"] = 123;                        // Compile error (indexer is read-only)\n\n// Invalid cast\n// (If type does not match, as_xxx() method throws std::bad_cast())\njson5pp::value f(123);    // type is number\n// f.as_null();           // throws std::bad_cast()\njson5pp::value g();       // type is null\n// f.as_boolean();        // throws std::bad_cast()\n\n// Truthy/falsy test\n// falsy: null, false, 0, -0, NaN, \"\"\n// truthy: other values\njson5pp::value truthy1(true);\njson5pp::value truthy2(1);\njson5pp::value truthy3(\"foo\");\njson5pp::value truthy4{};\nauto truthy5 = json5pp::object({});\ncout \u003c\u003c (bool)truthy1 \u003c\u003c endl;  // =\u003e 1\ncout \u003c\u003c (bool)truthy2 \u003c\u003c endl;  // =\u003e 1\ncout \u003c\u003c (bool)truthy3 \u003c\u003c endl;  // =\u003e 1\ncout \u003c\u003c (bool)truthy4 \u003c\u003c endl;  // =\u003e 1\ncout \u003c\u003c (bool)truthy5 \u003c\u003c endl;  // =\u003e 1\n\njson5pp::value falsy1();        // null\njson5pp::value falsy2(false);\njson5pp::value falsy3(0);\njson5pp::value falsy4(numeric_limits\u003cdouble\u003e::quiet_NaN());     // NaN\njson5pp::value falsy5(numeric_limits\u003cdouble\u003e::signaling_NaN()); // NaN\njson5pp::value falsy6(\"\");\ncout \u003c\u003c (bool)falsy1 \u003c\u003c endl;  // =\u003e 0\ncout \u003c\u003c (bool)falsy2 \u003c\u003c endl;  // =\u003e 0\ncout \u003c\u003c (bool)falsy3 \u003c\u003c endl;  // =\u003e 0\ncout \u003c\u003c (bool)falsy4 \u003c\u003c endl;  // =\u003e 0\ncout \u003c\u003c (bool)falsy5 \u003c\u003c endl;  // =\u003e 0\ncout \u003c\u003c (bool)falsy6 \u003c\u003c endl;  // =\u003e 0\n```\n\n### Parse\n```cpp\nusing namespace std;\n\nauto x = json5pp::parse(\"{\\\"foo\\\":[123,\\\"baz\\\"]}\");\ncout \u003c\u003c x.is_object() \u003c\u003c endl;            // =\u003e 1\ncout \u003c\u003c x[\"foo\"].is_array() \u003c\u003c endl;      // =\u003e 1\ncout \u003c\u003c x[\"foo\"][0].as_number() \u003c\u003c endl;  // =\u003e 123\ncout \u003c\u003c x[\"foo\"][1].as_string() \u003c\u003c endl;  // =\u003e baz\n\nauto y = json5pp::parse5(\"{\\\"foo\\\"://this is comment\\n[123,\\\"baz\\\"/*trailing comma--\u003e*/,],}\");\ncout \u003c\u003c y.is_object() \u003c\u003c endl;            // =\u003e 1\ncout \u003c\u003c y[\"foo\"].is_array() \u003c\u003c endl;      // =\u003e 1\ncout \u003c\u003c y[\"foo\"][0].as_number() \u003c\u003c endl;  // =\u003e 123\ncout \u003c\u003c y[\"foo\"][1].as_string() \u003c\u003c endl;  // =\u003e baz\n```\n\n### Stringify\n```cpp\nusing namespace std;\n\n// Make some example object...\njson5pp::value x = json5pp::object({\n  {\"foo\", 123},\n  {\"bar\",\n    json5pp::array({\n      1, \"baz\", true,\n    })\n  },\n});\n\n// Stringify to output stream by \"\u003c\u003c\" operator\ncout \u003c\u003c x \u003c\u003c endl;\n\n// Stringify to std::string by stringify() method\nauto s = x.stringify(); // decltype(s) =\u003e std::string\ncout \u003c\u003c s \u003c\u003c endl;      // =\u003e {\"bar\":[1,\"baz\",true],\"foo\":123}\n\n// Stringify to output stream with indent specification\ncout \u003c\u003c json5pp::rule::space_indent\u003c\u003e() \u003c\u003c x \u003c\u003c endl; /* =\u003e\n{\n  \"bar\": [\n    1,\n    \"baz\",\n    true\n  ],\n  \"foo\": 123\n}\n*/\n\n// Stringify to std::string with indent specification\nauto s2 = x.stringify(json5pp::rule::tab_indent\u003c\u003e());\ncout \u003c\u003c s2 \u003c\u003c endl; /* =\u003e\n{\n\u003e       \"bar\": [\n\u003e       \u003e       1,\n\u003e       \u003e       \"baz\",\n\u003e       \u003e       true,\n\u003e       ],\n\u003e       \"foo\": 123\n}\n(`\u003e` means tab) */\n```\n\n## Limitation\n\n* Not fully compatible with unquoted keys in JSON5 (Some unicode will be rejected as keys)\n* All strings are assumed to be stored in UTF-8 encoding.\n\n## ToDo\n\n* More tests\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkimushu%2Fjson5pp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkimushu%2Fjson5pp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkimushu%2Fjson5pp/lists"}