/// /// \mainpage toml++ /// \image html banner_small.png width=1280px /// \tableofcontents /// ////////////////////////////////////////////////////////////////////// /// /// \section mainpage-features Features /// - Supports the latest [TOML](https://toml.io/) release ([v1.0.0](https://toml.io/en/v1.0.0)), plus /// optional support for some unreleased TOML features /// - Supports serializing to JSON /// - Proper UTF-8 handling (incl. BOM) /// - C++17 (plus some C++20 features where available, e.g. experimental support for char8_t strings) /// - Header-only (optional!) /// - Doesn't require RTTI /// - Works with or without exceptions /// - Tested on Clang (6+), GCC (7+) and MSVC (VS2019) /// - Tested on x64, x86 and ARM /// ////////////////////////////////////////////////////////////////////// /// /// \section mainpage-api-documentation API documentation /// You're looking at it! Browse the docs using the links at the top of the page. /// You can search from anywhere by pressing the TAB key. /// ////////////////////////////////////////////////////////////////////// /// /// \section mainpage-example Basic examples /// ////////////////////////////////// /// /// \subsection mainpage-example-parsing-files Parsing files /// Call toml::parse_file() and work with the toml::table you get back, or handle any toml::parse_error that gets thrown: /// /// \cpp /// #include /// #include //required for parse_file() /// #include /// /// int main(int argc, char** argv) /// { /// toml::table tbl; /// try /// { /// tbl = toml::parse_file(argv[1]); /// std::cout << tbl << "\n"; /// } /// catch (const toml::parse_error& err) /// { /// std::cerr << "Parsing failed:\n" << err << "\n"; /// return 1; /// } /// /// return 0; /// } /// /// \ecpp /// /// \m_class{m-note m-warning} /// /// \parblock ///

Don't forget [code]\#include <fstream>[/code]!

