├── .clang-format ├── .editorconfig ├── .gitattributes ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ ├── feature_request.md │ └── spec_bug_report.md ├── pull_request_template.md └── workflows │ ├── ci.yaml │ ├── cifuzz.yml │ └── gh-pages.yaml ├── .gitignore ├── .gitmodules ├── .runsettings ├── .tipi └── deps ├── CHANGELOG.md ├── CMakeLists.txt ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── cmake ├── install-rules.cmake ├── project-is-top-level.cmake ├── tomlplusplusConfig.cmake ├── tomlplusplusConfig.cmake.meson.in ├── tomlplusplusConfigVersion.cmake.meson.in └── variables.cmake ├── cpp.hint ├── docs ├── images │ ├── badge-C++17.svg │ ├── badge-TOML.svg │ ├── badge-awesome.svg │ ├── badge-gitter.svg │ ├── badge-license-MIT.svg │ ├── banner.ai │ ├── banner.png │ ├── banner.svg │ ├── favicon.ico │ ├── logo.ai │ └── logo.svg ├── pages │ └── main_page.md └── poxy.toml ├── examples ├── CMakeLists.txt ├── benchmark_data.toml ├── error_printer.cpp ├── error_printer.vcxproj ├── example.toml ├── examples.hpp ├── merge_base.toml ├── merge_overrides.toml ├── meson.build ├── parse_benchmark.cpp ├── parse_benchmark.vcxproj ├── simple_parser.cpp ├── simple_parser.vcxproj ├── toml_generator.cpp ├── toml_generator.vcxproj ├── toml_merger.cpp ├── toml_merger.vcxproj ├── toml_to_json_transcoder.cpp └── toml_to_json_transcoder.vcxproj ├── fuzzing ├── CMakeLists.txt ├── build.sh └── toml_fuzzer.cpp ├── include ├── meson.build └── toml++ │ ├── impl │ ├── array.hpp │ ├── array.inl │ ├── at_path.hpp │ ├── at_path.inl │ ├── date_time.hpp │ ├── formatter.hpp │ ├── formatter.inl │ ├── forward_declarations.hpp │ ├── header_end.hpp │ ├── header_start.hpp │ ├── json_formatter.hpp │ ├── json_formatter.inl │ ├── key.hpp │ ├── make_node.hpp │ ├── node.hpp │ ├── node.inl │ ├── node_view.hpp │ ├── parse_error.hpp │ ├── parse_result.hpp │ ├── parser.hpp │ ├── parser.inl │ ├── path.hpp │ ├── path.inl │ ├── preprocessor.hpp │ ├── print_to_stream.hpp │ ├── print_to_stream.inl │ ├── simd.hpp │ ├── source_region.hpp │ ├── std_except.hpp │ ├── std_initializer_list.hpp │ ├── std_map.hpp │ ├── std_new.hpp │ ├── std_optional.hpp │ ├── std_string.hpp │ ├── std_string.inl │ ├── std_utility.hpp │ ├── std_variant.hpp │ ├── std_vector.hpp │ ├── table.hpp │ ├── table.inl │ ├── toml_formatter.hpp │ ├── toml_formatter.inl │ ├── unicode.hpp │ ├── unicode.inl │ ├── unicode_autogenerated.hpp │ ├── value.hpp │ ├── version.hpp │ ├── yaml_formatter.hpp │ └── yaml_formatter.inl │ ├── toml.h │ └── toml.hpp ├── meson.build ├── meson_options.txt ├── src ├── meson.build ├── modules │ ├── CMakeLists.txt │ └── tomlplusplus.cppm └── toml.cpp ├── tests ├── at_path.cpp ├── conformance_burntsushi_invalid.cpp ├── conformance_burntsushi_valid.cpp ├── conformance_iarna_invalid.cpp ├── conformance_iarna_valid.cpp ├── cpp.hint ├── for_each.cpp ├── formatters.cpp ├── impl_toml.cpp ├── leakproof.hpp ├── lib_catch2.hpp ├── main.cpp ├── manipulating_arrays.cpp ├── manipulating_parse_result.cpp ├── manipulating_tables.cpp ├── manipulating_values.cpp ├── meson.build ├── odr_test_1.cpp ├── odr_test_2.cpp ├── parsing_arrays.cpp ├── parsing_booleans.cpp ├── parsing_comments.cpp ├── parsing_dates_and_times.cpp ├── parsing_floats.cpp ├── parsing_integers.cpp ├── parsing_key_value_pairs.cpp ├── parsing_spec_example.cpp ├── parsing_strings.cpp ├── parsing_tables.cpp ├── path.cpp ├── settings.hpp ├── tests.cpp ├── tests.hpp ├── user_feedback.cpp ├── using_iterators.cpp ├── visit.cpp ├── vs │ ├── odr_test.vcxproj │ ├── test_debug_x64.vcxproj │ ├── test_debug_x64_cpplatest.vcxproj │ ├── test_debug_x64_cpplatest_noexcept.vcxproj │ ├── test_debug_x64_cpplatest_noexcept_unrel.vcxproj │ ├── test_debug_x64_cpplatest_unrel.vcxproj │ ├── test_debug_x64_noexcept.vcxproj │ ├── test_debug_x64_noexcept_unrel.vcxproj │ ├── test_debug_x64_unrel.vcxproj │ ├── test_debug_x86.vcxproj │ ├── test_debug_x86_cpplatest.vcxproj │ ├── test_debug_x86_cpplatest_noexcept.vcxproj │ ├── test_debug_x86_cpplatest_noexcept_unrel.vcxproj │ ├── test_debug_x86_cpplatest_unrel.vcxproj │ ├── test_debug_x86_noexcept.vcxproj │ ├── test_debug_x86_noexcept_unrel.vcxproj │ ├── test_debug_x86_unrel.vcxproj │ ├── test_release_x64.vcxproj │ ├── test_release_x64_cpplatest.vcxproj │ ├── test_release_x64_cpplatest_noexcept.vcxproj │ ├── test_release_x64_cpplatest_noexcept_unrel.vcxproj │ ├── test_release_x64_cpplatest_unrel.vcxproj │ ├── test_release_x64_legacy_lambda.vcxproj │ ├── test_release_x64_noexcept.vcxproj │ ├── test_release_x64_noexcept_unrel.vcxproj │ ├── test_release_x64_unrel.vcxproj │ ├── test_release_x86.vcxproj │ ├── test_release_x86_cpplatest.vcxproj │ ├── test_release_x86_cpplatest_noexcept.vcxproj │ ├── test_release_x86_cpplatest_noexcept_unrel.vcxproj │ ├── test_release_x86_cpplatest_unrel.vcxproj │ ├── test_release_x86_noexcept.vcxproj │ ├── test_release_x86_noexcept_unrel.vcxproj │ └── test_release_x86_unrel.vcxproj └── windows_compat.cpp ├── toml++.code-workspace ├── toml++.natvis ├── toml++.props ├── toml++.sln ├── toml++.vcxproj ├── toml++.vcxproj.filters ├── toml-test ├── README.md ├── meson.build ├── tt.hpp ├── tt_decoder.cpp ├── tt_decoder.vcxproj ├── tt_encoder.cpp └── tt_encoder.vcxproj ├── toml.hpp ├── tools ├── ci_single_header_check.py ├── clang_format.bat ├── generate_conformance_tests.py ├── generate_single_header.bat ├── generate_single_header.py ├── generate_windows_test_targets.py ├── requirements.txt ├── utils.py └── version.py └── vendor ├── README.md ├── catch.hpp └── json.hpp /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | insert_final_newline = true 5 | indent_style = tab 6 | indent_size = 4 7 | tab_width = 4 8 | end_of_line = lf 9 | trim_trailing_whitespace = true 10 | charset = utf-8 11 | max_line_length = 120 12 | 13 | [*.{gitattributes,yaml,yml,vcxproj,vcxproj.filters,sln,rc,clang-format,toml,py,cmake,md,markdown}] 14 | indent_style = space 15 | 16 | [{Doxyfile,Doxyfile-mcss,CMakeLists.txt}] 17 | indent_style = space 18 | 19 | [*.{hlsl,rc,sln,vcxproj,vcxproj.filters}] 20 | end_of_line = crlf 21 | 22 | [*.{sln,vcxproj,vcxproj.filters}] 23 | charset = utf-8-bom 24 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf encoding=UTF-8 2 | *.hlsl text eol=crlf encoding=UTF-8 3 | *.rc text eol=crlf encoding=UTF-8 4 | *.sln text eol=crlf encoding=UTF-8-BOM 5 | *.vcxproj text eol=crlf encoding=UTF-8-BOM 6 | *.vcxproj.filters text eol=crlf encoding=UTF-8-BOM 7 | 8 | *.cs eol=lf diff=csharp 9 | 10 | *.dot diff=astextplain 11 | *.DOT diff=astextplain 12 | *.rtf diff=astextplain 13 | *.RTF diff=astextplain 14 | 15 | *.doc binary 16 | *.DOC binary 17 | *.docx binary 18 | *.DOCX binary 19 | *.pdf binary 20 | *.PDF binary 21 | *.ai binary 22 | *.bin binary 23 | *.bmp binary 24 | *.dat binary 25 | *.gif binary 26 | *.ico binary 27 | *.jpeg binary 28 | *.jpg binary 29 | *.otf binary 30 | *.png binary 31 | *.psd binary 32 | *.rc binary 33 | *.ttf binary 34 | *.woff binary 35 | *.woff2 binary 36 | *.xlsx binary 37 | 38 | vendor/* linguist-vendored 39 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: marzer 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Regular ol' bugs. 4 | title: '' 5 | labels: [ "bug" ] 6 | assignees: marzer 7 | 8 | --- 9 | 10 | 23 | 24 | 25 | 26 | ## Environment 27 | **toml++ version and/or commit hash:** 28 | 36 | 37 | 38 | **Compiler:** 39 | 42 | 43 | 44 | 45 | **C++ standard mode:** 46 | 49 | 50 | 51 | 52 | **Target arch:** 53 | 56 | 57 | 58 | 59 | **Library configuration overrides:** 60 | 64 | 65 | 66 | 67 | **Relevant compilation flags:** 68 | 71 | 72 | 73 | 74 | ## Describe the bug 75 | 82 | 83 | 84 | 85 | ## Steps to reproduce (or a small repro code sample) 86 | 90 | 91 | 92 | 93 | ## Additional information 94 | 99 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Want to see something added or improved? Tell me all about it. 4 | title: '' 5 | labels: feature 6 | assignees: marzer 7 | 8 | --- 9 | 10 | 16 | 17 | 18 | 19 | **Is your feature request related to a problem? Please describe.** 20 | 24 | 25 | 26 | 27 | **Describe the solution you'd like** 28 | 31 | 32 | 33 | 34 | 35 | **Additional context** 36 | 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/spec_bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: TOML spec conformance bug 3 | about: Bugs relating to the library's TOML spec conformance (or lack thereof). 4 | title: '' 5 | labels: [ "bug", "TOML spec" ] 6 | assignees: marzer 7 | 8 | --- 9 | 10 | 16 | 17 | 18 | ## The non-conforming TOML snippet 19 | ```toml 20 | 21 | # your TOML here 22 | 23 | ``` 24 | 25 | 26 | ## What you expected 27 | 30 | 31 | 32 | ## What you got 33 | 36 | 37 | 38 | ## Environment 39 | **toml++ version and/or commit hash:** 40 | 49 | 50 | **Any other useful information:** 51 | 56 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | **What does this change do?** 7 | 8 | 11 | 12 | **Is it related to an exisiting bug report or feature request?** 13 | 14 | 17 | 18 | **Pre-merge checklist** 19 | 20 | 24 | 25 | - [ ] I've read [CONTRIBUTING.md] 26 | - [ ] I've rebased my changes against the current HEAD of `origin/master` (if necessary) 27 | - [ ] I've added new test cases to verify my change 28 | - [ ] I've regenerated toml.hpp ([how-to]) 29 | - [ ] I've updated any affected documentation 30 | - [ ] I've rebuilt and run the tests with at least one of: 31 | - [ ] Clang 8 or higher 32 | - [ ] GCC 8 or higher 33 | - [ ] MSVC 19.20 (Visual Studio 2019) or higher 34 | - [ ] I've added my name to the list of contributors in [README.md](https://github.com/marzer/tomlplusplus/blob/master/README.md) 35 | 36 | [CONTRIBUTING.md]: https://github.com/marzer/tomlplusplus/blob/master/CONTRIBUTING.md 37 | [how-to]: https://github.com/marzer/tomlplusplus/blob/master/CONTRIBUTING.md#regenerating-tomlhpp 38 | [README.md]: https://github.com/marzer/tomlplusplus/blob/master/README.md 39 | -------------------------------------------------------------------------------- /.github/workflows/cifuzz.yml: -------------------------------------------------------------------------------- 1 | name: CIFuzz 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | permissions: {} 8 | jobs: 9 | Fuzzing: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | security-events: write 13 | steps: 14 | - name: Build Fuzzers 15 | id: build 16 | uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master 17 | with: 18 | oss-fuzz-project-name: 'tomlplusplus' 19 | language: c++ 20 | - name: Run Fuzzers 21 | uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master 22 | with: 23 | oss-fuzz-project-name: 'tomlplusplus' 24 | language: c++ 25 | fuzz-seconds: 800 26 | output-sarif: true 27 | - name: Upload Crash 28 | uses: actions/upload-artifact@v4 29 | if: failure() && steps.build.outcome == 'success' 30 | with: 31 | name: artifacts 32 | path: ./out/artifacts 33 | - name: Upload Sarif 34 | if: always() && steps.build.outcome == 'success' 35 | uses: github/codeql-action/upload-sarif@v3 36 | with: 37 | # Path to SARIF file relative to the root of the repository 38 | sarif_file: cifuzz-sarif/results.sarif 39 | checkout_path: cifuzz-sarif 40 | -------------------------------------------------------------------------------- /.github/workflows/gh-pages.yaml: -------------------------------------------------------------------------------- 1 | name: gh-pages 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | paths: 8 | - "**.h" 9 | - "**.hpp" 10 | - "**.dox" 11 | - "**.md" 12 | - "docs/**" 13 | - "**/gh-pages.yaml" 14 | workflow_dispatch: 15 | 16 | jobs: 17 | gh-pages: 18 | runs-on: ubuntu-latest 19 | 20 | defaults: 21 | run: 22 | shell: bash 23 | 24 | steps: 25 | - uses: actions/checkout@v4 26 | with: 27 | fetch-depth: 0 28 | 29 | - name: Install dependencies 30 | run: | 31 | sudo apt -y update 32 | sudo apt -y install --no-install-recommends git doxygen 33 | pip3 install --user --upgrade poxy 34 | 35 | - name: Generate docs 36 | run: | 37 | git fetch origin master:refs/remotes/origin/master --tags --force 38 | git remote set-head origin -a 39 | git checkout master 40 | git pull --force 41 | cd docs 42 | poxy --verbose --git-tags 43 | 44 | - name: Deploy 45 | uses: peaceiris/actions-gh-pages@v3 46 | with: 47 | github_token: ${{ secrets.GITHUB_TOKEN }} 48 | publish_dir: ./docs/html 49 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marzer/tomlplusplus/2f35c28a52fd0ada7600273de9aacb66550bcdcb/.gitmodules -------------------------------------------------------------------------------- /.runsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 0 6 | build\TestResults 7 | 60000 8 | 9 | 10 | 11 | 12 | --verbosity high --list-tests * 13 | 500 14 | (?i:test) 15 | Solution 16 | tests\ 17 | AdditionalInfo 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /.tipi/deps: -------------------------------------------------------------------------------- 1 | { 2 | "requires": {} 3 | } 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | 3 | project( 4 | tomlplusplus 5 | VERSION 3.4.0 6 | DESCRIPTION "Header-only TOML config file parser and serializer for C++17" 7 | HOMEPAGE_URL "https://marzer.github.io/tomlplusplus/" 8 | LANGUAGES CXX 9 | ) 10 | 11 | include(cmake/project-is-top-level.cmake) 12 | include(cmake/variables.cmake) 13 | 14 | # ---- Declare library ---- 15 | 16 | add_library(tomlplusplus_tomlplusplus INTERFACE) 17 | add_library(tomlplusplus::tomlplusplus ALIAS tomlplusplus_tomlplusplus) 18 | 19 | set_property( 20 | TARGET tomlplusplus_tomlplusplus PROPERTY 21 | EXPORT_NAME tomlplusplus 22 | ) 23 | 24 | target_include_directories( 25 | tomlplusplus_tomlplusplus 26 | ${tomlplusplus_warning_guard} # unquoted for list expansion 27 | INTERFACE 28 | "$" 29 | ) 30 | 31 | target_compile_features(tomlplusplus_tomlplusplus INTERFACE cxx_std_17) 32 | 33 | # ---- Install rules ---- 34 | if (tomlplusplus_INSTALL) 35 | include(cmake/install-rules.cmake) 36 | endif() 37 | 38 | # ---- C++ Modules Support (optional) ---- 39 | option(TOMLPLUSPLUS_BUILD_MODULES "Build C++ modules support" OFF) 40 | 41 | if(TOMLPLUSPLUS_BUILD_MODULES) 42 | if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.28) 43 | message(STATUS "Building C++ modules (CMake ${CMAKE_VERSION} supports modules)") 44 | add_subdirectory(src/modules) 45 | else() 46 | message(WARNING "Skipping C++ modules (requires CMake 3.28+, found ${CMAKE_VERSION})") 47 | endif() 48 | else() 49 | message(STATUS "C++ modules support is disabled. Enable with -DTOMLPLUSPLUS_BUILD_MODULES=ON") 50 | endif() 51 | 52 | # ---- Examples and fuzzing ---- 53 | if(PROJECT_IS_TOP_LEVEL) 54 | option(BUILD_EXAMPLES "Build examples tree." OFF) 55 | option(BUILD_FUZZER "Build fuzzer." OFF) 56 | if(BUILD_EXAMPLES) 57 | add_subdirectory(examples) 58 | endif() 59 | if(BUILD_FUZZER AND DEFINED ENV{LIB_FUZZING_ENGINE}) 60 | add_subdirectory(fuzzing) 61 | endif() 62 | endif() 63 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at mark.gillard@outlook.com.au. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to toml++ 2 | 3 | Contributions are very welcome! Either by [reporting issues] or submitting pull requests. 4 | If you wish to submit a PR, please be aware that: 5 | 6 | - The single-header `toml.hpp` at the repository root is generated by a script, so don't change it directly; make your 7 | changes in the files in `include`. 8 | - Your changes should compile warning-free on at least one of: 9 | - GCC 8 or higher 10 | - Clang 8 or higher 11 | - MSVC 19.2X (Visual Studio 2019) or higher 12 | - You should regenerate the single-header version of `toml.hpp` as part of your PR (a CI check will fail if you don't). 13 | 14 |
15 | 16 | ## Regenerating the single-header toml.hpp 17 | 18 | 1. Make your changes as necessary 19 | - If you've added a new header file that isn't going to be transitively included by one of the 20 | others, add an include directive to `include/toml++/toml.hpp` 21 | 2. Install the prerequisite python packages: `pip3 install -r tools/requirements.txt` 22 | 3. Run `tools/generate_single_header.py` 23 | 24 |
25 | 26 | ## Building and running the tests 27 | 28 | Testing is done using [Catch2]. 29 | 30 | ### Testing on Windows with Visual Studio 31 | 32 | Install [Visual Studio] and [Test Adapter for Catch2], then open `toml++.sln` and build the 33 | projects in the `tests` solution folder. Visual Studio's Test Explorer should pick these up and 34 | allow you to run the tests directly. 35 | 36 | If test discovery fails you can usually fix it by enabling 37 | `Auto Detect runsettings Files` (settings gear icon > `Configure Run Settings`). 38 | 39 | ### Testing on Linux (and WSL) 40 | 41 | ```bash 42 | # install ninja, meson, locales (first time only) 43 | sudo apt update && sudo apt install -y locales python3 python3-pip ninja-build 44 | sudo pip3 install meson 45 | sudo locale-gen 'en_US.utf8' \ 46 | 'ja_JP.utf8' \ 47 | 'de_DE.utf8' \ 48 | 'it_IT.utf8' \ 49 | 'tr_TR.utf8' \ 50 | 'fi_FI.utf8' \ 51 | 'fr_FR.utf8' \ 52 | 'zh_CN.utf8' 53 | 54 | # create the build configs (first time only) 55 | meson setup build-debug --buildtype=debug -Ddevel=true 56 | meson setup build-release --buildtype=release -Ddevel=true 57 | 58 | # run the tests 59 | cd build-debug && ninja && ninja test \ 60 | && cd ../build-release && ninja && ninja test \ 61 | && cd .. 62 | ``` 63 | 64 | > ℹ️ Pass `-Duse_vendored_libs=false` to Meson if you wish to use the system-installed version 65 | > of Catch2 rather than the vendored one. 66 | 67 |
68 | 69 | ## Testing with the [toml-test] suite 70 | 71 | As an optional extra you may wish to test against the official test TOML test suite, [toml-test]. See the 72 | instructions at [toml-test/README](./toml-test/README.md). Note that the toml++ tests already consume tests from the 73 | offical suite via a C++ code-generation script so you are not expected to take this extra step as part of contributing 74 | to the library. 75 | 76 | [visual studio]: https://visualstudio.microsoft.com/vs/ 77 | [test adapter for catch2]: https://marketplace.visualstudio.com/items?itemName=JohnnyHendriks.ext01 78 | [reporting issues]: https://github.com/marzer/tomlplusplus/issues 79 | [catch2]: https://github.com/catchorg/Catch2 80 | [toml-test]: https://github.com/toml-lang/toml-test 81 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Mark Gillard 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 6 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the 11 | Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 14 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 15 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 16 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | -------------------------------------------------------------------------------- /cmake/install-rules.cmake: -------------------------------------------------------------------------------- 1 | include(CMakePackageConfigHelpers) 2 | include(GNUInstallDirs) 3 | 4 | install( 5 | FILES "${PROJECT_SOURCE_DIR}/toml++.natvis" "${PROJECT_SOURCE_DIR}/cpp.hint" 6 | DESTINATION "${CMAKE_INSTALL_DATADIR}/tomlplusplus" 7 | COMPONENT tomlplusplus_Development 8 | ) 9 | 10 | install( 11 | DIRECTORY "${PROJECT_SOURCE_DIR}/include/" 12 | DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" 13 | COMPONENT tomlplusplus_Development 14 | FILES_MATCHING REGEX "^.*[.](h|hpp|inl)$" 15 | ) 16 | 17 | install( 18 | TARGETS tomlplusplus_tomlplusplus 19 | EXPORT tomlplusplusTargets 20 | INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" 21 | ) 22 | 23 | write_basic_package_version_file( 24 | tomlplusplusConfigVersion.cmake 25 | COMPATIBILITY SameMajorVersion 26 | ARCH_INDEPENDENT 27 | ) 28 | 29 | set( 30 | tomlplusplus_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/tomlplusplus" 31 | CACHE STRING "CMake package config location relative to the install prefix" 32 | ) 33 | 34 | mark_as_advanced(tomlplusplus_INSTALL_CMAKEDIR) 35 | 36 | install( 37 | FILES 38 | "${PROJECT_SOURCE_DIR}/cmake/tomlplusplusConfig.cmake" 39 | "${PROJECT_BINARY_DIR}/tomlplusplusConfigVersion.cmake" 40 | DESTINATION "${tomlplusplus_INSTALL_CMAKEDIR}" 41 | COMPONENT tomlplusplus_Development 42 | ) 43 | 44 | install( 45 | EXPORT tomlplusplusTargets 46 | NAMESPACE tomlplusplus:: 47 | DESTINATION "${tomlplusplus_INSTALL_CMAKEDIR}" 48 | COMPONENT tomlplusplus_Development 49 | ) 50 | 51 | if(PROJECT_IS_TOP_LEVEL) 52 | include(CPack) 53 | endif() 54 | -------------------------------------------------------------------------------- /cmake/project-is-top-level.cmake: -------------------------------------------------------------------------------- 1 | # This variable is set by project() in CMake 3.21+ 2 | string( 3 | COMPARE EQUAL 4 | "${CMAKE_SOURCE_DIR}" "${PROJECT_SOURCE_DIR}" 5 | PROJECT_IS_TOP_LEVEL 6 | ) 7 | -------------------------------------------------------------------------------- /cmake/tomlplusplusConfig.cmake: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_LIST_DIR}/tomlplusplusTargets.cmake) 2 | -------------------------------------------------------------------------------- /cmake/tomlplusplusConfig.cmake.meson.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | # If tomlplusplus::tomlplusplus target is not defined it will be included 4 | if(NOT TARGET tomlplusplus::tomlplusplus) 5 | 6 | if (@compile_library@) 7 | set(imported_type UNKNOWN) 8 | else() 9 | set(imported_type INTERFACE) 10 | endif() 11 | 12 | # Import tomlplusplus interface library 13 | add_library(tomlplusplus::tomlplusplus ${imported_type} IMPORTED) 14 | set_target_properties(tomlplusplus::tomlplusplus PROPERTIES 15 | INTERFACE_INCLUDE_DIRECTORIES "${PACKAGE_PREFIX_DIR}/@includedir@") 16 | 17 | # Require C++17 18 | target_compile_features(tomlplusplus::tomlplusplus INTERFACE cxx_std_17) 19 | 20 | # Set the path to the installed library so that users can link to it 21 | if (@compile_library@) 22 | set_target_properties(tomlplusplus::tomlplusplus PROPERTIES 23 | IMPORTED_LOCATION "${PACKAGE_PREFIX_DIR}/@libdir@/@lib_name@" 24 | ) 25 | # compile_options not quoted on purpose 26 | target_compile_options(tomlplusplus::tomlplusplus INTERFACE @compile_options@) 27 | endif() 28 | 29 | endif() 30 | -------------------------------------------------------------------------------- /cmake/tomlplusplusConfigVersion.cmake.meson.in: -------------------------------------------------------------------------------- 1 | # This is a basic version file for the Config-mode of find_package(). 2 | # It is used by write_basic_package_version_file() as input file for configure_file() 3 | # to create a version-file which can be installed along a config.cmake file. 4 | # 5 | # The created file sets PACKAGE_VERSION_EXACT if the current version string and 6 | # the requested version string are exactly the same and it sets 7 | # PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version. 8 | # The variable CVF_VERSION must be set before calling configure_file(). 9 | 10 | set(PACKAGE_VERSION "@version@") 11 | 12 | if (PACKAGE_FIND_VERSION_RANGE) 13 | # Package version must be in the requested version range 14 | if ((PACKAGE_FIND_VERSION_RANGE_MIN STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MIN) 15 | OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_GREATER PACKAGE_FIND_VERSION_MAX) 16 | OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_GREATER_EQUAL PACKAGE_FIND_VERSION_MAX))) 17 | set(PACKAGE_VERSION_COMPATIBLE FALSE) 18 | else() 19 | set(PACKAGE_VERSION_COMPATIBLE TRUE) 20 | endif() 21 | else() 22 | if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) 23 | set(PACKAGE_VERSION_COMPATIBLE FALSE) 24 | else() 25 | set(PACKAGE_VERSION_COMPATIBLE TRUE) 26 | if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) 27 | set(PACKAGE_VERSION_EXACT TRUE) 28 | endif() 29 | endif() 30 | endif() 31 | 32 | 33 | # if the installed project requested no architecture check, don't perform the check 34 | if("True") 35 | return() 36 | endif() 37 | 38 | # if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: 39 | if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "") 40 | return() 41 | endif() 42 | 43 | # check that the installed version has the same 32/64bit-ness as the one which is currently searching: 44 | if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8") 45 | math(EXPR installedBits "8 * 8") 46 | set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") 47 | set(PACKAGE_VERSION_UNSUITABLE TRUE) 48 | endif() 49 | -------------------------------------------------------------------------------- /cmake/variables.cmake: -------------------------------------------------------------------------------- 1 | # ---- Warning guard ---- 2 | 3 | # target_include_directories with the SYSTEM modifier will request the compiler 4 | # to omit warnings from the provided paths, if the compiler supports that 5 | # This is to provide a user experience similar to find_package when 6 | # add_subdirectory or FetchContent is used to consume this project 7 | set(tomlplusplus_warning_guard "") 8 | option(tomlplusplus_INSTALL "Enable generation of tomlplusplus install targets" ${PROJECT_IS_TOP_LEVEL}) 9 | if(NOT PROJECT_IS_TOP_LEVEL) 10 | option( 11 | tomlplusplus_INCLUDES_WITH_SYSTEM 12 | "Use SYSTEM modifier for tomlplusplus's includes, disabling warnings" 13 | ON 14 | ) 15 | mark_as_advanced(tomlplusplus_INCLUDES_WITH_SYSTEM) 16 | if(tomlplusplus_INCLUDES_WITH_SYSTEM) 17 | set(tomlplusplus_warning_guard SYSTEM) 18 | endif() 19 | endif() 20 | -------------------------------------------------------------------------------- /cpp.hint: -------------------------------------------------------------------------------- 1 | #define TOML_ABI_NAMESPACE_BOOL(...) static_assert(true) 2 | #define TOML_ABI_NAMESPACE_END static_assert(true) 3 | #define TOML_ABSTRACT_INTERFACE 4 | #define TOML_ALWAYS_INLINE inline 5 | #define TOML_ANON_NAMESPACE_END static_assert(true) 6 | #define TOML_ANON_NAMESPACE_START namespace 7 | #define TOML_API 8 | #define TOML_ATTR(...) 9 | #define TOML_CLOSED_ENUM 10 | #define TOML_CLOSED_FLAGS_ENUM 11 | #define TOML_CONST_GETTER 12 | #define TOML_CONST_INLINE_GETTER inline 13 | #define TOML_CONSTRAINED_TEMPLATE(cond, ...) template <__VA_ARGS__> 14 | #define TOML_EMPTY_BASES 15 | #define TOML_EXPORTED_CLASS 16 | #define TOML_EXPORTED_FREE_FUNCTION 17 | #define TOML_EXPORTED_MEMBER_FUNCTION 18 | #define TOML_EXPORTED_STATIC_FUNCTION 19 | #define TOML_EXTERNAL_LINKAGE 20 | #define TOML_FLAGS_ENUM 21 | #define TOML_HIDDEN_CONSTRAINT(cond, ...) template <__VA_ARGS__> 22 | #define TOML_IMPL_NAMESPACE_END static_assert(true) 23 | #define TOML_IMPL_NAMESPACE_START namespace toml::impl 24 | #define TOML_INTERNAL_LINKAGE static 25 | #define TOML_LIKELY(...) (__VA_ARGS__) 26 | #define TOML_LIKELY_CASE 27 | #define TOML_NAMESPACE_END static_assert(true) 28 | #define TOML_NAMESPACE_START namespace toml 29 | #define TOML_NEVER_INLINE 30 | #define TOML_NODISCARD 31 | #define TOML_NODISCARD_CTOR 32 | #define TOML_OPEN_ENUM 33 | #define TOML_OPEN_FLAGS_ENUM 34 | #define TOML_PURE_GETTER 35 | #define TOML_PURE_INLINE_GETTER inline 36 | #define TOML_RETURNS_BY_THROWING 37 | #define TOML_TRIVIAL_ABI 38 | #define TOML_UNLIKELY(...) (__VA_ARGS__) 39 | #define TOML_UNLIKELY_CASE 40 | -------------------------------------------------------------------------------- /docs/images/badge-C++17.svg: -------------------------------------------------------------------------------- 1 | standardC++17 -------------------------------------------------------------------------------- /docs/images/badge-TOML.svg: -------------------------------------------------------------------------------- 1 | TOML: v1.0.0TOMLv1.0.0 -------------------------------------------------------------------------------- /docs/images/badge-awesome.svg: -------------------------------------------------------------------------------- 1 | Mentioned in an Awesome list 2 | -------------------------------------------------------------------------------- /docs/images/badge-gitter.svg: -------------------------------------------------------------------------------- 1 | chat: on gitterchaton gitter -------------------------------------------------------------------------------- /docs/images/badge-license-MIT.svg: -------------------------------------------------------------------------------- 1 | licenseMIT -------------------------------------------------------------------------------- /docs/images/banner.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marzer/tomlplusplus/2f35c28a52fd0ada7600273de9aacb66550bcdcb/docs/images/banner.ai -------------------------------------------------------------------------------- /docs/images/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marzer/tomlplusplus/2f35c28a52fd0ada7600273de9aacb66550bcdcb/docs/images/banner.png -------------------------------------------------------------------------------- /docs/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marzer/tomlplusplus/2f35c28a52fd0ada7600273de9aacb66550bcdcb/docs/images/favicon.ico -------------------------------------------------------------------------------- /docs/images/logo.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marzer/tomlplusplus/2f35c28a52fd0ada7600273de9aacb66550bcdcb/docs/images/logo.ai -------------------------------------------------------------------------------- /docs/images/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 9 | 12 | 15 | -------------------------------------------------------------------------------- /docs/poxy.toml: -------------------------------------------------------------------------------- 1 | # this is a config file for Poxy - a Doxygen + m.css front-end written in Python. 2 | # https://github.com/marzer/poxy 3 | # 4 | # config reference: https://github.com/marzer/poxy/wiki/Configuration-options 5 | 6 | name = 'toml++' 7 | author = 'Mark Gillard' 8 | description = 'TOML for C++' 9 | cpp = 17 10 | github = 'marzer/tomlplusplus' 11 | license = [ 'MIT', 'https://github.com/marzer/tomlplusplus/blob/master/LICENSE' ] 12 | twitter = 'marzer8789' 13 | sponsor = 'https://github.com/sponsors/marzer' 14 | show_includes = false 15 | changelog = true 16 | logo = 'images/logo.svg' 17 | favicon = 'images/favicon.ico' 18 | navbar = [ 'namespaces', 'annotated' ] 19 | theme = 'dark' 20 | extra_files = [ 21 | 'images/badge-awesome.svg', 22 | 'images/badge-TOML.svg', 23 | 'images/badge-gitter.svg', 24 | ] 25 | 26 | 27 | 28 | [warnings] 29 | enabled = true 30 | treat_as_errors = false 31 | undocumented = true 32 | 33 | 34 | 35 | [sources] 36 | paths = [ 'pages' ] 37 | recursive_paths = [ '../include' ] 38 | patterns = [ '*.h', '*.hpp', '*.dox', '*.md' ] 39 | strip_paths = [ '../include', 'pages' ] 40 | 41 | 42 | 43 | [images] 44 | paths = [ 'images' ] 45 | 46 | 47 | 48 | [macros] 49 | 'TOML_ASYMMETRICAL_EQUALITY_OPS(...)' = 'static_assert(true)' 50 | 'TOML_ABI_NAMESPACE_START(...)' = 'static_assert(true)' 51 | 'TOML_ABI_NAMESPACE_BOOL(...)' = 'static_assert(true)' 52 | 53 | 54 | 55 | [meta_tags] 56 | 'google-site-verification' = 'gbtcNgKlNiPSMKkYMw4zWFVWGPH_oU93m9n_-nb4qK8' 57 | 58 | 59 | 60 | [code_blocks] 61 | macros = [ 'TOML_[A-Z0-9_]+?', 'print_value' ] 62 | 63 | 64 | 65 | [badges] 66 | '1. TOML v1.0.0' = [ 67 | 'badge-TOML.svg', 68 | 'https://toml.io/en/v1.0.0' 69 | ] 70 | '2. Mentioned in Awesome C++' = [ 71 | 'badge-awesome.svg', 72 | 'https://github.com/fffaraz/awesome-cpp' 73 | ] 74 | '3. Gitter' = [ 75 | 'badge-gitter.svg', 76 | 'https://gitter.im/marzer/tomlplusplus' 77 | ] 78 | 79 | 80 | 81 | [autolinks] 82 | '(?:toml::)?date[_-]times?' = 'structtoml_1_1date__time.html' 83 | '(?:toml::)?default[_ ]formatters?' = 'classtoml_1_1default__formatter.html' 84 | '(?:toml::)?json[_ ]formatters?' = 'classtoml_1_1json__formatter.html' 85 | '(?:toml::)?node[_ ]views?' = 'classtoml_1_1node__view.html' 86 | '(?:toml::)?parse[_ ]errors?' = 'classtoml_1_1parse__error.html' 87 | '(?:toml::)?parse[_ ]results?' = 'classtoml_1_1parse__result.html' 88 | '(?:toml::)?path[_ ]components?' = 'classtoml_1_1path__component.html' 89 | '(?:toml::)?source[_ ]positions?' = 'structtoml_1_1source__position.html' 90 | '(?:toml::)?source[_ ]regions?' = 'structtoml_1_1source__region.html' 91 | '(?:toml::)?time[_ ]offsets?' = 'structtoml_1_1time__offset.html' 92 | '(?:toml::)?toml[_ ]formatters?' = 'classtoml_1_1toml__formatter.html' 93 | '(?:toml::)?yaml[_ ]formatters?' = 'classtoml_1_1yaml__formatter.html' 94 | 'toml::dates?' = 'structtoml_1_1date.html' 95 | 'toml::keys?' = 'classtoml_1_1key.html' 96 | 'toml::times?' = 'structtoml_1_1time.html' 97 | 'toml::values?' = 'classtoml_1_1value.html' 98 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | 3 | project(Examples LANGUAGES CXX) 4 | 5 | include(../cmake/project-is-top-level.cmake) 6 | 7 | if(PROJECT_IS_TOP_LEVEL) 8 | find_package(tomlplusplus REQUIRED) 9 | endif() 10 | 11 | add_custom_target(run_examples COMMENT "Running all examples") 12 | 13 | function(add_example name) 14 | cmake_parse_arguments(PARSE_ARGV 1 "" "" "" ARGS) 15 | add_executable("${name}" "${name}.cpp") 16 | target_link_libraries("${name}" PRIVATE tomlplusplus::tomlplusplus) 17 | target_compile_features("${name}" PRIVATE cxx_std_17) 18 | add_custom_target("run_${name}" COMMAND "${name}" ${_ARGS} VERBATIM) 19 | add_dependencies(run_examples "run_${name}") 20 | endfunction() 21 | 22 | add_example(error_printer) 23 | add_example(parse_benchmark) 24 | add_example(simple_parser) 25 | add_example(toml_generator) 26 | add_example(toml_merger) 27 | add_example(toml_to_json_transcoder ARGS "${PROJECT_SOURCE_DIR}/example.toml") 28 | -------------------------------------------------------------------------------- /examples/error_printer.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | 16.0 15 | {DAB4634D-8145-4860-AE45-5198E76FF324} 16 | 10.0 17 | 18 | 19 | 20 | Application 21 | true 22 | v143 23 | MultiByte 24 | 25 | 26 | Application 27 | false 28 | v143 29 | true 30 | MultiByte 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | Console 40 | 41 | 42 | 43 | ..\examples 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /examples/example.toml: -------------------------------------------------------------------------------- 1 | # This is a TOML document. Boom. 2 | 3 | title = "TOML Example" 4 | 5 | # plain signed integers 6 | int1 = -9223372036854775808 7 | int2 = 9223372036854775807 8 | 9 | # floats 10 | flt1 = 0.00000000001 11 | flt2 = 1e-11 12 | flt3 = 11.0 13 | flt4 = +1.0 14 | 15 | # hexadecimal with prefix `0x` 16 | hex1 = 0xDEADBEEF 17 | hex2 = 0xdeadbeef 18 | hex3 = 0xdead_beef 19 | 20 | # octal with prefix `0o` 21 | oct1 = 0o01234567 22 | oct2 = 0o755 # useful for Unix file permissions 23 | 24 | # binary with prefix `0b` 25 | bin1 = 0b11010110 # 214 26 | 27 | # local dates and times 28 | tim1 = 07:32:00 29 | tim2 = 00:32:00.100000000 30 | dat1 = 1979-05-27 31 | 32 | # offset date-times 33 | odt1 = 1979-05-27T07:32:00Z 34 | odt2 = 1979-05-27T00:32:00-07:00 35 | odt3 = 1979-05-27T00:32:00.999999-07:00 36 | 37 | # strings 38 | str1 = """ 39 | This is a 40 | multi-line 41 | string. 42 | """ 43 | str2 = "This is also\na multi-line\nstring." 44 | str3 = 'C:\highway\to\the\danger\zone' 45 | kosme = "κόσμε" # unicode! 46 | 47 | arr = [ 'this', 'is', 'a', 'long', 'array', 'with', 16, 'elements.', 'it', 'should', 'be', 'printed', 'as', 'a', 'multiline', 'array.'] 48 | 49 | tab = { this = 'is', an = 'inline', table = 'yay'} 50 | 51 | dotted.keys.are = "supported" 52 | dotted.and = "implemented as tables" 53 | 54 | [owner] 55 | name = "Mark Gillard" 56 | dob = 1987-03-16 10:20:00+09:30 57 | 58 | [[owner.pets]] 59 | name = "Brian" 60 | species = "cat" 61 | 62 | [[owner.pets]] 63 | name = "Skippy" 64 | species = "kangaroo" 65 | 66 | [database] 67 | server = "192.168.1.1" 68 | ports = [ 8001, 8001, 8002 ] 69 | connection_max = 5000 70 | enabled = true 71 | 72 | [servers] 73 | 74 | # You can indent as you please. Tabs or spaces. TOML don't care. 75 | [servers.alpha] 76 | ip = "10.0.0.1" 77 | dc = "eqdc10" 78 | 79 | [servers.beta] 80 | ip = "10.0.0.2" 81 | dc = "eqdc10" 82 | country = "中国" # This should be parsed as UTF-8 83 | 84 | [clients] 85 | data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it 86 | 87 | # Line breaks are OK when inside arrays 88 | hosts = [ 89 | "alpha", 90 | "omega" 91 | ] 92 | 93 | # Products 94 | 95 | [[products]] 96 | name = "Hammer" 97 | sku = 738594937 98 | 99 | [[products]] 100 | name = "Nail" 101 | sku = 284758393 102 | color = "gray" 103 | -------------------------------------------------------------------------------- /examples/examples.hpp: -------------------------------------------------------------------------------- 1 | //# This file is a part of toml++ and is subject to the the terms of the MIT license. 2 | //# Copyright (c) 2019-2020 Mark Gillard 3 | //# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. 4 | // SPDX-License-Identifier: MIT 5 | 6 | // this file is for boilerplate unrelated to the toml++ example learning outcomes. 7 | 8 | #ifdef __clang__ 9 | #pragma clang diagnostic push 10 | #pragma clang diagnostic ignored "-Weverything" 11 | #elif defined(__GNUC__) 12 | #pragma GCC diagnostic push 13 | #pragma GCC diagnostic ignored "-Wall" 14 | #pragma GCC diagnostic ignored "-Wextra" 15 | #elif defined(_MSC_VER) 16 | #pragma warning(push, 0) 17 | #endif 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #ifdef _WIN32 31 | #ifdef _MSC_VER 32 | extern "C" __declspec(dllimport) int __stdcall SetConsoleOutputCP(unsigned int); 33 | #pragma comment(lib, "Kernel32.lib") 34 | #else 35 | #include 36 | #endif 37 | #endif 38 | 39 | namespace 40 | { 41 | static const auto initialize_environment_automagically = []() noexcept 42 | { 43 | #ifdef _WIN32 44 | SetConsoleOutputCP(65001); // CP_UTF8 45 | #endif 46 | 47 | std::ios_base::sync_with_stdio(false); 48 | std::cout << std::boolalpha; 49 | 50 | srand(static_cast(time(nullptr))); 51 | 52 | return true; 53 | }(); 54 | } 55 | 56 | #ifdef __clang__ 57 | #pragma clang diagnostic pop 58 | #elif defined(__GNUC__) 59 | #pragma GCC diagnostic pop 60 | #elif defined(_MSC_VER) 61 | #pragma warning(pop) 62 | #endif 63 | -------------------------------------------------------------------------------- /examples/merge_base.toml: -------------------------------------------------------------------------------- 1 | [section1] 2 | key1="value1" 3 | key2="value2" 4 | 5 | [section1.child1] 6 | -------------------------------------------------------------------------------- /examples/merge_overrides.toml: -------------------------------------------------------------------------------- 1 | [section1] 2 | key2="value3" 3 | 4 | [section1.child1] 5 | foo="bar" 6 | 7 | [section1.child2] 8 | foo2="bar2" 9 | -------------------------------------------------------------------------------- /examples/meson.build: -------------------------------------------------------------------------------- 1 | # This file is a part of toml++ and is subject to the the terms of the MIT license. 2 | # Copyright (c) Mark Gillard 3 | # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. 4 | # SPDX-License-Identifier: MIT 5 | 6 | example_args = [] 7 | example_args += global_args 8 | 9 | examples = [ 10 | 'simple_parser', 11 | 'toml_to_json_transcoder', 12 | 'toml_generator', 13 | 'error_printer', 14 | 'parse_benchmark', 15 | 'toml_merger', 16 | ] 17 | 18 | example_executables = [] 19 | foreach example : examples 20 | example_executables += [[ 21 | example, 22 | executable( 23 | example, 24 | [ example + '.cpp' ], 25 | cpp_args: example_args, 26 | dependencies: tomlplusplus_dep, 27 | override_options: global_overrides, 28 | install: not is_subproject 29 | ) 30 | ]] 31 | endforeach 32 | -------------------------------------------------------------------------------- /examples/parse_benchmark.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of toml++ and is subject to the the terms of the MIT license. 2 | // Copyright (c) Mark Gillard 3 | // See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. 4 | // SPDX-License-Identifier: MIT 5 | 6 | // This example is just a short-n-shiny benchmark. 7 | 8 | #include "examples.hpp" 9 | #include 10 | 11 | using namespace std::string_view_literals; 12 | 13 | static constexpr size_t iterations = 10000; 14 | 15 | int main(int argc, char** argv) 16 | { 17 | const auto file_path = std::string(argc > 1 ? std::string_view{ argv[1] } : "benchmark_data.toml"sv); 18 | 19 | // read the file into a string first to remove file I/O from the benchmark 20 | std::string file_content; 21 | { 22 | std::ifstream file(file_path, std::ifstream::in | std::ifstream::binary | std::ifstream::ate); 23 | if (!file) 24 | { 25 | std::cerr << "File '"sv << file_path << "'could not be opened for reading\n"sv; 26 | return -1; 27 | } 28 | 29 | const auto file_size = file.tellg(); 30 | if (file_size == -1) 31 | { 32 | std::cerr << "File '"sv << file_path << "' could not be opened for reading\n"sv; 33 | return -1; 34 | } 35 | file.seekg(0, std::ifstream::beg); 36 | 37 | file_content.resize(static_cast(file_size)); 38 | file.read(file_content.data(), static_cast(file_size)); 39 | if (!file.eof() && !file) 40 | { 41 | std::cerr << "Failed to read contents of file '"sv << file_path << "'\n"sv; 42 | return -1; 43 | } 44 | } 45 | 46 | // parse once to make sure it isn't garbage 47 | { 48 | #if TOML_EXCEPTIONS 49 | try 50 | { 51 | const auto result = toml::parse(file_content, file_path); 52 | } 53 | catch (const toml::parse_error& err) 54 | { 55 | std::cerr << err << "\n"; 56 | return 1; 57 | } 58 | #else 59 | const auto result = toml::parse(file_content, file_path); 60 | if (!result) 61 | { 62 | std::cerr << result.error() << "\n"; 63 | return 1; 64 | } 65 | #endif 66 | } 67 | 68 | // run the benchmark 69 | std::cout << "Parsing '"sv << file_path << "' "sv << iterations << " times...\n"sv; 70 | 71 | const auto start = std::chrono::steady_clock::now(); 72 | for (size_t i = 0; i < iterations; i++) 73 | std::ignore = toml::parse(file_content, file_path); 74 | const auto cumulative_sec = 75 | std::chrono::duration_cast>(std::chrono::steady_clock::now() - start).count(); 76 | const auto mean_sec = cumulative_sec / static_cast(iterations); 77 | std::cout << " total: "sv << cumulative_sec << " s\n"sv 78 | << " mean: "sv << mean_sec << " s\n"sv; 79 | 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /examples/parse_benchmark.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | 16.0 15 | {407FCAA8-FC2C-424D-B44B-C6A1AFAD757A} 16 | 10.0 17 | 18 | 19 | 20 | Application 21 | true 22 | v143 23 | MultiByte 24 | 25 | 26 | Application 27 | false 28 | v143 29 | true 30 | MultiByte 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | Console 40 | 41 | 42 | 43 | ..\examples 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /examples/simple_parser.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of toml++ and is subject to the the terms of the MIT license. 2 | // Copyright (c) Mark Gillard 3 | // See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. 4 | // SPDX-License-Identifier: MIT 5 | 6 | // This example demonstrates how to parse TOML from a file or stdin and re-serialize it (print it out) to stdout. 7 | 8 | #include "examples.hpp" 9 | #include 10 | 11 | using namespace std::string_view_literals; 12 | 13 | int main(int argc, char** argv) 14 | { 15 | const auto path = argc > 1 ? std::string_view{ argv[1] } : "example.toml"sv; 16 | 17 | toml::table tbl; 18 | try 19 | { 20 | // read directly from stdin 21 | if (path == "-"sv || path.empty()) 22 | tbl = toml::parse(std::cin, "stdin"sv); 23 | 24 | // read from a file 25 | else 26 | tbl = toml::parse_file(path); 27 | } 28 | catch (const toml::parse_error& err) 29 | { 30 | std::cerr << err << "\n"; 31 | return 1; 32 | } 33 | 34 | std::cout << tbl << "\n"; 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /examples/simple_parser.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | 16.0 15 | {259FCEE5-3442-4076-9547-2BA793ECA1CB} 16 | 10.0 17 | 18 | 19 | 20 | Application 21 | true 22 | v143 23 | MultiByte 24 | 25 | 26 | Application 27 | false 28 | v143 29 | true 30 | MultiByte 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | Console 40 | 41 | 42 | 43 | ..\examples 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /examples/toml_generator.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | 16.0 15 | {23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2} 16 | 10.0 17 | toml_generator 18 | 19 | 20 | 21 | Application 22 | true 23 | v143 24 | MultiByte 25 | 26 | 27 | Application 28 | false 29 | v143 30 | true 31 | MultiByte 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | Console 41 | 42 | 43 | 44 | ..\examples 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /examples/toml_merger.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of toml++ and is subject to the the terms of the MIT license. 2 | // Copyright (c) Mark Gillard 3 | // See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. 4 | // SPDX-License-Identifier: MIT 5 | 6 | // This example demonstrates a method of merging one TOML data tree into another. 7 | 8 | #include "examples.hpp" 9 | #include 10 | 11 | using namespace std::string_view_literals; 12 | 13 | namespace 14 | { 15 | // recursively merge 'rhs' into 'lhs'. 16 | // 17 | // note that this implementation always prioritizes 'rhs' over 'lhs' in the event of a conflict; 18 | // extending it to handle conflicts in some other manner is left as an exercise to the reader :) 19 | 20 | static void merge_left(toml::table& lhs, toml::table&& rhs); 21 | 22 | static void merge_left(toml::array& lhs, toml::array&& rhs) 23 | { 24 | rhs.for_each( 25 | [&](std::size_t index, auto&& rhs_val) 26 | { 27 | // rhs index not found in lhs - direct move 28 | if (lhs.size() <= index) 29 | { 30 | lhs.push_back(std::move(rhs_val)); 31 | return; 32 | } 33 | 34 | // both elements were the same container type - recurse into them 35 | if constexpr (toml::is_container) 36 | { 37 | using rhs_type = std::remove_cv_t>; 38 | if (auto lhs_child = lhs[index].as()) 39 | { 40 | merge_left(*lhs_child, std::move(rhs_val)); 41 | return; 42 | } 43 | } 44 | 45 | // replace lhs element with rhs 46 | lhs.replace(lhs.cbegin() + static_cast(index), std::move(rhs_val)); 47 | }); 48 | } 49 | 50 | static void merge_left(toml::table& lhs, toml::table&& rhs) 51 | { 52 | rhs.for_each( 53 | [&](const toml::key& rhs_key, auto&& rhs_val) 54 | { 55 | auto lhs_it = lhs.lower_bound(rhs_key); 56 | 57 | // rhs key not found in lhs - direct move 58 | if (lhs_it == lhs.cend() || lhs_it->first != rhs_key) 59 | { 60 | using rhs_type = std::remove_cv_t>; 61 | lhs.emplace_hint(lhs_it, rhs_key, std::move(rhs_val)); 62 | return; 63 | } 64 | 65 | // both children were the same container type - recurse into them 66 | if constexpr (toml::is_container) 67 | { 68 | using rhs_type = std::remove_cv_t>; 69 | if (auto lhs_child = lhs_it->second.as()) 70 | { 71 | merge_left(*lhs_child, std::move(rhs_val)); 72 | return; 73 | } 74 | } 75 | 76 | // replace lhs value with rhs 77 | lhs.insert_or_assign(rhs_key, std::move(rhs_val)); 78 | }); 79 | } 80 | } 81 | 82 | int main(int argc, char** argv) 83 | { 84 | const auto base_path = argc > 1 ? std::string_view{ argv[1] } : "merge_base.toml"sv; 85 | const auto overrides_path = argc > 2 ? std::string_view{ argv[2] } : "merge_overrides.toml"sv; 86 | 87 | toml::table tbl; 88 | try 89 | { 90 | tbl = toml::parse_file(base_path); 91 | merge_left(tbl, toml::parse_file(overrides_path)); 92 | } 93 | catch (const toml::parse_error& err) 94 | { 95 | std::cerr << err << "\n"; 96 | return 1; 97 | } 98 | 99 | std::cout << tbl << "\n"; 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /examples/toml_merger.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | 16.0 15 | {E467EB97-B066-4D38-B3DB-60961E3F96A1} 16 | 10.0 17 | 18 | 19 | 20 | Application 21 | true 22 | v143 23 | MultiByte 24 | 25 | 26 | Application 27 | false 28 | v143 29 | true 30 | MultiByte 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | Console 40 | 41 | 42 | 43 | ..\examples 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /examples/toml_to_json_transcoder.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of toml++ and is subject to the the terms of the MIT license. 2 | // Copyright (c) Mark Gillard 3 | // See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. 4 | // SPDX-License-Identifier: MIT 5 | 6 | // This example demonstrates how to use the toml::json_formatter to re-serialize TOML data as JSON. 7 | 8 | #include "examples.hpp" 9 | #include 10 | 11 | using namespace std::string_view_literals; 12 | 13 | int main(int argc, char** argv) 14 | { 15 | const auto path = argc > 1 ? std::string_view{ argv[1] } : ""sv; 16 | 17 | toml::table table; 18 | try 19 | { 20 | // read directly from stdin 21 | if (path == "-"sv || path.empty()) 22 | table = toml::parse(std::cin, "stdin"sv); 23 | 24 | // read from a file 25 | else 26 | table = toml::parse_file(argv[1]); 27 | } 28 | catch (const toml::parse_error& err) 29 | { 30 | std::cerr << err << "\n"; 31 | return 1; 32 | } 33 | 34 | std::cout << toml::json_formatter{ table } << "\n"; 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /examples/toml_to_json_transcoder.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | 16.0 15 | {BE34AA99-BEE6-4B50-B237-217E7C88FCB5} 16 | 10.0 17 | toml_to_json_transcoder 18 | 19 | 20 | 21 | Application 22 | true 23 | v143 24 | MultiByte 25 | 26 | 27 | Application 28 | false 29 | v143 30 | true 31 | MultiByte 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | Console 41 | 42 | 43 | 44 | ..\examples 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /fuzzing/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Utilized by OSSFuzz to build the harness(es) for continuous fuzz-testing 2 | # OSSFuzz defines the following environment variables, that this target relies upon: 3 | # CXX, CFLAGS, LIB_FUZZING_ENGINE, OUT 4 | cmake_minimum_required(VERSION 3.14) 5 | 6 | project(Fuzzer LANGUAGES CXX) 7 | 8 | include(../cmake/project-is-top-level.cmake) 9 | 10 | add_definitions(-DNDEBUG) # Do not want assertions 11 | 12 | if (DEFINED ENV{CFLAGS}) 13 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} $ENV{CFLAGS}") 14 | endif () 15 | if (DEFINED ENV{CXXFLAGS}) 16 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{CXXFLAGS}") 17 | endif () 18 | 19 | if(PROJECT_IS_TOP_LEVEL) 20 | find_package(tomlplusplus REQUIRED) 21 | endif() 22 | 23 | add_executable(toml_fuzzer toml_fuzzer.cpp) 24 | target_link_libraries(toml_fuzzer PRIVATE tomlplusplus::tomlplusplus $ENV{LIB_FUZZING_ENGINE}) 25 | target_compile_features(toml_fuzzer PRIVATE cxx_std_17) 26 | 27 | if (DEFINED ENV{OUT}) 28 | install(TARGETS toml_fuzzer DESTINATION $ENV{OUT}) 29 | else () 30 | message(WARNING "Cannot install if $OUT is not defined!") 31 | endif () -------------------------------------------------------------------------------- /fuzzing/build.sh: -------------------------------------------------------------------------------- 1 | cd $SRC/tomlplusplus 2 | mkdir -p build 3 | cmake -S . -B build -DBUILD_FUZZER=ON && cmake --build build --target install 4 | 5 | # Build the corpus using the existing toml files in the source 6 | mkdir -p corpus 7 | find $SRC/tomlplusplus -name "*.toml" -exec cp {} corpus \; 8 | zip -q -j $OUT/toml_fuzzer_seed_corpus.zip corpus/* 9 | -------------------------------------------------------------------------------- /fuzzing/toml_fuzzer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | enum class SerializationTest 7 | { 8 | NONE = 0, 9 | JSON, 10 | YAML, 11 | TOML, 12 | kMaxValue = TOML 13 | }; 14 | 15 | extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, const std::size_t size) 16 | { 17 | FuzzedDataProvider fdp{data, size}; 18 | try 19 | { 20 | const toml::table tbl = toml::parse(fdp.ConsumeRandomLengthString()); 21 | 22 | switch (fdp.ConsumeEnum()) 23 | { 24 | case SerializationTest::JSON: 25 | static_cast(toml::json_formatter{tbl}); 26 | break; 27 | case SerializationTest::YAML: 28 | static_cast(toml::yaml_formatter{tbl}); 29 | break; 30 | case SerializationTest::TOML: 31 | static_cast(toml::toml_formatter{tbl}); 32 | default: 33 | break; 34 | } 35 | } 36 | catch (const toml::parse_error&) 37 | { 38 | return -1; 39 | } 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /include/meson.build: -------------------------------------------------------------------------------- 1 | # This file is a part of toml++ and is subject to the the terms of the MIT license. 2 | # Copyright (c) Mark Gillard 3 | # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. 4 | # SPDX-License-Identifier: MIT 5 | 6 | include_dir = include_directories('.') 7 | 8 | if not is_subproject 9 | install_subdir('toml++', install_dir: get_option('includedir')) 10 | endif 11 | 12 | if not build_lib # header-only mode 13 | 14 | tomlplusplus_dep = declare_dependency(include_directories: include_dir) 15 | 16 | if not is_subproject 17 | import('pkgconfig').generate( 18 | name: meson.project_name(), 19 | description: 'Header-only TOML config file parser and serializer for C++', 20 | install_dir: get_option('datadir')/'pkgconfig', 21 | url: 'https://marzer.github.io/tomlplusplus' 22 | ) 23 | endif 24 | 25 | # cmake 26 | if get_option('generate_cmake_config') and not is_subproject and not is_devel 27 | cmake = import('cmake') 28 | # Can't use until Meson 0.62.0, see https://github.com/mesonbuild/meson/pull/9916 29 | # and https://github.com/marzer/tomlplusplus/issues/140 30 | #cmake.write_basic_package_version_file( 31 | # name: meson.project_name(), 32 | # version: meson.project_version(), 33 | # install_dir: get_option('datadir')/'cmake'/meson.project_name(), 34 | # arch_independent: true 35 | #) 36 | # In the meantime, install a pre-generated Package Version file 37 | configure_file( 38 | configuration: {'version': meson.project_version()}, 39 | input: '..'/'cmake'/'tomlplusplusConfigVersion.cmake.meson.in', 40 | output: 'tomlplusplusConfigVersion.cmake', 41 | install_dir: get_option('datadir')/'cmake'/meson.project_name() 42 | ) 43 | 44 | cmake.configure_package_config_file( 45 | name: meson.project_name(), 46 | input: '..'/'cmake'/'tomlplusplusConfig.cmake.meson.in', 47 | configuration: configuration_data({'includedir': get_option('includedir')}), 48 | install_dir: get_option('datadir')/'cmake'/meson.project_name(), 49 | ) 50 | endif 51 | 52 | endif 53 | -------------------------------------------------------------------------------- /include/toml++/impl/at_path.hpp: -------------------------------------------------------------------------------- 1 | //# This file is a part of toml++ and is subject to the the terms of the MIT license. 2 | //# Copyright (c) Mark Gillard 3 | //# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. 4 | // SPDX-License-Identifier: MIT 5 | #pragma once 6 | 7 | #include "forward_declarations.hpp" 8 | 9 | /// \cond 10 | TOML_IMPL_NAMESPACE_START 11 | { 12 | template 13 | using parse_path_callback = bool(TOML_CALLCONV*)(void*, T); 14 | 15 | TOML_NODISCARD 16 | bool TOML_CALLCONV parse_path(std::string_view, 17 | void*, 18 | parse_path_callback, 19 | parse_path_callback); 20 | } 21 | TOML_IMPL_NAMESPACE_END; 22 | /// \endcond 23 | 24 | TOML_NAMESPACE_START 25 | { 26 | /// \brief Returns a view of the node matching a fully-qualified "TOML path". 27 | /// 28 | /// \detail \cpp 29 | /// auto config = toml::parse(R"( 30 | /// 31 | /// [foo] 32 | /// bar = [ 0, 1, 2, [ 3 ], { kek = 4 } ] 33 | /// 34 | /// )"sv); 35 | /// 36 | /// std::cout << toml::at_path(config, "foo.bar[2]") << "\n"; 37 | /// std::cout << toml::at_path(config, "foo.bar[3][0]") << "\n"; 38 | /// std::cout << toml::at_path(config, "foo.bar[4].kek") << "\n"; 39 | /// \ecpp 40 | /// 41 | /// \out 42 | /// 2 43 | /// 3 44 | /// 4 45 | /// \eout 46 | /// 47 | /// 48 | /// \note Keys in paths are interpreted literally, so whitespace (or lack thereof) matters: 49 | /// \cpp 50 | /// toml::at_path(config, "foo.bar") // same as config["foo"]["bar"] 51 | /// toml::at_path(config, "foo. bar") // same as config["foo"][" bar"] 52 | /// toml::at_path(config, "foo..bar") // same as config["foo"][""]["bar"] 53 | /// toml::at_path(config, ".foo.bar") // same as config[""]["foo"]["bar"] 54 | /// \ecpp 55 | ///
56 | /// Additionally, TOML allows '.' (period) characters to appear in keys if they are quoted strings. 57 | /// This function makes no allowance for this, instead treating all period characters as sub-table delimiters. 58 | /// If you have periods in your table keys, first consider: 59 | /// 1. Not doing that 60 | /// 2. Using node_view::operator[] instead. 61 | /// 62 | /// \param root The root node from which the path will be traversed. 63 | /// \param path The "TOML path" to traverse. 64 | TOML_NODISCARD 65 | TOML_EXPORTED_FREE_FUNCTION 66 | node_view TOML_CALLCONV at_path(node & root, std::string_view path) noexcept; 67 | 68 | /// \brief Returns a const view of the node matching a fully-qualified "TOML path". 69 | /// 70 | /// \see #toml::at_path(node&, std::string_view) 71 | TOML_NODISCARD 72 | TOML_EXPORTED_FREE_FUNCTION 73 | node_view TOML_CALLCONV at_path(const node& root, std::string_view path) noexcept; 74 | 75 | #if TOML_ENABLE_WINDOWS_COMPAT 76 | 77 | /// \brief Returns a view of the node matching a fully-qualified "TOML path". 78 | /// 79 | /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled. 80 | /// 81 | /// \see #toml::at_path(node&, std::string_view) 82 | TOML_NODISCARD 83 | TOML_EXPORTED_FREE_FUNCTION 84 | node_view TOML_CALLCONV at_path(node & root, std::wstring_view path); 85 | 86 | /// \brief Returns a const view of the node matching a fully-qualified "TOML path". 87 | /// 88 | /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled. 89 | /// 90 | /// \see #toml::at_path(node&, std::string_view) 91 | TOML_NODISCARD 92 | TOML_EXPORTED_FREE_FUNCTION 93 | node_view TOML_CALLCONV at_path(const node& root, std::wstring_view path); 94 | 95 | #endif 96 | } 97 | TOML_NAMESPACE_END; 98 | -------------------------------------------------------------------------------- /include/toml++/impl/formatter.hpp: -------------------------------------------------------------------------------- 1 | //# This file is a part of toml++ and is subject to the the terms of the MIT license. 2 | //# Copyright (c) Mark Gillard 3 | //# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. 4 | // SPDX-License-Identifier: MIT 5 | #pragma once 6 | 7 | #include "preprocessor.hpp" 8 | #if TOML_ENABLE_FORMATTERS 9 | 10 | #include "forward_declarations.hpp" 11 | #include "print_to_stream.hpp" 12 | #include "header_start.hpp" 13 | /// \cond 14 | 15 | TOML_IMPL_NAMESPACE_START 16 | { 17 | struct formatter_constants 18 | { 19 | format_flags mandatory_flags; 20 | format_flags ignored_flags; 21 | 22 | std::string_view float_pos_inf; 23 | std::string_view float_neg_inf; 24 | std::string_view float_nan; 25 | 26 | std::string_view bool_true; 27 | std::string_view bool_false; 28 | }; 29 | 30 | struct formatter_config 31 | { 32 | format_flags flags; 33 | std::string_view indent; 34 | }; 35 | 36 | class TOML_EXPORTED_CLASS formatter 37 | { 38 | private: 39 | const node* source_; 40 | #if TOML_ENABLE_PARSER && !TOML_EXCEPTIONS 41 | const parse_result* result_; 42 | #endif 43 | const formatter_constants* constants_; 44 | formatter_config config_; 45 | size_t indent_columns_; 46 | format_flags int_format_mask_; 47 | std::ostream* stream_; // 48 | int indent_; // these are set in attach() 49 | bool naked_newline_; // 50 | 51 | protected: 52 | TOML_PURE_INLINE_GETTER 53 | const node& source() const noexcept 54 | { 55 | return *source_; 56 | } 57 | 58 | TOML_PURE_INLINE_GETTER 59 | std::ostream& stream() const noexcept 60 | { 61 | return *stream_; 62 | } 63 | 64 | TOML_PURE_INLINE_GETTER 65 | int indent() const noexcept 66 | { 67 | return indent_; 68 | } 69 | 70 | void indent(int level) noexcept 71 | { 72 | indent_ = level; 73 | } 74 | 75 | void increase_indent() noexcept 76 | { 77 | indent_++; 78 | } 79 | 80 | void decrease_indent() noexcept 81 | { 82 | indent_--; 83 | } 84 | 85 | TOML_PURE_INLINE_GETTER 86 | size_t indent_columns() const noexcept 87 | { 88 | return indent_columns_; 89 | } 90 | 91 | TOML_PURE_INLINE_GETTER 92 | bool indent_array_elements() const noexcept 93 | { 94 | return !!(config_.flags & format_flags::indent_array_elements); 95 | } 96 | 97 | TOML_PURE_INLINE_GETTER 98 | bool indent_sub_tables() const noexcept 99 | { 100 | return !!(config_.flags & format_flags::indent_sub_tables); 101 | } 102 | 103 | TOML_PURE_INLINE_GETTER 104 | bool literal_strings_allowed() const noexcept 105 | { 106 | return !!(config_.flags & format_flags::allow_literal_strings); 107 | } 108 | 109 | TOML_PURE_INLINE_GETTER 110 | bool multi_line_strings_allowed() const noexcept 111 | { 112 | return !!(config_.flags & format_flags::allow_multi_line_strings); 113 | } 114 | 115 | TOML_PURE_INLINE_GETTER 116 | bool real_tabs_in_strings_allowed() const noexcept 117 | { 118 | return !!(config_.flags & format_flags::allow_real_tabs_in_strings); 119 | } 120 | 121 | TOML_PURE_INLINE_GETTER 122 | bool unicode_strings_allowed() const noexcept 123 | { 124 | return !!(config_.flags & format_flags::allow_unicode_strings); 125 | } 126 | 127 | TOML_PURE_INLINE_GETTER 128 | bool terse_kvps() const noexcept 129 | { 130 | return !!(config_.flags & format_flags::terse_key_value_pairs); 131 | } 132 | 133 | TOML_EXPORTED_MEMBER_FUNCTION 134 | void attach(std::ostream& stream) noexcept; 135 | 136 | TOML_EXPORTED_MEMBER_FUNCTION 137 | void detach() noexcept; 138 | 139 | TOML_EXPORTED_MEMBER_FUNCTION 140 | void print_newline(bool force = false); 141 | 142 | TOML_EXPORTED_MEMBER_FUNCTION 143 | void print_indent(); 144 | 145 | TOML_EXPORTED_MEMBER_FUNCTION 146 | void print_unformatted(char); 147 | 148 | TOML_EXPORTED_MEMBER_FUNCTION 149 | void print_unformatted(std::string_view); 150 | 151 | TOML_EXPORTED_MEMBER_FUNCTION 152 | void print_string(std::string_view str, 153 | bool allow_multi_line = true, 154 | bool allow_bare = false, 155 | bool allow_literal_whitespace = true); 156 | 157 | TOML_EXPORTED_MEMBER_FUNCTION 158 | void print(const value&); 159 | 160 | TOML_EXPORTED_MEMBER_FUNCTION 161 | void print(const value&); 162 | 163 | TOML_EXPORTED_MEMBER_FUNCTION 164 | void print(const value&); 165 | 166 | TOML_EXPORTED_MEMBER_FUNCTION 167 | void print(const value&); 168 | 169 | TOML_EXPORTED_MEMBER_FUNCTION 170 | void print(const value&); 171 | 172 | TOML_EXPORTED_MEMBER_FUNCTION 173 | void print(const value