# toml++ (tomlplusplus) — Overview ## What Is toml++? toml++ is a header-only TOML v1.0 parser, serializer, and data model library for C++17 and later. It is authored by Mark Gillard and published under the MIT license. The library version as of this documentation is **3.4.0**, implementing TOML language specification version **1.0.0**. The library lives in the `toml` namespace and provides a complete object model for TOML documents: tables, arrays, and typed values. It can parse TOML from strings, streams, and files; manipulate the resulting tree programmatically; and serialize back to TOML, JSON, or YAML. Repository: [https://github.com/marzer/tomlplusplus](https://github.com/marzer/tomlplusplus) --- ## What Is TOML? TOML stands for **Tom's Obvious Minimal Language**. It is a configuration file format designed to be easy to read, unambiguous, and map cleanly to a hash table (dictionary). A TOML document is fundamentally a collection of key-value pairs organized into tables. ### TOML Data Types TOML defines the following native data types: | TOML Type | C++ Representation in toml++ | `node_type` Enum | |-----------------|------------------------------|-------------------------------| | String | `std::string` | `node_type::string` | | Integer | `int64_t` | `node_type::integer` | | Float | `double` | `node_type::floating_point` | | Boolean | `bool` | `node_type::boolean` | | Local Date | `toml::date` | `node_type::date` | | Local Time | `toml::time` | `node_type::time` | | Offset Date-Time| `toml::date_time` | `node_type::date_time` | | Array | `toml::array` | `node_type::array` | | Table | `toml::table` | `node_type::table` | ### Example TOML Document ```toml # This is a TOML document title = "TOML Example" [owner] name = "Tom Preston-Werner" dob = 1979-05-27T07:32:00-08:00 [database] enabled = true ports = [ 8000, 8001, 8002 ] data = [ ["delta", "phi"], [3.14] ] temp_targets = { cpu = 79.5, case = 72.0 } [servers] [servers.alpha] ip = "10.0.0.1" role = "frontend" [servers.beta] ip = "10.0.0.2" role = "backend" ``` --- ## C++17 Features Used toml++ requires C++17 as its minimum standard. The version detection logic in `preprocessor.hpp` checks `__cplusplus` and `_MSVC_LANG`, rejecting anything below C++17: ```cpp #if TOML_CPP < 17 #error toml++ requires C++17 or higher. #endif ``` Key C++17 features utilized throughout the library: ### `std::string_view` Used pervasively for zero-copy string references in parsing, key lookups, path parsing, and formatting. The parser accepts `std::string_view` for document content and source paths. ### `std::optional` Returned by value retrieval functions like `node::value()` and `node::value_exact()`. The library also supports a custom optional type via `TOML_HAS_CUSTOM_OPTIONAL_TYPE`. ### `if constexpr` Used extensively in template code for compile-time type dispatch. For example, `node::is()` and `node::as()` use `if constexpr` chains to dispatch to the correct type check or cast: ```cpp template bool is() const noexcept { using type = impl::remove_cvref>; if constexpr (std::is_same_v) return is_table(); else if constexpr (std::is_same_v) return is_array(); else if constexpr (std::is_same_v) return is_string(); // ... } ``` ### Structured Bindings Table iteration supports structured bindings: ```cpp for (auto&& [key, value] : my_table) { std::cout << key << " = " << value << "\n"; } ``` ### Fold Expressions Used in template parameter packs throughout the implementation, such as in `impl::all_integral<>` constraints for date/time constructors. ### `std::variant` / `std::any` Awareness While not directly depending on `std::variant`, the library includes `std_variant.hpp` for platforms that need it. The node hierarchy itself is polymorphic (virtual dispatch), not variant-based. ### Inline Variables Used for constants like `impl::node_type_friendly_names[]` and `impl::control_char_escapes[]`, which are declared `inline constexpr` in header files. ### Class Template Argument Deduction (CTAD) `toml::value` supports CTAD for constructing values from native types without explicitly specifying the template parameter. --- ## C++20 Feature Support When compiled under C++20 or later, toml++ optionally supports: - **`char8_t` strings**: When `TOML_HAS_CHAR8` is true, the parser accepts `std::u8string_view` and `std::u8string` inputs. File paths can also be `char8_t`-based. - **C++20 Modules**: The library ships with experimental module support via `import tomlplusplus;`. Enabled by setting `TOMLPLUSPLUS_BUILD_MODULES=ON` in CMake (requires CMake 3.28+). --- ## Complete Feature List ### Parsing - Parse TOML from `std::string_view`, `std::istream`, or files (`toml::parse()`, `toml::parse_file()`) - Full TOML v1.0.0 conformance — passes all tests in the [toml-test](https://github.com/toml-lang/toml-test) suite - Optional support for unreleased TOML features (e.g., unicode bare keys from toml/pull/891) - Proper UTF-8 handling including BOM detection and skipping - Detailed error reporting with source positions (`toml::parse_error`, `toml::source_region`) - Works with or without exceptions (`TOML_EXCEPTIONS` macro) - Support for `char8_t` strings (C++20) - Windows wide string compatibility (`TOML_ENABLE_WINDOWS_COMPAT`) ### Data Model - Complete node type hierarchy: `toml::node` (abstract base) → `toml::table`, `toml::array`, `toml::value` - `toml::node_view` for safe, optional-like node access with chained subscript operators - `toml::key` class preserving source location information for parsed keys - Type-safe value access: `node::value()`, `node::value_exact()`, `node::value_or(default)` - Template `as()` for casting nodes to concrete types - `is()` family for type checking - Visitor pattern via `node::visit()` and `for_each()` - Homogeneity checking with `is_homogeneous()` ### Manipulation - Construct tables and arrays programmatically using initializer lists - `table::insert()`, `table::insert_or_assign()`, `table::emplace()` - `array::push_back()`, `array::emplace_back()`, `array::insert()` - `table::erase()`, `array::erase()` - Deep copy via copy constructors - All containers are movable ### Navigation - `operator[]` subscript chaining: `tbl["section"]["key"]` - `toml::at_path()` free function for dot-separated path lookup: `at_path(tbl, "section.key[0]")` - `toml::path` class for programmatic path construction and manipulation - `path::parent_path()`, `path::leaf()`, `path::subpath()` - Path components are either keys (`std::string`) or array indices (`size_t`) ### Serialization - `toml::toml_formatter` — serialize as valid TOML (default when streaming nodes) - `toml::json_formatter` — serialize as JSON - `toml::yaml_formatter` — serialize as YAML - All formatters support `format_flags` for fine-grained output control - Format flags include: `indent_array_elements`, `indent_sub_tables`, `allow_literal_strings`, `allow_multi_line_strings`, `allow_unicode_strings`, `allow_real_tabs_in_strings`, `allow_binary_integers`, `allow_octal_integers`, `allow_hexadecimal_integers`, `quote_dates_and_times`, `quote_infinities_and_nans`, `terse_key_value_pairs`, `force_multiline_arrays` - Inline table detection (`table::is_inline()`) - Value flags for controlling integer format representation (`value_flags::format_as_binary`, `format_as_octal`, `format_as_hexadecimal`) ### Build Modes - **Header-only** (default): just `#include ` - **Single-header**: drop `toml.hpp` (root-level amalgamated file) into your project - **Compiled library**: define `TOML_HEADER_ONLY=0` and compile `src/toml.cpp` - **C++20 Modules**: `import tomlplusplus;` ### Build Systems - Meson (primary, with full option support) - CMake (interface library target `tomlplusplus::tomlplusplus`) - Visual Studio solution files (`.sln`, `.vcxproj`) - Package managers: Conan, Vcpkg, DDS, tipi.build ### Compiler Support - GCC 8+ - Clang 8+ (including Apple Clang) - MSVC (VS2019+) - Intel C++ Compiler (ICC/ICL) - NVIDIA CUDA Compiler (NVCC) with workarounds ### Platform Support - x86, x64, ARM architectures - Windows, Linux, macOS - Does not require RTTI - Works with or without exceptions --- ## Version Information Version constants are defined in `include/toml++/impl/version.hpp`: ```cpp #define TOML_LIB_MAJOR 3 #define TOML_LIB_MINOR 4 #define TOML_LIB_PATCH 0 #define TOML_LANG_MAJOR 1 #define TOML_LANG_MINOR 0 #define TOML_LANG_PATCH 0 ``` - `TOML_LIB_MAJOR/MINOR/PATCH` — the library version (3.4.0) - `TOML_LANG_MAJOR/MINOR/PATCH` — the TOML specification version implemented (1.0.0) --- ## Configuration Macros toml++ is heavily configurable via preprocessor macros. Key ones include: | Macro | Default | Description | |-------|---------|-------------| | `TOML_HEADER_ONLY` | `1` | When `1`, the library is header-only. Set to `0` for compiled mode. | | `TOML_EXCEPTIONS` | auto-detected | Whether to use exceptions. Auto-detected from compiler settings. | | `TOML_ENABLE_PARSER` | `1` | Set to `0` to disable the parser entirely (serialization only). | | `TOML_ENABLE_FORMATTERS` | `1` | Set to `0` to disable all formatters. | | `TOML_ENABLE_WINDOWS_COMPAT` | `1` on Windows | Enables `std::wstring` overloads for Windows. | | `TOML_UNRELEASED_FEATURES` | `0` | Enable support for unreleased TOML spec features. | | `TOML_HAS_CUSTOM_OPTIONAL_TYPE` | `0` | Define with a custom optional type to use instead of `std::optional`. | | `TOML_DISABLE_ENVIRONMENT_CHECKS` | undefined | Define to skip compile-time environment validation. | ### Environment Ground-Truths The library validates its environment at compile time (unless `TOML_DISABLE_ENVIRONMENT_CHECKS` is defined): ```cpp static_assert(CHAR_BIT == 8, TOML_ENV_MESSAGE); static_assert('A' == 65, TOML_ENV_MESSAGE); // ASCII static_assert(sizeof(double) == 8, TOML_ENV_MESSAGE); static_assert(std::numeric_limits::is_iec559, TOML_ENV_MESSAGE); // IEEE 754 ``` These ensure the library operates on platforms with 8-bit bytes, ASCII character encoding, and IEEE 754 double-precision floats. --- ## Namespace Organization The library uses a layered namespace structure: - **`toml`** — The root namespace containing all public API types: `table`, `array`, `value`, `node`, `node_view`, `key`, `path`, `date`, `time`, `date_time`, `source_position`, `source_region`, `parse_error`, `parse_result`, etc. - **`toml::impl`** (internal) — Implementation details not part of the public API. Contains the parser, formatter base class, iterator implementations, and type trait utilities. - **ABI namespaces** — Conditional inline namespaces (e.g., `ex`/`noex` for exception mode, `custopt`/`stdopt` for optional type) ensure ABI compatibility when linking translation units compiled with different settings. --- ## Type Traits and Concepts The `toml` namespace provides several type trait utilities: ```cpp toml::is_value // true for native value types (std::string, int64_t, double, bool, date, time, date_time) toml::is_container // true for table and array toml::is_string // true if T is a toml::value or node_view thereof toml::is_integer // true if T is a toml::value or node_view thereof toml::is_floating_point toml::is_number toml::is_boolean toml::is_date toml::is_time toml::is_date_time toml::is_table toml::is_array ``` These are usable in `if constexpr` and `static_assert` contexts, making generic TOML-processing code straightforward. --- ## The `node_type` Enumeration Defined in the forward declarations, `node_type` identifies the kind of a TOML node: ```cpp enum class node_type : uint8_t { none, // Not a valid node type (used as nil sentinel) table, // toml::table array, // toml::array string, // toml::value integer, // toml::value floating_point, // toml::value boolean, // toml::value date, // toml::value time, // toml::value date_time // toml::value }; ``` Friendly display names are available via `impl::node_type_friendly_names[]`: `"none"`, `"table"`, `"array"`, `"string"`, `"integer"`, `"floating-point"`, `"boolean"`, `"date"`, `"time"`, `"date-time"`. --- ## The `value_flags` Enumeration Controls how integer values are formatted during serialization: ```cpp enum class value_flags : uint16_t { none = 0, format_as_binary = 1, // 0b... format_as_octal = 2, // 0o... format_as_hexadecimal = 3 // 0x... }; ``` The sentinel value `preserve_source_value_flags` tells the library to keep whatever format the parser originally detected. --- ## The `format_flags` Enumeration Controls formatter output behavior. It is a bitmask enum: ```cpp enum class format_flags : uint64_t { none = 0, quote_dates_and_times = 1, quote_infinities_and_nans = 2, allow_literal_strings = 4, allow_multi_line_strings = 8, allow_real_tabs_in_strings = 16, allow_unicode_strings = 32, allow_binary_integers = 64, allow_octal_integers = 128, allow_hexadecimal_integers = 256, indent_sub_tables = 512, indent_array_elements = 1024, indentation = indent_sub_tables | indent_array_elements, terse_key_value_pairs = 2048, force_multiline_arrays = 4096 }; ``` Each formatter has its own `default_flags` static constant and a set of mandatory/ignored flags defined in `formatter_constants`. --- ## Minimal Usage Example ```cpp #include #include int main() { // Parse a TOML string auto config = toml::parse(R"( [server] host = "localhost" port = 8080 debug = false )"); // Read values std::string_view host = config["server"]["host"].value_or("0.0.0.0"sv); int64_t port = config["server"]["port"].value_or(80); bool debug = config["server"]["debug"].value_or(true); std::cout << "Host: " << host << "\n"; std::cout << "Port: " << port << "\n"; std::cout << "Debug: " << std::boolalpha << debug << "\n"; // Serialize back to TOML std::cout << "\n" << config << "\n"; // Serialize as JSON std::cout << toml::json_formatter{ config } << "\n"; return 0; } ``` --- ## File Organization ``` tomlplusplus/ ├── toml.hpp # Single-header amalgamation (drop-in) ├── include/ │ └── toml++/ │ ├── toml.hpp # Main include (includes all impl headers) │ ├── toml.h # C-compatible header alias │ └── impl/ │ ├── forward_declarations.hpp # All forward decls, type aliases │ ├── preprocessor.hpp # Compiler/platform detection, macros │ ├── version.hpp # Version constants │ ├── node.hpp # toml::node base class │ ├── node.inl # node method implementations │ ├── node_view.hpp # toml::node_view │ ├── table.hpp # toml::table │ ├── table.inl # table method implementations │ ├── array.hpp # toml::array │ ├── array.inl # array method implementations │ ├── value.hpp # toml::value │ ├── key.hpp # toml::key │ ├── date_time.hpp # toml::date, toml::time, toml::date_time │ ├── source_region.hpp # source_position, source_region │ ├── parser.hpp # toml::parse(), toml::parse_file() │ ├── parser.inl # Parser implementation │ ├── parse_error.hpp # toml::parse_error │ ├── parse_result.hpp # toml::parse_result (no-exceptions mode) │ ├── path.hpp # toml::path, toml::path_component │ ├── path.inl # Path implementation │ ├── at_path.hpp # toml::at_path() free function │ ├── at_path.inl # at_path implementation │ ├── formatter.hpp # impl::formatter base class │ ├── formatter.inl # formatter base implementation │ ├── toml_formatter.hpp # toml::toml_formatter │ ├── toml_formatter.inl # TOML formatter implementation │ ├── json_formatter.hpp # toml::json_formatter │ ├── json_formatter.inl # JSON formatter implementation │ ├── yaml_formatter.hpp # toml::yaml_formatter │ ├── yaml_formatter.inl # YAML formatter implementation │ ├── make_node.hpp # impl::make_node() factory │ ├── print_to_stream.hpp/.inl # Stream output helpers │ ├── unicode.hpp # Unicode utilities │ ├── unicode.inl # UTF-8 decoder │ ├── unicode_autogenerated.hpp # Auto-generated Unicode tables │ └── std_*.hpp # Standard library includes ├── src/ │ └── toml.cpp # Compiled-library translation unit ├── tests/ # Catch2-based test suite ├── examples/ # Example programs ├── tools/ # Build/generation tools ├── meson.build # Primary build system ├── CMakeLists.txt # CMake build system └── toml-test/ # toml-test conformance suite integration ``` --- ## License toml++ is licensed under the **MIT License**. See `LICENSE` in the repository root for the full text. --- ## Related Documentation - [architecture.md](architecture.md) — Class hierarchy and internal design - [building.md](building.md) — Build instructions and integration - [basic-usage.md](basic-usage.md) — Common usage patterns - [node-system.md](node-system.md) — The node type system in depth - [tables.md](tables.md) — Working with toml::table - [arrays.md](arrays.md) — Working with toml::array - [values.md](values.md) — Working with toml::value - [parsing.md](parsing.md) — Parser internals and error handling - [formatting.md](formatting.md) — Output formatters - [path-system.md](path-system.md) — Path-based navigation - [unicode-handling.md](unicode-handling.md) — UTF-8 and Unicode support - [code-style.md](code-style.md) — Code conventions - [testing.md](testing.md) — Test framework and conformance