/// Not everyone who uses the library is going to work directly from files, so not everybody is forced to pay /// the compilation overhead of including ``. You need to explicitly include it if you're going to be calling /// toml::parse_file(). /// \endparblock /// /// \see /// - toml::parse_file() /// - toml::table /// - toml::parse_error /// ////////////////////////////////// /// /// \subsection mainpage-example-parsing-strings Parsing strings and iostreams /// /// Call toml::parse() and work with the toml::table you get back, or handle any toml::parse_error that gets thrown: /// /// \godbolt{NsR-xf} /// /// \cpp /// #include /// #include /// #include /// using namespace std::string_view_literals; /// /// int main() /// { /// static constexpr std::string_view some_toml = R"( /// [library] /// name = "toml++" /// authors = ["Mark Gillard "] /// cpp = 17 /// )"sv; /// /// try /// { /// // parse directly from a string view: /// { /// toml::table tbl = toml::parse(some_toml); /// std::cout << tbl << "\n"; /// } /// /// // parse from a string stream: /// { /// std::stringstream ss{ std::string{ some_toml } }; /// toml::table tbl = toml::parse(ss); /// std::cout << tbl << "\n"; /// } /// } /// catch (const toml::parse_error& err) /// { /// std::cerr << "Parsing failed:\n" << err << "\n"; /// return 1; /// } /// /// return 0; /// } /// \ecpp /// /// \out /// [library] /// authors = [ 'Mark Gillard ' ] /// cpp = 17 /// name = 'toml++' /// /// [library] /// authors = [ 'Mark Gillard ' ] /// cpp = 17 /// name = 'toml++' /// \eout /// /// \see /// - toml::parse_file() /// - toml::table /// - toml::parse_error /// ////////////////////////////////// /// /// \subsection mainpage-example-parsing-without-exceptions Handling errors without exceptions /// Can't (or won't) use exceptions? That's fine too. You can disable exceptions in your compiler flags and/or /// explicitly disable the library's use of them by setting the option \ref TOML_EXCEPTIONS to `0`. In either case, /// the parsing functions return a toml::parse_result instead of a toml::table: /// /// \cpp /// #include /// #include /// /// #define TOML_EXCEPTIONS 0 // only necessary if you've left them enabled in your compiler /// #include /// /// int main() /// { /// toml::parse_result result = toml::parse_file("configuration.toml"); /// if (!result) /// { /// std::cerr << "Parsing failed:\n" << result.error() << "\n"; /// return 1; /// } /// /// do_stuff_with_your_config(std::move(result).table()); // 'steal' the table from the result /// return 0; /// } /// \ecpp /// ////////////////////////////////// /// /// \subsection mainpage-example-custom-error-formatting Custom error formatting /// The examples above use an overloaded `operator<<` with ostreams to print basic error messages, and look like this: /// \out /// Error while parsing key: expected bare key starting character or string delimiter, saw '?' /// (error occurred at line 2, column 5) /// \eout /// /// In order to keep the library as small as possible I haven't bent over backwards to support things like custom /// colouring of the text in TTY environments, et cetera. That being said, the library provides the requisite information /// for you to build these yourself if necessary via toml::parse_error's source() and description() members: /// /// \cpp /// toml::table tbl; /// try /// { /// tbl = toml::parse_file("configuration.toml"); /// } /// catch (const toml::parse_error& err) /// { /// std::cerr /// << "Error parsing file '" << *err.source().path /// << "':\n" << err.description() /// << "\n (" << err.source().begin << ")\n"; /// return 1; /// } /// \ecpp /// /// \see /// - toml::parse_error /// - toml::source_region /// - toml::source_position /// ////////////////////////////////// /// /// \subsection mainpage-example-manipulations Working with TOML data /// A TOML document is a tree of values, arrays and tables, represented as the toml::value, toml::array /// and toml::table, respectively. All three inherit from toml::node, and can be easily accessed via /// the toml::node_view: /// /// \godbolt{7z6GGW} /// /// \cpp /// #include /// #include /// using namespace std::string_view_literals; /// /// int main() /// { /// static constexpr auto source = R"( /// str = "hello world" /// /// numbers = [ 1, 2, 3, "four", 5.0 ] /// vegetables = [ "tomato", "onion", "mushroom", "lettuce" ] /// minerals = [ "quartz", "iron", "copper", "diamond" ] /// /// [animals] /// cats = [ "tiger", "lion", "puma" ] /// birds = [ "macaw", "pigeon", "canary" ] /// fish = [ "salmon", "trout", "carp" ] /// /// )"sv; /// toml::table tbl = toml::parse(source); /// /// // different ways of directly querying data /// std::optional str1 = tbl["str"].value(); /// std::optional str2 = tbl["str"].value(); /// std::string_view str3 = tbl["str"].value_or(""sv); /// std::string& str4 = tbl["str"].ref(); // ~~dangerous~~ /// /// std::cout << *str1 << "\n"; /// std::cout << *str2 << "\n"; /// std::cout << str3 << "\n"; /// std::cout << str4 << "\n"; /// /// // get a toml::node_view of the element 'numbers' using operator[] /// auto numbers = tbl["numbers"]; /// std::cout << "table has 'numbers': " << !!numbers << "\n"; /// std::cout << "numbers is an: " << numbers.type() << "\n"; /// std::cout << "numbers: " << numbers << "\n"; /// /// // get the underlying array object to do some more advanced stuff /// if (toml::array* arr = numbers.as_array()) /// { /// for (toml::node& elem : *arr) /// { /// // visitation helps deal with the polymorphic nature of TOML data /// elem.visit([](auto&& el) noexcept /// { /// if constexpr (toml::is_number) /// (*el)++; /// else if constexpr (toml::is_string) /// el = "five"sv; /// }); /// } /// /// // arrays are very similar to std::vector /// arr->push_back(7); /// arr->emplace_back(8, 9); /// std::cout << "numbers: " << numbers << "\n"; /// } /// /// // node-views can be chained to quickly query deeper /// std::cout << "cats: " << tbl["animals"]["cats"] << "\n"; /// std::cout << "fish[1]: " << tbl["animals"]["fish"][1] << "\n"; /// /// // ...even if the element doesn't exist /// std::cout << "dinosaurs: " << tbl["animals"]["dinosaurs"] << "\n"; //no dinosaurs :( /// /// return 0; /// } /// \ecpp /// /// \out /// hello world /// hello world /// hello world /// hello world /// table has 'numbers': 1 /// numbers is an: array /// numbers: [ 1, 2, 3, 'four', 5.0 ] /// numbers: [ 2, 3, 4, 'five', 6.0, 7, [ 8, 9 ] ] /// cats: [ 'tiger', 'lion', 'puma' ] /// fish[1]: 'trout' /// dinosaurs: /// \eout /// /// \see /// - toml::node /// - toml::node_view /// - toml::value /// - toml::array /// - toml::table /// ////////////////////////////////// /// /// \subsection mainpage-example-serialization Serializing as TOML and JSON /// All toml++ data types have overloaded `operator<<` for ostreams, so 'serializing' a set of TOML data to actual /// TOML is done just by printing it to an ostream. Converting it to JSON is done in the same way, /// but via a toml::json_formatter. /// /// \godbolt{MMNoW4} /// /// \cpp /// #include /// #include /// /// int main() /// { /// auto tbl = toml::table{{ /// { "lib", "toml++" }, /// { "cpp", toml::array{ 17, 20, "and beyond" } }, /// { "toml", toml::array{ "1.0.0", "and beyond" } }, /// { "repo", "https://github.com/marzer/tomlplusplus/" }, /// { "author", toml::table{{ /// { "name", "Mark Gillard" }, /// { "github", "https://github.com/marzer" }, /// { "twitter", "https://twitter.com/marzer8789" } /// }} /// }, /// }}; /// /// // serializing as TOML /// std::cout << "###### TOML ######" << "\n\n"; /// std::cout << tbl << "\n\n"; /// /// // serializing as JSON using toml::json_formatter: /// std::cout << "###### JSON ######" << "\n\n"; /// std::cout << toml::json_formatter{ tbl } << "\n\n"; /// return 0; /// } /// \ecpp /// /// \out /// ###### TOML ###### /// /// cpp = [ 17, 20, 'and beyond' ] /// lib = 'toml++' /// repo = 'https://github.com/marzer/tomlplusplus/' /// toml = [ '1.0.0', 'and beyond' ] /// /// [author] /// github = 'https://github.com/marzer' /// name = 'Mark Gillard' /// twitter = 'https://twitter.com/marzer8789' /// /// ###### JSON ###### /// /// { /// "author" : { /// "github" : "https://github.com/marzer", /// "name" : "Mark Gillard", /// "twitter" : "https://twitter.com/marzer8789" /// }, /// "cpp" : [ /// 17, /// 20, /// "and beyond" /// ], /// "lib" : "toml++", /// "repo" : "https://github.com/marzer/tomlplusplus/", /// "toml" : [ /// "1.0.0", /// "and beyond" /// ] /// } /// \eout /// \see /// - toml::default_formatter /// - toml::json_formatter /// ////////////////////////////////// /// /// \subsection mainpage-example-speed-up-compilation Speeding up compilation /// Because toml++ is a header-only library of nontrivial size you might find that compilation times noticeably /// increase after you add it to your project, especially if you add the library's header somewhere that's visible from /// a large number of translation units. You can counter this by disabling 'all inline' mode and explicitly controlling /// where the library's implementation is compiled. /// /// Step 1: Set \ref TOML_HEADER_ONLY to [code]0[/code] before including toml++ /// /// This must be the same everywhere, so either set it as a global `#define` in your build system, or /// do it manually before including toml++ in some global header that's used everywhere in your project: /// \cpp /// // global_header_that_includes_toml++.h /// /// #define TOML_HEADER_ONLY 0 /// #include /// \ecpp /// /// Step 2: Define \ref TOML_IMPLEMENTATION before including toml++ in one specific translation unit /// /// \cpp /// // some_code_file.cpp /// /// #define TOML_IMPLEMENTATION /// #include "global_header_that_includes_toml++.h" /// \ecpp /// /// Bonus Step: Disable the parser if you don't need it /// /// If all you need to do is serialize some code-generated TOML and don't actually need the parser at all you can /// set \ref TOML_PARSER to `0` to disable the parser altogether. This can yield fairly significant compilation /// speedups since the parser accounts for a good chunk of the library's code. /// /// /// \see \ref configuration /// ////////////////////////////////////////////////////////////////////// /// /// \section mainpage-adding-lib Adding toml++ to your project /// /// \m_class{m-note m-default} /// /// The library comes in two flavours, [emoji icecream] Single-header /// and [emoji sundae] Regular. The API is the same for both. /// ////////////////////////////////// /// /// \subsection mainpage-adding-lib-old-school "The old fashioned way" /// Clone \github{marzer/tomlplusplus, the repository} from GitHub, and then: /// ///

