support for upcoming TOML v1.0.0 release
see https://github.com/toml-lang/toml/issues/698 for info about TOML v1.0.0 also: - fixed some parser error-paths not returning early enough when exceptions were disabled - added more specific error messages for parsing errors relating to prohibited codepoints - added compilation speed improvements (particularly for platforms lacking floating-point `std::to_chars`) - added many minor documentation improvements - added additional tests
1
.gitattributes
vendored
@ -18,3 +18,4 @@
|
||||
*.css text encoding=UTF-8 eol=lf
|
||||
meson.build text encoding=UTF-8 eol=lf
|
||||
Doxyfile text encoding=UTF-8 eol=lf
|
||||
Doxyfile-mcss text encoding=UTF-8 eol=lf
|
||||
|
80
README.md
@ -1,13 +1,15 @@
|
||||
![banner](docs/tomlplusplus-banner-small.png)
|
||||
[![C++](https://img.shields.io/badge/c%2B%2B-17%2C%2020-informational)][cpp_compilers]
|
||||
[![TOML](https://img.shields.io/badge/TOML-v0.5.0-informational)][v0.5.0]
|
||||
[![MIT license](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
|
||||
[![Releases](https://img.shields.io/github/release/marzer/tomlplusplus.svg)](https://github.com/marzer/tomlplusplus/releases)
|
||||
[![Mentioned in Awesome C++](https://awesome.re/mentioned-badge.svg)](https://github.com/fffaraz/awesome-cpp)
|
||||
[![CircleCI](https://circleci.com/gh/marzer/tomlplusplus.svg?style=shield)](https://circleci.com/gh/marzer/tomlplusplus)
|
||||
====
|
||||
[![banner](docs/banner_small.png)][homepage]
|
||||
[![Releases](https://img.shields.io/github/v/release/marzer/tomlplusplus?style=flat-square)](https://github.com/marzer/tomlplusplus/releases)
|
||||
[![C++17](docs/badge-C++17.svg)][cpp_compilers]
|
||||
[![C++20](docs/badge-C++20.svg)][cpp_compilers]
|
||||
[![TOML](docs/badge-TOML.svg)][v1.0.0-rc.1]
|
||||
[![MIT license](docs/badge-license-MIT.svg)](./LICENSE)
|
||||
[![CircleCI](https://img.shields.io/circleci/build/github/marzer/tomlplusplus?label=circle%20ci&logo=circleci&logoColor=white&style=flat-square)](https://circleci.com/gh/marzer/tomlplusplus)
|
||||
[![Mentioned in Awesome C++](docs/badge-awesome.svg)](https://github.com/fffaraz/awesome-cpp)
|
||||
====
|
||||
|
||||
- Header-only
|
||||
- [TOML v0.5.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.5.0.md), plus optional support for some [unreleased TOML language features]
|
||||
- [TOML v1.0.0-rc.1], plus optional support for some [unreleased TOML language features]
|
||||
- C++17 (plus some C++20 features where available, e.g. experimental support for char8_t strings)
|
||||
- Proper UTF-8 handling (incl. BOM)
|
||||
- Works with or without exceptions
|
||||
@ -24,7 +26,7 @@ Given a TOML file `configuration.toml` containing the following:
|
||||
```toml
|
||||
[library]
|
||||
name = "toml++"
|
||||
authors = ["Mark Gillard <mark@notarealwebsite.com>"]
|
||||
authors = ["Mark Gillard <mark.gillard@outlook.com.au>"]
|
||||
|
||||
[dependencies]
|
||||
cpp = 17
|
||||
@ -69,19 +71,25 @@ You'll find some more code examples in the `examples` directory, and plenty more
|
||||
<br>
|
||||
|
||||
# Adding toml++ to your project
|
||||
`toml++` comes in two flavours: Regular and Single-header.
|
||||
`toml++` comes in two flavours: Single-header and Regular. The API is the same for both.
|
||||
|
||||
### Regular mode
|
||||
1. Add `tomlplusplus/include` to your include paths
|
||||
2. `#include <toml++/toml.h>`
|
||||
|
||||
### Single-header mode
|
||||
## 🍦 Single-header flavour
|
||||
1. Drop `toml.hpp` wherever you like in your source tree
|
||||
2. There is no step two
|
||||
|
||||
The API is the same regardless of how you consume the library.
|
||||
## 🍨 Regular flavour
|
||||
1. Add `tomlplusplus/include` to your include paths
|
||||
2. `#include <toml++/toml.h>`
|
||||
|
||||
### Configuration
|
||||
## _"What about build system X, or package manager Y?"_
|
||||
Currently there's support for use as a meson submodule, which I _think_ means it can be used with Conan. That's the
|
||||
extent of my knowledge in this area; clearly an area of opportunity! If you would like me to add support for a
|
||||
particular build system or package manager please let me know by making a [feature request]. Better still, if you have
|
||||
the skills and motivation to add support yourself, I'd welcome a pull request with a smile and open arms!
|
||||
|
||||
<br>
|
||||
|
||||
# Configuration
|
||||
A number of configurable options are exposed in the form of preprocessor `#defines`. Most likely you
|
||||
won't need to mess with these at all, but if you do, set them before including toml++.
|
||||
|
||||
@ -101,35 +109,39 @@ won't need to mess with these at all, but if you do, set them before including t
|
||||
| `TOML_UNDEF_MACROS` | boolean | `1` | `#undefs` the library's internal macros at the end of the header. |
|
||||
| `TOML_UNRELEASED_FEATURES` | boolean | `1` | Enables support for [unreleased TOML language features] not yet part of a [numbered version]. |
|
||||
|
||||
_A number of these have ABI implications; the library uses inline namespaces to prevent you from accidentally linking incompatible combinations together._
|
||||
> ℹ _A number of these have ABI implications; the library uses inline namespaces to prevent you from accidentally
|
||||
linking incompatible combinations together._
|
||||
|
||||
<br>
|
||||
|
||||
# TOML Language Support
|
||||
At any given time `toml++` aims to implement whatever the [numbered version] of TOML is, with the
|
||||
At any given time `toml++` aims to implement whatever the [most recently-released version] of TOML is, with the
|
||||
addition of unreleased features from the [TOML master] and some sane cherry-picks from the
|
||||
[TOML issues list] where the discussion strongly indicates inclusion in a near-future release.
|
||||
|
||||
The library advertises the most recent numbered language version it fully supports via the preprocessor
|
||||
defines `TOML_LANG_MAJOR`, `TOML_LANG_MINOR` and `TOML_LANG_PATCH`.
|
||||
|
||||
### **🔸Unreleased TOML features:**
|
||||
- [#356]: Allow leading zeros in the exponent part of a float
|
||||
## 🔶 **Unreleased features:**
|
||||
- [#516]: Allow newlines and trailing commas in inline tables
|
||||
- [#562]: Allow hex floatingpoint values
|
||||
- [#567]: Clarify that control characters are not permitted in comments
|
||||
- [#571]: Allow raw tabs inside strings
|
||||
- [#562]: Allow hex floating-point values
|
||||
- [#644]: Support `+` in key names
|
||||
- [#665]: Make arrays heterogeneous
|
||||
- [#671]: Local time of day format should support `09:30` as opposed to `09:30:00`
|
||||
- [#687]: Relax bare key restrictions to allow additional unicode characters
|
||||
- [#709]: Include an \xHH escape code sequence
|
||||
|
||||
_These can be disabled (and thus strict [TOML v0.5.0] compliance enforced) by specifying
|
||||
> ℹ _Unreleased features can be disabled (and thus strict [TOML v1.0.0-rc.1] compliance enforced) by specifying
|
||||
`TOML_UNRELEASED_FEATURES = 0` (see [Configuration](#Configuration))._
|
||||
|
||||
### **🔹TOML v0.5.0 and earlier:**
|
||||
- All features supported.
|
||||
## 🟢 **TOML v1.0.0-rc.1:**
|
||||
All features supported, including:
|
||||
- [#356]: Allow leading zeros in the exponent part of a float
|
||||
- [#567]: Control characters are not permitted in comments
|
||||
- [#571]: Allow raw tabs inside strings
|
||||
- [#665]: Make arrays heterogeneous
|
||||
|
||||
## 🟢 **TOML v0.5.0:**
|
||||
All features supported.
|
||||
|
||||
<br>
|
||||
|
||||
@ -158,18 +170,20 @@ though you're welcome to reach out via other means. In order of likely response
|
||||
|
||||
|
||||
[API documentation]: https://marzer.github.io/tomlplusplus/
|
||||
[homepage]: https://marzer.github.io/tomlplusplus/
|
||||
[unreleased TOML language features]: #unreleased-toml-features
|
||||
[numbered version]: https://github.com/toml-lang/toml/releases
|
||||
[most recently-released version]: https://github.com/toml-lang/toml/releases
|
||||
[char8_t]: https://en.cppreference.com/w/cpp/keyword/char8_t
|
||||
[TOML master]: https://github.com/toml-lang/toml/blob/master/README.md
|
||||
[TOML issues list]: https://github.com/toml-lang/toml/issues
|
||||
[TOML v0.5.0]: https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.5.0.md
|
||||
[v0.5.0]: https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.5.0.md
|
||||
[TOML v1.0.0-rc.1]: https://github.com/toml-lang/toml/blob/master/README.md
|
||||
[v1.0.0-rc.1]: https://github.com/toml-lang/toml/blob/master/README.md
|
||||
[CONTRIBUTING]: ./CONTRIBUTING.md
|
||||
[LICENSE]: ./LICENSE
|
||||
[Flexible and Economical UTF-8 Decoder]: http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
|
||||
[cpp_compilers]: https://en.cppreference.com/w/cpp/compiler_support
|
||||
[reporting issues]: https://github.com/marzer/tomlplusplus/issues
|
||||
[reporting issues]: https://github.com/marzer/tomlplusplus/issues/new/choose
|
||||
[feature request]: https://github.com/marzer/tomlplusplus/issues/new/choose
|
||||
[issues]: https://github.com/marzer/tomlplusplus/issues
|
||||
[#356]: https://github.com/toml-lang/toml/issues/356
|
||||
[#516]: https://github.com/toml-lang/toml/issues/516
|
||||
|
@ -7,7 +7,7 @@ DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = toml++
|
||||
PROJECT_NUMBER =
|
||||
PROJECT_BRIEF = TOML for modern C++
|
||||
PROJECT_LOGO = tomlplusplus-logo.png
|
||||
PROJECT_LOGO = logo.png
|
||||
OUTPUT_DIRECTORY = ./
|
||||
CREATE_SUBDIRS = NO
|
||||
ALLOW_UNICODE_NAMES = NO
|
||||
|
@ -7,10 +7,15 @@ HTML_EXTRA_STYLESHEET = \
|
||||
|
||||
HTML_EXTRA_FILES = \
|
||||
tomlplusplus.js \
|
||||
tomlplusplus-logo.png \
|
||||
tomlplusplus-banner.png \
|
||||
tomlplusplus-banner-small.png \
|
||||
github-icon.png
|
||||
logo.png \
|
||||
banner_small.png \
|
||||
github-icon.png \
|
||||
badge-awesome.svg \
|
||||
badge-C++17.svg \
|
||||
badge-C++20.svg \
|
||||
badge-license-MIT.svg \
|
||||
badge-TOML.svg
|
||||
|
||||
|
||||
##! M_THEME_COLOR = #22272e
|
||||
##! M_LINKS_NAVBAR1 = \
|
||||
@ -25,6 +30,6 @@ HTML_EXTRA_FILES = \
|
||||
##! <a target="_blank" href="https://github.com/marzer/tomlplusplus/issues">Report an issue</a> \
|
||||
##! <br><br>Documentation generated using <a href="https://mcss.mosra.cz/">m.css</a>
|
||||
##! M_HTML_HEADER = <meta name="google-site-verification" content="gbtcNgKlNiPSMKkYMw4zWFVWGPH_oU93m9n_-nb4qK8" />\
|
||||
##! <meta name="description" content="TOML parser and serializer for C++17, C++20, and whatever comes after.">\
|
||||
##! <meta name="description" content="Header-only TOML config file parser and serializer for modern C++.">\
|
||||
##! <script src="tomlplusplus.js"></script>
|
||||
##! M_FAVICON = favicon.ico
|
||||
|
1
docs/badge-C++17.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="125" height="20"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h76v20H0z"/><path fill="#007ec6" d="M76 0h49v20H76z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"><image x="5" y="3" width="14" height="14" xlink:href="data:image/svg+xml;base64,PHN2ZyBmaWxsPSJ3aGl0ZXNtb2tlIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+QysrIGljb248L3RpdGxlPjxwYXRoIGQ9Ik0yMi4zOTMgNmMtLjE2Ny0uMjktLjM5OC0uNTQzLS42NTItLjY5TDEyLjkyNS4yMmMtLjUwOC0uMjkzLTEuMzM5LS4yOTMtMS44NDcgMEwyLjI2IDUuMzFjLS41MDguMjkzLS45MjMgMS4wMTMtLjkyMyAxLjZ2MTAuMThjMCAuMjk0LjEwNC42Mi4yNzEuOTEuMTY3LjI5LjM5OC41NDMuNjUyLjY4OWw4LjgxNiA1LjA5MWMuNTA4LjI5MyAxLjMzOS4yOTMgMS44NDcgMGw4LjgxNi01LjA5MWMuMjU0LS4xNDYuNDg1LS4zOTkuNjUyLS42ODlzLjI3MS0uNjE2LjI3MS0uOTFWNi45MWMuMDAyLS4yOTQtLjEwMi0uNjItLjI2OS0uOTF6TTEyIDE5LjEwOWMtMy45MiAwLTcuMTA5LTMuMTg5LTcuMTA5LTcuMTA5UzguMDggNC44OTEgMTIgNC44OTFhNy4xMzMgNy4xMzMgMCAwIDEgNi4xNTYgMy41NTJsLTMuMDc2IDEuNzgxQTMuNTY3IDMuNTY3IDAgMCAwIDEyIDguNDQ1Yy0xLjk2IDAtMy41NTQgMS41OTUtMy41NTQgMy41NTVTMTAuMDQgMTUuNTU1IDEyIDE1LjU1NWEzLjU3IDMuNTcgMCAwIDAgMy4wOC0xLjc3OGwzLjA3NyAxLjc4QTcuMTM1IDcuMTM1IDAgMCAxIDEyIDE5LjEwOXptNy4xMDktNi43MTRoLS43OXYuNzloLS43OXYtLjc5aC0uNzl2LS43OWguNzl2LS43OWguNzl2Ljc5aC43OXYuNzl6bTIuOTYyIDBoLS43OXYuNzloLS43OXYtLjc5aC0uNzg5di0uNzloLjc4OXYtLjc5aC43OXYuNzloLjc5di43OXoiLz48L3N2Zz4="/> <text x="475" y="140" transform="scale(.1)" textLength="490">standard</text><text x="995" y="140" transform="scale(.1)" textLength="390">C++17</text></g> </svg>
|
After Width: | Height: | Size: 1.6 KiB |
1
docs/badge-C++20.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="125" height="20"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h76v20H0z"/><path fill="#007ec6" d="M76 0h49v20H76z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"><image x="5" y="3" width="14" height="14" xlink:href="data:image/svg+xml;base64,PHN2ZyBmaWxsPSJ3aGl0ZXNtb2tlIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+QysrIGljb248L3RpdGxlPjxwYXRoIGQ9Ik0yMi4zOTMgNmMtLjE2Ny0uMjktLjM5OC0uNTQzLS42NTItLjY5TDEyLjkyNS4yMmMtLjUwOC0uMjkzLTEuMzM5LS4yOTMtMS44NDcgMEwyLjI2IDUuMzFjLS41MDguMjkzLS45MjMgMS4wMTMtLjkyMyAxLjZ2MTAuMThjMCAuMjk0LjEwNC42Mi4yNzEuOTEuMTY3LjI5LjM5OC41NDMuNjUyLjY4OWw4LjgxNiA1LjA5MWMuNTA4LjI5MyAxLjMzOS4yOTMgMS44NDcgMGw4LjgxNi01LjA5MWMuMjU0LS4xNDYuNDg1LS4zOTkuNjUyLS42ODlzLjI3MS0uNjE2LjI3MS0uOTFWNi45MWMuMDAyLS4yOTQtLjEwMi0uNjItLjI2OS0uOTF6TTEyIDE5LjEwOWMtMy45MiAwLTcuMTA5LTMuMTg5LTcuMTA5LTcuMTA5UzguMDggNC44OTEgMTIgNC44OTFhNy4xMzMgNy4xMzMgMCAwIDEgNi4xNTYgMy41NTJsLTMuMDc2IDEuNzgxQTMuNTY3IDMuNTY3IDAgMCAwIDEyIDguNDQ1Yy0xLjk2IDAtMy41NTQgMS41OTUtMy41NTQgMy41NTVTMTAuMDQgMTUuNTU1IDEyIDE1LjU1NWEzLjU3IDMuNTcgMCAwIDAgMy4wOC0xLjc3OGwzLjA3NyAxLjc4QTcuMTM1IDcuMTM1IDAgMCAxIDEyIDE5LjEwOXptNy4xMDktNi43MTRoLS43OXYuNzloLS43OXYtLjc5aC0uNzl2LS43OWguNzl2LS43OWguNzl2Ljc5aC43OXYuNzl6bTIuOTYyIDBoLS43OXYuNzloLS43OXYtLjc5aC0uNzg5di0uNzloLjc4OXYtLjc5aC43OXYuNzloLjc5di43OXoiLz48L3N2Zz4="/> <text x="475" y="140" transform="scale(.1)" textLength="490">standard</text><text x="995" y="140" transform="scale(.1)" textLength="390">C++20</text></g> </svg>
|
After Width: | Height: | Size: 1.6 KiB |
1
docs/badge-TOML.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="112" height="20"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h41v20H0z"/><path fill="#007ec6" d="M41 0h71v20H41z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="215" y="140" transform="scale(.1)" textLength="310">TOML</text><text x="755" y="140" transform="scale(.1)" textLength="610">v1.0.0 rc.1</text></g> </svg>
|
After Width: | Height: | Size: 489 B |
1
docs/badge-awesome.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="110" height="20" viewBox="0 0 110 20" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><title>Mentioned in an Awesome list</title><defs><path d="M53.57 3.52h-4.446V7h.648V4.3c0-.072.06-.132.132-.132h1.38c.072 0 .132.06.132.132V7h.648V4.3c0-.072.06-.132.132-.132h1.374c.078 0 .138.06.138.132V7h.642V4.3a.778.778 0 0 0-.78-.78zm4.704 0c.432 0 .78.348.78.78v1.284h-2.892v.636c0 .072.06.132.132.132h2.76V7h-2.76a.778.778 0 0 1-.78-.78V4.3c0-.432.348-.78.78-.78h1.98zm-2.112 1.416h2.244V4.3a.133.133 0 0 0-.132-.132h-1.98a.133.133 0 0 0-.132.132v.636zm6.822-1.416h-2.76V7h.648V4.3c0-.072.06-.132.132-.132h1.98c.072 0 .132.06.132.132V7h.648V4.3a.778.778 0 0 0-.78-.78zm4.026.648V3.52h-1.428V2.38h-.648v3.84c0 .432.348.78.78.78h1.296v-.648h-1.296a.133.133 0 0 1-.132-.132V4.168h1.428zM67.928 7h.648V3.52h-.648V7zm0-4.62v.648h.648V2.38h-.648zm2.562 1.14h1.98c.432 0 .78.348.78.78v1.92c0 .432-.348.78-.78.78h-1.98a.778.778 0 0 1-.78-.78V4.3c0-.432.348-.78.78-.78zm1.98.648h-1.98a.133.133 0 0 0-.132.132v1.92c0 .072.06.132.132.132h1.98c.072 0 .132-.06.132-.132V4.3a.133.133 0 0 0-.132-.132zm4.62-.648h-2.76V7h.648V4.3c0-.072.06-.132.132-.132h1.98c.072 0 .132.06.132.132V7h.648V4.3a.778.778 0 0 0-.78-.78zm4.698 0c.432 0 .78.348.78.78v1.284h-2.892v.636c0 .072.06.132.132.132h2.76V7h-2.76a.778.778 0 0 1-.78-.78V4.3c0-.432.348-.78.78-.78h1.98zm-2.112 1.416h2.244V4.3a.133.133 0 0 0-.132-.132h-1.98a.133.133 0 0 0-.132.132v.636zm6.768-2.556h.648V7h-2.76a.778.778 0 0 1-.78-.78V4.3c0-.432.348-.78.78-.78h2.112V2.38zm-2.112 3.972h1.98c.072 0 .132-.06.132-.132V4.3a.133.133 0 0 0-.132-.132h-1.98a.133.133 0 0 0-.132.132v1.92c0 .072.06.132.132.132zM90.548 7h.648V3.52h-.648V7zm0-4.62v.648h.648V2.38h-.648zm4.56 1.14h-2.76V7h.648V4.3c0-.072.06-.132.132-.132h1.98c.072 0 .132.06.132.132V7h.648V4.3a.778.778 0 0 0-.78-.78z" id="a"/></defs><g fill="none" fill-rule="evenodd"><g fill-rule="nonzero"><path fill="#CCA6C4" d="M0 0h34v20H0z"/><path fill="#494368" d="M34 0h77v20H34z"/></g><g fill-rule="nonzero"><path d="M46.97 9.92c.42 0 .75.13 1.05.4.28.27.43.59.43.98v4.79h-5.24c-.42 0-.77-.13-1.05-.4a1.31 1.31 0 0 1-.43-.98v-2.27h5.5v-1.15c0-.07-.03-.12-.08-.16a.284.284 0 0 0-.17-.07h-5.24V9.92h5.23zm.26 5.02v-1.36h-4.26v1.13c0 .07.03.12.08.16.05.04.11.07.17.07h4.01zm11.86-5.02h1.3l-2.49 6.17h-1l-2.22-4.59-2.1 4.59-.03-.01.01.01h-1l-2.6-6.17h1.3l1.79 4.09 1.91-4.09h1.4l2.02 4.09 1.71-4.09zm6.95 0c.42 0 .77.13 1.05.4s.43.59.43.98v2.27h-5.5v1.13c0 .07.03.12.08.16.05.04.11.07.17.07h5.24v1.14h-5.24c-.42 0-.77-.13-1.05-.4a1.31 1.31 0 0 1-.43-.98v-3.4c0-.38.15-.71.43-.98s.63-.4 1.05-.4h3.77v.01zm-4.01 2.5h4.26v-1.13c0-.07-.03-.12-.08-.16a.284.284 0 0 0-.17-.07h-3.77a.26.26 0 0 0-.17.07c-.05.04-.08.11-.08.16v1.13h.01zm13.35-1.13v.23h-1.22v-.23c0-.07-.03-.12-.08-.16a.284.284 0 0 0-.17-.07h-3.77a.26.26 0 0 0-.17.07c-.05.04-.08.11-.08.16v.9c0 .07.03.12.08.16.05.04.11.07.17.07h3.77c.42 0 .75.13 1.05.4.28.27.43.59.43.98v.89c0 .38-.15.71-.43.98s-.63.4-1.05.4h-3.77c-.42 0-.77-.13-1.05-.4a1.31 1.31 0 0 1-.43-.98v-.23h1.24v.23c0 .07.03.12.08.16.05.04.11.07.17.07h3.77c.07 0 .12-.03.17-.07.05-.04.08-.11.08-.16v-.89c0-.07-.03-.12-.08-.16a.284.284 0 0 0-.17-.07h-3.77c-.42 0-.77-.13-1.05-.4a1.31 1.31 0 0 1-.43-.98v-.9c0-.38.15-.71.43-.98s.63-.4 1.05-.4h3.77c.42 0 .75.13 1.05.4.27.28.41.61.41.98zm2.6-1.37h3.77c.42 0 .77.13 1.05.4s.43.59.43.98v3.4c0 .38-.15.71-.43.98s-.63.4-1.05.4h-3.77c-.42 0-.77-.13-1.05-.4a1.31 1.31 0 0 1-.43-.98v-3.41c0-.38.15-.71.43-.98.3-.26.65-.39 1.05-.39zm3.77 1.14h-3.77a.26.26 0 0 0-.17.07c-.05.04-.08.11-.08.16v3.4c0 .07.03.12.08.16.05.04.11.07.17.07h3.77c.07 0 .12-.03.17-.07.05-.04.08-.11.08-.16v-3.4c0-.07-.03-.12-.08-.16a.241.241 0 0 0-.17-.07zm11.12-1.14c.42 0 .75.13 1.05.4.28.27.43.59.43.98v4.79h-1.22v-4.8c0-.07-.03-.12-.08-.16a.294.294 0 0 0-.19-.07h-2.61a.26.26 0 0 0-.17.07c-.05.04-.08.11-.08.16v4.79h-1.24v-4.79c0-.07-.03-.12-.08-.16a.284.284 0 0 0-.17-.07h-2.62a.26.26 0 0 0-.17.07c-.05.04-.08.11-.08.16v4.79H84.4V9.92h8.47zm7.92 0c.42 0 .77.13 1.05.4s.43.59.43.98v2.27h-5.5v1.13c0 .07.03.12.08.16.05.04.11.07.17.07h5.24v1.14h-5.24c-.42 0-.77-.13-1.05-.4a1.31 1.31 0 0 1-.43-.98v-3.4c0-.38.15-.71.43-.98s.63-.4 1.05-.4h3.77v.01zm-4.02 2.5h4.26v-1.13c0-.07-.03-.12-.08-.16a.284.284 0 0 0-.17-.07h-3.77a.26.26 0 0 0-.17.07c-.05.04-.08.11-.08.16v1.13h.01z" fill="#FFF"/></g><use fill-opacity=".9" fill="#FFF" xlink:href="#a"/><g fill-rule="nonzero"><path d="M26.57 9.76l-4.91-4.5-.69.75 4.09 3.75H8.94l4.09-3.75-.69-.75-4.91 4.5v2.97c0 1.34 1.29 2.43 2.88 2.43h3.03c1.59 0 2.88-1.09 2.88-2.43v-1.95h1.57v1.95c0 1.34 1.29 2.43 2.88 2.43h3.03c1.59 0 2.88-1.09 2.88-2.43l-.01-2.97z" fill="#DDA4CA"/><path d="M26.57 9.34l-4.91-4.5-.69.75 4.09 3.75H8.94l4.09-3.75-.69-.75-4.91 4.5v2.97c0 1.34 1.29 2.43 2.88 2.43h3.03c1.59 0 2.88-1.09 2.88-2.43v-1.95h1.57v1.95c0 1.34 1.29 2.43 2.88 2.43h3.03c1.59 0 2.88-1.09 2.88-2.43l-.01-2.97z" fill="#261120"/></g></g></svg>
|
After Width: | Height: | Size: 4.8 KiB |
1
docs/badge-license-MIT.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="78" height="20"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h47v20H0z"/><path fill="purple" d="M47 0h31v20H47z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="245" y="140" transform="scale(.1)" textLength="370">license</text><text x="615" y="140" transform="scale(.1)" textLength="210">MIT</text></g> </svg>
|
After Width: | Height: | Size: 482 B |
BIN
docs/banner.ai
Normal file
BIN
docs/banner_large.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
docs/banner_small.png
Normal file
After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 11 KiB |
@ -193,10 +193,12 @@ pre.m-code + pre.m-console span
|
||||
.gh-badges
|
||||
{
|
||||
padding-bottom: 0.75rem;
|
||||
margin-left: -0.9rem;
|
||||
margin-right: -0.9rem;
|
||||
}
|
||||
.gh-badges a
|
||||
{
|
||||
margin-right: 0.5rem;
|
||||
margin-right: 0.3rem;
|
||||
}
|
||||
|
||||
/* page category subheading ("module" etc) */
|
||||
@ -204,3 +206,14 @@ h1 span.m-thin
|
||||
{
|
||||
color: #747474;
|
||||
}
|
||||
|
||||
/* banner on index page */
|
||||
main > article > .m-container.m-container-inflatable > .m-row > div.m-col-l-10.m-push-l-1 > img.m-image
|
||||
{
|
||||
border-color: #405363;
|
||||
border-style: solid;
|
||||
border-width: 0.1rem;
|
||||
margin-left: -1rem;
|
||||
margin-right: -1rem;
|
||||
max-width: calc(100% + 2rem);
|
||||
}
|
||||
|
@ -30,12 +30,13 @@
|
||||
#include "toml_array_impl.h"
|
||||
#include "toml_table_impl.h"
|
||||
#include "toml_parser_impl.h"
|
||||
#include "toml_default_formatter_impl.h"
|
||||
|
||||
#endif
|
||||
|
||||
// macro hygiene
|
||||
#if TOML_UNDEF_MACROS
|
||||
#undef TOML_USE_STREAMS_FOR_FLOATS
|
||||
#undef TOML_FLOATING_POINT_CHARCONV
|
||||
#undef TOML_GNU_ATTR
|
||||
#undef TOML_PUSH_WARNINGS
|
||||
#undef TOML_DISABLE_SWITCH_WARNINGS
|
||||
@ -60,7 +61,7 @@
|
||||
#undef TOML_LANG_EFFECTIVE_VERSION
|
||||
#undef TOML_LANG_HIGHER_THAN
|
||||
#undef TOML_LANG_AT_LEAST
|
||||
#undef TOML_LANG_EXACTLY
|
||||
#undef TOML_LANG_UNRELEASED
|
||||
#undef TOML_STRING_PREFIX_1
|
||||
#undef TOML_STRING_PREFIX
|
||||
#undef TOML_UNDEF_MACROS
|
||||
@ -74,19 +75,18 @@
|
||||
#undef TOML_TRIVIAL_ABI
|
||||
#undef TOML_ABI_NAMESPACES
|
||||
#undef TOML_PARSER_TYPENAME
|
||||
#undef TOML_HAS_API_ANNOTATION
|
||||
#endif
|
||||
|
||||
/// \mainpage toml++
|
||||
///
|
||||
/// \image html tomlplusplus-banner-small.png width=1280px
|
||||
/// \image html banner_small.png width=1280px
|
||||
///
|
||||
/// \tableofcontents
|
||||
///
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// \section mainpage-features Features
|
||||
/// - [TOML v0.5.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.5.0.md), plus optional support for some
|
||||
/// - [TOML v1.0.0-rc.1](https://github.com/toml-lang/toml/blob/master/README.md), plus optional support for some
|
||||
/// unreleased TOML features
|
||||
/// - C++17 (plus some C++20 features where available, e.g. experimental support for char8_t strings)
|
||||
/// - Proper UTF-8 handling (incl. BOM)
|
||||
@ -137,10 +137,9 @@
|
||||
/// catch (const toml::parse_error& err)
|
||||
/// {
|
||||
/// std::cerr
|
||||
/// << "Error parsing file '"sv << *err.source().path
|
||||
/// << "':\n"sv << err.description()
|
||||
/// << "\n ("sv << err.source().begin << ")"sv
|
||||
/// << std::endl;
|
||||
/// << "Error parsing file '" << *err.source().path
|
||||
/// << "':\n" << err.description()
|
||||
/// << "\n (" << err.source().begin << ")\n";
|
||||
/// return 1;
|
||||
/// }
|
||||
///
|
||||
@ -164,10 +163,9 @@
|
||||
/// if (!tbl)
|
||||
/// {
|
||||
/// std::cerr
|
||||
/// << "Error parsing file '"sv << *tbl.error().source().path
|
||||
/// << "':\n"sv << tbl.error().description()
|
||||
/// << "\n ("sv << tbl.error().source().begin << ")"sv
|
||||
/// << std::endl;
|
||||
/// << "Error parsing file '" << *tbl.error().source().path
|
||||
/// << "':\n" << tbl.error().description()
|
||||
/// << "\n (" << tbl.error().source().begin << ")\n";
|
||||
/// return 1;
|
||||
/// }
|
||||
///
|
||||
@ -184,7 +182,7 @@
|
||||
/// }
|
||||
/// catch (const toml::parse_error & err)
|
||||
/// {
|
||||
/// std::cerr << "Parsing failed:\n"sv << err << std::endl;
|
||||
/// std::cerr << "Parsing failed:\n" << err << "\n";
|
||||
/// return 1;
|
||||
/// }
|
||||
/// \ecpp
|
||||
@ -220,7 +218,7 @@
|
||||
/// static constexpr auto source = R"(
|
||||
/// [library]
|
||||
/// name = "toml++"
|
||||
/// authors = ["Mark Gillard <mark@notarealwebsite.com>"]
|
||||
/// authors = ["Mark Gillard <mark.gillard@outlook.com.au>"]
|
||||
///
|
||||
/// [dependencies]
|
||||
/// cpp = 17
|
||||
@ -229,14 +227,14 @@
|
||||
/// // parse directly from a string view:
|
||||
/// {
|
||||
/// auto tbl = toml::parse(source);
|
||||
/// std::cout << tbl << std::endl;
|
||||
/// std::cout << tbl << "\n";
|
||||
/// }
|
||||
///
|
||||
/// // parse from a string stream:
|
||||
/// {
|
||||
/// std::stringstream ss{ std::string{ source } };
|
||||
/// auto tbl = toml::parse(ss);
|
||||
/// std::cout << tbl << std::endl;
|
||||
/// std::cout << tbl << "\n";
|
||||
/// }
|
||||
///
|
||||
/// return 0;
|
||||
@ -284,9 +282,9 @@
|
||||
///
|
||||
/// // get a view of the element 'numbers'
|
||||
/// auto numbers = tbl["numbers"];
|
||||
/// std::cout << "table has 'numbers': "sv << !!numbers << std::endl;
|
||||
/// std::cout << "numbers is a: "sv << numbers.type() << std::endl;
|
||||
/// std::cout << "numbers: "sv << numbers << std::endl;
|
||||
/// std::cout << "table has 'numbers': " << !!numbers << "\n";
|
||||
/// std::cout << "numbers is a: " << numbers.type() << "\n";
|
||||
/// std::cout << "numbers: " << numbers << "\n";
|
||||
///
|
||||
/// // get the underlying array object to do some more advanced stuff
|
||||
/// if (auto arr = numbers.as_array())
|
||||
@ -306,15 +304,15 @@
|
||||
/// // arrays are very similar to std::vector
|
||||
/// arr->push_back(7);
|
||||
/// arr->emplace_back<toml::array>(8, 9);
|
||||
/// std::cout << "numbers: "sv << numbers << std::endl;
|
||||
/// std::cout << "numbers: " << numbers << "\n";
|
||||
/// }
|
||||
///
|
||||
/// // node-views can be chained to quickly query deeper
|
||||
/// std::cout << "cats: "sv << tbl["animals"]["cats"] << std::endl;
|
||||
/// std::cout << "fish[1]: "sv << tbl["animals"]["fish"][1] << std::endl;
|
||||
/// 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: "sv << tbl["animals"]["dinosaurs"] << std::endl; //no dinosaurs :(
|
||||
/// std::cout << "dinosaurs: " << tbl["animals"]["dinosaurs"] << "\n"; //no dinosaurs :(
|
||||
///
|
||||
/// return 0;
|
||||
/// }
|
||||
@ -349,7 +347,7 @@
|
||||
/// auto tbl = toml::table{{
|
||||
/// { "lib", "toml++" },
|
||||
/// { "cpp", toml::array{ 17, 20, "and beyond" } },
|
||||
/// { "toml", toml::array{ "0.5.0", "and beyond" } },
|
||||
/// { "toml", toml::array{ "1.0.0", "and beyond" } },
|
||||
/// { "repo", "https://github.com/marzer/tomlplusplus/" },
|
||||
/// { "author", toml::table{{
|
||||
/// { "name", "Mark Gillard" },
|
||||
@ -360,22 +358,23 @@
|
||||
/// }};
|
||||
///
|
||||
/// // serializing as TOML is just writing it to a stream
|
||||
/// std::cout << "###### TOML ######"sv << std::endl;
|
||||
/// std::cout << tbl << std::endl << std::endl;
|
||||
/// std::cout << "###### TOML ######" << "\n\n";
|
||||
/// std::cout << tbl << "\n\n";
|
||||
///
|
||||
/// // serializing as JSON is _also_ just writing it to a stream, but via a json_formatter:
|
||||
/// std::cout << "###### JSON ######"sv << std::endl;
|
||||
/// std::cout << toml::json_formatter{ tbl } << std::endl;
|
||||
/// 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 = ["0.5.0", "and beyond"]
|
||||
/// toml = ["1.0.0", "and beyond"]
|
||||
///
|
||||
/// [author]
|
||||
/// github = "https://github.com/marzer"
|
||||
@ -383,6 +382,7 @@
|
||||
/// twitter = "https://twitter.com/marzer8789"
|
||||
///
|
||||
/// ###### JSON ######
|
||||
///
|
||||
/// {
|
||||
/// "author" : {
|
||||
/// "github" : "https://github.com/marzer",
|
||||
@ -397,7 +397,7 @@
|
||||
/// "lib" : "toml++",
|
||||
/// "repo" : "https://github.com/marzer/tomlplusplus/",
|
||||
/// "toml" : [
|
||||
/// "0.5.0",
|
||||
/// "1.0.0",
|
||||
/// "and beyond"
|
||||
/// ]
|
||||
/// }
|
||||
@ -434,11 +434,6 @@
|
||||
/// #include "global_header_that_includes_toml++.h"
|
||||
/// \ecpp
|
||||
///
|
||||
/// \m_class{m-note m-default}
|
||||
///
|
||||
/// Your project may already have a specific header/source file pair configured as a 'precompiled header'; if so,
|
||||
/// that's the ideal place to put this machinery.
|
||||
///
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// \section mainpage-contributing Contributing
|
||||
|
@ -7,14 +7,14 @@
|
||||
|
||||
namespace toml::impl
|
||||
{
|
||||
template <bool is_const>
|
||||
template <bool IsConst>
|
||||
class array_iterator final
|
||||
{
|
||||
private:
|
||||
friend class toml::array;
|
||||
|
||||
using raw_iterator = std::conditional_t<
|
||||
is_const,
|
||||
IsConst,
|
||||
std::vector<std::unique_ptr<node>>::const_iterator,
|
||||
std::vector<std::unique_ptr<node>>::iterator
|
||||
>;
|
||||
@ -31,7 +31,7 @@ namespace toml::impl
|
||||
|
||||
public:
|
||||
|
||||
using value_type = std::conditional_t<is_const, const node, node>;
|
||||
using value_type = std::conditional_t<IsConst, const node, node>;
|
||||
using reference = value_type&;
|
||||
using pointer = value_type*;
|
||||
using difference_type = ptrdiff_t;
|
||||
@ -155,11 +155,6 @@ namespace toml::impl
|
||||
}
|
||||
};
|
||||
|
||||
#if !TOML_ALL_INLINE && !TOML_HAS_API_ANNOTATION
|
||||
extern template class array_iterator<true>;
|
||||
extern template class array_iterator<false>;
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
auto make_node(T&& val) noexcept
|
||||
@ -184,13 +179,12 @@ namespace toml::impl
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace toml
|
||||
{
|
||||
[[nodiscard]] TOML_API bool operator == (const array& lhs, const array& rhs) noexcept;
|
||||
[[nodiscard]] TOML_API bool operator != (const array& lhs, const array& rhs) noexcept;
|
||||
template <typename CHAR>
|
||||
std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>&, const array&);
|
||||
template <typename Char>
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>&, const array&);
|
||||
|
||||
/// \brief A TOML array.
|
||||
///
|
||||
@ -477,14 +471,14 @@ namespace toml
|
||||
|
||||
/// \brief Inserts a range of values into the array at a specific position.
|
||||
///
|
||||
/// \tparam ITER An iterator type. Must satisfy ForwardIterator.
|
||||
/// \tparam Iter An iterator type. Must satisfy ForwardIterator.
|
||||
/// \param pos The insertion position.
|
||||
/// \param first Iterator to the first value being inserted.
|
||||
/// \param last Iterator to the one-past-the-last value being inserted.
|
||||
///
|
||||
/// \returns An iterator to the first inserted value (or a copy of `pos` if `first` == `last`).
|
||||
template <typename ITER>
|
||||
iterator insert(const_iterator pos, ITER first, ITER last) noexcept
|
||||
template <typename Iter>
|
||||
iterator insert(const_iterator pos, Iter first, Iter last) noexcept
|
||||
{
|
||||
const auto count = std::distance(first, last);
|
||||
switch (count)
|
||||
@ -832,14 +826,7 @@ namespace toml
|
||||
/// \remarks Arrays inside child tables are not flattened.
|
||||
void flatten();
|
||||
|
||||
template <typename CHAR>
|
||||
friend std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>&, const array&);
|
||||
template <typename Char>
|
||||
friend std::basic_ostream<Char>& operator << (std::basic_ostream<Char>&, const array&);
|
||||
};
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE && !TOML_HAS_API_ANNOTATION
|
||||
namespace std
|
||||
{
|
||||
extern template class unique_ptr<toml::array>;
|
||||
}
|
||||
#endif
|
||||
|
@ -24,11 +24,8 @@
|
||||
#define TOML_IMPLEMENTATION 0
|
||||
#endif
|
||||
|
||||
#ifdef TOML_API
|
||||
#define TOML_HAS_API_ANNOTATION 1
|
||||
#else
|
||||
#ifndef TOML_API
|
||||
#define TOML_API
|
||||
#define TOML_HAS_API_ANNOTATION 0
|
||||
#endif
|
||||
|
||||
#ifndef TOML_CHAR_8_STRINGS
|
||||
@ -94,8 +91,8 @@
|
||||
#endif
|
||||
|
||||
//floating-point from_chars and to_chars are not implemented in any version of clang as of 1/1/2020
|
||||
#ifndef TOML_USE_STREAMS_FOR_FLOATS
|
||||
#define TOML_USE_STREAMS_FOR_FLOATS 1
|
||||
#ifndef TOML_FLOATING_POINT_CHARCONV
|
||||
#define TOML_FLOATING_POINT_CHARCONV 0
|
||||
#endif
|
||||
|
||||
#elif defined(_MSC_VER) || (defined(__INTEL_COMPILER) && defined(__ICL))
|
||||
@ -151,8 +148,8 @@
|
||||
#define TOML_UNLIKELY
|
||||
|
||||
// floating-point from_chars and to_chars are not implemented in any version of gcc as of 1/1/2020
|
||||
#ifndef TOML_USE_STREAMS_FOR_FLOATS
|
||||
#define TOML_USE_STREAMS_FOR_FLOATS 1
|
||||
#ifndef TOML_FLOATING_POINT_CHARCONV
|
||||
#define TOML_FLOATING_POINT_CHARCONV 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -195,8 +192,8 @@
|
||||
#ifndef TOML_DISABLE_INIT_WARNINGS
|
||||
#define TOML_DISABLE_INIT_WARNINGS
|
||||
#endif
|
||||
#ifndef TOML_USE_STREAMS_FOR_FLOATS
|
||||
#define TOML_USE_STREAMS_FOR_FLOATS 0
|
||||
#ifndef TOML_FLOATING_POINT_CHARCONV
|
||||
#define TOML_FLOATING_POINT_CHARCONV 1
|
||||
#endif
|
||||
#ifndef TOML_PUSH_WARNINGS
|
||||
#define TOML_PUSH_WARNINGS
|
||||
@ -293,8 +290,8 @@
|
||||
#define TOML_LANG_AT_LEAST(maj, min, rev) \
|
||||
(TOML_LANG_EFFECTIVE_VERSION >= TOML_MAKE_VERSION(maj, min, rev))
|
||||
|
||||
#define TOML_LANG_EXACTLY(maj, min, rev) \
|
||||
(TOML_LANG_EFFECTIVE_VERSION == TOML_MAKE_VERSION(maj, min, rev))
|
||||
#define TOML_LANG_UNRELEASED \
|
||||
TOML_LANG_HIGHER_THAN(TOML_LANG_MAJOR, TOML_LANG_MINOR, TOML_LANG_PATCH)
|
||||
|
||||
|
||||
////////// INCLUDES
|
||||
@ -325,9 +322,6 @@ TOML_DISABLE_ALL_WARNINGS
|
||||
#ifndef TOML_OPTIONAL_TYPE
|
||||
#include <optional>
|
||||
#endif
|
||||
#if TOML_USE_STREAMS_FOR_FLOATS
|
||||
#include <sstream>
|
||||
#endif
|
||||
#if TOML_EXCEPTIONS
|
||||
#include <stdexcept>
|
||||
#endif
|
||||
@ -503,7 +497,7 @@ namespace toml
|
||||
/// (typically the line numbers will be accurate but column numbers will be too high).
|
||||
/// <strong>This is not an error.</strong> I've chosen this behaviour as a deliberate trade-off
|
||||
/// between parser complexity and correctness.
|
||||
struct source_position
|
||||
struct TOML_TRIVIAL_ABI source_position
|
||||
{
|
||||
/// \brief The line number.
|
||||
/// \remarks Valid line numbers start at 1.
|
||||
@ -707,18 +701,9 @@ namespace toml::impl
|
||||
template <typename T>
|
||||
using string_map = std::map<string, T, std::less<>>; //heterogeneous lookup
|
||||
|
||||
#if defined(__cpp_lib_remove_cvref) || (defined(_MSC_VER) && defined(_HAS_CXX20) && _HAS_CXX20)
|
||||
|
||||
template <typename T>
|
||||
using remove_cvref_t = std::remove_cvref_t<T>;
|
||||
|
||||
#else
|
||||
|
||||
template <typename T>
|
||||
using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||
|
||||
#endif
|
||||
|
||||
template <typename T, typename... U>
|
||||
struct is_one_of_ : std::integral_constant<bool,
|
||||
(false || ... || std::is_same_v<T, U>)
|
||||
@ -727,12 +712,6 @@ namespace toml::impl
|
||||
template <typename T, typename... U>
|
||||
inline constexpr bool is_one_of = is_one_of_<T, U...>::value;
|
||||
|
||||
template <typename T, typename... U>
|
||||
using enable_if_one_of = std::enable_if_t<is_one_of<T, U...>>;
|
||||
|
||||
template <typename T, typename... U>
|
||||
using enable_if_not_one_of = std::enable_if_t<!is_one_of<T, U...>>;
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
constexpr std::underlying_type_t<T> unbox_enum(T val) noexcept
|
||||
@ -843,10 +822,10 @@ namespace toml::impl
|
||||
template <> struct value_promoter<uint8_t> { using type = int64_t; };
|
||||
template <> struct value_promoter<float> { using type = double; };
|
||||
#ifdef TOML_SMALL_FLOAT_TYPE
|
||||
template <> struct value_promoter<TOML_SMALL_FLOAT_TYPE> { using type = double; };
|
||||
template <> struct value_promoter<TOML_SMALL_FLOAT_TYPE> { using type = double; };
|
||||
#endif
|
||||
#ifdef TOML_SMALL_INT_TYPE
|
||||
template <> struct value_promoter<TOML_SMALL_INT_TYPE> { using type = int64_t; };
|
||||
template <> struct value_promoter<TOML_SMALL_INT_TYPE> { using type = int64_t; };
|
||||
#endif
|
||||
template <typename T> using promoted = typename impl::value_promoter<T>::type;
|
||||
|
||||
@ -914,10 +893,9 @@ namespace toml::impl
|
||||
"date-time"sv
|
||||
};
|
||||
|
||||
|
||||
#define TOML_P2S_DECL(linkage, type) \
|
||||
template <typename CHAR> \
|
||||
linkage void print_to_stream(type, std::basic_ostream<CHAR>&)
|
||||
template <typename Char> \
|
||||
linkage void print_to_stream(type, std::basic_ostream<Char>&)
|
||||
|
||||
TOML_P2S_DECL(TOML_ALWAYS_INLINE, int8_t);
|
||||
TOML_P2S_DECL(TOML_ALWAYS_INLINE, int16_t);
|
||||
@ -985,19 +963,24 @@ namespace toml
|
||||
/// Element [2] is: string
|
||||
/// Element [3] is: boolean
|
||||
/// \eout
|
||||
template <typename CHAR>
|
||||
inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, node_type rhs)
|
||||
template <typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, node_type rhs)
|
||||
{
|
||||
using underlying_t = std::underlying_type_t<node_type>;
|
||||
const auto str = impl::node_type_friendly_names[static_cast<underlying_t>(rhs)];
|
||||
if constexpr (std::is_same_v<CHAR, char>)
|
||||
if constexpr (std::is_same_v<Char, char>)
|
||||
return lhs << str;
|
||||
else
|
||||
{
|
||||
if constexpr (sizeof(CHAR) == 1)
|
||||
return lhs << std::basic_string_view<CHAR>{ reinterpret_cast<const CHAR*>(str.data()), str.length() };
|
||||
if constexpr (sizeof(Char) == 1)
|
||||
return lhs << std::basic_string_view<Char>{ reinterpret_cast<const Char*>(str.data()), str.length() };
|
||||
else
|
||||
return lhs << str.data();
|
||||
}
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, node_type);
|
||||
#endif
|
||||
}
|
||||
|
@ -84,13 +84,18 @@ namespace toml
|
||||
/// \out
|
||||
/// 1987-03-16
|
||||
/// \eout
|
||||
template <typename CHAR>
|
||||
inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const date& rhs)
|
||||
template <typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const date& rhs)
|
||||
{
|
||||
impl::print_to_stream(rhs, lhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const date&);
|
||||
#endif
|
||||
|
||||
/// \brief A local time-of-day.
|
||||
struct TOML_TRIVIAL_ABI time final
|
||||
{
|
||||
@ -172,13 +177,18 @@ namespace toml
|
||||
/// 10:20:34
|
||||
/// 10:20:34.5
|
||||
/// \eout
|
||||
template <typename CHAR>
|
||||
inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const time& rhs)
|
||||
template <typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const time& rhs)
|
||||
{
|
||||
impl::print_to_stream(rhs, lhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const time&);
|
||||
#endif
|
||||
|
||||
/// \brief A timezone offset.
|
||||
struct TOML_TRIVIAL_ABI time_offset final
|
||||
{
|
||||
@ -274,13 +284,18 @@ namespace toml
|
||||
/// -01:30
|
||||
/// -02:30
|
||||
/// \eout
|
||||
template <typename CHAR>
|
||||
inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const time_offset& rhs)
|
||||
template <typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const time_offset& rhs)
|
||||
{
|
||||
impl::print_to_stream(rhs, lhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const time_offset&);
|
||||
#endif
|
||||
|
||||
#if TOML_ABI_NAMESPACES
|
||||
#ifdef TOML_OPTIONAL_TYPE
|
||||
inline namespace abi_custopt {
|
||||
@ -406,11 +421,16 @@ namespace toml
|
||||
/// 1987-03-16T10:20:34-02:30
|
||||
/// 1987-03-16T10:20:34Z
|
||||
/// \eout
|
||||
template <typename CHAR>
|
||||
inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const date_time& rhs)
|
||||
template <typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const date_time& rhs)
|
||||
{
|
||||
impl::print_to_stream(rhs, lhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const date_time&);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -10,146 +10,14 @@
|
||||
|
||||
namespace toml::impl
|
||||
{
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ALL_WARNINGS
|
||||
[[nodiscard]] TOML_API
|
||||
toml::string default_formatter_make_key_segment(const toml::string& str) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
inline toml::string default_formatter_make_key_segment(const toml::string& str) noexcept
|
||||
{
|
||||
if (str.empty())
|
||||
return TOML_STRING_PREFIX("''"s);
|
||||
else
|
||||
{
|
||||
bool requiresQuotes = false;
|
||||
{
|
||||
impl::utf8_decoder decoder;
|
||||
for (size_t i = 0; i < str.length() && !requiresQuotes; i++)
|
||||
{
|
||||
decoder(static_cast<uint8_t>(str[i]));
|
||||
if (decoder.error())
|
||||
requiresQuotes = true;
|
||||
else if (decoder.has_code_point())
|
||||
requiresQuotes = !impl::is_bare_key_character(decoder.codepoint);
|
||||
}
|
||||
}
|
||||
[[nodiscard]] TOML_API
|
||||
size_t default_formatter_inline_columns(const node& node) noexcept;
|
||||
|
||||
if (requiresQuotes)
|
||||
{
|
||||
toml::string s;
|
||||
s.reserve(str.length() + 2_sz);
|
||||
s += TOML_STRING_PREFIX('"');
|
||||
for (auto c : str)
|
||||
{
|
||||
if (c >= TOML_STRING_PREFIX('\x00') && c <= TOML_STRING_PREFIX('\x1F')) TOML_UNLIKELY
|
||||
s.append(low_character_escape_table[c]);
|
||||
else if (c == TOML_STRING_PREFIX('\x7F')) TOML_UNLIKELY
|
||||
s.append(TOML_STRING_PREFIX("\\u007F"sv));
|
||||
else if (c == TOML_STRING_PREFIX('"')) TOML_UNLIKELY
|
||||
s.append(TOML_STRING_PREFIX("\\\""sv));
|
||||
else
|
||||
s += c;
|
||||
}
|
||||
s += TOML_STRING_PREFIX('"');
|
||||
return s;
|
||||
}
|
||||
else
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
TOML_POP_WARNINGS
|
||||
|
||||
[[nodiscard]]
|
||||
inline size_t default_formatter_inline_columns(const node& node) noexcept
|
||||
{
|
||||
return node.visit([](const auto& n) noexcept
|
||||
-> size_t
|
||||
{
|
||||
if constexpr (is_table<decltype(n)>)
|
||||
{
|
||||
if (n.empty())
|
||||
return 2_sz; // "{}"
|
||||
size_t weight = 3_sz; // "{ }"
|
||||
for (auto [k, v] : n)
|
||||
weight += k.length() + default_formatter_inline_columns(v) + 2_sz; // + ", "
|
||||
return weight;
|
||||
}
|
||||
else if constexpr (is_array<decltype(n)>)
|
||||
{
|
||||
if (n.empty())
|
||||
return 2_sz; // "[]"
|
||||
size_t weight = 3_sz; // "[ ]"
|
||||
for (auto& elem : n)
|
||||
weight += default_formatter_inline_columns(elem) + 2_sz; // + ", "
|
||||
return weight;
|
||||
}
|
||||
else if constexpr (is_string<decltype(n)>)
|
||||
{
|
||||
return n.get().length() + 2_sz; // + ""
|
||||
}
|
||||
else if constexpr (is_number<decltype(n)>)
|
||||
{
|
||||
static constexpr auto digit_count = [](auto num) noexcept
|
||||
-> size_t
|
||||
{
|
||||
using number_t = decltype(num);
|
||||
size_t digits = 1_sz;
|
||||
while (num >= number_t{ 10 })
|
||||
{
|
||||
num /= number_t{ 10 };
|
||||
digits++;
|
||||
}
|
||||
return digits;
|
||||
};
|
||||
|
||||
if constexpr (is_integer<decltype(n)>)
|
||||
{
|
||||
auto v = n.get();
|
||||
if (!v)
|
||||
return 1_sz;
|
||||
size_t weight = {};
|
||||
if (v < 0)
|
||||
{
|
||||
weight += 1;
|
||||
v *= -1;
|
||||
}
|
||||
return weight + digit_count(v);
|
||||
}
|
||||
else if constexpr (is_floating_point<decltype(n)>)
|
||||
{
|
||||
auto v = n.get();
|
||||
if (v == 0.0)
|
||||
return 3_sz;
|
||||
size_t weight = 2_sz; // ".0"
|
||||
if (v < 0.0)
|
||||
{
|
||||
weight += 1;
|
||||
v *= -1.0;
|
||||
}
|
||||
return weight + digit_count(v);
|
||||
}
|
||||
}
|
||||
else if constexpr (is_boolean<decltype(n)>)
|
||||
{
|
||||
return 5_sz;
|
||||
}
|
||||
else if constexpr (is_date<decltype(n)> || is_time<decltype(n)>)
|
||||
{
|
||||
return 10_sz;
|
||||
}
|
||||
else if constexpr (is_date_time<decltype(n)>)
|
||||
{
|
||||
return 30_sz;
|
||||
}
|
||||
TOML_UNREACHABLE;
|
||||
});
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool default_formatter_forces_multiline(const node& node, size_t starting_column_bias = 0) noexcept
|
||||
{
|
||||
return (default_formatter_inline_columns(node) + starting_column_bias) > 120_sz;
|
||||
}
|
||||
[[nodiscard]] TOML_API
|
||||
bool default_formatter_forces_multiline(const node& node, size_t starting_column_bias = 0) noexcept;
|
||||
}
|
||||
|
||||
|
||||
@ -188,12 +56,12 @@ namespace toml
|
||||
/// foo = "bar"
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam CHAR The underlying character type of the output stream. Must be 1 byte in size.
|
||||
template <typename CHAR = char>
|
||||
class default_formatter final : impl::formatter<CHAR>
|
||||
/// \tparam Char The underlying character type of the output stream. Must be 1 byte in size.
|
||||
template <typename Char = char>
|
||||
class TOML_API default_formatter final : impl::formatter<Char>
|
||||
{
|
||||
private:
|
||||
using base = impl::formatter<CHAR>;
|
||||
using base = impl::formatter<Char>;
|
||||
std::vector<toml::string> key_path;
|
||||
|
||||
void print_key_segment(const toml::string& str)
|
||||
@ -459,12 +327,16 @@ namespace toml
|
||||
friend std::basic_ostream<T>& operator << (std::basic_ostream<T>&, default_formatter<U>&&);
|
||||
};
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
extern template class TOML_API default_formatter<char>;
|
||||
#endif
|
||||
|
||||
default_formatter(const table&) -> default_formatter<char>;
|
||||
default_formatter(const array&) -> default_formatter<char>;
|
||||
template <typename T> default_formatter(const value<T>&) -> default_formatter<char>;
|
||||
|
||||
template <typename CHAR>
|
||||
inline void default_formatter<CHAR>::print_inline(const toml::table& tbl)
|
||||
template <typename Char>
|
||||
inline void default_formatter<Char>::print_inline(const toml::table& tbl)
|
||||
{
|
||||
if (tbl.empty())
|
||||
impl::print_to_stream("{}"sv, base::stream());
|
||||
@ -499,7 +371,8 @@ namespace toml
|
||||
|
||||
/// \brief Prints the bound TOML object out to the stream as formatted TOML.
|
||||
template <typename T, typename U>
|
||||
inline std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, default_formatter<U>& rhs)
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, default_formatter<U>& rhs)
|
||||
{
|
||||
rhs.attach(lhs);
|
||||
rhs.key_path.clear();
|
||||
@ -510,21 +383,31 @@ namespace toml
|
||||
|
||||
/// \brief Prints the bound TOML object out to the stream as formatted TOML (rvalue overload).
|
||||
template <typename T, typename U>
|
||||
inline std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, default_formatter<U>&& rhs)
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, default_formatter<U>&& rhs)
|
||||
{
|
||||
return lhs << rhs; //as lvalue
|
||||
}
|
||||
|
||||
template <typename CHAR>
|
||||
inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const table& rhs)
|
||||
template <typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const table& rhs)
|
||||
{
|
||||
return lhs << default_formatter<CHAR>{ rhs };
|
||||
return lhs << default_formatter<Char>{ rhs };
|
||||
}
|
||||
|
||||
template <typename CHAR>
|
||||
inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const array& rhs)
|
||||
template <typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const array& rhs)
|
||||
{
|
||||
return lhs << default_formatter<CHAR>{ rhs };
|
||||
return lhs << default_formatter<Char>{ rhs };
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, default_formatter<char>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, default_formatter<char>&&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const table&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const array&);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
156
include/toml++/toml_default_formatter_impl.h
Normal file
@ -0,0 +1,156 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) 2019-2020 Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
|
||||
#pragma once
|
||||
#include "toml_default_formatter.h"
|
||||
#if !defined(TOML_IMPLEMENTATION) || !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
|
||||
namespace toml::impl
|
||||
{
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ALL_WARNINGS
|
||||
|
||||
TOML_API
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
toml::string default_formatter_make_key_segment(const toml::string& str) noexcept
|
||||
{
|
||||
if (str.empty())
|
||||
return TOML_STRING_PREFIX("''"s);
|
||||
else
|
||||
{
|
||||
bool requiresQuotes = false;
|
||||
{
|
||||
impl::utf8_decoder decoder;
|
||||
for (size_t i = 0; i < str.length() && !requiresQuotes; i++)
|
||||
{
|
||||
decoder(static_cast<uint8_t>(str[i]));
|
||||
if (decoder.error())
|
||||
requiresQuotes = true;
|
||||
else if (decoder.has_code_point())
|
||||
requiresQuotes = !impl::is_bare_key_character(decoder.codepoint);
|
||||
}
|
||||
}
|
||||
|
||||
if (requiresQuotes)
|
||||
{
|
||||
toml::string s;
|
||||
s.reserve(str.length() + 2_sz);
|
||||
s += TOML_STRING_PREFIX('"');
|
||||
for (auto c : str)
|
||||
{
|
||||
if (c >= TOML_STRING_PREFIX('\x00') && c <= TOML_STRING_PREFIX('\x1F')) TOML_UNLIKELY
|
||||
s.append(low_character_escape_table[c]);
|
||||
else if (c == TOML_STRING_PREFIX('\x7F')) TOML_UNLIKELY
|
||||
s.append(TOML_STRING_PREFIX("\\u007F"sv));
|
||||
else if (c == TOML_STRING_PREFIX('"')) TOML_UNLIKELY
|
||||
s.append(TOML_STRING_PREFIX("\\\""sv));
|
||||
else
|
||||
s += c;
|
||||
}
|
||||
s += TOML_STRING_PREFIX('"');
|
||||
return s;
|
||||
}
|
||||
else
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
TOML_POP_WARNINGS
|
||||
|
||||
TOML_API
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
size_t default_formatter_inline_columns(const node& node) noexcept
|
||||
{
|
||||
return node.visit([](const auto& n) noexcept
|
||||
-> size_t
|
||||
{
|
||||
if constexpr (is_table<decltype(n)>)
|
||||
{
|
||||
if (n.empty())
|
||||
return 2_sz; // "{}"
|
||||
size_t weight = 3_sz; // "{ }"
|
||||
for (auto [k, v] : n)
|
||||
weight += k.length() + default_formatter_inline_columns(v) + 2_sz; // + ", "
|
||||
return weight;
|
||||
}
|
||||
else if constexpr (is_array<decltype(n)>)
|
||||
{
|
||||
if (n.empty())
|
||||
return 2_sz; // "[]"
|
||||
size_t weight = 3_sz; // "[ ]"
|
||||
for (auto& elem : n)
|
||||
weight += default_formatter_inline_columns(elem) + 2_sz; // + ", "
|
||||
return weight;
|
||||
}
|
||||
else if constexpr (is_string<decltype(n)>)
|
||||
{
|
||||
return n.get().length() + 2_sz; // + ""
|
||||
}
|
||||
else if constexpr (is_number<decltype(n)>)
|
||||
{
|
||||
static constexpr auto digit_count = [](auto num) noexcept
|
||||
-> size_t
|
||||
{
|
||||
using number_t = decltype(num);
|
||||
size_t digits = 1_sz;
|
||||
while (num >= number_t{ 10 })
|
||||
{
|
||||
num /= number_t{ 10 };
|
||||
digits++;
|
||||
}
|
||||
return digits;
|
||||
};
|
||||
|
||||
if constexpr (is_integer<decltype(n)>)
|
||||
{
|
||||
auto v = n.get();
|
||||
if (!v)
|
||||
return 1_sz;
|
||||
size_t weight = {};
|
||||
if (v < 0)
|
||||
{
|
||||
weight += 1;
|
||||
v *= -1;
|
||||
}
|
||||
return weight + digit_count(v);
|
||||
}
|
||||
else if constexpr (is_floating_point<decltype(n)>)
|
||||
{
|
||||
auto v = n.get();
|
||||
if (v == 0.0)
|
||||
return 3_sz;
|
||||
size_t weight = 2_sz; // ".0"
|
||||
if (v < 0.0)
|
||||
{
|
||||
weight += 1;
|
||||
v *= -1.0;
|
||||
}
|
||||
return weight + digit_count(v);
|
||||
}
|
||||
}
|
||||
else if constexpr (is_boolean<decltype(n)>)
|
||||
{
|
||||
return 5_sz;
|
||||
}
|
||||
else if constexpr (is_date<decltype(n)> || is_time<decltype(n)>)
|
||||
{
|
||||
return 10_sz;
|
||||
}
|
||||
else if constexpr (is_date_time<decltype(n)>)
|
||||
{
|
||||
return 30_sz;
|
||||
}
|
||||
TOML_UNREACHABLE;
|
||||
});
|
||||
}
|
||||
|
||||
TOML_API
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
bool default_formatter_forces_multiline(const node& node, size_t starting_column_bias) noexcept
|
||||
{
|
||||
return (default_formatter_inline_columns(node) + starting_column_bias) > 120_sz;
|
||||
}
|
||||
}
|
@ -26,12 +26,12 @@ namespace toml
|
||||
|
||||
namespace toml::impl
|
||||
{
|
||||
template <typename CHAR = char>
|
||||
class formatter
|
||||
template <typename Char = char>
|
||||
class TOML_API formatter
|
||||
{
|
||||
private:
|
||||
const toml::node* source_;
|
||||
std::basic_ostream<CHAR>* stream_ = nullptr;
|
||||
std::basic_ostream<Char>* stream_ = nullptr;
|
||||
format_flags flags_;
|
||||
int8_t indent_;
|
||||
bool naked_newline_;
|
||||
@ -40,7 +40,7 @@ namespace toml::impl
|
||||
|
||||
[[nodiscard]] const toml::node& source() const noexcept { return *source_; }
|
||||
[[nodiscard]] format_flags flags() const noexcept { return flags_; }
|
||||
[[nodiscard]] std::basic_ostream<CHAR>& stream() const noexcept { return *stream_; }
|
||||
[[nodiscard]] std::basic_ostream<Char>& stream() const noexcept { return *stream_; }
|
||||
|
||||
static constexpr size_t indent_columns = 4;
|
||||
static constexpr toml::string_view indent_string = TOML_STRING_PREFIX(" "sv);
|
||||
@ -51,7 +51,7 @@ namespace toml::impl
|
||||
|
||||
void clear_naked_newline() noexcept { naked_newline_ = false; }
|
||||
|
||||
void attach(std::basic_ostream<CHAR>& stream) noexcept
|
||||
void attach(std::basic_ostream<Char>& stream) noexcept
|
||||
{
|
||||
indent_ = {};
|
||||
naked_newline_ = true;
|
||||
@ -146,5 +146,9 @@ namespace toml::impl
|
||||
flags_{ flags }
|
||||
{}
|
||||
};
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
extern template class TOML_API formatter<char>;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -3,12 +3,21 @@
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
|
||||
#pragma once
|
||||
#include "toml_value.h"
|
||||
#include "toml_node_view.h"
|
||||
#include "toml_common.h"
|
||||
#if !defined(TOML_IMPLEMENTATION) || !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ALL_WARNINGS
|
||||
#include <ostream>
|
||||
TOML_POP_WARNINGS
|
||||
#include "toml_node_view.h"
|
||||
#include "toml_default_formatter.h"
|
||||
#include "toml_json_formatter.h"
|
||||
|
||||
namespace toml
|
||||
{
|
||||
// value<>
|
||||
@ -24,34 +33,44 @@ namespace toml
|
||||
template class TOML_API node_view<node>;
|
||||
template class TOML_API node_view<const node>;
|
||||
|
||||
// table and array iterators
|
||||
#if !TOML_ALL_INLINE && !TOML_HAS_API_ANNOTATION
|
||||
// formatters
|
||||
namespace impl
|
||||
{
|
||||
template struct table_proxy_pair<true>;
|
||||
template struct table_proxy_pair<false>;
|
||||
template class table_iterator<true>;
|
||||
template class table_iterator<false>;
|
||||
template class array_iterator<true>;
|
||||
template class array_iterator<false>;
|
||||
template class TOML_API formatter<char>;
|
||||
}
|
||||
template class TOML_API default_formatter<char>;
|
||||
template class TOML_API json_formatter<char>;
|
||||
|
||||
// various ostream operators
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const source_position&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const source_region&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const parse_error&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const date&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const time&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const time_offset&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const date_time&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const value<toml::string>&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const value<int64_t>&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const value<double>&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const value<bool>&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const value<toml::date>&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const value<toml::time>&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const value<toml::date_time>&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, default_formatter<char>&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, default_formatter<char>&&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, json_formatter<char>&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, json_formatter<char>&&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const table&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const array&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const node_view<node>&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const node_view<const node>&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, node_type);
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template TOML_API void print_floating_point_to_stream(float, std::ostream&, bool);
|
||||
template TOML_API void print_floating_point_to_stream(double, std::ostream&, bool);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// unique_ptrs to various things
|
||||
#if !TOML_ALL_INLINE && !TOML_HAS_API_ANNOTATION
|
||||
namespace std
|
||||
{
|
||||
template class unique_ptr<toml::node>;
|
||||
template class unique_ptr<toml::table>;
|
||||
template class unique_ptr<toml::array>;
|
||||
template class unique_ptr<toml::value<toml::string>>;
|
||||
template class unique_ptr<toml::value<int64_t>>;
|
||||
template class unique_ptr<toml::value<double>>;
|
||||
template class unique_ptr<toml::value<bool>>;
|
||||
template class unique_ptr<toml::value<toml::date>>;
|
||||
template class unique_ptr<toml::value<toml::time>>;
|
||||
template class unique_ptr<toml::value<toml::date_time>>;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !TOML_ALL_INLINE
|
||||
|
@ -43,12 +43,12 @@ namespace toml
|
||||
/// }
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam CHAR The underlying character type of the output stream. Must be 1 byte in size.
|
||||
template <typename CHAR = char>
|
||||
class json_formatter final : impl::formatter<CHAR>
|
||||
/// \tparam Char The underlying character type of the output stream. Must be 1 byte in size.
|
||||
template <typename Char = char>
|
||||
class TOML_API json_formatter final : impl::formatter<Char>
|
||||
{
|
||||
private:
|
||||
using base = impl::formatter<CHAR>;
|
||||
using base = impl::formatter<Char>;
|
||||
|
||||
inline void print(const toml::table& tbl);
|
||||
|
||||
@ -112,13 +112,17 @@ namespace toml
|
||||
template <typename T, typename U>
|
||||
friend std::basic_ostream<T>& operator << (std::basic_ostream<T>&, json_formatter<U>&&);
|
||||
};
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
extern template class TOML_API json_formatter<char>;
|
||||
#endif
|
||||
|
||||
json_formatter(const table&) -> json_formatter<char>;
|
||||
json_formatter(const array&) -> json_formatter<char>;
|
||||
template <typename T> json_formatter(const value<T>&) -> json_formatter<char>;
|
||||
|
||||
template <typename CHAR>
|
||||
inline void json_formatter<CHAR>::print(const toml::table& tbl)
|
||||
template <typename Char>
|
||||
inline void json_formatter<Char>::print(const toml::table& tbl)
|
||||
{
|
||||
if (tbl.empty())
|
||||
impl::print_to_stream("{}"sv, base::stream());
|
||||
@ -158,7 +162,8 @@ namespace toml
|
||||
|
||||
/// \brief Prints the bound TOML object out to the stream as JSON.
|
||||
template <typename T, typename U>
|
||||
inline std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, json_formatter<U>& rhs)
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, json_formatter<U>& rhs)
|
||||
{
|
||||
rhs.attach(lhs);
|
||||
rhs.print();
|
||||
@ -168,9 +173,15 @@ namespace toml
|
||||
|
||||
/// \brief Prints the bound TOML object out to the stream as JSON (rvalue overload).
|
||||
template <typename T, typename U>
|
||||
inline std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, json_formatter<U>&& rhs)
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, json_formatter<U>&& rhs)
|
||||
{
|
||||
return lhs << rhs; //as lvalue
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, json_formatter<char>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, json_formatter<char>&&);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -263,57 +263,57 @@ namespace toml
|
||||
|
||||
private:
|
||||
|
||||
template <typename FUNC, typename N, typename T>
|
||||
static constexpr bool can_visit = std::is_invocable_v<FUNC, ref_cast_type<N, T>>;
|
||||
template <typename Func, typename N, typename T>
|
||||
static constexpr bool can_visit = std::is_invocable_v<Func, ref_cast_type<N, T>>;
|
||||
|
||||
template <typename FUNC, typename N>
|
||||
template <typename Func, typename N>
|
||||
static constexpr bool can_visit_any =
|
||||
can_visit<FUNC, N, table>
|
||||
|| can_visit<FUNC, N, array>
|
||||
|| can_visit<FUNC, N, string>
|
||||
|| can_visit<FUNC, N, int64_t>
|
||||
|| can_visit<FUNC, N, double>
|
||||
|| can_visit<FUNC, N, bool>
|
||||
|| can_visit<FUNC, N, date>
|
||||
|| can_visit<FUNC, N, time>
|
||||
|| can_visit<FUNC, N, date_time>;
|
||||
can_visit<Func, N, table>
|
||||
|| can_visit<Func, N, array>
|
||||
|| can_visit<Func, N, string>
|
||||
|| can_visit<Func, N, int64_t>
|
||||
|| can_visit<Func, N, double>
|
||||
|| can_visit<Func, N, bool>
|
||||
|| can_visit<Func, N, date>
|
||||
|| can_visit<Func, N, time>
|
||||
|| can_visit<Func, N, date_time>;
|
||||
|
||||
template <typename FUNC, typename N>
|
||||
template <typename Func, typename N>
|
||||
static constexpr bool can_visit_all =
|
||||
can_visit<FUNC, N, table>
|
||||
&& can_visit<FUNC, N, array>
|
||||
&& can_visit<FUNC, N, string>
|
||||
&& can_visit<FUNC, N, int64_t>
|
||||
&& can_visit<FUNC, N, double>
|
||||
&& can_visit<FUNC, N, bool>
|
||||
&& can_visit<FUNC, N, date>
|
||||
&& can_visit<FUNC, N, time>
|
||||
&& can_visit<FUNC, N, date_time>;
|
||||
can_visit<Func, N, table>
|
||||
&& can_visit<Func, N, array>
|
||||
&& can_visit<Func, N, string>
|
||||
&& can_visit<Func, N, int64_t>
|
||||
&& can_visit<Func, N, double>
|
||||
&& can_visit<Func, N, bool>
|
||||
&& can_visit<Func, N, date>
|
||||
&& can_visit<Func, N, time>
|
||||
&& can_visit<Func, N, date_time>;
|
||||
|
||||
template <typename FUNC, typename N, typename T>
|
||||
template <typename Func, typename N, typename T>
|
||||
static constexpr bool visit_is_nothrow_one =
|
||||
!can_visit<FUNC, N, T>
|
||||
|| std::is_nothrow_invocable_v<FUNC, ref_cast_type<N, T>>;
|
||||
!can_visit<Func, N, T>
|
||||
|| std::is_nothrow_invocable_v<Func, ref_cast_type<N, T>>;
|
||||
|
||||
template <typename FUNC, typename N>
|
||||
template <typename Func, typename N>
|
||||
static constexpr bool visit_is_nothrow =
|
||||
visit_is_nothrow_one<FUNC, N, table>
|
||||
&& visit_is_nothrow_one<FUNC, N, array>
|
||||
&& visit_is_nothrow_one<FUNC, N, string>
|
||||
&& visit_is_nothrow_one<FUNC, N, int64_t>
|
||||
&& visit_is_nothrow_one<FUNC, N, double>
|
||||
&& visit_is_nothrow_one<FUNC, N, bool>
|
||||
&& visit_is_nothrow_one<FUNC, N, date>
|
||||
&& visit_is_nothrow_one<FUNC, N, time>
|
||||
&& visit_is_nothrow_one<FUNC, N, date_time>;
|
||||
visit_is_nothrow_one<Func, N, table>
|
||||
&& visit_is_nothrow_one<Func, N, array>
|
||||
&& visit_is_nothrow_one<Func, N, string>
|
||||
&& visit_is_nothrow_one<Func, N, int64_t>
|
||||
&& visit_is_nothrow_one<Func, N, double>
|
||||
&& visit_is_nothrow_one<Func, N, bool>
|
||||
&& visit_is_nothrow_one<Func, N, date>
|
||||
&& visit_is_nothrow_one<Func, N, time>
|
||||
&& visit_is_nothrow_one<Func, N, date_time>;
|
||||
|
||||
template <typename FUNC, typename N, typename T, bool = can_visit<FUNC, N, T>>
|
||||
template <typename Func, typename N, typename T, bool = can_visit<Func, N, T>>
|
||||
struct visit_return_type final
|
||||
{
|
||||
using type = decltype(std::declval<FUNC>()(std::declval<ref_cast_type<N, T>>()));
|
||||
using type = decltype(std::declval<Func>()(std::declval<ref_cast_type<N, T>>()));
|
||||
};
|
||||
template <typename FUNC, typename N, typename T>
|
||||
struct visit_return_type<FUNC, N, T, false> final
|
||||
template <typename Func, typename N, typename T>
|
||||
struct visit_return_type<Func, N, T, false> final
|
||||
{
|
||||
using type = void;
|
||||
};
|
||||
@ -325,79 +325,79 @@ namespace toml
|
||||
//# (otherwise I'd have to implement them thrice)
|
||||
//# ((propagation in C++: a modern horror story))
|
||||
|
||||
template <typename N, typename FUNC>
|
||||
static decltype(auto) do_visit(N&& n, FUNC&& visitor)
|
||||
noexcept(visit_is_nothrow<FUNC&&, N&&>)
|
||||
template <typename N, typename Func>
|
||||
static decltype(auto) do_visit(N&& n, Func&& visitor)
|
||||
noexcept(visit_is_nothrow<Func&&, N&&>)
|
||||
{
|
||||
static_assert(
|
||||
can_visit_any<FUNC&&, N&&>,
|
||||
can_visit_any<Func&&, N&&>,
|
||||
"Visitors must be invocable for at least one of the toml::node specializations"
|
||||
);
|
||||
|
||||
switch (n.type())
|
||||
{
|
||||
case node_type::table:
|
||||
if constexpr (can_visit<FUNC&&, N&&, table>)
|
||||
return std::forward<FUNC>(visitor)(std::forward<N>(n).template ref_cast<table>());
|
||||
if constexpr (can_visit<Func&&, N&&, table>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<table>());
|
||||
break;
|
||||
|
||||
case node_type::array:
|
||||
if constexpr (can_visit<FUNC&&, N&&, array>)
|
||||
return std::forward<FUNC>(visitor)(std::forward<N>(n).template ref_cast<array>());
|
||||
if constexpr (can_visit<Func&&, N&&, array>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<array>());
|
||||
break;
|
||||
|
||||
case node_type::string:
|
||||
if constexpr (can_visit<FUNC&&, N&&, string>)
|
||||
return std::forward<FUNC>(visitor)(std::forward<N>(n).template ref_cast<string>());
|
||||
if constexpr (can_visit<Func&&, N&&, string>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<string>());
|
||||
break;
|
||||
|
||||
case node_type::integer:
|
||||
if constexpr (can_visit<FUNC&&, N&&, int64_t>)
|
||||
return std::forward<FUNC>(visitor)(std::forward<N>(n).template ref_cast<int64_t>());
|
||||
if constexpr (can_visit<Func&&, N&&, int64_t>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<int64_t>());
|
||||
break;
|
||||
|
||||
case node_type::floating_point:
|
||||
if constexpr (can_visit<FUNC&&, N&&, double>)
|
||||
return std::forward<FUNC>(visitor)(std::forward<N>(n).template ref_cast<double>());
|
||||
if constexpr (can_visit<Func&&, N&&, double>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<double>());
|
||||
break;
|
||||
|
||||
case node_type::boolean:
|
||||
if constexpr (can_visit<FUNC&&, N&&, bool>)
|
||||
return std::forward<FUNC>(visitor)(std::forward<N>(n).template ref_cast<bool>());
|
||||
if constexpr (can_visit<Func&&, N&&, bool>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<bool>());
|
||||
break;
|
||||
|
||||
case node_type::date:
|
||||
if constexpr (can_visit<FUNC&&, N&&, date>)
|
||||
return std::forward<FUNC>(visitor)(std::forward<N>(n).template ref_cast<date>());
|
||||
if constexpr (can_visit<Func&&, N&&, date>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<date>());
|
||||
break;
|
||||
|
||||
case node_type::time:
|
||||
if constexpr (can_visit<FUNC&&, N&&, time>)
|
||||
return std::forward<FUNC>(visitor)(std::forward<N>(n).template ref_cast<time>());
|
||||
if constexpr (can_visit<Func&&, N&&, time>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<time>());
|
||||
break;
|
||||
|
||||
case node_type::date_time:
|
||||
if constexpr (can_visit<FUNC&&, N&&, date_time>)
|
||||
return std::forward<FUNC>(visitor)(std::forward<N>(n).template ref_cast<date_time>());
|
||||
if constexpr (can_visit<Func&&, N&&, date_time>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<date_time>());
|
||||
break;
|
||||
|
||||
TOML_NO_DEFAULT_CASE;
|
||||
}
|
||||
|
||||
if constexpr (can_visit_all<FUNC&&, N&&>)
|
||||
if constexpr (can_visit_all<Func&&, N&&>)
|
||||
TOML_UNREACHABLE;
|
||||
else
|
||||
{
|
||||
using return_type =
|
||||
nonvoid<typename visit_return_type<FUNC&&, N&&, table>::type,
|
||||
nonvoid<typename visit_return_type<FUNC&&, N&&, array>::type,
|
||||
nonvoid<typename visit_return_type<FUNC&&, N&&, string>::type,
|
||||
nonvoid<typename visit_return_type<FUNC&&, N&&, int64_t>::type,
|
||||
nonvoid<typename visit_return_type<FUNC&&, N&&, double>::type,
|
||||
nonvoid<typename visit_return_type<FUNC&&, N&&, bool>::type,
|
||||
nonvoid<typename visit_return_type<FUNC&&, N&&, date>::type,
|
||||
nonvoid<typename visit_return_type<FUNC&&, N&&, time>::type,
|
||||
typename visit_return_type<FUNC&&, N&&, date_time>::type
|
||||
nonvoid<typename visit_return_type<Func&&, N&&, table>::type,
|
||||
nonvoid<typename visit_return_type<Func&&, N&&, array>::type,
|
||||
nonvoid<typename visit_return_type<Func&&, N&&, string>::type,
|
||||
nonvoid<typename visit_return_type<Func&&, N&&, int64_t>::type,
|
||||
nonvoid<typename visit_return_type<Func&&, N&&, double>::type,
|
||||
nonvoid<typename visit_return_type<Func&&, N&&, bool>::type,
|
||||
nonvoid<typename visit_return_type<Func&&, N&&, date>::type,
|
||||
nonvoid<typename visit_return_type<Func&&, N&&, time>::type,
|
||||
typename visit_return_type<Func&&, N&&, date_time>::type
|
||||
>>>>>>>>;
|
||||
|
||||
if constexpr (!std::is_void_v<return_type>)
|
||||
@ -451,7 +451,7 @@ namespace toml
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \tparam FUNC A callable type invocable with one or more of the
|
||||
/// \tparam Func A callable type invocable with one or more of the
|
||||
/// toml++ node types.
|
||||
///
|
||||
/// \param visitor The visitor object.
|
||||
@ -460,22 +460,22 @@ namespace toml
|
||||
/// Can be void. Non-exhaustive visitors must return a default-constructible type.
|
||||
///
|
||||
/// \see https://en.wikipedia.org/wiki/Visitor_pattern
|
||||
template <typename FUNC>
|
||||
decltype(auto) visit(FUNC&& visitor) & noexcept(visit_is_nothrow<FUNC&&, node&>)
|
||||
template <typename Func>
|
||||
decltype(auto) visit(Func&& visitor) & noexcept(visit_is_nothrow<Func&&, node&>)
|
||||
{
|
||||
return do_visit(*this, std::forward<FUNC>(visitor));
|
||||
return do_visit(*this, std::forward<Func>(visitor));
|
||||
}
|
||||
|
||||
template <typename FUNC>
|
||||
decltype(auto) visit(FUNC&& visitor) && noexcept(visit_is_nothrow<FUNC&&, node&&>)
|
||||
template <typename Func>
|
||||
decltype(auto) visit(Func&& visitor) && noexcept(visit_is_nothrow<Func&&, node&&>)
|
||||
{
|
||||
return do_visit(std::move(*this), std::forward<FUNC>(visitor));
|
||||
return do_visit(std::move(*this), std::forward<Func>(visitor));
|
||||
}
|
||||
|
||||
template <typename FUNC>
|
||||
decltype(auto) visit(FUNC&& visitor) const& noexcept(visit_is_nothrow<FUNC&&, const node&>)
|
||||
template <typename Func>
|
||||
decltype(auto) visit(Func&& visitor) const& noexcept(visit_is_nothrow<Func&&, const node&>)
|
||||
{
|
||||
return do_visit(*this, std::forward<FUNC>(visitor));
|
||||
return do_visit(*this, std::forward<Func>(visitor));
|
||||
}
|
||||
|
||||
/// \brief Gets a raw reference to a value node's underlying data.
|
||||
@ -518,10 +518,3 @@ namespace toml
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE && !TOML_HAS_API_ANNOTATION
|
||||
namespace std
|
||||
{
|
||||
extern template class unique_ptr<toml::node>;
|
||||
}
|
||||
#endif
|
||||
|
@ -9,8 +9,8 @@
|
||||
|
||||
namespace toml
|
||||
{
|
||||
template <typename CHAR, typename T>
|
||||
inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>&, const node_view<T>&);
|
||||
template <typename Char, typename T>
|
||||
inline std::basic_ostream<Char>& operator << (std::basic_ostream<Char>&, const node_view<T>&);
|
||||
|
||||
/// \brief A view of a node.
|
||||
///
|
||||
@ -72,9 +72,9 @@ namespace toml
|
||||
: node_{ node }
|
||||
{}
|
||||
|
||||
template <typename FUNC>
|
||||
template <typename Func>
|
||||
static constexpr bool visit_is_nothrow
|
||||
= noexcept(std::declval<viewed_type*>()->visit(std::declval<FUNC&&>()));
|
||||
= noexcept(std::declval<viewed_type*>()->visit(std::declval<Func&&>()));
|
||||
|
||||
public:
|
||||
|
||||
@ -202,13 +202,13 @@ namespace toml
|
||||
/// \remarks Has no effect if the view does not reference a node.
|
||||
///
|
||||
/// \see node::visit()
|
||||
template <typename FUNC>
|
||||
decltype(auto) visit(FUNC&& visitor) const
|
||||
noexcept(visit_is_nothrow<FUNC&&>)
|
||||
template <typename Func>
|
||||
decltype(auto) visit(Func&& visitor) const
|
||||
noexcept(visit_is_nothrow<Func&&>)
|
||||
{
|
||||
using return_type = decltype(node_->visit(std::forward<FUNC>(visitor)));
|
||||
using return_type = decltype(node_->visit(std::forward<Func>(visitor)));
|
||||
if (node_)
|
||||
return node_->visit(std::forward<FUNC>(visitor));
|
||||
return node_->visit(std::forward<Func>(visitor));
|
||||
if constexpr (!std::is_void_v<return_type>)
|
||||
return return_type{};
|
||||
}
|
||||
@ -350,18 +350,14 @@ namespace toml
|
||||
return { nullptr };
|
||||
}
|
||||
|
||||
template <typename CHAR, typename U>
|
||||
friend std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>&, const node_view<U>&);
|
||||
template <typename Char, typename U>
|
||||
friend std::basic_ostream<Char>& operator << (std::basic_ostream<Char>&, const node_view<U>&);
|
||||
};
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
extern template class TOML_API node_view<node>;
|
||||
extern template class TOML_API node_view<const node>;
|
||||
#endif
|
||||
|
||||
/// \brief Prints the viewed node out to a stream.
|
||||
template <typename CHAR, typename T>
|
||||
inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& os, const node_view<T>& nv)
|
||||
template <typename Char, typename T>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& os, const node_view<T>& nv)
|
||||
{
|
||||
if (nv.node_)
|
||||
{
|
||||
@ -372,5 +368,12 @@ namespace toml
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
extern template class TOML_API node_view<node>;
|
||||
extern template class TOML_API node_view<const node>;
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const node_view<node>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const node_view<const node>&);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -325,7 +325,7 @@ namespace toml
|
||||
/// 3
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam CHAR The stream's underlying character type. Must be 1 byte in size.
|
||||
/// \tparam Char The stream's underlying character type. Must be 1 byte in size.
|
||||
/// \param doc The TOML document to parse. Must be valid UTF-8.
|
||||
/// \param source_path The path used to initialize each node's `source().path`.
|
||||
/// If you don't have a path (or you have no intention of using paths in diagnostics)
|
||||
@ -333,12 +333,12 @@ namespace toml
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
|
||||
template <typename CHAR>
|
||||
template <typename Char>
|
||||
[[nodiscard]]
|
||||
inline parse_result parse(std::basic_istream<CHAR>& doc, std::string_view source_path = {}) TOML_MAY_THROW
|
||||
inline parse_result parse(std::basic_istream<Char>& doc, std::string_view source_path = {}) TOML_MAY_THROW
|
||||
{
|
||||
static_assert(
|
||||
sizeof(CHAR) == 1,
|
||||
sizeof(Char) == 1,
|
||||
"The stream's underlying character type must be 1 byte in size."
|
||||
);
|
||||
|
||||
@ -360,18 +360,18 @@ namespace toml
|
||||
/// 3
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam CHAR The stream's underlying character type. Must be 1 byte in size.
|
||||
/// \tparam Char The stream's underlying character type. Must be 1 byte in size.
|
||||
/// \param doc The TOML document to parse. Must be valid UTF-8.
|
||||
/// \param source_path The path used to initialize each node's `source().path`.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
|
||||
template <typename CHAR>
|
||||
template <typename Char>
|
||||
[[nodiscard]]
|
||||
inline parse_result parse(std::basic_istream<CHAR>& doc, std::string&& source_path) TOML_MAY_THROW
|
||||
inline parse_result parse(std::basic_istream<Char>& doc, std::string&& source_path) TOML_MAY_THROW
|
||||
{
|
||||
static_assert(
|
||||
sizeof(CHAR) == 1,
|
||||
sizeof(Char) == 1,
|
||||
"The stream's underlying character type must be 1 byte in size."
|
||||
);
|
||||
|
||||
@ -389,7 +389,7 @@ namespace toml
|
||||
/// }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \tparam CHAR The path's character type. Must be 1 byte in size.
|
||||
/// \tparam Char The path's character type. Must be 1 byte in size.
|
||||
/// \param file_path The TOML document to parse. Must be valid UTF-8.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
@ -397,16 +397,16 @@ namespace toml
|
||||
///
|
||||
/// \attention You must `#include <fstream>` to use this function (toml++
|
||||
/// does not transitively include it for you).
|
||||
template <typename CHAR>
|
||||
inline parse_result parse_file(std::basic_string_view<CHAR> file_path) TOML_MAY_THROW
|
||||
template <typename Char>
|
||||
inline parse_result parse_file(std::basic_string_view<Char> file_path) TOML_MAY_THROW
|
||||
{
|
||||
static_assert(
|
||||
sizeof(CHAR) == 1,
|
||||
sizeof(Char) == 1,
|
||||
"The path's character type must be 1 byte in size."
|
||||
);
|
||||
|
||||
auto str = std::string(reinterpret_cast<const char*>(file_path.data()), file_path.length());
|
||||
auto ifs = std::basic_ifstream<CHAR>{ str };
|
||||
auto ifs = std::basic_ifstream<Char>{ str };
|
||||
return parse( ifs, std::move(str) );
|
||||
}
|
||||
|
||||
@ -416,16 +416,16 @@ namespace toml
|
||||
// until they're actually required, so only those users wanting to use parse_file()
|
||||
// are burdened by the <fstream> overhead.
|
||||
|
||||
template <typename CHAR>
|
||||
inline parse_result parse_file(const std::basic_string<CHAR>& file_path) TOML_MAY_THROW
|
||||
template <typename Char>
|
||||
inline parse_result parse_file(const std::basic_string<Char>& file_path) TOML_MAY_THROW
|
||||
{
|
||||
return parse_file(std::basic_string_view<CHAR>{ file_path });
|
||||
return parse_file(std::basic_string_view<Char>{ file_path });
|
||||
}
|
||||
|
||||
template <typename CHAR>
|
||||
inline parse_result parse_file(const CHAR* file_path) TOML_MAY_THROW
|
||||
template <typename Char>
|
||||
inline parse_result parse_file(const Char* file_path) TOML_MAY_THROW
|
||||
{
|
||||
return parse_file(std::basic_string_view<CHAR>{ file_path });
|
||||
return parse_file(std::basic_string_view<Char>{ file_path });
|
||||
}
|
||||
|
||||
#if TOML_ABI_NAMESPACES
|
||||
@ -438,7 +438,7 @@ namespace toml
|
||||
/// without dragging in everything in the toml namespace: \cpp
|
||||
///
|
||||
/// #include <toml++/toml.h>
|
||||
/// using namespace toml_literals;
|
||||
/// using namespace toml::literals;
|
||||
///
|
||||
/// int main()
|
||||
/// {
|
||||
|
@ -8,6 +8,13 @@
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
|
||||
#if !TOML_FLOATING_POINT_CHARCONV
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ALL_WARNINGS
|
||||
#include <sstream>
|
||||
TOML_POP_WARNINGS
|
||||
#endif
|
||||
|
||||
namespace toml::impl
|
||||
{
|
||||
#if TOML_EXCEPTIONS
|
||||
@ -136,7 +143,12 @@ namespace toml::impl
|
||||
}
|
||||
else if constexpr (std::is_floating_point_v<arg_t>)
|
||||
{
|
||||
#if TOML_USE_STREAMS_FOR_FLOATS
|
||||
#if TOML_FLOATING_POINT_CHARCONV
|
||||
{
|
||||
const auto result = std::to_chars(ptr, buf + N, arg);
|
||||
ptr = result.ptr;
|
||||
}
|
||||
#else
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss.precision(std::numeric_limits<arg_t>::digits10 + 1);
|
||||
@ -145,11 +157,6 @@ namespace toml::impl
|
||||
std::memcpy(ptr, str.c_str(), str.length());
|
||||
ptr += str.length();
|
||||
}
|
||||
#else
|
||||
{
|
||||
const auto result = std::to_chars(ptr, buf + N, arg);
|
||||
ptr = result.ptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if constexpr (std::is_integral_v<arg_t>)
|
||||
@ -272,7 +279,7 @@ namespace toml::impl
|
||||
|
||||
if (!cp)
|
||||
abort_with_error("Encountered EOF while consuming CRLF"sv);
|
||||
if (*cp != U'\n')
|
||||
else if (*cp != U'\n')
|
||||
abort_with_error("Encountered unexpected character while consuming CRLF"sv);
|
||||
}
|
||||
advance(); // skip \n (or other single-character line ending)
|
||||
@ -318,16 +325,22 @@ namespace toml::impl
|
||||
if (consume_line_break())
|
||||
return true;
|
||||
|
||||
if constexpr (TOML_LANG_HIGHER_THAN(0, 5, 0)) // toml/issues/567
|
||||
if constexpr (TOML_LANG_AT_LEAST(1, 0, 0))
|
||||
{
|
||||
if (*cp <= U'\u0008'
|
||||
|| (*cp >= U'\u000A' && *cp <= U'\u001F')
|
||||
|| *cp == U'\u007F')
|
||||
// toml/issues/567 (disallow non-TAB control characters in comments)
|
||||
if (is_nontab_control_character(*cp))
|
||||
abort_with_error(
|
||||
"Encountered unexpected character while parsing comment; control characters "
|
||||
"U+0000-U+0008, U+000A-U+001F and U+007F are explicitly prohibited from appearing "
|
||||
"other than TAB (U+0009) are explicitly prohibited from appearing "
|
||||
"in comments."sv
|
||||
);
|
||||
|
||||
// toml/pull/720 (disallow surrogates in comments)
|
||||
else if (is_unicode_surrogate(*cp))
|
||||
abort_with_error(
|
||||
"Encountered unexpected character while parsing comment; unicode surrogates "
|
||||
"(U+D800 to U+DFFF) are explicitly prohibited from appearing in comments."sv
|
||||
);
|
||||
}
|
||||
|
||||
advance();
|
||||
@ -391,7 +404,7 @@ namespace toml::impl
|
||||
return i;
|
||||
}
|
||||
|
||||
template <bool MULTI_LINE>
|
||||
template <bool MultiLine>
|
||||
[[nodiscard]]
|
||||
TOML_NEVER_INLINE
|
||||
string parse_basic_string() TOML_MAY_THROW
|
||||
@ -405,7 +418,7 @@ namespace toml::impl
|
||||
if (!cp)
|
||||
abort_with_error(
|
||||
"Encountered EOF while parsing "sv,
|
||||
(MULTI_LINE ? "multi-line "sv : ""sv),
|
||||
(MultiLine ? "multi-line "sv : ""sv),
|
||||
node_type::string
|
||||
);
|
||||
};
|
||||
@ -424,7 +437,7 @@ namespace toml::impl
|
||||
escaped = false;
|
||||
|
||||
// handle 'line ending slashes' in multi-line mode
|
||||
if constexpr (MULTI_LINE)
|
||||
if constexpr (MultiLine)
|
||||
{
|
||||
if (is_line_break(*cp))
|
||||
{
|
||||
@ -447,39 +460,20 @@ namespace toml::impl
|
||||
case U'f': str += TOML_STRING_PREFIX('\f'); break;
|
||||
case U'n': str += TOML_STRING_PREFIX('\n'); break;
|
||||
case U'r': str += TOML_STRING_PREFIX('\r'); break;
|
||||
|
||||
#if 0
|
||||
case U's':
|
||||
{
|
||||
if constexpr (!TOML_LANG_HIGHER_THAN(0, 5, 0)) // toml/issues/622
|
||||
{
|
||||
abort_with_error("Escape sequence '\\s' (Space, U+0020) is not supported "
|
||||
"in TOML 0.5.0 and earlier."sv
|
||||
);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
str += TOML_STRING_PREFIX(' ');
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
case U't': str += TOML_STRING_PREFIX('\t'); break;
|
||||
case U'"': str += TOML_STRING_PREFIX('"'); break;
|
||||
case U'\\': str += TOML_STRING_PREFIX('\\'); break;
|
||||
|
||||
// unicode scalar sequences
|
||||
case U'x':
|
||||
#if TOML_LANG_HIGHER_THAN(0, 5, 0)
|
||||
[[fallthrough]];
|
||||
#else
|
||||
if constexpr (!TOML_LANG_UNRELEASED) // toml/pull/709 (\xHH unicode scalar sequences)
|
||||
{
|
||||
abort_with_error("Escape sequence '\\x' is not supported "
|
||||
"in TOML 0.5.0 and earlier."sv
|
||||
"in TOML 1.0.0 and earlier."sv
|
||||
);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
[[fallthrough]];
|
||||
case U'u': [[fallthrough]];
|
||||
case U'U':
|
||||
{
|
||||
@ -491,12 +485,15 @@ namespace toml::impl
|
||||
TOML_ERROR_CHECK({});
|
||||
|
||||
if (!is_hexadecimal_digit(*cp))
|
||||
{
|
||||
abort_with_error(
|
||||
"Encountered unexpected character while parsing "sv,
|
||||
(MULTI_LINE ? "multi-line "sv : ""sv),
|
||||
(MultiLine ? "multi-line "sv : ""sv),
|
||||
node_type::string,
|
||||
"; expected hex digit, saw '\\"sv, *cp, "'"sv
|
||||
);
|
||||
break;
|
||||
}
|
||||
sequence_value += place_value * (
|
||||
*cp >= U'A'
|
||||
? 10u + static_cast<uint32_t>(*cp - (*cp >= U'a' ? U'a' : U'A'))
|
||||
@ -507,14 +504,21 @@ namespace toml::impl
|
||||
TOML_ERROR_CHECK({});
|
||||
}
|
||||
|
||||
if ((sequence_value > 0xD7FFu && sequence_value < 0xE000u) || sequence_value > 0x10FFFFu)
|
||||
if (is_unicode_surrogate(sequence_value))
|
||||
abort_with_error(
|
||||
"Encountered unknown unicode scalar sequence while parsing "sv,
|
||||
(MULTI_LINE ? "multi-line "sv : ""sv),
|
||||
node_type::string
|
||||
"Encountered illegal unicode scalar sequence while parsing "sv,
|
||||
(MultiLine ? "multi-line "sv : ""sv),
|
||||
node_type::string,
|
||||
"; unicode surrogates (U+D800 - U+DFFF) are explicitly prohibited."sv
|
||||
);
|
||||
|
||||
if (sequence_value <= 0x7Fu) //ascii
|
||||
else if (sequence_value > 0x10FFFFu)
|
||||
abort_with_error(
|
||||
"Encountered illegal unicode scalar sequence while parsing "sv,
|
||||
(MultiLine ? "multi-line "sv : ""sv),
|
||||
node_type::string,
|
||||
"; scalar values greater than U+10FFFF are invalid."sv
|
||||
);
|
||||
else if (sequence_value <= 0x7Fu) //ascii
|
||||
str += static_cast<string_char>(sequence_value & 0x7Fu);
|
||||
else if (sequence_value <= 0x7FFu)
|
||||
{
|
||||
@ -541,7 +545,7 @@ namespace toml::impl
|
||||
default:
|
||||
abort_with_error(
|
||||
"Encountered unexpected character while parsing "sv,
|
||||
(MULTI_LINE ? "multi-line "sv : ""sv),
|
||||
(MultiLine ? "multi-line "sv : ""sv),
|
||||
node_type::string,
|
||||
"; unknown escape sequence '\\"sv, *cp, "'"sv
|
||||
);
|
||||
@ -552,7 +556,7 @@ namespace toml::impl
|
||||
// handle closing delimiters
|
||||
if (*cp == U'"')
|
||||
{
|
||||
if constexpr (MULTI_LINE)
|
||||
if constexpr (MultiLine)
|
||||
{
|
||||
advance();
|
||||
eof_check();
|
||||
@ -607,7 +611,7 @@ namespace toml::impl
|
||||
}
|
||||
|
||||
// handle line endings in multi-line mode
|
||||
if constexpr (MULTI_LINE)
|
||||
if constexpr (MultiLine)
|
||||
{
|
||||
if (is_line_break(*cp))
|
||||
{
|
||||
@ -619,18 +623,31 @@ namespace toml::impl
|
||||
}
|
||||
}
|
||||
|
||||
// handle illegal characters
|
||||
if (*cp <= U'\u0008'
|
||||
|| (*cp >= U'\u000A' && *cp <= U'\u001F')
|
||||
|| *cp == U'\u007F')
|
||||
// handle control characters
|
||||
if (is_nontab_control_character(*cp))
|
||||
abort_with_error(
|
||||
"Encountered unexpected character while parsing "sv,
|
||||
(MULTI_LINE ? "multi-line "sv : ""sv),
|
||||
(MultiLine ? "multi-line "sv : ""sv),
|
||||
node_type::string,
|
||||
"; control characters must be escaped with back-slashes."sv
|
||||
"; unescaped control characters other than TAB (U+0009) are explicitly "
|
||||
"prohibited from appearing in strings."sv
|
||||
);
|
||||
|
||||
if constexpr (MULTI_LINE)
|
||||
// handle surrogates in strings (1.0.0 and later)
|
||||
if constexpr (TOML_LANG_AT_LEAST(1, 0, 0))
|
||||
{
|
||||
if (is_unicode_surrogate(*cp))
|
||||
abort_with_error(
|
||||
"Encountered unexpected character while parsing "sv,
|
||||
(MultiLine ? "multi-line "sv : ""sv),
|
||||
node_type::string,
|
||||
"; unescaped unicode surrogates (U+D800 to U+DFFF) are explicitly "
|
||||
"prohibited from appearing in strings."sv
|
||||
);
|
||||
}
|
||||
TOML_ERROR_CHECK({});
|
||||
|
||||
if constexpr (MultiLine)
|
||||
{
|
||||
if (!skipping_whitespace || !is_whitespace(*cp))
|
||||
{
|
||||
@ -648,14 +665,14 @@ namespace toml::impl
|
||||
|
||||
abort_with_error(
|
||||
"Encountered EOF while parsing "sv,
|
||||
(MULTI_LINE ? "multi-line "sv : ""sv),
|
||||
(MultiLine ? "multi-line "sv : ""sv),
|
||||
node_type::string
|
||||
);
|
||||
TOML_ERROR_CHECK({});
|
||||
TOML_UNREACHABLE;
|
||||
}
|
||||
|
||||
template <bool MULTI_LINE>
|
||||
template <bool MultiLine>
|
||||
[[nodiscard]]
|
||||
TOML_NEVER_INLINE
|
||||
string parse_literal_string() TOML_MAY_THROW
|
||||
@ -669,7 +686,7 @@ namespace toml::impl
|
||||
if (!cp)
|
||||
abort_with_error(
|
||||
"Encountered EOF while parsing "sv,
|
||||
(MULTI_LINE ? "multi-line "sv : ""sv),
|
||||
(MultiLine ? "multi-line "sv : ""sv),
|
||||
"literal "sv, node_type::string
|
||||
);
|
||||
};
|
||||
@ -686,7 +703,7 @@ namespace toml::impl
|
||||
// handle closing delimiters
|
||||
if (*cp == U'\'')
|
||||
{
|
||||
if constexpr (MULTI_LINE)
|
||||
if constexpr (MultiLine)
|
||||
{
|
||||
advance();
|
||||
eof_check();
|
||||
@ -720,7 +737,7 @@ namespace toml::impl
|
||||
}
|
||||
|
||||
// handle line endings in multi-line mode
|
||||
if constexpr (MULTI_LINE)
|
||||
if constexpr (MultiLine)
|
||||
{
|
||||
if (is_line_break(*cp))
|
||||
{
|
||||
@ -731,24 +748,37 @@ namespace toml::impl
|
||||
}
|
||||
}
|
||||
|
||||
// handle illegal characters
|
||||
if (*cp <= U'\u0008'
|
||||
|| (*cp >= U'\u000A' && *cp <= U'\u001F')
|
||||
|| *cp == U'\u007F')
|
||||
// handle control characters
|
||||
if (is_nontab_control_character(*cp))
|
||||
abort_with_error(
|
||||
"Encountered unexpected character while parsing "sv,
|
||||
(MULTI_LINE ? "multi-line "sv : ""sv),
|
||||
(MultiLine ? "multi-line "sv : ""sv),
|
||||
"literal "sv, node_type::string,
|
||||
"; control characters may not appear in literal strings"sv
|
||||
"; control characters other than TAB (U+0009) are explicitly prohibited from appearing "
|
||||
"in literal strings."sv
|
||||
);
|
||||
|
||||
// handle surrogates in strings (1.0.0 and later)
|
||||
if constexpr (TOML_LANG_AT_LEAST(1, 0, 0))
|
||||
{
|
||||
if (is_unicode_surrogate(*cp))
|
||||
abort_with_error(
|
||||
"Encountered unexpected character while parsing "sv,
|
||||
(MultiLine ? "multi-line "sv : ""sv),
|
||||
"literal "sv, node_type::string,
|
||||
"; unicode surrogates (U+D800 - U+DFFF) are explicitly "
|
||||
"prohibited from appearing in literal strings."sv
|
||||
);
|
||||
}
|
||||
TOML_ERROR_CHECK({});
|
||||
|
||||
str.append(cp->as_view());
|
||||
advance();
|
||||
TOML_ERROR_CHECK({});
|
||||
}
|
||||
|
||||
abort_with_error("Encountered EOF while parsing "sv,
|
||||
(MULTI_LINE ? "multi-line "sv : ""sv),
|
||||
(MultiLine ? "multi-line "sv : ""sv),
|
||||
"literal "sv, node_type::string
|
||||
);
|
||||
TOML_ERROR_CHECK({});
|
||||
@ -767,7 +797,11 @@ namespace toml::impl
|
||||
advance();
|
||||
TOML_ERROR_CHECK({});
|
||||
if (!cp)
|
||||
{
|
||||
abort_with_error("Encountered EOF while parsing "sv, node_type::string);
|
||||
TOML_ERROR_CHECK({});
|
||||
TOML_UNREACHABLE;
|
||||
}
|
||||
const auto second = cp->value;
|
||||
advance();
|
||||
TOML_ERROR_CHECK({});
|
||||
@ -779,12 +813,15 @@ namespace toml::impl
|
||||
{
|
||||
if (second == first)
|
||||
return string{};
|
||||
|
||||
abort_with_error("Encountered EOF while parsing "sv, node_type::string);
|
||||
TOML_ERROR_CHECK({});
|
||||
TOML_UNREACHABLE;
|
||||
}
|
||||
|
||||
// if the first three characters are all the same string delimiter then
|
||||
// it's a multi-line string.
|
||||
if (first == second && first == third)
|
||||
else if (first == second && first == third)
|
||||
{
|
||||
return first == U'\''
|
||||
? parse_literal_string<true>()
|
||||
@ -946,10 +983,13 @@ namespace toml::impl
|
||||
if (*cp == U'_')
|
||||
{
|
||||
if (!prev || !is_decimal_digit(*prev))
|
||||
{
|
||||
abort_with_error(
|
||||
"Encountered unexpected character while parsing "sv, node_type::floating_point,
|
||||
"; underscores may only follow digits"sv
|
||||
);
|
||||
break;
|
||||
}
|
||||
prev = cp;
|
||||
advance();
|
||||
TOML_ERROR_CHECK({});
|
||||
@ -963,7 +1003,7 @@ namespace toml::impl
|
||||
"Encountered unexpected character while parsing "sv, node_type::floating_point,
|
||||
"; decimal points may appear only once"sv
|
||||
);
|
||||
if (seen_exponent)
|
||||
else if (seen_exponent)
|
||||
abort_with_error(
|
||||
"Encountered unexpected character while parsing "sv, node_type::floating_point,
|
||||
"; decimal points may not appear after exponents"sv
|
||||
@ -986,7 +1026,7 @@ namespace toml::impl
|
||||
"Encountered unexpected character while parsing "sv, node_type::floating_point,
|
||||
"; exponent signs must immediately follow 'e'"sv
|
||||
);
|
||||
if (seen_exponent_sign)
|
||||
else if (seen_exponent_sign)
|
||||
abort_with_error(
|
||||
"Encountered unexpected character while parsing "sv, node_type::floating_point,
|
||||
"; exponents signs may appear only once"sv
|
||||
@ -997,19 +1037,20 @@ namespace toml::impl
|
||||
abort_with_error("Encountered unexpected character while parsing "sv,
|
||||
node_type::floating_point, "; expected decimal digit, saw '"sv, *cp, '\''
|
||||
);
|
||||
|
||||
if (length == sizeof(chars))
|
||||
else if (length == sizeof(chars))
|
||||
abort_with_error(
|
||||
"Error parsing "sv, node_type::floating_point,
|
||||
"; exceeds maximum length of "sv, sizeof(chars), " characters"sv
|
||||
);
|
||||
TOML_ERROR_CHECK({});
|
||||
|
||||
chars[length++] = static_cast<char>(cp->bytes[0]);
|
||||
prev = cp;
|
||||
advance();
|
||||
|
||||
TOML_ERROR_CHECK({});
|
||||
}
|
||||
TOML_ERROR_CHECK({});
|
||||
|
||||
if (prev && *prev == U'_')
|
||||
{
|
||||
eof_check();
|
||||
@ -1017,25 +1058,13 @@ namespace toml::impl
|
||||
"Encountered unexpected character while parsing "sv, node_type::floating_point,
|
||||
"; expected decimal digit, saw '"sv, *cp, '\''
|
||||
);
|
||||
TOML_ERROR_CHECK({});
|
||||
TOML_UNREACHABLE;
|
||||
}
|
||||
|
||||
TOML_ERROR_CHECK({});
|
||||
|
||||
// convert to double
|
||||
double result;
|
||||
#if TOML_USE_STREAMS_FOR_FLOATS
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss.write(chars, static_cast<std::streamsize>(length));
|
||||
if ((ss >> result))
|
||||
return result * sign;
|
||||
else
|
||||
abort_with_error(
|
||||
"Error parsing "sv, node_type::floating_point,
|
||||
"; '"sv, std::string_view{ chars, length }, "' could not be interpreted as a value"sv
|
||||
);
|
||||
}
|
||||
#else
|
||||
#if TOML_FLOATING_POINT_CHARCONV
|
||||
{
|
||||
auto fc_result = std::from_chars(chars, chars + length, result);
|
||||
switch (fc_result.ec)
|
||||
@ -1065,12 +1094,24 @@ namespace toml::impl
|
||||
);
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss.write(chars, static_cast<std::streamsize>(length));
|
||||
if ((ss >> result))
|
||||
return result * sign;
|
||||
else
|
||||
abort_with_error(
|
||||
"Error parsing "sv, node_type::floating_point,
|
||||
"; '"sv, std::string_view{ chars, length }, "' could not be interpreted as a value"sv
|
||||
);
|
||||
}
|
||||
#endif
|
||||
TOML_ERROR_CHECK({});
|
||||
TOML_UNREACHABLE;
|
||||
}
|
||||
|
||||
#if TOML_LANG_HIGHER_THAN(0, 5, 0) // toml/issues/562
|
||||
#if TOML_LANG_UNRELEASED // toml/issues/562 (hexfloats)
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_NEVER_INLINE
|
||||
@ -1119,10 +1160,14 @@ namespace toml::impl
|
||||
if (*cp == U'_')
|
||||
{
|
||||
if (!prev || !is_hexadecimal_digit(*prev))
|
||||
{
|
||||
abort_with_error(
|
||||
"Encountered unexpected character while parsing hexadecimal "sv,
|
||||
node_type::floating_point, "; underscores may only follow digits"sv
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
prev = cp;
|
||||
advance();
|
||||
TOML_ERROR_CHECK({});
|
||||
@ -1136,7 +1181,7 @@ namespace toml::impl
|
||||
"Encountered unexpected character while parsing hexadecimal "sv,
|
||||
node_type::floating_point, "; decimal points may appear only once"sv
|
||||
);
|
||||
if (seen_exponent)
|
||||
else if (seen_exponent)
|
||||
abort_with_error(
|
||||
"Encountered unexpected character while parsing "sv, node_type::floating_point,
|
||||
"; decimal points may not appear after exponents"sv
|
||||
@ -1150,7 +1195,7 @@ namespace toml::impl
|
||||
"Encountered unexpected character while parsing hexadecimal "sv,
|
||||
node_type::floating_point, "; exponents may appear only once"sv
|
||||
);
|
||||
if (!seen_decimal)
|
||||
else if (!seen_decimal)
|
||||
abort_with_error(
|
||||
"Encountered unexpected character while parsing hexadecimal "sv,
|
||||
node_type::floating_point, "; exponents may not appear before decimal points"sv
|
||||
@ -1164,36 +1209,35 @@ namespace toml::impl
|
||||
"Encountered unexpected character while parsing hexadecimal "sv,
|
||||
node_type::floating_point, "; exponent signs must immediately follow 'p'"sv
|
||||
);
|
||||
if (seen_exponent_sign)
|
||||
else if (seen_exponent_sign)
|
||||
abort_with_error(
|
||||
"Encountered unexpected character while parsing hexadecimal "sv,
|
||||
node_type::floating_point, "; exponents signs may appear only once"sv
|
||||
);
|
||||
seen_exponent_sign = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!seen_exponent && !is_hexadecimal_digit(*cp))
|
||||
abort_with_error("Encountered unexpected character while parsing hexadecimal "sv,
|
||||
node_type::floating_point, "; expected hexadecimal digit, saw '"sv, *cp, '\''
|
||||
);
|
||||
else if (seen_exponent && !is_decimal_digit(*cp))
|
||||
abort_with_error("Encountered unexpected character while parsing hexadecimal "sv,
|
||||
node_type::floating_point, " exponent; expected decimal digit, saw '"sv, *cp, '\''
|
||||
);
|
||||
}
|
||||
|
||||
if (length == sizeof(chars))
|
||||
else if (!seen_exponent && !is_hexadecimal_digit(*cp))
|
||||
abort_with_error("Encountered unexpected character while parsing hexadecimal "sv,
|
||||
node_type::floating_point, "; expected hexadecimal digit, saw '"sv, *cp, '\''
|
||||
);
|
||||
else if (seen_exponent && !is_decimal_digit(*cp))
|
||||
abort_with_error("Encountered unexpected character while parsing hexadecimal "sv,
|
||||
node_type::floating_point, " exponent; expected decimal digit, saw '"sv, *cp, '\''
|
||||
);
|
||||
else if (length == sizeof(chars))
|
||||
abort_with_error(
|
||||
"Error parsing hexadecimal "sv, node_type::floating_point,
|
||||
"; exceeds maximum length of "sv, sizeof(chars), " characters"sv
|
||||
);
|
||||
);
|
||||
TOML_ERROR_CHECK({});
|
||||
|
||||
chars[length++] = static_cast<char>(cp->bytes[0]);
|
||||
prev = cp;
|
||||
advance();
|
||||
|
||||
TOML_ERROR_CHECK({});
|
||||
}
|
||||
TOML_ERROR_CHECK({});
|
||||
|
||||
if (prev && *prev == U'_')
|
||||
{
|
||||
eof_check();
|
||||
@ -1207,33 +1251,14 @@ namespace toml::impl
|
||||
"Encountered unexpected character while parsing hexadecimal "sv,
|
||||
node_type::floating_point, "; expected hexadecimal digit, saw '"sv, *cp, '\''
|
||||
);
|
||||
TOML_ERROR_CHECK({});
|
||||
TOML_UNREACHABLE;
|
||||
}
|
||||
|
||||
TOML_ERROR_CHECK({});
|
||||
|
||||
// convert to double
|
||||
double result;
|
||||
#if TOML_USE_STREAMS_FOR_FLOATS
|
||||
{
|
||||
std::string str;
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss.write("0x", 2_sz);
|
||||
ss.write(chars, static_cast<std::streamsize>(length));
|
||||
str = std::move(ss).str();
|
||||
}
|
||||
|
||||
char* end = {};
|
||||
result = std::strtod(str.c_str(), &end);
|
||||
if (result == 0.0 && end == str.c_str())
|
||||
abort_with_error(
|
||||
"Error parsing hexadecimal "sv, node_type::floating_point,
|
||||
"; '"sv, std::string_view{ chars, length }, "' could not be interpreted as a value"sv
|
||||
);
|
||||
else
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
#if TOML_FLOATING_POINT_CHARCONV
|
||||
{
|
||||
auto fc_result = std::from_chars(chars, chars + length, result, std::chars_format::hex);
|
||||
switch (fc_result.ec)
|
||||
@ -1263,12 +1288,32 @@ namespace toml::impl
|
||||
);
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
std::string str;
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss.write("0x", 2_sz);
|
||||
ss.write(chars, static_cast<std::streamsize>(length));
|
||||
str = std::move(ss).str();
|
||||
}
|
||||
|
||||
char* end = {};
|
||||
result = std::strtod(str.c_str(), &end);
|
||||
if (result == 0.0 && end == str.c_str())
|
||||
abort_with_error(
|
||||
"Error parsing hexadecimal "sv, node_type::floating_point,
|
||||
"; '"sv, std::string_view{ chars, length }, "' could not be interpreted as a value"sv
|
||||
);
|
||||
else
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
TOML_ERROR_CHECK({});
|
||||
TOML_UNREACHABLE;
|
||||
}
|
||||
|
||||
#endif //TOML_LANG_HIGHER_THAN(0, 5, 0)
|
||||
#endif // TOML_LANG_UNRELEASED
|
||||
|
||||
template <int base>
|
||||
[[nodiscard]]
|
||||
@ -1361,7 +1406,7 @@ namespace toml::impl
|
||||
' ', node_type::integer, "; expected "sv, traits::qualifier,
|
||||
" digit, saw '"sv, *cp, '\''
|
||||
);
|
||||
if (length == sizeof(chars))
|
||||
else if (length == sizeof(chars))
|
||||
abort_with_error(
|
||||
"Error parsing "sv, traits::qualifier, ' ', node_type::integer,
|
||||
"; exceeds maximum length of "sv, sizeof(chars), " characters"sv
|
||||
@ -1632,16 +1677,15 @@ namespace toml::impl
|
||||
static_cast<uint8_t>(minute),
|
||||
};
|
||||
|
||||
if constexpr (!TOML_LANG_HIGHER_THAN(0, 5, 0)) // toml/issues/671
|
||||
// ':'
|
||||
if constexpr (!TOML_LANG_UNRELEASED) // toml/issues/671 (allow omission of seconds)
|
||||
{
|
||||
// ':'
|
||||
eof_check();
|
||||
if (*cp != U':')
|
||||
abort_with_error(
|
||||
"Encountered unexpected character while parsing "sv, type,
|
||||
"; expected ':', saw '"sv, *cp, '\''
|
||||
);
|
||||
advance();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1657,11 +1701,8 @@ namespace toml::impl
|
||||
TOML_ERROR_CHECK({});
|
||||
if (!cp || *cp != U':')
|
||||
return time;
|
||||
|
||||
// ':'
|
||||
advance();
|
||||
}
|
||||
|
||||
advance();
|
||||
TOML_ERROR_CHECK({});
|
||||
|
||||
// "SS"
|
||||
@ -1712,11 +1753,12 @@ namespace toml::impl
|
||||
"; expected fractional digits, saw '"sv,
|
||||
*cp, '\''
|
||||
);
|
||||
if (digit_count == max_fractional_digits && cp && is_decimal_digit(*cp))
|
||||
else if (digit_count == max_fractional_digits && cp && is_decimal_digit(*cp))
|
||||
abort_with_error(
|
||||
"Error parsing "sv, type,
|
||||
"Fractional component exceeds maximum precision of "sv, max_fractional_digits
|
||||
);
|
||||
TOML_ERROR_CHECK({});
|
||||
|
||||
uint32_t value = 0u;
|
||||
uint32_t place = 1u;
|
||||
@ -1884,12 +1926,11 @@ namespace toml::impl
|
||||
else if (*cp == U'[')
|
||||
{
|
||||
val = parse_array();
|
||||
if constexpr (!TOML_LANG_HIGHER_THAN(0, 5, 0)) // toml/issues/665
|
||||
if constexpr (!TOML_LANG_AT_LEAST(1, 0, 0)) // toml/issues/665 (heterogeneous arrays)
|
||||
{
|
||||
// arrays must be homogeneous in toml 0.5.0 and earlier
|
||||
if (!val->ref_cast<array>().is_homogeneous())
|
||||
TOML_ERROR(
|
||||
"Arrays cannot contain values of different types in TOML 0.5.0 and earlier.",
|
||||
"Arrays cannot contain values of different types before TOML 1.0.0.",
|
||||
begin_pos,
|
||||
reader.source_path()
|
||||
);
|
||||
@ -2075,16 +2116,16 @@ namespace toml::impl
|
||||
{
|
||||
if (chars[i] == U'p' || chars[i] == U'P')
|
||||
{
|
||||
#if !TOML_LANG_HIGHER_THAN(0, 5, 0) // toml/issues/562
|
||||
#if TOML_LANG_UNRELEASED // toml/issues/562 - hexfloats
|
||||
val = std::make_unique<value<double>>(parse_hex_float());
|
||||
break;
|
||||
#else
|
||||
TOML_ERROR(
|
||||
"Hexadecimal floating-point values are not supported "
|
||||
"in TOML 0.5.0 and earlier.",
|
||||
"in TOML 1.0.0 and earlier.",
|
||||
begin_pos,
|
||||
reader.source_path()
|
||||
);
|
||||
#else
|
||||
val = std::make_unique<value<double>>(parse_hex_float());
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -2221,6 +2262,7 @@ namespace toml::impl
|
||||
{
|
||||
abort_with_error("Could not determine value type"sv);
|
||||
TOML_ERROR_CHECK({});
|
||||
TOML_UNREACHABLE;
|
||||
}
|
||||
|
||||
val->source_ = { begin_pos, current_position(1), reader.source_path() };
|
||||
@ -2247,15 +2289,15 @@ namespace toml::impl
|
||||
abort_with_error("Encountered EOF while parsing key"sv);
|
||||
|
||||
// bare_key_segment
|
||||
#if TOML_LANG_HIGHER_THAN(0, 5, 0) // toml/issues/687
|
||||
if (is_unicode_combining_mark(*cp))
|
||||
#if TOML_LANG_UNRELEASED // toml/issues/687 (unicode bare keys)
|
||||
else if (is_unicode_combining_mark(*cp))
|
||||
abort_with_error(
|
||||
"Encountered unexpected character while parsing key; expected bare key starting character "
|
||||
"or string delimiter, saw combining mark '"sv, *cp, '\''
|
||||
);
|
||||
else
|
||||
#endif
|
||||
if (is_bare_key_start_character(*cp))
|
||||
|
||||
else if (is_bare_key_start_character(*cp))
|
||||
key.segments.push_back(parse_bare_key_segment());
|
||||
|
||||
// "quoted key segment"
|
||||
@ -2270,6 +2312,7 @@ namespace toml::impl
|
||||
);
|
||||
|
||||
consume_leading_whitespace();
|
||||
TOML_ERROR_CHECK({});
|
||||
|
||||
// eof or no more key to come
|
||||
if (!cp)
|
||||
@ -2325,6 +2368,7 @@ namespace toml::impl
|
||||
"expected '=', saw '"sv, *cp, '\''
|
||||
);
|
||||
advance();
|
||||
TOML_ERROR_CHECK({});
|
||||
|
||||
// skip past any whitespace that followed the '='
|
||||
consume_leading_whitespace();
|
||||
@ -2378,7 +2422,7 @@ namespace toml::impl
|
||||
eof_check();
|
||||
|
||||
// sanity-check the key start
|
||||
#if TOML_LANG_HIGHER_THAN(0, 5, 0) // toml/issues/687
|
||||
#if TOML_LANG_UNRELEASED // toml/issues/687 (unicode bare keys)
|
||||
if (is_unicode_combining_mark(*cp))
|
||||
abort_with_error(
|
||||
"Encountered unexpected character while parsing table key; "
|
||||
@ -2634,7 +2678,7 @@ namespace toml::impl
|
||||
// bare_keys
|
||||
// dotted.keys
|
||||
// "quoted keys"
|
||||
#if TOML_LANG_HIGHER_THAN(0, 5, 0) // toml/issues/687
|
||||
#if TOML_LANG_UNRELEASED // toml/issues/687 (unicode bare keys)
|
||||
else if (is_unicode_combining_mark(*cp))
|
||||
abort_with_error(
|
||||
"Encountered unexpected character while parsing key; "
|
||||
@ -2871,7 +2915,7 @@ namespace toml::impl
|
||||
{
|
||||
TOML_ERROR_CHECK({});
|
||||
|
||||
if constexpr (TOML_LANG_HIGHER_THAN(0, 5, 0)) // toml/issues/516
|
||||
if constexpr (TOML_LANG_UNRELEASED) // toml/issues/516 (newlines/trailing commas in inline tables)
|
||||
{
|
||||
while (consume_leading_whitespace()
|
||||
|| consume_line_break()
|
||||
@ -2904,7 +2948,7 @@ namespace toml::impl
|
||||
// closing '}'
|
||||
else if (*cp == U'}')
|
||||
{
|
||||
if constexpr (!TOML_LANG_HIGHER_THAN(0, 5, 0)) // toml/issues/516
|
||||
if constexpr (!TOML_LANG_UNRELEASED) // toml/issues/516 (newlines/trailing commas in inline tables)
|
||||
{
|
||||
if (prev == comma)
|
||||
{
|
||||
@ -2921,7 +2965,7 @@ namespace toml::impl
|
||||
}
|
||||
|
||||
// key-value pair
|
||||
#if TOML_LANG_HIGHER_THAN(0, 5, 0) // toml/issues/687
|
||||
#if TOML_LANG_UNRELEASED // toml/issues/687 (unicode bare keys)
|
||||
else if (is_unicode_combining_mark(*cp))
|
||||
{
|
||||
abort_with_error(
|
||||
|
@ -12,63 +12,63 @@ namespace toml::impl
|
||||
// - I'm using <charconv> to format numerics. Faster and locale-independent.
|
||||
// - I can avoid forcing users to drag in <sstream> and <iomanip>.
|
||||
|
||||
// Q: "there's a lot of reinterpret_casting here, is any of it UB?"
|
||||
// Q: "there's a bit of reinterpret_casting here, is any of it UB?"
|
||||
// A: - If the source string data is char and the output string is char8_t, then technically yes,
|
||||
// but not in the other direction. I test in both modes on Clang, GCC and MSVC and have yet to
|
||||
// see it actually causing an issue, but in the event it does present a problem it's not going to
|
||||
// be a show-stopper since all it means is I need to do duplicate some code.
|
||||
// - Strings in C++. Honestly.
|
||||
|
||||
template <typename CHAR1, typename CHAR2>
|
||||
template <typename Char1, typename Char2>
|
||||
TOML_ALWAYS_INLINE
|
||||
void print_to_stream(std::basic_string_view<CHAR1> str, std::basic_ostream<CHAR2>& stream)
|
||||
void print_to_stream(std::basic_string_view<Char1> str, std::basic_ostream<Char2>& stream)
|
||||
{
|
||||
static_assert(sizeof(CHAR1) == 1);
|
||||
static_assert(sizeof(CHAR2) == 1);
|
||||
stream.write(reinterpret_cast<const CHAR2*>(str.data()), static_cast<std::streamsize>(str.length()));
|
||||
static_assert(sizeof(Char1) == 1);
|
||||
static_assert(sizeof(Char2) == 1);
|
||||
stream.write(reinterpret_cast<const Char2*>(str.data()), static_cast<std::streamsize>(str.length()));
|
||||
}
|
||||
|
||||
template <typename CHAR1, typename CHAR2>
|
||||
template <typename Char1, typename Char2>
|
||||
TOML_ALWAYS_INLINE
|
||||
void print_to_stream(const std::basic_string<CHAR1>& str, std::basic_ostream<CHAR2>& stream)
|
||||
void print_to_stream(const std::basic_string<Char1>& str, std::basic_ostream<Char2>& stream)
|
||||
{
|
||||
static_assert(sizeof(CHAR1) == 1);
|
||||
static_assert(sizeof(CHAR2) == 1);
|
||||
stream.write(reinterpret_cast<const CHAR2*>(str.data()), static_cast<std::streamsize>(str.length()));
|
||||
static_assert(sizeof(Char1) == 1);
|
||||
static_assert(sizeof(Char2) == 1);
|
||||
stream.write(reinterpret_cast<const Char2*>(str.data()), static_cast<std::streamsize>(str.length()));
|
||||
}
|
||||
|
||||
template <typename CHAR>
|
||||
template <typename Char>
|
||||
TOML_ALWAYS_INLINE
|
||||
void print_to_stream(char character, std::basic_ostream<CHAR>& stream)
|
||||
void print_to_stream(char character, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(CHAR) == 1);
|
||||
stream.put(static_cast<CHAR>(character));
|
||||
static_assert(sizeof(Char) == 1);
|
||||
stream.put(static_cast<Char>(character));
|
||||
}
|
||||
|
||||
template <typename CHAR>
|
||||
template <typename Char>
|
||||
TOML_GNU_ATTR(nonnull) TOML_ALWAYS_INLINE
|
||||
void print_to_stream(const char* str, size_t len, std::basic_ostream<CHAR>& stream)
|
||||
void print_to_stream(const char* str, size_t len, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(CHAR) == 1);
|
||||
stream.write(reinterpret_cast<const CHAR*>(str), static_cast<std::streamsize>(len));
|
||||
static_assert(sizeof(Char) == 1);
|
||||
stream.write(reinterpret_cast<const Char*>(str), static_cast<std::streamsize>(len));
|
||||
}
|
||||
|
||||
#if defined(__cpp_lib_char8_t)
|
||||
|
||||
template <typename CHAR>
|
||||
template <typename Char>
|
||||
TOML_ALWAYS_INLINE
|
||||
void print_to_stream(char8_t character, std::basic_ostream<CHAR>& stream)
|
||||
void print_to_stream(char8_t character, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(CHAR) == 1);
|
||||
stream.put(static_cast<CHAR>(character));
|
||||
static_assert(sizeof(Char) == 1);
|
||||
stream.put(static_cast<Char>(character));
|
||||
}
|
||||
|
||||
template <typename CHAR>
|
||||
template <typename Char>
|
||||
TOML_GNU_ATTR(nonnull) TOML_ALWAYS_INLINE
|
||||
void print_to_stream(const char8_t* str, size_t len, std::basic_ostream<CHAR>& stream)
|
||||
void print_to_stream(const char8_t* str, size_t len, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(CHAR) == 1);
|
||||
stream.write(reinterpret_cast<const CHAR*>(str), static_cast<std::streamsize>(len));
|
||||
static_assert(sizeof(Char) == 1);
|
||||
stream.write(reinterpret_cast<const Char*>(str), static_cast<std::streamsize>(len));
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -85,11 +85,11 @@ namespace toml::impl
|
||||
template <> inline constexpr size_t charconv_buffer_length<uint16_t> = 5; // strlen("65535")
|
||||
template <> inline constexpr size_t charconv_buffer_length<uint8_t> = 3; // strlen("255")
|
||||
|
||||
template <typename T, typename CHAR>
|
||||
inline void print_integer_to_stream(T val, std::basic_ostream<CHAR>& stream)
|
||||
template <typename T, typename Char>
|
||||
inline void print_integer_to_stream(T val, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(
|
||||
sizeof(CHAR) == 1,
|
||||
sizeof(Char) == 1,
|
||||
"The stream's underlying character type must be 1 byte in size."
|
||||
);
|
||||
|
||||
@ -99,11 +99,11 @@ namespace toml::impl
|
||||
}
|
||||
|
||||
#define TOML_P2S_OVERLOAD(type) \
|
||||
template <typename CHAR> \
|
||||
template <typename Char> \
|
||||
TOML_ALWAYS_INLINE \
|
||||
void print_to_stream(type val, std::basic_ostream<CHAR>& stream) \
|
||||
void print_to_stream(type val, std::basic_ostream<Char>& stream) \
|
||||
{ \
|
||||
static_assert(sizeof(CHAR) == 1); \
|
||||
static_assert(sizeof(Char) == 1); \
|
||||
print_integer_to_stream(val, stream); \
|
||||
}
|
||||
|
||||
@ -118,11 +118,12 @@ namespace toml::impl
|
||||
|
||||
#undef TOML_P2S_OVERLOAD
|
||||
|
||||
template <typename T, typename CHAR>
|
||||
inline void print_floating_point_to_stream(T val, std::basic_ostream<CHAR>& stream, bool hexfloat = false)
|
||||
template <typename T, typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
void print_floating_point_to_stream(T val, std::basic_ostream<Char>& stream, bool hexfloat = false)
|
||||
{
|
||||
static_assert(
|
||||
sizeof(CHAR) == 1,
|
||||
sizeof(Char) == 1,
|
||||
"The stream's underlying character type must be 1 byte in size."
|
||||
);
|
||||
|
||||
@ -134,19 +135,7 @@ namespace toml::impl
|
||||
return true;
|
||||
};
|
||||
|
||||
#if TOML_USE_STREAMS_FOR_FLOATS
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss.precision(std::numeric_limits<T>::digits10 + 1);
|
||||
if (hexfloat)
|
||||
ss << std::hexfloat;
|
||||
ss << val;
|
||||
const auto str = std::move(ss).str();
|
||||
print_to_stream(str, stream);
|
||||
if (needs_decimal_point(str))
|
||||
print_to_stream(".0"sv, stream);
|
||||
}
|
||||
#else
|
||||
#if TOML_FLOATING_POINT_CHARCONV
|
||||
{
|
||||
char buf[charconv_buffer_length<T>];
|
||||
const auto res = hexfloat
|
||||
@ -154,18 +143,43 @@ namespace toml::impl
|
||||
: std::to_chars(buf, buf + sizeof(buf), val);
|
||||
const auto str = std::string_view{ buf, static_cast<size_t>(res.ptr - buf) };
|
||||
print_to_stream(str, stream);
|
||||
if (needs_decimal_point(str))
|
||||
if (!hexfloat && needs_decimal_point(str))
|
||||
print_to_stream(".0"sv, stream);
|
||||
}
|
||||
#else
|
||||
{
|
||||
char buf[charconv_buffer_length<T> + 1_sz];
|
||||
int len = -1;
|
||||
if (hexfloat)
|
||||
len = snprintf(buf, charconv_buffer_length<T> + 1_sz, "%a", static_cast<double>(val));
|
||||
else
|
||||
len = snprintf(
|
||||
buf, charconv_buffer_length<T> + 1_sz, "%.*g",
|
||||
std::numeric_limits<T>::digits10 + 1, static_cast<double>(val)
|
||||
);
|
||||
TOML_ASSERT(len > 0);
|
||||
len = static_cast<int>(charconv_buffer_length<T>) < len
|
||||
? static_cast<int>(charconv_buffer_length<T>)
|
||||
: len;
|
||||
const auto str = std::string_view{ buf, static_cast<size_t>(len) };
|
||||
print_to_stream(str, stream);
|
||||
if (!hexfloat && needs_decimal_point(str))
|
||||
print_to_stream(".0"sv, stream);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
extern template TOML_API void print_floating_point_to_stream(float, std::ostream&, bool);
|
||||
extern template TOML_API void print_floating_point_to_stream(double, std::ostream&, bool);
|
||||
#endif
|
||||
|
||||
#define TOML_P2S_OVERLOAD(type) \
|
||||
template <typename CHAR> \
|
||||
template <typename Char> \
|
||||
TOML_ALWAYS_INLINE \
|
||||
void print_to_stream(type val, std::basic_ostream<CHAR>& stream) \
|
||||
void print_to_stream(type val, std::basic_ostream<Char>& stream) \
|
||||
{ \
|
||||
static_assert(sizeof(CHAR) == 1); \
|
||||
static_assert(sizeof(Char) == 1); \
|
||||
print_floating_point_to_stream(val, stream); \
|
||||
}
|
||||
|
||||
@ -174,18 +188,18 @@ namespace toml::impl
|
||||
|
||||
#undef TOML_P2S_OVERLOAD
|
||||
|
||||
template <typename CHAR>
|
||||
template <typename Char>
|
||||
TOML_ALWAYS_INLINE
|
||||
void print_to_stream(bool val, std::basic_ostream<CHAR>& stream)
|
||||
void print_to_stream(bool val, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(CHAR) == 1);
|
||||
static_assert(sizeof(Char) == 1);
|
||||
print_to_stream(val ? "true"sv : "false"sv, stream);
|
||||
}
|
||||
|
||||
template <typename T, typename CHAR>
|
||||
inline void print_to_stream(T val, std::basic_ostream<CHAR>& stream, size_t zero_pad_to_digits)
|
||||
template <typename T, typename Char>
|
||||
inline void print_to_stream(T val, std::basic_ostream<Char>& stream, size_t zero_pad_to_digits)
|
||||
{
|
||||
static_assert(sizeof(CHAR) == 1);
|
||||
static_assert(sizeof(Char) == 1);
|
||||
char buf[charconv_buffer_length<T>];
|
||||
const auto res = std::to_chars(buf, buf + sizeof(buf), val);
|
||||
const auto len = static_cast<size_t>(res.ptr - buf);
|
||||
@ -194,10 +208,10 @@ namespace toml::impl
|
||||
print_to_stream(buf, static_cast<size_t>(res.ptr - buf), stream);
|
||||
}
|
||||
|
||||
template <typename CHAR>
|
||||
inline void print_to_stream(const toml::date& val, std::basic_ostream<CHAR>& stream)
|
||||
template <typename Char>
|
||||
inline void print_to_stream(const toml::date& val, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(CHAR) == 1);
|
||||
static_assert(sizeof(Char) == 1);
|
||||
print_to_stream(val.year, stream, 4_sz);
|
||||
print_to_stream('-', stream);
|
||||
print_to_stream(val.month, stream, 2_sz);
|
||||
@ -205,10 +219,10 @@ namespace toml::impl
|
||||
print_to_stream(val.day, stream, 2_sz);
|
||||
}
|
||||
|
||||
template <typename CHAR>
|
||||
inline void print_to_stream(const toml::time& val, std::basic_ostream<CHAR>& stream)
|
||||
template <typename Char>
|
||||
inline void print_to_stream(const toml::time& val, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(CHAR) == 1);
|
||||
static_assert(sizeof(Char) == 1);
|
||||
print_to_stream(val.hour, stream, 2_sz);
|
||||
print_to_stream(':', stream);
|
||||
print_to_stream(val.minute, stream, 2_sz);
|
||||
@ -228,10 +242,10 @@ namespace toml::impl
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CHAR>
|
||||
inline void print_to_stream(toml::time_offset val, std::basic_ostream<CHAR>& stream)
|
||||
template <typename Char>
|
||||
inline void print_to_stream(toml::time_offset val, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(CHAR) == 1);
|
||||
static_assert(sizeof(Char) == 1);
|
||||
if (!val.minutes)
|
||||
print_to_stream('Z', stream);
|
||||
else
|
||||
@ -257,10 +271,10 @@ namespace toml::impl
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CHAR>
|
||||
inline void print_to_stream(const toml::date_time& val, std::basic_ostream<CHAR>& stream)
|
||||
template <typename Char>
|
||||
inline void print_to_stream(const toml::date_time& val, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(CHAR) == 1);
|
||||
static_assert(sizeof(Char) == 1);
|
||||
print_to_stream(val.date, stream);
|
||||
print_to_stream('T', stream);
|
||||
print_to_stream(val.time, stream);
|
||||
@ -271,10 +285,10 @@ namespace toml::impl
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ALL_WARNINGS
|
||||
|
||||
template <typename T, typename CHAR>
|
||||
void print_to_stream_with_escapes(T && str, std::basic_ostream<CHAR>& stream)
|
||||
template <typename T, typename Char>
|
||||
void print_to_stream_with_escapes(T && str, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(CHAR) == 1);
|
||||
static_assert(sizeof(Char) == 1);
|
||||
for (auto c : str)
|
||||
{
|
||||
if (c >= TOML_STRING_PREFIX('\x00') && c <= TOML_STRING_PREFIX('\x1F')) TOML_UNLIKELY
|
||||
@ -311,16 +325,17 @@ namespace toml
|
||||
/// The value for 'bar' was found on line 1, column 7
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam CHAR The output stream's underlying character type. Must be 1 byte in size.
|
||||
/// \tparam Char The output stream's underlying character type. Must be 1 byte in size.
|
||||
/// \param lhs The stream.
|
||||
/// \param rhs The source_position.
|
||||
///
|
||||
/// \returns The input stream.
|
||||
template <typename CHAR>
|
||||
std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const source_position& rhs)
|
||||
template <typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const source_position& rhs)
|
||||
{
|
||||
static_assert(
|
||||
sizeof(CHAR) == 1,
|
||||
sizeof(Char) == 1,
|
||||
"The stream's underlying character type must be 1 byte in size."
|
||||
);
|
||||
impl::print_to_stream("line "sv, lhs);
|
||||
@ -345,16 +360,17 @@ namespace toml
|
||||
/// The value for 'bar' was found on line 1, column 7 of 'config.toml'
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam CHAR The output stream's underlying character type. Must be 1 byte in size.
|
||||
/// \tparam Char The output stream's underlying character type. Must be 1 byte in size.
|
||||
/// \param lhs The stream.
|
||||
/// \param rhs The source_position.
|
||||
///
|
||||
/// \returns The input stream.
|
||||
template <typename CHAR>
|
||||
std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const source_region& rhs)
|
||||
template <typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const source_region& rhs)
|
||||
{
|
||||
static_assert(
|
||||
sizeof(CHAR) == 1,
|
||||
sizeof(Char) == 1,
|
||||
"The stream's underlying character type must be 1 byte in size."
|
||||
);
|
||||
lhs << rhs.begin;
|
||||
@ -386,13 +402,14 @@ namespace toml
|
||||
/// (error occurred at line 1, column 13)
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam CHAR The output stream's underlying character type. Must be 1 byte in size.
|
||||
/// \tparam Char The output stream's underlying character type. Must be 1 byte in size.
|
||||
/// \param lhs The stream.
|
||||
/// \param rhs The parse_error.
|
||||
///
|
||||
/// \returns The input stream.
|
||||
template <typename CHAR>
|
||||
std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const parse_error& rhs)
|
||||
template <typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const parse_error& rhs)
|
||||
{
|
||||
impl::print_to_stream(rhs.description(), lhs);
|
||||
impl::print_to_stream("\n\t(error occurred at "sv, lhs);
|
||||
@ -400,5 +417,10 @@ namespace toml
|
||||
impl::print_to_stream(")"sv, lhs);
|
||||
return lhs;
|
||||
}
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const source_position&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const source_region&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const parse_error&);
|
||||
#endif
|
||||
}
|
||||
|
@ -7,28 +7,23 @@
|
||||
|
||||
namespace toml::impl
|
||||
{
|
||||
template <bool is_const>
|
||||
template <bool IsConst>
|
||||
struct table_proxy_pair final
|
||||
{
|
||||
using value_type = std::conditional_t<is_const, const node, node>;
|
||||
using value_type = std::conditional_t<IsConst, const node, node>;
|
||||
|
||||
const string& key;
|
||||
value_type& value;
|
||||
};
|
||||
|
||||
#if !TOML_ALL_INLINE && !TOML_HAS_API_ANNOTATION
|
||||
extern template struct table_proxy_pair<true>;
|
||||
extern template struct table_proxy_pair<false>;
|
||||
#endif
|
||||
|
||||
template <bool is_const>
|
||||
template <bool IsConst>
|
||||
class table_iterator final
|
||||
{
|
||||
private:
|
||||
friend class toml::table;
|
||||
|
||||
using raw_iterator = std::conditional_t<
|
||||
is_const,
|
||||
IsConst,
|
||||
string_map<std::unique_ptr<node>>::const_iterator,
|
||||
string_map<std::unique_ptr<node>>::iterator
|
||||
>;
|
||||
@ -47,7 +42,7 @@ namespace toml::impl
|
||||
|
||||
table_iterator() noexcept = default;
|
||||
|
||||
using reference = table_proxy_pair<is_const>;
|
||||
using reference = table_proxy_pair<IsConst>;
|
||||
using difference_type = ptrdiff_t;
|
||||
|
||||
table_iterator& operator++() noexcept // ++pre
|
||||
@ -94,11 +89,6 @@ namespace toml::impl
|
||||
}
|
||||
};
|
||||
|
||||
#if !TOML_ALL_INLINE && !TOML_HAS_API_ANNOTATION
|
||||
extern template class table_iterator<true>;
|
||||
extern template class table_iterator<false>;
|
||||
#endif
|
||||
|
||||
struct table_init_pair final
|
||||
{
|
||||
string key;
|
||||
@ -129,8 +119,8 @@ namespace toml
|
||||
{
|
||||
[[nodiscard]] TOML_API bool operator == (const table& lhs, const table& rhs) noexcept;
|
||||
[[nodiscard]] TOML_API bool operator != (const table& lhs, const table& rhs) noexcept;
|
||||
template <typename CHAR>
|
||||
std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>&, const table&);
|
||||
template <typename Char>
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>&, const table&);
|
||||
|
||||
/// \brief A TOML table.
|
||||
///
|
||||
@ -368,17 +358,17 @@ namespace toml
|
||||
/// { a = 1, b = 2, c = 3, d = 42 } //"a" already existed
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam ITER An InputIterator to a collection of key-value pairs.
|
||||
/// \tparam Iter An InputIterator to a collection of key-value pairs.
|
||||
/// \param first An iterator to the first value in the input collection.
|
||||
/// \param last An iterator to one-past-the-last value in the input collection.
|
||||
///
|
||||
/// \remarks This function is morally equivalent to calling `insert(key, value)` for each
|
||||
/// key-value pair covered by the iterator range, so any values with keys already found in the
|
||||
/// table will not be replaced.
|
||||
template <typename ITER, typename = std::enable_if_t<
|
||||
!std::is_convertible_v<ITER&&, string_view>
|
||||
template <typename Iter, typename = std::enable_if_t<
|
||||
!std::is_convertible_v<Iter&&, string_view>
|
||||
>>
|
||||
void insert(ITER first, ITER last) noexcept
|
||||
void insert(Iter first, Iter last) noexcept
|
||||
{
|
||||
if (first == last)
|
||||
return;
|
||||
@ -609,11 +599,11 @@ namespace toml
|
||||
|
||||
private:
|
||||
|
||||
template <typename MAP, typename KEY>
|
||||
[[nodiscard]] static auto do_get(MAP& vals, const KEY& key) noexcept
|
||||
template <typename Map, typename Key>
|
||||
[[nodiscard]] static auto do_get(Map& vals, const Key& key) noexcept
|
||||
{
|
||||
using return_type = std::conditional_t<
|
||||
std::is_const_v<MAP>,
|
||||
std::is_const_v<Map>,
|
||||
const node*,
|
||||
node*
|
||||
>;
|
||||
@ -623,16 +613,16 @@ namespace toml
|
||||
return return_type{};
|
||||
}
|
||||
|
||||
template <typename T, typename MAP, typename KEY>
|
||||
[[nodiscard]] static auto do_get_as(MAP& vals, const KEY& key) noexcept
|
||||
template <typename T, typename Map, typename Key>
|
||||
[[nodiscard]] static auto do_get_as(Map& vals, const Key& key) noexcept
|
||||
{
|
||||
const auto node = do_get(vals, key);
|
||||
return node ? node->template as<T>() : nullptr;
|
||||
}
|
||||
|
||||
template <typename MAP, typename KEY>
|
||||
template <typename Map, typename Key>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
static bool do_contains(MAP& vals, const KEY& key) noexcept
|
||||
static bool do_contains(Map& vals, const Key& key) noexcept
|
||||
{
|
||||
#if TOML_CPP >= 20
|
||||
return vals.contains(key);
|
||||
@ -737,14 +727,7 @@ namespace toml
|
||||
/// \returns True if the tables did not contain the same keys and values.
|
||||
friend bool operator != (const table& lhs, const table& rhs) noexcept;
|
||||
|
||||
template <typename CHAR>
|
||||
friend std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>&, const table&);
|
||||
template <typename Char>
|
||||
friend std::basic_ostream<Char>& operator << (std::basic_ostream<Char>&, const table&);
|
||||
};
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE && !TOML_HAS_API_ANNOTATION
|
||||
namespace std
|
||||
{
|
||||
extern template class unique_ptr<toml::table>;
|
||||
}
|
||||
#endif
|
||||
|
@ -36,11 +36,11 @@ namespace toml::impl
|
||||
return is_ascii_whitespace(codepoint) || is_unicode_whitespace(codepoint);
|
||||
}
|
||||
|
||||
template <bool CR = true>
|
||||
template <bool IncludeCarriageReturn = true>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
constexpr bool is_ascii_line_break(char32_t codepoint) noexcept
|
||||
{
|
||||
constexpr auto low_range_end = CR ? U'\r' : U'\f';
|
||||
constexpr auto low_range_end = IncludeCarriageReturn ? U'\r' : U'\f';
|
||||
return (codepoint >= U'\n' && codepoint <= low_range_end);
|
||||
}
|
||||
|
||||
@ -56,11 +56,11 @@ namespace toml::impl
|
||||
;
|
||||
}
|
||||
|
||||
template <bool CR = true>
|
||||
template <bool IncludeCarriageReturn = true>
|
||||
[[nodiscard]]
|
||||
constexpr bool is_line_break(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_ascii_line_break<CR>(codepoint) || is_unicode_line_break(codepoint);
|
||||
return is_ascii_line_break<IncludeCarriageReturn>(codepoint) || is_unicode_line_break(codepoint);
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
@ -110,7 +110,7 @@ namespace toml::impl
|
||||
|| is_decimal_digit(codepoint)
|
||||
|| codepoint == U'-'
|
||||
|| codepoint == U'_'
|
||||
#if TOML_LANG_HIGHER_THAN(0, 5, 0) // toml/issues/644 & toml/issues/687
|
||||
#if TOML_LANG_UNRELEASED // toml/issues/644 ('+' in bare keys) & toml/issues/687 (unicode bare keys)
|
||||
|| codepoint == U'+'
|
||||
|| is_unicode_letter(codepoint)
|
||||
|| is_unicode_number(codepoint)
|
||||
@ -122,7 +122,7 @@ namespace toml::impl
|
||||
constexpr bool is_bare_key_character(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_bare_key_start_character(codepoint)
|
||||
#if TOML_LANG_HIGHER_THAN(0, 5, 0) // toml/issues/687
|
||||
#if TOML_LANG_UNRELEASED // toml/issues/687 (unicode bare keys)
|
||||
|| is_unicode_combining_mark(codepoint)
|
||||
#endif
|
||||
;
|
||||
@ -142,6 +142,20 @@ namespace toml::impl
|
||||
;
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
constexpr bool is_nontab_control_character(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint <= U'\u0008'
|
||||
|| (codepoint >= U'\u000A' && codepoint <= U'\u001F')
|
||||
|| codepoint == U'\u007F';
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
constexpr bool is_unicode_surrogate(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint >= 0xD800u && codepoint <= 0xDFFF;
|
||||
}
|
||||
|
||||
struct utf8_decoder final
|
||||
{
|
||||
//# This decoder is based on the 'Flexible and Economical UTF-8 Decoder'
|
||||
@ -206,17 +220,17 @@ namespace toml::impl
|
||||
template <typename T>
|
||||
class utf8_byte_stream;
|
||||
|
||||
template <typename CHAR>
|
||||
class utf8_byte_stream<std::basic_string_view<CHAR>> final
|
||||
template <typename Char>
|
||||
class utf8_byte_stream<std::basic_string_view<Char>> final
|
||||
{
|
||||
static_assert(sizeof(CHAR) == 1_sz);
|
||||
static_assert(sizeof(Char) == 1_sz);
|
||||
|
||||
private:
|
||||
std::basic_string_view<CHAR> source;
|
||||
std::basic_string_view<Char> source;
|
||||
size_t position = {};
|
||||
|
||||
public:
|
||||
explicit constexpr utf8_byte_stream(std::basic_string_view<CHAR> sv) noexcept
|
||||
explicit constexpr utf8_byte_stream(std::basic_string_view<Char> sv) noexcept
|
||||
: source{ sv }
|
||||
{
|
||||
if (source.length() >= 3_sz
|
||||
@ -249,16 +263,16 @@ namespace toml::impl
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CHAR>
|
||||
class utf8_byte_stream<std::basic_istream<CHAR>> final
|
||||
template <typename Char>
|
||||
class utf8_byte_stream<std::basic_istream<Char>> final
|
||||
{
|
||||
static_assert(sizeof(CHAR) == 1_sz);
|
||||
static_assert(sizeof(Char) == 1_sz);
|
||||
|
||||
private:
|
||||
std::basic_istream<CHAR>* source;
|
||||
std::basic_istream<Char>* source;
|
||||
|
||||
public:
|
||||
explicit utf8_byte_stream(std::basic_istream<CHAR>& stream)
|
||||
explicit utf8_byte_stream(std::basic_istream<Char>& stream)
|
||||
: source{ &stream }
|
||||
{
|
||||
if (*source)
|
||||
@ -299,7 +313,7 @@ namespace toml::impl
|
||||
optional<uint8_t> operator() ()
|
||||
{
|
||||
auto val = source->get();
|
||||
if (val == std::basic_istream<CHAR>::traits_type::eof())
|
||||
if (val == std::basic_istream<Char>::traits_type::eof())
|
||||
return {};
|
||||
return static_cast<uint8_t>(val);
|
||||
}
|
||||
@ -311,18 +325,18 @@ namespace toml::impl
|
||||
string_char bytes[4];
|
||||
source_position position;
|
||||
|
||||
template <typename CHAR = string_char>
|
||||
template <typename Char = string_char>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
std::basic_string_view<CHAR> as_view() const noexcept
|
||||
std::basic_string_view<Char> as_view() const noexcept
|
||||
{
|
||||
static_assert(
|
||||
sizeof(CHAR) == 1,
|
||||
sizeof(Char) == 1,
|
||||
"The string view's underlying character type must be 1 byte in size."
|
||||
);
|
||||
|
||||
return bytes[3]
|
||||
? std::basic_string_view<CHAR>{ reinterpret_cast<const CHAR*>(bytes), 4_sz }
|
||||
: std::basic_string_view<CHAR>{ reinterpret_cast<const CHAR*>(bytes) };
|
||||
? std::basic_string_view<Char>{ reinterpret_cast<const Char*>(bytes), 4_sz }
|
||||
: std::basic_string_view<Char>{ reinterpret_cast<const Char*>(bytes) };
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@ -389,8 +403,8 @@ namespace toml::impl
|
||||
|
||||
public:
|
||||
|
||||
template <typename U, typename STR = std::string_view>
|
||||
explicit utf8_reader(U && source, STR&& source_path = {})
|
||||
template <typename U, typename String = std::string_view>
|
||||
explicit utf8_reader(U && source, String&& source_path = {})
|
||||
noexcept(std::is_nothrow_constructible_v<utf8_byte_stream<T>, U&&>)
|
||||
: stream{ std::forward<U>(source) }
|
||||
{
|
||||
@ -399,7 +413,7 @@ namespace toml::impl
|
||||
codepoints[1].position = { 1, 1 };
|
||||
|
||||
if (!source_path.empty())
|
||||
source_path_ = std::make_shared<const std::string>(std::forward<STR>(source_path));
|
||||
source_path_ = std::make_shared<const std::string>(std::forward<String>(source_path));
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@ -504,17 +518,17 @@ namespace toml::impl
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename CHAR>
|
||||
utf8_reader(std::basic_string_view<CHAR>, std::string_view) -> utf8_reader<std::basic_string_view<CHAR>>;
|
||||
template <typename Char>
|
||||
utf8_reader(std::basic_string_view<Char>, std::string_view) -> utf8_reader<std::basic_string_view<Char>>;
|
||||
|
||||
template <typename CHAR>
|
||||
utf8_reader(std::basic_istream<CHAR>&, std::string_view) -> utf8_reader<std::basic_istream<CHAR>>;
|
||||
template <typename Char>
|
||||
utf8_reader(std::basic_istream<Char>&, std::string_view) -> utf8_reader<std::basic_istream<Char>>;
|
||||
|
||||
template <typename CHAR>
|
||||
utf8_reader(std::basic_string_view<CHAR>, std::string&&) -> utf8_reader<std::basic_string_view<CHAR>>;
|
||||
template <typename Char>
|
||||
utf8_reader(std::basic_string_view<Char>, std::string&&) -> utf8_reader<std::basic_string_view<Char>>;
|
||||
|
||||
template <typename CHAR>
|
||||
utf8_reader(std::basic_istream<CHAR>&, std::string&&) -> utf8_reader<std::basic_istream<CHAR>>;
|
||||
template <typename Char>
|
||||
utf8_reader(std::basic_istream<Char>&, std::string&&) -> utf8_reader<std::basic_istream<Char>>;
|
||||
|
||||
#if !TOML_EXCEPTIONS
|
||||
#undef TOML_ERROR_CHECK
|
||||
|
@ -7,7 +7,7 @@
|
||||
#pragma once
|
||||
#include "toml_common.h"
|
||||
|
||||
#if TOML_LANG_HIGHER_THAN(0, 5, 0) // toml/issues/687
|
||||
#if TOML_LANG_UNRELEASED // toml/issues/687 (unicode bare keys)
|
||||
|
||||
#define TOML_ASSUME_CODEPOINT_BETWEEN(first, last) \
|
||||
TOML_ASSUME(codepoint >= first); \
|
||||
@ -915,4 +915,4 @@ namespace toml::impl
|
||||
|
||||
#undef TOML_ASSUME_CODEPOINT_BETWEEN
|
||||
|
||||
#endif // TOML_LANG_HIGHER_THAN(0, 5, 0)
|
||||
#endif // TOML_LANG_UNRELEASED
|
||||
|
@ -8,8 +8,8 @@
|
||||
|
||||
namespace toml
|
||||
{
|
||||
template <typename CHAR, typename T>
|
||||
std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>&, const value<T>&);
|
||||
template <typename Char, typename T>
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>&, const value<T>&);
|
||||
|
||||
/// \brief A TOML value.
|
||||
///
|
||||
@ -167,8 +167,8 @@ namespace toml
|
||||
/// \brief Returns a reference to the underlying value (const overload).
|
||||
[[nodiscard]] explicit operator const T& () const& noexcept { return val_; }
|
||||
|
||||
template <typename CHAR, typename U>
|
||||
friend std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const value<U>& rhs);
|
||||
template <typename Char, typename U>
|
||||
friend std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const value<U>& rhs);
|
||||
|
||||
/// \brief Value-assignment operator.
|
||||
value& operator= (value_arg rhs) noexcept
|
||||
@ -312,23 +312,7 @@ namespace toml
|
||||
extern template class TOML_API value<time>;
|
||||
extern template class TOML_API value<date_time>;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE && !TOML_HAS_API_ANNOTATION
|
||||
namespace std
|
||||
{
|
||||
extern template class unique_ptr<toml::value<toml::string>>;
|
||||
extern template class unique_ptr<toml::value<int64_t>>;
|
||||
extern template class unique_ptr<toml::value<double>>;
|
||||
extern template class unique_ptr<toml::value<bool>>;
|
||||
extern template class unique_ptr<toml::value<toml::date>>;
|
||||
extern template class unique_ptr<toml::value<toml::time>>;
|
||||
extern template class unique_ptr<toml::value<toml::date_time>>;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace toml
|
||||
{
|
||||
template <size_t N> value(const string_char(&)[N]) -> value<string>;
|
||||
template <size_t N> value(const string_char(&&)[N]) -> value<string>;
|
||||
value(const string_char*) -> value<string>;
|
||||
@ -358,8 +342,9 @@ namespace toml
|
||||
#endif
|
||||
|
||||
/// \brief Prints the value out to a stream.
|
||||
template <typename CHAR, typename T>
|
||||
inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const value<T>& rhs)
|
||||
template <typename Char, typename T>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const value<T>& rhs)
|
||||
{
|
||||
// this is the same behaviour as default_formatter, but it's so simple that there's
|
||||
// no need to spin up a new instance of it just for individual values.
|
||||
@ -376,6 +361,16 @@ namespace toml
|
||||
return lhs;
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<toml::string>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<int64_t>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<double>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<bool>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<toml::date>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<toml::time>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<toml::date_time>&);
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
inline optional<T> node::value() const noexcept
|
||||
{
|
||||
|
@ -5,9 +5,9 @@
|
||||
#pragma once
|
||||
|
||||
#define TOML_LIB_MAJOR 1
|
||||
#define TOML_LIB_MINOR 0
|
||||
#define TOML_LIB_PATCH 1
|
||||
#define TOML_LIB_MINOR 1
|
||||
#define TOML_LIB_PATCH 0
|
||||
|
||||
#define TOML_LANG_MAJOR 0
|
||||
#define TOML_LANG_MINOR 5
|
||||
#define TOML_LANG_MAJOR 1
|
||||
#define TOML_LANG_MINOR 0
|
||||
#define TOML_LANG_PATCH 0
|
||||
|
@ -1,7 +1,7 @@
|
||||
project(
|
||||
'tomlplusplus',
|
||||
'cpp',
|
||||
version : '1.0.1',
|
||||
version : '1.1.0',
|
||||
license : 'MIT',
|
||||
default_options : [
|
||||
'cpp_std=c++17',
|
||||
|
@ -457,12 +457,42 @@ class ModifiersFix2(ModifiersFixBase):
|
||||
class IndexPageFix(object):
|
||||
|
||||
__badges = [
|
||||
('C++', 'https://img.shields.io/badge/c%2B%2B-17%2C%2020-informational', 'https://en.cppreference.com/w/cpp/compiler_support'),
|
||||
('TOML', 'https://img.shields.io/badge/TOML-v0.5.0-informational', 'https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.5.0.md'),
|
||||
('MIT License', 'https://img.shields.io/badge/license-MIT-blue.svg', 'https://github.com/marzer/tomlplusplus/blob/master/LICENSE'),
|
||||
('Releases', 'https://img.shields.io/github/release/marzer/tomlplusplus.svg', 'https://github.com/marzer/tomlplusplus/releases'),
|
||||
('Mentioned in Awesome C++', 'https://awesome.re/mentioned-badge.svg', 'https://github.com/fffaraz/awesome-cpp'),
|
||||
('CircleCI', 'https://circleci.com/gh/marzer/tomlplusplus.svg?style=shield', 'https://circleci.com/gh/marzer/tomlplusplus')
|
||||
(
|
||||
'Releases',
|
||||
'https://img.shields.io/github/v/release/marzer/tomlplusplus?style=flat-square',
|
||||
'https://github.com/marzer/tomlplusplus/releases'
|
||||
),
|
||||
(
|
||||
'C++17',
|
||||
'badge-C++17.svg',
|
||||
'https://en.cppreference.com/w/cpp/compiler_support'
|
||||
),
|
||||
(
|
||||
'C++20',
|
||||
'badge-C++20.svg',
|
||||
'https://en.cppreference.com/w/cpp/compiler_support'
|
||||
),
|
||||
(
|
||||
'TOML',
|
||||
'badge-TOML.svg',
|
||||
'https://github.com/toml-lang/toml/blob/master/README.md'
|
||||
),
|
||||
(
|
||||
'MIT License',
|
||||
'badge-license-MIT.svg',
|
||||
'https://github.com/marzer/tomlplusplus/blob/master/LICENSE'
|
||||
),
|
||||
(
|
||||
'CircleCI',
|
||||
'https://img.shields.io/circleci/build/github/marzer/tomlplusplus'
|
||||
+ '?label=circle%20ci&logo=circleci&logoColor=white&style=flat-square',
|
||||
'https://circleci.com/gh/marzer/tomlplusplus'
|
||||
),
|
||||
(
|
||||
'Mentioned in Awesome C++',
|
||||
'badge-awesome.svg',
|
||||
'https://github.com/fffaraz/awesome-cpp'
|
||||
)
|
||||
]
|
||||
|
||||
def __call__(self, file, doc):
|
||||
@ -474,7 +504,7 @@ class IndexPageFix(object):
|
||||
parent = doc.new_tag('div', class_='gh-badges', after=banner)
|
||||
for (alt, src, href) in self.__badges:
|
||||
anchor = doc.new_tag('a', parent=parent, href=href, target='_blank')
|
||||
doc.new_tag('img', parent=anchor, src=src, alt='caption')
|
||||
doc.new_tag('img', parent=anchor, src=src, alt=alt)
|
||||
return True
|
||||
|
||||
|
||||
|
@ -133,8 +133,9 @@ file was assembled from a number of smaller files by a python script, and code c
|
||||
against it directly. You should instead make your changes in the relevant source file(s). The file names of the files
|
||||
that contributed to this header can be found at the beginnings and ends of the corresponding sections of this file.''')
|
||||
preamble.append('''
|
||||
TOML language specification:
|
||||
TOML language specifications:
|
||||
Latest: https://github.com/toml-lang/toml/blob/master/README.md
|
||||
v1.0.0: https://github.com/toml-lang/toml/blob/master/README.md
|
||||
v0.5.0: https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.5.0.md''')
|
||||
preamble.append(read_all_text_from_file(path.join(get_script_folder(), '..', 'LICENSE')))
|
||||
|
||||
|
@ -514,7 +514,7 @@ def emit_function(name, categories, file, codepoints):
|
||||
|
||||
|
||||
def get_script_folder():
|
||||
return path.dirname(path.realpath(sys.argv[0]))
|
||||
return path.dirname(path.realpath(sys.argv[0]))
|
||||
|
||||
|
||||
|
||||
@ -589,7 +589,7 @@ def main():
|
||||
#pragma once
|
||||
#include "toml_common.h"
|
||||
|
||||
#if TOML_LANG_HIGHER_THAN(0, 5, 0) // toml/issues/687
|
||||
#if TOML_LANG_UNRELEASED // toml/issues/687 (unicode bare keys)
|
||||
|
||||
#define TOML_ASSUME_CODEPOINT_BETWEEN(first, last) \\
|
||||
TOML_ASSUME(codepoint >= first); \\
|
||||
@ -606,7 +606,7 @@ namespace toml::impl
|
||||
|
||||
#undef TOML_ASSUME_CODEPOINT_BETWEEN
|
||||
|
||||
#endif // TOML_LANG_HIGHER_THAN(0, 5, 0)
|
||||
#endif // TOML_LANG_UNRELEASED
|
||||
''', file=output_file, end='')
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
11
tests/impl_catch2.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#define CATCH_CONFIG_RUNNER
|
||||
#include "catch2.h"
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
#ifdef _WIN32
|
||||
SetConsoleOutputCP(65001);
|
||||
#endif
|
||||
|
||||
return Catch::Session().run(argc, argv);
|
||||
}
|
42
tests/impl_toml.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
#ifdef TARTANLLAMA_OPTIONAL
|
||||
#if __has_include(<tloptional/include/tl/optional.hpp>)
|
||||
#include <tloptional/include/tl/optional.hpp>
|
||||
#else
|
||||
#error TartanLlama/optional is missing! You probably need to fetch submodules ("git submodule update --init extern/tloptional")
|
||||
#endif
|
||||
#define TOML_OPTIONAL_TYPE tl::optional
|
||||
#endif
|
||||
#include <ostream>
|
||||
#if !defined(_MSC_VER) || !defined(_M_IX86)
|
||||
#define TOML_ALL_INLINE 0
|
||||
#define TOML_IMPLEMENTATION
|
||||
#endif
|
||||
#include "../include/toml++/toml.h"
|
||||
|
||||
namespace toml
|
||||
{
|
||||
using std::declval;
|
||||
using std::is_same_v;
|
||||
|
||||
static_assert(is_same_v<decltype(declval<node&>().ref<double>()), double&>);
|
||||
static_assert(is_same_v<decltype(declval<node&&>().ref<double>()), double&&>);
|
||||
static_assert(is_same_v<decltype(declval<const node&>().ref<double>()), const double&>);
|
||||
static_assert(is_same_v<decltype(declval<node&>().ref<value<double>>()), double&>);
|
||||
static_assert(is_same_v<decltype(declval<node&&>().ref<value<double>>()), double&&>);
|
||||
static_assert(is_same_v<decltype(declval<const node&>().ref<value<double>>()), const double&>);
|
||||
static_assert(is_same_v<decltype(declval<node&>().ref<table>()), table&>);
|
||||
static_assert(is_same_v<decltype(declval<node&&>().ref<table>()), table&&>);
|
||||
static_assert(is_same_v<decltype(declval<const node&>().ref<table>()), const table&>);
|
||||
static_assert(is_same_v<decltype(declval<node&>().ref<array>()), array&>);
|
||||
static_assert(is_same_v<decltype(declval<node&&>().ref<array>()), array&&>);
|
||||
static_assert(is_same_v<decltype(declval<const node&>().ref<array>()), const array&>);
|
||||
|
||||
static_assert(is_same_v<decltype(declval<node_view<node>>().ref<double>()), double&>);
|
||||
static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<double>()), const double&>);
|
||||
static_assert(is_same_v<decltype(declval<node_view<node>>().ref<value<double>>()), double&>);
|
||||
static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<value<double>>()), const double&>);
|
||||
static_assert(is_same_v<decltype(declval<node_view<node>>().ref<table>()), table&>);
|
||||
static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<table>()), const table&>);
|
||||
static_assert(is_same_v<decltype(declval<node_view<node>>().ref<array>()), array&>);
|
||||
static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<array>()), const array&>);
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
#ifdef TARTANLLAMA_OPTIONAL
|
||||
#if __has_include(<tloptional/include/tl/optional.hpp>)
|
||||
#include <tloptional/include/tl/optional.hpp>
|
||||
#else
|
||||
#error TartanLlama/optional is missing! You probably need to fetch submodules ("git submodule update --init extern/tloptional")
|
||||
#endif
|
||||
#define TOML_OPTIONAL_TYPE tl::optional
|
||||
#endif
|
||||
#if !defined(_MSC_VER) || !defined(_M_IX86)
|
||||
#define TOML_ALL_INLINE 0
|
||||
#define TOML_IMPLEMENTATION
|
||||
#endif
|
||||
#include "../include/toml++/toml.h"
|
||||
|
||||
#define CATCH_CONFIG_RUNNER
|
||||
#include "catch2.h"
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
#ifdef _WIN32
|
||||
SetConsoleOutputCP(65001);
|
||||
#endif
|
||||
|
||||
return Catch::Session().run(argc, argv);
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
test_sources = [
|
||||
'main.cpp',
|
||||
'impl_toml.cpp',
|
||||
'impl_catch2.cpp',
|
||||
'parsing_arrays.cpp',
|
||||
'parsing_booleans.cpp',
|
||||
'parsing_comments.cpp',
|
||||
|
@ -91,8 +91,8 @@ string_array = [ "all", 'strings', """are the same""", '''type''' ]
|
||||
}
|
||||
);
|
||||
|
||||
// toml/issues/665 - heterogeneous arrays
|
||||
#if TOML_LANG_HIGHER_THAN(0, 5, 0)
|
||||
// toml/issues/665 (heterogeneous arrays)
|
||||
#if TOML_LANG_AT_LEAST(1, 0, 0)
|
||||
|
||||
parsing_should_succeed(S(R"(
|
||||
# Mixed-type arrays are allowed
|
||||
|
@ -14,4 +14,95 @@ another = "# This is not a comment"
|
||||
CHECK(tbl[S("another")] == S("# This is not a comment"sv));
|
||||
}
|
||||
);
|
||||
|
||||
parsing_should_succeed(S(R"(# this = "looks like a KVP but is commented out)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
{
|
||||
CHECK(tbl.size() == 0);
|
||||
}
|
||||
);
|
||||
|
||||
if constexpr (TOML_LANG_AT_LEAST(1, 0, 0))
|
||||
{
|
||||
// toml/issues/567 (disallow non-TAB control characters in comments)
|
||||
// 00 - 08
|
||||
parsing_should_fail(S("# \u0000"sv));
|
||||
parsing_should_fail(S("# \u0001"sv));
|
||||
parsing_should_fail(S("# \u0002"sv));
|
||||
parsing_should_fail(S("# \u0003"sv));
|
||||
parsing_should_fail(S("# \u0004"sv));
|
||||
parsing_should_fail(S("# \u0005"sv));
|
||||
parsing_should_fail(S("# \u0006"sv));
|
||||
parsing_should_fail(S("# \u0007"sv));
|
||||
parsing_should_fail(S("# \u0008"sv));
|
||||
|
||||
// skip tab and line breaks (real and otherwise)
|
||||
// \u0009 is \t
|
||||
// \u000A is \n
|
||||
// \u000B is \v (vertical tab)
|
||||
// \u000C is \f (form feed)
|
||||
// \u000D is \r
|
||||
|
||||
// 0E - 1F
|
||||
parsing_should_fail(S("# \u000E"sv));
|
||||
parsing_should_fail(S("# \u000F"sv));
|
||||
parsing_should_fail(S("# \u0010"sv));
|
||||
parsing_should_fail(S("# \u0011"sv));
|
||||
parsing_should_fail(S("# \u0012"sv));
|
||||
parsing_should_fail(S("# \u0013"sv));
|
||||
parsing_should_fail(S("# \u0014"sv));
|
||||
parsing_should_fail(S("# \u0015"sv));
|
||||
parsing_should_fail(S("# \u0016"sv));
|
||||
parsing_should_fail(S("# \u0017"sv));
|
||||
parsing_should_fail(S("# \u0018"sv));
|
||||
parsing_should_fail(S("# \u0019"sv));
|
||||
parsing_should_fail(S("# \u001A"sv));
|
||||
parsing_should_fail(S("# \u001B"sv));
|
||||
parsing_should_fail(S("# \u001C"sv));
|
||||
parsing_should_fail(S("# \u001D"sv));
|
||||
parsing_should_fail(S("# \u001E"sv));
|
||||
parsing_should_fail(S("# \u001F"sv));
|
||||
// 7F
|
||||
parsing_should_fail(S("# \u007F"sv));
|
||||
}
|
||||
else
|
||||
{
|
||||
parsing_should_succeed(S(
|
||||
"## 00 - 08"
|
||||
"# \u0000 "
|
||||
"# \u0001 "
|
||||
"# \u0002 "
|
||||
"# \u0003 "
|
||||
"# \u0004 "
|
||||
"# \u0005 "
|
||||
"# \u0006 "
|
||||
"# \u0007 "
|
||||
"# \u0008 "
|
||||
"## 0A - 1F"
|
||||
"# \u000A "
|
||||
"# \u000B "
|
||||
"# \u000C "
|
||||
"# \u000D "
|
||||
"# \u000E "
|
||||
"# \u000F "
|
||||
"# \u0010 "
|
||||
"# \u0011 "
|
||||
"# \u0012 "
|
||||
"# \u0013 "
|
||||
"# \u0014 "
|
||||
"# \u0015 "
|
||||
"# \u0016 "
|
||||
"# \u0017 "
|
||||
"# \u0018 "
|
||||
"# \u0019 "
|
||||
"# \u001A "
|
||||
"# \u001B "
|
||||
"# \u001C "
|
||||
"# \u001D "
|
||||
"# \u001E "
|
||||
"# \u001F "
|
||||
"## 7F "
|
||||
"# \u007F "sv
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -84,8 +84,8 @@ lt2 = 00:32:00.999999
|
||||
parse_expected_value("1987-03-16 10:20:30.04Z"sv, val);
|
||||
}
|
||||
|
||||
// toml/issues/671 - omitting seconds
|
||||
#if TOML_LANG_HIGHER_THAN(0, 5, 0)
|
||||
// toml/issues/671 (allow omission of seconds)
|
||||
#if TOML_LANG_UNRELEASED
|
||||
|
||||
parse_expected_value( "10:20"sv, toml::time{ 10, 20 } );
|
||||
{
|
||||
|
@ -102,15 +102,15 @@ flt8 = 224_617.445_991_228
|
||||
parse_expected_value( "6.02e+23"sv, 6.02e+23 );
|
||||
parse_expected_value( "1.112_650_06e-17"sv, 1.11265006e-17 );
|
||||
|
||||
//toml/issues/562 - hexfloat literals
|
||||
#if TOML_LANG_HIGHER_THAN(0, 5, 0)
|
||||
parse_expected_value(" 0x10.1p0"sv, 0x10.1p0 );
|
||||
parse_expected_value(" 0x0.3p10"sv, 0x0.3p10 );
|
||||
parse_expected_value(" 0x12.2P2"sv, 0x12.2P2 );
|
||||
//toml/issues/562 (hexfloats)
|
||||
#if TOML_LANG_UNRELEASED
|
||||
parse_expected_value(" 0x10.1p0"sv, 0x10.1p0 );
|
||||
parse_expected_value(" 0x0.3p10"sv, 0x0.3p10 );
|
||||
parse_expected_value(" 0x12.2P2"sv, 0x12.2P2 );
|
||||
#else
|
||||
parsing_should_fail(S("val = 0x10.1p0"sv));
|
||||
parsing_should_fail(S("val = 0x0.3p10"sv));
|
||||
parsing_should_fail(S("val = 0x12.2P2"sv));
|
||||
parsing_should_fail(S("val = 0x10.1p0"sv));
|
||||
parsing_should_fail(S("val = 0x0.3p10"sv));
|
||||
parsing_should_fail(S("val = 0x12.2P2"sv));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -7,14 +7,16 @@ key = "value"
|
||||
bare_key = "value"
|
||||
bare-key = "value"
|
||||
1234 = "value"
|
||||
"" = "blank"
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
{
|
||||
CHECK(tbl.size() == 4);
|
||||
CHECK(tbl.size() == 5);
|
||||
CHECK(tbl[S("key")] == S("value"sv));
|
||||
CHECK(tbl[S("bare_key")] == S("value"sv));
|
||||
CHECK(tbl[S("bare-key")] == S("value"sv));
|
||||
CHECK(tbl[S("1234")] == S("value"sv));
|
||||
CHECK(tbl[S("")] == S("blank"sv));
|
||||
}
|
||||
);
|
||||
|
||||
@ -26,6 +28,7 @@ bare-key = "value"
|
||||
"ʎǝʞ" = "value"
|
||||
'key2' = "value"
|
||||
'quoted "value"' = "value"
|
||||
'' = 'blank'
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
{
|
||||
@ -34,6 +37,7 @@ bare-key = "value"
|
||||
CHECK(tbl[S("ʎǝʞ")] == S("value"sv));
|
||||
CHECK(tbl[S("key2")] == S("value"sv));
|
||||
CHECK(tbl[S("quoted \"value\"")] == S("value"sv));
|
||||
CHECK(tbl[S("")] == S("blank"sv));
|
||||
}
|
||||
);
|
||||
|
||||
@ -55,14 +59,16 @@ name = "Orange"
|
||||
physical.color = "orange"
|
||||
physical.shape = "round"
|
||||
site."google.com" = true
|
||||
3.14159 = "pi"
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
{
|
||||
CHECK(tbl.size() == 3);
|
||||
CHECK(tbl.size() == 4);
|
||||
CHECK(tbl[S("name")] == S("Orange"sv));
|
||||
CHECK(tbl[S("physical")][S("color")] == S("orange"sv));
|
||||
CHECK(tbl[S("physical")][S("shape")] == S("round"sv));
|
||||
CHECK(tbl[S("site")][S("google.com")] == true);
|
||||
CHECK(tbl[S("3")][S("14159")] == S("pi"sv));
|
||||
}
|
||||
);
|
||||
|
||||
@ -130,22 +136,21 @@ orange.color = "orange"
|
||||
}
|
||||
);
|
||||
|
||||
// allow + in bare keys - toml/issues/644
|
||||
// allow unicode in bare keys - toml/issues/687
|
||||
#if TOML_LANG_HIGHER_THAN(0, 5, 0)
|
||||
parsing_should_succeed(S(R"(
|
||||
key+1 = 0
|
||||
ʎǝʞ2 = 0
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
{
|
||||
CHECK(tbl.size() == 2);
|
||||
CHECK(tbl[S("key+1")] == 0);
|
||||
CHECK(tbl[S("ʎǝʞ2")] == 0);
|
||||
}
|
||||
);
|
||||
// toml/issues/644 ('+' in bare keys) & toml/issues/687 (unicode bare keys)
|
||||
#if TOML_LANG_UNRELEASED
|
||||
parsing_should_succeed(S(R"(
|
||||
key+1 = 0
|
||||
ʎǝʞ2 = 0
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
{
|
||||
CHECK(tbl.size() == 2);
|
||||
CHECK(tbl[S("key+1")] == 0);
|
||||
CHECK(tbl[S("ʎǝʞ2")] == 0);
|
||||
}
|
||||
);
|
||||
#else
|
||||
parsing_should_fail(R"(key+1 = 0)"sv);
|
||||
parsing_should_fail(R"(ʎǝʞ2 = 0)"sv);
|
||||
parsing_should_fail(R"(key+1 = 0)"sv);
|
||||
parsing_should_fail(R"(ʎǝʞ2 = 0)"sv);
|
||||
#endif
|
||||
}
|
||||
|
@ -130,22 +130,13 @@ str = ''''That's still pointless', she said.'''
|
||||
R"("\"\u03B1\u03B2\u03B3\"")"sv,
|
||||
S("\"\u03B1\u03B2\u03B3\""sv));
|
||||
|
||||
// toml/issues/622 - escaping alias for spaces
|
||||
#if 0 && TOML_LANG_HIGHER_THAN(0, 5, 0)
|
||||
parse_expected_value(
|
||||
R"("The\squick\sbrown\sfox\sjumps\sover\sthe\slazy\sdog")"sv,
|
||||
S("The quick brown fox jumps over the lazy dog"sv));
|
||||
// toml/pull/709 (\xHH unicode scalars)
|
||||
#if TOML_LANG_UNRELEASED
|
||||
parse_expected_value(
|
||||
R"("\x00\x10\x20\x30\x40\x50\x60\x70\x80\x90\x11\xFF\xEE")"sv,
|
||||
S("\u0000\u0010\u0020\u0030\u0040\u0050\u0060\u0070\u0080\u0090\u0011\u00FF\u00EE"sv));
|
||||
#else
|
||||
parsing_should_fail(R"(str = "The\squick\sbrown\sfox\sjumps\sover\sthe\slazy\sdog")"sv);
|
||||
#endif
|
||||
|
||||
// toml/pull/709 - \xHH short-form unicode scalars
|
||||
#if TOML_LANG_HIGHER_THAN(0, 5, 0)
|
||||
parse_expected_value(
|
||||
R"("\x00\x10\x20\x30\x40\x50\x60\x70\x80\x90\x11\xFF\xEE")"sv,
|
||||
S("\u0000\u0010\u0020\u0030\u0040\u0050\u0060\u0070\u0080\u0090\u0011\u00FF\u00EE"sv));
|
||||
#else
|
||||
parsing_should_fail(R"(str = "\x00\x10\x20\x30\x40\x50\x60\x70\x80\x90\x11\xFF\xEE")"sv);
|
||||
parsing_should_fail(R"(str = "\x00\x10\x20\x30\x40\x50\x60\x70\x80\x90\x11\xFF\xEE")"sv);
|
||||
#endif
|
||||
|
||||
//check 8-digit \U scalars with insufficient digits
|
||||
|
@ -227,9 +227,9 @@ test = { val1 = "foo", val2 = [
|
||||
}
|
||||
);
|
||||
|
||||
#if TOML_LANG_HIGHER_THAN(0, 5, 0)
|
||||
// toml/issues/516 (newlines/trailing commas in inline tables)
|
||||
#if TOML_LANG_UNRELEASED
|
||||
{
|
||||
// toml/issues/516 - allow newlines and trailing commas in inline tables
|
||||
parsing_should_succeed(S(R"(
|
||||
name = {
|
||||
first = "Tom",
|
||||
|
@ -1,7 +1,5 @@
|
||||
#include "tests.h"
|
||||
|
||||
#if TESTS_MANUAL_INSTANTIATIONS
|
||||
|
||||
template void parse_expected_value(std::string_view, const int&) noexcept;
|
||||
template void parse_expected_value(std::string_view, const unsigned int&) noexcept;
|
||||
template void parse_expected_value(std::string_view, const bool&) noexcept;
|
||||
@ -9,41 +7,10 @@ template void parse_expected_value(std::string_view, const float&) noexcept;
|
||||
template void parse_expected_value(std::string_view, const double&) noexcept;
|
||||
template void parse_expected_value(std::string_view, const toml::string_view&) noexcept;
|
||||
|
||||
namespace toml::impl
|
||||
namespace std
|
||||
{
|
||||
template class formatter<char>;
|
||||
template class unique_ptr<const Catch::IExceptionTranslator>;
|
||||
}
|
||||
|
||||
|
||||
namespace toml
|
||||
{
|
||||
template class default_formatter<char>;
|
||||
|
||||
template std::ostream& operator<< (std::ostream&, const table&);
|
||||
template std::ostream& operator<< (std::ostream&, const array&);
|
||||
template std::ostream& operator<< (std::ostream&, const value<string>&);
|
||||
template std::ostream& operator<< (std::ostream&, const value<int64_t>&);
|
||||
template std::ostream& operator<< (std::ostream&, const value<double>&);
|
||||
template std::ostream& operator<< (std::ostream&, const value<bool>&);
|
||||
template std::ostream& operator<< (std::ostream&, const value<date>&);
|
||||
template std::ostream& operator<< (std::ostream&, const value<time>&);
|
||||
template std::ostream& operator<< (std::ostream&, const value<date_time>&);
|
||||
template std::ostream& operator<< (std::ostream&, const node_view<node>&);
|
||||
template std::ostream& operator<< (std::ostream&, const node_view<const node>&);
|
||||
template std::ostream& operator<< (std::ostream&, node_type);
|
||||
template std::ostream& operator<< (std::ostream&, const source_region&);
|
||||
template std::ostream& operator<< (std::ostream&, const source_position&);
|
||||
template std::ostream& operator<< (std::ostream&, const parse_error&);
|
||||
template std::ostream& operator<< (std::ostream&, const date&);
|
||||
template std::ostream& operator<< (std::ostream&, const time&);
|
||||
template std::ostream& operator<< (std::ostream&, const time_offset&);
|
||||
template std::ostream& operator<< (std::ostream&, const date_time&);
|
||||
template std::ostream& operator<< (std::ostream&, default_formatter<char>&);
|
||||
template std::ostream& operator<< (std::ostream&, default_formatter<char>&&);
|
||||
}
|
||||
|
||||
|
||||
template class std::unique_ptr<const Catch::IExceptionTranslator>;
|
||||
namespace Catch
|
||||
{
|
||||
template struct StringMaker<node_view<node>>;
|
||||
@ -57,34 +24,4 @@ namespace Catch
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TESTS_MANUAL_INSTANTIATIONS
|
||||
|
||||
namespace toml
|
||||
{
|
||||
using std::declval;
|
||||
using std::is_same_v;
|
||||
|
||||
static_assert(is_same_v<decltype(declval<node&>().ref<double>()), double&>);
|
||||
static_assert(is_same_v<decltype(declval<node&&>().ref<double>()), double&&>);
|
||||
static_assert(is_same_v<decltype(declval<const node&>().ref<double>()), const double&>);
|
||||
static_assert(is_same_v<decltype(declval<node&>().ref<value<double>>()), double&>);
|
||||
static_assert(is_same_v<decltype(declval<node&&>().ref<value<double>>()), double&&>);
|
||||
static_assert(is_same_v<decltype(declval<const node&>().ref<value<double>>()), const double&>);
|
||||
static_assert(is_same_v<decltype(declval<node&>().ref<table>()), table&>);
|
||||
static_assert(is_same_v<decltype(declval<node&&>().ref<table>()), table&&>);
|
||||
static_assert(is_same_v<decltype(declval<const node&>().ref<table>()), const table&>);
|
||||
static_assert(is_same_v<decltype(declval<node&>().ref<array>()), array&>);
|
||||
static_assert(is_same_v<decltype(declval<node&&>().ref<array>()), array&&>);
|
||||
static_assert(is_same_v<decltype(declval<const node&>().ref<array>()), const array&>);
|
||||
|
||||
static_assert(is_same_v<decltype(declval<node_view<node>>().ref<double>()), double&>);
|
||||
static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<double>()), const double&>);
|
||||
static_assert(is_same_v<decltype(declval<node_view<node>>().ref<value<double>>()), double&>);
|
||||
static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<value<double>>()), const double&>);
|
||||
static_assert(is_same_v<decltype(declval<node_view<node>>().ref<table>()), table&>);
|
||||
static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<table>()), const table&>);
|
||||
static_assert(is_same_v<decltype(declval<node_view<node>>().ref<array>()), array&>);
|
||||
static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<array>()), const array&>);
|
||||
|
||||
}
|
||||
|
||||
|
@ -30,8 +30,8 @@ using namespace Catch::literals;
|
||||
|
||||
#define S(str) TOML_STRING_PREFIX(str)
|
||||
|
||||
template <typename CHAR, typename FUNC>
|
||||
inline void parsing_should_succeed(std::basic_string_view<CHAR> toml_str, FUNC&& func, std::string_view source_path = {}) noexcept
|
||||
template <typename Char, typename Func = std::false_type>
|
||||
inline void parsing_should_succeed(std::basic_string_view<Char> toml_str, Func&& func = {}, std::string_view source_path = {}) noexcept
|
||||
{
|
||||
INFO("String being parsed: '"sv << std::string_view( reinterpret_cast<const char*>(toml_str.data()), toml_str.length() ) << "'"sv)
|
||||
|
||||
@ -50,19 +50,27 @@ inline void parsing_should_succeed(std::basic_string_view<CHAR> toml_str, FUNC&&
|
||||
return std::move(tabl);
|
||||
};
|
||||
|
||||
static constexpr auto is_functor = !std::is_same_v<impl::remove_cvref_t<Func>, std::false_type>;
|
||||
|
||||
#if TOML_EXCEPTIONS
|
||||
|
||||
try
|
||||
{
|
||||
{
|
||||
INFO("Parsing string directly"sv)
|
||||
std::forward<FUNC>(func)(validate_table(toml::parse(toml_str, source_path), source_path));
|
||||
if constexpr (is_functor)
|
||||
std::forward<Func>(func)(validate_table(toml::parse(toml_str, source_path), source_path));
|
||||
else
|
||||
validate_table(toml::parse(toml_str, source_path), source_path);
|
||||
}
|
||||
{
|
||||
INFO("Parsing from a string stream"sv)
|
||||
std::basic_stringstream<CHAR, std::char_traits<CHAR>, std::allocator<CHAR>> ss;
|
||||
std::basic_stringstream<Char, std::char_traits<Char>, std::allocator<Char>> ss;
|
||||
ss.write(toml_str.data(), static_cast<std::streamsize>(toml_str.length()));
|
||||
std::forward<FUNC>(func)(validate_table(toml::parse(ss, source_path), source_path));
|
||||
if constexpr (is_functor)
|
||||
std::forward<Func>(func)(validate_table(toml::parse(ss, source_path), source_path));
|
||||
else
|
||||
validate_table(toml::parse(ss, source_path), source_path);
|
||||
}
|
||||
}
|
||||
catch (const parse_error& err)
|
||||
@ -80,7 +88,12 @@ inline void parsing_should_succeed(std::basic_string_view<CHAR> toml_str, FUNC&&
|
||||
INFO("Parsing string directly"sv)
|
||||
parse_result result = toml::parse(toml_str, source_path);
|
||||
if (result)
|
||||
std::forward<FUNC>(func)(validate_table(std::move(result), source_path));
|
||||
{
|
||||
if constexpr (is_functor)
|
||||
std::forward<Func>(func)(validate_table(std::move(result), source_path));
|
||||
else
|
||||
validate_table(std::move(result), source_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
FAIL(
|
||||
@ -88,17 +101,23 @@ inline void parsing_should_succeed(std::basic_string_view<CHAR> toml_str, FUNC&&
|
||||
<< ", column "sv << result.error().source().begin.column
|
||||
<< ":\n"sv << result.error().description()
|
||||
);
|
||||
return;
|
||||
std::exit(-1);
|
||||
TOML_UNREACHABLE;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
INFO("Parsing from a string stream"sv)
|
||||
std::basic_stringstream<CHAR, std::char_traits<CHAR>, std::allocator<CHAR>> ss;
|
||||
std::basic_stringstream<Char, std::char_traits<Char>, std::allocator<Char>> ss;
|
||||
ss.write(toml_str.data(), static_cast<std::streamsize>(toml_str.length()));
|
||||
parse_result result = toml::parse(ss, source_path);
|
||||
if (result)
|
||||
std::forward<FUNC>(func)(validate_table(std::move(result), source_path));
|
||||
{
|
||||
if constexpr (is_functor)
|
||||
std::forward<Func>(func)(validate_table(std::move(result), source_path));
|
||||
else
|
||||
validate_table(std::move(result), source_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
FAIL(
|
||||
@ -106,15 +125,16 @@ inline void parsing_should_succeed(std::basic_string_view<CHAR> toml_str, FUNC&&
|
||||
<< ", column "sv << result.error().source().begin.column
|
||||
<< ":\n"sv << result.error().description()
|
||||
);
|
||||
return;
|
||||
std::exit(-1);
|
||||
TOML_UNREACHABLE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename CHAR>
|
||||
inline void parsing_should_fail(std::basic_string_view<CHAR> toml_str) noexcept
|
||||
template <typename Char>
|
||||
inline void parsing_should_fail(std::basic_string_view<Char> toml_str) noexcept
|
||||
{
|
||||
INFO("String being parsed: '"sv << std::string_view(reinterpret_cast<const char*>(toml_str.data()), toml_str.length()) << "'"sv)
|
||||
|
||||
@ -145,7 +165,7 @@ inline void parsing_should_fail(std::basic_string_view<CHAR> toml_str) noexcept
|
||||
if (run_tests([=]() { (void)toml::parse(toml_str); }))
|
||||
run_tests([=]()
|
||||
{
|
||||
std::basic_stringstream<CHAR, std::char_traits<CHAR>, std::allocator<CHAR>> ss;
|
||||
std::basic_stringstream<Char, std::char_traits<Char>, std::allocator<Char>> ss;
|
||||
ss.write(toml_str.data(), static_cast<std::streamsize>(toml_str.length()));
|
||||
(void)toml::parse(ss);
|
||||
});
|
||||
@ -158,7 +178,8 @@ inline void parsing_should_fail(std::basic_string_view<CHAR> toml_str) noexcept
|
||||
if (result)
|
||||
{
|
||||
FAIL("Expected parsing failure"sv);
|
||||
return false;
|
||||
std::exit(-1);
|
||||
TOML_UNREACHABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -170,7 +191,7 @@ inline void parsing_should_fail(std::basic_string_view<CHAR> toml_str) noexcept
|
||||
if (run_tests([=]() noexcept { return toml::parse(toml_str); }))
|
||||
run_tests([=]() noexcept
|
||||
{
|
||||
std::basic_stringstream<CHAR, std::char_traits<CHAR>, std::allocator<CHAR>> ss;
|
||||
std::basic_stringstream<Char, std::char_traits<Char>, std::allocator<Char>> ss;
|
||||
ss.write(toml_str.data(), static_cast<std::streamsize>(toml_str.length()));
|
||||
return toml::parse(ss);
|
||||
});
|
||||
@ -291,7 +312,7 @@ inline void parse_expected_value(std::string_view value_str, const T& expected)
|
||||
REQUIRE(nv.get()->type() == impl::node_type_of<T>);
|
||||
|
||||
CHECK(nv.as<value_type>()->get() == expected);
|
||||
CHECK(nv.value_or(T{}) == expected);
|
||||
CHECK(nv.ref<value_type>() == expected);
|
||||
|
||||
val_reparsed = std::move(*nv.as<value_type>());
|
||||
});
|
||||
@ -301,51 +322,16 @@ inline void parse_expected_value(std::string_view value_str, const T& expected)
|
||||
}
|
||||
|
||||
// manually instantiate some templates to reduce test compilation time (chosen using ClangBuildAnalyzer)
|
||||
#define TESTS_MANUAL_INSTANTIATIONS 1
|
||||
#if TESTS_MANUAL_INSTANTIATIONS
|
||||
|
||||
extern template void parse_expected_value(std::string_view, const int&) noexcept;
|
||||
extern template void parse_expected_value(std::string_view, const unsigned int&) noexcept;
|
||||
extern template void parse_expected_value(std::string_view, const bool&) noexcept;
|
||||
extern template void parse_expected_value(std::string_view, const float&) noexcept;
|
||||
extern template void parse_expected_value(std::string_view, const double&) noexcept;
|
||||
extern template void parse_expected_value(std::string_view, const toml::string_view&) noexcept;
|
||||
|
||||
namespace toml::impl
|
||||
namespace std
|
||||
{
|
||||
extern template class formatter<char>;
|
||||
extern template class unique_ptr<const Catch::IExceptionTranslator>;
|
||||
}
|
||||
|
||||
|
||||
namespace toml
|
||||
{
|
||||
extern template class default_formatter<char>;
|
||||
|
||||
extern template std::ostream& operator<< (std::ostream&, const table&);
|
||||
extern template std::ostream& operator<< (std::ostream&, const array&);
|
||||
extern template std::ostream& operator<< (std::ostream&, const value<string>&);
|
||||
extern template std::ostream& operator<< (std::ostream&, const value<int64_t>&);
|
||||
extern template std::ostream& operator<< (std::ostream&, const value<double>&);
|
||||
extern template std::ostream& operator<< (std::ostream&, const value<bool>&);
|
||||
extern template std::ostream& operator<< (std::ostream&, const value<date>&);
|
||||
extern template std::ostream& operator<< (std::ostream&, const value<time>&);
|
||||
extern template std::ostream& operator<< (std::ostream&, const value<date_time>&);
|
||||
extern template std::ostream& operator<< (std::ostream&, const node_view<node>&);
|
||||
extern template std::ostream& operator<< (std::ostream&, const node_view<const node>&);
|
||||
extern template std::ostream& operator<< (std::ostream&, node_type);
|
||||
extern template std::ostream& operator<< (std::ostream&, const source_region&);
|
||||
extern template std::ostream& operator<< (std::ostream&, const source_position&);
|
||||
extern template std::ostream& operator<< (std::ostream&, const parse_error&);
|
||||
extern template std::ostream& operator<< (std::ostream&, const date&);
|
||||
extern template std::ostream& operator<< (std::ostream&, const time&);
|
||||
extern template std::ostream& operator<< (std::ostream&, const time_offset&);
|
||||
extern template std::ostream& operator<< (std::ostream&, const date_time&);
|
||||
extern template std::ostream& operator<< (std::ostream&, default_formatter<char>&);
|
||||
extern template std::ostream& operator<< (std::ostream&, default_formatter<char>&&);
|
||||
}
|
||||
|
||||
|
||||
extern template class std::unique_ptr<const Catch::IExceptionTranslator>;
|
||||
namespace Catch
|
||||
{
|
||||
extern template struct StringMaker<node_view<node>>;
|
||||
@ -358,6 +344,3 @@ namespace Catch
|
||||
extern template std::string stringify(const node_view<const node>&);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TESTS_MANUAL_INSTANTIATIONS
|
||||
|
||||
|
@ -60,11 +60,14 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<ClCompile Include="..\tests\impl_catch2.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\impl_toml.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\manipulating_tables.cpp" />
|
||||
<ClCompile Include="..\tests\manipulating_tables.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_booleans.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_comments.cpp" />
|
||||
|
@ -60,7 +60,10 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<ClCompile Include="..\tests\impl_catch2.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\impl_toml.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
|
@ -62,7 +62,10 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<ClCompile Include="..\tests\impl_catch2.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\impl_toml.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
|
@ -61,7 +61,10 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<ClCompile Include="..\tests\impl_catch2.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\impl_toml.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
|
@ -63,7 +63,10 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<ClCompile Include="..\tests\impl_catch2.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\impl_toml.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
|
@ -62,7 +62,10 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<ClCompile Include="..\tests\impl_catch2.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\impl_toml.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
|
@ -61,7 +61,10 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<ClCompile Include="..\tests\impl_catch2.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\impl_toml.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
|
@ -63,7 +63,10 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<ClCompile Include="..\tests\impl_catch2.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\impl_toml.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
|
@ -60,7 +60,10 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<ClCompile Include="..\tests\impl_catch2.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\impl_toml.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
|
@ -60,7 +60,10 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<ClCompile Include="..\tests\impl_catch2.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\impl_toml.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
|
@ -62,7 +62,10 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<ClCompile Include="..\tests\impl_catch2.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\impl_toml.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
|
@ -61,7 +61,10 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<ClCompile Include="..\tests\impl_catch2.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\impl_toml.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
|
@ -63,7 +63,10 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<ClCompile Include="..\tests\impl_catch2.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\impl_toml.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
|
@ -62,7 +62,10 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<ClCompile Include="..\tests\impl_catch2.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\impl_toml.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
|
@ -61,7 +61,10 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<ClCompile Include="..\tests\impl_catch2.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\impl_toml.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
|
@ -63,7 +63,10 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<ClCompile Include="..\tests\impl_catch2.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\impl_toml.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
|
@ -62,6 +62,7 @@
|
||||
<ClInclude Include="..\include\toml++\toml_common.h" />
|
||||
<ClInclude Include="..\include\toml++\toml_date_time.h" />
|
||||
<ClInclude Include="..\include\toml++\toml_default_formatter.h" />
|
||||
<ClInclude Include="..\include\toml++\toml_default_formatter_impl.h" />
|
||||
<ClInclude Include="..\include\toml++\toml_formatter.h" />
|
||||
<ClInclude Include="..\include\toml++\toml_json_formatter.h" />
|
||||
<ClInclude Include="..\include\toml++\toml_node.h" />
|
||||
|
@ -67,6 +67,9 @@
|
||||
<ClInclude Include="..\tests\catch2.h">
|
||||
<Filter>tests</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\toml++\toml_default_formatter_impl.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\.editorconfig" />
|
||||
|