{"id":18644744,"url":"https://github.com/hjson/hjson-cpp","last_synced_at":"2025-05-06T23:43:01.348Z","repository":{"id":52290665,"uuid":"100888094","full_name":"hjson/hjson-cpp","owner":"hjson","description":"Hjson for C++","archived":false,"fork":false,"pushed_at":"2025-04-20T15:29:56.000Z","size":164,"stargazers_count":70,"open_issues_count":2,"forks_count":20,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-05-01T17:54:38.520Z","etag":null,"topics":["cpp","hjson"],"latest_commit_sha":null,"homepage":"https://hjson.github.io/","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/hjson.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,"zenodo":null}},"created_at":"2017-08-20T20:50:59.000Z","updated_at":"2025-04-20T15:10:50.000Z","dependencies_parsed_at":"2023-02-09T13:00:40.860Z","dependency_job_id":"d7c4b191-c615-434a-8d73-c4b77c1be8b4","html_url":"https://github.com/hjson/hjson-cpp","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hjson%2Fhjson-cpp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hjson%2Fhjson-cpp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hjson%2Fhjson-cpp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hjson%2Fhjson-cpp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hjson","download_url":"https://codeload.github.com/hjson/hjson-cpp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252788389,"owners_count":21804280,"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":["cpp","hjson"],"created_at":"2024-11-07T06:13:27.075Z","updated_at":"2025-05-06T23:43:01.332Z","avatar_url":"https://github.com/hjson.png","language":"C++","readme":"# hjson-cpp\n\n[![Build Status](https://github.com/hjson/hjson-cpp/workflows/test/badge.svg)](https://github.com/hjson/hjson-cpp/actions)\n[![C++](https://img.shields.io/github/release/hjson/hjson-cpp.svg?style=flat-square\u0026label=c%2b%2b)](https://github.com/hjson/hjson-cpp/releases)\n![license](https://img.shields.io/github/license/mashape/apistatus.svg)\n\n![Hjson Intro](https://hjson.github.io/hjson1.gif)\n\n```\n{\n  # specify rate in requests/second (because comments are helpful!)\n  rate: 1000\n\n  // prefer c-style comments?\n  /* feeling old fashioned? */\n\n  # did you notice that rate doesn't need quotes?\n  hey: look ma, no quotes for strings either!\n\n  # best of all\n  notice: []\n  anything: ?\n\n  # yes, commas are optional!\n}\n```\n\nTo quickly get up and running with a new C++ application project using Hjson configuration files, use the [hjson-cpp-example](https://github.com/hjson/hjson-cpp-example) template repository.\n\nFor other platforms see [hjson.github.io](https://hjson.github.io).\n\n# Compiling\n\nThe easiest way to use hjson-cpp is to simply include all of the files from the folders `src` and `include` into your own project. The only requirement is that your compiler fully supports C++11.\n\nGCC 4.8 has the C++11 headers for regex, but unfortunately not a working implementation, so for GCC at least version 4.9 is required.\n\n## Cmake\n\nThe second easiest way to use hjson-cpp is to either add it as a subfolder to your own Cmake project, or to install the Hjson lib on your system by using Cmake. Works on Linux, Windows and MacOS. Your mileage may vary on other platforms. Cmake version 3.10 or newer is required.\n\n### Cmake subfolder\n\nInstead of building a lib, you can choose to include Hjson as a subfolder in your own Cmake project. That way, Hjson will be built together with your own project, with the same settings. In Visual Studio that also means the Hjson source code will be visible in a project in your own solution. Example `CMakeLists.txt` for your own project, if your executable is called `myapp`:\n```cmake\nadd_executable(myapp main.cpp)\n\nadd_subdirectory(../hjson-cpp ${CMAKE_BINARY_DIR}/hjson)\ntarget_link_libraries(myapp hjson)\n```\n\n### Cmake options\n\nA list of Hjson Cmake options and their default values:\n\n```bash\nBUILD_SHARED_LIBS=OFF\nBUILD_WITH_STATIC_CRT=  # Can be set to Yes or No. Only used on Windows.\nCMAKE_BUILD_TYPE=  # Set to Debug for debug symbols, or Release for optimization.\nCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=ON  # Needed for shared libs on Windows. Introduced in Cmake 3.4.\nHJSON_ENABLE_INSTALL=OFF\nHJSON_ENABLE_TEST=OFF\nHJSON_ENABLE_PERFTEST=OFF\nHJSON_NUMBER_PARSER=StringStream  # Possible values are StringStream, StrToD and CharConv.\nHJSON_VERSIONED_INSTALL=OFF  # Use version suffix on header and lib folders.\n```\n\n### Linux lib\n\n1. First create a Makefile using Cmake.\n```bash\n$ cd hjson-cpp\n$ mkdir build\n$ cd build\n$ cmake .. -DHJSON_ENABLE_TEST=ON -DHJSON_ENABLE_INSTALL=ON -DCMAKE_BUILD_TYPE=Release\n```\n2. Then you can optionally run the tests.\n```bash\n$ make runtest\n```\n3. Install the include files and lib to make them accessible system wide (optional).\n```bash\n$ sudo make install\n```\n4. If you haven't done either step 2 or step 3, you must at least compile the code into a library by calling make.\n```bash\n$ make\n```\n\n### Windows lib\n\nThe Cmake GUI is the most convenient way to generate a Visual Studio solution. Make sure that you tick the boxes for `HJSON_ENABLE_TEST` and `HJSON_ENABLE_INSTALL` if you want to run tests or make the Hjson lib accessible system wide.\n\nAfter generating the solution and opening it in Visual Studio you can run the tests by right-clicking the project `runtest` and selecting `Build`. The test results are shown in the `Output` window (the same window that shows the build result).\n\nIn order to make the Hjson lib accessible system wide you must run Visual Studio as an administrator. In Windows 7 you can do that by right-clicking on the Visual Studio icon in the start menu and selecting `Run as an administrator`. Then open the Hjson solution, right-click the `INSTALL` project and select `Build`. Make sure to do that for both the `Debug` and `Release` targets.\n\n## Linking\n\nThe hjson lib can now be used in your own Cmake projects, for example like this if your application is called `myapp`:\n```cmake\nadd_executable(myapp main.cpp)\n\nfind_package(hjson REQUIRED)\ntarget_link_libraries(myapp hjson)\n```\n\nOn Windows it's important that you compiled or installed both `Debug` and `Release` Hjson libraries before Cmake-generating your own project. Otherwise the target type you didn't compile/install will not be available in your own project.\n\nIf you did not install Hjson system wide, you can still use it like in the example above if you specify the location of the Hjson build when running Cmake for your own project. Example:\n```bash\n$ cmake .. -Dhjson_DIR=../hjson-cpp/build\n```\n\n# Usage in C++\n\n### Functions\n\nThe most important functions in the Hjson namespace are:\n\n```cpp\nstd::string Marshal(const Value\u0026 v, const EncoderOptions\u0026 options = EncoderOptions());\n\nvoid MarshalToFile(const Value\u0026 v, const std::string\u0026 path,\n  const EncoderOptions\u0026 options = EncoderOptions());\n\nValue Unmarshal(const std::string\u0026 data,\n  const DecoderOptions\u0026 options = DecoderOptions());\n\nValue UnmarshalFromFile(const std::string\u0026 path,\n  const DecoderOptions\u0026 options = DecoderOptions());\n\nValue Merge(const Value\u0026 base, const Value\u0026 ext);\n```\n\n*Marshal* is the output-function, transforming an *Hjson::Value* tree (represented by its root node) to a string that can be written to a file.\n\n*MarshalToFile* writes the output directly to a file instead of returning a string.\n\n*Unmarshal* is the input-function, transforming a string to a *Hjson::Value* tree. The string is expected to be UTF8 encoded. Other encodings might work too, but have not been tested. The function comes in three flavors: char pointer with or without the `dataSize` parameter, or std::string. For a char pointer without `dataSize` parameter the `data` parameter must be null-terminated (like all normal strings). All of the unmarshal functions throw an *Hjson::syntax_error* exception if the input string is not fully valid Hjson syntax.\n\n*UnmarshalFromFile* reads directly from a file instead of taking a string as input.\n\n*Merge* returns an *Hjson::Value* tree that is a cloned combination of the input *Hjson::Value* trees `base` and `ext`, with values from `ext` used whenever both `base` and `ext` has a value for some specific position in the tree. The function is convenient when implementing an application with a default configuration (`base`) that can be overridden by input parameters (`ext`).\n\n### Stream operator\n\nAn *Hjson::Value* can be inserted into a stream, for example like this:\n\n```cpp\nHjson::Value myValue = 3.0;\nstd::cout \u003c\u003c myValue;\n```\n\nThe stream operator marshals the *Hjson::Value* using standard options, so this code will produce the exact same result, but uses more RAM since the full output is temporarily stored in a string instead of being written directly to the stream:\n\n```cpp\nHjson::Value myValue = 3.0;\nstd::cout \u003c\u003c Hjson::Marshal(myValue);\n```\n\nIf you want to use custom encoding options they can be communicated like this:\n\n```cpp\nHjson::Value myValue = 3.0;\nHjson::EncoderOptions encOpt;\nencOpt.omitRootBraces = true;\nstd::cout \u003c\u003c Hjson::StreamEncoder(myValue, encOpt);\n```\n\nLikewise for reading from a stream. Hjson will consume the entire stream from its current position, and throws an *Hjson::syntax_error* exception if not all of the stream (from its current position) is valid Hjson syntax.\n\n```cpp\nHjson::Value myValue;\nstd::cin \u003e\u003e myValue;\n```\n\n```cpp\nHjson::Value myValue;\nHjson::DecoderOptions decOpt;\ndecOpt.comments = false;\nstd::cin \u003e\u003e Hjson::StreamDecoder(myValue, decOpt);\n```\n\n### Hjson::Value\n\nInput strings are unmarshalled into a tree representation where each node in the tree is an object of the type *Hjson::Value*. The class *Hjson::Value* mimics the behavior of Javascript in that you can assign any type of primitive value to it without casting. Existing *Hjson::Value* objects can change type when given a new assignment. Examples:\n\n```cpp\nHjson::Value myValue(true);\nHjson::Value myValue2 = 3.0;\nmyValue2 = \"A text.\";\n```\n\nThese are the possible types for an *Hjson::Value*:\n\n    Undefined\n    Null\n    Bool\n    Double\n    Int64\n    String\n    Vector\n    Map\n\nThe default constructor creates an *Hjson::Value* of the type *Hjson::Type::Undefined*.\n\nAn *Hjson::Value* can behave both like a vector (array) and like a map (*Object* in Javascript):\n\n```cpp\nHjson::Value map;\nmap[\"down1\"][\"down2\"][\"down3\"] = \"three levels deep!\";\nmap[\"down1\"][\"number\"] = 7;\n\nHjson::Value arr;\narr.push_back(\"first\");\nstd::string myString = arr[0];\n```\n\nIf you try to access a map element that doesn't exist, an *Hjson::Value* of type *Hjson::Type::Undefined* is returned. But if you try to access a vector element that doesn't exist, an *Hjson::index_out_of_bounds* exception is thrown.\n\nIn order to make it possible to check for the existence of a specific key in a map without creating an empty element in the map with that key, a temporary object of type *Hjson::MapProxy* is returned from the string bracket operators:\n\n```cpp\nMapProxy operator[](const std::string\u0026);\nMapProxy operator[](const char*);\n```\n\nThe *Hjson::MapProxy* desctructor creates or updates an element in the map if needed. Therefore the *Hjson::MapProxy* copy and move constructors are private, so that objects of that class do not stay alive longer than a single line of code. The downside of that is that you cannot store the returned value in an auto declared variable.\n\n```cpp\nHjson::Value map;\n\n// This statement won't compile.\nauto badValue = map[\"key\"];\n\n// This statement will compile just fine.\nHjson::Value goodValue = map[\"key\"];\n```\n\nBecause of *Hjson::MapProxy*, you cannot get a reference to a map element from the string bracket operator. You can however get such a reference from the integer bracket operator, or from the function *Hjson::Value::at(const std::string\u0026 key)*. Both the integer bracket operator and the *at* function throw an *Hjson::index_out_of_bounds* exception if the element could not be found.\n\n```cpp\nHjson::Value map;\nmap[\"myKey\"] = \"myValue\";\n\nauto use_reference = [](Hjson::Value\u0026 input) {\n};\n\n// This statement won't compile in gcc or clang. Visual Studio will compile\n// and use a reference to the MapProxy temporary object.\nuse_reference(map[\"myKey\"]);\n\n// This statement will compile just fine.\nuse_reference(map.at(\"myKey\"));\n```\n\n### Number representations\n\nThe C++ implementation of Hjson can both read and write 64-bit integers. No special care is needed, you can simply assign the value.\n\nExample:\n\n```cpp\nHjson::Value myValue = 9223372036854775807;\nassert(myValue == 9223372036854775807);\n```\n\nAll integers are stored with 64-bit precision. An *Hjson::Value* containing an integer will be of the type *Hjson::Type::Int64*. The only other way that a number is stored in an *Hjson::Value* is in the form of a double precision floating point representation, which can handle up to 52 bits of integer precision. An *Hjson::Value* containing a floating point value will be of the type *Hjson::Type::Double*.\n\nAn *Hjson::Value* that has been unmarshalled from a string that contains a decimal point (for example the string `\"1.0\"`), or a string containing a number that is bigger or smaller than what can be represented by an *std::int64_t* variable (bigger than 9223372036854775807 or smaller than -9223372036854775808) will be stored as a double precision floating point number internally in the *Hjson::Value*.\n\nAny *Hjson::Value* of type *Hjson::Type::Double* will be represented by a string containing a decimal point when marshalled (for example `\"1.0\"`), so that the string can be unmarshalled back into an *Hjson::Type::Double*, i.e. no information is lost in the marshall-unmarshall cycle.\n\nThe function *Hjson::Value::is_numeric()* returns true if the *Hjson::Value* is of type *Hjson::Type::Double* or *Hjson::Type::Int64*.\n\n### Avoiding type mismatch errors\n\nWhen *static_cast\u003c\u003e()* is used on an *Hjson::Value*, an *Hjson::type_mismatch* error is thrown if the *Hjson::Value* is not of a compatible type. For example, if you do `static_cast\u003cconst char*\u003e(myVal)` then `myVal` must be of the type *Hjson::Type::String*, otherwise an *Hjson::type_mismatch* error is thrown.\n\nSo if you use static or implicit casting, errors can be thrown depending on the content of the input *Hjson* file. Maybe the *Hjson* file contains a collection of first and last names in quoteless lowercase strings and [Christopher Null](https://en.wikipedia.org/wiki/Christopher_Null) is one of the persons in the collection... The unquoted string `null` is stored in an *Hjson::Value* of type *Hjson::Type::Null* instead of *Hjson::Type::String* as the other names.\n\nTo avoid errors being thrown when casting, instead use these *Hjson::Value* member functions that will return the best possible representation of the value regardless of *Hjson::Type*:\n\n```cpp\ndouble Value::to_double() const;\nstd::int64_t Value::to_int64() const;\nstd::string Value::to_string() const;\n```\n\nFor example, if `myVal` is of type *Hjson::Type::Null* then `myVal.to_string()` returns the string `\"null\"`.\n\n### Operators\n\nThis table shows all operators defined for *Hjson::Value*, and the *Hjson::Type* they require. If an operator is used on an *Hjson::Value* of a type for which that operator is not valid, the exception *Hjson::type_mismatch* is thrown.\n\n| | Undefined | Null | Bool | Double | Int64 | String | Vector | Map |\n| :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: |\n| = | X | X | X | X | X | X | X | X |\n| == | X | X | X | X | X | X | X | X |\n| != | X | X | X | X | X | X | X | X |\n| + | | | | X | X | X | | |\n| - | | | | X | X | | | |\n| ++ | | | | X | X | | | |\n| -- | | | | X | X | | | |\n| += | | | | X | X | X | | |\n| -= | | | | X | X | | | |\n| \u003c | | | | X | X | X | | |\n| \u003e | | | | X | X | X | | |\n| \u003c= | | | | X | X | X | | |\n| \u003e= | | | | X | X | X | | |\n| \\* | | | | X | X | | | |\n| \\/ | | | | X | X | | | |\n| \\*= | | | | X | X | | | |\n| \\/= | | | | X | X | | | |\n| % | | | | | X | | | |\n| %= | | | | | X | | | |\n| \\[int\\] | X | | | | | | X | X |\n| \\[string\\] | X | | | | | | | X |\n\nThe equality operator (*==*) returns true if the two *Hjson::Value* objects are both of type *Hjson::Type::Undefined* or *Hjson::Type::Null*.\n\nWhen comparing *Hjson::Value* objects of type *Hjson::Type::Vector* or *Hjson::Type::Map*, the equality operator (*==*) returns true if both objects reference the same underlying vector or map (i.e. the same behavior as when comparing pointers).\n\n### Order of map elements\n\nIterators for an *Hjson::Value* of type *Hjson::Type::Map* are always ordered by the keys in alphabetic order. But when editing a configuration file you might instead want the output to have the same order of elements as the file you read for input. That is the default ordering in the output from *Hjson::Marshal()*, thanks to *true* being the default value of the option *preserveInsertionOrder* in *Hjson::EncoderOptions*.\n\nThe elements in an *Hjson::Value* of type *Hjson::Type::Map* can be accessed directly using the bracket operator with either the string key or the insertion index as input parameter.\n\n```cpp\nHjson::Value val1;\nval1[\"zeta\"] = 1;\nassert(val1[0] == 1);\nval1[0] = 99;\nassert(val1[\"zeta\"] == 99);\n```\n\nThe key for a given insertion index can be viewed using the function *Hjson::Value::key(int index)*.\n\n```cpp\nHjson::Value val1;\nval1[\"zeta\"] = 1;\nassert(val1.key(0) == \"zeta\");\n```\n\nThe insertion order can be changed using the function *Hjson::Value::move(int from, int to)*. If the input parameter `from` is lower than the input parameter `to`, the value will end up at index `to - 1`.\n\n```cpp\nHjson::Value val1;\nval1[\"zeta\"] = 1;\nval1[\"y\"] = 2;\nval1.move(0, 2);\nassert(val1.key(1) == \"zeta\");\nassert(val1[0] == 2);\n```\n\nThe insertion order is kept when cloning or merging *Hjson::Value* maps.\n\n### Comments\n\nThe Hjson unmarshal functions will by default store any comments in the resulting *Hjson::Value* tree, so that you can easily create an app that updates existing Hjson documents without losing the comments. In this example, any comments in the Hjson file are kept:\n\n```cpp\nHjson::Value root = Hjson::UnmarshalFromFile(szPath);\nroot[\"myKey\"] = \"aNewValue\";\nHjson::MarshalToFile(root, szPath);\n```\n\nThe *Hjson::Value* assignment operator does not assign new comments unless the receiving *Hjson::Value* is of type *Hjson::Type::Undefined*. The reason for that is that comments should not be lost when assigning a new value, as in the example here above. If you actually do want to replace both the value and the existing comments, use the function *Hjson::Value::assign_with_comments()*:\n\n```cpp\n// Changes the value but does not change any comments in root[\"myKey\"], unless\n// root[\"myKey\"] was undefined before this assignment.\nroot[\"myKey\"] = otherValue;\n\n// Changes the value and also copies all comments from otherValue into root[\"myKey\"].\nroot[\"myKey\"].assign_with_comments(otherValue);\n```\n\nThere are four types of comments: *before*, *key*, *inside* and *after*. If a comment is found, all chars (including line feeds and white spaces) between the values and/or separators are included in the string that becomes stored as a comment in an *Hjson::Value*.\n\n```cpp\n# This is a *before* comment to the object that starts on the next line.\n{\n  # This is a *before* comment to value1.\n  // This is still the same *before* comment to value1.\n  key1: /* This is a *key* comment to value1. */ \"value1\" // This is an *after* comment to value1.\n  /* This is a *before* comment to value2. */\n  key2:\n  // This is a *key* comment to value2.\n  value2 /* This is an *after* comment to value2. */\n  key3: {\n    // This is an *inside* comment.\n  }\n  key4: value4\n  // This is an *after* comment to value4. Would have been a *before* comment\n  // to value5 if this map contained a fifth value.\n}\n// This is an *after* comment to the root object.\n```\n\nAn *inside* comment is shown right after `{` or `[` in a map or vector. The unmarshal functions will only assign a comment as an *inside* comment if the map or vector is empty. Otherwise such a comment will be assigned to the *before* comment of the first element in the map or vector.\n\nA *key* comment is shown between the key and the value if the value is an element in a map. If the value is not an element in a map, the *key* comment is shown between the *before* comment and the value.\n\nAfter unmarshalling (with comments) the example here above, some of the comment strings would look like this:\n\n```cpp\nroot[\"key1\"].get_comment_before() == \"\\n  # This is a *before* comment to value1.\\n  // This is still the same *before* comment to value1.\\n  \";\n\nroot.get_comment_after() == \"\\n// This is an *after* comment to the root object.\";\n```\n\nThe *Hjson::Value::set_comment_X* functions do not analyze the strings they get as input, so you will change the meaning of the Hjson output if you are not careful when using them. For example, a comment starting with *//* or *#* must end with a line feed or else the marshal functions will place the value on the same line as the comment, thus making the value a part of the comment.\n\nIf you want to keep blank lines and other formatting in an Hjson document even if there are no comments, set the option *whitespaceAsComments* to *true* in *DecoderOptions*. Then the output from the marshal functions will look exactly like the input to the unmarshal functions, except possibly changes in root braces, quotation and comma separators. When *whitespaceAsComments* is *true*, the option *comments* is ignored (treated as *true*).\n\n### Performance\n\nHjson is not much optimized for speed. But if you require fast(-ish) execution, escpecially in a multithreaded application, you can experiment with different values for the Cmake option `HJSON_NUMBER_PARSER`. The default value `StringStream` uses C++ string streams with the locale `classic` imbued to ensure that dots are used as decimal separators rather than commas.\n\nThe value `StrToD` gives better performance, especially in multi threaded applications, but will use whatever locale the application is using. If the current locale uses commas as decimal separator *Hjson* will umarshal floating point numbers into strings, and will use commas in floating point numbers in the marshal output, which means that other parsers will treat that value as a string.\n\nSetting `HJSON_NUMBER_PARSER` to `CharConv` gives the best performance, and uses dots as comma separator regardless of the application locale. Using `CharConv` will automatically cause the code to be compiled using the C++17 standard (or a newer standard if required by your project). Unfortunately neither GCC 10.1 or Clang 10.0 implement the required feature of C++17 (*std::from_chars()* for *double*), but GCC 11 will have it. It does work in Visual Studio 17 and later.\n\nAnother way to increase performance and reduce memory usage is to disable reading and writing of comments. Set the option *comments* to *false* in *DecoderOptions* and *EncoderOptions*. In this example, any comments in the Hjson file are ignored:\n\n```cpp\nHjson::DecoderOptions decOpt;\ndecOpt.comments = false;\nHjson::Value root = Hjson::UnmarshalFromFile(szPath, decOpt);\nHjson::EncoderOptions encOpt;\nencOpt.comments = false;\nHjson::MarshalToFile(root, szPath, encOpt);\n```\n\n### Example code\n\n```cpp\n#include \u003chjson.h\u003e\n\n\nint main() {\n\n  // Now let's look at decoding Hjson data into Hjson::Value.\n  std::string sampleText = R\"(\n{\n  # specify rate in requests/second\n  rate: 1000\n  array:\n  [\n    foo\n    bar\n  ]\n}\n)\";\n\n  // Decode. Throws Hjson::syntax_error if the string is not fully valid Hjson.\n  Hjson::Value dat = Hjson::Unmarshal(sampleText.c_str(), sampleText.size());\n\n  // Values can be assigned directly without casting.\n  int rate = dat[\"rate\"];\n  printf(\"%d\\n\", rate);\n\n  // Sometimes it's difficult for the compiler to know\n  // what primitive type to convert the Hjson::Value to.\n  // Then an explicit cast can be used.\n  printf(\"%s\\n\", static_cast\u003cconst char*\u003e(dat[\"array\"][0]));\n\n  // To encode to Hjson with default options:\n  Hjson::Value sampleMap;\n  sampleMap[\"apple\"] = 5;\n  sampleMap[\"lettuce\"] = 7;\n  std::string hjson = Hjson::Marshal(sampleMap);\n  printf(\"%s\\n\", hjson.c_str());\n}\n```\n\nIterating through the elements of an *Hjson::Value* of type *Hjson::Type::Vector*:\n\n```cpp\nfor (int index = 0; index \u003c int(arr.size()); ++index) {\n  std::cout \u003c\u003c arr[index] \u003c\u003c std::endl;\n}\n```\n\nIterating through the elements of an *Hjson::Value* of type *Hjson::Type::Map* in alphabetical order:\n\n```cpp\nfor (auto it = map.begin(); it != map.end(); ++it) {\n  std::cout \u003c\u003c \"key: \" \u003c\u003c it-\u003efirst \u003c\u003c \"  value: \" \u003c\u003c it-\u003esecond \u003c\u003c std::endl;\n}\n```\n\nHaving a default configuration:\n\n```cpp\n#include \u003chjson.h\u003e\n#include \u003ccstdio\u003e\n\n\nstatic const char *_szDefaultConfig = R\"(\n{\n  imageSource: NO DEFAULT\n  showImages: true\n  writeImages: true\n  printFrameIndex: false\n  printFrameRate: true\n}\n)\";\n\n\nHjson::Value GetConfig(const char *szConfigPath) {\n  Hjson::Value defaultConfig = Hjson::Unmarshal(_szDefaultConfig);\n\n  Hjson::Value inputConfig;\n  try {\n    inputConfig = Hjson::UnmarshalFromFile(szConfigPath);\n  } catch(const std::exception\u0026 e) {\n    std::fprintf(stderr, \"Error in config: %s\\n\\n\", e.what());\n    std::fprintf(stdout, \"Default config:\\n\");\n    std::fprintf(stdout, _szDefaultConfig);\n\n    return Hjson::Value();\n  }\n\n  return Hjson::Merge(defaultConfig, inputConfig);\n}\n```\n\nFor a full multi-platform example application using Hjson configuration files, see the [hjson-cpp-example](https://github.com/hjson/hjson-cpp-example) template repository.\n\n# History\n\n[see releases](https://github.com/hjson/hjson-cpp/releases)\n\n","funding_links":[],"categories":["Libraries"],"sub_categories":["Parsing \u0026 Serialization"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhjson%2Fhjson-cpp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhjson%2Fhjson-cpp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhjson%2Fhjson-cpp/lists"}