[emoji icecream] Single-header flavour

/// 1. Drop `toml.hpp` wherever you like in your source tree /// 2. There is no step two /// ///

[emoji sundae] Regular flavour

/// 1. Add `tomlplusplus/include` to your include paths /// 2. `#include ` /// ////////////////////////////////// /// /// \subsection mainpage-adding-lib-conan Conan /// Add `tomlplusplus/2.3.0` to your conanfile. This adds the single-header version by default, but you can specify the /// regular version using `"multiple_headers": True`. /// ////////////////////////////////// /// /// \subsection mainpage-adding-lib-dds DDS /// Add `tomlpp` to your `package.json5`, e.g.: /// \bash /// depends: [ /// 'tomlpp^2.3.0', /// ] /// \ebash /// /// \see [What is DDS?](https://dds.pizza/) /// ////////////////////////////////// /// /// \subsection mainpage-adding-lib-meson Meson /// The library supports being added as a subproject in the meson build system. /// ////////////////////////////////// /// /// \subsection mainpage-adding-lib-vcpkg Vcpkg /// \bash /// vcpkg install tomlplusplus /// \ebash /// ////////////////////////////////// /// /// \subsection mainpage-adding-lib-other Other environments and package managers /// toml++ is a fairly new project and I'm not up-to-speed with all of the available packaging and integration options /// in the modern C++ ecosystem. I'm also a cmake novice, for better or worse. If there's an integration option missing /// be assured that I fully support it being added, and welcome pull requests! /// ////////////////////////////////// /// /// \subsection mainpage-adding-lib-python Special mention: Python /// Yes, you read correctly, python. There exists a python wrapper built around toml++ called /// \github{bobfang1992/pytomlpp, pytomlpp}: /// /// \bash /// pip install pytomlpp /// \ebash /// /// Note that I'm not the developer or maintainer of that project so if you wish to report a bug relating to the python /// implementation, please do so at their repository, not on the main toml++ one. /// ////////////////////////////////////////////////////////////////////// /// /// \section mainpage-configuration Library configuration options /// The library exposes a number of configuration options in the form of compiler `#defines`. Things like /// changing the `optional` type, disabling header-only mode, et cetera. The full list of /// configurables can be found on the \ref configuration page. /// /// \see \ref configuration /// ////////////////////////////////////////////////////////////////////// /// /// \section mainpage-contributing Contributing /// Contributions are very welcome! Either by \github{marzer/tomlplusplus/issues, reporting issues} /// or submitting pull requests. If you wish to submit a pull request, /// please see \github{marzer/tomlplusplus/blob/master/CONTRIBUTING.md, CONTRIBUTING} /// for all the details you need to get going. /// ////////////////////////////////////////////////////////////////////// /// /// \section mainpage-license License /// /// toml++ is licensed under the terms of the MIT license - see /// [LICENSE](https://github.com/marzer/tomlplusplus/blob/master/LICENSE). /// /// \m_class{m-note m-default} /// /// If you're using the single-header version of the library you don't need to explicitly distribute the license file; /// it is embedded in the preamble at the top of the header. /// ////////////////////////////////////////////////////////////////////// /// /// \section mainpage-contact Contacting the author /// For bug reports and feature requests please use the \github{marzer/tomlplusplus/issues, Github Issues} /// system. For anything else you're welcome to reach out via other means. In order of likely response speed: /// - Twitter: [marzer8789](https://twitter.com/marzer8789) /// - Email: [mark.gillard@outlook.com.au](mailto:mark.gillard@outlook.com.au) /// - Facebook: [marzer](https://www.facebook.com/marzer) /// - LinkedIn: [marzer](https://www.linkedin.com/in/marzer/) ///