Compare commits

..

1223 Commits

Author SHA1 Message Date
ToruNiina
0d1a52c3db test: add toml::find for optinal<user-defined> 2025-03-26 23:55:34 +09:00
ToruNiina
89b376b4df fix: disambiguate overload for optional<T> 2025-03-26 23:54:00 +09:00
ToruNiina
37262bbbbe feat: add default is_std_something
if std::something does not exist, toml::detail::is_std_something<T>
always returns false
2025-03-26 23:09:26 +09:00
ToruNiina
be08ba2be2 doc: update versions in docs 2025-02-16 00:15:09 +09:00
ToruNiina
587f9acb2a feat [skip ci]: update single_include 2025-02-15 14:42:45 +00:00
ToruNiina
0c7dba2d0a feat: bump version.hpp to v4.4.0 2025-02-15 23:41:59 +09:00
ToruNiina
a15a68a821 doc: update acknowledgement 2025-02-15 23:26:37 +09:00
ToruNiina
91316213bf docs: add ordered_map::erase to doc 2025-02-15 23:23:21 +09:00
ToruNiina
197e95d390 ci: move clang-15 to ubuntu 22
it seems that clang15 std=20 does not go well with the default-installed
libstdc++ on ubuntu 24
2025-02-15 01:57:37 +09:00
ToruNiina
166e66cbba ci: use new versions of ubuntu
and new versions of compilers
2025-02-15 01:32:30 +09:00
ToruNiina
23c159775f docs: add accessed() to reference 2025-02-14 02:17:52 +09:00
ToruNiina
e6f90434bf feat [skip ci]: update single_include 2025-02-13 17:10:33 +00:00
ToruNiina
7f54791fc6 feat: Merge branch 'main' into perf-scanner-cache 2025-02-13 21:28:18 +09:00
ToruNiina
c4637a4222 feat: keep only 1 scanner in a cache
while parsing, thread_local cache will not use scanners constructed from
multiple toml::spec. we don't need to keep multiple scanners
2025-02-13 20:57:07 +09:00
ToruNiina
48ad269cfb ci: turn sanitizers on 2025-02-13 00:28:41 +09:00
ToruNiina
bc197bd600 ci: enable sanitizers 2025-02-12 23:49:10 +09:00
ToruNiina
3d7a66ff71 ci: add build tests with sanitizers 2025-02-12 01:17:52 +09:00
ToruNiina
f736cbe072 ci: add build with sanitizers 2025-02-12 01:17:34 +09:00
ToruNiina
17c5599ad6 feat: Merge branch 'main' into perf-scanner-cache 2025-02-12 01:10:37 +09:00
ToruNiina
405fd8e2ca feat: cache syntax scanner to speedup 2025-02-10 20:01:41 +09:00
ToruNiina
6462da85bc feat [skip ci]: update single_include 2025-02-07 16:15:32 +00:00
ToruNiina
37359d42e6 feat: directly use sub-scanners in special scanner 2025-02-08 00:59:08 +09:00
ToruNiina
46db8643c1 feat: Merge branch 'main' into refactor-scanner 2025-02-08 00:30:37 +09:00
ToruNiina
dda740281e fix: add missing include file 2025-02-07 01:26:58 +09:00
ToruNiina
d7aae40365 feat: add compare operators to spec 2025-02-07 01:06:23 +09:00
ToruNiina
7c94ae1500 feat: use escaped_uUx in parse_escape_sequence 2025-02-07 00:55:39 +09:00
ToruNiina
0e734cb3b6 feat: add syntax for each escape seqs 2025-02-07 00:49:26 +09:00
ToruNiina
122b8a2e74 refactor: use literal instead of seq(char,char) 2025-02-07 00:49:04 +09:00
ToruNiina
4fc4d7fd75 fix: escape backslash 2025-02-05 01:31:28 +09:00
ToruNiina
63e4e6fdab refactor: remove push_back from scanners 2025-02-05 00:28:14 +09:00
ToruNiina
5d78fc832d test: rm init_list ctor of char_either from test 2025-02-04 23:58:00 +09:00
ToruNiina
7f6913dafe feat: use character literal in character_either
using `std::vector` for this scanner requires many times of memory
allocation and free.
2025-02-04 23:57:12 +09:00
ToruNiina
45209aae4a feat [skip ci]: update single_include 2025-02-02 14:02:48 +00:00
ToruNiina
f64ef36ffa feat: Merge branch 'access-check' 2025-02-02 23:02:17 +09:00
ToruNiina
8043503961 ci: run access-check only in the latest env 2025-02-02 15:11:57 +09:00
ToruNiina
a1dd0bb677 doc: add accessed() 2025-02-02 14:05:46 +09:00
ToruNiina
0c5472eef3 doc: fix broken internal links 2025-01-30 01:35:34 +09:00
ToruNiina
067b46d8f5 ci: add on/off to TOML11_ENABLE_ACCESS_CHECK 2025-01-30 00:39:30 +09:00
ToruNiina
942eadef5c fix: guard access check funcs by macro 2025-01-30 00:35:36 +09:00
ToruNiina
46f009d25e feat: add test_accessed 2025-01-30 00:27:13 +09:00
ToruNiina
d2b66ba2e3 feat: unset access flag before returning 2025-01-30 00:26:53 +09:00
ToruNiina
8ec9257f26 feat: enable to unset flag 2025-01-30 00:13:26 +09:00
ToruNiina
074e3507aa feat: consider type check is also access 2025-01-30 00:13:10 +09:00
ToruNiina
bb082bc0bb feat: add accessed() flag 2025-01-29 01:31:15 +09:00
ToruNiina
cba2f062ae feat: add TOML11_ENABLE_ACCESS_CHECK macro 2025-01-28 01:33:42 +09:00
ToruNiina
fdd5e29f78 feat [skip ci]: update single_include 2025-01-27 16:32:29 +00:00
Toru Niina
9d55c4361c Merge pull request #283 from SunPodder/main
feat: add erase methods to ordered_map
2025-01-28 01:32:13 +09:00
ToruNiina
3a0a35aa4e feat [skip ci]: update single_include 2025-01-27 15:08:34 +00:00
Toru Niina
e23094aa9a Merge pull request #281 from ken-matsui/use-is_void
Use is_void<T> instead of is_same<T, void>
2025-01-28 00:08:14 +09:00
Sun Podder
c20968d1dd feat: add erase methods to ordered_map 2025-01-26 14:00:07 +06:00
Ken Matsui
2485f8fe03 Use is_void<T> instead of is_same<T, void>
The original code incorrectly accepts cv-qualified void types for
success.
2025-01-18 22:23:34 -05:00
ToruNiina
c87bdaaeea feat [skip ci]: update single_include 2025-01-18 08:23:45 +00:00
Toru Niina
9251741189 Merge pull request #280 from ken-matsui/find_or_default
Implement find_or_default
2025-01-18 17:23:28 +09:00
Ken Matsui
4ceba3a8ce Implement find_or_default 2025-01-18 01:16:54 -05:00
ToruNiina
499be3c177 doc: update example tag/version 2025-01-13 19:50:06 +09:00
ToruNiina
df089a82e5 feat [skip ci]: update single_include 2025-01-13 10:46:54 +00:00
ToruNiina
5396847979 chore: bump version 2025-01-13 19:46:24 +09:00
ToruNiina
9b83842948 docs: update CHANGELOG 2025-01-13 18:28:50 +09:00
ToruNiina
02d1f0b9e0 doc: update std::visit arguments 2025-01-13 18:28:08 +09:00
ToruNiina
1e7bea87b6 doc: update acknowledgement 2025-01-13 18:15:56 +09:00
ToruNiina
b09d02a921 feat [skip ci]: update single_include 2025-01-12 17:05:53 +00:00
ToruNiina
f69f7ae9f4 feat: Merge branch 'visit-multi' 2025-01-13 02:05:22 +09:00
ToruNiina
7fd0f39e4d feat [skip ci]: update single_include 2025-01-12 15:49:02 +00:00
ToruNiina
844e8fd4e0 fix(#279): fix compilation with older msvc
by avoiding known SFINAE problem in msvc 2017
2025-01-13 00:47:58 +09:00
ToruNiina
04c55d0b0f feat: toml::visit takes multiple values 2025-01-12 16:08:43 +09:00
ToruNiina
c9a00dea5c feat [skip ci]: update single_include 2025-01-05 11:15:45 +00:00
ToruNiina
0f6e08fe69 feat: Merge branch 'main' into find-optional 2025-01-05 18:34:52 +09:00
ToruNiina
0468b76bdc feat: merge branch 'check-source-location-file-name-result' 2025-01-05 18:34:14 +09:00
ToruNiina
12be4e7983 doc: update hugo-book
to avoid deprecation warning
2025-01-05 15:42:41 +09:00
ToruNiina
e781d37c05 feat [skip ci]: update single_include 2025-01-05 06:39:01 +00:00
ToruNiina
5bea3508c6 feat: Merge branch 'main' into check-source-location-file-name-result 2025-01-05 15:38:28 +09:00
ToruNiina
f042b38a23 feat: merge branch 'main' into issue278 2025-01-05 15:01:36 +09:00
ToruNiina
93428f295a doc: add find<optional> to docs 2025-01-05 14:50:17 +09:00
ToruNiina
d13ca04041 test: add test_find<optional<T>> 2025-01-05 14:27:26 +09:00
ToruNiina
7bfbfcab95 feat: add find<optional<T>> 2025-01-05 14:27:09 +09:00
ToruNiina
247796c8f6 chore: Merge branch 'main' 2024-11-27 02:53:57 +09:00
ToruNiina
c7717b6d70 ci: remove deprecated os and duplicated os 2024-11-27 01:51:29 +09:00
ToruNiina
8fcb759694 fix: check std::source_location::file_name result
encountered an error with nullptr from std::source_location::file_name
2024-11-26 02:42:51 +09:00
ToruNiina
869fdbdf8f feat: reduce memory consumption with long line
source_location stores the whole line. In case of short range in a long
line like:
```
array = [1, 2, 3, ... , 100, 101, ..., 10000]
                        ^^^- the region
```
It save the whole line as a `std::stirng`. It consumes a lot of memory
and slows down everything. We can omit most of the part of the line
because we only need the region, `100` here.
2024-10-21 03:03:13 +09:00
ToruNiina
42a2628924 feat: save column_number in location
instead of calculating it every time
2024-10-19 00:04:08 +09:00
ToruNiina
befe379241 refactor: restrict retrace dist == 1
to simplify the implementation
2024-10-18 02:24:11 +09:00
ToruNiina
f06ad06ad7 refactor: rm argument(same as default) of retrace 2024-10-18 02:21:38 +09:00
ToruNiina
5fbb86d989 refactor: rename adv_line_num -> adv_impl 2024-10-18 02:08:22 +09:00
ToruNiina
1ba90bc505 refactor: remove set_location 2024-10-18 00:35:13 +09:00
ToruNiina
7f6c574ff5 doc: update CPM in README with OPTIONS 2024-10-14 20:25:53 +09:00
Toru Niina
f925e7f287 Merge pull request #277 from oldoldtea/fix-readme 2024-09-30 21:14:01 +09:00
somebody
5445905e5e Update README.md
Co-authored-by: Toru Niina <niina.toru.68u@gmail.com>
2024-09-30 11:04:57 +08:00
lz
576a71aa0e update README.md 2024-09-29 15:27:07 +08:00
lz
2c96a2059f 🐞 fix(README.md): fix syntax errors 2024-09-29 15:25:57 +08:00
ToruNiina
d050c6b137 feat [skip ci]: update single_include 2024-09-23 13:44:01 +00:00
Toru Niina
9cda72d308 Merge pull request #276 from hayt/main
fix: prevent size_t-max length string allocation
2024-09-23 22:43:28 +09:00
hayt
b0d9e81d85 fix: prevent size_t-max length string allocation
prevent an issue, where a string was created with size_t(0)-1 length.

When creating underlines for error output, the current column sometimes had cases
where it was set to 0 caused an underflow.
2024-09-22 10:15:47 +02:00
Toru Niina
4b74012723 Merge pull request #271 from SeverinLeonhardt/CMP0127
Fix use with CMake 3.21 and older
2024-08-29 21:30:14 +09:00
Severin Leonhardt
5e786476dd Fix use with CMake 3.21 and older
The minimum required CMake version is 3.16 but CMP0127 was only
introduced in 3.22. This results in errors with versions 3.16 - 3.21:

```
CMake Error at CMakeLists.txt:28 (cmake_policy):

  Policy "CMP0127" is not known to this version of CMake.
```

Fixed by only setting the policy when it's actually available.
2024-08-27 09:40:48 +02:00
ToruNiina
26d403e461 feat [skip ci]: update single_include 2024-08-19 14:10:59 +00:00
Toru Niina
f40f4d7770 Merge pull request #268 from kontura/zero-init
fix: add missing zero initialization to region
2024-08-19 23:10:35 +09:00
Aleš Matěj
9c7cef94a5 fix: add missing zero initialization to region 2024-08-19 14:18:29 +02:00
ToruNiina
cc0bee4fd4 feat: bump version 2024-08-12 12:47:30 +09:00
ToruNiina
b415dd81ed doc: update changelog 2024-08-12 12:47:09 +09:00
ToruNiina
0c833452e4 Merge branch 'main' of github.com:ToruNiina/toml11 2024-08-12 00:24:30 +09:00
ToruNiina
070fa825e4 doc: update README 2024-08-12 00:23:59 +09:00
ToruNiina
a2e8d68c95 doc: update doc for thread-local colorization 2024-08-12 00:23:17 +09:00
ToruNiina
b90b5bdb35 feat [skip ci]: update single_include 2024-08-10 09:35:38 +00:00
ToruNiina
9b58c7e321 Merge branch 'find-or-deep-nest' 2024-08-10 18:35:10 +09:00
ToruNiina
5d74160df3 fix: do not use recursion in last_one(Ts...) 2024-08-10 14:19:11 +09:00
ToruNiina
3498af032f test: add deeply nested example to find_or 2024-08-10 14:17:05 +09:00
ToruNiina
9b914db23d doc: add description about ordered_type_config 2024-08-10 02:10:54 +09:00
Toru Niina
fcb1d3d7e5 Merge pull request #264 from jackwil1/jackwil1-docs-typo
Fix typos in documentation template syntax
2024-08-08 23:56:36 +09:00
Jack W
9d39b1f54a Fix template syntax in jp docs 2024-08-08 17:57:05 +12:00
Jack W
157d65f91f Fix template syntax in en docs 2024-08-08 17:55:13 +12:00
ToruNiina
9481c477f1 feat [skip ci]: update single_include 2024-08-07 16:25:53 +00:00
ToruNiina
f886a91c02 feat: Merge branch 'ci-osx-latest' 2024-08-08 01:04:38 +09:00
ToruNiina
834ec3a835 feat: include <exception> for terminate 2024-08-08 00:58:00 +09:00
ToruNiina
df8f978f3d ci: add macos with latest (unstable) xcode 2024-08-07 23:57:31 +09:00
ToruNiina
6421df3c6d ci: add missing cpu-cores var 2024-08-07 00:41:33 +09:00
ToruNiina
9f7434bc6e ci: add osx-14 to build envs 2024-08-07 00:41:17 +09:00
ToruNiina
91b7cd637c feat [skip ci]: update single_include 2024-08-06 15:37:10 +00:00
ToruNiina
63d9c04718 fix #262: merge 'check-empty-aot-while-format' 2024-08-07 00:36:24 +09:00
ToruNiina
80c3e343e7 fix: if aot is empty, format as oneline
[[aot]] itself defines an empty table, so there is no way to format an
empty array-of-tables as table-like format. the only way to format an
empty array is: = [].
2024-08-06 01:28:59 +09:00
ToruNiina
12c0f379f2 fix: typo in format output 2024-07-25 01:41:21 +09:00
ToruNiina
ff3d866728 feat [skip ci]: update single_include 2024-07-24 16:30:58 +00:00
Toru Niina
35ac3d1356 Merge pull request #261 from ken-matsui/make-thread-local-optional
Make thread_local for color_mode optional
2024-07-25 01:30:38 +09:00
Ken Matsui
696335aaf7 Make thread_local for color_mode optional 2024-07-24 07:04:40 -07:00
ToruNiina
83843fd699 feat [skip ci]: update single_include 2024-07-24 12:22:48 +00:00
Toru Niina
455fadbae0 Merge pull request #260 from ken-matsui/support-optional-conversion
Support std::optional members for TOML11_DEFINE_CONVERSION_NON_INTRUSIVE
2024-07-24 21:22:24 +09:00
Ken Matsui
6d4d953304 Support std::optional members for TOML11_DEFINE_CONVERSION_NON_INTRUSIVE 2024-07-23 10:03:58 -07:00
ToruNiina
572781971f doc: add doc about CPM 2024-07-23 01:29:13 +09:00
ToruNiina
0072e740d5 feat [skip ci]: update single_include 2024-07-21 15:53:41 +00:00
Toru Niina
4dd83fe778 Merge pull request #258 from pinotree/read-streamsize
fix: manually cast file size to std::streamsize
2024-07-22 00:41:56 +09:00
Pino Toscano
fe19e7ee0a fix: manually cast file size to std::streamsize
When reading a file to vector, manually cast the file size (represented
as std::streamoff hidden as auto) to std::streamsize, which is the type
for std::istream::read(); this avoids the warning/error

  error: conversion from ‘long long int’ to ‘std::streamsize’ {aka ‘int’} may change value [-Werror=conversion]

This means a truncation happens on 32bit architectures, however that
seems a limitation of the standard library.
2024-07-21 10:36:40 +02:00
ToruNiina
f33ca743fb chore: bump version 4.1.0 2024-07-21 14:48:47 +09:00
ToruNiina
754c1ef879 doc: update changelogs 2024-07-21 14:48:19 +09:00
ToruNiina
911abe939e doc: update acknowledgment in README 2024-07-21 14:34:20 +09:00
ToruNiina
100d05822a feat [skip ci]: update single_include 2024-07-20 16:01:53 +00:00
ToruNiina
feda8356a3 Merge branch 'example-u8string' 2024-07-21 01:01:24 +09:00
ToruNiina
88aaefd747 Revert "ci: build examples in each cases"
This reverts commit 4d0ad7335b.
2024-07-20 22:43:00 +09:00
ToruNiina
4d0ad7335b ci: build examples in each cases 2024-07-20 21:12:09 +09:00
ToruNiina
96460a15d4 feat: support key string conversion in get<map> 2024-07-20 20:57:42 +09:00
ToruNiina
a50895cdff doc: add u8string example 2024-07-20 20:57:18 +09:00
ToruNiina
886801d00a feat [skip ci]: update single_include 2024-07-20 10:07:38 +00:00
ToruNiina
f3a1586a44 Merge branch 'u8string' into v4_1_0 2024-07-20 17:59:30 +09:00
ToruNiina
098569a96d Merge branch 'main' into v4_1_0 2024-07-20 17:57:05 +09:00
ToruNiina
43f5a74bf0 feat: support string_type in toml::format 2024-07-20 17:23:05 +09:00
ToruNiina
6085c53ea2 fix: skip null char in string literal 2024-07-20 17:21:56 +09:00
Toru Niina
496782b42e Merge pull request #256 from CDK6182CHR/main
Support template into_toml members (Issue #255)
2024-07-20 16:20:24 +09:00
ToruNiina
f7deb1e89e feat [skip ci]: update single_include 2024-07-20 03:15:58 +00:00
xep
ce42e78e3c add test for template into_toml 2024-07-20 11:15:30 +08:00
xep
b853860a8f Add: template-version into_toml (Github issue #255) 2024-07-20 10:44:45 +08:00
ToruNiina
eba1aa2fde feat: take string type itself when conversion 2024-07-20 04:36:32 +09:00
ToruNiina
8434a6b18b Merge branch 'u8string' into v4_1_0 2024-07-18 01:03:58 +09:00
ToruNiina
eefca6e080 Merge branch 'main' into v4_1_0 2024-07-18 01:03:43 +09:00
ToruNiina
5e05b75473 test: add u8string constructor 2024-07-17 01:04:10 +09:00
ToruNiina
d9449747f3 fix: add constraint to array-like/table-like 2024-07-17 01:03:47 +09:00
ToruNiina
00e0ce12e7 feat: generalize ctor and remove feature macro 2024-07-16 23:48:15 +09:00
ToruNiina
92c2af024c feat: Merge branch 'ci-use-j' 2024-07-16 22:44:54 +09:00
ToruNiina
c9574b8ce6 ci: add cpu-cores and -j 2024-07-16 01:17:43 +09:00
ToruNiina
b68f1fd57f test: add case of get/find<u8string> 2024-07-16 01:03:19 +09:00
ToruNiina
d99f260c1a Merge branch 'origin/output-operator' into v4_1_0 2024-07-16 00:31:20 +09:00
ToruNiina
c0a8b60a5d feat: enable to convert generic string 2024-07-16 00:17:18 +09:00
ToruNiina
93503e9c59 fix: remove operator<<(basic_value) from test 2024-07-14 17:08:44 +09:00
ToruNiina
cae5f34fb1 doc: add int_fmt.uppercase to doc 2024-07-14 15:17:15 +09:00
ToruNiina
a69877005d test: check if uppercase is parsed 2024-07-14 15:14:01 +09:00
ToruNiina
452f1702c2 test: enable to output int_fmt.uppercase 2024-07-14 15:13:34 +09:00
ToruNiina
0f0f9cf3c1 feat: set upper/lowercase while serialization 2024-07-14 15:12:34 +09:00
ToruNiina
49b373d4f5 feat: parse hex int upper/lowercase 2024-07-14 15:12:18 +09:00
ToruNiina
acd6ed9a1e feat: add uppercase to integer fmt
for hex integer
2024-07-14 15:11:05 +09:00
ToruNiina
654ec0e013 feat: add stream operator to value 2024-07-14 14:20:04 +09:00
ToruNiina
9fd24aa23b feat [skip ci]: update single_include 2024-07-10 15:17:11 +00:00
Toru Niina
d8d325741c Merge pull request #253 from andreaskeller96/fix/correctly-resolve-carriage-return
Fix not checking for \r\n when parsing line comments
2024-07-11 00:06:43 +09:00
ToruNiina
f86d04f64d fix: toml::get<array-like> avoid u8string 2024-07-10 02:42:25 +09:00
ToruNiina
b78a37c826 feat: add u8string ctor 2024-07-10 02:39:51 +09:00
ToruNiina
29fbb6b695 feat: enable to convert key char type 2024-07-10 02:39:04 +09:00
ToruNiina
31810136d1 feat: generalize string converter 2024-07-10 02:37:29 +09:00
ToruNiina
a77516a2d0 feat: add string converter 2024-07-10 02:22:50 +09:00
ToruNiina
826e6414a0 feat: add detail::is_std_basic_string
to check if type T is a kind of std::basic_string<Char,...>
2024-07-10 02:04:31 +09:00
Andreas Keller
143437d309 Fix not checking for \\r\\n when parsing line comments 2024-07-09 09:50:31 +02:00
ToruNiina
5ac47b8983 chore: bump version to 4.0.3 2024-07-06 18:59:31 +09:00
ToruNiina
34a2091a4d doc: update README 2024-07-06 18:58:50 +09:00
ToruNiina
2e108e7010 feat [skip ci]: update single_include 2024-07-06 06:02:50 +00:00
ToruNiina
43c9c95de8 chore: avoid cmake compatibility warning 2024-07-06 14:48:55 +09:00
ToruNiina
9b41f4ab00 ci [skip actions]: trying to set newer SDK
to avoid warnings
2024-07-06 03:39:00 +09:00
ToruNiina
ed1604ca58 fix: ignore argument for NDEBUG build 2024-07-06 03:38:25 +09:00
ToruNiina
2c1269b82a ci: re-activate gcc/clang build 2024-07-06 02:38:07 +09:00
ToruNiina
ab94fbb2de feat [skip ci]: update single_include 2024-07-05 17:37:32 +00:00
ToruNiina
7ba94b37ab feat: merge branch 'add-werror' 2024-07-06 02:36:50 +09:00
ToruNiina
b2ea268d69 fix: unreachable code 2024-07-06 02:30:09 +09:00
ToruNiina
2912407d33 ci: temporary suppress gcc/clang 2024-07-06 02:29:56 +09:00
ToruNiina
b63668c0dc chore: raise msvc warning level 2024-07-06 02:14:24 +09:00
ToruNiina
d72493a2fc fix: remove name of unused argument 2024-07-06 01:37:11 +09:00
ToruNiina
58ddb8f589 doc: fix reference for the latest hugo ver 2024-07-06 01:31:20 +09:00
ToruNiina
9e194ea8b6 chore: add -Werror and while compilation 2024-07-06 01:13:32 +09:00
ToruNiina
be7d7257c9 feat [skip ci]: update single_include 2024-07-05 15:41:19 +00:00
ToruNiina
0eb9a90abf refactor: move HAS_CHAR8_T to version.hpp 2024-07-05 23:40:16 +09:00
ToruNiina
0cc0ef959b fix: directly access to member if type is the same 2024-07-05 23:32:00 +09:00
ToruNiina
edbea2f483 Merge branch 'add-test-case' 2024-07-03 01:58:17 +09:00
ToruNiina
973ecee32d fix: add missing include file 2024-07-03 00:24:45 +09:00
ToruNiina
b9b2ee02ff feat [skip ci]: update single_include 2024-07-02 15:23:57 +00:00
ToruNiina
d77caa94d0 chore: Merge 'fix-make-error-info' 2024-07-03 00:22:55 +09:00
ToruNiina
65e722da43 test: add minimum cases of serializer 2024-07-03 00:00:50 +09:00
ToruNiina
37d0391b9d test: add test to make error_info
check if it compiles
2024-07-02 23:35:16 +09:00
ToruNiina
d4742334ce fix: add detail::make_error_info_rec overload
that converts basic_value to location
2024-07-02 23:34:49 +09:00
ToruNiina
ccd941dc5b fix: remove default arg from fwd decl 2024-07-02 00:03:10 +09:00
ToruNiina
fc493afb4e chore: update version 4.0.2 2024-06-30 23:59:23 +09:00
ToruNiina
1d3abc9718 ci: remove verbose message from ci build 2024-06-30 17:40:40 +09:00
ToruNiina
9f59c591f0 feat [skip ci]: update single_include 2024-06-29 15:56:19 +00:00
ToruNiina
de092e5457 fix: cast fsize to avoid sign-conv 2024-06-30 00:55:45 +09:00
ToruNiina
bcd8a6d1e4 doc: update notice about open mode
in overload of toml::parse that takes file stream or FILE* itself
2024-06-30 00:47:44 +09:00
ToruNiina
5b0ea5e95c fix #249: make sure all the file content is read 2024-06-30 00:29:34 +09:00
ToruNiina
d00c0c1b15 doc: explain a macro to link pre-built lib 2024-06-28 23:52:58 +09:00
ToruNiina
5d23f4b8a8 feat [skip ci]: update single_include 2024-06-27 15:08:22 +00:00
ToruNiina
42734ea642 fix: typo in type-trait impl 2024-06-28 00:07:26 +09:00
ToruNiina
8596419e24 feat [skip ci]: update single_include 2024-06-26 15:31:25 +00:00
ToruNiina
932acba7f1 fix #250: bump patch version macro in version.hpp 2024-06-27 00:30:38 +09:00
ToruNiina
b2a93eb267 chore: auto extract version string in cmake 2024-06-27 00:28:40 +09:00
ToruNiina
e004eaf006 Merge branch 'main' of github.com:ToruNiina/toml11
to merge single_include update
2024-06-24 00:30:38 +09:00
ToruNiina
7c336a52a0 doc: update changelog in docs 2024-06-24 00:26:15 +09:00
ToruNiina
bc7c5cd7a3 feat [skip ci]: update single_include 2024-06-23 14:59:17 +00:00
ToruNiina
3c09d3046c refactor: remove detail::(local|gm)time_s from fwd 2024-06-23 23:25:57 +09:00
ToruNiina
7af0e66c25 refactor: add make_xxx_error funcs 2024-06-23 15:36:50 +09:00
ToruNiina
8c20067493 fix: title in example README 2024-06-23 15:32:50 +09:00
ToruNiina
89921483a8 feat [skip ci]: update single_include 2024-06-20 15:47:00 +00:00
ToruNiina
1bc6ef9fce ci: fix git options 2024-06-21 00:46:01 +09:00
ToruNiina
312996565d ci: add token 2024-06-21 00:27:14 +09:00
ToruNiina
db46c1c64b ci: fix git options 2024-06-21 00:24:03 +09:00
ToruNiina
34bf32a9e5 ci: fix symbol quote in if statement 2024-06-21 00:07:32 +09:00
ToruNiina
137f17f2e9 ci: add gen-single-include 2024-06-21 00:05:48 +09:00
ToruNiina
5e8d8d0243 doc: fix link in README 2024-06-21 00:05:09 +09:00
ToruNiina
9e27fd24b7 Merge branch 'fix-format-location-first-line' 2024-06-20 22:18:44 +09:00
ToruNiina
d023a93e3c fix: do not duplicate empty line in err msg 2024-06-20 21:11:43 +09:00
ToruNiina
995b25efe0 fix: pass empty filename to format_location
not to skip the first empty line
2024-06-20 21:10:42 +09:00
Toru Niina
6ba0772053 Merge pull request #248 from egorpugin/patch-1
Fix incorrect operator<<() argument type that gives build error.
2024-06-20 00:35:38 +09:00
Egor Pugin
a32289dc70 Fix incorrect operator<<() argument type that gives build error. 2024-06-19 17:42:10 +03:00
ToruNiina
7149b3cb29 refactor: rename member vars, adding _ at the end 2024-06-19 01:55:57 +09:00
ToruNiina
013d1e396f feat: use brace init in ctor for raw values 2024-06-19 01:45:58 +09:00
ToruNiina
7cab13f6e5 feat: use brace-init list for raw memvars 2024-06-19 01:45:29 +09:00
ToruNiina
74bea5368a fix #246: use brace-init in major/minor
to avoid name collision with <sys/sysmacros> major and minor
2024-06-19 01:36:40 +09:00
ToruNiina
4efae93585 feat: update single_include 2024-06-17 00:56:07 +09:00
ToruNiina
3e2a155b62 doc: add readme to tools/expand 2024-06-17 00:55:02 +09:00
ToruNiina
fbfdb6af30 fix: call destructor correctly 2024-06-17 00:21:28 +09:00
ToruNiina
835d38a22b feat: add SFINAE to result template ctor 2024-06-17 00:21:11 +09:00
ToruNiina
f317cc0448 ci: add fuzzer workflow
Squashed commit of the following:

commit b13ab5d298da1472e27254b801e21b26fe8c5e3f
Merge: 2feb35e 26212f3
Author: ToruNiina <niina.toru.68u@gmail.com>
Date:   Mon Jun 17 00:08:04 2024 +0900

    [skip appveyor] Merge branch 'main' into fuzzing

commit 2feb35e83e3f2f9b68f5e2074c9ddbce9a8b0ebc
Author: ToruNiina <niina.toru.68u@gmail.com>
Date:   Mon Jun 17 00:07:34 2024 +0900

    fix: call destructor correctly

commit c6078b5afec054bd7f488c4de8cbbd719fa89d3b
Author: ToruNiina <niina.toru.68u@gmail.com>
Date:   Mon Jun 17 00:07:12 2024 +0900

    feat: add SFINAE to template ctor of result

commit 850ea75bae7c7f54bde653cd99c066240bd95674
Author: ToruNiina <niina.toru.68u@gmail.com>
Date:   Sun Jun 16 22:16:17 2024 +0900

    fix: path to fuzzer impl

commit e91edeae96b48b243b97c96f36ca027cace6925b
Author: ToruNiina <niina.toru.68u@gmail.com>
Date:   Sun Jun 16 22:10:07 2024 +0900

    ci[skip appveyor]: move fuzzing dir to default dir

commit 3bd51f2047936e9abb6dd47e627379b04d711d2b
Author: ToruNiina <niina.toru.68u@gmail.com>
Date:   Sun Jun 16 21:46:56 2024 +0900

    ci[skip appveyor]: temporary remove other workflows

    until fuzzer works

commit 847a76e089e12302557ba7ffd699d2b26e3e954a
Author: ToruNiina <niina.toru.68u@gmail.com>
Date:   Sun Jun 16 21:46:02 2024 +0900

    ci[skip appveyor]: add fuzzer workflow
2024-06-17 00:20:45 +09:00
ToruNiina
26212f3536 ci: fix option name 2024-06-16 22:32:22 +09:00
ToruNiina
aa76604585 test: add (void) to not to discard v.value()
even if v is empty so value() never returns anything
2024-06-16 22:13:59 +09:00
ToruNiina
27e8976d37 ci[skip appveyor]: stop building unit tests
build toml-test related stuff only
2024-06-16 21:55:05 +09:00
ToruNiina
5638ea90b1 test: stop using std::gmtime in tests 2024-06-16 21:49:57 +09:00
ToruNiina
8da85f8d2a ci: add missing option to encoder test 2024-06-16 21:19:48 +09:00
ToruNiina
1511452747 ci: fix path to decoder v1.1.0 2024-06-16 21:14:26 +09:00
ToruNiina
adeb1c7bb8 doc: add gitignore to docs 2024-06-16 20:57:20 +09:00
ToruNiina
18ccd6b237 fix: include test dir if BUILD_TOML_TESTS=ON 2024-06-16 20:56:24 +09:00
ToruNiina
acf00fc476 ci: fix name of workflow 2024-06-16 20:52:55 +09:00
ToruNiina
51805ba537 ci: use actions/setup-go to to setup go 2024-06-16 20:51:48 +09:00
ToruNiina
5dcbec0fad ci: add toml-test workflow 2024-06-16 20:45:30 +09:00
ToruNiina
29f8517cf4 test: set precision if non-toml float is given
in toml-test encoder test, it passes a large integer with float type.
in that case, we used a std::stringstream, so no prec information is
stored.
2024-06-16 20:43:17 +09:00
ToruNiina
717c2d8eaa doc: add links to README 2024-06-16 20:33:10 +09:00
ToruNiina
24b24d7fa9 fix: deploy dir, and update actions-gh-pages 2024-06-16 20:20:44 +09:00
ToruNiina
f48d3f81fe ci: use submodule as theme location 2024-06-16 20:03:45 +09:00
ToruNiina
38e4a34ea2 doc: update README a bit 2024-06-16 19:43:40 +09:00
ToruNiina
172ddcbd12 feat: update single_include/toml.hpp 2024-06-16 19:35:58 +09:00
ToruNiina
9c725140ca refactor: add basic_value::config_type 2024-06-16 19:33:55 +09:00
ToruNiina
5c4722fb5d feat: use MSVC_LANG after 2015 Update 3 2024-06-16 19:33:22 +09:00
ToruNiina
6f05bffb5f fix: do not use assert-only never reached branch 2024-06-16 19:32:54 +09:00
ToruNiina
872ef72572 fix: use sscanf_s in case of MSVC 2024-06-16 19:32:28 +09:00
ToruNiina
cb1a20407d fix: add missing include file 2024-06-16 19:31:29 +09:00
ToruNiina
c5851db533 fix: do not use std::gmtime in tests 2024-06-16 19:30:35 +09:00
ToruNiina
3443f86a4a chore: use warning level 3 in msvc 2024-06-16 19:29:16 +09:00
ToruNiina
12452a695d ci: use appveyor for multi msvc versions 2024-06-16 19:28:46 +09:00
ToruNiina
9fa137599f feat: add hugo theme as a submodule 2024-06-16 13:27:22 +09:00
ToruNiina
abcbed92a3 chore: add options required to use MSVC
to use utf-8 file and to use standard-compliant preprocessor
2024-06-16 13:12:12 +09:00
ToruNiina
8326709fae fix: set prec as max in case of hex 2024-06-16 13:11:47 +09:00
ToruNiina
6533454bc6 fix: template forgotten to rewrite
Squashed commit of the following:

commit c0b2ff1cd5de60c467d22a9174c0b8439f234b34
Author: ToruNiina <niina.toru.68u@gmail.com>
Date:   Sun Jun 16 12:27:58 2024 +0900

    ci: turn on ci

commit 41f6e1d4d710b841580c0a34126cbdc5c95203b0
Author: ToruNiina <niina.toru.68u@gmail.com>
Date:   Sun Jun 16 12:27:44 2024 +0900

    refactor: remove debug dumps

commit d037e26a5a77102168f9c30694e158e8388bddb6
Author: ToruNiina <niina.toru.68u@gmail.com>
Date:   Sun Jun 16 12:19:43 2024 +0900

    fix: avoid taking next of end

commit 0ce5565686a0f684d61dc55014e4cd670ecbfc87
Author: ToruNiina <niina.toru.68u@gmail.com>
Date:   Sun Jun 16 12:14:04 2024 +0900

    ci(WIP): add more debug dumps

commit e7ebef57d5d463ff591c37c120a1bed93824a7ba
Author: ToruNiina <niina.toru.68u@gmail.com>
Date:   Sun Jun 16 00:41:36 2024 +0900

    ci(WIP): add more debug dumps

commit 8e3488e038d5241af14dab334bedbae911bc6d29
Author: ToruNiina <niina.toru.68u@gmail.com>
Date:   Sun Jun 16 00:33:52 2024 +0900

    ci(WIP): add iostream

commit 4198d1274c5a8701df885f5fb36ef1d54ea9b18e
Author: ToruNiina <niina.toru.68u@gmail.com>
Date:   Sun Jun 16 00:32:13 2024 +0900

    ci(WIP): add debug dumps

commit 1c87d24743f9b3228c7ed216e9e2a4d7cb588f6d
Author: ToruNiina <niina.toru.68u@gmail.com>
Date:   Sun Jun 16 00:06:11 2024 +0900

    ci: disable ci jobs except msvc

commit 605ee1e7635c7f99f150ede70360d0ca792de7c0
Author: ToruNiina <niina.toru.68u@gmail.com>
Date:   Sun Jun 16 00:06:00 2024 +0900

    ci(WIP): add debug dumps

commit 2851b22246fc87fa26ac8d4d708dccf02fd3dbee
Author: ToruNiina <niina.toru.68u@gmail.com>
Date:   Sat Jun 15 23:59:06 2024 +0900

    chore: mark interface for interface lib

commit 74e5e49d2c1540d055e8397b3ce5d7b22dc50288
Author: ToruNiina <niina.toru.68u@gmail.com>
Date:   Sat Jun 15 23:53:50 2024 +0900

    chore: add required options for MSVC

commit 5ec385753473d1535b769299c66438eed929330a
Author: ToruNiina <niina.toru.68u@gmail.com>
Date:   Sat Jun 15 23:53:34 2024 +0900

    ci: fix typo after copy-paste
2024-06-16 13:11:13 +09:00
ToruNiina
c7db1a3de0 fix: typo in macro definitions 2024-06-15 22:35:16 +09:00
ToruNiina
6cf003f374 ci: install hugo module 2024-06-15 22:21:32 +09:00
ToruNiina
bb2542f2bf chore: remove debug flag fatal-errors from ci 2024-06-15 21:55:25 +09:00
ToruNiina
3a1e893d68 ci: add actions test and docs 2024-06-15 19:41:59 +09:00
ToruNiina
1e97dff5e3 chore: update gitignore 2024-06-15 19:38:00 +09:00
ToruNiina
7444d2df95 ci: reset all ci setup 2024-06-15 19:35:19 +09:00
ToruNiina
2c6460ae77 fix: add example/CMakeLists 2024-06-15 19:32:30 +09:00
ToruNiina
4b5e85c2bc doc: update README 2024-06-15 19:28:16 +09:00
ToruNiina
64197caa05 doc: add reference manual 2024-06-15 19:27:42 +09:00
ToruNiina
7210e708a6 feat: add single_include file and generator 2024-06-15 19:25:15 +09:00
ToruNiina
da2a85b500 feat: add examples 2024-06-15 19:23:05 +09:00
ToruNiina
7789b4e8be feat: add json to tests/extlib 2024-06-15 19:19:12 +09:00
ToruNiina
e68e77320d feat: add doctest as a submodule 2024-06-15 19:15:09 +09:00
ToruNiina
3f9e3ce5d2 feat: update build system to v4 2024-06-15 19:14:44 +09:00
ToruNiina
c47ff10a64 test: update test codes to v4 2024-06-15 19:14:06 +09:00
ToruNiina
7c123ab378 feat: update codes to v4 2024-06-15 19:13:02 +09:00
ToruNiina
7277ebdbad feat: move codes under include/ 2024-06-15 19:11:46 +09:00
Toru Niina
b389bbc4eb Merge pull request #242 from 0X1A/master
Fix issues with CMake package configuration when used with vcpkg #110
2024-06-12 00:46:15 +09:00
ToruNiina
5e4eb52f84 fix: add cxx_std to check_cxx_source_compiles
in macos, default version is 98 and it fails to compile boost test.
ci fails in the test branch because of apt timeout, but osx jobs works.
2024-06-11 23:47:49 +09:00
Alberto Corona
cbd596144d Fix issue with CMake package configuration #110 2024-05-01 18:57:49 -05:00
ToruNiina
85faca9cbe ci: update action checkout 2024-03-20 23:43:01 +09:00
ToruNiina
3509be6629 ci: add env var to avoid installation failure 2024-03-20 23:33:47 +09:00
ToruNiina
fb7b02f254 ci: remove old version of osx that takes time 2024-03-20 23:33:27 +09:00
ToruNiina
2466959cf9 chore: avoid false-positive ref life warning 2024-03-20 22:42:00 +09:00
ToruNiina
a76c5b385f refactor: replace mut-ref by take-and-move pattern 2024-03-20 22:40:46 +09:00
ToruNiina
52621a4fd8 feat: remove cxx_standard related stuff
fix #241
2024-03-20 22:38:56 +09:00
ToruNiina
64cd90637b refactor: move cmake component to where it's used 2024-03-20 22:35:03 +09:00
ToruNiina
d4a6fc7953 refactor: remove scripts for old version of cmake
now minimum_require ensures that version is not used
2024-03-20 22:34:02 +09:00
ToruNiina
d4eb5f3c9d chore: update patch version 2024-01-07 18:06:50 +09:00
ToruNiina
cc2e453b5b feat: remove strerror from errmsg in FILE* version
parse(FILE*) is a minor overload, but dispatching strerror takes too
much cost. Standard library version is not thread-safe, so some compiler
reports a warning. There are thread-safe versions defined in XSI, GNU,
and Windows. XSI/GNU versions can be detected by macros, but in some
cases, detection-by-macro written in the doc does not work.
Since errno can be obtained from the exception, users can call strerror
that is available in their env if needed. We can just report errno.
2024-01-07 10:48:17 +09:00
ToruNiina
8ed1a1d7e4 feat: update version 2024-01-06 02:20:21 +09:00
ToruNiina
04209b1540 doc: update contributors list 2024-01-06 01:58:51 +09:00
Toru Niina
1bb5284eb5 Merge pull request #233 from Esonhugh/master
fix issue #231
2024-01-05 01:39:23 +09:00
Toru Niina
7bd09245fa ci: disable macos-13-arm64 2024-01-05 00:00:25 +09:00
Toru Niina
1dd15ffa26 Merge pull request #234 from ToruNiina/limit-value-recursion
Limit value recursion
2024-01-04 22:32:01 +09:00
ToruNiina
1c2c710ec9 refactor: add comment 2024-01-04 21:18:47 +09:00
ToruNiina
db72451bcf test: update test to add rec start val 2024-01-04 20:47:46 +09:00
ToruNiina
8e214ec411 fix: limit value recursion in array/inl-table
to avoid parse_value/parse_array recursion
2024-01-04 20:45:35 +09:00
Esonhugh
655d76b828 update: test on github action with macos 13 and macos 13 arm64 image 2023-12-27 11:27:21 +08:00
Esonhugh
0db935b602 fix: let __DARWIN_C as an exception 2023-12-27 11:19:59 +08:00
Esonhugh
ed577df40a fix: strerror_r error handling toml/exception.hpp in macos 2023-12-27 11:11:23 +08:00
ToruNiina
01a0e93e5f ci: disable bad combination of compiler and stdlib 2023-12-23 23:32:39 +09:00
Toru Niina
510419fb6a Merge pull request #232 from DavidKorczynski/clusterfuzzlite
Add fuzzing by way of ClusterFuzzLite
2023-12-23 22:28:46 +09:00
David Korczynski
7d09cdf067 cflite: change branch name
Signed-off-by: David Korczynski <david@adalogics.com>
2023-12-23 03:00:51 -08:00
David Korczynski
828afc3b1e Add fuzzing by way of ClusterFuzzLite
Signed-off-by: David Korczynski <david@adalogics.com>
2023-12-23 01:12:21 -08:00
ToruNiina
c32a20e1ee fix: #226 use strerror_s/strerror_r if possible 2023-10-11 23:44:23 +09:00
ToruNiina
937a7c45fe feat: fill char buffer with null char
those funcs always return null-terminated string but just to make it
sure
2023-10-11 01:44:30 +09:00
ToruNiina
947c995189 fix: include array to use char buffer 2023-10-11 01:43:55 +09:00
ToruNiina
9b7b8908e8 fix: avoid evaluating undefined macro as zero
to suppress a warning
2023-10-11 01:24:41 +09:00
ToruNiina
22d22198ec feat: use thread-safe variant of strerror 2023-10-11 01:08:12 +09:00
ToruNiina
1beb391a43 ci: use default version of libboost on ubuntu 20 2023-10-11 00:14:53 +09:00
ToruNiina
dfc625f38d fix: #229 do not move temporary object 2023-10-10 23:49:51 +09:00
Toru Niina
22d96ed921 Merge pull request #230 from arp242/t
Escape control characters in keys
2023-10-10 23:21:43 +09:00
Martin Tournoij
d2937ff4e1 Escape control characters in keys
Previously a key like:

        "a\u0000\u0001b" = 1

Would get written with literal control characters, rather than escapes:

        "a<00><01>b" = 1

The "valid/key/quoted-unicode" test from toml-test would fail with this,
although it seems they're not run automatically(?)

Can also reproduce with something like:

        % cat test.cpp
        #include <toml.hpp>
        #include <iostream>

        int main()
        {
                const auto data  = toml::parse("test.toml");
                std::cout << data << "\n";
                return 0;
        }

        % cat test.toml
        "a\u0000\u0001b" = "a\u0000\u0001b"

        % c++ -I. test.cpp

        % ./a.out
        "ab" = "a\u0000\u0001b"

        % ./a.out | hexdump -C
        00000000  22 61 00 01 62 22 20 3d  20 22 61 5c 75 30 30 30  |"a..b" = "a\u000|
        00000010  30 5c 75 30 30 30 31 62  22 0a 0a                 |0\u0001b"..|
2023-10-10 09:03:33 +01:00
Toru Niina
087408a8fb Merge pull request #225 from kfirgollan/kfir/add_install_instructions
Add installation example with checkinstall and cmake
2023-07-31 01:22:32 +09:00
Kfir Gollan
2339b32258 Add installation example with checkinstall and cmake 2023-07-28 19:02:01 +00:00
Toru Niina
5cc79bbd7b Merge pull request #224 from offa/remove_travisci
Remove Travis CI config
2023-07-27 20:55:45 +09:00
Toru Niina
9323a315eb Merge pull request #223 from offa/cmake_update
Require CMake 3.5+
2023-07-27 20:55:05 +09:00
offa
85d880d84e Remove Travis CI config 2023-07-25 20:14:37 +02:00
offa
c44459dc47 Require CMake 3.5+ 2023-07-25 20:09:52 +02:00
ToruNiina
1340692442 fix #218: consider locale while serialization 2023-05-29 23:18:38 +09:00
ToruNiina
da3d5153d1 ci: install language pack to test locale 2023-05-28 23:37:53 +09:00
ToruNiina
af13c2867a test: add test case for serializer with locale 2023-05-28 18:47:06 +09:00
ToruNiina
327f6e7701 fix: set locale to C when writing numbers 2023-05-28 18:42:33 +09:00
ToruNiina
e36eabf216 feat: add get<T> overload with toml::value& 2023-05-27 00:16:17 +09:00
ToruNiina
40eb1d2213 chore: update ci runners to the latest 2023-04-29 02:16:40 +09:00
ToruNiina
2da3b67d02 doc #217: add description about C++17 feature 2023-04-24 22:36:08 +09:00
ToruNiina
0dcf07b774 doc: update contributor list 2023-04-24 22:34:49 +09:00
Toru Niina
d47fe788bc Merge pull request #214 from VestniK/raw_ptr_iter
Fix for case when vector iterator is raw pointer
2023-03-17 22:11:38 +09:00
Sergey Vidyuk
78ae165096 Fix for case when vector iterator is raw pointer
We are using patched libc++ which uses raw pointers for vector itrators
to improve code compilation speed. This commit fixed two compilation
issues in toml11:
 * location::const_iterator deinition assumes that vector const_iterator
   is struct or class type rather than raw pointer.
 * `const const_itetr foo()` triggers `-Wignored-qualifiers` for primitive
   types and `void` which breaks `-Wextra -Werror` compilation.
2023-03-16 23:02:19 +07:00
ToruNiina
86eefc7255 feat: update toml-test from v1.2.0 to v1.3.0 2023-02-13 00:44:15 +09:00
ToruNiina
51e5d845b0 fix: #213 allow long binary integer 2023-02-12 23:20:09 +09:00
ToruNiina
ce941c318b fix: prevent windows minmax macro 2023-02-12 20:27:14 +09:00
ToruNiina
fd969a679b test: check if a large bin ints are parsed 2023-02-12 19:03:59 +09:00
ToruNiina
51587338cd fix: avoid overflow at postproc of the last loop 2023-02-12 18:50:46 +09:00
ToruNiina
418bfe9117 fix: cast explicitly to avoid un/signed comparison 2023-02-12 16:44:18 +09:00
ToruNiina
15346114ef fix: allow long binary integer and leading zeros 2023-02-12 16:22:23 +09:00
ToruNiina
565f43c484 fix: #211 reopen table implicitly defined by aot 2023-02-12 15:55:20 +09:00
ToruNiina
f9b224c222 fix: reopening table implicitly defined by aot 2023-02-12 02:55:03 +09:00
Toru Niina
72789dca42 Merge pull request #210 from offa/action_update
Update checkout action to v3
2023-02-11 23:47:41 +09:00
Toru Niina
75daa2dde0 Merge pull request #208 from cxw42/issue199-nonutf-string
Fix address-sanitizer error when parsing literal strings having invalid UTF-8 characters
2023-02-11 23:46:53 +09:00
Toru Niina
ff48387677 Merge pull request #207 from cxw42/misc
Add .editorconfig; fix some error messages in the parser
2023-02-11 23:43:59 +09:00
offa
132aa17f97 Update checkout action to v3 2023-01-22 16:01:50 +01:00
Chris White
a2f884b11e fix: parse_ml_literal_string() properly issues invalid-utf8 errors
Fix the same out-of-bounds read as in parse_literal_string().
2023-01-14 18:32:40 -05:00
Chris White
e3639d2bbc fix: parse_literal_string() properly issues invalid-utf8 errors
When creating the inner iterator, make sure it points into the same
vector as the outer iterator.  Otherwise, attempts to reset the iterator
wind up causing it to read out-of-bounds.

Fixes #199.
2023-01-14 18:32:40 -05:00
Chris White
626b0e6b95 fix: Correct function names in error messages
- fix error messages that referred to the wrong functions.
- parse_key(): remove "detail::" from the only error message that had
  it, for consistency with the other error messages in that function
2023-01-14 18:24:17 -05:00
Chris White
0acd2b9c88 Add EditorConfig file
Four-space indents in C++ files; two-space indents in Markdown and YAML.
2023-01-14 18:18:05 -05:00
ToruNiina
22db720ad5 fix: #202 do not set CMAKE_CXX_STANDARD 2022-10-24 23:56:51 +09:00
ToruNiina
7ec3086f19 ci: update appveyor script 2022-10-24 22:55:43 +09:00
ToruNiina
4c4e82866e feat: CMAKE_CXX_STD should be given by the enduser 2022-10-24 22:42:31 +09:00
Toru Niina
41908b2cef Merge pull request #200 from ctcmkl/several-simple-patches
Several simple patches
2022-09-30 23:33:57 +09:00
Moritz Klammler
3f197c3cab Fix use-after-move in test_parse_function_compiles and refactor
My recent patch had introduced a conditional use-after-move bug into the
test_parse_function_compiles function.  This patch fixes that by
reworking the entire test case into a compile-time check.  In my
opinion, we're not loosing anything by not actually executing the code
(the result wasn't looked at anyway) and the code becomes much clearer
by omitting the argument-preparation fluff.
2022-09-29 19:22:25 +02:00
Moritz Klammler
e064a5c371 Avoid unnecessary copies of parser result
The 'result' class has unwrap() and unwrap_err() member functions
overloaded for const lvalue and rvalue *this to avoid an unnecessarily
copying the to-be unwrapped object of its containing object is going to
be discarded anyway.  Alas, the parse() function toml/parser.hpp file
stored the parse result in a local `const` variable so, although the
unwrap call would have been the last use of the object in each case, the
unnecessary copy would still be made.  This patch removes the `const`
and adds a std::move() to actually benefit from the already implemented
optimization.
2022-09-29 19:02:52 +02:00
Moritz Klammler
e86d7c3cd3 Remove excess blank lines at end of file 2022-09-29 19:02:52 +02:00
Moritz Klammler
10fd14f8b9 Consistent unit test header inclusion order
This patch consistently changes the inclusion order for unit test files
to the following:

 1. The header of the unit under test (using <> includes).
 2. The unit_test.hpp header (using "" includes).
 3. Any additional auxiliary test headers (using "" includes and sorted alphabetically).
 4. Additional system headers needed for the test (using <> includes and sorted alphabetically).
 5. Conditionally included system headers (using <> includes).

Putting the unit under test's header at the very beginning has the
advantage of also testing that the header is self-contained.  It also
makes it very quick to tell what unit is tested in this file.
2022-09-29 19:02:52 +02:00
Moritz Klammler
81c5ba9082 Define BOOST_TEST_MODULE in CMake
This removes one #define from each unit test file and ensures
consistency between file and module names.  This consistency, was not
strictly maintained before.  I hope that any discrepancies were
unintentional and that a 1:1 mapping is actually what is desired.

Since the definition is now done at one single place, it would be easy
to apply transformations like removing the 'test_' prefix or replacing
'_' with '-' if this should be desired.
2022-09-29 19:02:52 +02:00
Moritz Klammler
d7c04ed5ee Factor redundant test boilerplate out into unit_test.hpp helper 2022-09-29 19:02:52 +02:00
Moritz Klammler
b10348c576 More flexible https://github.com/toml-lang/toml handling
Instead of unconditionally attempting to clone from a fixed location
(GitHub) during the build / test process, honor the following two
configuration variables:

  TOML11_LANGSPEC_GIT_REPOSITORY
    Can be set to override the URL from which the repository is cloned.
    This allows using a local mirror, including file:// URLs for working
    offline or reducing network traffic.

  TOML11_LANGSPEC_SOURCE_DIR
    Can be set to configure the location at which the repository is
    expected.  If it already exists no download will be attempted.  This
    allows avoiding the additional git-clone(1) altogether and use an
    existing directory as-is.  This offers two new possibilities:
    (1) The same checkout can be reused for building multiple
    configurations (e.g. Debug versus Release) saving a little bit of
    time and disk space.
    (2) Experimental changes can easily be applied to the local source
    tree without having them destroyed by the build process.

In order for this flexible location to work, the unit tests which
attempt to read files from the repository had to be adjusted.  They now
honor an environment variable TOMLDIR which can be set to point to an
alternate root directory.

All defaults are set such that the previous behavior is maintained.

Instead of introducing the TOMLDIR environment variable, an alternative
solution would have been to set the WORKING_DIRECTORY of the tests to
the TOML11_LANGSPEC_SOURCE_DIR and leave the relative paths in these
tests hard-coded.  Alas, some tests also expect that they can /write/
into the current working directory which isn't desirable if it is
potentially pointing outside the build tree.  I personally prefer to
mount the source directory read-only and build in a fast tempfs, so this
would e a problem.  To be perfectly honest, I don't quite understand why
these tests need to write to the file system in the first place, though.
It seems to me that refactoring them to serialize to a std::ostrstream
instead of a std::ofstream would not only simplify but also speed up the
unit tests and avoid file system problems.  But there might have been a
hidden reason why actually using the real file system was considered
necessary for these tests, so I didn't went ahead with that change yet.
2022-09-29 19:02:52 +02:00
Moritz Klammler
ac949437f8 Avoid false negative Boost.Test detection due to -Werror
Depending on the CMake and Boost version, the -Werror flags that might
get added to CMAKE_CXX_FLAGS could adversely affect the feature
detection logic, leading to the wrong conclusion that Boost.Test isn't
usable altogether.  Performing these checks first and only afterwards
altering CMAKE_CXX_FLAGS avoids this issue.
2022-09-29 17:59:28 +02:00
Moritz Klammler
fe471bcbe9 Autodetect the best option to use Boost.Test
The conditional inclusion of either the library or the header-only
version of the Boost.Test header wasn't tremendously useful in practice
because the tests/CMakeLists.txt file would unconditionally add compile
definitions to basically fore dynamic linking.

This patch adds feature detection to the tests/CMakeLists.txt file to
determine whether to use dynamic linking, static linking or the
header-only version (in that order of preference, for best performance).

The automatic detection could be overridden if needed by defining the
TOML11_WITH_BOOST_TEST_{HEADER,STATIC,DYNAMIC}
variables on the CMake command line.

While we are at it, instead of having a conditional
#define BOOST_TEST_NO_LIB
in each unit test file, handle this once in the CMakeLists.txt file.
2022-09-29 17:59:28 +02:00
Moritz Klammler
5312b8eb0e Honor UNITTEST_FRAMEWORK_LIBRARY_EXIST in all unit test files
Most unit test files checked UNITTEST_FRAMEWORK_LIBRARY_EXIST and
adapted themselves accordingly to either use the header-only version or
link with the library.  Alas, eight files didn't so the project couldn't
really be tested with the header-only version of that Boost library.

This patch adds the missing pre-processor logic to the files that were
missing it.  The style of using no indentation after the '#' was
followed from the existing unit test files.  Some other files in this
repository do indent their pre-processor logic, though.

Since replicating the conditional in every file is kind of verbose,
tedious and, apparently, easily forgotten, I'm wondering whether
isolating that logic into a tiny little auxiliary header and then
unconditionally including that one in each unit test file would be a
good idea, though.
2022-09-29 17:59:28 +02:00
Moritz Klammler
cf8a977be2 Don't deliberately dereference the null pointer
This patch addresses a static analysis issue reported by Cppcheck 2.9
where several member functions of the toml::discard_comment class
defined in the toml/comments.hpp header were implemented to deliberately
dereference the null pointer returned unconditionally by the
always-empty container's data() member function.  This behavior wasn't
technically wrong because those functions all have as precondition that
the container is non-empty so they must never be called on an instance
of toml::discard_comment but we can still be more helpful without
adversely affecting code generation.  Instead of dereferencing the null
pointer, this patch has these functions call an inline private helper
function which is defined to invoke __builtin_unreachable() if available
"and then" throw an exception with a helpful error message.  Even at the
-O1 level, GCC will optimize the code under the assumption that the
function will never be called (i.e. no assembly is emitted), making
failure to ensure this undefined behavior exactly as if the null pointer
had been dereferenced.  However, static analysis will now understand the
programmer's intent and remain silent.  Furthermore, when using the -O0
or -Og levels, GCC won't optimize under this assumption so the exception
will be thrown and might be helpful for debugging.  Compilers that don't
have __builtin_unreachable() won't get any help in determining that the
function must not be called and will have to figure this out by
analyzing the calling code -- which really shouldn't exist in the first
place anyway as the whole point is that these functions must not be
called.
2022-09-29 17:59:28 +02:00
Moritz Klammler
8bb2c63a01 Don't compare iterators from potentially different containers
This patch addresses a static analysis issue reported by Cppcheck 2.9
where an assertion in the toml/region.hpp header would compare two
container's (that are known to be of type std::vector<char>) begin() and
end() iterators in order to verify that they are the same.  This
assertion either passes or invokes undefined behavior.  Which isn't
technically wrong because calling code must always ensure that
preconditions are met and assertions therefore pass anyway but it does
make the value that is added by having the assertion in the first place
marginal.  Fortunately, the assertion was easy to rewrite: Just compare
the container's address itself.  This is well-defined regardless of
whether the assertion will pass or fail.
2022-09-29 17:59:28 +02:00
Moritz Klammler
79c125b54f Initialize data members for defaulted c'tors
This patch addresses a static analysis issue reported by Cppcheck 2.9
where several classes in the toml/datetime.hpp header explicitly default
all their special member functions, including the default constructor,
but don't provide initializers for their data members.  This might or
might not have caused any observable surprising behavior but I agree
with Cppcheck on this one in that an explicitly defaulted default
constructor should be expected to initialize all data members.  So let's
do that.
2022-09-29 17:59:27 +02:00
ToruNiina
b02aaed4fc fix: use fs::path, not fs::path::string() result 2022-09-29 21:28:35 +09:00
ToruNiina
c2af975609 fix: add missing include file and specifiers 2022-09-29 20:14:58 +09:00
Toru Niina
c3a3423fb2 Merge pull request #193 from lukash/replace-fstream
Use C-style IO instead of ifstream for parsing
2022-09-24 00:17:52 +09:00
Lukáš Hrázký
6c2c804eff fix: Improve error handling of ifstream a bit
Set the exceptions mask so that exceptions are thrown when an I/O error
occurs. Also throw the same exception type when the opening fails.
2022-09-08 17:05:15 +02:00
Lukáš Hrázký
021d84623c chore: De-duplicate code for parse(std::filesystem::path) 2022-09-08 17:05:15 +02:00
Lukáš Hrázký
bf9c9d620d feat: Add a parse(FILE *) interface
The fstream classes are notorious for their non-existent error handling.

This adds a C-style fILE * IO (fopen(), etc.) alternative interface, so
that if a user needs reliable error handling, they can use that, albeit
more inconvenient, but more robust approach.
2022-09-08 17:05:11 +02:00
Toru Niina
bbdbae91eb Merge pull request #196 from Jajauma/AvoidCharStaticCasts
Avoid possible lexer truncation warnings
2022-08-17 23:47:10 +09:00
Jajauma's GitHub
72af7b48d3 Avoid possible lexer truncation warnings
Instead of static_cast calls that convert int to char, literals of type
char are now used directly with the value encoded via escape sequence.

The benefits are:
- code without static_cast is much more compact and expresses intent
better
- fixed value truncation warning on some compilers (e.g. C4309 on Visual
Studio 2017)
2022-08-13 10:30:18 +00:00
Toru Niina
c7627ff6a1 Merge pull request #194 from Helaxious/patch-1
Fix a typo ('optinoal' to 'optional')
2022-07-28 21:02:21 +09:00
helaxious
1c3c84e90a fixed a typo ('optinoal' to 'optional') 2022-07-27 17:58:47 -03:00
ToruNiina
1400dd223f fix: #192 quick fix by checking address 2022-07-01 01:09:22 +09:00
Lukáš Hrázký
594accf9a7 chore: Don't include fstream in lexer 2022-06-30 11:37:53 +02:00
ToruNiina
c1378cd3d1 ci: test older gcc/clang on older ubuntu 2022-06-25 01:18:32 +09:00
ToruNiina
728f73ea24 ci: update compilers available on the os 2022-06-24 23:31:52 +09:00
ToruNiina
4212985443 ci: update os used on ci to the current default 2022-06-22 22:06:11 +09:00
ToruNiina
8e95891af1 fix: report an error if a table is inserted to aot 2022-06-22 21:48:37 +09:00
ToruNiina
2a987ac9ea chore: update toml-test to the latest release 2022-06-22 21:28:31 +09:00
ToruNiina
9e1bfcc962 doc: merge contributions from the same person 2022-06-22 21:24:22 +09:00
ToruNiina
4a0df22548 doc: update contributor list 2022-06-14 23:31:58 +09:00
ToruNiina
1ba3be38d0 fix: point the beginning of value in err msg 2022-06-08 01:33:10 +09:00
ToruNiina
5be587bb68 fix #190: Merge branch 'throw-when-overflow' 2022-06-08 01:27:30 +09:00
ToruNiina
d6efdf7d9e test: check if an exception is thrown by overflow 2022-06-08 00:40:28 +09:00
ToruNiina
12d0dbc6f4 fix: throw if number cannot be read losslessly
it throws when strtoll and strtof that are internally called fail
2022-06-08 00:39:04 +09:00
Toru Niina
6d9e533cf1 Merge pull request #189 from muggenhor/fix/avoid-fname-copy
fix: don't force a copy of std::string fname when moving is an option
2022-06-04 20:49:33 +09:00
Giel van Schijndel
aff6f0f574 fix: don't force a copy of std::string fname when moving is an option
Taking this parameter by const reference forces us to copy it (because
we know we're going to store it). Taking it by r-value reference would
suggest that we _might_ take ownership over it and would also force the
user to make a copy if they wish to retain the original value.

Taking this parameter by value however clearly gives us ownership of its
content without forcing a copy if it's implicit conversion from
`const char*` or explicitly handed over to us by the user via std::move.
2022-06-02 14:39:10 +02:00
ToruNiina
25be97dc39 refactor: style update 2022-05-29 00:37:39 +09:00
Toru Niina
846abd9a49 Merge pull request #188 from ken-matsui/support-changing-color-mode-at-runtime
Support changing color mode at runtime
2022-05-27 22:49:56 +09:00
Ken Matsui
9086b1114f Support changing color mode at runtime 2022-05-27 00:01:28 +09:00
ToruNiina
e8f922a1b8 chore: use the latest release of toml-test on CI
The CI task that corresponds to toml-test HEAD is currently failing.
Using the latest stable release is safer.
2022-05-22 15:40:54 +09:00
Toru Niina
fdb228598d Merge pull request #187 from ken-matsui/support-opting-out-of-error-prefix
Support opting out of the default `[error]` prefix
2022-05-22 15:22:01 +09:00
Ken Matsui
c26aa013cd Support opting out of the default [error] prefix 2022-05-22 13:50:45 +09:00
ToruNiina
5924325652 doc: update unreleased TOML features section 2022-03-17 00:07:48 +09:00
ToruNiina
1836ddc129 test: test -DTOML11_USE_UNRELEASED_TOML_FEATURES 2022-03-16 22:46:21 +09:00
ToruNiina
1c82c7a1dc fix: move cmake option to toplevel cmakelists 2022-03-16 22:40:42 +09:00
ToruNiina
dde351ea40 feat: add escape sequence of ESC
as an unreleased feature
2022-03-16 22:39:52 +09:00
ToruNiina
dcfe39a783 chore: update version number 2022-03-13 01:44:29 +09:00
ToruNiina
2f07030d43 doc: update the list of contributors 2022-03-13 01:40:43 +09:00
ToruNiina
97cc0ef62b fix #166: reorder local/gmtime wrapper for MSVC 2022-03-13 00:20:00 +09:00
ToruNiina
0e80cabe65 Merge branch 'check-specialized-conversion' 2022-03-12 19:00:29 +09:00
ToruNiina
cd97dfcec1 Merge branch 'insertion-to-table-defined-by-dotted-key' 2022-03-12 19:00:07 +09:00
ToruNiina
e60442c6db fix: check if re-open dotkey by a table
like:
```
a.b.c = "foo"
[a.b] # this is invalid
d = "bar"
```
2022-03-12 18:22:01 +09:00
Toru Niina
d39fd88a17 Merge pull request #185 from ax3l/topic-installEmbed
CMake: Optional Install if Embedded
2022-03-07 23:12:33 +09:00
Axel Huebl
7fb8b84143 CMake: Optional Install if Embedded
When adding this library as embedded library with private
"target link", e.g., only used inside private source files, the
library does not need to be installed when the main project gets
installed.

This adds an additional option `toml11_INSTALL` similar to the
test-build control switch in order to skip installing headers and
CMake config files if requested.

Avoids using
```cmake
add_subdirectory(path/to/toml11 EXCLUDE_FROM_ALL)
```

which has further side-effects:
https://cmake.org/cmake/help/v3.0/command/add_subdirectory.html
2022-03-03 18:55:55 -08:00
ToruNiina
03259e2003 fix #177: check specific conversion function
when converting toml::value to array-like
2021-12-25 14:08:55 +09:00
ToruNiina
bf2384d8da fix #182: Merge branch 'workaround-msvc-cplusplus-macro' 2021-12-18 15:41:43 +09:00
ToruNiina
8ebf9c984b ci: check if it works w/o /Zc:__cplusplus 2021-12-18 14:23:58 +09:00
ToruNiina
7354e91924 fix: Allow MSVC to have old version 2021-12-18 00:36:20 +09:00
ToruNiina
4522070391 ci: check if MSVC 14 2015 (19.0.24241.7) (1900)
passes ci build if we skip _MSVC_LANG
2021-12-18 00:21:55 +09:00
ToruNiina
02fd8a577b feat: workaround __cplusplus problem on MSVC 2021-12-17 22:29:57 +09:00
ToruNiina
40777070ad fix: disallow dotkey and inline table migration 2021-12-16 22:16:24 +09:00
ToruNiina
cc1cc27613 fix: disallow merging dotted key and inline table
current code mistakenly allows the following TOML file.
```toml
a.b = 42       # table "a" is defined here, implicitly
a = {c = 3.14} # table "a" is overwritten here
```
But we need to allow the following (structually similar) TOML file.
```toml
a.b = 42   # table "a" is defined here, implicitly
a.c = 3.14 # table "a" is merged with {c = 3.14}
```
To distinguish those, we check whether the current table is defined as
an inline table or via dotted key. If the table we are inserting is
defined via dotted key, we accept it and merge the table. If the table
being inserted is defined as an inline table, then we report an error.
2021-12-16 01:11:47 +09:00
ToruNiina
75e297eb47 fix: Merge branch 'check-datetime'
Briefly check if a given date and time is valid
2021-12-15 22:35:56 +09:00
ToruNiina
0d0605e290 fix #181: Merge branch 'no-null-char' 2021-12-15 22:35:31 +09:00
ToruNiina
23f6c931e5 test: add valid/invalid datetime cases 2021-12-15 00:51:07 +09:00
ToruNiina
518e6d4ae2 feat: check date and time are valid or not 2021-12-15 00:31:41 +09:00
ToruNiina
db2aa55d20 fix: disallow null char at the end of input
since std::string and ""_toml literal actually does not include null
char, we don't need to check if the last char is null or not
2021-12-14 22:33:58 +09:00
ToruNiina
1b5107e5e3 fix #180: Merge branch 'linefeed-at-eof' 2021-12-11 23:13:42 +09:00
ToruNiina
2152c85cd1 test: add test_file_ends_without_lf 2021-12-10 23:46:47 +09:00
ToruNiina
2e4c7fb95e fix: line-feed is not required at the EOF 2021-12-10 23:39:54 +09:00
ToruNiina
2ddcfb4b61 doc: update constributors in README 2021-12-08 21:50:09 +09:00
Toru Niina
3f233d57be Merge pull request #178 from marascio/lrm-resolve-173-free-nonheap-object
Resolve g++ warning: free-nonheap-object
2021-12-05 19:46:38 +09:00
Louis R. Marascio
21732fce45 Resolve g++ warning: free-nonheap-object
As described in issue #173, this warning is raised on various platforms
and in various build types. For example, g++ 11 in release mode will
cause this warning to be raised. This change fixes this warning.
2021-12-01 14:43:43 -06:00
Toru Niina
1dc09d0332 Merge pull request #176 from GMLC-TDC/fix_warnings
Fix warnings
2021-11-25 00:13:36 +09:00
Philip Top
9c1708c988 Update toml/traits.hpp
Co-authored-by: Toru Niina <niina.toru.68u@gmail.com>
2021-11-24 06:40:09 -08:00
Philip Top
84f61f7dc8 match the cmake condition to upstream 2021-11-23 16:16:16 -08:00
Philip Top
eef7106fbe fix more warnings 2021-11-19 10:22:37 -08:00
Philip Top
a919190490 tweak the cmake a little 2021-11-19 08:47:18 -08:00
Philip Top
7f98740c9c update from changes in cmake standard 2021-11-19 08:43:04 -08:00
Philip Top
e08c579e36 fix a change in the key_value name from upstream merge 2021-11-19 08:43:03 -08:00
Philip Top
6dd44dc672 fix project issue with cmake 2021-11-19 08:41:24 -08:00
Philip Top
99e483c447 [ci skip] use a policy in the CMakeLists.txt for toml11 fix some more string_view errors 2021-11-19 08:41:00 -08:00
Philip Top
26a066ad07 skip ci
ci skip

update another string_view issue
2021-11-19 08:39:00 -08:00
Philip Top
acad8b1a61 add additional check for invocability 2021-11-19 08:37:02 -08:00
Philip Top
605cd8ef4a fix shadow and some undef warnings 2021-11-19 08:37:01 -08:00
ToruNiina
bcee9f25a2 fix: check if subtable key conflicts 2021-10-10 20:58:28 +09:00
Toru Niina
f2f2b44d87 Merge pull request #172 from estshorter/fix_readme
fix a compile error in a code example
2021-10-10 14:44:00 +09:00
estshorter
e40dfc28eb fix a compile error in a code example 2021-10-10 14:07:34 +09:00
Toru Niina
24284c70ee Merge pull request #171 from estshorter/issue_170
fix a compile warning C26478
2021-10-10 13:29:37 +09:00
estshorter
dced71224d fix a compile warning C26478 2021-10-09 11:12:58 +09:00
Toru Niina
177c09f43d Merge pull request #169 from ohdarling/fix_force_inline
fix: serializer has wrong constructor params order when format root object
2021-09-24 00:29:14 +09:00
ohdarling
e434c96b7f fix: serializer has wrong constructor params order when format root object 2021-09-22 11:38:42 +08:00
Toru Niina
fda0a2b9ab Merge pull request #167 from karl-nilsson/spelling
Spelling fixes
2021-08-30 01:01:27 +09:00
Karl Nilsson
3eee515ce1 Spelling fixes 2021-08-27 19:52:45 -04:00
ToruNiina
ca9e36a484 fix: avoid duplicated-branches in result
when both two types are trivially destructible, both branches of cleanup
function results in the same code...
2021-07-01 00:46:56 +09:00
ToruNiina
0858fbfced fix: avoid max macro expansion on Windows
in numeric_limits<T>::max
2021-06-30 01:43:27 +09:00
ToruNiina
fe240e1ffc ci: trying to run toml_test 2021-06-30 01:28:53 +09:00
ToruNiina
d9959fcdeb ci: trying to make go get work 2021-06-30 01:18:52 +09:00
ToruNiina
1d0b003312 ci: add a patch to avoid nan comparison 2021-06-30 01:18:42 +09:00
ToruNiina
0aa3773860 feat: add bare minimum utf8 seq validity check 2021-06-30 00:58:50 +09:00
ToruNiina
9745c0005f ci: fix setup of toml-test 2021-06-27 18:58:44 +09:00
ToruNiina
4adf36d9fd test: update typename in json for toml-test 2021-06-27 18:58:10 +09:00
ToruNiina
c72b27bb4b fix: escape control characters in a string 2021-06-27 18:57:20 +09:00
ToruNiina
be5ffaf662 feat: check if width == max before using ml-string 2021-06-27 18:56:57 +09:00
ToruNiina
47a2a3332b fix: use empty quoted string for empty key 2021-06-27 18:56:33 +09:00
ToruNiina
9d28afa012 fix: fix serialization of inf/nan 2021-06-27 18:56:05 +09:00
ToruNiina
f09bd5b035 feat: easy check for datetime 2021-06-27 18:54:55 +09:00
ToruNiina
0dc51f95d9 fix: disallow trailing comma in an inline table 2021-06-27 18:54:28 +09:00
ToruNiina
cf9e86a84f fix: disallow control characters
in basic/literal string and comment
2021-06-27 18:53:48 +09:00
ToruNiina
5190e5148b ci: update go version to 1.16 2021-06-27 16:32:49 +09:00
ToruNiina
45bd566f7a fix: serialization of array containing a table
table in a (hetero-) array should be force-inlined
2021-06-27 16:28:41 +09:00
ToruNiina
2c72329530 ci: remove needless flag and allow hetero array
the example of hetero array (that was not allowed in v0.5.0 but allowed
in v1.0.0-rc1) has been moved from invalid/ to valid/
2021-06-27 16:12:01 +09:00
ToruNiina
1b7ca8566b fix: out_of_range with malformed toml file #164 2021-06-27 15:58:40 +09:00
ToruNiina
647381020e chore: update version number 2021-05-27 10:14:29 +09:00
ToruNiina
f04cf596eb doc: update README 2021-05-26 23:16:03 +09:00
Toru Niina
c281539b26 Merge pull request #161 from cubiest/bugfix/empty_files_missing_filename_in_error
Preserve empty location for empty files
2021-05-26 12:28:38 +09:00
Oliver Kahrmann
58542d36be Preserve empty location for empty files
Without a region, error messages in exceptions are unable to print
a filename.

By retaining the location in a zero-length region and detecting this
when formatting the exception text it is possible to print the filename
and explicitly state that the file is completely empty.

Fixes #160
2021-05-25 20:52:33 +02:00
ToruNiina
c38079f7c0 fix: remove needless include file
that might cause compilation error
2021-05-25 21:40:41 +09:00
ToruNiina
0c4594f59a doc: add TOML11_PRESERVE_COMMENTS_BY_DEFAULT 2021-05-15 21:53:13 +09:00
ToruNiina
e73c98490b doc: add recursive find_or to README 2021-05-15 21:47:03 +09:00
ToruNiina
7b9a1abdb3 feat: add test_find_or_recursive 2021-05-15 20:51:43 +09:00
ToruNiina
891f68eab0 feat: support all &/const&/&& variants 2021-05-15 20:41:11 +09:00
ToruNiina
4b1df61142 Merge branch 'master' into recursive-find-or 2021-05-15 20:01:30 +09:00
ToruNiina
392a260db8 doc: write about precedence 2021-05-15 00:24:51 +09:00
ToruNiina
7339ce39d5 fix: #159 Merge branch 'conversion-precedence' 2021-05-14 20:10:03 +09:00
ToruNiina
287be5a575 ci: clang11 is too new to install it
without adding a new ppa
2021-05-14 18:25:29 +09:00
ToruNiina
798856946f ci: add new compilers
gcc 10, 11, clang 11
2021-05-14 18:19:44 +09:00
ToruNiina
07c1d10212 ci: avoid clang-9 + C++20 because it lacks <=>
And the operator<=> is used in the (GNU-) standard library
implementation installed by default.
Note: consider using libc++ library
2021-05-14 16:16:23 +09:00
ToruNiina
0ac3919e08 feat: from<T> and from_toml precede constructor
constructor sometimes has `template<T> ctor(const T&)` and it causes
ambiguity. To avoid it, from<T> and T.from_toml precedes any
constructor. But, to check the ambiguity between from<T> and from_toml,
they do not precede each other. If anyone define both from<T> and
from_toml, it causes compilation error.
2021-05-14 16:05:54 +09:00
ToruNiina
e622595426 fix: fix has_specialized_from/into
to avoid ambiguity
2021-05-14 16:01:43 +09:00
ToruNiina
72ee8caf09 refactor: use has_specialized_from<T>
to check if toml::from<T> exists for a specific T
2021-05-14 15:53:34 +09:00
ToruNiina
b6e2c6e235 feat: add detail::has_specialization_from/into 2021-05-14 15:46:00 +09:00
ToruNiina
c5a22b9d88 fix: #158 Merge branch 'gcc-wshadow'
The -Wshadow warning is avoided from the source code level
2021-05-11 00:08:32 +09:00
ToruNiina
7e90282175 fix: add region where -Wshadow is ignored on GCC 4 2021-05-10 23:00:30 +09:00
ToruNiina
b8291af42b fix: rename func args to avoid -Wshadow in GCC 4.x 2021-05-10 22:56:16 +09:00
ToruNiina
cd60045014 fix: gcc 7 introduces wshadow variants 2021-05-10 21:51:51 +09:00
ToruNiina
db0d9a024b test: add -Wshadow while compiling tests 2021-05-10 20:49:41 +09:00
ToruNiina
4acc563b28 feat: explicitly avoid -Wshadow=global in GCC 2021-05-10 20:49:20 +09:00
ToruNiina
dce50142e6 fix: avoid argname key to supress warning
about shadowing
2021-05-10 20:47:08 +09:00
ToruNiina
06e8b853ba test: add Wshadow=local 2021-05-04 17:50:14 +09:00
ToruNiina
e3092335aa Merge branch 'enable-to-change-default-comment-handling' 2021-04-30 20:28:38 +09:00
ToruNiina
31b9b79312 ci: suppress clang-8 / c++20 because of gcc header 2021-04-28 15:12:04 +09:00
ToruNiina
beb665ba58 test: explicitly specify if comments are preserved 2021-04-27 13:19:55 +09:00
ToruNiina
b51ef5e869 test: explicitly specify the comment preservation 2021-04-27 13:18:39 +09:00
ToruNiina
21ea4a348d test: explicitly specify template arguments
toml::value is an alias of default parameters, so we need to avoid
conflict of definitions between default and non-default parameters
2021-04-27 13:12:37 +09:00
ToruNiina
c4a803df50 test: add comment/no-comment cases to parse_array
When we add a macro to change the default comment preservation scheme,
some of the current tests that assume comments are discarded by defualt
fails. To make it more robust, we need to explicitly specify the comment
preservation scheme and add test cases for both of discard_ and
preserve_comments.
2021-04-27 13:05:03 +09:00
ToruNiina
c40e0dbd37 feat: use comment macro everywhere 2021-04-16 15:29:24 +09:00
ToruNiina
d90c26f9ac feat: add TOML11_PRESERVE_COMMENTS_BY_DEFAULT 2021-04-16 15:28:58 +09:00
ToruNiina
b592ddcca2 fix: add SFINAE to avoid incorrect matching 2021-04-14 13:09:51 +09:00
ToruNiina
5518b2b155 refactor: simplify last_one_in_pack meta func 2021-04-14 13:09:25 +09:00
ToruNiina
ba3d41d913 feat(#156): add find_or(value, keys..., opt) 2021-04-14 11:22:19 +09:00
ToruNiina
8bc09d552a fix(#139): Merge branch 'auto-conversion-macro' 2021-04-02 19:29:04 +09:00
ToruNiina
03c846dc9d doc: add conversion macro to README 2021-04-02 19:28:45 +09:00
ToruNiina
e658a0126c test: disable macro testing if the macro is diabled 2021-04-02 18:26:24 +09:00
ToruNiina
6e3967e26e ci: check compiler version detected by cmake 2021-04-02 18:24:17 +09:00
ToruNiina
db1f42b5da fix: enable to control macro definition 2021-04-02 17:21:25 +09:00
ToruNiina
c7d6d793cb ci: install compiler 2021-04-02 17:00:00 +09:00
ToruNiina
14c6430dda Merge branch 'master' into auto-conversion-macro 2021-04-02 16:25:41 +09:00
ToruNiina
b4bc704e6e fix: trying to workaround MSVC preprocessor 2021-04-02 15:39:23 +09:00
ToruNiina
3f6e873aba fix: merge branch 'uneven-spacing-between-tables' 2021-03-31 11:53:54 +09:00
ToruNiina
a3b8dd6787 fix(#152): add newline btw kv-pair and subtables 2021-03-31 10:52:18 +09:00
ToruNiina
c121492071 fix: uneven spacing between tables
related: issue #152
2021-03-29 17:48:03 +09:00
ToruNiina
5e3f8f9105 chore: update version values 2021-03-25 22:43:37 +09:00
ToruNiina
17a15d3c18 doc: update contributor list and link in README 2021-03-25 22:33:05 +09:00
ToruNiina
42cc111b05 ci: activate linux/windows
confirmed that macos works.
2021-03-25 15:01:40 +09:00
ToruNiina
5e0ee32854 ci: trying to add macos to github actions [skip travis] [skip appveyor]
it is already listed in travis CI, but not in the GH actions
2021-03-25 14:53:28 +09:00
ToruNiina
2c5cc431fe ci: re-activate linux CI 2021-03-25 14:33:55 +09:00
ToruNiina
970f7cb36a ci: trying to update boost installation settings [skip travis] [skip appveyor] 2021-03-25 14:03:26 +09:00
ToruNiina
b924e70e3c feat: add a simple way to disable <filesystem>
As jwillikers pointed out in #150, there is a case where compiler
defines the corresponding feature test macro of <filesystem> but is
actually not available. The macro is a way to disable the feature
regardless of the status of feature test macro.
2021-03-25 11:44:11 +09:00
Toru Niina
7782258e68 Merge pull request #148 from sneakypete81/patch-1
Fix typo in error message
2021-01-31 14:26:02 +09:00
sneakypete81
08859c36d0 Fix typo in error message 2021-01-30 20:04:00 +00:00
ToruNiina
d3de136562 doc: simplity example code a bit 2021-01-25 17:25:29 +09:00
ToruNiina
43183e2ad1 Merge branch 'master' of github.com:ToruNiina/toml11 2020-12-29 18:54:58 +09:00
ToruNiina
e9144b41fb test: returning toml::value directly from into<T> 2020-12-29 18:53:10 +09:00
ToruNiina
2fb8793f1a doc: add document about basic_value and toml::into
related to #146.
2020-12-29 18:52:07 +09:00
Toru Niina
6c8a53915a Merge pull request #144 from amerry/sstream-include-fix
Add missing standard includes
2020-12-10 01:53:31 +09:00
Alex Merry
db2d33ca4b Add missing header for std::out_of_range exception
Failure seen on GCC 4.8.5 when including "toml/value.hpp".
2020-12-09 10:39:10 +00:00
Alex Merry
935da51769 Add missing include for ostringstream
Since region.hpp no longer includes <iostream> (but only <iomanip>),
source_location.hpp no longer includes a header that provides
std::ostringstream. Including <sstream> fixes this.
2020-12-09 10:19:07 +00:00
ToruNiina
be0d4bd0a9 fix: fix #141; Merge branch 'issue-141' 2020-11-05 00:01:41 +09:00
ToruNiina
9b472a6c72 fix: check it is empty before calling back 2020-11-04 23:24:59 +09:00
ToruNiina
1ead14589e fix: check if it is empty before calling back() 2020-11-04 23:24:02 +09:00
ToruNiina
b13065b1b5 fix: #142 Merge branch 'issue-142' 2020-11-03 21:05:03 +09:00
ToruNiina
a6581ee66b fix: an empty array is not an array of table 2020-11-03 20:34:01 +09:00
ToruNiina
0dafa7ee42 test: add case where a table should be inlined
array-of-table implicitly defines an array. If the array itself has a
comment, we need to format it explicitly.
2020-10-18 20:45:12 +09:00
ToruNiina
908b91079b fix: distinguish the comments and try to keep it
If a value has a comment, we need to try to write it explicitly.
2020-10-18 20:43:33 +09:00
ToruNiina
fce6ff317e refactor: distinguish the reason of failure 2020-10-18 18:36:05 +09:00
ToruNiina
fd50b11523 refactor: add write_comments() 2020-10-18 18:35:56 +09:00
ToruNiina
9090b8273c refactor: move array-of-table stuff to a function 2020-10-18 17:20:06 +09:00
ToruNiina
bfae1ab86c test: add test for auto-generated conversion 2020-10-16 21:40:54 +09:00
ToruNiina
88882b523f feat: add a macro defines convertion automatically 2020-10-16 21:40:47 +09:00
ToruNiina
382e3dc3ab refactor: use serializer::is_array_of_tables 2020-10-14 22:27:29 +09:00
ToruNiina
f7bfcdd7aa fix: check all the elements in an array
while checking if the array is array-of-tables or not (heterogeneous
arrays are allowed, so there might be an array that has a table and
an integer at the same time)
2020-10-14 18:00:04 +09:00
ToruNiina
2e41a26785 Merge branch 'master' of github.com:ToruNiina/toml11 into master 2020-10-14 15:35:18 +09:00
ToruNiina
f3378f0ac1 fix: #131 distinguish implicitly declared array 2020-10-14 15:32:08 +09:00
ToruNiina
12ee73d6a9 ci: suppress some of the combinations in CI
clang-7 with C++20 fails with the same reason, 'undefined reference to
std::allocator<char>::(de)allocate'.
2020-10-14 00:38:46 +09:00
ToruNiina
503baf52ed ci: suppress clang 6 + cxx20
Since the main branch that passed the same check 9 days ago also fails
with clang-6 and C++20 because of the same error, "undefined reference
to allocator_traits<char>::allocate". It could be a change in upstream
and since others (e.g. gcc) works well, I suppress the setting at this
moment.
2020-10-14 00:05:55 +09:00
ToruNiina
2deb75052c ci: use the same version of clang
I don't think it resolves the problem, undefined reference to
'std::allocator<char>::deallocate(char*, unsigned long)', though
2020-10-13 23:37:52 +09:00
ToruNiina
290dca3d67 test: add test for comment duplication 2020-10-13 22:04:28 +09:00
ToruNiina
f283a257d2 Revert "quick temporary patch for comment dup"
This reverts commit a6d38c1ec0.
Since the problem is solved, we don't need this patch any more.
2020-10-13 22:02:32 +09:00
ToruNiina
3d86f3a4e1 fix: avoid comment duplication in array of tables 2020-10-13 21:59:46 +09:00
ToruNiina
dc5a8069a9 refactor: require comments while construction
Note: at this commit, the code would not compile.
2020-10-13 21:58:08 +09:00
Toru Niina
4f31b90665 Merge pull request #136 from chronoxor/master
Fixed: Compile toml11 with MinGW cause error in <filesystem> #135
2020-10-04 18:53:34 +09:00
Ivan Shynkarenka
5d8c573357 Fixed: Compile toml11 with MinGW cause error in <filesystem> #136 2020-10-03 23:16:58 +03:00
Ivan Shynkarenka
6e1e5ccd84 Fixed: Compile toml11 with MinGW cause error in <filesystem> #136 2020-10-03 23:06:47 +03:00
Ivan Shynkarenka
f2d9fd1d1f Fixed: Compile toml11 with MinGW cause error in <filesystem> #136 2020-10-03 22:36:59 +03:00
Ivan Shynkarenka
97c8cbdaf5 Fixed: Compile toml11 with MinGW cause error in <filesystem> #135 2020-10-02 19:10:04 +03:00
ToruNiina
05ceb5ae79 fix: workaround for error around SFINAE in MSVC
avoid lambda with template argument
2020-09-29 02:26:16 +09:00
ToruNiina
96cfdb260a fix: update version in macro and cmake 2020-09-29 01:41:38 +09:00
ToruNiina
0fec125688 feat: remove default value from internal src 2020-09-29 01:40:49 +09:00
ToruNiina
a6d38c1ec0 fix: add a quick temporary patch for comment dup
first aid for #131
2020-09-22 17:36:24 +09:00
ToruNiina
c037913b2c doc: update link to the TOML spec 2020-09-20 19:24:48 +09:00
ToruNiina
6a328fe890 doc: recommend to set /Zc:__cplusplus 2020-09-20 18:07:58 +09:00
ToruNiina
7c18cbb1d9 doc: update section "contributors" 2020-09-19 20:35:37 +09:00
ToruNiina
ba7d49f452 test: use normal string literal
as a workaround for older version of gcc
2020-09-19 19:08:20 +09:00
ToruNiina
b0784ce286 test: in case of comment-before-comma 2020-09-19 18:24:23 +09:00
ToruNiina
670186fac7 Merge branch 'master' into allow-comment-before-comma 2020-09-19 18:10:45 +09:00
ToruNiina
5005998709 Merge branch 'master' into cpp20-mode-u8literal-workaround 2020-09-19 13:42:12 +09:00
ToruNiina
84fb703e04 ci: add utf-8 option to MSVC 2020-09-19 00:41:05 +09:00
ToruNiina
8c2560761b chore: enable to use __cplusplus on MSVC
related: https://github.com/ToruNiina/toml11/issues/112
2020-09-19 00:40:44 +09:00
ToruNiina
07ea5e52e2 ci: pass REQ_FS_LIB=ON in case of g++-8 & C++20 2020-09-16 22:16:20 +09:00
ToruNiina
d2b1e962c9 ci: add std=20 to some compilers on github actions 2020-09-16 21:28:19 +09:00
ToruNiina
528031012d test: add test for u8""_toml literals 2020-09-16 21:25:38 +09:00
ToruNiina
c205c762fe test: remove needless u8s from ascii characters 2020-09-16 21:25:04 +09:00
ToruNiina
a32cd6cb61 feat: enable to use u8""_toml literal in C++20 2020-09-16 21:24:03 +09:00
ToruNiina
38e113d2dc ci: set BUILD_TEST=ON on appveyor 2020-09-15 22:40:24 +09:00
Toru Niina
f15480ae4d Merge pull request #130 from MoAlyousef/master
Make toml11_BUILD_TEST Off by default
2020-09-15 22:28:34 +09:00
MoAlyousef
00bec8ae45 update Running Tests heading 2020-09-14 22:05:15 +03:00
MoAlyousef
d599edd1d4 make testing optional 2020-09-14 20:34:19 +03:00
MoAlyousef
a9534579c6 make testing optional 2020-09-14 20:25:38 +03:00
ToruNiina
c8ff302c94 test: add test for no-eof-newline cases 2020-09-14 16:39:05 +09:00
ToruNiina
003bc16c1b fix: skip the last zero in the file 2020-09-14 16:35:51 +09:00
Toru Niina
9132abc5c4 Merge pull request #127 from kenichiice/fix-include
Fix include path in README
2020-09-07 16:19:29 +09:00
OGAWA KenIchi
99d565bcc4 doc: fix include path
* see #72
2020-09-07 15:32:28 +09:00
ToruNiina
5f38127692 feat: allow comments before comma
replace ws by ws_comment_newline, as suggested.
discussed here: toml-lang/toml/issues/766
2020-08-16 11:03:58 +09:00
ToruNiina
3c3ebd88b4 feat: improve error message about invalid keys 2020-08-09 18:38:50 +09:00
ToruNiina
08f7ea9c56 refactor: remove extraneous whitespaces in errmsg 2020-08-09 18:38:21 +09:00
ToruNiina
cde29399f4 fix: use 1 in source_location as the default pos 2020-08-07 22:24:01 +09:00
ToruNiina
eec429e31b ci: add REQUIRE_FILESYSTEM_LIBRARY on CI 2020-08-06 16:35:49 +09:00
ToruNiina
79ddcaece6 chore: add CMake option to link with (std)c++fs 2020-08-06 16:29:24 +09:00
ToruNiina
8398b9a08b test: use array for char*
forgot to delete
2020-08-05 20:43:48 +09:00
ToruNiina
9c5abf0bfd test: check each overload compiles 2020-08-05 20:29:07 +09:00
ToruNiina
4fa94d45b3 fix: use const char* instead of &char[N]
to enable to pass char*, not only string literal
2020-08-04 20:08:58 +09:00
ToruNiina
46e84a9cc2 refactor: Merge branch 'refactor-region' 2020-07-31 12:45:52 +09:00
ToruNiina
4e6ae9a994 refactor: avoid string construct in format_ul 2020-07-30 16:11:35 +09:00
ToruNiina
f23c003d2f fix: add missing namespace specifier 2020-07-28 00:04:25 +09:00
ToruNiina
4b719f0806 refactor: use location() instead of get_region 2020-07-27 23:15:14 +09:00
ToruNiina
22ace027de refactor: rm template from detail::change_region 2020-07-27 23:04:24 +09:00
ToruNiina
bc219af5b5 refactor: use location() member instead of ctor 2020-07-27 23:03:33 +09:00
ToruNiina
68e8a31659 refactor: remove needless addressof() call 2020-07-27 23:00:40 +09:00
ToruNiina
32a5341d09 refactor: use source_location, not region_base* 2020-07-27 22:29:18 +09:00
ToruNiina
ce68f6f4c2 refactor: check (always-valid) ptr before deref 2020-07-27 21:32:35 +09:00
ToruNiina
e696aabd11 refactor: change internal interface to reduce code
to remove `std::addressof` calls, get_region(toml::value) now
returns a pointer to region.
2020-07-27 00:48:04 +09:00
ToruNiina
7fb93e2f54 fix: add missing explicit to detail::region 2020-07-27 00:20:26 +09:00
ToruNiina
19cc9a2edf refactor: remove template from detail::region 2020-07-25 22:01:34 +09:00
ToruNiina
72f5afb6af refactor: remove template from detail::location 2020-07-25 21:06:26 +09:00
ToruNiina
a8fa14d159 refactor: remove vec() method, use a constructor 2020-07-21 20:55:18 +09:00
ToruNiina
75999aa9ad refactor: add a constructor to location
By adding the constructor, vec() would not be not needed. But inserting
Container = std::string makes the constructor ambiguous, so it breaks
the current code.
2020-07-21 20:53:44 +09:00
ToruNiina
259da54edb refactor: always use vector<char> in location
`location` and `region` have a (shared_ptr to the) container of TOML
contents. Those take a template argument to allow both std::vector<char>
and std::string as an interanal container. But since those are internal
feature, i.e. it should not be used by a user directly, this template
can be removed by re-writing a parser a bit. This introduces a
complexity to toml11 error reporting system, so I'm removing this.
First, remove all the location<std::string> from the parser. Then the
template argument can be removed because everyone uses std::vector<char>
now.
2020-07-20 19:52:11 +09:00
ToruNiina
b461f363da refactor: add a method to reduce complexity later 2020-07-20 19:40:55 +09:00
ToruNiina
d43139a471 doc: update Contributors section 2020-07-19 19:50:02 +09:00
ToruNiina
a344668fa2 doc: update version to 3.5.0 2020-07-19 19:12:18 +09:00
ToruNiina
25aa97a435 doc: add actions status badge to README 2020-07-19 19:09:47 +09:00
ToruNiina
af70d3dfed ci [skip ci]: add github actions workflow file 2020-07-19 17:13:39 +09:00
ToruNiina
8b5cfb4105 test: add missing binary flag to ifstream 2020-07-19 16:57:20 +09:00
ToruNiina
4e0624aa60 feat: make sure the last null is removed 2020-07-19 16:56:31 +09:00
ToruNiina
3ac2c065eb Merge branch 'reorder-headers' to master 2020-07-17 15:17:40 +09:00
ToruNiina
470f81dc94 fix: #123 merge branch 'windows-nominmax' 2020-07-10 20:55:53 +09:00
ToruNiina
93a9f2711c test: add windows.h test 2020-07-10 18:32:59 +09:00
ToruNiina
761e576991 fix: workaround for windows.h that defines min/max
related to #123
2020-07-10 15:07:13 +09:00
ToruNiina
e6e84714c5 Merge branch 'master' into reorder-headers 2020-07-10 00:06:22 +09:00
Toru Niina
1efc99e11c Merge pull request #121 from SeverinLeonhardt/fix_msvc_c4866
Fix MSVC warning C4866
2020-07-03 21:37:22 +09:00
Marius Maaß
92aa42a58e Fix MSVC warning C4866
This fixes the warning "compiler may not enforce left-to-right
evaluation order for call to" that is caused by Visual Studio if this is
compiled with a target of C++17.
2020-07-03 08:00:47 +02:00
ToruNiina
b1c9df8998 feat: reorder headers following google c++ style
related to: #115
2020-06-28 00:58:20 +09:00
ToruNiina
9633e5fe5a doc: add iteration examples into as_xxx section
related to #120
2020-06-21 14:11:26 +09:00
ToruNiina
2164fd39f7 doc: explain about the type of the top-level value
fix #120.
2020-06-21 14:04:20 +09:00
ToruNiina
c22a3fd227 feat: support parse(std::filesystem::path) #113 2020-06-07 15:11:48 +09:00
ToruNiina
57c6652360 Merge branch 'master' into std-filesystem 2020-06-06 17:25:26 +09:00
ToruNiina
defde33544 fix: avoid ambiguity in overload resolution
Since both `std::string` and `std::filesystem::path` can be convertible
from `const char &[N]` (like, `parse("file.toml")`), after adding
`parse(std::filesystem::path)`, the overload resolution of
`parse("file.toml")` becomes ambiguous. By adding `parse(...)` that
exactly matches to `parse("file.toml")`, we can remove this ambiguity.
2020-06-06 17:18:02 +09:00
ToruNiina
46ed051740 fix: pass path.string as a filename 2020-06-05 23:15:19 +09:00
ToruNiina
2963d9a25b feat: add std::filesystem::path support 2020-06-05 19:43:23 +09:00
Toru Niina
531f335417 Merge pull request #119 from halfelf/fix/readme_finding_value_in_table
fix: "Finding a value in an array" example in README
2020-05-20 00:27:33 +09:00
Shu Wang
f29f42277e fix: "Finding a value in an array" example in README 2020-05-18 13:53:48 +08:00
Toru Niina
b03cde566a Merge pull request #117 from usefulcat/master
when parsing a local_time, parse up to 9 digits worth (nanoseconds) o…
2020-05-11 13:36:23 +09:00
Scott McCaskill
57d4e196a3 when parsing a local_time, parse up to 9 digits worth (nanoseconds) of fractional seconds 2020-05-10 16:06:52 -05:00
ToruNiina
deb3ab6617 ci: add DISALLOW_HETEROGENEOUS_ARRAYS 2020-04-03 23:57:52 +09:00
ToruNiina
bf992e8f94 doc: update README for v1-rc1 2020-04-03 23:45:45 +09:00
ToruNiina
7c07f4382c ci: add DISALLOW_HETEROGENEOUS_ARRAYS to toml-test 2020-04-03 23:43:59 +09:00
ToruNiina
125f608fa5 feat: remove TOML11_UNRELEASED_FEATURES.
v1.0.0-rc.1 has been released
2020-04-03 23:42:58 +09:00
ToruNiina
4d0ed847f9 test: remove default ctor from test code 2020-03-30 15:04:51 +09:00
ToruNiina
79594709fe fix: don't use default ctor when converting to map 2020-03-30 15:02:26 +09:00
ToruNiina
55a738c11f Merge branch 'do-not-require-default-ctor-108'
fix #108.
2020-03-28 23:19:52 +09:00
ToruNiina
eebe1f87e6 fix: update cmake version 3.4.0 2020-03-28 17:59:10 +09:00
ToruNiina
95c3b5f538 feat: use push_back instead of resize 2020-03-27 18:06:26 +09:00
ToruNiina
e2790c9e7b test: remove test_resize and add test_try_reserve 2020-03-27 18:06:02 +09:00
ToruNiina
9b52dc0131 feat: remove resize and add try_reserve 2020-03-27 18:05:31 +09:00
ToruNiina
5212992f05 feat: add is_std_forward_list
std::forward_list does not have push_back, insert, or emplace but
push_front, insert_after, and emplace_after. We need to distinguish it
from other continers.
2020-03-27 18:02:37 +09:00
ToruNiina
fcd6e47500 feat: add meta funcs, has_reserve/push_back_method 2020-03-27 18:01:47 +09:00
ToruNiina
31826b55ce feat: avoid double checking in helper methods 2020-03-25 22:49:19 +09:00
ToruNiina
e3fc354e8d Merge branch 'shorten-switch-cast' 2020-03-24 22:43:09 +09:00
ToruNiina
ea87f92358 doc: update exception section in README (fix #107) 2020-03-23 20:57:36 +09:00
ToruNiina
c259456282 ci: fix Travis.CI OS X build 2020-03-22 20:40:02 +09:00
ToruNiina
d7662347f2 refactor: shorten switch_cast definition by macro 2020-03-21 17:44:23 +09:00
ToruNiina
5f5539d402 feat: throw informative error from value.at(...) 2020-03-21 17:09:04 +09:00
ToruNiina
c2151cab0b refactor: show func name in bad_cast from helpers 2020-03-21 17:06:34 +09:00
ToruNiina
653c87592c feat: enable to show function name in bad_cast 2020-03-21 17:04:05 +09:00
ToruNiina
bdf4e75122 refactor: move helper function from get to value 2020-03-21 16:57:12 +09:00
ToruNiina
60d23116ba Merge branch 'master' of github.com:ToruNiina/toml11 2020-03-13 14:38:33 +09:00
ToruNiina
af8cf9ddc5 refactor: remove redundant functions in serializer 2020-03-13 13:55:14 +09:00
ToruNiina
f125cca010 refactor: simplify serializer's template argument 2020-03-12 13:46:17 +09:00
ToruNiina
a20a2c0b80 doc: update README 2020-03-01 00:35:27 +09:00
ToruNiina
9694afbe32 Merge branch 'improve-error-message' 2020-02-29 23:43:23 +09:00
ToruNiina
d11e42ca7e fix: explicitly say the table is top-level
The top-level table has its region at the first character of the file.
That means that, in the case when a key is not found in the top-level
table, the error message points to the first character. If the file has
its first table at the first line, the error message would be like this.
```console
[error] key "a" not found
 --> example.toml
   |
 1 | [table]
   | ^------ in this table
```
It actually points to the top-level table at the first character,
not `[table]`. But it is too confusing. To avoid the confusion, the
error message should explicitly say "key not found in the top-level
table".
2020-02-29 22:56:29 +09:00
ToruNiina
128b66bda9 refactor: add missing whitespace 2020-02-29 22:54:50 +09:00
ToruNiina
d1af42f151 refactor: add throw_key_not_found_error
and replace related throw statements with it
2020-02-29 22:23:15 +09:00
ToruNiina
8acf105b56 doc: update contributor list and test commands 2020-02-27 19:30:34 +09:00
Toru Niina
b86b5364ba Merge pull request #103 from jwillikers/fix_tests
Use FetchContent to retrieve TOML test data
2020-02-27 19:13:02 +09:00
Jordan Williams
bfe57340f4 no longer explicitly clone the TOML repository in CI builds 2020-02-24 08:03:29 -06:00
Jordan Williams
02a6f029ad use ExternalProject to download the toml tests
In order to evaluate the relative paths correctly, add_test should use the current binary directory as the working directory.
2020-02-24 07:59:59 -06:00
Jordan Williams
9017900ff3 set version directly from CMake project command
This silences the warning for CMake policy CMP0048: https://cmake.org/cmake/help/v3.0/policy/CMP0048.html
2020-02-24 07:35:59 -06:00
Jordan Williams
3c5ebd73d7 require CMake version 3.1 2020-02-24 07:31:48 -06:00
Jordan Williams
2223eb4f62 Revert "no longer explicitly clone the TOML repository in CI builds"
This reverts commit fe644ea4b7.
2020-02-24 07:31:15 -06:00
Jordan Williams
a655a71cef Revert "use FetchContent to retrieve TOML test data"
This reverts commit 4c34986db0.
2020-02-24 07:31:06 -06:00
ToruNiina
c34001725c Merge branch 'workaround-gcc-48x' 2020-02-20 11:59:49 +09:00
ToruNiina
5e3ffb70dd fix: check clang macro when checking gcc is used 2020-02-19 17:00:22 +09:00
ToruNiina
2265ca41c6 ci: test with gcc 4.8 and 4.9 on CI 2020-02-19 15:47:34 +09:00
ToruNiina
82fec38e37 refactor: simplify internally-used function 2020-02-19 15:46:25 +09:00
ToruNiina
189b910384 fix: solve #97 in the naivest way, macros 2020-02-19 15:44:38 +09:00
Jordan Williams
fe644ea4b7 no longer explicitly clone the TOML repository in CI builds 2020-02-18 20:21:02 -06:00
Jordan Williams
4c34986db0 use FetchContent to retrieve TOML test data 2020-02-18 19:37:28 -06:00
ToruNiina
ac1130f9f4 tag: update patch version v3.3.1 2020-02-16 22:02:40 +09:00
ToruNiina
d290c3b7e5 doc: add contributor to README 2020-02-14 19:25:41 +09:00
Toru Niina
e4140ac1fd Merge pull request #102 from jwillikers/cmake_cache_variables
Set CMake Standard Cache Variables. Fixes #101
2020-02-13 13:22:25 +09:00
Jordan Williams
ef33c10ba8 use cache variables for the CMake standard and extensions settings 2020-02-12 07:44:47 -06:00
Toru Niina
ced710bb4c Merge pull request #100 from jwillikers/clang_warnings
Silence Clang Warnings. Fixes #98 & #99
2020-02-12 13:37:58 +09:00
Jordan Williams
6b5944e839 fix -Wundef warnings 2020-02-11 06:30:18 -06:00
Jordan Williams
76cae8c057 enable -Wundef flag for tests 2020-02-11 06:25:10 -06:00
Jordan Williams
3930a44ccd enable range-loop-analysis flag for tests 2020-02-11 06:17:54 -06:00
Jordan Williams
3b6417de00 fix clang range-loop-analysis warnings 2020-02-11 06:13:55 -06:00
ToruNiina
573a6f1d81 test: use JSON format_key to format a key in JSON
The rule to format a basic string and a key is different. `"""` cannot
be used with JSON keys. Also, toml key is basically not wrapped by `"`.
So we need a function to format a key in JSON.
2020-02-06 01:28:37 +09:00
ToruNiina
f6a41d986c feat: handle quotes in strings in the better way
- if a basic string contains any double quote, make it multiline.
  - because 1 or 2 consecutive "s do not require escape sequence in it.
- if a basic string will be sufficiently long, make it multiline.
- if 3 consecutive "s appeared, insert backslash to break it down.
2020-02-05 22:42:10 +09:00
ToruNiina
16fc172b21 feat: check string length before adding newline
In literal strings, only the first newline will be trimmed.
```toml
str = '''
The first newline will be trimmed.'''
```
The previous code always adds this first-newline, but after this commit
it checks the length of the string and adds newline if the string is
sufficiently long.
2020-02-05 22:39:08 +09:00
ToruNiina
7d03eb489a test: add test cases with quotes in ml-string
some of these example strings are copied from toml-lang/toml:README.md
and some are modified.
2020-02-04 22:37:11 +09:00
ToruNiina
0582e1535b fix: handle edge-cases with quotes in ml-string
See comments in the code for detail.
2020-02-04 22:36:39 +09:00
ToruNiina
d495df93a6 refactor: remove trailing whitespaces 2020-02-04 22:21:37 +09:00
ToruNiina
5ca3a3c262 refactor: change ifdef UNRELEASED_FEATURE region
to eliminate dead code after returning from a function
2020-02-04 21:05:03 +09:00
ToruNiina
aa8d574dfe chore: update minor version 2020-01-24 22:08:12 +09:00
ToruNiina
49fdb61731 refactor: add explicit to ctors of internal types 2020-01-24 15:58:24 +09:00
ToruNiina
b2bb21a473 doc: update year of copyright notice 2020-01-23 22:18:04 +09:00
ToruNiina
0c58549fc6 Merge branch 'master' of github.com:ToruNiina/toml11 2020-01-22 12:20:34 +09:00
ToruNiina
b7b5e847d3 ci: test with C++14, not only 11/17 2020-01-22 12:19:53 +09:00
ToruNiina
22d630fec1 feat: replace detail::stuff by std if possible 2020-01-20 12:18:05 +09:00
ToruNiina
f7bf341452 fix: add missing noexcept specifier 2020-01-19 21:06:10 +09:00
ToruNiina
0934d90f90 refactor: move ctors that are only used internally 2020-01-19 18:30:27 +09:00
ToruNiina
f2c8d0e279 refactor: add missing explicit to toml::exception 2020-01-19 17:51:24 +09:00
ToruNiina
8c7d83d985 Merge branch 'add-value-member-methods' 2020-01-17 20:30:26 +09:00
ToruNiina
5ce44adbdc doc: add description about toml::value memfuns 2020-01-17 20:26:36 +09:00
ToruNiina
5c5b1320d0 test: add test for map/vector methods 2020-01-16 20:58:36 +09:00
ToruNiina
8b737dc21f feat: add member methods to toml::value 2020-01-16 20:58:10 +09:00
ToruNiina
ee654b6c3f chore: add -Werror when building test codes 2020-01-13 11:31:03 +09:00
ToruNiina
c59782d180 fix: remove useless conversions in the test codes 2020-01-13 11:29:17 +09:00
ToruNiina
9bef715ccd fix: use u32 as a result of binary operation 2020-01-13 11:26:53 +09:00
ToruNiina
d2b1cf5123 refactor: just use a constructor
to remove conversions
2020-01-13 11:26:29 +09:00
ToruNiina
9f92916d1d fix: suppress -Wuseless-conversion
`{integer} + 1` will automatically be an int, so static_cast<int>(a+1)
will be useless conversion.
2020-01-13 11:24:48 +09:00
ToruNiina
666e4cf9dc fix: suppress sign-conversion warnings 2020-01-13 00:46:21 +09:00
ToruNiina
cafee29c64 test: add some combinations of types in toml::find 2020-01-13 00:27:39 +09:00
ToruNiina
a7a2272b29 chore: turn more diagnostic flags on 2020-01-13 00:16:33 +09:00
ToruNiina
dc0bca2bb6 fix: update patch version ... 2020-01-12 23:18:03 +09:00
ToruNiina
490abe04fd refactor: remove redundant template argument 2020-01-12 23:07:17 +09:00
ToruNiina
81ed4c0e9d Merge branch 'master' of github.com:ToruNiina/toml11 2020-01-10 21:17:17 +09:00
ToruNiina
1b07baf184 doc: add toml::get specialization using ctor 2020-01-10 20:46:54 +09:00
ToruNiina
9073d52159 test: check get<foo> works with constructor 2020-01-10 20:39:56 +09:00
ToruNiina
55260654bf feat: get user-defined value by constructor
If a user-defined constructor has constructor(const toml::value&),
then it should be convertible in `toml::get` and `toml::find`.
2020-01-10 20:38:52 +09:00
ToruNiina
aa6271af75 doc: update README 2020-01-09 01:40:05 +09:00
ToruNiina
c54a03f189 Merge branch 'master' into find-idx 2020-01-09 00:27:51 +09:00
ToruNiina
c153c0e8c3 ci: test with sanitizers 2020-01-08 23:28:17 +09:00
ToruNiina
1f90af8e67 ci: refactor list of env vars 2020-01-08 23:17:38 +09:00
ToruNiina
a0c5192b74 chore: add option to use sanitizers 2020-01-08 23:07:05 +09:00
ToruNiina
7f020f3f44 refactor: remove error prefix
that will automatically be added in format_underline
2020-01-07 22:27:13 +09:00
ToruNiina
827b433389 Merge branch 'master' into find-idx 2020-01-07 22:13:15 +09:00
ToruNiina
b1827e6fca test: check immutability of inline tables 2019-12-20 19:46:54 +09:00
ToruNiina
18f84088b4 perf: avoid tmp str construction while checking 2019-12-19 22:13:47 +09:00
ToruNiina
c199bd8b49 feat: enable to access the 1st char of region 2019-12-19 22:13:33 +09:00
ToruNiina
5b35c1a74e fix: prohibit modification on inline table
According to toml-lang/toml:36d3091b3 "Clarify that inline tables are
immutable", check if it adds key-value pair to an inline table.
  This is one of the unreleased (after-0.5.0) toml feature. But this is
marked as "Clarify", so TOML-lang intended that inline tables are
immutable in all version.
2019-12-19 22:02:17 +09:00
ToruNiina
d3513c0f84 fix: fmt line num in err msg correctly 2019-12-17 19:35:26 +09:00
ToruNiina
8567f09cbf chore: update version info in CMake 2019-12-13 20:25:52 +09:00
ToruNiina
a6d24b02d5 Merge branch 'colorize-err-msg' 2019-12-13 20:23:27 +09:00
ToruNiina
08bf5ffbdf doc: put screenshot to colorize-error-message 2019-12-13 17:28:43 +09:00
ToruNiina
a945bd6eac ci: pass TOML11_COLORIZE_ERROR_MESSAGE on CircleCI 2019-12-13 16:47:33 +09:00
ToruNiina
f4ac286b0f doc: add description about format_error 2019-12-12 21:31:21 +09:00
ToruNiina
f31dc6ba37 doc: add example of hints in an error message 2019-12-12 18:09:13 +09:00
ToruNiina
fecd50dfeb doc: add contributors 2019-12-12 18:02:16 +09:00
ToruNiina
d48d454a61 doc: modify README a bit 2019-12-12 17:55:20 +09:00
ToruNiina
4688c235f5 refactor: rename internal macro value 2019-12-12 17:38:29 +09:00
ToruNiina
5c146857a3 Merge branch 'master' into colorize-err-msg 2019-12-11 22:49:38 +09:00
ToruNiina
bc51699415 Merge branch 'bracket-operator' 2019-12-11 19:36:21 +09:00
Toru Niina
8b923d56e9 Merge pull request #96 from kenichiice/icpc_warning2
Suppress warning on Intel C++ Compiler
2019-12-11 18:30:44 +09:00
OGAWA KenIchi
3190c1da9f fix: suppress warning on Intel C++ Compiler 2019-12-11 17:47:16 +09:00
ToruNiina
a41dc08025 doc: add document of operator[] 2019-12-10 20:06:01 +09:00
ToruNiina
0c084b3a5c test: add test: accessing via bracket operator 2019-12-10 00:08:40 +09:00
ToruNiina
8fbeaabfd9 feat: add operator[] to access table/array 2019-12-10 00:00:05 +09:00
ToruNiina
331de4ea5d fix: use datetime info while getting time offset
to convert offset_datetime to system_clock::time_point.
2019-12-08 22:44:12 +11:00
ToruNiina
b246f5ac5c fix: combine date and time to convert loc datetime
Normally DST begins at A.M. 3 or 4. If we re-use conversion operator
of local_date and local_time independently, the conversion fails if
it is the day when DST begins or ends. Since local_date considers the
time is 00:00 A.M. and local_time does not consider DST because it
does not have any date information. We need to consider both date and
time information at the same time to convert it correctly.
2019-12-08 22:38:49 +11:00
ToruNiina
89714fb24b doc: note about local timezone and datetime 2019-12-06 21:15:31 +09:00
ToruNiina
62c01f9826 fix: consider timezone correctly
explicitly set tm.tm_isdst = 0 and use UTC offset
2019-12-06 20:57:51 +09:00
ToruNiina
5a8d368927 feat: add thread-safe detail::gmtime_s 2019-12-06 20:33:15 +09:00
ToruNiina
28519f5712 doc: add colorize section to README 2019-12-02 17:08:00 +09:00
Toru Niina
63fdbd25cf Merge pull request #95 from blockparty-sh/unused-variable-warning
Suppress unused variable warning
2019-11-23 12:59:21 +09:00
blockparty
6d41a1adb9 Suppress unused variable warning 2019-11-22 05:59:55 -06:00
Toru Niina
26a09b2f65 Merge pull request #93 from blockparty-sh/fix_compile_error
Check if features are defined
2019-11-21 21:57:26 +09:00
blockparty
7e62dad6dc Check if features are defined 2019-11-21 05:51:31 -06:00
ToruNiina
2fd466a3c3 fix: skip only the prefix, keep spaces 2019-11-14 15:32:17 +09:00
ToruNiina
6f7539dc6a fix: deduplicate [error] prefix in the messages 2019-11-14 15:31:27 +09:00
ToruNiina
f290390c63 fix: consider the no-space cases like [error]: 2019-11-13 18:14:42 +09:00
ToruNiina
571baa2c26 refactor: remove nocolor:: operations
since color can be on-off at runtime
2019-11-13 18:08:31 +09:00
ToruNiina
bbe33e87d9 feat: detect [error] prefix duplication 2019-11-13 18:05:37 +09:00
ToruNiina
4c5076f263 feat: add runtime colorize flag 2019-11-13 18:01:47 +09:00
ToruNiina
d47174954f feat: colorize user-defined msg by format_error 2019-11-13 18:00:55 +09:00
ToruNiina
821eb9632b feat: add a macro-dependent constant 2019-11-13 17:59:47 +09:00
ToruNiina
af116991b6 fix: remove overlapping [error] sign 2019-11-13 17:35:23 +09:00
ToruNiina
87bebbc37d feat: put color to the internal error messages 2019-11-13 17:35:05 +09:00
ToruNiina
c2d0351e69 feat: add (ANSI) terminal colorize operators 2019-11-13 17:24:51 +09:00
ToruNiina
1526b9feee Merge branch 'heterogeneous-array' 2019-11-09 11:03:18 +09:00
ToruNiina
281206dcc6 doc: add heterogeneous array to README 2019-11-08 19:03:16 +09:00
ToruNiina
adf8fa9234 fix: fix typos in an error message in toml::get
when converting toml::value to std::tuple
2019-11-08 16:12:18 +09:00
ToruNiina
0a66be3257 test: add test for parsing heterogeneous array
this test case is activated only if TOML11_USE_UNRELEASED_TOML_FEATURES
is defined.
2019-11-08 15:52:31 +09:00
ToruNiina
160537360c test: deactivate error check for hetero array
if TOML11_USE_UNRELEASED_TOML_FEATURES is activated.
2019-11-08 15:39:14 +09:00
ToruNiina
9af2d65417 feat: allow heterogenous array
if TOML11_USE_UNRELEASED_TOML_FEATURES is activated.
In TOML v0.5.0, heterogenous arrays are not allowed. But after some
discussions in toml-lang/toml, it is decided to allow it in the next
release (toml-lang/toml/pull/676).
To support it, disable type check in parse_array function.
2019-11-08 15:36:58 +09:00
ToruNiina
429763377f Merge branch 'add-src-loc-to-exception' #87 2019-11-02 13:42:14 +09:00
ToruNiina
c774beb79a doc: write about source_location in exceptions 2019-11-02 13:03:50 +09:00
ToruNiina
8240fffeca Merge branch 'master' into add-src-loc-to-exception 2019-11-02 12:53:16 +09:00
ToruNiina
047611764c fix: silly typo 2019-11-01 21:15:20 +09:00
ToruNiina
bc3eb9d967 feat: add src_loc to all the exceptions
including internal_error.
2019-11-01 21:14:33 +09:00
ToruNiina
6862264bde feat: use the first char as the top-level region
A bit related to #89
2019-11-01 20:47:25 +09:00
ToruNiina
2ee69fc420 fix: improve error messages about strings a bit 2019-11-01 13:34:15 +09:00
ToruNiina
6a15e8360f refactor: remove redundant namespace specifier 2019-10-31 23:13:49 +09:00
ToruNiina
b4c6d26842 Merge origin/add-src-loc-to-exception #87 2019-10-31 23:11:53 +09:00
ToruNiina
41eb1d6887 feat: pass source_location to exception 2019-10-31 22:23:31 +09:00
ToruNiina
3ca712a8da feat: check line_num before converting it to int 2019-10-31 22:21:24 +09:00
ToruNiina
8e589ff4d7 feat: add source_location to (syntax_|type_)error 2019-10-31 22:04:16 +09:00
ToruNiina
56812114c3 refactor: simplify inclusion dependencies 2019-10-31 21:58:28 +09:00
ToruNiina
f98615d0df fix: check file content is empty or not 2019-10-30 16:49:49 +09:00
ToruNiina
37769e28f0 fix #88: check if input is null-terminated or not 2019-10-30 16:33:22 +09:00
ToruNiina
2acdec00aa Merge branch 'refactor-ci' 2019-10-15 23:13:44 +09:00
ToruNiina
354cfc979a ci: cache brew directory 2019-10-15 23:13:11 +09:00
ToruNiina
3dc3b001ff ci: update clang 3.x from 3.7 to 3.9 2019-10-15 23:13:06 +09:00
ToruNiina
ea24a91f4c ci: use sourceline 2019-10-15 20:32:09 +09:00
ToruNiina
5bba73a8ca ci: use addons in OS X on Travis.CI 2019-10-15 20:27:27 +09:00
ToruNiina
54eced6c82 test: add test for toml::string::operator+= 2019-10-09 21:51:33 +09:00
ToruNiina
258e62f8f3 feat: add operator+= to toml::string 2019-10-09 21:51:14 +09:00
ToruNiina
06086a9ff7 doc: add note about value::at 2019-10-09 21:09:38 +09:00
ToruNiina
b4b35ea33e feat: allow 0-prefix exponent if the flag is on
If unreleased feature is activated, zero-prefixes in an exponent part of
a floating point is allowed. If the flag TOML11_UNRELEASED_TOML_FEATURES
is turned on, we don't need to check whether there is a zero prefix in
the exponent part that is formatted by a standard library.
2019-10-08 23:23:53 +09:00
ToruNiina
d7b4d104d3 refactor: reduce checking; just check once 2019-10-08 23:15:03 +09:00
ToruNiina
1148d01c70 Merge branch 'master' into find-idx 2019-10-07 11:11:08 +09:00
ToruNiina
e12fd4d944 doc: add contributors 2019-10-04 14:28:43 +09:00
ToruNiina
36af02cb3a test: add test cases for one-way conversion 2019-10-04 13:01:15 +09:00
ToruNiina
488015df49 fix: toml -> T is required; related to #83 2019-10-04 13:00:34 +09:00
Toru Niina
1f951e49b1 Merge pull request #84 from jcmoyer/master
Update documentation for toml::from and toml::into
2019-10-04 12:58:13 +09:00
J.C. Moyer
6a7dbb7875 Update documentation for toml::from and toml::into 2019-10-03 21:28:06 -04:00
ToruNiina
17d78553ff test: add test cases for find(v, idx)
- check whether find(v, idx) throws
- check find(v, ks...) works with both indices and strings
2019-10-03 15:48:04 +09:00
ToruNiina
4c12dad51f feat: add find<T>(value, idx) for arrays (#79) 2019-10-03 15:27:25 +09:00
ToruNiina
ad7eb56634 fix: avoid potential memory bugs related to move 2019-10-03 14:42:52 +09:00
ToruNiina
b01c5534ed test: add test cases for const-ref version 2019-10-03 13:52:12 +09:00
ToruNiina
22dac3c9f2 Merge branch 'value-at' 2019-09-28 19:40:51 +09:00
ToruNiina
d5adfe8c7d refactor: use as_xxx instead of cast<enum>
because cast<enum>() requires `template` specifier inside a template
function. it makes code long.
2019-09-28 17:01:45 +09:00
ToruNiina
4bb8045c84 doc: add basic_value::at. 2019-09-28 16:31:45 +09:00
ToruNiina
babb6ab3fe test: add test case for basic_value::at 2019-09-28 16:22:01 +09:00
ToruNiina
d73bc6076c feat: add basic_value::at(key) and at(idx) 2019-09-28 16:21:51 +09:00
ToruNiina
8d1da6e8b5 test: add test cases for find_or(&&) + conversion 2019-09-28 14:01:33 +09:00
ToruNiina
8276e12f06 test: add test cases for toml::find_or(value&&) 2019-09-28 13:38:59 +09:00
ToruNiina
f3d3f63ff9 fix: return values from find_or(value&&) 2019-09-28 13:38:26 +09:00
ToruNiina
d9689c878d test: add test cases for toml::find(value&&, key) 2019-09-28 13:05:13 +09:00
ToruNiina
df097cb09a test: add test cases of get_or(value&&, U) 2019-09-28 12:13:59 +09:00
ToruNiina
a425e3b7c6 test: add test cases of toml::get_or(value&&, T&&) 2019-09-28 12:08:14 +09:00
ToruNiina
e4b4503b81 style: add comment to test::operator<< 2019-09-28 12:07:53 +09:00
ToruNiina
b44fbad925 fix: remove needless ::type 2019-09-28 11:14:14 +09:00
ToruNiina
826c9444ac refactor: use remove_cvref 2019-09-28 11:03:46 +09:00
ToruNiina
a1095f3e4c refactor: use std::map::at instead of [] 2019-09-28 11:03:14 +09:00
ToruNiina
483a39beb4 refactor: remove unsupported overload
expect<T>(table, ...)
2019-09-28 11:00:35 +09:00
ToruNiina
1409114c96 refactor: add utility meta-func for internal use 2019-09-28 10:58:02 +09:00
ToruNiina
ecfc9d0c5a fix: make return type rvalue when rvalue is passed 2019-09-28 10:31:10 +09:00
ToruNiina
94f76137a3 doc: add description of unreleased toml features 2019-09-05 14:31:05 +09:00
ToruNiina
c2e1aa9a3c Merge branch 'master' into fp-exp-leading-zeroes 2019-09-05 13:50:58 +09:00
ToruNiina
5b5ece6c32 fix: add "unreleased" flag to raw-tab-in-string 2019-09-04 18:10:15 +09:00
ToruNiina
b696e327d7 ci: add options to test toml-head features 2019-09-04 13:37:08 +09:00
ToruNiina
757e5d60be test: add flag for toml-head features to tests 2019-09-04 13:36:42 +09:00
ToruNiina
c02093de7f chore: add an option to tests
that enable/disable to use unreleased toml features
2019-09-04 13:34:28 +09:00
ToruNiina
4f8b62a7e9 feat: add TOML11_USE_UNRELEASED_TOML_FEATURES flag
to choose to use unreleased toml feature
2019-09-04 13:32:05 +09:00
ToruNiina
d9b8582c47 test: add test for toml::get<T>(std::move(v)) 2019-09-01 19:39:37 +09:00
ToruNiina
c9543d8d9e test: add test of find_or with conversion 2019-08-31 13:05:05 +09:00
ToruNiina
15b68a89c6 fix: suppress warnings by forwarding argument 2019-08-31 13:04:25 +09:00
ToruNiina
64e7bdb835 test: add test for leading zeroes in fp exp 2019-08-28 17:49:12 +09:00
ToruNiina
1acf87679e feat: permit leading 0s in exp parts of floats
This is an unreleased feature of toml language, but is merged into
toml-lang/toml:master.
2019-08-28 16:02:10 +09:00
ToruNiina
7a1b5bd64e fix: skip whitespaces without newline 2019-08-26 18:16:09 +09:00
ToruNiina
e332e018db feat: allow raw tab characters in basic strings
This feature is planned to be incorporated in toml v1.0.0 but not
released yet.
2019-08-21 11:19:47 +09:00
ToruNiina
b1ec6d87bd chore: update patch version 2019-08-07 15:58:28 +09:00
ToruNiina
8dded288b4 Merge branch 'master' into find-or-value 2019-08-07 14:58:56 +09:00
ToruNiina
0f491c7f3a fix: add overload for find_or with toml::value 2019-08-07 14:55:30 +09:00
ToruNiina
5edf43a1d2 test: add missing include file to test code 2019-07-23 22:32:32 +09:00
ToruNiina
cffc605505 fix: stop including iostream 2019-07-23 22:27:20 +09:00
ToruNiina
fb91936a1d fix #76: correct version description in CMakeLists 2019-07-21 13:16:48 +09:00
ToruNiina
8833292858 doc: rearrange toml::find section in README 2019-07-19 20:42:47 +09:00
ToruNiina
3fe04aff77 doc: fix sample script in README 2019-07-19 20:13:12 +09:00
ToruNiina
138f030b5d doc: fix sample codes in README 2019-07-18 17:39:24 +09:00
ToruNiina
2eb2e0a753 doc: update README 2019-07-13 15:11:01 +09:00
ToruNiina
87e0ba201e feat: enable to swap comment and strings 2019-07-13 14:33:14 +09:00
ToruNiina
24a05c7c93 doc: update serialization section #73 2019-07-10 09:12:38 +09:00
ToruNiina
c3653b85f1 doc: fix include directory #72 2019-07-10 08:45:09 +09:00
ToruNiina
00b05c63b9 doc: add explanation about os << toml::string 2019-07-07 21:24:33 +09:00
ToruNiina
35b7c79ebd doc: update README 2019-07-03 17:33:24 +09:00
ToruNiina
9ef146d022 🔀 Merge branch 'v3' 2019-07-03 17:31:45 +09:00
ToruNiina
2c192af35d test: add test for toml::string format 2019-06-29 20:20:31 +09:00
ToruNiina
c2435b0d56 feat:boom:: format toml::string as TOML format 2019-06-29 20:19:47 +09:00
ToruNiina
9b12b17d5e ci: fix ci job script 2019-06-29 17:36:16 +09:00
ToruNiina
e61b38fac2 ci: add test_serialization to the jobs 2019-06-29 16:45:59 +09:00
ToruNiina
716f7bacba ci: run serialization test to circleci 2019-06-29 16:43:11 +09:00
ToruNiina
299d1098e4 test: add serialization test for arbitrary file 2019-06-29 16:40:42 +09:00
ToruNiina
c272188060 fix: check inline table does not include LF 2019-06-29 16:39:54 +09:00
ToruNiina
0fc0967f6f fix: remove CR before comparing to the reference 2019-06-29 15:38:28 +09:00
ToruNiina
df0d870c97 test: add test for serialization with nocomment 2019-06-29 15:00:00 +09:00
ToruNiina
d5299fef04 feat: add no_comment option to serializer 2019-06-29 14:59:18 +09:00
ToruNiina
937a3b4a2e test: add test for nocomment/showcomment 2019-06-28 19:09:05 +09:00
ToruNiina
0502924d25 feat: add nocomment and showcomment 2019-06-28 19:08:48 +09:00
ToruNiina
6182f3ee9d test: add test for operator<<(os, non-table-value) 2019-06-28 17:56:41 +09:00
ToruNiina
3624e4b690 fix: put comment just after non-table values
When non-table value is passed to the `operator<<`, it assumes that the
original C++ code looks like the following.

```cpp
std::cout << "key = " << v << std::endl;
```

In this case, the comment associated to `v` should be put just after
`v`, not before.
```toml
key = # comment <= bad
"value"

key = "value" # comment <= good
```

So, if `v` is not a table it would put comments just after the value.
2019-06-28 17:53:19 +09:00
ToruNiina
37e96ed8dc test: add test for format_key() 2019-06-28 17:47:42 +09:00
ToruNiina
79e7511871 feat: add format_key to help serialization 2019-06-28 17:47:19 +09:00
ToruNiina
284f122433 refactor: replace for-loop by comment output 2019-06-28 14:58:47 +09:00
ToruNiina
134475e292 test: check ostream op for comment containers 2019-06-28 14:58:16 +09:00
ToruNiina
28b3f7d6fb feat: add ostream operator to comment containers 2019-06-28 14:57:45 +09:00
ToruNiina
6b5fd349aa fix: initialize source_location correctly 2019-06-26 21:35:01 +09:00
ToruNiina
76e44a0c48 refactor: remove needless inline specifier 2019-06-26 21:34:36 +09:00
ToruNiina
b4bbd0a005 chore: update version string in CMakeLists 2019-06-26 21:31:35 +09:00
ToruNiina
f9ee645dc2 doc: add link to v3 branch 2019-06-23 21:00:59 +09:00
ToruNiina
6a251f582e refactor: remove needless code snippet 2019-06-22 17:52:01 +09:00
ToruNiina
74ef494797 feat: remove unused trait types 2019-06-22 17:35:40 +09:00
ToruNiina
3a5f8a4b88 test: rename test source file 2019-06-22 17:23:51 +09:00
ToruNiina
4d2b24b647 test: add test_find_or 2019-06-22 16:58:45 +09:00
ToruNiina
3fcb6bb20d test: fix test module name 2019-06-22 16:58:21 +09:00
ToruNiina
1e8af710a0 test: add test for get_or 2019-06-22 16:39:01 +09:00
ToruNiina
0ca8eeeb09 test: add missing include files 2019-06-21 17:11:21 +09:00
ToruNiina
a343ffd2a1 doc: update README 2019-06-21 17:02:30 +09:00
ToruNiina
b79797d2c7 refactor: replace BOOST_CHECK_EQUAL by BOOST_TEST 2019-06-21 16:01:14 +09:00
ToruNiina
90918b6d76 test: add basic_value type to serialization tests 2019-06-21 16:01:08 +09:00
ToruNiina
dd9b04ae3b fix: fix test case name 2019-06-21 16:01:04 +09:00
ToruNiina
4032b438c0 fix: time offset may change while conversion 2019-06-21 16:00:48 +09:00
ToruNiina
7b37d876ae refactor: update Boost.Test v2 to v3 2019-06-21 14:50:17 +09:00
ToruNiina
713b42e589 refactor: use CHECK_THROW macro to check it throws 2019-06-21 14:47:27 +09:00
ToruNiina
1694f74510 chore: update boost test library usage (v2->v3) 2019-06-21 14:43:13 +09:00
ToruNiina
9f69ffa993 fix: add unsigned symbol to integer literals 2019-06-21 14:42:44 +09:00
ToruNiina
0cee58b0b1 Merge branch 'v3' of github.com:ToruNiina/toml11 into v3 2019-06-21 14:31:52 +09:00
ToruNiina
ab1ef63da6 doc: add value ctor with comments to README 2019-06-21 14:31:28 +09:00
ToruNiina
e8d535e485 test: add tests for constructors with comments 2019-06-21 14:26:49 +09:00
ToruNiina
d4afed5bbb feat: construct value with a list of comments 2019-06-21 14:26:05 +09:00
ToruNiina
3ef8bddb6d doc: update README 2019-06-21 13:23:15 +09:00
ToruNiina
a68543a895 fix: detect comment in stricter way 2019-06-21 13:10:02 +09:00
ToruNiina
ec839bbd75 chore: add -Wextra when compiling tests 2019-06-21 00:29:45 +09:00
ToruNiina
ecf55f86d6 refactor: add explicit type conversion 2019-06-21 00:25:57 +09:00
ToruNiina
3b71f80652 refactor: streamsize is a signed integer 2019-06-21 00:00:37 +09:00
ToruNiina
be2d2aec52 refactor: explicitly convert difference_t to size_t 2019-06-20 23:59:16 +09:00
ToruNiina
be04bf1302 refactor: convert file size to size_t 2019-06-20 23:58:35 +09:00
ToruNiina
427706d671 fix: explicitly add float conversion 2019-06-20 23:58:15 +09:00
ToruNiina
71ff54e76c fix: rearrange internal int types in datetimes 2019-06-20 23:58:08 +09:00
ToruNiina
8208bbf236 fix: check and convert value manually
I totally have no idea when std::count returns a negative value, but the
result type of `std::count` is a differnce_type. So when it is added
with size_t value, implicit sign conversion happens. This changes check
this kind of (almost trivial but required) checking.
2019-06-20 22:27:16 +09:00
ToruNiina
f689d26294 refactor: add conversion function to utf8 encoder 2019-06-20 22:25:40 +09:00
ToruNiina
9e6d8e76d0 fix: replace null deref by terminate for safety
Since empty_iterator never points anything, so it always points null
(it returns nullptr by operator->). but dereferencing null causes UB.
Just calling std::terminate is of course better.
2019-06-20 20:56:49 +09:00
ToruNiina
0e2e4a26be ci: Revert "ci: use libstdc++ when compiling"
Ok, it already worked without this.
This reverts commit 092db50700.
2019-06-20 20:48:17 +09:00
ToruNiina
092db50700 ci: use libstdc++ when compiling
because some of the earlier versions of libc++ does not conform c++11
2019-06-20 20:43:57 +09:00
ToruNiina
295e9bb795 ci: try to update system library 2019-06-20 20:24:12 +09:00
ToruNiina
dd2238e1ad ci: change apt source on travis
clang 3.7 trusty version seems to be restricted. I don't know why, but
precise version seems to be working.
2019-06-20 20:21:06 +09:00
ToruNiina
5dfa88a1b3 ci: rename package to be installed 2019-06-20 20:13:16 +09:00
ToruNiina
37b4442d7f ci: upgrade boost on Travis Linux 2019-06-20 20:00:56 +09:00
ToruNiina
48aa0a4c67 ci: update boost version on appveyor 2019-06-20 19:53:27 +09:00
ToruNiina
86a1f7ad75 fix: add missing include files 2019-06-20 16:23:51 +09:00
ToruNiina
99c10dd6bc fix: enable to deduce what basic_value to be used 2019-06-20 16:21:01 +09:00
ToruNiina
7d087ef2a8 doc: update README 2019-06-20 15:22:20 +09:00
ToruNiina
a0d74a5542 doc: add info about breaking changes to README 2019-06-20 14:58:18 +09:00
ToruNiina
c3922c0d51 test: move some test_cases across test files 2019-06-20 14:43:31 +09:00
ToruNiina
5e5a757208 fix: conversion between different basic_value s 2019-06-20 14:35:38 +09:00
ToruNiina
f178379c07 test: add test_find 2019-06-20 14:34:42 +09:00
ToruNiina
321db42b1c Merge branch 'master' into v3 2019-06-19 23:44:09 +09:00
ToruNiina
1bf9e42835 chore: update version 2019-06-19 21:12:05 +09:00
ToruNiina
3379ed82ec refactor: remove meaningless meta conditions 2019-06-19 20:06:06 +09:00
ToruNiina
9663a6bbdb Merge branch 'master' into v3 2019-06-19 19:53:08 +09:00
ToruNiina
4a2c823d56 fix: comparison between values that has a table 2019-06-19 19:32:25 +09:00
ToruNiina
9a47c2a15a Merge branch 'v3' of gitlab.com:ToruNiina/toml11 into v3 2019-06-19 19:03:47 +09:00
ToruNiina
3311d00845 Merge branch 'v3' of gitlab.com:ToruNiina/toml11 into v3 2019-06-19 19:05:22 +09:00
ToruNiina
24c28c7f4f fix: correct some SFINAE expressions 2019-06-19 18:59:12 +09:00
ToruNiina
cab3144507 style: format CMakelists.txt 2019-06-19 16:53:45 +09:00
ToruNiina
7e5859ba73 Merge branch 'master' into v3 2019-06-19 15:36:27 +09:00
ToruNiina
dee32e7d5e style: make hint messages clearer 2019-06-19 12:58:34 +09:00
ToruNiina
53a185e7a9 fix: revert misjudgement as a bug
Probably I'm too tired.

This reverts commit adcd75e017.
2019-06-18 21:41:30 +09:00
ToruNiina
fd980a8c5d 🔀 Merge branch 'guess-type-error' 2019-06-18 21:29:45 +09:00
ToruNiina
73ac43d70c doc: add contributor 2019-06-18 21:28:50 +09:00
ToruNiina
adcd75e017 fix: correctly initialize offset 2019-06-18 21:27:16 +09:00
ToruNiina
3613580bb3 doc: update README 2019-06-18 21:26:17 +09:00
ToruNiina
d9f9df61a2 fix: fix links in README 2019-06-18 01:39:36 +09:00
ToruNiina
32d5c9e924 fix: serialize array correctly 2019-06-18 01:27:52 +09:00
ToruNiina
262f9c5fcc fix: avoid duplicating comment: array/table elems 2019-06-18 01:26:40 +09:00
ToruNiina
86e55c3bf7 test: check serialization keeps comments 2019-06-18 01:26:16 +09:00
ToruNiina
159283fdad test: check preserve_comment keep it read 2019-06-18 01:25:43 +09:00
ToruNiina
fb5834caab refactor: exchange order of test section 2019-06-18 00:45:30 +09:00
ToruNiina
ca084abe90 feat: consider the first comments as a file comment 2019-06-18 00:44:49 +09:00
ToruNiina
7b1a788e2d feat: enable to convert vector<string> to comments 2019-06-18 00:43:25 +09:00
ToruNiina
228487eafd test: fix typos in tests 2019-06-17 23:46:42 +09:00
ToruNiina
f744a792e2 fix: constructor with array-like types 2019-06-17 23:45:43 +09:00
ToruNiina
bf2dc76d5e test: add test for templatized conversions 2019-06-17 23:21:18 +09:00
ToruNiina
4d267cadf4 doc: add templatized conversion to README 2019-06-17 23:12:46 +09:00
ToruNiina
bc68a9d9ee refactor: remove needless include file 2019-06-17 23:07:14 +09:00
ToruNiina
4008c24e84 test: add test for init-list-map to value conversion 2019-06-17 22:50:38 +09:00
ToruNiina
c2b0de623f feat: enable to convert map-like to toml::value 2019-06-17 22:50:14 +09:00
ToruNiina
af11d56e79 fix: correctly move value from find_or to get_or 2019-06-17 22:40:52 +09:00
ToruNiina
5cb7c961aa fix: update README 2019-06-17 22:26:41 +09:00
ToruNiina
bf4eae0b76 test: drop test for find_or(table) 2019-06-17 22:14:26 +09:00
ToruNiina
6399d44e3b fix: consider comments while serialization 2019-06-17 22:13:58 +09:00
ToruNiina
d10c0725fd fix: consider closing bracket when collect comments
table = {key = "value"} # comment.
a value named "table" ({key = "value"}) has the above comment.
but a value named "key" ("value") does not have any comment.
2019-06-17 22:12:20 +09:00
ToruNiina
7eac3a3028 feat: support serialization of basic_value 2019-06-17 20:34:42 +09:00
ToruNiina
57b5545ba2 fix: add _type suffix to value::xxx_type 2019-06-17 20:34:13 +09:00
ToruNiina
f36b39c04f fix: consider comments while comparing values 2019-06-17 20:33:57 +09:00
Toru Niina
569341a514 Merge pull request #69 from KerstinKeller/cmake_install
Allow to install toml11 library with CMake.
2019-06-17 18:03:00 +09:00
KerstinKeller
0357d8fb57 Add newline to end of CMake files. 2019-06-17 10:04:39 +02:00
ToruNiina
00d40140ac doc: add an example of error message to README 2019-06-17 12:59:29 +09:00
ToruNiina
1bfe8f1f54 Merge branch 'master' into guess-type-error 2019-06-17 12:48:36 +09:00
ToruNiina
b3300fad2a fix: move element of map in toml::find(val&&) 2019-06-17 12:13:59 +09:00
ToruNiina
94bcf0aae9 Merge branch remote into v3 2019-06-17 12:10:45 +09:00
ToruNiina
bc143263cd Merge branch 'revert-recursive-find' 2019-06-17 11:54:52 +09:00
ToruNiina
0ef232a1e0 feat: 💥 remove toml::find_or for toml::table 2019-06-17 01:26:05 +09:00
ToruNiina
0604cf813a feat: 💥 remove toml::find for tables 2019-06-17 01:24:32 +09:00
ToruNiina
10f410a02c doc: add some notes and comments to README 2019-06-17 00:48:06 +09:00
ToruNiina
12ef0f6287 doc: add containers and comments to README 2019-06-17 00:29:43 +09:00
ToruNiina
d9ad0e4b92 doc: add source_location to README 2019-06-16 23:44:54 +09:00
ToruNiina
1b19d5f1eb doc: update README 2019-06-16 21:44:59 +09:00
ToruNiina
fd7da05798 doc: update README 2019-06-16 20:31:08 +09:00
ToruNiina
cbaaaaca7c revert recursive find function
I found that in a user-code (I'm also one of the users of this library),
this new feature sometimes causes an error. Some of my code won't
compile because of this change. Since toml::table is convertible to
toml::value *implicitly*, if toml::find(table, key, tablename) was
called, the overload resolution becomes ambiguous with toml::find(
value, key1, key2). But dropping support for toml::find(toml::table,
key, tablename) is a breaking change. So I concluded that now is not
the right time yet.
2019-06-16 19:55:40 +09:00
ToruNiina
cf1c9371b6 fix: correct example and positions in err msgs 2019-06-16 17:52:42 +09:00
ToruNiina
62e8d58d8d feat: guess possible format errors 2019-06-16 17:32:29 +09:00
ToruNiina
fec4e1db9a doc(WIP): add source_location to README 2019-06-15 20:34:20 +09:00
ToruNiina
8665272bab test: add test for custom basic_value type 2019-06-15 20:25:19 +09:00
ToruNiina
cc4a9c8d5d fix: consider identity conversion in SFINAE 2019-06-15 20:20:14 +09:00
ToruNiina
af19dfe032 fix: conversion between different basic_values 2019-06-15 20:19:51 +09:00
ToruNiina
64dc086878 doc(WIP): re-write README 2019-06-15 19:50:31 +09:00
ToruNiina
9acc55a7ac test: add test for discard_comment 2019-06-15 17:18:25 +09:00
ToruNiina
177022b2cb test: update tests for comment 2019-06-15 17:13:25 +09:00
ToruNiina
5726d10339 feat: save comment information in value 2019-06-15 17:13:02 +09:00
ToruNiina
a6706f7879 fix: templatize internal function for value 2019-06-15 17:12:30 +09:00
ToruNiina
558349170d fix: correct the order and remove last CR 2019-06-15 17:11:49 +09:00
ToruNiina
eb4eca86db feat: 💥 change comment interface in region 2019-06-15 16:11:05 +09:00
ToruNiina
d8a9ee4f72 🔀 Merge branch 'master' into v3 2019-06-15 15:17:08 +09:00
KerstinKeller
acbc2a73cb Allow to install tom11 library with CMake.
Add option to build tests.
2019-06-14 17:24:21 +02:00
ToruNiina
b2daf916b3 doc: add contributor to README 2019-06-11 22:45:46 +09:00
Toru Niina
e66bb3d359 Merge pull request #67 from ToruNiina/hotfix
suppress warnings on clang v7+
2019-06-10 10:54:54 +09:00
Toru Niina
cfaa94f072 Merge pull request #68 from khoitd1997/master
fix sign-compare warning
2019-06-10 10:49:49 +09:00
khoitd1997
2f4f3efbf0 fix sign-compare warning 2019-06-09 12:00:28 -07:00
ToruNiina
06ae67502a fix: move argument correctly 2019-06-09 21:05:46 +09:00
ToruNiina
6345910c3e 🔀 Merge branch 'master' into v3 2019-06-08 20:05:05 +09:00
ToruNiina
9948549b62 fix: add missing template parameters 2019-06-08 19:53:50 +09:00
ToruNiina
54d46f08c3 🔀 Merge branch 'master' into v3 2019-06-08 19:40:11 +09:00
ToruNiina
57cb806e14 Merge branch 'master' into throw-from-as-something 2019-06-08 19:23:32 +09:00
ToruNiina
d6f3654185 refactor: reduce test code by using CHECK_THROW 2019-06-08 19:23:12 +09:00
ToruNiina
8befe3f1ad test: add test for throw/nothrow versions of as_* 2019-06-08 19:20:09 +09:00
ToruNiina
2d43119ac7 doc: change README a bit 2019-06-07 21:05:33 +09:00
ToruNiina
436af12815 doc: update README 2019-06-07 19:43:01 +09:00
ToruNiina
4f4d4380f2 feat: throw from as_* if type differs 2019-06-07 19:34:04 +09:00
ToruNiina
31debcb8aa 🔀 Merge branch 'master' into recursive-find 2019-06-07 19:02:20 +09:00
ToruNiina
2afa0ff0c3 doc: add find(value, key1, key2, ...) to README 2019-06-07 19:01:46 +09:00
ToruNiina
46047c48bf doc: add note about is|as_float to README 2019-06-07 13:40:21 +09:00
ToruNiina
897aecf5d4 test: avoid deprecated functions in the test codes 2019-06-07 13:32:02 +09:00
ToruNiina
7db8388d17 fix: avoid deprecated stuff in the internal code 2019-06-07 13:27:10 +09:00
ToruNiina
62c993e096 feat: add as|is_floating and deprecate as|is_float
to make the function names consistent with snake_case_typenames
2019-06-07 00:10:12 +09:00
ToruNiina
014d882f8f feat: enable to find value by recursive search 2019-06-07 00:06:14 +09:00
ToruNiina
e781545c53 feat(WIP): diable test for comments once
because the interfaces would be changed a lot.
2019-06-06 22:34:08 +09:00
ToruNiina
a8b5fef827 feat(WIP): add workaround to make literal compiles 2019-06-06 22:32:51 +09:00
ToruNiina
7258c52334 feat: enable to edit comments through memfun 2019-06-03 22:17:10 +09:00
ToruNiina
407d9223f6 feat: 💥 is_float -> is_floating 2019-06-03 22:01:47 +09:00
ToruNiina
53efaed179 test: update interfaces of parse_* and value 2019-06-03 22:01:16 +09:00
ToruNiina
d7c5606dcf fix: update as_float -> floating 2019-06-03 21:46:48 +09:00
ToruNiina
761718b3b9 test: update retval of parse and related get/find 2019-06-03 21:44:47 +09:00
ToruNiina
ae2bafa907 fix: correct SFINAE conditions and types 2019-06-03 21:44:11 +09:00
ToruNiina
f19b3822bb feat: 💥 change as_float -> as_floating 2019-06-03 21:43:35 +09:00
ToruNiina
2cbb93d86e fix: #65 Merge branch 'hotfix' 2019-06-03 21:27:25 +09:00
ToruNiina
a19b94511b fix: add space between operator"" and _toml
In C++11, it is required.
2019-06-03 20:58:35 +09:00
ToruNiina
cf1114b47b test: update typenames from Camel to snake 2019-06-02 22:13:36 +09:00
ToruNiina
ad3c1950f2 test: use find instead of get<T>(v.at("")) 2019-06-02 22:12:52 +09:00
ToruNiina
296ba060ef test: update typename from CamelCase to snake_case 2019-06-02 22:11:37 +09:00
ToruNiina
fe8a909213 fix: correctly put references 2019-06-02 22:09:26 +09:00
ToruNiina
c313e1382c test: update test for multiple translation units 2019-06-02 22:00:56 +09:00
ToruNiina
5fe166e375 fix: update value_t::* names in serializer
Although currently serializer does not support basic_value, it compiles.
2019-06-02 21:51:37 +09:00
ToruNiina
319365f86b feat: update types in format_error 2019-06-02 21:50:27 +09:00
ToruNiina
89f0ace6ee fix: initialize comment container correctly 2019-06-02 21:50:01 +09:00
ToruNiina
2e34035e7a feat: 💥 update types and retval of parser
- change return value from toml::table to toml::value
- enable to change container types and comment policy by template
2019-06-02 21:47:57 +09:00
ToruNiina
7d34436535 test: update value_t::* names in the test code 2019-06-02 21:36:09 +09:00
ToruNiina
8456186eac fix: remove inclusion of removed file 2019-06-02 21:34:57 +09:00
ToruNiina
e094d6e85a refactor: move type alias from get to trait 2019-06-02 20:43:08 +09:00
ToruNiina
4664f91517 feat: remove unused meta-function alias 2019-06-02 20:40:44 +09:00
ToruNiina
c0b6ca762a feat: 💥 drop from_toml support 2019-06-02 19:27:03 +09:00
ToruNiina
5ef9890d0c feat: update find_or for basic_value 2019-06-02 19:22:17 +09:00
ToruNiina
bda337b51f feat: support conversion between basic_values 2019-06-02 19:09:56 +09:00
ToruNiina
6569c26e1b feat: make SFINAE condition strict 2019-06-02 19:04:32 +09:00
ToruNiina
6d17d5f60f feat: update expect for basic_value 2019-06-02 19:02:25 +09:00
ToruNiina
c00eeb18ef feat: add meta function that detects toml::basic_value 2019-06-02 19:02:01 +09:00
ToruNiina
3ce1aa31f3 feat: update get_or for basic_value 2019-06-02 18:55:02 +09:00
ToruNiina
cf28c3fb95 feat: update toml::find for basic_value 2019-06-02 18:36:49 +09:00
ToruNiina
6de494598a fix: remove unused argument to suppress warnings 2019-06-02 18:32:47 +09:00
ToruNiina
b06ae03deb feat: update toml::get<T> for basic_value 2019-06-02 17:53:08 +09:00
ToruNiina
725d915ba9 feat(WIP): update toml::get 2019-06-02 17:31:49 +09:00
ToruNiina
e1556183d1 refactor: remove unused include files 2019-06-02 17:12:01 +09:00
ToruNiina
9676499ab5 refactor: move file inclusion to correct position 2019-06-02 15:29:34 +09:00
ToruNiina
5792411d5e feat: add default template argument to basic_value 2019-06-02 15:15:43 +09:00
ToruNiina
44184026f9 feat: enable to convert different basic_values 2019-06-02 00:13:12 +09:00
ToruNiina
898423166f feat: enable to convert preserve/discard comments 2019-06-02 00:02:31 +09:00
ToruNiina
f9b5166c09 refactor: move default value types to value.hpp 2019-06-01 23:58:17 +09:00
ToruNiina
5c5d8b686a feat: introduce basic_value
it is capable to change comment policy, backend container of an array
and a table.
2019-06-01 20:18:57 +09:00
ToruNiina
5c3c1bd0e7 feat: add missing default array/table type 2019-06-01 20:18:15 +09:00
ToruNiina
696e5bb66f feat: extend has_from_toml_method to be generic 2019-06-01 20:16:59 +09:00
ToruNiina
65540fbb5c fix: typos 2019-06-01 19:47:10 +09:00
ToruNiina
351320491d fix: fix has_from_toml using basic_value 2019-06-01 19:46:20 +09:00
ToruNiina
d30700517d fix: add missing include file 2019-06-01 19:43:35 +09:00
ToruNiina
14ad8d0556 fix: fix typos and invalid names 2019-06-01 19:43:15 +09:00
ToruNiina
f04c97b587 refactor: simplify format_underline a bit 2019-06-01 19:06:08 +09:00
ToruNiina
b8d3038d38 feat: add meta function to detect conversions 2019-06-01 16:03:26 +09:00
ToruNiina
eaa3604dce refactor: introduce value_t_constant
as an alias for integral_constant
2019-06-01 16:01:48 +09:00
ToruNiina
8acc348106 feat: 💥 change interface around types
- change value_t::typename from CamelCase to snake_case.
- drop CamelCase typename supports.
The changes are introduced to make the interfaces uniform. For some
(historical) reasons, toml11 has both CamelCase names and snake_case
names for types. Additionally, since `float` is a keyword, snake_case
names uses `floating` to avoid collision and CamelCase name uses `Float`
because toml official calls it `Float`. This is too confusing.
Since it is a major upgrade, I think it is a big chance to make them
uniform.
2019-06-01 13:33:57 +09:00
ToruNiina
2567f2a787 feat: add source_location for error message generation. 2019-06-01 13:25:02 +09:00
ToruNiina
84b5749c6b feat: implement comment containers 2019-06-01 13:24:54 +09:00
ToruNiina
70d0049511 refactor: move some meta-funcs to traits.hpp 2019-06-01 12:35:40 +09:00
ToruNiina
717f5929c2 feat: use detail::none_t instead of char
Although the error value from combinators currently does not have any
information, it can have an information because it is a char value. It
is better to use no-information-type explicitly to make it clear that
it does not have any information. So I added none_t in toml::detai and
use it in combinators and parsers as an error value from combinators.
2019-05-31 17:07:52 +09:00
ToruNiina
81abb6c9d7 perf: remove err-msg from combinator
Generate error message in `parse_something()`, not in `lex_something`.
Since the error message generated by `lex_something` is too difficult to
read for humans, I've disabled the error message generation for the sake
of efficiency (it takes time to generate error message that will never
be read). I think now the error message generation itself safely can be
removed from combinators. At this stage, `lex_something` does not need
to return `result<T, E>` because all the error type would be discarded.
Now it is turned out that returing `optional<T>` from lex_* is enough.
Maybe later I would change the return type itself, but currently I
changed the error type from std::string to char because implementing
optional takes time and effort. It makes the parsing process a bit
faster.
2019-05-30 20:08:37 +09:00
ToruNiina
8bba3c8a14 refactor: use literal instead of empty string
so far, the error value of the lexer is just ignored because they are
not readable (results from all the nested combinator are concatenated,
so they are too redundant). those ones are replaced by a simple literal.
2019-05-30 19:33:25 +09:00
ToruNiina
b13e727b90 refactor: remove unused func, combinator::pattern
because it is not human-readable (too long and redundant)
2019-05-30 18:05:47 +09:00
ToruNiina
d352c9e66f perf: suppress unused error message generation 2019-05-30 17:47:06 +09:00
ToruNiina
c0aaba06d0 Merge branch 'refactoring' 2019-05-30 16:25:10 +09:00
ToruNiina
1633268d57 refactor: use snake_case typename only 2019-05-30 14:39:15 +09:00
ToruNiina
3bf1c2b820 Merge branch 'refactoring' to master 2019-05-30 00:18:07 +09:00
ToruNiina
4dbd2cb9fe refactor: use as_* to avoid needless checking 2019-05-29 21:22:32 +09:00
ToruNiina
65124a8d2e refactor: use is_something instead of is(...)
to reduce the code size a bit
2019-05-29 21:20:22 +09:00
ToruNiina
1b78f161f5 refactor: use is_something/as_something in parser
this reduces the size of the code. And also it skips needless
double-checking, so we can expect it makes parsing a bit faster.
2019-05-29 21:18:17 +09:00
ToruNiina
0ce259ada0 refactor: split throw_bad_cast from value::cast 2019-05-29 21:06:25 +09:00
ToruNiina
74da49f87f refactor: move switch_cast from inside of value
use as_something() instead of it. To realize this, the implementation of
as_something() is also changed. Now as_something does not depends on
`cast`. This reduces complexity around casting toml::value to other types.
2019-05-29 20:18:15 +09:00
ToruNiina
d5d697639c docs: add contributor to README 2019-05-10 23:02:23 +09:00
Toru Niina
0b365ca7d3 Merge pull request #63 from chronoxor/master
Fix Visual Studio 2019 warnings in pedantic compilation mode (/W4 /WX)
2019-05-10 22:58:17 +09:00
Ivan Shynkarenka
db6f3d5d11 Fix Visual Studio 2019 warnings in pedantic compilation mode (/W4 /WX) 2019-05-10 14:58:22 +03:00
ToruNiina
87be890e07 feat: remove deprecated functions 2019-04-28 15:59:09 +09:00
Toru Niina
d72dc706d0 Merge pull request #61 from ToruNiina/as-something
feat: add as_something functions for convenience
2019-04-28 15:02:19 +09:00
ToruNiina
4cbbcd8f62 Merge branch 'master' into as-something 2019-04-27 19:04:44 +09:00
Toru Niina
a2631ecacb Merge pull request #60 from ToruNiina/string-view
support std::string_view
2019-04-27 18:33:59 +09:00
ToruNiina
4bcc5e8375 Merge branch 'master' into as-something 2019-04-27 17:42:12 +09:00
Toru Niina
90f84000ba Merge pull request #59 from ToruNiina/preserve-comments
Preserve comments; related to #48
2019-04-27 17:40:26 +09:00
ToruNiina
20a13754a7 chore: update README for as_* functions 2019-04-27 16:50:44 +09:00
ToruNiina
aa7b9a3965 refactor: rename as_floating -> as_float
Actually, since `floating` is used for toml::types, `as_floating`
seems to be clearer. But currently `is_*` functions uses `float`,
not `floating`, so `as_float` is chosen for the consistency.
In a future release, possibly v3, those names may need to be
re-considered for clarity.
2019-04-27 16:45:25 +09:00
ToruNiina
84ac1d10f3 test: add test for toml::value::as_something 2019-04-27 16:22:50 +09:00
ToruNiina
0d623856a7 feat: add value::as_something() for convenience 2019-04-27 16:22:23 +09:00
ToruNiina
ec0d4e4e8c chore: update README for comments 2019-04-27 15:50:54 +09:00
ToruNiina
80ea736b3f ci: try to update standard library on travis 2019-04-27 14:46:40 +09:00
ToruNiina
ebaa5dfb51 chore: fix build settings for OS X on Travis 2019-04-26 21:10:29 +09:00
ToruNiina
f3bdf083fe fix: fix typo in test code for string_view 2019-04-26 16:51:23 +09:00
ToruNiina
1ce54a9cf9 chore: add auto test with c++17 + latest compilers 2019-04-26 16:35:03 +09:00
ToruNiina
6383a93ce7 chore: check CXX_STANDARD exists or not 2019-04-26 16:33:48 +09:00
ToruNiina
01aa2ef5b2 feat: add ctor to value to init with string_view 2019-04-26 16:33:09 +09:00
ToruNiina
819351f5a4 test: add test for init toml::value by string_view 2019-04-26 16:32:23 +09:00
ToruNiina
2967cebfb3 test: add test to get a toml::value as string_view 2019-04-26 16:31:59 +09:00
ToruNiina
32e9a2c1c7 test: add test for comments in an array 2019-04-26 15:35:41 +09:00
ToruNiina
8e0a40a1aa test: add test for getting comments 2019-04-25 22:34:12 +09:00
ToruNiina
e460826084 feat: enable to get a comment related to a value
- comment_before(): get comments just before a value.
- comment_inline(): get a comment in the same line as a value.
- comment(): get comment_before() + comment_inline().
2019-04-25 22:32:39 +09:00
ToruNiina
aa3445f38c feat: add functions to get comments around region 2019-04-25 22:32:18 +09:00
ToruNiina
408b7bf35e Merge branch 'master' into string-view 2019-04-23 23:32:08 +09:00
ToruNiina
6185dfee14 chore: fix typo in README 2019-04-23 23:31:37 +09:00
ToruNiina
37aa2739a5 chore: add description about string_view to README 2019-04-23 23:27:53 +09:00
ToruNiina
d061c33a16 feat: enable toml::get with std::string_view 2019-04-23 23:24:23 +09:00
ToruNiina
0c7d2d07d4 feat: do not consider string_view as a container
it is a kind of string.
2019-04-23 23:23:57 +09:00
ToruNiina
62cf4373bd feat: conversion toml::string <-> string_view 2019-04-22 23:18:05 +09:00
Toru Niina
a74ad23514 Merge pull request #58 from ToruNiina/improve-err-msg-literal
Improve error message from toml literal
2019-04-22 20:50:11 +09:00
ToruNiina
2d9b4992ec fix: restrict length of underline by size of line
in some cases, `region` contains several lines and `region::size`
returns the whole size that is a sum of lengthes of all the lines.
To avoid too long underlines, restrict the length of underline by
the length of the line that is shown in the message.
2019-04-21 16:38:08 +09:00
ToruNiina
82e8c1e68b fix: skip first ws/newlines in toml literal
when ""_toml literal is used with C++11 raw-string literal,
it normally starts with newline like the following.
```cpp
const auto v = u8R"(
    [table]
    key = "value"
    )"_toml;
```
With this, the error message shows the first empty line that starts just
after `u8R"(` and thus the error message shows nothing. To avoid this,
skip the first empty lines and whitespaces in literal.
2019-04-21 16:31:24 +09:00
ToruNiina
46be054ce9 fix: improve err msg for multiline inline table
show "missing curly brace" instead of "missing table key-value separator"
2019-04-19 13:22:13 +09:00
ToruNiina
789d784769 chore: update README; about literals 2019-04-19 13:18:35 +09:00
ToruNiina
81deb8efde chore: update README 2019-04-19 12:41:24 +09:00
Toru Niina
072dccd05d Merge pull request #56 from ToruNiina/optimization
Optimization
2019-04-19 01:30:29 +09:00
ToruNiina
637c99d637 refactor: generate error message in parser 2019-04-18 15:09:58 +09:00
ToruNiina
0f48852730 perf: check value type before parsing
to avoid needless error message generation
2019-04-18 14:26:27 +09:00
ToruNiina
0499b2907d Merge branch 'master' into optimization 2019-04-18 14:10:08 +09:00
ToruNiina
61e69c9251 fix: count line number from 1, not 0 2019-04-18 13:56:19 +09:00
ToruNiina
4a560ea1e5 fix: show correct error message 2019-04-18 00:04:33 +09:00
ToruNiina
c5b6ee6f81 feat: add yet another constructor to value
to make implementation of parse_value easier
2019-04-17 23:43:42 +09:00
ToruNiina
1a7bf63622 Merge branch 'master' into optimization 2019-04-17 14:58:28 +09:00
Toru Niina
8847cdc0a9 Merge pull request #55 from wbenny/master
fix /W4 warnings on MSVC
2019-04-17 13:16:19 +09:00
ToruNiina
c82e76a111 perf: check string type before parsing it
to avoid unncessary error message generation, check the first some
characters before parsing it. It makes parsing process faster and
is also helpful to generate more accurate error messages.
2019-04-16 21:47:24 +09:00
ToruNiina
4db486d76d perf: check integer prefix before trying to parse
all the parsers generate error messages and error message generation is
not a lightweight task. It concatenates a lot of strings, it formats
many values, etc. To avoid useless error-message generation, first check
which prefix is used and then parse special integers. Additionally, by
checking that, the quality of the error message can be improved (later).
2019-04-16 21:37:12 +09:00
ToruNiina
91966a6917 perf: do not use concat_string if it is not needed
At the earlier stage of the development, I thought that it is useful if
lexer-combinators generate error messages, because by doing this,
parser would not need to generate an error message. But now it turned
out that to show an appropriate error message, parser need to generate
according to the context. And almost all the messages from lexer are
discarded. So I added another parameter to lexer-combinator to suppress
error message generation. In the future, we may want to remove messages
completely from lexers, but currently I will keep it. Removing those
unused message generation makes the parsing process faster.
2019-04-16 21:09:59 +09:00
ToruNiina
b3917aaadf refactor: use snprintf to show char in hex
instead of std::ostringstream.
2019-04-16 20:54:29 +09:00
Petr Benes
ba307003c4 fix /W4 warnings on MSVC 2019-04-16 13:25:45 +02:00
Toru Niina
21fd1271d9 Merge pull request #54 from ToruNiina/hotfix
fix: resolve ambiguity in the `""_toml` literal
2019-04-15 13:34:35 +09:00
ToruNiina
f9ab7d6f56 chore: add note about literals to README.md 2019-04-14 20:08:23 +09:00
ToruNiina
0a3a41a708 test: add test for literals for difficult case 2019-04-14 20:06:11 +09:00
ToruNiina
6c2a536fa5 fix: check literal has a table or an array first
The literal like this `"[[table]]"_toml` caused a syntax error. It is
because the literal parser first check that it might be a bare value
without a key, and parse_array directory throws syntax_error. This
change makes the parser first check a literal is a name of table, and
then parse the content.
2019-04-14 19:48:43 +09:00
Toru Niina
26eced3640 Merge pull request #52 from ToruNiina/speedup-for-large-files
Speedup parsing large files
2019-04-13 16:11:21 +09:00
ToruNiina
6f950c9ec8 perf: cache current line number in location
`location::line_num()` function used to be implemented by using
`std::count`, so each time the parser encounters a type mismatch,
`std::count` was called with almost whole file. It decelerates the
parsing process too much, so I decided to add `line_number_` member
variable to `location` and add `advance/retrace/reset` to `location`
in order to modify the position that is pointed.
2019-04-12 18:32:46 +09:00
ToruNiina
ea13e40889 feat: add static_assert for location/range
to check the container is randomly-accessible
2019-04-12 18:00:53 +09:00
ToruNiina
595fb1aef3 refactor: remove unused function parameter names 2019-04-06 19:39:13 +09:00
ToruNiina
18986978fb chore: add short example code to README 2019-03-24 21:30:27 +09:00
ToruNiina
c3cb22a789 chore: fix example of err msg by re-running sample 2019-03-21 18:12:35 +09:00
ToruNiina
5aebd6b562 fix: restore the back compat of format_error
the following code was okay in the last release
```
toml::format_error("[test]", v, "test", {"hint1", "hint2"})
```
but was not okay in the current master. This commit fixes this.

cons: By this, the number of values to show is limited upto 3.
2019-03-20 20:46:22 +09:00
ToruNiina
4c13085b35 fix: add stream operator for toml::table 2019-03-20 19:30:08 +09:00
ToruNiina
8709e8a14e chore: fix incorrect syntax highlight in README 2019-03-20 19:29:03 +09:00
ToruNiina
9eea46ec01 chore: fix typoes and broken links in README 2019-03-20 12:06:55 +09:00
ToruNiina
2e9f937c43 chore: update README 2019-03-20 11:53:03 +09:00
Toru Niina
65b10b6537 Merge pull request #46 from ToruNiina/toml-literal
feat: add ""_toml literal
2019-03-20 10:12:56 +09:00
ToruNiina
b51a8d5966 fix: add missing include file in test code 2019-03-20 00:58:58 +09:00
Toru Niina
55e3d70869 Merge pull request #47 from ToruNiina/format-table
`toml::format` and top-level table
2019-03-20 00:49:59 +09:00
ToruNiina
20ba57e389 fix: add missing const specifier to some of get()s 2019-03-20 00:37:13 +09:00
ToruNiina
39bc3c64fe test: add test for ""_toml literals 2019-03-20 00:36:46 +09:00
ToruNiina
40ccf1d912 feat: add argument to control top-level inlinization 2019-03-19 23:25:26 +09:00
ToruNiina
982ae36428 feat: add ""_toml literal 2019-03-19 21:34:57 +09:00
ToruNiina
d6714ec450 feat: detect value type and format as a file
in toml::format
2019-03-19 21:24:51 +09:00
ToruNiina
773c3816be ci: remove needless confirmation on CI 2019-03-19 19:39:45 +09:00
Toru Niina
1b417ddc7a Merge pull request #45 from ToruNiina/get_or
fix `get_or` and add `find_or`
2019-03-19 01:41:21 +09:00
ToruNiina
7a0ecf977d feat: add find_or(table, key, fallback)
get_or(value, fallback) is still ok, but get_or(table, key, fallback)
is now deprecated.
2019-03-18 17:44:03 +09:00
ToruNiina
aade704411 refactor: remove needless overload of get_or 2019-03-18 17:10:18 +09:00
ToruNiina
ca3f6102ef fix: correctly resolve overloads of get_or 2019-03-18 16:44:36 +09:00
ToruNiina
4a58b629ce feat: add a way to check arg is "string literal" 2019-03-18 16:31:12 +09:00
ToruNiina
3adba237b8 feat: enable to show message for deprecated() 2019-03-18 16:28:27 +09:00
Toru Niina
ccf03d9291 Merge pull request #44 from ToruNiina/test-link
test: add test for multiple translation unit
2019-03-18 15:20:04 +09:00
Toru Niina
30ae90ebd5 Merge pull request #43 from ToruNiina/hotfix
fix: incorrect move in constructor and return type deducing in toml::visit
2019-03-18 14:08:23 +09:00
ToruNiina
d5369c3429 test: add test for multiple translation unit 2019-03-18 12:39:58 +09:00
Toru Niina
48f2f0555d Merge pull request #42 from ToruNiina/test-suite
run toml-test suite
2019-03-18 12:33:48 +09:00
ToruNiina
f40fd12e25 refactor: add and rewrite comments 2019-03-18 11:09:12 +09:00
ToruNiina
65c2c3c238 fix: correctly deduce return value of visitor 2019-03-18 10:53:04 +09:00
ToruNiina
891a61a5e3 fix: do not move array element without checking 2019-03-18 02:05:55 +09:00
ToruNiina
1e6f30f6fa chore: update README.md 2019-03-18 01:50:23 +09:00
ToruNiina
02346a3126 Merge branch 'master' into test-suite 2019-03-18 01:40:17 +09:00
Toru Niina
1908f18e95 Merge pull request #41 from ToruNiina/hotfix
fix: simplify and correct the format of timezone
2019-03-18 01:39:11 +09:00
ToruNiina
3bfa7f09ba test: use the test suite in the effective way
add tests/check_toml_test.cpp to compare json object
2019-03-18 01:36:43 +09:00
ToruNiina
243f43fafd Merge branch 'master' into hotfix 2019-03-17 21:16:37 +09:00
ToruNiina
66e27a94b6 fix: simplify and correct the format of timezone 2019-03-17 21:14:17 +09:00
ToruNiina
227688ec63 ci: make result clearer a bit 2019-03-17 19:36:23 +09:00
ToruNiina
e761a503c0 ci: fix silly mistake in circleci script 2019-03-17 19:27:58 +09:00
ToruNiina
209ad79a8f ci: fix config file of circleci 2019-03-17 19:26:22 +09:00
ToruNiina
cdf209d7f6 ci: show the status on CI 2019-03-17 19:23:52 +09:00
ToruNiina
77ab391885 ci: fix name of directory and add test script 2019-03-17 19:20:24 +09:00
ToruNiina
6628fe5ace test: add language agnostic toml-test 2019-03-17 19:12:13 +09:00
Toru Niina
f3e3000d45 Merge pull request #40 from ToruNiina/remove-to-toml
refactor: remove to_toml and related tests
2019-03-17 13:12:30 +09:00
Toru Niina
f7380c6e32 Merge pull request #39 from ToruNiina/throw-incorrect-unicode
Throw syntax_error when parser encounter an incorrect utf-8 codepoint
2019-03-17 13:12:16 +09:00
Toru Niina
d86870e038 Merge pull request #38 from ToruNiina/get-any-type
extended conversions
2019-03-17 13:11:59 +09:00
Toru Niina
0908806915 Merge pull request #33 from ToruNiina/is-something
add `is_boolean` and other stuffs like that
2019-03-16 23:55:01 +09:00
ToruNiina
d17c192681 refactor: remove to_toml and related tests 2019-03-16 17:05:58 +09:00
ToruNiina
cad8f51256 doc: add explanation of conversions to README 2019-03-16 16:56:37 +09:00
ToruNiina
43014c6619 fix: remove redefined default template argument 2019-03-16 16:24:10 +09:00
ToruNiina
30a41aa710 fix: use older style in BOOST_TEST 2019-03-16 16:15:01 +09:00
ToruNiina
04bfeba3f2 merge branch master into get-any-type 2019-03-16 15:58:18 +09:00
ToruNiina
190636b791 fix: support getting a container of external types 2019-03-16 15:52:22 +09:00
ToruNiina
31e450f9af test: add test for from/into based conversions 2019-03-16 15:46:21 +09:00
ToruNiina
b1b72a94a8 feat: support conversion with external types 2019-03-16 14:44:04 +09:00
ToruNiina
6929bcdf78 feat: add from<T> and into<T> 2019-03-16 14:27:05 +09:00
ToruNiina
fd063af7ce refactor: make include guard style uniform 2019-03-16 14:19:47 +09:00
ToruNiina
df6dcbc4ed feat: check a class has from/into_toml member fn
to support better serialization
2019-03-16 14:16:31 +09:00
ToruNiina
9b8db6a225 fix: remove extraneous null character after float
the bug was introduced by snprintf
2019-03-15 19:30:36 +09:00
ToruNiina
76863cb27f refactor: simplify branches about utf8 codepoint 2019-03-15 17:48:47 +09:00
ToruNiina
514df99e40 feat: consider invalid UTF-8 as syntax_error
the following codepoints are considered to be a syntax_error
- [0xD800, 0xDFFF]
- larger than 0x10FFFF
2019-03-15 17:39:31 +09:00
ToruNiina
055353a460 chore: merge branch 'master' into is-something 2019-03-15 17:25:17 +09:00
ToruNiina
c4c416e8b2 doc: add is_* function to README 2019-03-12 22:18:25 +09:00
ToruNiina
6693ec78f4 test: add test for toml::value::is_something() 2019-03-12 20:44:27 +09:00
ToruNiina
dc112bd6c1 feat: add is_[boolean|integer|...]() member func
it is an alias to is<toml::value_t::[Boolean|Integer|...]>
2019-03-12 20:43:07 +09:00
296 changed files with 68169 additions and 11501 deletions

View File

@@ -0,0 +1,6 @@
FROM gcr.io/oss-fuzz-base/base-builder
RUN apt-get update && apt-get install -y make autoconf automake libtool
COPY . $SRC/toml11
COPY .clusterfuzzlite/build.sh $SRC/build.sh
WORKDIR $SRC/toml11

View File

@@ -0,0 +1,3 @@
# ClusterFuzzLite set up
This folder contains a fuzzing set for [ClusterFuzzLite](https://google.github.io/clusterfuzzlite).

View File

@@ -0,0 +1,6 @@
#!/bin/bash -eu
# Copy fuzzer executable to $OUT/
$CXX $CFLAGS $LIB_FUZZING_ENGINE \
$SRC/toml11/.clusterfuzzlite/parse_fuzzer.cpp \
-o $OUT/parse_fuzzer \
-I$SRC/toml11/include/

View File

@@ -0,0 +1,10 @@
#include <toml.hpp>
#include <string>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
std::string s(reinterpret_cast<const char *>(data), size);
const auto ref = toml::try_parse_str(s);
return 0;
}

View File

@@ -0,0 +1 @@
language: c++

13
.editorconfig Normal file
View File

@@ -0,0 +1,13 @@
root = true
[*]
indent_style = space
[CMakeLists.txt]
indent_size = 4
[*.{c,h}*]
indent_size = 4
[*.{md,yml}]
indent_size = 2

32
.github/workflows/document.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: document
on:
push:
branches:
- main
jobs:
deploy:
runs-on: Ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
- name: Install Hugo
uses: peaceiris/actions-hugo@v3
with:
hugo-version: 'latest'
extended: true
- name: Build Webpage
working-directory: ./docs/
run: |
hugo --minify
- name: Deploy
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_branch: gh-pages
publish_dir: ./docs/public
force_orphan: true
commit_message: ${{ github.event.head_commit.message }}

30
.github/workflows/fuzzing.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: ClusterFuzzLite fuzzing
on: [push, pull_request]
permissions: read-all
jobs:
fuzzing:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
sanitizer: [address]
steps:
- name: Build Fuzzers (${{ matrix.sanitizer }})
id: build
uses: google/clusterfuzzlite/actions/build_fuzzers@v1
with:
sanitizer: ${{ matrix.sanitizer }}
language: c++
bad-build-check: false
- name: Run Fuzzers (${{ matrix.sanitizer }})
id: run
uses: google/clusterfuzzlite/actions/run_fuzzers@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
fuzz-seconds: 240
mode: 'code-change'
report-unreproducible-crashes: false
sanitizer: ${{ matrix.sanitizer }}

213
.github/workflows/main.yml vendored Normal file
View File

@@ -0,0 +1,213 @@
name: build
on: [push, pull_request]
jobs:
build-linux-gcc:
runs-on: Ubuntu-24.04
strategy:
matrix:
compiler: ['g++-14', 'g++-13', 'g++-12', 'g++-11', 'g++-10', 'g++-9']
standard: ['11', '14', '17', '20']
precompile: ['ON', 'OFF']
betafeature: ['ON', 'OFF']
steps:
- name: Get number of CPU cores
uses: SimenB/github-actions-cpu-cores@v2
id: cpu-cores
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
- name: Install
run: |
sudo apt-get update
sudo apt-get install language-pack-fr # test serializer w/ locale
sudo apt-get install ${{ matrix.compiler }}
- name: Configure
run: |
cmake -B build/ -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_ENABLE_ACCESS_CHECK=${{ matrix.betafeature }}
- name: Build
run: |
cmake --build build/ -j${{ steps.cpu-cores.outputs.count }}
- name: Test
run: |
ctest --output-on-failure --test-dir build/
build-linux-gcc-sanitizers:
runs-on: Ubuntu-24.04
strategy:
matrix:
compiler: ['g++-13']
standard: ['11', '14', '17', '20']
precompile: ['ON', 'OFF']
betafeature: ['ON', 'OFF']
asan: ['ON', 'OFF']
ubsan: ['ON', 'OFF']
exclude:
- asan: 'ON'
ubsan: 'ON'
steps:
- name: Get number of CPU cores
uses: SimenB/github-actions-cpu-cores@v2
id: cpu-cores
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
- name: Install
run: |
sudo apt-get update
sudo apt-get install language-pack-fr # test serializer w/ locale
sudo apt-get install ${{ matrix.compiler }}
- name: Configure
run: |
cmake -B build/ -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_ENABLE_ACCESS_CHECK=${{ matrix.betafeature }} -DTOML11_TEST_WITH_ASAN=${{ matrix.asan }} -DTOML11_TEST_WITH_UBSAN=${{ matrix.ubsan }}
- name: Build
run: |
cmake --build build/ -j${{ steps.cpu-cores.outputs.count }}
- name: Test
run: |
ctest --output-on-failure --test-dir build/
build-linux-clang:
runs-on: Ubuntu-24.04
strategy:
matrix:
compiler: ['19', '18', '17', '16']
standard: ['11', '14', '17', '20']
precompile: ['ON', 'OFF']
steps:
- name: Get number of CPU cores
uses: SimenB/github-actions-cpu-cores@v2
id: cpu-cores
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
- name: Install
run: |
sudo apt-get update
sudo apt-get install language-pack-fr # test serializer w/ locale
sudo apt-get install clang-${{ matrix.compiler }}
- name: Configure
run: |
cmake -B build/ -DCMAKE_CXX_COMPILER=clang++-${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }}
- name: Build
run: |
cmake --build build/ -j${{ steps.cpu-cores.outputs.count }}
- name: Test
run: |
ctest --output-on-failure --test-dir build/
build-linux-old-clang:
runs-on: Ubuntu-22.04
strategy:
matrix:
compiler: ['15', '14', '13', '12', '11']
standard: ['11', '14', '17', '20']
precompile: ['ON', 'OFF']
exclude:
- {compiler: '14', standard: '20'}
- {compiler: '13', standard: '20'}
- {compiler: '12', standard: '20'}
- {compiler: '11', standard: '20'}
steps:
- name: Get number of CPU cores
uses: SimenB/github-actions-cpu-cores@v2
id: cpu-cores
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
- name: Install
run: |
sudo apt-get update
sudo apt-get install language-pack-fr # test serializer w/ locale
sudo apt-get install clang-${{ matrix.compiler }}
- name: Configure
run: |
cmake -B build/ -DCMAKE_CXX_COMPILER=clang++-${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }}
- name: Build
run: |
cmake --build build/ -j${{ steps.cpu-cores.outputs.count }}
- name: Test
run: |
ctest --output-on-failure --test-dir build/
build-osx-14:
runs-on: macos-14
strategy:
matrix:
standard: ['11', '14', '17', '20']
precompile: ['ON', 'OFF']
betafeature: ['ON', 'OFF']
steps:
- name: Get number of CPU cores
uses: SimenB/github-actions-cpu-cores@v2
id: cpu-cores
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
- name: Configure
run: |
cmake -B build/ -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_ENABLE_ACCESS_CHECK=${{ matrix.betafeature }}
- name: Build
run: |
cmake --build build/ -j${{ steps.cpu-cores.outputs.count }}
- name: Test
run: |
ctest --output-on-failure --test-dir build/
build-osx-13:
runs-on: macos-13
strategy:
matrix:
standard: ['11', '14', '17', '20']
precompile: ['ON', 'OFF']
steps:
- name: Get number of CPU cores
uses: SimenB/github-actions-cpu-cores@v2
id: cpu-cores
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
- name: Configure
run: |
cmake -B build/ -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }}
- name: Build
run: |
cmake --build build/ -j${{ steps.cpu-cores.outputs.count }}
- name: Test
run: |
ctest --output-on-failure --test-dir build/
build-windows-msvc:
runs-on: windows-2022
strategy:
matrix:
standard: ['11', '14', '17', '20']
config: ['Release', 'Debug']
precompile: ['ON', 'OFF']
betafeature: ['ON', 'OFF']
steps:
- name: Get number of CPU cores
uses: SimenB/github-actions-cpu-cores@v2
id: cpu-cores
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
- uses: ilammy/msvc-dev-cmd@v1
- name: Configure
shell: cmd
run: |
cmake -B build/ -G "NMake Makefiles" -DTOML11_BUILD_TESTS=ON -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_ENABLE_ACCESS_CHECK=${{ matrix.betafeature }}
- name: Build
run: |
cmake --build ./build --config "${{ matrix.config }}" -j${{ steps.cpu-cores.outputs.count }}
- name: Test
run: |
ctest --build-config "${{ matrix.config }}" --test-dir build/ --output-on-failure

33
.github/workflows/single-include.yml vendored Normal file
View File

@@ -0,0 +1,33 @@
name: gen-singlue-include
on:
push:
branches:
- main
jobs:
generate:
runs-on: Ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build
run: |
g++-12 -std=c++20 -O2 tools/expand/main.cpp -o expand
./expand include/toml.hpp > single_include.hpp
- name: Check diff
id: check-diff
continue-on-error: true
run: |
diff single_include.hpp single_include/toml.hpp
- name: Commit and Push
if: steps.check-diff.outcome == 'failure'
run: |
mv single_include.hpp single_include/toml.hpp
git config --global user.name "ToruNiina"
git config --global user.email "ToruNiina@users.noreply.github.com"
git add single_include/toml.hpp
git commit -m "feat [skip ci]: update single_include"
git push origin main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

41
.github/workflows/toml-test.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: toml-test
on: [push, pull_request]
jobs:
toml-test:
runs-on: Ubuntu-22.04
strategy:
matrix:
compiler: ['g++-12']
standard: ['11', '14', '17', '20']
asan: ['ON', 'OFF']
ubsan: ['ON', 'OFF']
exclude:
- asan: 'ON'
ubsan: 'ON'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
- name: Install
run: |
sudo apt update
sudo apt install -y ${{ matrix.compiler }}
- name: Setup Go
uses: actions/setup-go@v5
- name: Configure
run: |
cmake -B build/ -DBUILD_TESTING=OFF -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TOML_TESTS=ON -DTOML11_TEST_WITH_ASAN=${{ matrix.asan }} -DTOML11_TEST_WITH_UBSAN=${{ matrix.ubsan }}
- name: Build
run: |
cmake --build build/
- name: Test
run: |
go install github.com/toml-lang/toml-test/cmd/toml-test@latest
toml-test ./build/tests/toml11_decoder
# skipped tests does not conform the latest commit in toml-lang/toml
toml-test -toml 1.1.0 ./build/tests/toml11_decoder_v1_1_0 -skip invalid/control/comment-del,invalid/control/comment-lf,invalid/control/comment-us
toml-test -encoder ./build/tests/toml11_encoder

3
.gitignore vendored
View File

@@ -1 +1,4 @@
build/*
.cache/*
.clangd/*
compile_commands.json

9
.gitmodules vendored Normal file
View File

@@ -0,0 +1,9 @@
[submodule "tests/extlib/doctest"]
path = tests/extlib/doctest
url = https://github.com/doctest/doctest.git
[submodule "tests/extlib/json"]
path = tests/extlib/json
url = https://github.com/nlohmann/json.git
[submodule "docs/themes/hugo-book"]
path = docs/themes/hugo-book
url = https://github.com/alex-shpak/hugo-book.git

View File

@@ -1,131 +0,0 @@
dist: trusty
matrix:
include:
- os: linux
language: cpp
compiler: gcc
env: COMPILER="g++-5"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-5
- libboost-all-dev
- os: linux
language: cpp
compiler: gcc
env: COMPILER="g++-6"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-6
- libboost-all-dev
- os: linux
language: cpp
compiler: gcc
env: COMPILER="g++-7"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-7
- libboost-all-dev
- os: linux
language: cpp
compiler: gcc
env: COMPILER="g++-8"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-8
- libboost-all-dev
- os: linux
language: cpp
compiler: clang
env: COMPILER="clang++-3.7"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
packages:
- clang-3.7
- libboost-all-dev
- os: linux
language: cpp
compiler: clang
env: COMPILER="clang++-4.0"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
packages:
- clang-4.0
- libboost-all-dev
- os: linux
language: cpp
compiler: clang
env: COMPILER="clang++-5.0"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
packages:
- clang-5.0
- libboost-all-dev
- os: linux
language: cpp
compiler: clang
env: COMPILER="clang++-6.0"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-6.0
packages:
- clang-6.0
- libboost-all-dev
- os: linux
language: cpp
compiler: clang
env: COMPILER="clang++-7"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-7
packages:
- clang-7
- libboost-all-dev
- os: linux
language: cpp
compiler: clang
env: COMPILER="clang++-8"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-8
packages:
- clang-8
- libboost-all-dev
- os: osx
language: cpp
compiler: clang
script:
- mkdir build
- cd build
- git clone https://github.com/toml-lang/toml.git
- cmake -DCMAKE_CXX_COMPILER=$COMPILER ..
- make
- ctest --output-on-failure

View File

@@ -1,35 +1,89 @@
cmake_minimum_required(VERSION 2.8)
enable_testing()
project(toml11)
cmake_minimum_required(VERSION 3.16)
# project_source_dir has not been set yet
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/toml11/version.hpp" TOML11_MAJOR_VERSION_STRING
REGEX "#define TOML11_VERSION_MAJOR ([0-9]+)")
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/toml11/version.hpp" TOML11_MINOR_VERSION_STRING
REGEX "#define TOML11_VERSION_MINOR ([0-9]+)")
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/toml11/version.hpp" TOML11_PATCH_VERSION_STRING
REGEX "#define TOML11_VERSION_PATCH ([0-9]+)")
string(REGEX REPLACE "#define TOML11_VERSION_MAJOR ([0-9]+)" "\\1" TOML11_VERSION_MAJOR "${TOML11_MAJOR_VERSION_STRING}")
string(REGEX REPLACE "#define TOML11_VERSION_MINOR ([0-9]+)" "\\1" TOML11_VERSION_MINOR "${TOML11_MINOR_VERSION_STRING}")
string(REGEX REPLACE "#define TOML11_VERSION_PATCH ([0-9]+)" "\\1" TOML11_VERSION_PATCH "${TOML11_PATCH_VERSION_STRING}")
project(toml11 LANGUAGES CXX VERSION "${TOML11_VERSION_MAJOR}.${TOML11_VERSION_MINOR}.${TOML11_VERSION_PATCH}")
include(CTest) # to use ${BUILD_TESTING}
option(TOML11_PRECOMPILE "precompile toml11 library" OFF)
option(TOML11_ENABLE_ACCESS_CHECK "enable access check feature (beta)" OFF)
include(CMakeDependentOption)
cmake_policy(PUSH)
if(POLICY CMP0127)
cmake_policy(SET CMP0127 OLD) # syntax of condition changed in 3.22
endif()
cmake_dependent_option(TOML11_INSTALL "install toml11 library" ON
"${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME}" OFF)
cmake_dependent_option(TOML11_BUILD_EXAMPLES "build toml11 examples" OFF
"${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME}" OFF)
cmake_dependent_option(TOML11_BUILD_TESTS "build toml11 unit tests" OFF
"${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME}; ${BUILD_TESTING}" OFF)
cmake_dependent_option(TOML11_BUILD_TOML_TESTS "build toml11 toml-test encoder & decoder" OFF
"${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME}" OFF)
cmake_policy(POP)
cmake_dependent_option(TOML11_TEST_WITH_ASAN "build toml11 unit tests with asan" OFF
"${TOML11_BUILD_TESTS}" OFF)
cmake_dependent_option(TOML11_TEST_WITH_UBSAN "build toml11 unit tests with ubsan" OFF
"${TOML11_BUILD_TESTS}" OFF)
if(${TOML11_TEST_WITH_ASAN} AND ${TOML11_TEST_WITH_UBSAN})
message(FATAL_ERROR "trying to build tests with BOTH asan and ubsan")
endif()
include(CheckCXXCompilerFlag)
if("${CMAKE_VERSION}" VERSION_GREATER 3.1)
set(CMAKE_CXX_STANDARD 11)
set(CXX_STANDARD_REQUIRED ON)
else()
# Manually check for C++11 compiler flag.
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
CHECK_CXX_COMPILER_FLAG("-std=gnu++11" COMPILER_SUPPORTS_GNU11)
CHECK_CXX_COMPILER_FLAG("-std=gnu++0x" COMPILER_SUPPORTS_GNU0X)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXXOX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
elseif(COMPILER_SUPPORTS_GNU11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
elseif(COMPILER_SUPPORTS_GNU0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")
else()
if(MSVC)
if(MSVC_VERSION LESS 1900)
message(SEND_ERROR "MSVC < 14.0 is not supported. Please update your compiler or use mingw")
endif()
else()
message(SEND_ERROR "The ${CMAKE_CXX_COMPILER} compiler lacks C++11 support. Use another compiler.")
endif()
check_cxx_compiler_flag("-Wall" TOML11_COMPILER_SUPPORTS_WALL)
check_cxx_compiler_flag("-Wextra" TOML11_COMPILER_SUPPORTS_WEXTRA)
check_cxx_compiler_flag("-Wpedantic" TOML11_COMPILER_SUPPORTS_WPEDANTIC)
check_cxx_compiler_flag("-Werror" TOML11_COMPILER_SUPPORTS_WERROR)
check_cxx_compiler_flag("-Wsign-conversion" TOML11_COMPILER_SUPPORTS_WSIGN_CONVERSION)
check_cxx_compiler_flag("-Wconversion" TOML11_COMPILER_SUPPORTS_WCONVERSION)
check_cxx_compiler_flag("-Wduplicated-cond" TOML11_COMPILER_SUPPORTS_WDUPLICATED_COND)
check_cxx_compiler_flag("-Wduplicated-branches" TOML11_COMPILER_SUPPORTS_WDUPLICATED_BRANCHES)
check_cxx_compiler_flag("-Wlogical-op" TOML11_COMPILER_SUPPORTS_WLOGICAL_OP)
check_cxx_compiler_flag("-Wdouble-promotion" TOML11_COMPILER_SUPPORTS_WDOUBLE_PROMOTION)
check_cxx_compiler_flag("-Wrange-loop-analysis" TOML11_COMPILER_SUPPORTS_WRANGE_LOOP_ANALYSIS)
check_cxx_compiler_flag("-Wundef" TOML11_COMPILER_SUPPORTS_WUNDEF)
check_cxx_compiler_flag("-Wshadow" TOML11_COMPILER_SUPPORTS_WSHADOW)
include(GNUInstallDirs)
set(TOML11_INSTALL_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/toml11)
set(TOML11_INSTALL_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR})
set(TOML11_CONFIG_DIR ${CMAKE_CURRENT_BINARY_DIR}/cmake)
set(TOML11_CONFIG ${TOML11_CONFIG_DIR}/toml11Config.cmake)
set(TOML11_CONFIG_VERSION ${TOML11_CONFIG_DIR}/toml11ConfigVersion.cmake)
# root project?
if(${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME})
if(NOT DEFINED CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 11)
endif()
if(NOT DEFINED CMAKE_CXX_EXTENSIONS)
set(CMAKE_CXX_EXTENSIONS OFF)
endif()
if(NOT DEFINED CMAKE_CXX_STANDARD_REQUIRED)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
endif()
if(${TOML11_BUILD_TESTS} OR ${TOML11_BUILD_TOML_TESTS})
add_subdirectory(tests)
endif()
if(${TOML11_BUILD_EXAMPLES})
add_subdirectory(examples)
endif()
endif()
include_directories(${PROJECT_SOURCE_DIR})
add_subdirectory(tests)
add_subdirectory(src)

1111
README.md

File diff suppressed because it is too large Load Diff

710
README_ja.md Normal file
View File

@@ -0,0 +1,710 @@
# toml11 v4
[![Build Status on GitHub Actions](https://github.com/ToruNiina/toml11/workflows/build/badge.svg)](https://github.com/ToruNiina/toml11/actions)
[![Version](https://img.shields.io/github/release/ToruNiina/toml11.svg?style=flat)](https://github.com/ToruNiina/toml11/releases)
[![License](https://img.shields.io/github/license/ToruNiina/toml11.svg?style=flat)](LICENSE)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.1209136.svg)](https://doi.org/10.5281/zenodo.1209136)
toml11は、C++11,14,17,20のための豊富な機能を持つTOML言語ライブラリです。
- [TOML言語の最新規格](https://toml.io/ja/v1.0.0)に準拠しています。
- TOML言語標準のテストケースすべてにパスしています。
- TOML言語の次期バージョン (v1.1.0) にマージされた新機能のそれぞれを試すことができます。
- エラーが起きた位置を含めたわかりやすいエラーメッセージを出力します。
- コメントもパースし、対応する値に保存します。
- 16進整数やクオートの種類などのフォーマット情報を保持し、シリアライズ時に考慮します。
- 例外を投げないバージョンをサポートします。
- TOML値からの複雑な型変換をサポートします。
- 整数、浮動小数点数、コンテナ等の型を変更可能です。
- TOML言語にない一部の拡張機能を試すことができます。
## Example
```toml
# example.toml
title = "an example toml file"
nums = [3, 1, 4, 1, 5] # pi!
```
```cpp
#include <toml.hpp>
#include <iostream>
// ```toml
// title = "an example toml file"
// nums = [3, 1, 4, 1, 5] # pi!
// ```
int main()
{
// select TOML version at runtime (optional)
auto data = toml::parse("example.toml", toml::spec::v(1,1,0));
// find a value with the specified type from a table
std::string title = toml::find<std::string>(data, "title");
// convert the whole array into STL-like container automatically
std::vector<int> nums = toml::find<std::vector<int>>(data, "nums");
// access with STL-like manner
if( ! data.contains("foo"))
{
data["foo"] = "bar";
}
if(data.at("nums").is_array())
{
data.push_back(9);
}
// check comments
assert(data.at("nums").comments().at(0) == "# pi!");
// pass a fallback
std::string name = toml::find_or<std::string>(data, "name", "not found");
// serialization considering format info
data.at("nums").as_array_fmt().fmt = toml::array_format::multiline;
data.at("nums").as_array_fmt().indent_type = toml::indent_char::space;
data.at("nums").as_array_fmt().body_indent = 2;
std::cout << toml::format(data) << std::endl;
return 0;
}
```
詳細な機能とリファレンスに関しては、[ドキュメント](https://toruniina.github.io/toml11/ja/)を参照してください。
## Table of Contents
- [toml11](#toml11)
- [Example](#example)
- [Table of Contents](#table-of-contents)
- [Integration](#integration)
- [Single Include File](#single-include-file)
- [git submodule](#git-submodule)
- [CMake `FetchContent`](#cmake-fetchcontent)
- [CMake Package Manager (CPM)](#cmake-package-manager-cpm)
- [Install Using CMake](#install-using-cmake)
- [Precompile Library](#precompile-library)
- [Building Example](#building-example)
- [Building Tests](#building-tests)
- [Features](#features)
- [Parsing a File](#parsing-a-file)
- [finding a value](#finding-a-value)
- [comments](#comments)
- [error messages](#error-messages)
- [serialization](#serialization)
- [Configuring Types](#configuring-types)
- [Examples](#examples)
- [Changes from v3](#changes-from-v3)
- [Breaking Changes](#breaking-changes)
- [Added features](#added-features)
- [Contributors](#contributors)
- [Licensing terms](#licensing-terms)
## Integration
toml11を使うには複数の方法があります。
ここではそれぞれを短く紹介します。詳細は、[ドキュメント](https://toruniina.github.io/toml11/ja/docs/installation/)を参照してください。
### Single include file
`single_include/toml.hpp`を好きなところにコピーして、インクルードパスを通してください。
### git submodule
git submoduleなどでサブディレクトリにすれば、`toml11/include`にインクルードパスを通すか、
`add_subdirectory(toml11)` とすることで使用できます。
### CMake `FetchContent`
CMakeの `FetchContent`を使用することで、`build`ディレクトリに自動でダウンロードすることができます。
```cmake
include(FetchContent)
FetchContent_Declare(
toml11
GIT_REPOSITORY https://github.com/ToruNiina/toml11.git
GIT_TAG v4.4.0
)
FetchContent_MakeAvailable(toml11)
add_executable(main main.cpp)
target_link_libraries(main PRIVATE toml11::toml11)
```
### CMake Package Manager (CPM)
[CMake package manager](https://github.com/cpm-cmake/CPM.cmake)を導入すると、以下のようにして使用することができます。
```cmake
include(cmake/CPM.cmake)
CPMAddPackage("gh:ToruNiina/toml11@4.4.0")
# OR
CPMAddPackage(
NAME toml11
GITHUB_REPOSITORY "ToruNiina/toml11"
VERSION 4.4.0
OPTIONS
"TOML11_PRECOMPILE ON" # to pre-compile
"TOML11_ENABLE_ACCESS_CHECK ON" # to use value.accessed()
)
add_executable(main main.cpp)
target_link_libraries(main PUBLIC toml11::toml11)
```
### Install using CMake
以下の手順で、CMakeを使ってインストールすることができます。
```console
$ git clone https://github.com/ToruNiina/toml11
$ cd toml11
$ git submodule update --init --recursive
$ cmake -B ./build/
$ cmake --build ./build/
$ cmake --install ./build --prefix /path/to/toml11
```
### Precompile library
`-DTOML11_PRECOMPILE=ON` とすることで、ライブラリの一部の関数をコンパイルできます。
この場合、C++バージョンによって使用できる標準ライブラリ機能が変化し、
インターフェースの一部が変わるため、`CMAKE_CXX_STANDARD`を指定する必要があります。
```console
$ cmake -B ./build/ -DTOML11_PRECOMPILE=ON -DCMAKE_CXX_STANDARD=11/14/17/20
$ cmake --build ./build/
```
ライブラリをリンクする場合は、CMakeで
```cmake
target_link_libraries(your_target PUBLIC toml11::toml11)
```
とするか、コンパイラに`-DTOML11_COMPILE_SOURCES`を渡してください。
### Building example
`-DTOML11_BUILD_EXAMPLES=ON`とすることで、`examples/`をコンパイルできます。
```console
$ cmake -B ./build/ -DTOML11_BUILD_EXAMPLES=ON
$ cmake --build ./build/
```
### Building Tests
`-DTOML11_BUILD_TESTS=ON`とすることで、ユニットテストをコンパイルできます。
また、`-DTOML11_BUILD_TOML_TESTS=ON`とすることで、toml-test用の`encoder``decoder`をコンパイルできます。
```console
$ cmake -B ./build/ -DTOML11_BUILD_EXAMPLES=ON
$ cmake --build ./build/
```
## Features
ここでは、toml11の持つ機能を短く紹介します。
詳細については[ドキュメント](https://toruniina.github.io/toml11/ja/docs/features/)を参照してください。
### parsing a file
ファイルをパースする場合は、`toml::parse`を使います。
ファイル全体の型は常にテーブルですが、 `toml::value` はコメントや
フォーマット情報などのメタデータを持つので、`toml::parse`からは
`toml::table` ではなく `toml::value` が返ります。
```cpp
const toml::value input = toml::parse("input.toml");
```
文字列そのものをパースする場合は、`toml::parse_str`を使います。
```cpp
const toml::value input = toml::parse_str("a = 42");
```
文字列リテラルをパースする際は、`""_toml`リテラルを使うことができます。
```cpp
using namespace toml::literals::toml_literals;
const toml::value lit = "a = 42"_toml;
```
`toml::parse``parse_str`は文法エラーの際に `toml::syntax_error` 例外を投げます。
`what()`で得られるエラーメッセージは以下のようになります。
```
[error] bad integer: `_` must be surrounded by digits
--> internal string at line 64 in file main.cpp
|
1 | a = 123__456
| ^-- invalid underscore
Hint: valid : -42, 1_000, 1_2_3_4_5, 0xC0FFEE, 0b0010, 0o755
Hint: invalid: _42, 1__000, 0123
```
エラーメッセージには`toml::color::enable()`を呼ぶことで色を付けることも可能です。
`toml::try_parse`を使うことで、例外を投げずに `toml::result<toml::value, std::vector<toml::error_info>>` を受け取ることができます。
```cpp
const auto input = toml::try_parse("input.toml");
if(input.is_ok())
{
std::cout << input.unwrap().at("a").as_integer() << std::endl;
}
```
また、使用するTOML言語のバージョンを簡単に、かつ細かく変更できるようになりました。
TOML v1.0.0に加えて、v1.1.0の新機能を一部だけ使用するというような制御が可能です。
```cpp
toml::spec s = toml::spec::v(1, 0, 0);
s.v1_1_0_allow_trailing_comma_in_inline_tables = true;
const toml::value input = toml::parse("input.toml");
```
また、TOML言語自体に含まれない言語拡張もいくつか用意しています。
```cpp
toml::spec s = toml::spec::v(1, 0, 0);
s.ext_hex_float = true; // 16進数浮動小数点数を許可
s.ext_null_value = true; // 空の値 `null` を許可
s.ext_num_suffix = true; // `100_msec`などのsuffixを許可
```
各機能の紹介とリファレンスは、[ドキュメント](https://toruniina.github.io/toml11/ja/docs/features/)を参照してください。
### finding a value
`toml::value` はアクセス用のメンバ関数、`at()``is_xxx()`, `as_xxx()` を持ちます。
```cpp
const toml::value input = toml::parse("input.toml");
if(input.contains("a") && input.at("a").is_integer())
{
std::cout << input.at("a").as_integer() << std::endl;
}
```
`toml::find` を使うことで、型変換と検索を同時に行うことができます。
```cpp
const toml::value input = toml::parse("input.toml");
std::cout << toml::find<std::string>(input, "a") << std::endl;
```
型変換や値の検索に失敗した場合は、`toml::type_error`が送出されます。
その場合のエラーメッセージは以下のようになります。
```
[error] toml::value::as_string(): bad_cast to string
--> input.toml
|
1 | a = 123_456
| ^^^^^^^-- the actual type is integer
```
ネストされたテーブルやテーブルの配列にも同じ方法でアクセスできます。
```cpp
// [a]
// b = [
// {c = 42},
// {c = 54}
// ]
const toml::value input = toml::parse("input.toml");
std::cout << toml::find<int>(input, "a", "b", 1, "c") << std::endl;
```
ほとんどのSTLコンテナや、同様のインターフェースを持つコンテナへ変換が可能です。
```cpp
// array = [3,1,4,1,5]
const toml::value input = toml::parse("input.toml");
const auto a1 = toml::find<std::vector<int> >(input, "array") << std::endl;
const auto a2 = toml::find<std::array<int, 5>>(input, "array") << std::endl;
const auto a3 = toml::find<std::deque<int> >(input, "array") << std::endl;
const auto a4 = toml::find<boost::container::small_vector<int, 8>>(input, "array") << std::endl;
```
また、複雑なTOML値に対して、高度な型変換を行うことができます。
```toml
mixed_array = [
42,
3.14,
{a = "foo", b = "bar"}
]
```
```cpp
const toml::value input = toml::parse("input.toml");
const auto mixed = toml::find<
std::tuple<int, double, std::map<std::string, std::string>>
>(input, "mixed_array") << std::endl;
```
マクロの使用または特定の関数を定義することで、ユーザー定義型にも変換が可能です。
```cpp
namespace extlib
{
struct foo
{
int a;
std::string b;
};
} // extlib
TOML11_DEFINE_CONVERSION_NON_INTRUSIVE(extlib::foo, a, b)
// ...
const auto input = R"(
[foo]
a = 42
b = "bar"
)"_toml;
const extlib::foo f = toml::find<extlib::foo>(input, "foo");
```
`toml::find_or`を使うことで、失敗時にデフォルト値を得ることができます。
```cpp
const toml::value input = toml::parse("input.toml");
std::cout << toml::find_or(input, "a", 6*9) << std::endl;
```
詳細については[ドキュメント](https://toruniina.github.io/toml11/ja/docs/features/value/)を参照してください。
### comments
toml11は、値に関するコメントを値に保存します。
値に関するコメントとは、ある値の直前に書かれた一連のコメントと、値の直後に改行を挟まず書かれたコメントです。
```toml
# これは a のコメントです。
# これも a のコメントです。
a = 42 # これも a のコメントです。
# これは改行で分かれているので、 b のコメントではありません。
# これは b のコメントです。
b = "foo"
```
これは `std::vector<std::string>` と同じインターフェースで `toml::value` に格納されます。
```cpp
const toml::value input = toml::parse("input.toml");
std::cout << input.at("a").comments().size() << std::endl;
std::cout << input.at("a").comments().at(0) << std::endl;
```
詳細については[ドキュメント](https://toruniina.github.io/toml11/ja/docs/features/value/#%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%99%E3%82%8B)を参照してください。
### error messages
toml11の目標の一つは、わかりやすいエラーメッセージを出力することです。
パースエラーに対しては以下のようなエラーメッセージが、
```
[error] bad integer: `_` must be surrounded by digits
--> internal string at line 64 in file main.cpp
|
1 | a = 123__456
| ^-- invalid underscore
Hint: valid : -42, 1_000, 1_2_3_4_5, 0xC0FFEE, 0b0010, 0o755
Hint: invalid: _42, 1__000, 0123
```
実際に格納されている型と異なる型を要求した場合には以下のようなエラーメッセージが表示されます。
```
[error] toml::value::as_string(): bad_cast to string
--> input.toml
|
1 | a = 123_456
| ^^^^^^^-- the actual type is integer
```
このようなエラーメッセージを、TOMLの文法とは関係のないユーザー特有の処理に対しても出力することが可能です。
```cpp
const toml::value& a = input.at("a");
if(a.as_integer() < 0)
{
const toml::error_info err = toml::make_error_info(
"positive integer is required",
a, "but got negative value"
);
std::cerr << toml::format_error(err) << std::endl;
}
```
詳細は[ドキュメント](https://toruniina.github.io/toml11/ja/docs/features/error_message/)を参照してください。
### serialization
`toml::format` を使うことで、`toml::value``std::string` にフォーマットできます。
```cpp
const toml::value input = toml::parse("input.toml");
std::cout << toml::format(input) << std::endl;
```
`toml::format` はフォーマット情報を参照します。
なので、フォーマット方法を変更することが可能です。
```cpp
toml::value output(toml::table{ {"a", 0xDEADBEEF} });
output.at("a").as_integer_fmt().fmt = toml::integer_format::hex;
output.at("a").as_integer_fmt().spacer = 4;
std::cout << toml::format(output) << std::endl;
// a = 0xdead_beef
```
テーブルや配列のフォーマットも指定が可能です。
```cpp
toml::value output(toml::table{
{"array-of-tables", toml::array{}},
{"subtable", toml::table{}},
});
auto& aot = output.at("array-of-tables");
aot.as_array_fmt().fmt = toml::array_format::multiline;
aot.as_array_fmt().body_indent = 4;
aot.as_array_fmt().closing_indent = 2;
toml::value v1(toml::table{ {"a", 42}, {"b", 3.14} });
v1.as_table_fmt().fmt = toml::table_format::oneline;
aot.push_back(std::move(v1));
toml::value v2(toml::table{ {"a", 42}, {"b", 3.14} });
v2.as_table_fmt().fmt = toml::table_format::oneline;
aot.push_back(std::move(v2));
output.at("subtable").as_table_fmt().fmt = toml::table_format::dotted;
output.at("subtable")["a"] = 42;
output.at("subtable")["b"] = 3.14;
std::cout << toml::format(output) << std::endl;
// subtable.b = 3.14
// subtable.a = 42
// array-of-tables = [
// {b = 3.14, a = 42},
// {b = 2.71, a = 54},
// ]
```
これらの設定はパース時に読み取られ、値を変更した際も型が変わらない限り維持されます。
どのような指定が可能かなどの詳細は[ドキュメント](https://toruniina.github.io/toml11/ja/docs/features/serialize/)を参照してください。
### configuring types
`toml::value`が持つ型の多く、`integer_type``array_type`などは`type_config`型を変更することで変更可能です。
よくある例として、値を追加した順序を保つ`map`型である`ordered_map`を使うというものがあります。
toml11は`toml::ordered_map`を使用する`type_config`型として、`toml::ordered_type_config`を提供しています。
```cpp
const toml::ordered_value input = toml::parse<toml::ordered_type_config>("input.toml");
```
ここで、`toml::ordered_value``toml::basic_value<toml::ordered_type_config>`のエイリアスです。
ただし、`toml::value``std::unordered_map`を使用しているため、一度`toml::ordered_value`から`toml::value`に変換してしまうと、順序は失われてしまうことに注意してください。
[`examples`ディレクトリ](https://github.com/ToruNiina/toml11/tree/main/examples)には、
多倍長整数を使用する場合やコンテナを変更する場合、ユニコードを正規化する場合などの複雑な使用例を用意しています。
`type_config`を実装する際の例として参照してください。
## Examples
[`examples`ディレクトリ](https://github.com/ToruNiina/toml11/tree/main/examples)では、
型の設定の他にも実装例を紹介しています。
- [boost_container](https://github.com/ToruNiina/toml11/tree/main/examples/boost_container)
- `array_type``table_type``boost::container`のコンテナを使う例です。
- [boost_multiprecision](https://github.com/ToruNiina/toml11/tree/main/examples/boost_multiprecision)
- `integer_type``floating_type``boost::multiprecision`の多倍長数値型を使う例です。
- [parse_file](https://github.com/ToruNiina/toml11/tree/main/examples/parse_file)
- 少し複雑な場合も含めた、型変換の実装例です。対応するTOMLファイルが同梱されています。
- [reflect](https://github.com/ToruNiina/toml11/tree/main/examples/reflect)
- boost-ext/reflectを用いたユーザー定義型との自型変換の例です。
- [unicode](https://github.com/ToruNiina/toml11/tree/main/examples/unicode)
- uni-algoを用いて、キーを検索する際にユニコード文字列を正規化する例です。
## Changes from v3
toml11 v3からは複数の破壊的変更が追加されています。
シンプルな使い方をしている場合にはほとんど変更せずに済むように努力はしていますが、
高度な機能を利用していた場合は多少の変更が必要になります。
しかし、追加された機能や整理された機能は、その分の利便性を提供できると考えています。
### 破壊的な変更
- ブランチを `master` から `main` に変更
- `toml::basic_value``template` 引数を変更
- フォーマット情報を陽に格納するため`toml::string` を廃止
- フォーマット情報を使用するため`toml::format`の引数を変更
- TOMLバージョン情報を格納する`toml::spec`を追加するため`toml::parse`のデフォルト引数を変更
- `toml::source_location` のインターフェースを複数行を前提とした形に変更
- `toml::format_error` の引数を変更
- `toml::format_underline` の名称を `toml::format_location` に変更
- `toml::color` の制御方法を `toml::color::enable()`に統一
### 破壊的でない変更
- `toml::parse_str`の追加
- `toml::try_parse`の追加
- バイト列のパースをサポート
- `toml::value` にフォーマット情報を追加
- コメントをデフォルトで保存するよう変更
- `single_include/toml.hpp`の追加
- コンパイル済みライブラリとしての使用を可能に
## Contributors
このライブラリに新機能を追加、あるいはバグを修正してくださったコントリビュータの方々に感謝します。
- Guillaume Fraux (@Luthaf)
- Windows support and CI on Appvayor
- Intel Compiler support
- Quentin Khan (@xaxousis)
- Found & Fixed a bug around ODR
- Improved error messages for invalid keys to show the location where the parser fails
- Petr Beneš (@wbenny)
- Fixed warnings on MSVC
- Ivan Shynkarenka (@chronoxor)
- Fixed Visual Studio 2019 warnings
- Fix compilation error in `<filesystem>` with MinGW
- Khoi Dinh Trinh (@khoitd1997)
- Fixed warnings while type conversion
- @KerstinKeller
- Added installation script to CMake
- J.C. Moyer (@jcmoyer)
- Fixed an example code in the documentation
- Jt Freeman (@blockparty-sh)
- Fixed feature test macro around `localtime_s`
- Suppress warnings in Debug mode
- OGAWA Kenichi (@kenichiice)
- Suppress warnings on intel compiler
- Fix include path in README
- Jordan Williams (@jwillikers)
- Fixed clang range-loop-analysis warnings
- Fixed feature test macro to suppress -Wundef
- Use cache variables in CMakeLists.txt
- Automate test set fetching, update and refactor CMakeLists.txt
- Scott McCaskill
- Parse 9 digits (nanoseconds) of fractional seconds in a `local_time`
- Shu Wang (@halfelf)
- fix "Finding a value in an array" example in README
- @maass-tv and @SeverinLeonhardt
- Fix MSVC warning C4866
- Mohammed Alyousef (@MoAlyousef)
- Made testing optional in CMake
- Alex Merry (@amerry)
- Add missing include files
- sneakypete81 (@sneakypete81)
- Fix typo in error message
- Oliver Kahrmann (@founderio)
- Fix missing filename in error message if parsed file is empty
- Karl Nilsson (@karl-nilsson)
- Fix many spelling errors
- ohdarling88 (@ohdarling)
- Fix a bug in a constructor of serializer
- estshorter (@estshorter)
- Fix MSVC warning C26478
- Philip Top (@phlptp)
- Improve checking standard library feature availability check
- Louis Marascio (@marascio)
- Fix free-nonheap-object warning
- Axel Huebl (@ax3l)
- Make installation optional if the library is embedded
- Ken Matsui (@ken-matsui)
- Support user-defined error message prefix
- Support dynamic color mode
- Giel van Schijndel (@muggenhor)
- Remove needless copy in `parse` function
- Lukáš Hrázký (@lukash)
- Add a `parse(FILE *)` interface and improve file-related error messages
- spiderman idog (@spiderman-idog)
- Fix typo in README
- Jajauma's GitHub (@Jajauma)
- Avoid possible lexer truncation warnings
- Moritz Klammler (@ctcmkl)
- Many patches in (#200) including:
- Improve CMake scripts, build process, and test file handling
- Detect error when `discard_comments` is accessed
- And more.
- Chris White (@cxw42)
- Fix address-sanitizer error when parsing literal strings having invalid UTF-8 characters
- Fix function name in error messages
- offa (@offa)
- Update checkout action to v3
- Update Required CMake version
- Cleanup old CI settings
- Sergey Vidyuk (@VestniK)
- Fix for case when vector iterator is raw pointer
- Kfir Gollan (@kfirgollan)
- Add installation example with checkinstall and cmake
- Martin Tournoij (@arp242)
- Escape control characters in keys
- @DavidKorczynski
- Add fuzzing test based on ClusterFuzzLite
- Esonhugh Skyworship (@Esonhugh)
- Fix function signature of `strerror_r` on macos
- Alberto (@0X1A)
- Fix issues with CMake package configuration when used with vcpkg
- Egor Pugin (@egorpugin)
- Fix incorrect operator<<() argument type that gives build error
- Andreas Keller (@andreaskeller96)
- Fix not checking for \r\n when parsing line comments
- 萧迩珀 (@CDK6182CHR)
- Support template into_toml members
- Pino Toscano (@pinotree)
- Suppress warnings by manually cast file size to `std::streamsize`
- Jack W (@jackwil1)
- Fix typos in documentation template syntax
- amatej (@kontura)
- Fix: `toml::detail::region::last_` may be used uninitialized
- Severin Leonhardt (@SeverinLeonhardt)
- Fix use with CMake 3.21 and older
- hayt (@hayt)
- fix: prevent size_t-max length string allocation
- somebody (@oldoldtea), (lz)
- Update README for better ToC, fixing example code
## Licensing terms
This product is licensed under the terms of the [MIT License](LICENSE).
- Copyright (c) 2017-2024 Toru Niina
All rights reserved.

View File

@@ -1,26 +1,41 @@
version: "{build}"
os: Visual Studio 2015
environment:
matrix:
- generator: Visual Studio 14 2015 Win64
- generator: Visual Studio 14 2015
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
MSVC_VERSION: 2017
CXX_VERSION: 11
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
MSVC_VERSION: 2017
CXX_VERSION: 14
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
MSVC_VERSION: 2017
CXX_VERSION: 17
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
MSVC_VERSION: 2019
CXX_VERSION: 11
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
MSVC_VERSION: 2019
CXX_VERSION: 14
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
MSVC_VERSION: 2019
CXX_VERSION: 17
configuration:
- Release
- Debug
clone_depth: 10
clone_folder: c:\toml11
install:
- git submodule update --init --recursive
build_script:
- '"C:\Program Files (x86)\Microsoft Visual Studio\%MSVC_VERSION%\Community\VC\Auxiliary\Build\vcvarsall.bat" x64'
- cd C:\toml11
- mkdir build
- cd build
- git clone https://github.com/toml-lang/toml.git
- file --mime-encoding toml/tests/hard_example_unicode.toml
- cmake -G"%generator%" -DBOOST_ROOT=C:/Libraries/boost_1_63_0 ..
- cmake --build . --config "%configuration%"
- cmake -B build -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=%configuration% -DCMAKE_CXX_STANDARD=%CXX_VERSION% -DTOML11_BUILD_TESTS=ON -DBUILD_TESTING=ON -DTOML11_PRECOMPILE=ON
- cmake --build build
test_script:
- ctest --build-config "%configuration%" --timeout 300 --output-on-failure
- cd build\tests\
- ctest --timeout 300 --output-on-failure

View File

@@ -0,0 +1,3 @@
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/toml11Targets.cmake")
set_and_check(TOML11_INCLUDE_DIR "@PACKAGE_TOML11_INSTALL_INCLUDE_DIR@/")

3
docs/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
public/*
resources/*
.hugo_build.lock

34
docs/config.toml Normal file
View File

@@ -0,0 +1,34 @@
baseURL = "https://toruniina.github.io/toml11"
title = "toml11"
languageCode = "en-us"
theme = "hugo-book"
disablePathToLower = true
[languages]
[languages.en]
weight = 1
languageName = "English"
contentDir = "content.en"
[languages.ja]
weight = 2
languageName = "日本語"
contentDir = "content.ja"
[menu]
[[menu.after]]
name = "GitHub"
url = "https://github.com/ToruNiina/toml11"
weight = 10
[params]
BookTheme = 'auto'
BookToC = true
BookSection = 'docs'
BookSearch = true
BookComments = false
BookRepo = 'https://github.com/ToruNiina/toml11'
[markup.tableOfContents]
startLevel = 1
endLevel = 3

25
docs/content.en/_index.md Normal file
View File

@@ -0,0 +1,25 @@
+++
title = "Introduction"
type = "docs"
+++
# Introduction
日本語版は[こちら](/toml11/ja/)
## [Installation](docs/installation)
This section describes how to build and install toml11.
## [Features](docs/features)
This section describes how to use toml11's features with examples.
## [Reference](docs/reference)
This section details toml11 functions and classes.
## [ChangeLog](docs/changelog)
This section describes changes from release to release.

View File

@@ -0,0 +1,415 @@
+++
title = "changelog"
type = "docs"
weight = 4
+++
# Change Log
# v4.4.0
## Added
- Add `toml::find_or_default()` (#280) (by Ken Matsui @ken-matsui)
- Add `erase` to `ordered_map` (#282) (#283) (by Sunlight @SunPodder)
- Add `bool basic_value::accessed() const` to detect whether the value has been accessed
- enabled only if `TOML11_ENABLE_ACCESS_CHECK` is defined
- Add compare operators to `toml::spec`
## Fixed
- Use `is_void<T>` instead of `is_same<T, void>` (#281) (by Ken Matsui @ken-matsui)
## Changed
- Improve `toml::parse` performance by 2x
- Stop using deprecated Ubuntu 20 image on GitHub Actions
# v4.3.0
## Added
- Support `std::optional` as a template argument of `toml::find`
- Support multiple arguments `toml::visit(visitor, args...)`
## Fixed
- `toml::detail::region::last_` may be used uninitialized (#267) (#268) (by amatej @kontura)
- Fix use with CMake 3.21 and older (#271) (by Severin Leonhardt @SeverinLeonhardt)
- fix: prevent size_t-max length string allocation (#275) (#276) (by @hayt)
- update README.md (#277) (by somebody @oldoldtea) (by lz)
- Make parsing faster for very long line (#278)
- Avoid known problem in MSVC (#279)
- Check if `source_location::file_name()` is null before formatting
## Changed
- Update hugo-book theme
- Add MSVC 2017 to appveyor build
# v4.2.0
## Added
- Support `std::optional` members for `TOML11_DEFINE_CONVERSION_NON_INTRUSIVE` (by Ken Matsui)
- Make `thread_local` for `color_mode` optional (by Ken Matsui)
- add usage with CPM to README
- add explanation about `ordered_map` to README and update doc
## Fixed
- Manually cast file size to `std::streamsize` (by Pino Toscano)
- Typographical error in `table_format` output
- Format an empty array specified as array-of-table in one line
- Added a missing include file
- Fix typos in documentation template syntax (by Jack W)
- Fix `toml::find_or` for deeply nested tables
# v4.1.0
## Added
- support `std::get<std::u8string>`
- support `toml::value(std::u8string)`
- support `string_type = std::u8string`
- support `operator<<(std::ostream&, toml::value)`
- add `bool uppercase` to `toml::integer_format`
- support `template into_toml()` (by 萧迩珀)
## Fixed
- Fix not checking for `\r\n` when parsing line comments (by Andreas Keller)
## Changed
- speedup CI tests by multicore build
# v4.0.3
## Fixed
- remove default template argument from forward declaration in `toml_fwd.hpp`
- enable to call `toml::make_error_info` with multiple `toml::value`s
- enable to copy/move `toml::result` having `std::reference_wrapper`
- fix document generation error with the latest version of hugo
- fix several tiny errors that causes warning
- fix CMake compatibility warning
## Changed
add `-Werror` / `/WX` to build script
set MSVC warning level to `/W4`
add explanation of features to README
# v4.0.2
## Fixed
- check return value of fread in `parse(FILE*)`
- version macro defined in `toml11/version.hpp`
- update docs about compilation
- update docs about file open mode
## Changed
- use version macros defined in `toml11/version.hpp` as the project version in `CMakeLists.txt`
# v4.0.1
## Fixed
- Resolved naming conflict of `sematic_version::{major, minor}` with macros defined in `<sys/sysmacro.h>`
- Fixed the definition of `operator<<` in `discard_comments` (by Egor Pugin)
- Fixed the issue where the first blank line was not output in `format_location`
- Fixed the issue where error messages pointing to `source_location` referring to lines containing only newline characters were displayed in two lines
- Corrected links in the README
- Corrected the title of the README in `example/unicode`
## Added
- Configured CI to automatically update `single_include/toml.hpp` when changes are made to `main`
# Changes from v3 to v4
## Breaking Changes
### Changed `template` Parameters of `toml::basic_value`
In toml11 v3, `toml::basic_value` took separate template arguments for the comment container, table-type container, and array-type container.
```cpp
template<typename Comment,
template<typename ...> class Table = std::unordered_map,
template<typename ...> class Array = std::vector>
class basic_value;
```
However, this approach does not accommodate changes to types such as `integer_type`.
In toml11 v4, `toml::basic_value` now accepts a single `TypeConfig`, allowing for more types to be customized.
```cpp
template<typename TypeConfig>
class basic_value;
```
By default, the types stored in `toml::value` remain unchanged.
For more information on changing types, please refer to the
[`type_config`]({{< ref "/docs/reference/types.md">}}) documentation.
### Removed `std::initializer_list` Support for `toml::basic_value`
In toml11 v3, there was an overload for `toml::value` that accepted `std::initializer_list`. This allowed for more intuitive initialization of `toml::value` with arrays and tables.
```cpp
// toml11 v3
toml::value v{1,2,3,4,5};
toml::value v{ {"a", 42}, {"b", "foo"} };
```
However, this caused the following issues:
First, it was impossible to distinguish between a single-element array and a regular value, as it always became an array.
```cpp
// toml11 v3
toml::value v{1}; // Becomes [1,] instead of 1
```
With the widespread use of uniform initialization, this became very inconvenient.
Second, it was unclear whether the value represented a table with all string values or a nested array.
```cpp
// toml11 v3
toml::value v{ {"a", "foo"}, {"b", "bar"} };
// Could be either:
// {a = "foo", b = "bar"}
// [["a", "foo"], ["b", "bar"]]
```
These issues were difficult to resolve due to language specifications.
To avoid confusion, toml11 v4 has removed `std::initializer_list` support.
When initializing `toml::value` with an array, you must explicitly specify `toml::array`, and when initializing with a table, you must explicitly specify `toml::table`.
```cpp
// toml11 v4
toml::value v(toml::array{1,2,3,4,5});
toml::value v(toml::table{ {"a", 42}, {"b", "foo"} });
toml::value v{toml::array{1}}; // [1,]
toml::value v{1} // 1
toml::value v{toml::table{{"a", "foo"}, {"b", "bar"}}};
toml::value v{toml::array{toml::array{"a", "foo"}, toml::array{"b", "bar"}}};
```
While this makes initializing `toml::value` with tables or arrays slightly less convenient, it ensures that the values will not become unpredictable by requiring explicit type information.
### Renamed `toml::basic_value::is_uninitialized()` to `is_empty()`
In toml11 v3, the function to check whether a `basic_value` was uninitialized was called `is_uninitialized`.
However, in toml11 v4, the library supports `null` values as an extension, allowing for the intentional construction of empty values.
Therefore, the function has been renamed to `is_empty` to reflect this change.
### Added Format Information and Removed `toml::string`
In toml11 v3, to retain information on whether a string was `basic` or `literal`, the library used a thin wrapper around `std::string` called `toml::string`.
```cpp
// toml11 v3
namespace toml
{
enum class string_t : std::uint8_t
{
basic = 0,
literal = 1,
};
struct string
{
string_t kind;
std::string str;
};
} // namespace toml
```
In toml11 v4, to accommodate more format information such as the numeric base or whether arrays should be multiline, every type now has an associated `xxx_format` type, which is stored alongside the value.
```cpp
// toml11 v4
enum class string_format : std::uint8_t
{
basic = 0,
literal = 1,
multiline_basic = 2,
multiline_literal = 3
};
struct string_format_info
{
string_format fmt = string_format::basic;
bool start_with_newline = false;
};
```
This change allows for more detailed format information to be preserved, ensuring that format specifics for numeric types, arrays, and tables are maintained even after parsing.
### Changed Arguments of `toml::format`
In toml11 v3, `toml::format` accepted values such as the precision and width of numeric types.
However, this approach did not allow for detailed formatting specifications, resulting in serialized files that did not match expectations.
In toml11 v4, each `toml::value` now carries its own format information, enabling more detailed formatting options to be preserved within the `toml::value` itself.
As a result, `toml::format` no longer accepts specific formatting values. Instead, it now only takes a `toml::spec`, which includes language feature flags used during formatting.
### Changed Member Functions of `toml::source_location`
In toml11 v3, the member types of `toml::source_location` were designed to handle only single lines.
In toml11 v4, the member types of `toml::source_location` are designed to handle multiple lines.
### Renamed `toml::format_underline` to `toml::format_location`
In toml11 v3, the function used to format location information from `toml::source_location` was called `toml::format_underline`.
To make the name clearer, it has been renamed to `toml::format_location`.
## Changed Arguments of `toml::format_error`
In toml11 v3, there was no class to represent error information, resulting in complex arguments for `toml::format_error`.
```cpp
template<typename C, template<typename ...> class T, template<typename ...> class A>
std::string format_error(const std::string& err_msg,
const basic_value<C, T, A>& v, const std::string& comment,
std::vector<std::string> hints = {},
const bool colorize = TOML11_ERROR_MESSAGE_COLORIZED);
template<typename C, template<typename ...> class T, template<typename ...> class A>
inline std::string format_error(const std::string& err_msg,
const toml::basic_value<C, T, A>& v1, const std::string& comment1,
const toml::basic_value<C, T, A>& v2, const std::string& comment2,
std::vector<std::string> hints = {},
const bool colorize = TOML11_ERROR_MESSAGE_COLORIZED);
template<typename C, template<typename ...> class T, template<typename ...> class A>
inline std::string format_error(const std::string& err_msg,
const toml::basic_value<C, T, A>& v1, const std::string& comment1,
const toml::basic_value<C, T, A>& v2, const std::string& comment2,
const toml::basic_value<C, T, A>& v3, const std::string& comment3,
std::vector<std::string> hints = {},
const bool colorize = TOML11_ERROR_MESSAGE_COLORIZED);
```
In toml11 v4, we have introduced `class error_info` and `make_error_info`, simplifying the arguments for `format_error`.
```cpp
std::string format_error(const error_info& err);
std::string format_error(const std::string& errkind, const error_info& err);
template<typename ... Ts>
std::string format_error(std::string title,
source_location loc, std::string msg, Ts&& ... tail);
template<typename TC, typename ... Ts>
std::string format_error(std::string title,
const basic_value<TC>& v, std::string msg, Ts&& ... tail);
```
### Changed Control of `toml::color`
In toml11 v3, to control whether to colorize the output, we used the manipulator `toml::colorize` in conjunction with `toml::color::enable/disable`.
The manipulator allowed us to decide whether to apply color to each stream,
but in v4, the frequency of using streams has decreased,
and issues such as the fact that `std::ios_base::xalloc` used internally is not thread-safe in C++11 have arisen.
Therefore, we have decided to use only `toml::color::enable/disable` and have removed `toml::colorize`.
## Non-Breaking Changes
### Added `parse_str`
In toml11 v3, there was no function to directly parse a string itself.
Therefore, when parsing a string, it was necessary to use `std::istringstream`.
To address this inconvenience, we have added `toml::parse_str`, allowing for direct parsing of strings.
### Added `try_parse`
In toml11 v3, when a parser encountered an error, it threw `toml::syntax_error`.
However, there are cases where you do not want to throw exceptions due to environments where exceptions cannot be thrown, or for reasons of performance.
In toml11 v4, we have implemented `toml::try_parse` using `toml::result`, which communicates parsing failures without throwing exceptions.
This doesn't mean exceptions are never thrown. Errors in the standard library being used, such as `std::bad_alloc` due to allocation failure from memory exhaustion, may still be thrown.
### Support for Parsing Byte Sequences
To allow for parsing TOML content obtained through means other than files, we have added `toml::parse` and `toml::try_parse` functions that accept `std::vector<unsigned char>`.
### Added `toml::spec`
In toml11 v3, all new features of the TOML language were incorporated, and features that were decided to be introduced in future versions of the TOML language were controlled by the macro `TOML11_USE_UNRELEASED_TOML_FEATURES`.
This was because, at the time of developing toml11 v3, the TOML language had not yet reached version 1.0.0, being at versions 0.4.0 to 0.5.0.
As not all users are familiar with the latest TOML language specification, displaying error messages based on an older language usage could confuse the entire community. Therefore, until reaching version 1.0.0, it was necessary to provide new language specifications as quickly as possible and encourage users to update.
However, the current TOML language specification is at version 1.0.0. Therefore, there was a need to be mindful of the choice to continue using version 1.0.0 even after TOML v1.1.0 was released.
To allow for more flexibility in selecting the TOML language specification, we introduced `toml::spec`, enabling the TOML language version to be changed at runtime.
Additionally, in `toml::spec`, flags are set for each language feature, allowing for the testing of specific language features only.
This mechanism is also used for TOML-specific language extensions in toml11 v4.
### Added Format Information
In toml11 v3, format information was not saved except for strings, and during serialization, only width and precision were considered.
However, this resulted in hexadecimal integers being serialized as decimal integers and no reliable way to ensure inline tables.
In toml11 v4, format information (`integer_format`, etc.) has been added to all TOML types, and it is now considered during parsing and serialization.
This allows for more detailed format information to be set for values, such as hexadecimal integers or inline tables.
### Changed to `preserve_comments` by Default
In toml11 v3, comments were not parsed by default and were also not serialized.
This was because comments were a later introduced feature and were being read through a special hack.
In toml11 v4, comments are parsed, preserved, and serialized by default.
Furthermore, the parser implementation has been significantly changed to ensure comments are parsed alongside other elements.
### Changed to Preserve Comments by Default
In toml11 v3, comments were neither parsed nor serialized by default. This was because comment support was a late addition, implemented through a special hack.
In toml11 v4, comments are now parsed, preserved, and serialized by default. The parser implementation has also been significantly revised so that comments are parsed just like any other element.
### Added `single_include/toml.hpp`
toml11 is a versatile library with different header files for various features to enhance development efficiency. However, this required a certain amount of effort to install.
Starting with toml11 v4, a `single_include/toml.hpp` file has been added, which combines all the header files in the correct order. This allows the library to be installed by simply copying a single file.
### Option to Use Precompiled Library
Due to the extensive use of templates in toml11, compile times have been long.
In toml11 v4, the number of precompilable functions has been increased, allowing them to be compiled ahead of time into a library. This is expected to reduce compile times when using the library in large-scale development projects.
### Reference Documentation
Previously, all features were documented in the README, with no detailed function definitions or reference materials available in Japanese.
In toml11 v4, reference documentation has been included, provided in both Japanese and English. However, since the library author is a native Japanese speaker, the Japanese content is considered primary. If there are discrepancies between the Japanese and English content, the Japanese version takes precedence.

View File

@@ -0,0 +1,100 @@
+++
title = "features"
type = "docs"
weight = 2
bookCollapseSection = true
+++
# Features
This section explains the main features provided by toml11, with examples.
## [Parsing Files and Strings](parsing_files)
Describes the functions for parsing files and strings, and how to handle the errors they produce.
Includes:
- Parsing files
- Parsing strings
- Parsing byte arrays
- Parsing files without throwing exceptions
- Parsing strings without throwing exceptions
- Parsing byte arrays without throwing exceptions
## [Extracting Values from `toml::value`](value)
Explains how to examine, extract, and convert the data types held by `toml::value`.
Includes:
- Checking the type of a value using member functions
- Accessing values using member functions
- Accessing comments
- Handling inline tables and dotted keys
- Handling date information
- Using `toml::get<T>` for conversion
- Using `toml::get_or` to specify a fallback value
- Using `toml::find<T>` for searching and conversion
- Using `toml::find_or` to specify a fallback value
- Defining conversions with user-defined types
- Applying functions with `toml::visit`
- Constructing `toml::value`
## [Creating Error Messages](error_message)
Explains how to generate error messages with location information from a TOML file using `toml::value`.
Includes:
- Extracting location information from `toml::value`
- Constructing error messages
- Adding color to the output
## [Serializing TOML Files](serialize)
Describes how to format the values of `toml::value` and the available formatting options.
Includes:
- Specifying formats for each value of `toml::value`
- Formatting `toml::value` into a string
## [Configuring Types of `toml::value`](configure_types)
Explains how to customize the types stored in `toml::value` (such as `integer_type` and `table_type`).
Includes:
- Defining `type_config`
- Using `ordered_type_config`
- Disabling comment preservation
- Using different containers like `std::deque`
- Using different numeric types like `boost::multiprecision`
## [TOML Literals](literal)
Explains the `_toml` literal for embedding TOML files directly in C++ code.
Includes:
- Using TOML literals
## [TOML Language Version](toml_spec)
Describes the versions of the TOML language supported by toml11 and how to control language features added in TOML-v1.1.0.
Includes:
- Using TOML language version 1.1.0
- Using specific features of TOML language version 1.1.0
## [TOML Language Extensions](extension)
Explains the custom extensions to the TOML language provided by toml11.
Includes:
- Supporting `null`
- Supporting hexadecimal format for floating-point numbers
- Allowing units for numbers

View File

@@ -0,0 +1,199 @@
+++
title = "configuring types"
type = "docs"
weight = 50
+++
# Customizing Types
The `toml::value` class uses `std::int64_t` for `integer_type` and `std::unordered_map<key_type, value_type>` for `table_type`.
However, in some cases, you may want to use `boost::multiprecision::int128_t` or `std::map`.
To accommodate this, `toml::value` is implemented with template parameters that allow you to change the stored types.
Just as `std::string` is actually an alias for `std::basic_string<char, std::char_traits<char>, std::allocator<char>>`, `toml::value` is an alias for `toml::basic_value<toml::type_config>`.
Here, we will explain the types contained in `toml::type_config` and how to define a different `config` type.
## `type_config`
The `type_config` class contains the following member types and `static` member functions:
```cpp
namespace toml
{
struct type_config
{
using comment_type = preserve_comments;
using boolean_type = bool;
using integer_type = std::int64_t;
using floating_type = double;
using string_type = std::string;
template<typename T>
using array_type = std::vector<T>;
template<typename K, typename T>
using table_type = std::unordered_map<K, T>;
static result<integer_type, error_info>
parse_int(const std::string& str, const source_location src, const std::uint8_t base);
static result<floating_type, error_info>
parse_float(const std::string& str, const source_location src, const bool is_hex);
};
}
```
`toml::basic_value<TypeConfig>` defines the stored `boolean_type` as `TypeConfig::boolean_type`, the stored `integer_type` as `TypeConfig::integer_type`, and so on.
Additionally, `array_type` is defined as `TypeConfig::array_type<toml::basic_value<TypeConfig>>` and `table_type` is defined as `TypeConfig::table_type<key_type, toml::basic_value<TypeConfig>>`.
By passing a class that defines these member types and functions to `toml::basic_value`, you can customize the types used by that `toml::basic_value`.
The `parse_int` and `parse_float` functions provide parsing methods when custom numeric types are used. These functions receive strings with prefixes like `0x` and digit separators like `_` removed, such as `123456` or `DEADBEEF`. The `base` parameter will be one of `10`, `16`, `8`, or `2`. Implement these functions to parse your custom `integer_type` and `floating_type`.
As a default implementation, `toml::read_int` and `toml::read_float` are provided.
```cpp
static result<integer_type, error_info>
parse_int(const std::string& str, const source_location src, const std::uint8_t base)
{
return toml::read_int<integer_type>(str, src, base);
}
static result<floating_type, error_info>
parse_float(const std::string& str, const source_location src, const bool is_hex)
{
return toml::read_float<floating_type>(str, src, is_hex);
}
```
The `read_int` function uses `istream` and employs `std::hex` and `std::oct` for hexadecimal and octal parsing, respectively. For binary parsing, it is implemented using multiplication and addition. If your type supports these operations, you can use `read_int` as-is.
The `read_float` function also uses `istream`. Hexadecimal floating-point numbers are only supported for `double` and `float` types. If `read_float` is called with any other type and `hexfloat` is used, it will always return a parse error. Therefore, if you need to use a floating-point type other than `double` or `float` with `hexfloat`, you will need to implement support for that. If `hexfloat` is not used, no additional implementation is necessary.
## Preserving Order of Values in Tables
In addition to the default `toml::type_config`, there is also `toml::ordered_type_config`. This changes the `table_type` to an [ordered_map]({{< ref "docs/reference/ordered_map" >}}).
Using this, `toml::ordered_value` is defined, along with aliases for its array and table types as `toml::ordered_array` and `toml::ordered_table`, respectively.
You can use `toml::ordered_value` by calling `toml::parse(...)` as `toml::parse<toml::ordered_type_config>(...)`.
```cpp
#include <toml.hpp>
int main()
{
toml::ordered_value input = toml::parse<toml::ordered_type_config>("example.toml");
std::cout << toml::format(input) << std::endl;
return 0;
}
```
## Not Preserving Comments
The `type_config` defines a container for storing comments via `comment_type`.
If comments do not contain significant information and can be discarded during parsing, specify `toml::discard_comments` for `comment_type`.
```cpp
struct wo_comment_config
{
using comment_type = toml::discard_comments; // XXX
using boolean_type = bool;
using integer_type = std::int64_t;
using floating_type = double;
using string_type = std::string;
template<typename T>
using array_type = std::vector<T>;
template<typename K, typename T>
using table_type = std::unordered_map<K, T>;
static result<integer_type, error_info>
parse_int(const std::string& str, const source_location src, const std::uint8_t base)
{
return toml::read_int<integer_type>(str, src, base);
}
static result<floating_type, error_info>
parse_float(const std::string& str, const source_location src, const bool is_hex)
{
return toml::read_float<floating_type>(str, src, is_hex);
}
};
```
## Using Containers Other Than `std::vector` for Arrays
To use a container other than `vector` (e.g., `std::deque`) for implementing TOML arrays, modify `array_type` as follows.
Similarly, to use a container other than `unordered_map` (e.g., `std::map`) for table types, modify `table_type` as shown below.
```cpp
struct deque_map_config
{
using comment_type = toml::preserve_comments;
using boolean_type = bool;
using integer_type = std::int64_t;
using floating_type = double;
using string_type = std::string;
template<typename T>
using array_type = std::deque<T>; // XXX
template<typename K, typename T>
using table_type = std::map<K, T>; // XXX
static result<integer_type, error_info>
parse_int(const std::string& str, const source_location src, const std::uint8_t base)
{
return toml::read_int<integer_type>(str, src, base);
}
static result<floating_type, error_info>
parse_float(const std::string& str, const source_location src, const bool is_hex)
{
return toml::read_float<floating_type>(str, src, is_hex);
}
};
```
## Using `boost::multiprecision` for Numeric Types
By using `boost::multiprecision::cpp_int` and `boost::multiprecision::cpp_bin_float_oct`, you can utilize a wider integer type and a more precise floating-point type.
These types implement stream operators, so you can use the default implementations of `read_int` and `read_float` without modification.
```cpp
struct large_num_config
{
using comment_type = toml::preserve_comments;
using boolean_type = bool;
using integer_type = boost::multiprecision::cpp_int;
using floating_type = boost::multiprecision::cpp_bin_float_oct;
using string_type = std::string;
template<typename T>
using array_type = std::vector<T>;
template<typename K, typename T>
using table_type = std::unordered_map<K, T>;
static toml::result<integer_type, toml::error_info>
parse_int(const std::string& str, const toml::source_location src, const std::uint8_t base)
{
return toml::read_int<integer_type>(str, src, base);
}
static toml::result<floating_type, toml::error_info>
parse_float(const std::string& str, const toml::source_location src, const bool is_hex)
{
return toml::read_float<floating_type>(str, src, is_hex);
}
};
```

View File

@@ -0,0 +1,212 @@
+++
title = "error message"
type = "docs"
weight = 30
+++
# Outputting Error Messages
`toml11` provides error messages that include location information within the file when using functions like `toml::parse`, `toml::get<T>/find<T>`, and `as_integer()`, among others.
For instance, if a syntax error in an integer is detected during parsing, an error message might look like this:
```
[error] bad integer: `_` must be surrounded by digits
--> internal string at line 64 in file main.cpp
|
1 | a = 123__456
| ^-- invalid underscore
Hint: valid : -42, 1_000, 1_2_3_4_5, 0xC0FFEE, 0b0010, 0o755
Hint: invalid: _42, 1__000, 0123
```
Or, if a type different from the one actually stored is requested:
```
[error] toml::value::as_string(): bad_cast to string
--> input.toml
|
1 | a = 123_456
| ^^^^^^^-- the actual type is integer
```
`toml11` provides methods to create such error messages from `toml::value`.
By utilizing this feature, you can inform users not only about TOML syntax errors but also about application-specific errors. For example, if a negative number appears where only positive values are allowed, you can highlight the location within the TOML file to convey the error to the user.
## Creating Error Messages from `toml::value` Location Information
`toml::value` retains information about the location where it was parsed.
This information is encapsulated in `toml::source_location` and can be retrieved using `toml::value::location()`.
```cpp
const toml::value& a = input.at("a");
const toml::source_location src = a.location();
```
When a file is parsed with `toml::parse`, the TOML filename and line numbers are stored.
If parsed with `toml::parse_str`, the TOML filename is not available, but instead, the filename and line number of the C++ source code that called `toml::parse_str` are stored as the TOML filename. The first example on this page was output from `toml::parse_str`. Note the filename part.
For details, see the [reference]({{<ref "/docs/reference/source_location">}}).
You can build error information by passing a `toml::source_location` or `toml::value` and the associated error message to `toml::make_error_info`. Passing this to `toml::format_error` formats the error message into a `std::string`.
```cpp
const toml::value& a = input.at("a");
if(a.as_integer() < 0)
{
const toml::error_info err = toml::make_error_info(
"positive integer is required", // Error title
a, "but got negative value" // Message next to the value
);
std::cerr << toml::format_error(err) << std::endl;
}
```
This will output:
```
[error] positive integer is required
--> input.toml
|
1 | a = -123456
| ^^^^^^^-- but got negative value
```
You can also add a supplementary message at the end. This part is not indented.
```cpp
const toml::value& a = input.at("a");
if(a.as_integer() < 0)
{
const toml::error_info err = toml::make_error_info(
"positive integer is required", // Error title
a, "but got negative value", // Message next to the value
"Hint: `a` means length of the data" // Supplementary message
);
std::cerr << toml::format_error(err) << std::endl;
}
```
This will output:
```
[error] positive integer is required
--> input.toml
|
1 | a = -123456
| ^^^^^^^-- but got negative value
Hint: `a` means length of the data
```
{{<hint info>}}
The ability to output lines from the file using `toml::value` is because the parsed file is retained in memory as a string.
The parsed string is shared by `toml::value` via a `std::shared_ptr`. Copying it does not duplicate the entire file string. The file information is freed from memory when all `toml::value` instances constructed from parsing the file are destructed.
Therefore, when using this in an application, it is recommended to extract and store the required values during loading rather than directly storing `toml::value`.
{{</hint>}}
## Adding Colors to Strings
You can add color to error messages using ANSI escape codes.
If `TOML11_COLORIZE_ERROR_MESSAGE` is defined at compile time, the error messages output by toml11 will be colored by default.
If not, you can enable color for subsequent error messages by calling `toml::color::enable()`. Conversely, if you do not want colored output, for example, because the output is not to a console, call `toml::color::disable()`. You can check whether coloring is enabled at any point by calling `toml::color::should_color()`.
Additionally, while the error title, error message, and supplementary information are not colored by default, you can use manipulators from toml::color to add color to them.
```cpp
std::ostringstream oss;
oss << toml::color::red << "but got negative value";
const toml::error_info err = toml::make_error_info(
"positive integer is required", // Error title
a, oss.str(), // Message next to the value
"Hint: `a` means length of the data" // Supplementary message
);
```
For more details, see the [reference]({{<ref "docs/reference/color">}}).
## Changing the Prefix of Error Messages from `[error]`
There may be different types of errors, and the default `[error]` prefix might not always be appropriate.
With `toml::format_error`, you can provide a `std::string` before `toml::error_info` to replace the `[error]` prefix.
For example:
```cpp
const toml::value& a = input.at("a");
if(a.as_integer() < 0)
{
const toml::error_info err = toml::make_error_info(
"positive integer is required", // Error title
a, "but got negative value" // Message next to the value
);
std::ostringstream prefix;
prefix << toml::color::bold << toml::color::yellow << "[warn]";
std::cerr << toml::format_error(prefix.str(), err) << std::endl;
return 0;
}
else
{
return a.as_integer();
}
```
This will output a warning starting with `[warn]`.
Additionally, you can create error messages without the `[error]` prefix by directly passing the components of `error_info` to `toml::format_error`.
```cpp
const toml::value& a = input.at("a");
if(a.as_integer() < 0)
{
std::cerr << toml::format_error(
"[warn] positive integer is required", // Error title
a, "but got negative value" // Message next to the value
) << std::endl;
return 0;
}
else
{
return a.as_integer()
}
```
## Creating Error Messages Referencing Multiple `toml::value`
In application settings, the range of permissible values might change based on previously read values.
In such cases, you may want to output the values causing the error simultaneously.
`toml::format_error` and `toml::make_error_info` can take multiple pairs of `toml::value` and their corresponding error messages as `std::string`.
```cpp
std::cerr << toml::format_error(
"[error] invalid range",
a, "minimum value is defined here",
b, "maximum value is defined here",
c, "and it exceeds the range"
) << std::endl;
```
You can also add supplementary information at the end.
```cpp
std::cerr << toml::format_error(
"[error] invalid range",
a, "minimum value is defined here",
b, "maximum value is defined here",
c, "and it exceeds the range",
"Hint: all the values must be in the range [a, b)"
) << std::endl;
```
When passing `toml::value` or `toml::source_location`, an error message related to it must follow. If not, it will result in a very confusing compilation error.

View File

@@ -0,0 +1,124 @@
+++
title = "extension"
type = "docs"
weight = 80
+++
# TOML Language Extensions
The TOML language is currently at version v1.0.0, but several new features have been discussed and merged, with ongoing discussions for v1.1.0.
Among the proposed features, some were deemed to have limited use cases, some faced implementation challenges in their proposed form, and others were not adopted at all.
In toml11, we have experimentally implemented a selection of these features. Please note that these features are supported in toml11 but are not supported by other parsers and are unlikely to be supported in the future.
Additionally, these features are disabled by default. To use them, you must explicitly set the corresponding feature flags to `true`. This design choice ensures that non-standard features are only used intentionally.
Some of these features may eventually be merged into the TOML language itself. If a feature is officially adopted, the corresponding experimental implementation in toml11 may be removed in a minor version update after the official feature is implemented.
## `null`
This feature allows the use of `null` as a value in TOML files.
```
a = null
b = [ 1, 2, 3, null, 5]
```
To enable this, set the `ext_null_value` flag in `toml::spec` to `true`.
When parsed, it will be treated as `toml::value_t::empty`, similar to a default-constructed value. However, the location information within the file will be set.
`null` is parsed only in the context of values. Therefore, if `null` is used as a key, it will be interpreted as the string `"null"`, as it has been in the standard TOML.
```cpp
#include <toml.hpp>
int main()
{
toml::spec spec;
spec.ext_null_value = true;
const auto v = toml::parse_str("a = null", spec);
assert(v.at("a").is_empty());
assert(v.at("a").is(toml::value_t::empty));
return 0;
}
```
## Hexadecimal Format for Floating-Point Numbers
This feature allows the use of hexadecimal format for floating-point numbers in TOML files.
```
a = 0x1.91eb851eb851fp+1 # 3.14
```
To enable this, set the `ext_hex_float` flag in `toml::spec` to `true`.
The format follows the `printf` specification for `%a/%A`.
```cpp
#include <toml.hpp>
int main()
{
toml::spec spec;
spec.ext_hex_float = true;
const auto v = toml::parse_str("a = 0x1.91eb851eb851fp+1", spec);
assert(v.at("a").is_floating());
assert(v.at("a").as_floating() == 3.14);
return 0;
}
```
## Suffixes for Integers and Floating-Point Numbers
This feature allows the use of suffixes for numbers in TOML files. It can be applied to integers and floating-point numbers in decimal notation.
This is particularly useful for displaying units.
```
a = 86_400_sec
b = 3.1416_rad
c = 10_μm
```
However, these are purely suffixes and do not perform any unit conversion. If unit conversion is needed, users should implement it by referencing the suffix.
To enable this, set the `ext_num_suffix` flag in `toml::spec` to `true`.
The suffix must be separated from the number by an underscore (`_`).
For clarity, the suffix cannot start with a digit.
```
distance = 100_m # valid
distance = 10_0m # invalid
distance = 10_0_m # valid
```
The suffix is stored as `std::string suffix` in the format information.
```cpp
#include <toml.hpp>
int main()
{
toml::spec spec;
spec.ext_hex_float = true;
const auto v = toml::parse_str("a = 86_400_sec", spec);
assert(v.at("a").is_integer());
assert(v.at("a").as_integer() == 86400);
assert(v.at("a").as_integer_fmt().suffix == "sec");
return 0;
}
```

View File

@@ -0,0 +1,92 @@
+++
title = "toml literal"
type = "docs"
weight = 60
+++
# `_toml` Literal
With the `""_toml` literal, you can format TOML files inline.
```cpp
#include <toml.hpp>
int main()
{
using namespace toml::literals::toml_literals;
const auto v = "a = 42"_toml;
assert(v.at("a").as_integer() == 42);
return 0;
}
```
When including line breaks, raw string literals come in handy.
```cpp
#include <toml.hpp>
int main()
{
using namespace toml::literals::toml_literals;
const auto v = R"(
a = 42
b = "foo"
)"_toml;
assert(v.at("a").as_integer() == 42);
assert(v.at("b").as_string() == "foo");
return 0;
}
```
If a value is written on its own, that value is returned.
```cpp
#include <toml.hpp>
int main()
{
using namespace toml::literals::toml_literals;
const auto a = "42"_toml;
const auto b = "12:34:56"_toml;
assert(a.as_integer() == 42);
assert(b.as_local_time().hour == 12);
assert(b.as_local_time().minute == 34);
assert(b.as_local_time().second == 56);
return 0;
}
```
TOML allows keys consisting solely of numbers. Therefore, `[1]` is a valid table name.
When there's ambiguity between table definitions and arrays, table definitions take precedence.
To interpret as an array, please use a trailing comma.
```cpp
#include <toml.hpp>
int main()
{
using namespace toml::literals::toml_literals;
const auto t = "[1]"_toml; // {1 = {}}
const auto a = "[1,]"_toml; // [1,]
assert(t.is_table());
assert(t.at("1").is_table());
assert(a.is_array());
assert(a.at(0).as_integer() == 1);
return 0;
}
```

View File

@@ -0,0 +1,244 @@
+++
title = "parsing files"
type = "docs"
weight = 10
+++
# Parsing Files and Strings
In toml11, you can parse files, strings, and byte arrays using `toml::parse` or `toml::try_parse`.
Upon success, these functions return a `toml::value`.
Although the parsed file is always a table, the return type is not `toml::table`.
This is because `toml::value` contains metadata about the file, whereas `toml::table` is merely an alias for `std::unordered_map<std::string, toml::value>`.
To include metadata, a `toml::value` is returned instead of a `toml::table`.
The `toml::value` corresponding to the root of the file will always hold a `table_type`.
## Parsing Files
To parse files, use either
[`toml::parse`]({{< ref "docs/reference/parser#parse" >}})
or
[`toml::try_parse`]({{< ref "docs/reference/parser#try_parse" >}}).
### `toml::parse`
#### Specifying the Filename with `std::string`
[`toml::parse`]({{< ref "docs/reference/parser#parse" >}})
accepts a filename as a string, opens the file, and parses it.
The following sample code parses a file named `input.toml`, extracts the `title` variable as a string, and prints it.
```cpp
#include <toml.hpp>
#include <iostream>
int main()
{
const toml::value input = toml::parse("input.toml");
std::cout << input.at("title").as_string() << std::endl;
return 0;
}
```
#### Specifying a File with `std::filesystem::path`
[`toml::parse`]({{< ref "docs/reference/parser#parse" >}}) can accept a `std::filesystem::path`.
This requires C++17 or later, as it relies on the `<filesystem>` support.
#### Specifying an Input Stream with `std::istream`
[`toml::parse`]({{< ref "docs/reference/parser#parse" >}}) can also accept an `std::istream`.
Open a stream in binary mode by passing `std::ios::binary` to avoid inconsistency between the file size and the number of characters due to automatic conversion of newline characters by the standard library.
Without the filename information, error messages will display `"unknown file"`. To avoid this, you can pass the filename as a `std::string` in the second argument when using `std::istream`.
You can use streams other than `std::ifstream`, such as `std::istringstream`. Note that the entire content is readable at the time of the call.
```cpp
#include <toml.hpp>
#include <iostream>
int main()
{
std::string filename("input.toml");
std::ifstream ifs(filename);
const toml::value input = toml::parse(ifs, filename);
std::cout << input.at("title").as_string() << std::endl;
return 0;
}
```
#### Specifying a File with `FILE*`
[`toml::parse`]({{< ref "docs/reference/parser#parse" >}}) can also accept a `FILE*`.
Open a stream in binary mode by passing `"rb"` to avoid inconsistency between the file size and the number of characters due to automatic conversion of newline characters by the standard library.
As with `std::istream`, you need to provide the filename as a string in the second argument.
When passing a `FILE*`, if the file read fails, `errno` will be reported.
#### Error Handling
[`toml::parse`]({{< ref "docs/reference/parser#parse" >}}) throws a [`toml::syntax_error`]({{< ref "docs/reference/parser#syntax_error" >}}) if it encounters a syntax error.
[`toml::syntax_error`]({{< ref "docs/reference/parser#syntax_error" >}}) is derived from [`toml::exception`]({{< ref "docs/reference/exception" >}}), which in turn is derived from `std::exception`.
Therefore, you can use the `what()` member function to retrieve the error message from a [`toml::syntax_error`]({{< ref "docs/reference/parser#syntax_error" >}}).
Additionally, [`toml::syntax_error`]({{< ref "docs/reference/parser#syntax_error" >}}) contains a [`std::vector<toml::error_info>`]({{< ref "docs/reference/error_info" >}}), which can be accessed using the `errors()` member function.
`toml::parse` attempts to recover from minor errors and report multiple errors whenever possible. While it can often recover from simple errors like number format issues, errors within arrays or tables might not be recoverable and may lead to multiple similar error reports. If you find the error messages redundant, you can use only the `front()` of the `std::vector<toml::error_info>` to get a message about the most critical issue.
```cpp
#include <toml.hpp>
int main()
{
try {
const toml::value input = toml::parse("input.toml");
std::cout << input.at("title").as_string() << std::endl;
} catch(const toml::syntax_error& err) {
// report all the errors
std::cerr << err.what() << std::endl;
// report the first error only
std::cerr << err.errors().front() << std::endl;
}
}
```
### `toml::try_parse`
While `toml::parse` throws an exception on failure, `toml::try_parse` does not throw exceptions when it fails.
Instead, its return type is [`toml::result<toml::value, std::vector<toml::error_info>>`]({{<ref "docs/reference/result#result">}}).
The [`result`]({{<ref "docs/reference/result#result">}}) type holds either a success value or a failure value, similar to Rust's `Result` or Haskell's `Either`.
```cpp
#include <toml.hpp>
int main()
{
const auto parse_result = toml::try_parse("input.toml");
if(parse_result.is_ok())
{
std::cout << parse_result.unwrap().at("title").as_string() << std::endl;
}
else
{
std::cerr << parse_result.unwrap_err().at(0) << std::endl;
}
return 0;
}
```
To check which value the [`result`]({{<ref "docs/reference/result#result">}}) type holds, use the `is_ok()` and `is_err()` functions. The success or failure value can be retrieved using `unwrap()` and `unwrap_err()`, respectively. If `unwrap` fails, it throws a `bad_result_access` exception. Using the `as_ok()` and `as_err()` functions does not throw exceptions on failure, but results in undefined behavior.
{{<hint warning>}}
Although `try_parse` does not throw `syntax_error` or `file_io_error`, it returns the same `toml::error_info` as the failure type in the `result`. However, it is not entirely exception-free.
If an internal standard library error occurs, such as `std::bad_alloc` when a `vector` fails to allocate memory, `toml::try_parse` does not catch this and will let it propagate. Thus, exceptions originating from the standard library may still be thrown.
{{</hint>}}
## Parsing Strings
### `toml::parse_str`
[`toml::parse_str`]({{<ref "docs/reference/parser#parse_str">}}) accepts the string to be parsed directly, instead of a filename.
For the part of the error message that corresponds to the TOML file's name, if the `std::source_location` equivalent compiler extension is available, the name and line number of the C++ file that called `parse_str` will be used instead.
```cpp
#include <toml.hpp>
#include <iostream>
int main()
{
const toml::value input = toml::parse_str("title = \"parse_str\"");
std::cout << input.at("title").as_string() << std::endl;
return 0;
}
```
### `toml::try_parse_str`
[`toml::try_parse_str`]({{<ref "docs/reference/parser#try_parse_str">}}) also takes the string to be parsed directly, similar to `parse_str`. Like `try_parse`, it uses [`toml::result`]({{<ref "docs/reference/result#result">}}) to report errors.
```cpp
#include <toml.hpp>
#include <iostream>
int main()
{
const auto parse_result = toml::try_parse_str("title = \"parse_str\"");
if(parse_result.is_ok())
{
std::cout << parse_result.unwrap().at("title").as_string() << std::endl;
}
else
{
std::cerr << parse_result.unwrap_err().at(0) << std::endl;
}
return 0;
}
```
## Parsing Byte Arrays
It is also possible to parse byte arrays instead of files.
Since the byte arrays must be encoded in UTF-8, `unsigned char` is used.
### `toml::parse(std::vector<unsigned char>)`
The behavior is the same as [`toml::parse`]({{<ref "docs/reference/parser#parse">}}).
When parsing byte arrays, a `filename` is required.
```cpp
#include <toml.hpp>
#include <iostream>
int main()
{
std::vector<unsigned char> bytes{/* ... */};
const toml::value input = toml::parse(bytes, "internal bytes");
std::cout << input.at("title").as_string() << std::endl;
return 0;
}
```
### `toml::try_parse(std::vector<unsigned char>)`
The behavior is the same as [`toml::try_parse`]({{<ref "docs/reference/parser#try_parse">}}).
When parsing byte arrays, a `filename` is required.
```cpp
#include <toml.hpp>
#include <iostream>
int main()
{
std::vector<unsigned char> bytes{/* ... */};
const auto parse_result = toml::try_parse(bytes, "internal bytes");
if(parse_result.is_ok())
{
std::cout << parse_result.unwrap().at("title").as_string() << std::endl;
}
else
{
std::cerr << parse_result.unwrap_err().at(0) << std::endl;
}
return 0;
}
```

View File

@@ -0,0 +1,198 @@
+++
title = "serializing values"
type = "docs"
weight = 40
+++
# Outputting TOML Files
Using `toml::format`, you can convert a `toml::value` to a string.
```cpp
#include <toml.hpp>
#include <cassert>
int main()
{
const toml::value v(toml::table{
{"a", 42},
{"b", "foo"},
});
const std::string s = toml::format(v);
const toml::value u = toml::parse_str(s);
assert(u.at("a").as_integer() == 42);
assert(u.at("b").as_string() == "foo");
return 0;
}
```
If the `toml::value` contains a `table_type`, it is interpreted as the root table of the file.
If a `toml::value` containing anything other than `table_type` is passed, only that value is formatted.
Certain format specifications may require a key to be provided for formatting. For example, `toml::array_format::array_of_tables` formats as `[[array.of.tables]]`, which requires key access.
If a format specification that requires a key is provided without a key, a `toml::serialization_error` is thrown.
Additionally, if there are values that contradict the format specification, a `toml::serialization_error` is thrown. For instance, specifying `integer_format::hex` for a negative integer, or `string_format::literal` for a string containing newlines, will cause an error.
The method for specifying formats is explained later.
## Outputting with Keys
You can pass a key to `toml::format` as a `std::string`.
In this case, the key is considered to be under the root table, and the passed value corresponds to that key.
For nested keys, you can pass a `std::vector<std::string>`.
```cpp
#include <toml.hpp>
#include <cassert>
int main()
{
const toml::value v(toml::table{
{"a", 42},
{"b", "foo"},
});
const std::string s = toml::format("bar", v);
const toml::value u = toml::parse_str(s);
assert(u.at("bar").at("a").as_integer() == 42);
assert(u.at("bar").at("b").as_string() == "foo");
return 0;
}
```
## Specifying Formats
Each type in `toml::value` has a corresponding format information type.
For `toml::value::integer_type`, there is `toml::integer_format_info`.
For `toml::value::table_type`, there is `toml::table_format_info`.
These format information types are set when parsing and are retained even if the value is changed, as long as the type remains the same.
You can access and directly edit these formats using member functions like `as_integer_fmt()` or `as_table_fmt()`.
Below are some examples explaining how to use these formats.
For more details on how to access formats, refer to the [`toml::value` reference]({{< ref "/docs/reference/value" >}}). For a complete list and detailed information on format information classes, see the [format reference]({{< ref "/docs/reference/format" >}}).
### Specifying Integer Formats
For integers, you can specify the radix, width, and the position of `_`.
When using `hex`, `oct`, or `bin`, values are padded with zeros until the specified width is reached. For `dec`, the width specification adds spaces, which are not parsed.
For more details, see the [integer format reference]({{< ref "/docs/reference/format#integer_format" >}}).
### Single-Line and Multi-Line Arrays
For arrays, you can specify `toml::array_format::oneline` or `toml::array_format::multiline`.
```toml
# oneline
a = [1, 2, 3, 4, 5]
# multiline
a = [
1,
2,
3,
4,
5
]
```
When using `multiline`, you can specify the indentation. Each element is indented by the amount specified in `body_indent`, and the closing bracket `]` is indented by the amount specified in `closing_indent`.
The type of character used for indentation is specified by `indent_type`, and you can choose between `toml::indent_char::space` or `toml::indent_char::tab`.
{{<hint warning>}}
Ensure that the same type of character is used for indentation throughout the document.
If different types of characters are specified for indentation within the same file, the result is undefined. Some form of indentation will be applied, but the type of character and the depth of the indentation may be inconsistent.
{{</hint>}}
If all elements of an `array` have `table_type`, you can specify `toml::array_format::array_of_tables`.
If you do not specify `array_of_tables` and use `multiline`, the tables will be formatted as inline tables.
```toml
# multiline
a = [
{foo = 42},
{bar = "hoge"},
]
# array_of_tables
[[a]]
foo = 42
[[a]]
bar = "hoge"
```
By default, `toml::array_format::default_format` is used. This automatically selects an appropriate format.
For example, with `default_format`, if all elements are `table_type`, it will choose `array_of_tables`. Short arrays are formatted as `oneline`, while long or nested arrays, or those with complex elements, are formatted as `multiline`.
For more details, see the [array format reference]({{< ref "/docs/reference/format#array_format" >}}).
### Inline Tables
To format a table as an inline table, specify `toml::table_format::oneline`.
For standard tables, use `toml::table_format::multiline`.
```toml
oneline = {a = 42, b = "foo"}
[multiline]
a = 42
b = "foo"
```
In TOML v1.1.0, line breaks within inline tables are allowed. In this case, use `toml::table_format::multiline_oneline`. This is only applied if the corresponding feature flag is set to `true` as per the TOML version specification described later.
```toml
multiline_oneline = {
a = 42,
b = "foo"
}
```
For more details, see the [table format reference]({{< ref "/docs/reference/format#table_format" >}}).
## Specifying the TOML Language Version for Output
Certain language features, such as line breaks within inline tables and `\x` escape sequences, are only available after TOML v1.1.0.
The `toml::format` function accepts a `toml::spec` as its argument.
This allows you to specify the version of TOML to use during serialization.
When you use `toml::parse` with a `toml::spec` to leverage new features,
the parsed values may contain format information that is only compatible with that specific version.
Ensure that you pass the same `toml::spec` to `toml::format` to maintain compatibility.
```cpp
#include <toml.hpp>
#include <iostream>
int main()
{
const auto spec = toml::spec::v(1, 1, 0);
const toml::value v = toml::parse("input.toml", spec);
std::cout << toml::format(v, spec) << std::endl;
return 0;
}
```

View File

@@ -0,0 +1,107 @@
+++
title = "toml spec"
type = "docs"
weight = 70
+++
# TOML Language Version
You can specify the version of the TOML language and individual feature flags to use with `toml::parse` or `toml::format` through [`toml::spec`]({{< ref "docs/reference/spec#tomlspec" >}}).
## Specifying TOML Version
You can construct a [`toml::spec`]({{< ref "docs/reference/spec#tomlspec" >}}) from [`toml::semantic_version`]({{< ref "docs/reference/spec#tomlsemantic_version" >}}).
```cpp
#include <toml.hpp>
int main()
{
toml::spec spec(toml::semantic_version(1, 1, 0));
return 0;
}
```
However, to make this shorter, the `toml::spec::v()` function is provided.
```cpp
#include <toml.hpp>
int main()
{
toml::spec spec = toml::spec::v(1, 1, 0);
return 0;
}
```
If not specified explicitly, `toml::spec::default_version()` is used to construct with default values.
The default value depends on the version of toml11 and follows the latest version of the TOML language released at that time.
As of v4.4.0, TOML v1.1.0 has not been released yet, so the default TOML version is v1.0.0.
{{<hint warning>}}
Some features of TOML v1.1.0 are still under fairly lengthy discussion and may still be reverted.
If they are indeed reverted, toml11 will remove those features in a minor version upgrade or move them to a corresponding later version.
As such, any features related to future versions should be considered unstable.
{{</hint>}}
### Parsing with Version Specification
The overload of [`toml::parse`]({{< ref "docs/reference/parser#parse" >}}) takes a `toml::spec` following the file name.
This allows you to change the TOML version being used.
```cpp
#include <toml.hpp>
int main()
{
toml::value input = toml::parse("input.toml", toml::spec::v(1, 1, 0));
return 0;
}
```
### Serializing with Version Specification
The overload of [`toml::format`]({{< ref "docs/reference/serializer" >}}) takes a `toml::spec` following the `toml::value`.
This allows you to change the TOML version being used.
```cpp
#include <toml.hpp>
int main()
{
toml::value v = toml::parse("input.toml", toml::spec::v(1, 1, 0));
std::cout << toml::format(v, toml::spec::v(1, 1, 0)) << std::endl;
return 0;
}
```
If a format is passed that is not permitted by the provided `toml::spec`, it will be ignored, and another format will be used as a fallback.
## Specifying Newly Added Features in TOML
With version upgrades in TOML, multiple new features are introduced, and it's possible to enable only some of them.
```cpp
#include <toml.hpp>
int main()
{
toml::spec spec = toml::spec::v(1, 0, 0);
// Allowing newlines in inline tables
spec.v1_1_0_allow_newlines_in_inline_tables = true;
toml::value input = toml::parse("input.toml", spec);
return 0;
}
```
For a full list of all flags, refer to [`toml::spec`]({{< ref "docs/reference/spec#tomlspec" >}}).

View File

@@ -0,0 +1,909 @@
+++
title = "getting values"
type = "docs"
weight = 20
+++
# Retrieving Values
This section explains how to access the values stored in `toml::value`.
## Accessing Values Using Member Functions
### `is_something` and `as_something`
`toml::value` has member functions like `is_boolean()` and `is_integer()` which allow you to check the type of the stored value.
Additionally, it has member functions like `as_boolean()` and `as_integer()` that allow you to access the value of that type.
For a complete list, refer to the [`toml::value` reference]({{<ref "docs/reference/value#is_xxx">}}).
```cpp
toml::value v = /* ... */;
if(v.is_string())
{
std::cout << v.as_string() << std::endl;
}
```
If the stored value is of a different type than specified, a [`toml::type_error`]({{<ref "docs/reference/value#tomltype_error">}}) is thrown.
The `what()` method will contain a message like the following:
```
[error] toml::value::as_string(): bad_cast to string
--> input.toml
|
1 | a = 123_456
| ^^^^^^^-- the actual type is integer
```
### `toml::value_t`
Type information can be identified using [`enum class toml::value_t`]({{<ref "docs/reference/value_t">}}).
The [`type()`]({{<ref "docs/reference/value#type">}}) member function returns the type information of the currently stored value.
```cpp
toml::value v = /* ... */;
switch(v.type())
{
case toml:value_t::empty : { /*...*/ break; }
case toml:value_t::boolean : { /*...*/ break; }
case toml:value_t::integer : { /*...*/ break; }
case toml:value_t::floating : { /*...*/ break; }
case toml:value_t::string : { /*...*/ break; }
case toml:value_t::offset_datetime: { /*...*/ break; }
case toml:value_t::local_datetime : { /*...*/ break; }
case toml:value_t::local_date : { /*...*/ break; }
case toml:value_t::local_time : { /*...*/ break; }
case toml:value_t::array : { /*...*/ break; }
case toml:value_t::table : { /*...*/ break; }
default: {break;}
}
```
The [`is(toml::value_t)`]({{<ref "docs/reference/value#istomlvalue_t">}}) member function returns `true` if the stored value is of the given `value_t` type, otherwise it returns `false`.
```cpp
toml::value v = /* ... */;
if(v.is(toml::value_t::integer))
{
std::cout << v.as_integer() << std::endl;
}
```
### `at`, `[]`, `contains`, `size`, `push_back`, `emplace_back`
`toml::value` provides some member functions similar to those of standard library containers.
These functions internally convert `toml::value` to the corresponding type and call the respective member functions.
#### `at(std::size_t i)`, `operator[](std::size_t i)`
These are equivalent to `as_array().at(i)` and `as_array()[i]`.
`toml::value` uses `std::vector<toml::value>` as `array_type` by default, so `at` throws `std::out_of_range` on error, while `operator[]` results in undefined behavior.
```cpp
toml::value v(toml::array{1,2,3});
std::cout << v.at(1);
```
If the stored type is not `array_type`, a `type_error` is thrown.
#### `at(std::string key)`, `operator[](std::string key)`
These are equivalent to `as_table().at(key)` and `as_table()[key]`.
`toml::value` uses `std::unordered_map<std::string, toml::value>` as `table_type` by default, so if the corresponding value does not exist, `at` throws `std::out_of_range`, while `operator[]` constructs a new `toml::value` and returns a reference to it. Therefore, there is no `const` version of `operator[]`.
```cpp
toml::value v(toml::table{});
v["a"] = 42;
```
If the stored type is not `table_type`, a `type_error` is thrown.
#### `size()`
Returns the length.
For `array_type` or `table_type`, it returns the number of elements; for `string_type`, it returns the number of characters (in bytes).
If the stored type is none of these, a `type_error` is thrown.
#### `push_back()`, `emplace_back()`
These are equivalent to `as_array().push_back()` and `as_array().emplace_back()`.
If the stored type is not `array_type`, a `type_error` is thrown.
## Accessing Comments
In toml11, comments are parsed by default and saved line by line with the corresponding value.
A comment corresponds to the value that comes immediately after the consecutive lines of comments, or to the value on the same line as the comment.
If there is no value immediately before or after the comment, it is not associated with any value and is ignored.
```toml
# input.toml
# This is a comment about a.
a = 42
b = 3.14 # This is a comment about b.
# This comment is ignored because it has no corresponding value.
# This is the 1st comment about c.
# This is the 2nd comment about c.
c = "foo" # This is the final comment about c.
# This comment is NOT a comment about c.
```
Comments corresponding to a value can be accessed using the `comments()` member function of `toml::value`.
`comments()` returns a container that has the same member functions as `std::vector<std::string>`.
```cpp
const auto v = toml::parse("input.toml");
const auto& a = v.at("a");
const auto& b = v.at("b");
const auto& c = v.at("c");
assert(a.comments().size() == 1);
assert(a.comments().at(0) == "# This is a comment about a.");
assert(b.comments().size() == 1);
assert(b.comments().at(0) == "# This is a comment about b.");
assert(c.comments().size() == 3);
assert(c.comments().at(0) == "# This is the 1st comment about c.");
assert(c.comments().at(1) == "# This is the 2nd comment about c.");
assert(c.comments().at(2) == "# This is the final comment about c.");
```
Comments related to the root table of the entire file are written at the beginning of the file.
```toml
# This is a comment about the root table.
# This is also a comment about the root table.
# This comment is ignored.
# This is a comment about a.
a = 42
```
However, if a value immediately follows the initial comment, the comment is interpreted as pertaining to that value, and there are no comments for the root table.
```toml
# This is a comment about a.
# This is also a comment about a.
a = 42
```
## Handling Inline Tables and Dotted Keys
An inline table is simply a table, and there is no difference in handling it compared to other tables in C++ code.
```toml
a = {b = 42, c = "foo"}
```
Dotted keys are also just tables, with no difference in handling compared to other tables in C++ code.
```toml
a.b = 42
a.c = "foo"
```
These TOML files are identical to the following file.
```toml
[a]
b = 42
c = "foo"
```
Thus, they can all be processed with the exact same code.
```cpp
const auto input = toml::parse("input.toml");
assert(input.at("a").at("b").as_integer() == 42);
assert(input.at("a").at("c").as_string() == "foo");
```
However, it is possible to distinguish them based on format information.
```cpp
const auto input = toml::parse("input.toml");
switch(input.at("a").as_table_fmt().fmt)
{
case toml::table_format::oneline:
{
std::cout << "inline table" << std::endl;
break;
}
case toml::table_format::multiline:
{
std::cout << "normal table" << std::endl;
break;
}
case toml::table_format::dotted:
{
std::cout << "dotted keys" << std::endl;
break;
}
}
```
This format information is also considered during serialization, which will be described later.
## Handling Date and Time Information
[`local_date`]({{<ref "docs/reference/datetime#local_date">}}),
[`local_time`]({{<ref "docs/reference/datetime#local_time">}}),
[`local_datetime`]({{<ref "docs/reference/datetime#local_datetime">}}), and
[`offset_datetime`]({{<ref "docs/reference/datetime#offset_datetime">}})
are parsed into dedicated structures with corresponding member variables in toml11.
When using these, you can directly extract the values or use `toml::get` and `toml::find` to convert them into types such as `std::chrono::system_clock::time_point` or `std::tm`.
## Converting Using `toml::get<T>`
`toml::get<T>` is a function that converts and retrieves the value stored in `toml::value`.
Specify the desired target type as `T`.
```cpp
const toml::value v = /*...*/;
std::cout << toml::get<int>(v) << std::endl;
```
The `toml::find<T>` function, described later, also has the same functionality for type conversion.
If an unsupported type is specified for the stored value, a `toml::type_error` is thrown.
### Simple Conversions
#### boolean_type
Conversion from `boolean_type` is possible only to `bool`.
#### integer_type
Any type for which `std::is_integral<T>` is `true`, except `bool`, can be converted from `integer_type`.
```cpp
toml::value v(42);
const auto u32 = toml::get<std::uint32_t>(v);
const auto i16 = toml::get<short>(v);
```
#### floating_type
Any type for which `std::is_floating_point<T>` is `true` can be converted from `floating_type`.
```cpp
toml::value v(3.14);
const auto f64 = toml::get<double>(v);
const auto f32 = toml::get<float >(v);
```
#### string_type
`string_type` can be converted to `std::string`.
From C++17 onwards, it can also be converted to `std::string_view`.
```cpp
toml::value v("foo");
const auto s = toml::get<std::string>(v);
// C++17
const auto sv = toml::get<std::string_view>(v);
```
#### datetime variants
[`local_date`]({{<ref "docs/reference/datetime#local_date">}}),
[`local_datetime`]({{<ref "docs/reference/datetime#local_datetime">}}), and
[`offset_datetime`]({{<ref "docs/reference/datetime#offset_datetime">}}) represent specific dates and times,
so they can be converted to `std::chrono::system_clock::time_point`.
However, since [`local_time`]({{<ref "docs/reference/datetime#local_time">}}) does not include date information, it supports conversion to `std::chrono::duration` as the elapsed time from `00:00.00`.
Additionally, `local_date` and `local_datetime` conversions take the executing machine's timezone into account.
```toml
date = 2024-01-23
time = 12:30:00
l_dt = 2024-01-23T12:30:00
o_dt = 2024-01-23T12:30:00+09:00
```
```cpp
const auto input = toml::parse("input.toml");
const auto date = toml::get<std::chrono::system_clock::time_point>(input.at("date"));
const auto l_dt = toml::get<std::chrono::system_clock::time_point>(input.at("l_dt"));
const auto o_dt = toml::get<std::chrono::system_clock::time_point>(input.at("o_dt"));
const auto time = toml::get<std::chrono::minutes>(input.at("time")); // 12 * 60 + 30 min
```
### Conditions for Obtaining References
`toml::get<T>` can return a reference if `T` is the exact type stored in `toml::value`.
Conversely, if a conversion is necessary (e.g., extracting an integer stored as `std::int64_t` into `std::uint32_t`), it is not possible to return a reference to the converted type.
When no conversion is needed, the returned reference can be used to modify the value.
```cpp
toml::value v(42);
toml::get<toml::value::integer_type>(v) = 6 * 9;
assert(v.as_integer() == 54);
```
### Converting Arrays to STL Containers
If all elements in an array have the same type and can be converted to `T`, it is possible to convert them to `std::vector<T>`.
```toml
a = [1, 2, 3, 4, 5]
```
```cpp
const auto a = toml::get<std::vector<int>>(input.at("a"));
```
Other STL containers can also be used.
```cpp
const auto a1 = toml::get<std::deque<int>>(input.at("a"));
const auto a2 = toml::get<std::list <int>>(input.at("a"));
const auto a3 = toml::get<std::array<int, 5>>(input.at("a"));
```
When converting to `std::array`, the number of elements must match. If they don't match, a `std::out_of_range` exception is thrown.
Non-STL containers that have a default constructor and a `push_back` method can also be converted using `toml::get`.
```cpp
const auto a = toml::get<boost::container::small_vector<int, 8>>(input.at("a"));
```
### Converting Arrays to `std::pair` or `std::tuple`
If an array contains elements of different types, it can be converted to `std::pair` or `std::tuple`.
```toml
a = [true, 3.14]
b = [42, 2.718, "foo"]
```
```cpp
const auto a = toml::get<std::pair<bool, double>>(input.at("a"));
const auto b = toml::get<std::tuple<int, double, std::string>>(input.at("b"));
```
As with `std::array`, the length of the array must match the number of elements in the `std::pair` or `std::tuple`. If they don't match, a `std::out_of_range` exception is thrown.
Additionally, each element must be convertible to the corresponding element in the `std::pair` or `std::tuple`. If conversion is not possible, a `toml::type_error` exception is thrown.
### Converting Nested Arrays
Nested arrays can be converted to nested containers.
```toml
a = [ [1, 2, 3], [4, 5, 6] ]
```
```cpp
const auto a = toml::get<std::vector<std::vector<int>>>(input.at("a"));
```
If the types are different, `std::pair` or `std::tuple` can be useful.
```toml
a = [ [1, 2, 3], ["foo", "bar"] ]
```
```cpp
const auto a = toml::get<
std::pair<std::vector<int>, std::vector<std::string>>
>(input.at("a"));
```
### Converting Tables to `std::map`
If all values in a table have the same type, they can be converted to `std::map` or `std::unordered_map`.
```toml
t = {a = 1, b = 2}
```
```cpp
const auto t = toml::get<std::map<std::string, int>>(input.at("t"));
```
Non-STL containers that have a default constructor and an `emplace(key, mapped)` method can also be converted using `toml::get`.
```cpp
const auto t = toml::get<boost::container::flat_map<std::string, int>>(input.at("t"));
```
If the conversion of any element fails, a `toml::type_error` exception is thrown.
## Using `toml::get_or` to Specify a Value on Failure
`toml::get` throws a `toml::type_error` exception if the conversion fails.
By using `toml::get_or`, you can specify a default value to return instead of an exception in case of a conversion failure.
Unlike `toml::get<T>`, `get_or` infers the target type from the arguments, so there is no need to specify `<T>`.
```cpp
const auto a = toml::get_or(input.at("a"), 42);
```
The types that can be converted are the same as for `toml::get`.
If you specify `toml::value::xxx_type`, you can also retrieve a reference, but in that case, the argument must also be a reference.
```cpp
toml::value::integer_type a_default = 42;
auto a& = toml::get_or(input.at("a"), a_default);
```
## Using `toml::find<T>` to Search and Convert Simultaneously
`toml::find<T>` is a function that searches for a value in a `toml::value` holding a table and simultaneously performs the same type conversion as `toml::get`.
```cpp
const auto a = toml::find<int>(input, "a");
// Equivalent to: const auto a = toml::get<int>(input.at("a"));
```
`toml::find<T>` can also be used with arrays.
```cpp
const auto a = input.at("a");
const auto a2 = toml::find<int>(a, 2);
// Equivalent to: const auto a2 = toml::get<int>(input.at("a").at(2));
```
If an error occurs during type conversion, `toml::find<T>` throws the same `toml::type_error` as `toml::get`.
If the key is not found or the index does not exist, it throws `std::out_of_range`.
If no type is specified, `toml::find` returns a `toml::value` without type conversion.
```cpp
const auto a = toml::find(input, "a");
// Equivalent to: const auto a = input.at("a");
```
`toml::find<T>` can access values recursively.
```toml
a = {b = {c = 42}}
```
```cpp
const auto a_b_c = toml::find<int>(input, "a", "b", "c");
// Equivalent to: const auto a = toml::get<int>(input.at("a").at("b").at("c"));
```
You can mix keys and indexes.
```toml
a = [ {b = 1}, {b = 2}, {b = 3} ]
```
```cpp
const auto a_2_b = toml::find<int>(input, "a", 2, "b");
// Equivalent to: const auto a = toml::get<int>(input.at("a").at(2).at("c"));
```
{{<hint info>}}
TOML supports a feature called quoted keys, which allows using normally disallowed characters in keys by enclosing them in `""` or `''`. Within quoted keys, `.` does **not** introduce tables.
```toml
"127.0.0.1" = "value"
site."google.com" = true
```
You can read this TOML file as follows:
```cpp
const auto input = toml::parse("input.toml");
assert(input.at("127.0.0.1").as_string() == "value");
assert(input.at("site").at("google.com").as_boolean());
```
To handle such cases seamlessly, toml11 does not automatically split keys containing `.`. Explicitly specifying the table hierarchy helps in structuring the input file correctly.
Reference: [toml.io/Key](https://toml.io/en/v1.0.0#key)
{{</hint>}}
## Using `toml::find_or` to Search and Specify a Value on Failure
`toml::find_or` works similarly to `toml::find<T>`, but allows specifying a default value to return if the search or conversion fails.
This is useful when you want to provide a fallback value instead of handling exceptions.
```cpp
const auto a = toml::find_or(input, "a", 42);
```
## Using `toml::find_or_default` to Search and Use the Default Value on Failure
`toml::find_or_default` works similarly to `toml::find_or<T>` but returns the default constructor result if the search or conversion fails.
This is useful when you want to use the default value instead of handling exceptions, especially when the default construction is costly, as this delays it until the actual failure happens.
```cpp
const auto a = toml::find_or(input, "a", expensive()); // ctor is called before the function call
const auto a = toml::find_or_default<expensive>(input, "a"); // ctor will be called only on failure
```
## `toml::find<std::optional<T>>`
If `std::optional` is available, you can specify `std::optional` as a template argument of `toml::find`.
Recursive access is also supported.
```cpp
const auto input = toml::parse_str(R"(
integer = 1
[table]
key = 2
[[array-of-tables]]
key = 3
)");
const auto a = toml::find<std::optional<int>>(input, "integer");
const auto b = toml::find<std::optional<int>>(input, "table", "key");
const auto c = toml::find<std::optional<int>>(input, "array-of-tables", 0, "key");
```
If a key does not exist, no exception is thrown, and `std::nullopt` is returned.
However, if a type conversion fails, or if you attempt to access a key on a value that is not a table, or an index on a value that is not an array, a `toml::type_error` is thrown.
## Defining Conversions for User-Defined Types
With `toml::get` and `toml::find`, you can use user-defined types by employing one of the following methods.
### Defining `toml::from`
In toml11, there is a `toml::from` type that supports conversions from user-defined types by specializing it as follows:
```cpp
namespace extlib
{
struct foo
{
int a;
std::string b;
};
} // extlib
namespace toml
{
template<>
struct from<extlib::foo>
{
static extlib::foo from_toml(const toml::value& v)
{
return extlib::foo{
toml::find<int>(v, "a"),
toml::find<std::string>(v, "b")
};
}
};
} // toml
```
If you also want to support `toml::value` with a modified type configuration, do as follows:
```cpp
namespace extlib
{
struct foo
{
int a;
std::string b;
};
} // extlib
namespace toml
{
template<>
struct from<extlib::foo>
{
template<typename TC>
static extlib::foo from_toml(const toml::basic_value<TC>& v)
{
return extlib::foo{
toml::find<int>(v, "a"),
toml::find<std::string>(v, "b")
};
}
};
} // toml
```
This definition can be automatically generated using `TOML11_DEFINE_CONVERSION_NON_INTRUSIVE`.
```cpp
namespace extlib
{
struct foo
{
int a;
std::string b;
};
} // extlib
TOML11_DEFINE_CONVERSION_NON_INTRUSIVE(extlib::foo, a, b)
```
Alternatively, you can use a reflection library. Refer to the sample in `example` using `boost-ext/reflect`.
### Defining a `from_toml` Member Function
You can also define a conversion by defining a `from_toml` member function.
When using this method, a default constructor is required.
```cpp
struct bar
{
int a;
std::string b;
void from_toml(const toml::value& v)
{
this->a = toml::find<int>(v, "a");
this->b = toml::find<std::string>(v, "b");
return ;
}
};
```
If both are defined, `toml::from` takes precedence.
### Constructor Accepting `toml::value`
If there is a constructor that accepts `toml::value`, conversion via `toml::get` can be performed.
```cpp
struct baz
{
explicit baz(const toml::value& v)
: a(toml::find<int>(v, "a")), b(toml::find<std::string>(v, "b"))
{}
int a;
std::string b;
};
```
If both are defined, `toml::from` and `from_toml` take precedence.
## Applying Functions with `toml::visit`
If you have a function object that can be applied to all types stored in `toml::value`, you can directly call that function without type conversion using `toml::visit`.
```cpp
struct type_name_of
{
std::string operator()(const toml::value::boolean_type &) const {return "boolean";}
std::string operator()(const toml::value::integer_type &) const {return "integer";}
std::string operator()(const toml::value::floating_type &) const {return "floating";}
std::string operator()(const toml::value::string_type &) const {return "string";}
std::string operator()(const toml::value::local_time_type &) const {return "local_time";}
std::string operator()(const toml::value::local_date_type &) const {return "local_date";}
std::string operator()(const toml::value::local_datetime_type &) const {return "local_datetime";}
std::string operator()(const toml::value::offset_datetime_type&) const {return "offset_datetime";}
std::string operator()(const toml::value::array_type &) const {return "array";}
std::string operator()(const toml::value::table_type &) const {return "table";}
};
toml::value v(3.14);
std::cout << toml::visit(type_name_of{}, v) << std::endl; // floating
```
## Constructing `toml::value`
`toml::value` can be constructed not only internally by the parser but also in user code.
You can construct it by passing a type that is either the same as or convertible to the types stored in `toml::value`.
```cpp
toml::value v1(true);
toml::value v2(42);
toml::value v3(3.14);
```
For arrays, you can use `toml::array`:
```cpp
toml::value v(toml::array{1, 2, 3});
```
Alternatively, you can pass containers such as `std::vector` directly:
```cpp
const std::vector<toml::value> a{1,2,3};
toml::value v(a);
```
For tables, you can use `toml::table`:
```cpp
toml::value v(toml::table{{"foo", 1}, {"bar", 2}, {"baz", 3}});
```
Or pass containers such as `std::map` directly:
```cpp
const std::map<std::string, toml::value> t{
{"foo", 1}, {"bar", 2}, {"baz", 3}
}
toml::value v(t);
```
You can pass `format_info` and comments to the constructor.
The type of comments is `std::vector<std::string>`.
Each element corresponds to a line.
```cpp
toml::integer_format_info fmt;
fmt.fmt = toml::integer_format::hex;
fmt.spacer = 4;
toml::value v1(0xDEADBEEF, fmt);
toml::value v2(0xC0FFEE, fmt, {"hex value!"});
```
## Converting to `toml::value`
When constructing `toml::value` from user-defined types, you can customize the behavior by defining `toml::into` or `into_toml`.
`toml::into` is particularly useful when converting types from other libraries.
### Defining `toml::into`
By specializing `toml::into`, you can enable conversions to `toml::value`.
This is useful for types from external libraries that do not provide a conversion to `toml::value`.
Since `toml::value` passes `type_config` during conversion, you need to accept the `template` argument of `basic_value`.
```cpp
namespace extlib
{
struct foo
{
int a;
std::string b;
};
} // extlib
template<>
struct into<extlib::foo>
{
template<typename TC>
static toml::basic_value<TC> into_toml(const extlib::foo& f)
{
return toml::basic_value<TC>(typename toml::basic_value<TC>::table_type{{"a", f.a}, {"b", f.b}});
}
};
```
### Defining `into_toml` Member Function
Similar to `from_toml`, you can define the conversion through a member function.
If `toml::into` is defined, it takes precedence.
```cpp
struct bar
{
int a;
std::string b;
template<typename TC>
toml::basic_value<TC> into_toml() const
{
return toml::basic_value<TC>(typename toml::basic_value<TC>::table_type{
{"a", this->a}, {"b", this->b}
});
}
};
```
# Checking Whether a Value Has Been Accessed
{{% hint warning %}}
This feature is not enabled by default. To use it, you need to define `TOML11_ENABLE_ACCESS_CHECK`.
Additionally, since this feature introduces extra processing on parsed values, it may impact runtime performance.
{{% /hint %}}
When compiled with the `TOML11_ENABLE_ACCESS_CHECK` macro defined, the `toml::value` class gains an additional method: `bool accessed() const`.
This allows you to check whether a value has been accessed after parsing.
```console
$ g++ -std=c++17 -O2 -DTOML11_ENABLE_ACCESS_CHECK -I/path/to/toml11/include main.cpp
```
or
```console
$ cmake -B ./build -DTOML11_ENABLE_ACCESS_CHECK=ON
```
or
```cmake
CPMAddPackage(
NAME toml11
GITHUB_REPOSITORY "ToruNiina/toml11"
VERSION 4.4.0
OPTIONS "CMAKE_CXX_STANDARD 17" "TOML11_PRECOMPILE ON" "TOML11_ENABLE_ACCESS_CHECK ON"
)
```
This feature allows users to implement code that warns about values defined in a table but never used.
```cpp
#include <toml.hpp>
namespace yours
{
Config read_config(const toml::value& input)
{
const auto cfg = read_your_config(input);
for (const auto& [k, v] : input.as_table())
{
if (!v.accessed())
{
std::cerr << toml::format_error("value defined but not used",
v.source_location(), "not used");
}
}
return cfg;
}
} // namespace yours
```
This feature is useful when a value is mistakenly defined under the wrong name but is never accessed. For example:
```toml
# The correct key is "reactions"
# reactions = [ ":+1:", "star" ]
# This key is incorrect and will not be read
reaction = [ ":+1:", "star" ]
```
If this file is read using the above code, `read_your_config` will search for `reactions`. Since it is not defined, it will process `reactions` as an empty array.
In this case, `input.at("reaction").accessed()` will be `false`, allowing it to be detected as an error.

View File

@@ -0,0 +1,151 @@
+++
title = "installation"
type = "docs"
weight = 1
+++
# Installation
## Using `single_include`
The `ingle_include/toml.hpp`s is a single-file, header-only library that consolidates all the functionalities of toml11 into one file.
The simplest way to use it is to copy this file to a location included in your `INCLUDE_PATH` and then add `#include <toml.hpp>` to your source code.
The MIT license notice is included in both the comments and the `toml::license_notice()` function.
If you are redistributing the software without releasing the source code, you must either copy the toml11 license file and include it with your distribution, or ensure that the `toml::license_notice()` function can be called.
## Cloning toml11 and using cmake
If you place toml11 within your repository, for example by using git submodule, and you are using cmake, you can make use of it by adding `add_subdirectory(toml11)` to your `CMakeLists.txt`.
```cmake
add_subdirectory(toml11)
add_executable(main main.cpp)
target_link_libraries(main PUBLIC toml11::toml11)
```
toml11 will only run tests and install when it is the root project.
### CMake `FetchContent`
Using `FetchContent`, you can automatically download toml11 to your `build` directory.
```cmake
include(FetchContent)
FetchContent_Declare(
toml11
GIT_REPOSITORY https://github.com/ToruNiina/toml11.git
GIT_TAG v4.4.0
)
FetchContent_MakeAvailable(toml11)
add_executable(main main.cpp)
target_link_libraries(main PRIVATE toml11::toml11)
```
### CMake Package Manager (CPM)
After [adding cpm to your project](https://github.com/cpm-cmake/CPM.cmake?tab=readme-ov-file#adding-cpm), you can use toml11 by doing:
```cmake
include(cmake/CPM.cmake)
CPMAddPackage("gh:ToruNiina/toml11@4.4.0")
# OR
CPMAddPackage(
NAME toml11
GITHUB_REPOSITORY "ToruNiina/toml11"
VERSION 4.4.0
OPTIONS
"TOML11_PRECOMPILE ON" # to pre-compile
"TOML11_ENABLE_ACCESS_CHECK ON" # to use value.accessed()
)
add_executable(main main.cpp)
target_link_libraries(main PUBLIC toml11::toml11)
```
## Installing using cmake
After cloning toml11, you can install it using cmake.
```console
$ cmake -B ./build/ -DTOML11_BUILD_TESTS=ON
$ cmake --install ./build/ --prefix=/opt/toml11
```
If you want to run the test programs before installation, make sure to set `-DTOML11_BUILD_TESTS=ON` first.
Once the installation is complete, you can use it as follows:
```cmake
find_package(toml11)
add_executable(main main.cpp)
target_link_libraries(main PRIVATE toml11::toml11)
```
## Compiling with cmake to Create a Static Library
By defining `-DTOML11_PRECOMPILE=ON` when running cmake, you can precompile some of the functions in toml11, thereby reducing the overall compile time.
```console
$ cmake -B ./build/ -DTOML11_PRECOMPILE=ON
```
When linking the library, use `target_link_libraries` in CMake
```cmake
target_link_libraries(your_target PUBLIC toml11::toml11)
```
or pass `-DTOML11_COMPILE_SOURCES` to the compiler to suppress header-only features.
However, since toml11 supports multiple C++ versions and may switch types based on the value of `__cplusplus`,
there is a possibility of link failures if the version used during build differs from the version used during usage.
If you encounter issues, set the required version using `CMAKE_CXX_STANDARD` during compilation.
If this is difficult, use it as a header-only library as usual.
The `find_package(toml11)` command defines `TOML11_INCLUDE_DIR`.
Even if you install it as a precompiled library, you can still use it as a header-only library by adding `TOML11_INCLUDE_DIR` to `target_include_directories` and avoiding the use of `target_link_libraries`.
```cmake
find_package(toml11)
add_executable(main main.cpp)
# Include only, do not link
target_include_directories(main PRIVATE ${TOML11_INCLUDE_DIR})
```
## Compiling Examples
You can compile the `examples/` directory by setting `-DTOML11_BUILD_EXAMPLES=ON`.
```console
$ cmake -B ./build/ -DTOML11_BUILD_EXAMPLES=ON
$ cmake --build ./build/
```
The executable binaries for the examples will be generated in the `examples/` directory.
## Running Tests
To build the tests, set `-DTOML11_BUILD_TESTS=ON`.
```console
$ git submodule update --init --recursive
$ cmake -B ./build/ -DTOML11_BUILD_TESTS=ON
$ cmake --build ./build/
$ ctest --test-dir ./build/
```
To run the `toml-lang/toml-tests`, set `-DTOML11_BUILD_TOML_TESTS=ON`. This will build `toml11_decoder` and `toml11_encoder` in the `tests/` directory.
```console
$ git submodule update --init --recursive
$ cmake -B ./build/ -DTOML11_BUILD_TOML_TESTS=ON
$ cmake --build ./build/
$ ctest --test-dir ./build/
```

View File

@@ -0,0 +1,122 @@
+++
title = "reference"
type = "docs"
weight = 3
bookCollapseSection = true
+++
# Reference
Here, we explain the effects of the classes and functions provided by toml11.
## Directory Structure
`toml.hpp` and `toml_fwd.hpp` reside in `${TOML11_INCLUDE_DIR}`.
Other files are located in `${TOML11_INCLUDE_DIR}/toml11`.
If you want to `#include` each feature's file individually, use `#include <toml11/color.hpp>`.
If you want to include all at once, use `#include <toml.hpp>`.
## [color.hpp](color)
Defines functions related to colorizing error messages.
## [comments.hpp](comments)
Defines types `preserve_comment` and `discard_comment` for preserving comments.
## [conversion.hpp](conversion)
Defines macros to automatically convert `toml::value` and user-defined classes.
## [datetime.hpp](datetime)
Defines classes for datetime information.
## [error_info.hpp](error_info)
Defines a class for error information.
## [exception.hpp](exception)
Defines the base class for exceptions used in toml11, `toml::exception`.
## [find.hpp](find)
Defines the `toml::find` function to search for and convert values.
## [format.hpp](format)
Defines classes for formatting information of values.
## [from.hpp](from)
Forward declaration of the `from<T>` type for converting user-defined types.
## [get.hpp](get)
Defines the `toml::get<T>` function to retrieve and convert values from `toml::value`.
## [into.hpp](into)
Forward declaration of the `into<T>` type for converting user-defined types.
## [literal.hpp](literal)
Defines the `operator"" _toml` literal.
## [ordered_map.hpp](ordered_map)
Defines `toml::ordered_map`.
## [parser.hpp](parser)
Defines functions to parse files or strings.
## [result.hpp](result)
Defines the `result<T, E>` type for representing success or failure values used as return types in other functions.
## [serializer.hpp](serializer)
Defines the `toml::format` function and `toml::serializer` used for serialization.
## [source_location.hpp](source_location)
Defines the `source_location` type used for error information, pointing to a location within a file.
## [spec.hpp](spec)
Defines the `toml::semantic_version` and `toml::spec` types to control TOML language version information and feature flags.
## [toml.hpp](toml)
`toml.hpp` includes all other headers, making all toml11 features available.
## [toml_fwd.hpp](toml_fwd)
`toml_fwd.hpp` contains forward declarations of structs defined in toml11 and macro definitions.
## [types.hpp](types)
Defines the `toml::type_config` type for controlling the types held by `toml::value`.
## [value.hpp](value)
Defines the `toml::value` type.
## [value_t.hpp](value_t)
Defines the `toml::value_t` enumeration.
## [version.hpp](version)
Defines the version information for toml11.
## [visit.hpp](visit)
Defines the `toml::visit` function to apply functions to the values held by `toml::value`.
## Notes
Functions not explicitly mentioned here (mostly those defined under `namespace toml::detail` or `namespace toml::cxx`) are available by inspecting the source code but are not guaranteed to maintain their interface across future versions (including patch version updates).

View File

@@ -0,0 +1,147 @@
+++
title = "color.hpp"
type = "docs"
+++
# color.hpp
In `color.hpp`, functions related to colorizing error messages are defined.
Colors are specified using ANSI escape code.
In terminals or other output destinations that do not support ANSI escape code, the output may become difficult to read.
## Macros
### `TOML11_COLORIZE_ERROR_MESSAGE`
If this macro is defined during compilation (`-DTOML11_COLORIZE_ERROR_MESASGE`), error messages are colored by default.
If not defined, colors are not applied by default. You need to specify them using `toml::color::enable()`.
### `TOML11_USE_THREAD_LOCAL_COLORIZATION`
If this macro is defined during compilation (`-DTOML11_USE_THREAD_LOCAL_COLORIZATION`), the colorization flag becomes `thread_local`.
In this case, `toml::color::enable()` or `toml::color::disable()` will only affect the colorization flag in the thread that called it.
This means that if you want to use a different setting from the default, you will need to set it again when starting a new thread.
This makes `toml::color::enable()` and `toml::color::disable()` thread safe.
By default, the setting is global.
When it is global, if one thread executes `toml::color::enable()`, the error messages will be colored in all threads.
However, if one thread executes `enable()` or `disable()` while another executes `enable()`, `disable()` or `should_color()`, the result is undefined.
## Functions
### `enable()`
```cpp
namespace toml {
namespace color {
void enable();
} // color
} // toml
```
Enables colorization using ANSI escape code.
#### Example
```cpp
#include <toml.hpp>
int main()
{
toml::color::enable(); // All subsequent errors will be colored.
const auto input = toml::parse("input.toml");
return 0;
}
```
### `disable()`
```cpp
namespace toml {
namespace color {
void disable();
} // color
} // toml
```
Disables colorization using ANSI escape code.
#### Example
```cpp
#include <toml.hpp>
int main()
{
toml::color::disable(); // All subsequent errors will not be colored.
const auto input = toml::parse("input.toml");
return 0;
}
```
### `should_color()`
```cpp
namespace toml {
namespace color {
bool should_color();
} // color
} // toml
```
Returns `true` if colorization is enabled, `false` otherwise.
#### Example
```cpp
#include <toml.hpp>
#include <iomanip>
#include <iostream>
int main()
{
std::cout << "colorized? : " << std::boolalpha << toml::color::should_color() << std::endl;
return 0;
}
```
## Manipulators
```cpp
namespace toml {
namespace color {
std::ostream& reset (std::ostream&);
std::ostream& bold (std::ostream&);
std::ostream& grey (std::ostream&);
std::ostream& gray (std::ostream&);
std::ostream& red (std::ostream&);
std::ostream& green (std::ostream&);
std::ostream& yellow (std::ostream&);
std::ostream& blue (std::ostream&);
std::ostream& magenta(std::ostream&);
std::ostream& cyan (std::ostream&);
std::ostream& white (std::ostream&);
} // color
} // toml
```
Colorizes the foreground with ANSI escape code.
#### Example
```cpp
#include <toml.hpp>
#include <iostream>
int main()
{
std::cout << toml::color::red << "red!" << toml::color::reset << std::endl;
return 0;
}
```
# Related
- [error_info.hpp]({{<ref "error_info.md">}})

View File

@@ -0,0 +1,776 @@
+++
title = "comments.hpp"
type = "docs"
+++
# comments.hpp
In `comments.hpp`, comment containers are provided.
# `toml::preserve_comments`
`preserve_comments` is a container that preserves comments.
It has all the member functions of `std::vector<std::string>`.
Comments are preserved as `std::string`.
If the comment does not start with `#`, it will be prefixed with `#` during output.
However, this prefixing is not done when adding comments to the container.
Spaces are not automatically added, so if you want a space immediately after `#`,
either start the comment with a space or pass the comment with `#`.
```cpp
namespace toml
{
class preserve_comments;
bool operator==(const preserve_comments&, const preserve_comments&);
bool operator!=(const preserve_comments&, const preserve_comments&);
bool operator< (const preserve_comments&, const preserve_comments&);
bool operator<=(const preserve_comments&, const preserve_comments&);
bool operator> (const preserve_comments&, const preserve_comments&);
bool operator>=(const preserve_comments&, const preserve_comments&);
void swap(preserve_comments&, preserve_comments&);
void swap(preserve_comments&, std::vector<std::string>&);
void swap(std::vector<std::string>&, preserve_comments&);
std::ostream& operator<<(std::ostream&, const preserve_comments&);
} //toml
```
## Member types
```cpp
using container_type = std::vector<std::string>;
using size_type = container_type::size_type;
using difference_type = container_type::difference_type;
using value_type = container_type::value_type;
using reference = container_type::reference;
using const_reference = container_type::const_reference;
using pointer = container_type::pointer;
using const_pointer = container_type::const_pointer;
using iterator = container_type::iterator;
using const_iterator = container_type::const_iterator;
using reverse_iterator = container_type::reverse_iterator;
using const_reverse_iterator = container_type::const_reverse_iterator;
```
## Member Functions
### Default Constructor
```cpp
preserve_comments() = default;
```
Constructs an empty `preserve_comments`.
### Copy and Move Constructors
```cpp
preserve_comments(preserve_comments const&) = default;
preserve_comments(preserve_comments &&) = default;
```
Constructs a `preserve_comments` by copying or moving.
### Constructor (`std::vector<std::string>`)
```cpp
explicit preserve_comments(const std::vector<std::string>& c);
explicit preserve_comments(std::vector<std::string>&& c);
```
Constructs a `preserve_comments` holding the contents of `std::vector<std::string>`.
### Constructor (`discard_comments`)
```cpp
explicit preserve_comments(const discard_comments&);
```
Constructs an empty `preserve_comments`.
### Constructor (`Iterator`)
```cpp
template<typename InputIterator>
preserve_comments(InputIterator first, InputIterator last);
```
Constructs a `preserve_comments` from the range represented by `InputIterator` pointing to `std::string`.
### Constructor (`std::initializer_list`)
```cpp
preserve_comments(std::initializer_list<std::string> x);
```
Constructs a `preserve_comments` from the range represented by `std::initializer_list<std::string>`.
### Constructor (Size Specified)
```cpp
explicit preserve_comments(size_type n);
preserve_comments(size_type n, const std::string& x);
```
Constructs a `preserve_comments` with `n` comments.
If a `std::string` is passed, it replicates that comment `n` times.
### Destructor
```cpp
~preserve_comments() = default;
```
Destroys the `preserve_comments`.
### `operator=(preserve_comments)`
```cpp
preserve_comments& operator=(preserve_comments const&) = default;
preserve_comments& operator=(preserve_comments &&) = default;
```
Assigns a `preserve_comments` by copying or moving.
### `operator=(std::vector<std::string>)`
```cpp
preserve_comments& operator=(const std::vector<std::string>& c);
preserve_comments& operator=(std::vector<std::string>&& c);
```
Assigns a `std::vector<std::string>` by copying or moving.
### `assign`
```cpp
template<typename InputIterator>
void assign(InputIterator first, InputIterator last);
void assign(std::initializer_list<std::string> ini);
void assign(size_type n, const std::string& val);
```
The same as `std::vector<std::string>::assign`.
### `insert`
```cpp
iterator insert(const_iterator p, const std::string& x);
iterator insert(const_iterator p, std::string&& x);
iterator insert(const_iterator p, size_type n, const std::string& x);
template<typename InputIterator>
iterator insert(const_iterator p, InputIterator first, InputIterator last);
iterator insert(const_iterator p, std::initializer_list<std::string> ini);
```
The same as `std::vector<std::string>::insert`.
### `emplace`
```cpp
template<typename ... Ts>
iterator emplace(const_iterator p, Ts&& ... args);
```
The same as `std::vector<std::string>::emplace`.
### `erase`
```cpp
iterator erase(const_iterator pos);
iterator erase(const_iterator first, const_iterator last);
```
The same as `std::vector<std::string>::erase`.
### `swap`
```cpp
void swap(preserve_comments& other);
```
Swaps the comments.
### `push_back`
```cpp
void push_back(const std::string& v);
void push_back(std::string&& v);
```
The same as `std::vector<std::string>::push_back`.
### `pop_back`
```cpp
void pop_back();
```
The same as `std::vector<std::string>::pop_back`.
### `emplace_back`
```cpp
template<typename ... Ts>
void emplace_back(Ts&& ... args);
```
The same as `std::vector<std::string>::emplace_back`.
### `clear`
```cpp
void clear();
```
The same as `std::vector<std::string>::clear`.
### `size`
```cpp
size_type size() const noexcept;
```
The same as `std::vector<std::string>::size`.
### `max_size`
```cpp
size_type max_size() const noexcept;
```
The same as `std::vector<std::string>::max_size`.
### `capacity`
```cpp
size_type capacity() const noexcept;
```
The same as `std::vector<std::string>::capacity`.
### `empty`
```cpp
bool empty() const noexcept;
```
The same as `std::vector<std::string>::empty`.
### `reserve`
```cpp
void reserve(size_type n);
```
The same as `std::vector<std::string>::reserve`.
### `resize`
```cpp
void resize(size_type n);
void resize(size_type n, const std::string& c);
```
The same as `std::vector<std::string>::resize`.
### `shrink_to_fit`
```cpp
void shrink_to_fit();
```
The same as `std::vector<std::string>::shrink_to_fit`.
### `operator[]`
```cpp
reference operator[](const size_type n) noexcept;
const_reference operator[](const size_type n) const noexcept;
```
The same as `std::vector<std::string>::operator[]`.
### `at`
```cpp
reference at(const size_type n) ;
const_reference at(const size_type n) const;
```
The same as `std::vector<std::string>::at`.
### `front`
```cpp
reference front() noexcept;
const_reference front() const noexcept;
```
The same as `std::vector<std::string>::front`.
### `back`
```cpp
reference back() noexcept;
const_reference back() const noexcept;
```
The same as `std::vector<std::string>::back`.
### `data`
```cpp
pointer data() noexcept;
const_pointer data() const noexcept;
```
The same as `std::vector<std::string>::data`.
### `begin/end`
```cpp
iterator begin() noexcept;
iterator end() noexcept;
const_iterator begin() const noexcept;
const_iterator end() const noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
```
The same as `std::vector<std::string>::begin/end`.
### `rbegin/rend`
```cpp
reverse_iterator rbegin() noexcept;
reverse_iterator rend() noexcept;
const_reverse_iterator rbegin() const noexcept;
const_reverse_iterator rend() const noexcept;
const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept;
```
The same as `std::vector<std::string>::rbegin/rend`
## non-member functions
### Comparison operator
```cpp
bool operator==(const preserve_comments&, const preserve_comments&);
bool operator!=(const preserve_comments&, const preserve_comments&);
bool operator< (const preserve_comments&, const preserve_comments&);
bool operator<=(const preserve_comments&, const preserve_comments&);
bool operator> (const preserve_comments&, const preserve_comments&);
bool operator>=(const preserve_comments&, const preserve_comments&);
```
It compares two `preserve_comments` in the same way as `std::vector<std::string>`.
### `swap`
```cpp
void swap(preserve_comments&, preserve_comments&);
void swap(preserve_comments&, std::vector<std::string>&);
void swap(std::vector<std::string>&, preserve_comments&);
```
### Stream operator
```cpp
std::ostream& operator<<(std::ostream&, const preserve_comments&);
```
Outputs as TOML comments.
If the first character is not `#`, it adds `#`.
# `toml::discard_comments`
`discard_comments` serves as a container for discarding comments.
It encompasses all the member functions of `std::vector<std::string>`, but invoking functions that modify the content has no effect, leaving it perpetually empty.
```cpp
namespace toml
{
class discard_comments;
bool operator==(const discard_comments&, const discard_comments&);
bool operator!=(const discard_comments&, const discard_comments&);
bool operator< (const discard_comments&, const discard_comments&);
bool operator<=(const discard_comments&, const discard_comments&);
bool operator> (const discard_comments&, const discard_comments&);
bool operator>=(const discard_comments&, const discard_comments&);
void swap(discard_comments&, discard_comments&);
std::ostream& operator<<(std::ostream&, const discard_comments&);
} //toml
```
## Member types
```cpp
// container_type is not defined
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using value_type = std::string;
using reference = std::string&;
using const_reference = std::string const&;
using pointer = std::string*;
using const_pointer = std::string const*;
using iterator = /* internal type: empty-iterator */
using const_iterator = /* internal type: empty-iterator */
using reverse_iterator = /* internal type: empty-iterator */
using const_reverse_iterator = /* internal type: empty-iterator */
```
### Default Constructor
```cpp
discard_comments() = default;
```
Constructs an empty `discard_comments`.
### Copy / Move Constructor
```cpp
discard_comments(discard_comments const&) = default;
discard_comments(discard_comments &&) = default;
```
Constructs a `discard_comments` by copying or moving.
### Constructor(`std::vector<std::string>`)
```cpp
explicit discard_comments(const std::vector<std::string>& c);
explicit discard_comments(std::vector<std::string>&& c);
```
Constructs an empty `discard_comments`. Arguments are ignored.
### Constructor(`preserve_comments`)
```cpp
explicit discard_comments(const preserve_comments&);
```
Constructs an empty `discard_comments`. Arguments are ignored.
### Constructor(`Iterator`)
```cpp
template<typename InputIterator>
discard_comments(InputIterator first, InputIterator last);
```
Constructs an empty `discard_comments`. Arguments are ignored.
### Constructor(`std::initializer_list`)
```cpp
discard_comments(std::initializer_list<std::string> x);
```
Constructs an empty `discard_comments`. Arguments are ignored.
### Constructor(サイズ指定)
```cpp
explicit discard_comments(size_type n);
discard_comments(size_type n, const std::string& x);
```
Constructs an empty `discard_comments`. Arguments are ignored.
### Destructor
```cpp
~discard_comments() = default;
```
Destroys `discard_comments`.
### `operator=(discard_comments)`
```cpp
discard_comments& operator=(discard_comments const&) = default;
discard_comments& operator=(discard_comments &&) = default;
```
Assigns `discard_comments` by copying or moving.
### `operator=(std::vector<std::string>)`
```cpp
discard_comments& operator=(const std::vector<std::string>& c);
discard_comments& operator=(std::vector<std::string>&& c);
```
Does nothing.
### `assign`
```cpp
template<typename InputIterator>
void assign(InputIterator first, InputIterator last);
void assign(std::initializer_list<std::string> ini);
void assign(size_type n, const std::string& val);
```
Does nothing.
### `insert`
```cpp
iterator insert(const_iterator p, const std::string& x);
iterator insert(const_iterator p, std::string&& x);
iterator insert(const_iterator p, size_type n, const std::string& x);
template<typename InputIterator>
iterator insert(const_iterator p, InputIterator first, InputIterator last);
iterator insert(const_iterator p, std::initializer_list<std::string> ini);
```
Does nothing.
### `emplace`
```cpp
template<typename ... Ts>
iterator emplace(const_iterator p, Ts&& ... args);
```
Does nothing.
### `erase`
```cpp
iterator erase(const_iterator pos);
iterator erase(const_iterator first, const_iterator last);
```
Does nothing.
### `swap`
```cpp
void swap(discard_comments& other);
```
Swaps two `discard_comments`. Effectively it does nothing.
### `push_back`
```cpp
void push_back(const std::string& v);
void push_back(std::string&& v);
```
Does nothing.
### `pop_back`
```cpp
void pop_back();
```
Does nothing.
### `emplace_back`
```cpp
template<typename ... Ts>
void emplace_back(Ts&& ... args);
```
Does nothing.
### `clear`
```cpp
void clear();
```
Does nothing.
### `size`
```cpp
size_type size() const noexcept;
```
Returns `0`.
### `max_size`
```cpp
size_type max_size() const noexcept;
```
Returns `0`.
### `capacity`
```cpp
size_type capacity() const noexcept;
```
Returns `0`.
### `empty`
```cpp
bool empty() const noexcept;
```
Returns `true`.
### `reserve`
```cpp
void reserve(size_type n);
```
Does nothing.
### `resize`
```cpp
void resize(size_type n);
void resize(size_type n, const std::string& c);
```
Does nothing.
### `shrink_to_fit`
```cpp
void shrink_to_fit();
```
Does nothing.
### `operator[]`
```cpp
reference operator[](const size_type n) noexcept;
const_reference operator[](const size_type n) const noexcept;
```
Causes undefined behavior.
### `at`
```cpp
reference at(const size_type n) ;
const_reference at(const size_type n) const;
```
Throws `std::out_of_range`.
### `front`
```cpp
reference front() noexcept;
const_reference front() const noexcept;
```
Causes undefined behavior.
### `back`
```cpp
reference back() noexcept;
const_reference back() const noexcept;
```
Causes undefined behavior.
### `data`
```cpp
pointer data() noexcept;
const_pointer data() const noexcept;
```
Returns `nullptr`.
### `begin/end`
```cpp
iterator begin() noexcept;
iterator end() noexcept;
const_iterator begin() const noexcept;
const_iterator end() const noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
```
Returns an internally defined `empty-iterator`.
The `empty-iterator` remains at the same value after incrementing or decrementing and all values are equivalent.
Accessing the target of the `empty-iterator` always calls `std::terminate`.
### `rbegin/rend`
```cpp
reverse_iterator rbegin() noexcept;
reverse_iterator rend() noexcept;
const_reverse_iterator rbegin() const noexcept;
const_reverse_iterator rend() const noexcept;
const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept;
```
Returns an internally defined `empty-iterator`.
The `empty-iterator` remains at the same value after incrementing or decrementing and all values are equivalent.
Accessing the target of the `empty-iterator` always calls `std::terminate`.
## non-member functions
### Comparison operator
```cpp
bool operator==(const discard_comments&, const discard_comments&);
bool operator!=(const discard_comments&, const discard_comments&);
bool operator< (const discard_comments&, const discard_comments&);
bool operator<=(const discard_comments&, const discard_comments&);
bool operator> (const discard_comments&, const discard_comments&);
bool operator>=(const discard_comments&, const discard_comments&);
```
All the instances of `discard_comments` are the same value. `operator==` returns `true`, `operator=!` returns `false`.
### `swap`
```cpp
void swap(discard_comments&, discard_comments&);
```
Swaps `discard_comments`. Effectively it does nothing.
### Stream operator
```cpp
std::ostream& operator<<(std::ostream&, const discard_comments&);
```
Outputs nothing.
# Related
- [value.hpp]({{<ref "value.md">}})

View File

@@ -0,0 +1,33 @@
+++
title = "conversion.hpp"
type = "docs"
+++
# conversion.hpp
Provides macros to automatically define conversion functions for supporting user-defined types with `toml::get` and `toml::find`.
```cpp
TOML11_DEFINE_CONVERSION_NON_INTRUSIVE(NAME, ...)
```
## Example
```cpp
namespace foo
{
struct Foo
{
std::string s;
double d;
int i;
};
} // foo
TOML11_DEFINE_CONVERSION_NON_INTRUSIVE(foo::Foo, s, d, i)
```
# Related
- [from.hpp]({{<ref "from.md">}})
- [into.hpp]({{<ref "into.md">}})

View File

@@ -0,0 +1,779 @@
+++
title = "datetime.hpp"
type = "docs"
+++
# datetime.hpp
Defines a class that stores date and time information used in TOML's `datetime`.
# `enum class month_t`
Enum class to specify months.
Due to its relationship with `std::tm`, `local_date` treats January as `0`.
To avoid confusion, `month_t` allows specification of months by their names.
```cpp
namespace toml
{
enum class month_t : std::uint8_t
{
Jan = 0,
Feb = 1,
Mar = 2,
Apr = 3,
May = 4,
Jun = 5,
Jul = 6,
Aug = 7,
Sep = 8,
Oct = 9,
Nov = 10,
Dec = 11
};
}
```
# `local_date`
`local_date` holds a date.
`year` represents the year in AD. For `month`, January is represented as `0` to align with `std::tm`. `day` holds the day of the month.
```cpp
namespace toml
{
struct local_date
{
std::int16_t year;
std::uint8_t month;
std::uint8_t day;
local_date() = default;
~local_date() = default;
local_date(local_date const&) = default;
local_date(local_date&&) = default;
local_date& operator=(local_date const&) = default;
local_date& operator=(local_date&&) = default;
local_date(int y, month_t m, int d);
explicit local_date(const std::tm& t);
explicit local_date(const std::chrono::system_clock::time_point& tp);
explicit local_date(const std::time_t t);
operator std::chrono::system_clock::time_point() const;
operator std::time_t() const;
};
bool operator==(const local_date&, const local_date&);
bool operator!=(const local_date&, const local_date&);
bool operator< (const local_date&, const local_date&);
bool operator<=(const local_date&, const local_date&);
bool operator> (const local_date&, const local_date&);
bool operator>=(const local_date&, const local_date&);
std::ostream& operator<<(std::ostream& os, const local_date& date);
std::string to_string(const local_date& date);
}
```
## Member Variables
### `year`
```cpp
std::int16_t year;
```
Represents the year in AD. There's no offset. `2024` is simply `2024`.
### `month`
```cpp
std::uint8_t month;
```
Represents the month. To align with `std::tm`, January is `0`, February is `1`, and so on.
To avoid confusion, use `month_t` during construction.
### `day`
```cpp
std::uint8_t day;
```
Represents the day of the month. The first day is `1`.
## Member Functions
### Constructor
```cpp
local_date() = default;
```
Uses the default implementation.
### Destructor
```cpp
~local_date() = default;
```
Uses the default implementation.
### Copy and Move Constructors
```cpp
local_date(local_date const&) = default;
local_date(local_date&&) = default;
```
Uses the default implementations.
### Copy and Move Assignment Operators
```cpp
local_date& operator=(local_date const&) = default;
local_date& operator=(local_date&&) = default;
```
Uses the default implementations.
### Constructor (`int year, month_t month, int day`)
```cpp
local_date(int y, month_t m, int d);
```
Constructs a `local_date` from the specified values.
Does not perform boundary checks.
### Constructor (`std::tm`)
```cpp
local_date(const std::tm&);
```
Constructs a `local_date` from the specified `std::tm` value.
### Constructor (`std::chrono::system_clock::time_point`)
```cpp
local_date(const std::chrono::system_clock::time_point&);
```
Constructs a `local_date` from the specified `std::chrono::system_clock::time_point` value.
Time zone is determined by the environment.
### Constructor (`std::time_t`)
```cpp
local_date(const std::time_t);
```
Constructs a `local_date` from the specified `std::time_t` value.
Time zone is determined by the environment.
### `operator std::chrono::system_clock::time_point`
```cpp
operator std::chrono::system_clock::time_point() const;
```
Converts to `std::chrono::system_clock::time_point`.
Time zone is determined by the environment.
Time is set to 0 hours and 0 minutes.
### `operator std::time_t`
```cpp
operator std::time_t() const;
```
Converts to `std::time_t`.
Time zone is determined by the execution environment.
Time is set to 0 hours and 0 minutes.
## Non-member Functions
### Comparison Operators
```cpp
bool operator==(const local_date&, const local_date&);
bool operator!=(const local_date&, const local_date&);
bool operator< (const local_date&, const local_date&);
bool operator<=(const local_date&, const local_date&);
bool operator> (const local_date&, const local_date&);
bool operator>=(const local_date&, const local_date&);
```
Compares two dates.
### Stream Operators
```cpp
std::ostream& operator<<(std::ostream& os, const local_date& date);
```
Outputs in the default TOML format.
### `to_string`
```cpp
std::string to_string(const local_date& date);
```
Converts to a string in the default TOML format.
# `local_time`
```cpp
namespace toml
{
struct local_time
{
std::uint8_t hour; // [0, 23]
std::uint8_t minute; // [0, 59]
std::uint8_t second; // [0, 60]
std::uint16_t millisecond; // [0, 999]
std::uint16_t microsecond; // [0, 999]
std::uint16_t nanosecond; // [0, 999]
local_time(int h, int m, int s, int ms = 0, int us = 0, int ns = 0);
explicit local_time(const std::tm& t);
template<typename Rep, typename Period>
explicit local_time(const std::chrono::duration<Rep, Period>& t);
operator std::chrono::nanoseconds() const;
local_time() = default;
~local_time() = default;
local_time(local_time const&) = default;
local_time(local_time&&) = default;
local_time& operator=(local_time const&) = default;
local_time& operator=(local_time&&) = default;
};
bool operator==(const local_time& lhs, const local_time& rhs);
bool operator!=(const local_time& lhs, const local_time& rhs);
bool operator< (const local_time& lhs, const local_time& rhs);
bool operator<=(const local_time& lhs, const local_time& rhs);
bool operator> (const local_time& lhs, const local_time& rhs);
bool operator>=(const local_time& lhs, const local_time& rhs);
std::ostream& operator<<(std::ostream& os, const local_time& time);
std::string to_string(const local_time& time);
}
```
## Member Values
### `hour`
```cpp
std::uint8_t hour;
```
Represents the hour. Values range from `0` to `23`.
### `minute`
```cpp
std::uint8_t minute; // [0, 59]
```
Represents the minute. Values range from `0` to `59`.
### `second`
```cpp
std::uint8_t second; // [0, 60]
```
Represents the second. Values range from `0` to `60`.
### `millisecond`
```cpp
std::uint16_t millisecond; // [0, 999]
```
Represents the millisecond. Values range from `0` to `999`.
### `microsecond`
```cpp
std::uint16_t microsecond; // [0, 999]
```
Represents the microsecond. Values range from `0` to `999`.
### `nanosecond`
```cpp
std::uint16_t nanosecond; // [0, 999]
```
Represents the nanosecond. Values range from `0` to `999`.
## Member Functions
### default constructor
```cpp
local_time() = default;
```
Initializes all values to `0`.
### constructor (h, m, s, ms = 0, us = 0, ns = 0)
```cpp
local_time(int h, int m, int s, int ms = 0, int us = 0, int ns = 0);
```
Constructs using the specified time components.
No boundary checks are performed.
### constructor(`std::tm`)
```cpp
explicit local_time(const std::tm& t);
```
Constructs using `tm_hour`, `tm_min`, and `tm_sec` from `std::tm`.
Subseconds are initialized to `0`.
### constructor(`std::chrono::duration`)
```cpp
template<typename Rep, typename Period>
explicit local_time(const std::chrono::duration<Rep, Period>& t);
```
Constructs as the time of day from `0` hours of the day specified by `duration`.
### `operator std::chrono::nanoseconds`
```cpp
operator std::chrono::nanoseconds() const;
```
Converts to `std::chrono::nanoseconds`.
## Non-member Functions
### Comparison Operators
```cpp
bool operator==(const local_time& lhs, const local_time& rhs);
bool operator!=(const local_time& lhs, const local_time& rhs);
bool operator< (const local_time& lhs, const local_time& rhs);
bool operator<=(const local_time& lhs, const local_time& rhs);
bool operator> (const local_time& lhs, const local_time& rhs);
bool operator>=(const local_time& lhs, const local_time& rhs);
```
Compares based on time values.
### Stream Operator
```cpp
std::ostream& operator<<(std::ostream& os, const local_time& time);
```
Outputs in the default TOML format.
### `to_string`
```cpp
std::string to_string(const local_time& time);
```
Converts to a string in the default TOML format.
# `time_offset`
```cpp
namespace toml
{
struct time_offset
{
std::int8_t hour{0}; // [-12, 12]
std::int8_t minute{0}; // [-59, 59]
time_offset(int h, int m);
operator std::chrono::minutes() const;
time_offset() = default;
~time_offset() = default;
time_offset(time_offset const&) = default;
time_offset(time_offset&&) = default;
time_offset& operator=(time_offset const&) = default;
time_offset& operator=(time_offset&&) = default;
};
bool operator==(const time_offset&, const time_offset&);
bool operator!=(const time_offset&, const time_offset&);
bool operator< (const time_offset&, const time_offset&);
bool operator<=(const time_offset&, const time_offset&);
bool operator> (const time_offset&, const time_offset&);
bool operator>=(const time_offset&, const time_offset&);
std::ostream& operator<<(std::ostream& os, const time_offset& offset);
std::string to_string(const time_offset& offset);
}
```
## Member Variables
### `hour`
```cpp
std::int8_t hour{0}; // [-12, 12]
```
Represents the hour offset, ranging from -12 to +12.
### `minute`
```cpp
std::int8_t minute{0}; // [-59, 59]
```
Represents the minute offset, ranging from -59 to +59.
## Member Functions
### Constructor
```cpp
time_offset(int h, int m);
```
Constructs with given hours and minutes.
No boundary checking is performed.
### `operator std::chrono::minutes`
```cpp
operator std::chrono::minutes() const;
```
Converts to `std::chrono::minutes`.
## Non-member Functions
### Comparison Operators
```cpp
bool operator==(const time_offset&, const time_offset&);
bool operator!=(const time_offset&, const time_offset&);
bool operator< (const time_offset&, const time_offset&);
bool operator<=(const time_offset&, const time_offset&);
bool operator> (const time_offset&, const time_offset&);
bool operator>=(const time_offset&, const time_offset&);
```
Compares based on time length.
### Stream Output Operator
```cpp
std::ostream& operator<<(std::ostream& os, const time_offset&);
```
Outputs in the default TOML format.
### `to_string`
```cpp
std::string to_string(const time_offset&);
```
Converts to a string in the default TOML format.
# `local_datetime`
```cpp
namespace toml
{
struct local_datetime
{
local_date date;
local_time time;
local_datetime(local_date d, local_time t);
explicit local_datetime(const std::tm& t);
explicit local_datetime(const std::chrono::system_clock::time_point& tp);
explicit local_datetime(const std::time_t t);
operator std::chrono::system_clock::time_point() const;
operator std::time_t() const;
local_datetime() = default;
~local_datetime() = default;
local_datetime(local_datetime const&) = default;
local_datetime(local_datetime&&) = default;
local_datetime& operator=(local_datetime const&) = default;
local_datetime& operator=(local_datetime&&) = default;
};
bool operator==(const local_datetime&, const local_datetime&);
bool operator!=(const local_datetime&, const local_datetime&);
bool operator< (const local_datetime&, const local_datetime&);
bool operator<=(const local_datetime&, const local_datetime&);
bool operator> (const local_datetime&, const local_datetime&);
bool operator>=(const local_datetime&, const local_datetime&);
std::ostream& operator<<(std::ostream& os, const local_datetime& dt);
std::string to_string(const local_datetime& dt);
}
```
## Member Variables
### `local_date date`
```cpp
local_date date;
```
Stores the date component data.
### `local_time time`
```cpp
local_time time;
```
Stores the time component data.
## Member Functions
### Default Constructor
Constructs both `date` and `time` with default values.
### Constructor (`local_date, local_time`)
Constructs with the specified `date` and `time`.
### Constructor (`std::tm`)
Constructs from `std::tm`.
The timezone is selected based on the execution environment.
### Constructor (`std::chrono::system_clock::time_point`)
Constructs from `std::chrono::system_clock::time_point`.
The timezone is selected based on the execution environment.
### Constructor (`std::time_t`)
Constructs from `std::time_t`.
The timezone is selected based on the execution environment.
### `operator std::chrono::system_clock::time_point`
Converts to `std::chrono::system_clock::time_point`.
### `operator std::time_t`
Converts to `std::time_t`.
## Non-member Functions
### Comparison Operators
```cpp
bool operator==(const local_datetime&, const local_datetime&);
bool operator!=(const local_datetime&, const local_datetime&);
bool operator< (const local_datetime&, const local_datetime&);
bool operator<=(const local_datetime&, const local_datetime&);
bool operator> (const local_datetime&, const local_datetime&);
bool operator>=(const local_datetime&, const local_datetime&);
```
Compares based on chronological order.
### Stream Output Operator
```cpp
std::ostream& operator<<(std::ostream& os, const local_datetime&);
```
Outputs in the default TOML format.
### `to_string`
```cpp
std::string to_string(const local_datetime&);
```
Converts to a string in the default TOML format.
# `offset_datetime`
```cpp
namespace toml
{
struct offset_datetime
{
local_date date;
local_time time;
time_offset offset;
offset_datetime(local_date d, local_time t, time_offset o);
offset_datetime(const local_datetime& dt, time_offset o);
explicit offset_datetime(const local_datetime& ld);
explicit offset_datetime(const std::chrono::system_clock::time_point& tp);
explicit offset_datetime(const std::time_t& t);
explicit offset_datetime(const std::tm& t);
operator std::chrono::system_clock::time_point() const;
operator std::time_t() const;
offset_datetime() = default;
~offset_datetime() = default;
offset_datetime(offset_datetime const&) = default;
offset_datetime(offset_datetime&&) = default;
offset_datetime& operator=(offset_datetime const&) = default;
offset_datetime& operator=(offset_datetime&&) = default;
};
bool operator==(const offset_datetime&, const offset_datetime&);
bool operator!=(const offset_datetime&, const offset_datetime&);
bool operator< (const offset_datetime&, const offset_datetime&);
bool operator<=(const offset_datetime&, const offset_datetime&);
bool operator> (const offset_datetime&, const offset_datetime&);
bool operator>=(const offset_datetime&, const offset_datetime&);
std::ostream& operator<<(std::ostream& os, const offset_datetime& dt);
std::string to_string(const offset_datetime& dt);
}
```
## Member Variables
### `date`
```cpp
local_date date;
```
Stores the date component.
### `time`
```cpp
local_time time;
```
Stores the time component.
### `offset`
```cpp
time_offset offset;
```
Stores the offset component.
## Member Functions
### Default Constructor
Constructs `date`, `time`, and `offset` with default values.
### Constructor (`local_date, local_time, time_offset`)
Constructs with the specified `date`, `time`, and `offset`.
### Constructor (`local_datetime, time_offset`)
Constructs from `local_datetime` and `offset`.
### Constructor (`std::tm`)
Constructs from `std::tm`.
The timezone is UTC (00:00).
### Constructor (`std::chrono::system_clock::time_point`)
Constructs from `std::chrono::system_clock::time_point`.
The timezone is UTC (00:00).
### Constructor (`std::time_t`)
Constructs from `std::time_t`.
The timezone is UTC (00:00).
### `operator std::chrono::system_clock::time_point`
Converts to `std::chrono::system_clock::time_point`.
The timezone is UTC (00:00).
### `operator std::time_t`
Converts to `std::time_t`.
The timezone is UTC (00:00).
## Non-member Functions
### Comparison Operators
```cpp
bool operator==(const offset_datetime&, const offset_datetime&);
bool operator!=(const offset_datetime&, const offset_datetime&);
bool operator< (const offset_datetime&, const offset_datetime&);
bool operator<=(const offset_datetime&, const offset_datetime&);
bool operator> (const offset_datetime&, const offset_datetime&);
bool operator>=(const offset_datetime&, const offset_datetime&);
```
Compares based on chronological order.
If dates are the same, compares based on timezone order.
### Stream Output Operator
```cpp
std::ostream& operator<<(std::ostream& os, const offset_datetime&);
```
Outputs in the default TOML format.
### `to_string`
```cpp
std::string to_string(const offset_datetime&);
```
Converts to a string in the default TOML format.

View File

@@ -0,0 +1,145 @@
+++
title = "error_info.hpp"
type = "docs"
+++
# error_info.hpp
In `error_info.hpp`, definitions for `error_info` and functions to format it are provided.
# `toml::error_info`
```cpp
namespace toml
{
struct error_info
{
error_info(std::string t, source_location l, std::string m, std::string s = "");
error_info(std::string t, std::vector<std::pair<source_location, std::string>> l, std::string s = "");
std::string const& title() const noexcept;
std::string & title() noexcept;
std::vector<std::pair<source_location, std::string>> const& locations() const noexcept;
void add_locations(source_location loc, std::string msg) noexcept;
std::string const& suffix() const noexcept;
std::string & suffix() noexcept;
};
template<typename ... Ts>
error_info make_error_info(
std::string title, source_location loc, std::string msg, Ts&& ... tail);
std::string format_error(const std::string& errkind, const error_info& err);
std::string format_error(const error_info& err);
template<typename ... Ts>
std::string format_error(std::string title,
source_location loc, std::string msg, Ts&& ... tail);
std::ostream& operator<<(std::ostream& os, const error_info& e);
}
```
## Member Functions
### Constructor (`title, loc, msg, suffix`)
Constructs `error_info` with specified `title`, location information `loc`, message `msg`, and optional `suffix`.
`suffix` defaults to empty.
### Constructor (`title, [{loc, msg}, ...], suffix`)
Constructs `error_info` with specified `title`, an array of location-message pairs `[{loc, msg}, ...]`, and optional `suffix`.
`suffix` defaults to empty.
### `std::string title()`
Returns the title of the error message.
### `std::vector<std::pair<source_location, std::string>> locations()`
Returns the list of locations where errors occurred along with their respective messages.
Multiple locations can be specified.
### `std::string suffix()`
Returns the suffix message to display at the end, providing hints or additional information.
## Non-Member Functions
### `make_error_info`
```cpp
template<typename ... Ts>
error_info make_error_info(
std::string title, source_location loc, std::string msg, Ts&& ... tail);
```
Creates a new `error_info`.
Must be followed by a `msg` related to `source_location` or `basic_value`.
Overloads are added in [`value.hpp`]({{< ref "docs/reference/value#tomlmake_error_info" >}}) when passing `toml::basic_value` instead of `source_location`.
Possible to pass `suffix` at the end.
### `format_error`
Formats `error_info` as follows:
```
{title}
--> {locations().at(0).first.file_name()}
|
1 | {locations().at(0).first.line()}
| ^-- {locations().at(0).second}
|
2 | {locations().at(1).first.line()}
| ^-- {locations().at(1).second}
{suffix}
```
If file names differ between two `source_location`, the file name is displayed again.
```cpp
std::string format_error(const std::string& errkind, const error_info& err);
std::string format_error(const error_info& err);
```
Formats `error_info`.
If `errkind` is not provided, a red-bold `[error]` prefix is added before `title`.
If `errkind` is provided (including an empty string), it replaces `[error]`.
```cpp
namespace toml
{
template<typename ... Ts>
std::string format_error(std::string title,
source_location loc, std::string msg, Ts&& ... tail);
} // toml
```
Returns a formatted string using `format_error` for `error_info` created with `make_error_info`.
Overloads are added in [`value.hpp`]({{< ref "docs/reference/value#tomlformat_error" >}}) when passing `toml::basic_value` instead of `source_location`.
### Stream Operator
```cpp
std::ostream& operator<<(std::ostream& os, const error_info& e);
```
Calls `format_error(e)` and outputs it.
# Related
- [color.hpp]({{< ref "color.md" >}})
- [parser.hpp]({{< ref "parser.md" >}})
- [source_location.hpp]({{< ref "source_location.md" >}})

View File

@@ -0,0 +1,40 @@
+++
title = "exception.hpp"
type = "docs"
+++
# exception.hpp
# `toml::exception`
Base class for exception types defined in toml11.
```cpp
namespace toml
{
struct exception : public std::exception
{
public:
virtual ~exception() noexcept override = default;
virtual const char* what() const noexcept override {return "";}
};
} // toml
```
## Member Functions
### Destructor
```cpp
virtual ~exception() noexcept override = default;
```
Override when derived.
### `what`
```cpp
virtual const char* what() const noexcept override {return "";}
```
Returns the error message. Override when derived.

View File

@@ -0,0 +1,244 @@
+++
title = "find.hpp"
type = "docs"
+++
# find.hpp
This function searches for a value in a `toml::value` and performs type conversion if necessary.
{{< hint info >}}
`toml::value` can change the type it stores, and `toml::find` accommodates these types.
Technically, all functions use `toml::basic_value<TC>`.
However, for simplicity, we refer to it as `toml::value` in explanations unless a distinction is necessary.
In the documentation, if the template parameter `TC` changes the type, assume that types like `toml::value::integer_type` will also change accordingly.
{{< /hint >}}
# `toml::find`
## Overview
`toml::find` uses template arguments for the type you want to retrieve and function arguments for the key of the value you want to find.
```cpp
template<typename T, typename TC, typename ... Keys>
T find(const basic_value<TC>& v, Keys ... keys);
```
The supported types for `T` and the behavior of the conversion are the same as for `toml::get`.
If `T` is not specified, a `toml::value` will be returned.
Keys can be of type `toml::value::key_type` or `std::size_t`.
When multiple keys are provided, the function will search recursively through sub-tables or arrays.
If a `toml::value::key_type` is given, `toml::value` is interpreted as a `toml::table`; if a `std::size_t` is given, `toml::value` is interpreted as a `toml::array`.
### Note on Recursive Search
TOML allows for bare keys as well as quoted keys (enclosed in `"` or `'`). Using a quoted key like `"foo.bar" = "baz"` means no sub-table is constructed, and the key is `"foo.bar"`. To handle such patterns, toml11 does not split keys containing `.` and searches using the full string.
Consider the following TOML file:
```toml
[foo]
[foo.bar]
baz = "hoge"
["foo.bar"]
baz = "fuga"
```
The corresponding usage of `toml::find` is shown below:
```cpp
const auto input = toml::parse("input.toml");
const auto baz1 = toml::find<std::string>(input, "foo", "bar", "baz"); // hoge
const auto baz2 = toml::find<std::string>(input, "foo.bar", "baz"); // fuga
```
cf. [toml.io/en/v1.0.0#keys](https://toml.io/en/v1.0.0#keys)
## `toml::find(value, key)`
Searches for `key` in `value` as if `value` were a `toml::table`, then converts using `toml::get`.
```cpp
template<typename T, typename TC>
/* Equivalent to toml::get<T>(const value&) */ find(
const basic_value<TC>& v, const typename basic_value<TC>::key_type& ky);
template<typename T, typename TC>
/* Equivalent to toml::get<T>(value&) */ find(
basic_value<TC>& v, const typename basic_value<TC>::key_type& ky);
template<typename T, typename TC>
/* Equivalent to toml::get<T>(value&&) */ find(
basic_value<TC>&& v, const typename basic_value<TC>::key_type& ky);
```
If `T` is not specified, the function returns a `toml::value` without conversion.
```cpp
template<typename TC>
basic_value<TC> const& find(
basic_value<TC> const& v, const typename basic_value<TC>::key_type& ky);
template<typename TC>
basic_value<TC>& find(
basic_value<TC>& v, const typename basic_value<TC>::key_type& ky);
template<typename TC>
basic_value<TC> find(
basic_value<TC>&& v, const typename basic_value<TC>::key_type& ky);
```
### Exceptions
If the `toml::value` does not contain a `table`, a `toml::type_error` is thrown.
If the contained `table` does not have the specified element, a `std::out_of_range` is thrown.
If the specified element cannot be converted to `T` (i.e., `toml::get` fails), a `toml::type_error` is thrown.
## `toml::find(value, index)`
Accesses the `index`-th element of `value` as if `value` were a `toml::array`, then converts using `toml::get`.
```cpp
template<typename T, typename TC>
/* Equivalent to toml::get<T>(const value&) */ find(
const basic_value<TC>& v, const std::size_t index);
template<typename T, typename TC>
/* Equivalent to toml::get<T>(value&) */ find(
basic_value<TC>& v, const std::size_t index);
template<typename T, typename TC>
/* Equivalent to toml::get<T>(value&&) */ find(
basic_value<TC>&& v, const std::size_t index);
```
If `T` is not specified, the function returns a `toml::value` without conversion.
```cpp
template<typename TC>
basic_value<TC> const& find(basic_value<TC> const& v, const std::size_t ky);
template<typename TC>
basic_value<TC>& find(basic_value<TC>& v, const std::size_t ky);
template<typename TC>
basic_value<TC> find(basic_value<TC>&& v, const std::size_t ky);
```
### Exceptions
If the `toml::value` does not contain an `array`, a `toml::type_error` is thrown.
If the contained `array` does not have the specified number of elements, a `std::out_of_range` is thrown.
If the specified element cannot be converted to `T` (i.e., `toml::get` fails), a `toml::type_error` is thrown.
## `toml::find(value, keys...)`
```cpp
template<typename T, typename TC, typename K1, typename K2, typename ... Ks>
/* Equivalent to toml::get<T>(const value&) */ find(
const basic_value<TC>& v, const K1& k1, const K2& k2, const Ks& ... ks);
template<typename T, typename TC, typename K1, typename K2, typename ... Ks>
/* Equivalent to toml::get<T>(value&) */ find(
basic_value<TC>& v, const K1& k1, const K2& k2, const Ks& ... ks);
template<typename T, typename TC, typename K1, typename K2, typename ... Ks>
/* Equivalent to toml::get<T>(value&&) */ find(
basic_value<TC>&& v, const K1& k1, const K2& k2, const Ks& ... ks);
```
This function calls `toml::find` recursively.
The failure conditions and the exceptions thrown are the same as those for `toml::find`.
# `toml::find_or(value, key, fallback)`
```cpp
template<typename T, typename TC, typename Key>
T find_or(const basic_value<TC>& v, const Key& key, T&& opt);
```
The `find_or` function takes a default value to avoid throwing an exception when the search fails.
The default value must be of the same type as the return type `T`. Therefore, unlike `toml::find<T>`, `find_or` infers the type `T`.
You can specify `T` explicitly with `find_or<T>`, but this always returns a new value. To obtain a reference, do not specify `T`.
## When `T` is `basic_value`
```cpp
template<typename TC, typename K>
basic_value<TC>& find_or(basic_value<TC>& v, const K& key, basic_value<TC>& opt) noexcept
template<typename TC, typename K>
basic_value<TC> const& find_or(const basic_value<TC>& v, const K& key, const basic_value<TC>& opt) noexcept
```
Searches for the corresponding value and returns it without conversion. Because no conversion is needed, a reference can be returned.
If the value is not found, the default value is returned.
## When `T` is `toml::value::{some_type}`
```cpp
template<typename T, typename TC, typename K>
T& find_or(basic_value<TC>& v, const K& key, T& opt) noexcept
template<typename T, typename TC, typename K>
T const& find_or(const basic_value<TC>& v, const K& key, const T& opt) noexcept
```
Searches for the corresponding value and returns it without conversion. Because no conversion is needed, a reference can be returned.
If the value is not found or if a different type is stored, the default value is returned.
## When `T` is `const char*`
```cpp
template<typename T, typename TC, typename K>
T find_or(const basic_value<TC>& v, const K& key, T opt)
```
Searches for the corresponding value and returns it as a `std::string`.
Since the fallback is constructed from `const char*` to `std::string`, a reference cannot be returned in case of failure.
## When `T` is any other type
```cpp
template<typename T, typename TC, typename K>
T find_or(const basic_value<TC>& v, const K& key, T opt);
```
Searches for the corresponding value and converts it to `T` before returning it.
Because conversion is performed, a reference cannot be returned.
## When multiple keys are provided
```cpp
template<typename Value, typename K1, typename K2, typename K3, typename ... Ks>
auto find_or(Value&& v, const K1& k1, const K2& k2, K3&& k3, Ks&& ... keys) noexcept
-> decltype(find_or(v, k2, std::forward<K3>(k3), std::forward<Ks>(keys)...))
```
Interprets the last element in the key sequence as the default value and applies `find_or` recursively.
If the inferred type of `T` is `toml::value` or `toml::value::some_type`, a reference can be returned.
If `T` is explicitly specified, conversion is always performed.
# Related
- [get.hpp]({{<ref "get.md">}})
- [value.hpp]({{<ref "value.md">}})

View File

@@ -0,0 +1,451 @@
+++
title = "format.hpp"
type = "docs"
+++
# format.hpp
Defines structures and enumerations related to formatting information for `toml::value`.
# `indent_char`
An enumeration representing the indentation character choice.
```cpp
enum class indent_char : std::uint8_t
{
space, // use space
tab, // use tab
none // no indent
};
std::ostream& operator<<(std::ostream& os, const indent_char& c);
std::string to_string(const indent_char);
```
Choosing `none` means no indentation is used, regardless of the value in super tables.
If both `space` and `tab` are specified within the serializable value, the behavior is unspecified; typically, the unspecified indentation character appears.
# `boolean_format_info`
Formatting information for `boolean`.
```cpp
struct boolean_format_info {};
bool operator==(const boolean_format_info&, const boolean_format_info&) noexcept;
bool operator!=(const boolean_format_info&, const boolean_format_info&) noexcept;
```
There is only one way to format `boolean`, so no configurable values are provided.
# `integer_format`
```cpp
enum class integer_format : std::uint8_t
{
dec = 0,
bin = 1,
oct = 2,
hex = 3,
};
std::ostream& operator<<(std::ostream& os, const integer_format f);
std::string to_string(const integer_format);
```
Specifies the radix of an `integer`.
# `integer_format_info`
```cpp
struct integer_format_info
{
integer_format fmt = integer_format::dec;
bool uppercase = true; // use uppercase letters
std::size_t width = 0; // minimal width (may exceed)
std::size_t spacer = 0; // position of `_` (if 0, no spacer)
std::string suffix = ""; // _suffix (library extension)
};
bool operator==(const integer_format_info&, const integer_format_info&) noexcept;
bool operator!=(const integer_format_info&, const integer_format_info&) noexcept;
```
## Member Variables
### `integer_format fmt`
Specifies the radix.
### `bool uppercase`
Uses uppercase letters when formatted as a hexadecimal integer.
### `std::size_t width`
Specifies the minimum width. The formatted value may exceed this width.
For values smaller than this width, if `integer_format::dec`, no effect. Otherwise, leading zeros are added.
### `std::size_t spacer`
Specifies the width at which underscores `_` are inserted.
- If `3`, formatted as `1_234_567`.
- If `4`, formatted as `0xdead_beef`.
- If `0`, no underscores are inserted.
Irregular widths are not allowed.
### `std::string suffix`
Stores the suffix when `spec::ext_num_suffix` of toml11 extension is `true`.
cf. [spec.hpp]({{< ref "spec.md" >}})
# `floating_format`
```cpp
enum class floating_format : std::uint8_t
{
defaultfloat = 0,
fixed = 1, // does not include exponential part
scientific = 2, // always include exponential part
hex = 3 // hexfloat extension
};
std::ostream& operator<<(std::ostream& os, const floating_format f);
std::string to_string(const floating_format);
```
Specifies the formatting style for `floating` numbers.
Corresponds to `std::defaultfloat`, `std::fixed`, `std::scientific`, `std::hexfloat`.
`hexfloat` is available only if `toml::spec::ext_hex_float` is `true`.
cf. [spec.hpp]({{< ref "spec.md" >}})
# `floating_format_info`
```cpp
struct floating_format_info
{
floating_format fmt = floating_format::defaultfloat;
std::size_t prec = 0; // precision (if 0, use the default)
std::string suffix = ""; // 1.0e+2_suffix (library extension)
};
bool operator==(const floating_format_info&, const floating_format_info&) noexcept;
bool operator!=(const floating_format_info&, const floating_format_info&) noexcept;
```
## Member Variables
### `floating_format fmt`
Specifies the formatting style.
### `std::size_t prec`
Specifies the precision after the decimal point.
### `std::string suffix`
Stores the suffix when `spec::ext_num_suffix` of toml11 extension is `true`.
cf. [spec.hpp]({{< ref "spec.md" >}})
# `string_format`
```cpp
enum class string_format : std::uint8_t
{
basic = 0,
literal = 1,
multiline_basic = 2,
multiline_literal = 3
};
std::ostream& operator<<(std::ostream& os, const string_format f);
std::string to_string(const string_format);
```
Specifies the formatting style for strings.
# `string_format_info`
```cpp
struct string_format_info
{
string_format fmt = string_format::basic;
bool start_with_newline = false;
};
bool operator==(const string_format_info&, const string_format_info&) noexcept;
bool operator!=(const string_format_info&, const string_format_info&) noexcept;
```
## Member Variables
### `string_format fmt`
Specifies the formatting information for strings.
### `bool start_with_newline`
For `multiline_basic` or `multiline_literal`, specifies whether to include a newline after the initial `"""` or `'''`.
# `datetime_delimiter_kind`
```cpp
enum class datetime_delimiter_kind : std::uint8_t
{
upper_T = 0,
lower_t = 1,
space = 2,
};
std::ostream& operator<<(std::ostream& os, const datetime_delimiter_kind d);
std::string to_string(const datetime_delimiter_kind);
```
Specifies the delimiter used between date and time in `datetime`.
Possible options include `T`, `t`, and a space ` `.
# `offset_datetime_format_info`
```cpp
struct offset_datetime_format_info
{
datetime_delimiter_kind delimiter = datetime_delimiter_kind::upper_T;
bool has_seconds = true;
std::size_t subsecond_precision = 6; // [us]
};
bool operator==(const offset_datetime_format_info&, const offset_datetime_format_info&) noexcept;
bool operator!=(const offset_datetime_format_info&, const offset_datetime_format_info&) noexcept;
```
## Member Variables
### `datetime_delimiter_kind delimiter`
Specifies the delimiter to use.
### `bool has_seconds`
Specifies whether to omit seconds.
### `std::size_t subsecond_precision`
Specifies how many digits to output for subseconds.
# `local_datetime_format_info`
```cpp
struct local_datetime_format_info
{
datetime_delimiter_kind delimiter = datetime_delimiter_kind::upper_T;
bool has_seconds = true;
std::size_t subsecond_precision = 6; // [us]
};
bool operator==(const local_datetime_format_info&, const local_datetime_format_info&) noexcept;
bool operator!=(const local_datetime_format_info&, const local_datetime_format_info&) noexcept;
```
## Member Variables
### `datetime_delimiter_kind delimiter`
Specifies the delimiter to use.
### `bool has_seconds`
Specifies whether to omit seconds.
### `std::size_t subsecond_precision`
Specifies how many digits to output for subseconds.
# `local_date_format_info`
```cpp
struct local_date_format_info
{
// nothing, for now
};
bool operator==(const local_date_format_info&, const local_date_format_info&) noexcept;
bool operator!=(const local_date_format_info&, const local_date_format_info&) noexcept;
```
No formatting parameters are specified for `local_date`.
# `local_time_format_info`
```cpp
struct local_time_format_info
{
bool has_seconds = true;
std::size_t subsecond_precision = 6; // [us]
};
bool operator==(const local_time_format_info&, const local_time_format_info&) noexcept;
bool operator!=(const local_time_format_info&, const local_time_format_info&) noexcept;
```
## Member Variables
### `bool has_seconds`
Specifies whether to omit seconds.
### `std::size_t subsecond_precision`
Specifies how many digits to output for subseconds.
# `array_format`
```cpp
enum class array_format : std::uint8_t
{
default_format = 0,
oneline = 1,
multiline = 2,
array_of_tables = 3 // [[format.in.this.way]]
};
std::ostream& operator<<(std::ostream& os, const array_format f);
std::string to_string(const array_format);
```
- `default_format`
- Automatically selects the appropriate format. Longer arrays may span multiple lines.
- `oneline`
- Formats all elements in a single line.
- `multiline`
- Outputs each element on its own line.
- `array_of_tables`
- Formats in the `[[array.of.tables]]` style. Cannot contain elements other than `table`.
# `array_format_info`
```cpp
struct array_format_info
{
array_format fmt = array_format::default_format;
indent_char indent_type = indent_char::space;
std::int32_t body_indent = 4; // indent in case of multiline
std::int32_t closing_indent = 0; // indent of `]`
};
bool operator==(const array_format_info&, const array_format_info&) noexcept;
bool operator!=(const array_format_info&, const array_format_info&) noexcept;
```
## Member Variables
### `array_format fmt`
Specifies the format style.
### `indent_char indent_type`
Selects the type of character used for indentation.
### `std::int32_t body_indent`
Specifies the number of characters to indent before each element in `array_format::multiline`.
### `std::int32_t closing_indent`
Specifies the number of characters to indent before the closing bracket `]` in `array_format::multiline`.
# `table_format`
```cpp
enum class table_format : std::uint8_t
{
multiline = 0, // [foo] \n bar = "baz"
oneline = 1, // foo = {bar = "baz"}
dotted = 2, // foo.bar = "baz"
multiline_oneline = 3, // foo = { \n bar = "baz" \n }
implicit = 4 // [x] defined by [x.y.z]. skip in serializer.
};
std::ostream& operator<<(std::ostream& os, const table_format f);
std::string to_string(const table_format);
```
- `multiline`
- Formats as a multiline normal table.
- `oneline`
- Formats as an inline table.
- `dotted`
- Formats in the form of `a.b.c = "d"`.
- `multiline_oneline`
- Formats as a multiline inline table with line breaks. Available from TOML v1.1.0 onwards.
- cf. [spec.hpp]({{< ref "spec.md" >}})
- `implicit`
- Skips implicit definitions like `[x.y.z.w]`, leaving `[x]`, `[x.y]`, `[x.y.z]` as implicit.
{{< hint warning >}}
According to TOML syntax, `dotted` table can have sub-tables:
```toml
[fruit]
apple.color = "red"
apple.taste.sweet = true
# [fruit.apple] # INVALID
# [fruit.apple.taste] # INVALID
[fruit.apple.texture] # you can add sub-tables
smooth = true
```
toml11 currently does not support this format.
Sub-tables under a `dotted` table would all be `dotted`, and tables are forced into inline table format.
{{< /hint >}}
# `table_format_info`
```cpp
struct table_format_info
{
table_format fmt = table_format::multiline;
indent_char indent_type = indent_char::space;
std::int32_t body_indent = 0; // indent of values
std::int32_t name_indent = 0; // indent of [table]
std::int32_t closing_indent = 0; // in case of {inline-table}
};
bool operator==(const table_format_info&, const table_format_info&) noexcept;
bool operator!=(const table_format_info&, const table_format_info&) noexcept;
```
## Member Variables
### `table_format fmt`
Specifies the formatting method.
### `indent_char indent_type`
Specifies the character used for indentation.
### `std::int32_t body_indent`
Specifies the width of indentation before keys.
The indentation width of the super table is not added.
### `std::int32_t name_indent`
Specifies the indentation of keys in `[table]` format.
The indentation width of the super table is not added.
### `std::int32_t closing_indent`
Specifies the indentation width before the closing brace `}` in the case of `multiline_oneline`.

View File

@@ -0,0 +1,56 @@
+++
title = "from.hpp"
type = "docs"
+++
# from.hpp
Defines a `struct` used for conversion from `toml::value` in `toml::get` and `toml::find`.
You can achieve the same functionality by adding a `from_toml` member function, but for classes where you cannot add member functions, use `from<T>`.
This file does not provide specific implementations. Please specialize this `struct` when using.
```cpp
namespace toml
{
template<typename T>
struct from;
} // toml
```
## Example
```cpp
namespace extlib
{
struct foo
{
int a;
std::string b;
};
} // extlib
#include <toml11/from.hpp>
namespace toml
{
template<>
struct from<extlib::foo>
{
template<typename TC>
static extlib::foo from_toml(const toml::basic_value<TC>& v)
{
return extlib::foo{toml::find<int>(v, "a"), toml::find<std::string>(v, "b")};
}
};
} // toml
```
# Related
- [conversion.hpp]({{<ref "conversion.md">}})
- [into.hpp]({{<ref "into.md">}})

View File

@@ -0,0 +1,427 @@
+++
title = "get.hpp"
type = "docs"
+++
# get.hpp
These are functions for extracting values from `toml::value` and performing type conversions if necessary.
{{< hint info >}}
`toml::value` can change the type it stores, and `toml::get` accommodates these types.
Technically, all functions use `toml::basic_value<TC>`.
However, for simplicity, we refer to it as `toml::value` in explanations unless a distinction is necessary.
In the documentation, if the template parameter `TC` changes the type, assume that types like `toml::value::integer_type` will also change accordingly.
{{< /hint >}}
# `toml::get<T>`
## Overview
Generally, `toml::get` behaves as follows:
You specify `T` as in `toml::get<int>(v)`.
```cpp
template<typename T, typename TC>
T get(const basic_value<TC>& v);
```
However, depending on the type of `T`, `toml::get` can exhibit different behaviors.
The types of `T` can be categorized into:
1. Types that do not require conversion
2. Types that require conversion
Detailed conditions and the specific types supported are discussed later.
### Types that Do Not Require Conversion
No conversion is needed if the provided `toml::value` is already storing the desired type. For instance, since `toml::value::integer_type` is an alias for `std::int64_t`, `toml::get<std::int64_t>(v)` requires no conversion. In this case, `toml::get` retrieves the `integer` value from `toml::value` and returns a reference to it.
If the provided `toml::value` is a mutable reference (`&`), the returned value is also a mutable reference (`&`). If it is an immutable reference (`const&`), the returned value will also be an immutable reference (`const&`). Returning a mutable reference allows you to overwrite the value stored in `toml::value` through that reference.
### Types that Require Conversion
Types other than the ones mentioned above require conversion. For example, since `toml::value::integer_type` is an alias for `std::int64_t`, `toml::get<std::size_t>(toml::value&)` requires conversion. In this case, `toml::get` retrieves the `integer` value from `toml::value` and casts it to return the appropriate type.
toml11 supports not only simple casts but also complex type conversions like converting from `toml::array` to `std::tuple<int, double, std::string>`, `std::array<double, 4>`, or from `toml::table` to `std::map<std::string, int>`. For specifics, refer to the subsequent sections.
### When Conversion Fails
Sometimes, the expected type conversion cannot be performed. For example, applying `toml::get<int>(v)` to a `toml::value` that holds a `table`.
In such cases, an attempt to convert to the type most similar to the desired type (in this case, `int` using `as_integer`) fails, and a `toml::type_error` is thrown.
When parsing from a file, an error message similar to the following is output:
```
terminate called after throwing an instance of 'toml::type_error'
what(): toml::value::as_integer(): bad_cast to integer
--> input.toml
|
6 | [fruit]
| ^^^^^^^-- the actual type is table
```
## When `T` is identical to `toml::value`
```cpp
template<typename T, typename TC>
T& get(basic_value<TC>& v);
template<typename T, typename TC>
T const& get(const basic_value<TC>& v);
template<typename T, typename TC>
T get(basic_value<TC>&& v);
```
Condition:
- `std::is_same<T, basic_value<TC>>` is satisfied.
Since this involves retrieving `toml::value` from `toml::value`, no conversion is performed, and the value is returned as is. This exists solely to generalize the implementation of other functions.
This does not fail.
## When `T` is one of `toml::value::{some_type}`
```cpp
template<typename T, typename TC>
T& get(basic_value<TC>& v);
template<typename T, typename TC>
T const& get(const basic_value<TC>& v);
template<typename T, typename TC>
T get(basic_value<TC>&& v);
```
Condition:
- `T` must be the same as one of the types that `toml::value` can store (e.g., `toml::value::boolean_type`).
If `toml::value` is storing a type that matches the specified type in `toml::get<T>`, such as `toml::value::integer_type`, no type conversion is needed, and a reference can be returned.
If a different type is stored, a `toml::type_error` is thrown.
## When `T` is `basic_value<OtherTC>` with a different `TypeConfig`
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
Condition:
- `T` is not `toml::basic_value<TC>`.
- `T` is `toml::basic_value<OtherTC>`.
When a `basic_value` that can store different types is specified, conversion is performed.
Since type conversion occurs, the returned value is a new value and not a reference.
This does not fail (except in cases like memory exhaustion).
## When `T` is an integer type
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
Condition:
- `std::is_integral<T>` is satisfied
- `T` is not `bool`
- `T` is not `toml::value::integer_type`
The function assumes that `toml::value` holds an `integer_type`, retrieves its value, converts it to `T`, and returns it.
If a type other than `toml::value::integer_type` is stored, a `toml::type_error` is thrown.
## When `T` is a floating-point type
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
Condition:
- `std::is_floating_point<T>` is satisfied
- `T` is not `toml::value::floating_type`
The function assumes that `toml::value` holds a `floating_type`, retrieves its value, converts it to `T`, and returns it.
If a type other than `toml::value::floating_type` is stored, a `toml::type_error` is thrown.
## When `T` is `std::string_view`
This is only available in C++17 and later.
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
Condition:
- `std::is_same<std::string_view, T>` is satisfied
The function assumes that `toml::value` holds a `string_type`, retrieves its value, constructs a `std::string_view` from it, and returns it.
If a type other than `toml::value::string_type` is stored, a `toml::type_error` is thrown.
## When `T` is `std::chrono::duration`
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
Condition:
- `T` is `std::chrono::duration<Rep, Period>`
The function assumes that `toml::value` holds a `local_time`, retrieves its value, converts it to `std::chrono::duration`, and returns it.
If a type other than `toml::value::local_time` is stored, a `toml::type_error` is thrown.
## When `T` is `std::chrono::system_clock::time_point`
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
Condition:
- `std::is_same<T, std::chrono::system_clock::time_point>` is satisfied
If the `toml::value` holds a `local_date`, `local_datetime`, or `offset_datetime`, this function retrieves the value and converts it to `std::chrono::system_clock::time_point`, returning the result.
If the value is of a type other than `local_date`, `local_datetime`, or `offset_datetime`, a `toml::type_error` is thrown.
## When `T` is array-like
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
Conditions:
- `T` has an `iterator`
- `T` has a `value_type`
- `T` supports `push_back(x)`
- `T` is not `toml::value::array_type`
- `T` is not `std::string`
- `T` is not `std::string_view`
- `T` is not map-like
- `T` does not have `from_toml()` member function
- `toml::from<T>` is not defined
- A constructor from `toml::basic_value<TC>` is not defined
This includes types like `std::vector<int>` and `std::deque<std::string>`.
If the `toml::value` holds an `array`, this function retrieves the value and converts it to the specified container type, returning the result.
If the value is of a type other than `toml::value::array_type`, a `toml::type_error` is thrown.
## When `T` is `std::array`
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
条件:
- `T` is `std::array<U, N>`
If the `toml::value` holds an `array`, this function retrieves the value and converts it to the specified container type, returning the result.
If the value is of a type other than `toml::value::array_type`, a `toml::type_error` is thrown.
If the `array` held by `toml::value` does not contain enough elements, a `std::out_of_range` is thrown.
## When `T` is `std::forward_list`
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
Condition:
- `T` is `std::forward_list<U>`
If the `toml::value` holds an `array`, this function retrieves the value and converts it to a `std::forward_list`, returning the result.
If the value is of a type other than `toml::value::array_type`, a `toml::type_error` is thrown.
## When `T` is `std::pair`
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
Condition:
- `T` is `std::pair<T1, T2>`
If the `toml::value` holds an `array`, this function retrieves the value and converts it to `std::pair<T1, T2>`, returning the result.
The `first` and `second` elements are recursively converted.
If the value is of a type other than `basic_value::array_type`, a `toml::type_error` is thrown.
If the `array` held by `toml::value` does not contain exactly 2 elements, a `std::out_of_range` is thrown.
## When `T` is `std::tuple`
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
Condition:
- `T` is `std::tuple<T1, T2, ... TN>`
If the `toml::value` holds an `array`, this function retrieves the value and converts it to `std::tuple<T1, T2, ...TN>`, returning the result.
Each element is recursively converted.
If the value is of a type other than `basic_value::array_type`, a `toml::type_error` is thrown.
If the `array` held by `toml::value` does not contain exactly `std::tuple_size<T>::value` elements, a `std::out_of_range` is thrown.
## When `T` is map-like
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
Conditions:
- `T` has an `iterator`
- `T` has a `key_type`
- `T` has a `value_type`
- `T` has a `mapped_type`
- `T` is not `toml::value::table_type`
- `T` does not have a `from_toml()` member function
- `toml::from<T>` is not defined
- A constructor from `toml::basic_value<TC>` is not defined
This includes types like `std::map<std::string, int>` and `std::unordered_map<std::string, float>`.
If the `toml::value` holds a `table`, this function retrieves the value and converts it to `T`, returning the result.
Elements are recursively converted.
If the value is of a type other than `basic_value::table_type`, a `toml::type_error` is thrown.
## When `T` is a user-defined type with a specialization of `toml::from<T>`
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
Condition:
- A specialization of `toml::from<T>` is defined
If a specialization of `toml::from` for `T` is defined, it is used for type conversion.
Ensure this does not conflict with individually supported types (`std::array`, `std::pair`, `std::tuple` etc).
## When `T` is a user-defined type with a `from_toml` member function
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
Conditions:
- `toml::from<T>` is not defined
- `T` has `from_toml()` member function
If `T` has a `from_toml(toml::basic_value<TC>)` member function, it is used for type conversion.
If `toml::from<T>` is defined, it takes precedence.
## When `T` is a user-defined type with a constructor that takes `toml::basic_value<TC>`
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
Conditions:
- `toml::from<T>` is not defined
- `T` does not have `from_toml()` member function
- `T` has a constructor that takes `toml::basic_value<TC>`
If `T` has a constructor that takes `toml::basic_value<TC>`, it is used for type conversion.
If `toml::from<T>` or `T::from_toml` is defined, they take precedence.
# `toml::get_or<T>`
`get_or` takes a default value for use when the conversion fails, avoiding exceptions.
The default value must be of the same type as the target type `T`.
Therefore, unlike `toml::get<T>`, `T` can be inferred in `get_or`.
## When `T` is `basic_value<TC>`
```cpp
template<typename TC>
basic_value<TC> const& get_or(const basic_value<TC>& v, const basic_value<TC>& opt)
template<typename TC>
basic_value<TC> & get_or(basic_value<TC>& v, basic_value<TC>& opt)
template<typename TC>
basic_value<TC> get_or(basic_value<TC>&& v, basic_value<TC>&& opt)
```
Since the conversion target is the same `toml::value`, this never fails.
It exists solely to generalize the implementation of other functions.
## When `T` is `basic_value<TC>::{some_type}`
```cpp
template<typename T, typename TC>
T const& get_or(const basic_value<TC>& v, const T& opt) noexcept
template<typename T, typename TC>
T & get_or(basic_value<TC>& v, T& opt) noexcept
template<typename T, typename TC>
T get_or(basic_value<TC>&& v, T&& opt) noexcept
```
Performs the same conversion as `toml::get<T>`. If it fails, the second argument is returned.
## When `T` is `const char*`
```cpp
template<typename TC>
typename basic_value<TC>::string_type
get_or(const basic_value<TC>& v,
const typename basic_value<TC>::string_type::value_type* opt);
```
When `const char*` is passed, the conversion target is interpreted as `std::string`.
## When `T` is something else
```cpp
template<typename TC>
typename std::remove_cv<typename std::remove_reference<T>::type>::type
get_or(const basic_value<TC>& v, T&& opt);
```
Performs the same conversion as `toml::get<T>`. If it fails, the second argument is returned.
# Related
- [find.hpp]({{<ref "find.md">}})
- [from.hpp]({{<ref "from.md">}})
- [value.hpp]({{<ref "value.md">}})

View File

@@ -0,0 +1,58 @@
+++
title = "into.hpp"
type = "docs"
+++
# into.hpp
Defines a `struct` used for conversion from user-defined types into `toml::value` constructors.
You can achieve the same functionality by adding an `into_toml` member function, but for classes where you cannot add member functions, use `into<T>`.
This file does not provide specific implementations. Please specialize this `struct` when using.
```cpp
namespace toml
{
template<typename T>
struct into;
} // toml
```
## Example
```cpp
namespace extlib
{
struct foo
{
int a;
std::string b;
};
} // extlib
#include <toml11/into.hpp>
namespace toml
{
template<>
struct into<extlib::foo>
{
template<typename TC>
static toml::basic_value<TC> into_toml(const extlib::foo& f)
{
using value_type = toml::basic_value<TC>;
using table_type = typename value_type::table_type;
return value_type(table_type{{"a", f.a}, {"b", f.b}});
}
};
} // toml
```
# Related
- [conversion.hpp]({{<ref "conversion.md">}})
- [from.hpp]({{<ref "from.md">}})

View File

@@ -0,0 +1,82 @@
+++
title = "literal.hpp"
type = "docs"
+++
# literal.hpp
In `literal.hpp`, the `_toml` literal is defined.
The `_toml` literal parses string literals into `toml::value`.
```cpp
namespace toml
{
inline namespace literals
{
inline namespace toml_literals
{
toml::value operator"" _toml(const char* str, std::size_t len);
toml::value operator"" _toml(const char8_t* str, std::size_t len); // Available in C++20 and later
} // toml_literals
} // literals
} // toml
```
## Free Functions
### `operator"" _toml(const char*)`
```cpp
toml::value operator"" _toml(const char* str, std::size_t len);
```
Converts a string literal into a `toml::value` by parsing it.
For typical TOML files, this performs equivalent parsing to `toml::parse`.
```cpp
const auto v1 = "a = 'foo'"_toml; // v1: {a = 'foo'}
```
When dealing with multiline content, raw string literal is convenient.
```cpp
const auto v1 = R"(
a = 42
b = "foo"
)"_toml;
```
If the value is a standalone entity, it represents that value.
```cpp
const auto v2 = "'foo'"_toml; // v2: 'foo'
```
TOML allows keys consisting solely of numbers. When distinguishing between table definitions and arrays is ambiguous (e.g., `[1]`), table definitions take precedence.
To interpret as an array, use a trailing comma.
```cpp
const auto v3 = "[1]"_toml; // v3: {1 = {}}
const auto v4 = "[1,]"_toml; // v4: [1,]
```
### `operator"" _toml(const char8_t*)`
Defined when `char8_t` is available. Otherwise identical in functionality, differing only in argument type.
# Example
```cpp
#include <toml.hpp>
int main()
{
using namespace toml::literals::toml_literals;
const auto v = "a = \"foo\""_toml;
assert(v.at("a").as_string() == "foo");
return 0;
}
```

View File

@@ -0,0 +1,355 @@
+++
title = "ordered_map.hpp"
type = "docs"
+++
# ordered_map.hpp
Defines `toml::ordered_map`, which is used to maintain the order of values in a file.
# `class ordered_map`
```cpp
namespace toml
{
template<typename Key, typename Val, typename Cmp = std::equal_to<Key>,
typename Allocator = std::allocator<std::pair<Key, Val>>>
class ordered_map;
}
```
The `ordered_map` is a `map` type that preserves the insertion order of values, allowing iteration in that order.
As a linear container, searches require `O(n)` time relative to the number of elements.
Use this when search operations are infrequent and maintaining the order of values is important.
## Non-Member Types
```cpp
namespace toml
{
struct ordered_type_config;
using ordered_value = basic_value<ordered_type_config>;
using ordered_table = typename ordered_value::table_type;
using ordered_array = typename ordered_value::array_type;
}
```
Use these in place of `toml::type_config` and `toml::value`.
{{< hint info >}}
Since `toml::parse` defaults to using `type_config`, specify
```cpp
const auto input = toml::parse<toml::ordered_type_config>("input.toml");
```
when parsing.
{{< /hint >}}
## Member Types
```cpp
using key_type = Key;
using mapped_type = Val;
using value_type = std::pair<Key, Val>;
using key_compare = Cmp;
using allocator_type = Allocator;
using container_type = std::vector<value_type, Allocator>;
using reference = typename container_type::reference;
using pointer = typename container_type::pointer;
using const_reference = typename container_type::const_reference;
using const_pointer = typename container_type::const_pointer;
using iterator = typename container_type::iterator;
using const_iterator = typename container_type::const_iterator;
using size_type = typename container_type::size_type;
using difference_type = typename container_type::difference_type;
```
## Member Functions
### Constructors
```cpp
ordered_map() = default;
```
Constructs an empty `ordered_map`.
### Constructors (Comparator, Allocator)
```cpp
explicit ordered_map(const Cmp& cmp, const Allocator& alloc = Allocator());
explicit ordered_map(const Allocator& alloc);
```
Constructs an `ordered_map` with a specified comparator for key comparison and an allocator for memory management.
### Copy and Move Constructors
```cpp
ordered_map(const ordered_map&) = default;
ordered_map(ordered_map&&) = default;
ordered_map(const ordered_map& other, const Allocator& alloc);
ordered_map(ordered_map&& other, const Allocator& alloc);
```
Constructs an `ordered_map` by copying or moving the contents from another `ordered_map`.
An allocator can also be specified for memory management.
### Constructors (Iterator)
```cpp
template<typename InputIterator>
ordered_map(InputIterator first, InputIterator last, const Cmp& cmp = Cmp(), const Allocator& alloc = Allocator());
template<typename InputIterator>
ordered_map(InputIterator first, InputIterator last, const Allocator& alloc = Allocator());
```
Constructs an `ordered_map` with a range represented by iterators.
The order of the elements follows the order of the iterators.
### Constructors (std::initializer_list)
```cpp
ordered_map(std::initializer_list<value_type> v, const Cmp& cmp = Cmp(), const Allocator& alloc = Allocator());
ordered_map(std::initializer_list<value_type> v, const Allocator& alloc);
```
Initializes the `ordered_map` using an initializer list.
### Copy and Move Assignment Operators
```cpp
ordered_map& operator=(const ordered_map&) = default;
ordered_map& operator=(ordered_map&&) = default;
```
Assigns the contents of another `ordered_map` to this one, using copy or move semantics.
### Assignment Operator (std::initializer_list)
```cpp
ordered_map& operator=(std::initializer_list<value_type> v);
```
Assigns the contents of an initializer list to the `ordered_map`.
### Destructor
```cpp
~ordered_map() = default;
```
Destroys the `ordered_map`.
### `begin()`, `end()`
```cpp
iterator begin() noexcept;
iterator end() noexcept;
const_iterator begin() const noexcept;
const_iterator end() const noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
```
Returns iterators to the beginning and end of the container, allowing iteration over its contents in order.
### `empty()`
```cpp
bool empty() const noexcept;
```
Returns `true` if the `ordered_map` is empty, `false` otherwise.
### `size()`
```cpp
std::size_t size() const noexcept;
```
Returns the number of elements in the `ordered_map`.
### `max_size()`
```cpp
std::size_t max_size() const noexcept;
```
Returns the maximum number of elements the `ordered_map` can hold.
### `clear()`
```cpp
void clear();
```
Clears all elements from the `ordered_map`.
### `push_back(kv)`
```cpp
void push_back(const value_type&);
void push_back(value_type&&);
```
Appends a key-value pair to the end of the `ordered_map`.
### `emplace_back(k, v)`
```cpp
void emplace_back(key_type, mapped_type);
```
Appends a key-value pair to the end of the `ordered_map` by constructing it in place.
### `pop_back()`
```cpp
void pop_back();
```
Removes the last element from the `ordered_map`.
### `insert(kv)`
```cpp
void insert(value_type);
```
Inserts a key-value pair at the end of the `ordered_map`.
### `emplace(k, v)`
```cpp
void emplace(key_type, mapped_type);
```
Inserts a key-value pair at the end of the `ordered_map` by constructing it in place.
### `count(k)`
```cpp
std::size_t count(const key_type&) const noexcept;
```
Returns the number of elements with the specified key.
Since duplicate keys are not allowed, this will return either `1` if the key exists or `0` if it does not.
### `contains(k)`
```cpp
bool contains(const key_type&) const noexcept;
```
Returns `true` if the `ordered_map` contains an element with the specified key, `false` otherwise.
### `find(k)`
```cpp
iterator find(const key_type& key) noexcept;
const_iterator find(const key_type& key) const noexcept;
```
Finds an element with the specified key and returns an iterator to it. If the key is not found, returns `end()`.
### `at(k)`
```cpp
mapped_type& at(const key_type& k);
mapped_type const& at(const key_type& k) const;
```
Finds an element with the specified key and returns a reference to its value. Throws `std::out_of_range` if the key is not found.
### `operator[](k)`
```cpp
mapped_type& operator[](const key_type& k);
mapped_type const& operator[](const key_type& k) const;
```
Finds an element with the specified key and returns a reference to its value.
If the key is not found, a new value is constructed and returned.
If the `ordered_map` is `const`, throws `std::out_of_range` instead.
### `erase(...)`
```cpp
iterator erase(iterator pos);
iterator erase(const_iterator pos);
iterator erase(const_iterator first, const_iterator last);
size_type erase(const key_type& key);
```
Removes values pointed by an iterator or a value corresponding to a key.
### `key_comp()`
```cpp
key_compare key_comp() const;
```
Returns the comparator used for key comparison.
## Notes
### Key Modification
{{< hint warning >}}
Since `ordered_map` uses `std::pair<Key, Val>` for `value_type`, it is possible to modify the key through an iterator. However, this practice is not recommended.
If you modify a key this way and it conflicts with an existing key, one of the conflicting keys will become unsearchable.
When using `operator[]`, `push_back`, or `insert`, collisions with existing keys are detected.
{{< /hint >}}
### Order Preservation Details
{{< hint warning >}}
`ordered_map` maintains the order of keys, but this order preservation applies only to keys defined within the same table. Order across different tables is not maintained.
For example, the order in the following file will be preserved:
```cpp
apple.type = "fruit"
apple.skin = "thin"
apple.color = "red"
orange.type = "fruit"
orange.skin = "thick"
orange.color = "orange"
```
In contrast, the order in the following file will not be preserved:
```cpp
apple.type = "fruit"
orange.type = "fruit"
apple.skin = "thin"
orange.skin = "thick"
apple.color = "red"
orange.color = "orange"
```
`ordered_map` preserves the order of the `apple` and `orange` definitions at the root table level, and the order of `type`, `skin`, `color` within each `apple` and `orange` table.
{{< /hint >}}
## Related
- [parser.hpp]({{<ref "parser.md">}})
- [types.hpp]({{<ref "types.md">}})
- [value.hpp]({{<ref "value.md">}})

View File

@@ -0,0 +1,383 @@
+++
title = "parser.hpp"
type = "docs"
+++
# parser.hpp
Defines functions for parsing files or strings and the exceptions they use.
While `parse` throws an exception on failure, `try_parse` returns error information.
# `parse`
Parses the content of a given file and returns a `toml::basic_value`.
In case of failure, `toml::syntax_error` is thrown.
The type information of `basic_value` is provided by a `template`, and the TOML language version is specified by `toml::spec`.
### `parse(std::string filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
basic_value<TC>
parse(std::string fname,
spec s = spec::default_version());
}
```
Parses the content of the given filename.
If reading the file fails, `toml::file_io_error` is thrown.
If parsing fails, `toml::syntax_error` is thrown.
### `parse(const char (&)[N] filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config, std::size_t N>
basic_value<TC>
parse(const char (&fname)[N],
spec s = spec::default_version());
}
```
Parses the content of the given filename from a string literal.
If reading the file fails, `toml::file_io_error` is thrown.
If parsing fails, `toml::syntax_error` is thrown.
### `parse(std::filesystem::path, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
basic_value<TC>
parse(const std::filesystem::path& fpath,
spec s = spec::default_version());
}
```
This is defined only if `<filesystem>` is available.
Parses the content of the file at the given file path.
If reading the file fails, `toml::file_io_error` is thrown.
If parsing fails, `toml::syntax_error` is thrown.
### `parse(std::istream&, std::string filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
basic_value<TC>
parse(std::istream& is,
std::string fname = "unknown file",
spec s = spec::default_version());
}
```
Parses the content of the given `std::istream&`.
Open a stream in binary mode by passing `std::ios::binary` to avoid inconsistency between the file size and the number of characters due to automatic conversion of newline characters by the standard library.
The filename information is taken as the third argument. If the filename is not provided, it defaults to `"unknown file"`.
### `parse(FILE*, std::string filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
result<basic_value<TC>, std::vector<error_info>>
parse(FILE* fp,
std::string filename,
spec s = spec::default_version());
}
```
Parses the content of the file pointed to by `FILE*`.
Open a stream in binary mode by passing `"rb"` to avoid inconsistency between the file size and the number of characters due to automatic conversion of newline characters by the standard library.
If reading the file fails, `file_io_error` containing `errno` is thrown.
If parsing fails, `syntax_error` is thrown.
### `parse(std::vector<unsigned char>, std::string filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
basic_value<TC>
parse(std::vector<unsigned char> content,
std::string filename,
spec s = spec::default_version());
}
```
Parses the byte sequence as a TOML file.
If parsing fails, `toml::syntax_error` is thrown.
# `parse_str`
### `parse_str(std::string, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
basic_value<TC>
parse_str(std::string content,
spec s = spec::default_version(),
cxx::source_location loc = cxx::source_location::current());
}
```
Parses a string as a TOML file.
In case of failure, `toml::syntax_error` is thrown.
The type information of `basic_value` is provided by a `template`, and the TOML language version is specified by `toml::spec`.
You generally don't need to manually set the third argument, `cxx::source_location`.
If `std::source_location`, `std::experimental::source_location`, or `__builtin_FILE` is available,
the location information where `parse_str` was called will be stored.
# `try_parse`
Parses the contents of the given file and returns a `toml::basic_value` if successful, or a `std::vector<toml::error_info>` if it fails.
The type information of `basic_value` is specified by `template`, and the version of the TOML language is specified by `toml::spec`.
{{< hint warning >}}
Unlike `parse`, `try_parse` does not throw exceptions defined in toml11 such as `syntax_error`.
However, please note that exceptions thrown by the standard library will still propagate.
For instance, errors occurring internally within `std::ifstream` or memory exhaustion in `std::vector` will throw exceptions.
{{< /hint >}}
### `try_parse(std::string filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
result<basic_value<TC>, std::vector<error_info>>
try_parse(std::string fname,
spec s = spec::default_version());
}
```
Takes a file name and parses its content.
If parsing fails, a `result` holding the error type `std::vector<error_info>` is returned.
If successful, a `result` holding a `basic_value` is returned.
### `try_parse(const char (&)[N] filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config, std::size_t N>
result<basic_value<TC>, std::vector<error_info>>
try_parse(const char (&fname)[N],
spec s = spec::default_version());
}
```
Takes a string literal as a file name and parses its content.
If parsing fails, a `result` holding the error type `std::vector<error_info>` is returned.
If successful, a `result` holding a `basic_value` is returned.
### `try_parse(std::filesystem::path, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
result<basic_value<TC>, std::vector<error_info>>
try_parse(const std::filesystem::path& fpath,
spec s = spec::default_version());
}
```
Takes a file path and parses its content.
If parsing fails, a `result` holding the error type `std::vector<error_info>` is returned.
If successful, a `result` holding a `basic_value` is returned.
### `try_parse(std::istream&, std::string filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
result<basic_value<TC>, std::vector<error_info>>
try_parse(std::istream& is,
std::string fname = "unknown file",
spec s = spec::default_version());
}
```
Takes a `std::istream&` and parses its content.
Open a stream in binary mode by passing `std::ios::binary` to avoid inconsistency between the file size and the number of characters due to automatic conversion of newline characters by the standard library.
The file name information is taken as the second argument. If a file name is not provided, it defaults to `"unknown file"`.
If parsing fails, a `result` holding the error type `std::vector<error_info>` is returned.
If successful, a `result` holding a `basic_value` is returned.
### `try_parse(FILE*, std::string filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
result<basic_value<TC>, std::vector<error_info>>
try_parse(FILE* fp,
std::string filename,
spec s = spec::default_version());
}
```
Takes a `FILE*` and parses its content.
Open a stream in binary mode by passing `"rb"` to avoid inconsistency between the file size and the number of characters due to automatic conversion of newline characters by the standard library.
If parsing fails, a `result` holding the error type `std::vector<error_info>` is returned.
If successful, a `result` holding a `basic_value` is returned.
### `try_parse(std::vector<unsigned char>, std::string filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
result<basic_value<TC>, std::vector<error_info>>
try_parse(std::vector<unsigned char> content,
std::string filename,
spec s = spec::default_version());
}
```
Takes a byte array and parses its content as a TOML file.
If parsing fails, a `result` holding the error type `std::vector<error_info>` is returned.
If successful, a `result` holding a `basic_value` is returned.
# `try_parse_str`
### `try_parse_str(std::string, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
result<basic_value<TC>, std::vector<error_info>>
try_parse_str(std::string content,
spec s = spec::default_version(),
cxx::source_location loc = cxx::source_location::current());
}
```
Parses a string as a TOML file, returning a `toml::basic_value` if successful, or a `std::vector<toml::error_info>` if it fails.
Unlike `parse_str`, it does not throw `syntax_error`, but instead returns error information as the failure type of the `result`.
If `std::source_location`, `std::experimental::source_location`, or `__builtin_FILE` is available, it will record the location information.
Typically, you do not need to manually set the third argument `cxx::source_location`. If any of `std::source_location`, `std::experimental::source_location`, or `__builtin_FILE` are available, the information of the location where `parse_str` was called will be saved as the location information.
{{< hint warning >}}
Unlike `parse`, `try_parse` does not throw exceptions defined in toml11 such as `syntax_error`. However, please note that exceptions thrown by the standard library will still propagate.
For instance, errors occurring internally within `std::ifstream` or memory exhaustion in `std::vector` will throw exceptions.
{{< /hint >}}
# `syntax_error`
```cpp
namespace toml
{
struct syntax_error final : public ::toml::exception
{
public:
syntax_error(std::string what_arg, std::vector<error_info> err);
~syntax_error() noexcept override = default;
const char* what() const noexcept override;
std::vector<error_info> const& errors() const noexcept
};
}
```
An exception thrown when a syntax error is detected in TOML.
It is thrown by `parse` but not by `try_parse`.
# `file_io_error`
```cpp
namespace toml
{
struct file_io_error final : public ::toml::exception
{
public:
file_io_error(const std::string& msg, const std::string& fname);
file_io_error(int errnum, const std::string& msg, const std::string& fname);
~file_io_error() noexcept override = default;
const char* what() const noexcept override;
bool has_errno() const noexcept;
int get_errno() const noexcept;
};
}
```
An exception thrown when reading the contents of a file fails.
When using `FILE*` to read a file, `errno` is set.
### `has_errno`
If `std::ifstream` fails, `errno` is not set.
In this case, `has_errno` returns `false`.
### `get_errno`
Particularly when passing a `FILE*`, retrieves the value of `errno`.
If `has_errno` is `false`, it returns `0`.
# Related
- [error_info.hpp]({{<ref "error_info.md">}})
- [result.hpp]({{<ref "result.md">}})
- [spec.hpp]({{<ref "spec.md">}})
- [value.hpp]({{<ref "value.md">}})

View File

@@ -0,0 +1,518 @@
+++
title = "result.hpp"
type = "docs"
+++
# result.hpp
`result.hpp` defines the `result` type, which can hold either a success value or a failure value.
This is used as the return type for `toml::try_parse`, which does not throw exceptions.
# success
A type that holds a success value.
```cpp
namespace toml
{
template<typename T>
struct success
{
using value_type = T;
explicit success(value_type v);
~success() = default;
success(const success&) = default;
success(success&&) = default;
success& operator=(const success&) = default;
success& operator=(success&&) = default;
template<typename U>
explicit success(U&& v);
template<typename U>
explicit success(success<U> v);
value_type& get() noexcept;
value_type const& get() const noexcept;
};
template<typename T>
success<typename std::decay<T>::type> ok(T&& v);
template<std::size_t N>
success<std::string> ok(const char (&literal)[N])
}
```
## Member Types
```cpp
using value_type = T;
```
The type of the success value.
## Member Functions
### Constructor
```cpp
explicit success(value_type v);
```
Constructs with a `value_type` argument.
```cpp
template<typename U>
explicit success(U&& v);
```
Constructs with another type that can be converted to `value_type`.
```cpp
template<typename U>
explicit success(success<U> v);
```
Constructs with another `success` type that can be converted to `value_type`.
### `get()`
```cpp
value_type& get() noexcept;
value_type const& get() const noexcept;
```
Accesses the stored value.
## Non-Member Functions
### `ok(T)`
```cpp
template<typename T>
success<typename std::decay<T>::type> ok(T&& v);
template<std::size_t N>
success<std::string> ok(const char (&literal)[N]);
```
Constructs and returns a `success` type from a success value.
Converts a string literal into `std::string`.
# `success<reference_wrapper<T>>`
Specialization of `success` for when the success value is a reference.
```cpp
namespace toml
{
template<typename T>
struct success<std::reference_wrapper<T>>
{
using value_type = T;
explicit success(std::reference_wrapper<value_type> v) noexcept;
value_type& get() noexcept;
value_type const& get() const noexcept;
};
}
```
## Member Types
```cpp
using value_type = T;
```
The type of the success value. It is `T` from `std::reference_wrapper<T>`, not the reference itself.
### `get()`
```cpp
value_type& get() noexcept;
value_type const& get() const noexcept;
```
Accesses the stored value.
# failure
A type that holds a failure value.
```cpp
namespace toml
{
template<typename T>
struct failure
{
using value_type = T;
explicit failure(value_type v);
~failure() = default;
failure(const failure&) = default;
failure(failure&&) = default;
failure& operator=(const failure&) = default;
failure& operator=(failure&&) = default;
template<typename U>
explicit failure(U&& v);
template<typename U>
explicit failure(failure<U> v);
value_type& get() noexcept;
value_type const& get() const noexcept;
};
template<typename T>
failure<typename std::decay<T>::type> err(T&& v);
template<std::size_t N>
failure<std::string> err(const char (&literal)[N]);
}
```
## Member Types
```cpp
using value_type = T;
```
The type of the failure value.
## Member Functions
### Constructor
```cpp
explicit failure(value_type v);
```
Constructs with a `value_type` argument.
```cpp
template<typename U>
explicit failure(U&& v);
```
Constructs with another type that can be converted to `value_type`.
```cpp
template<typename U>
explicit failure(failure<U> v);
```
Constructs with another `failure` type that can be converted to `value_type`.
### `get()`
```cpp
value_type& get() noexcept;
value_type const& get() const noexcept;
```
Accesses the stored value.
## Non-Member Functions
### `err(T)`
```cpp
template<typename T>
failure<typename std::decay<T>::type> err(T&& v);
template<std::size_t N>
failure<std::string> err(const char (&literal)[N]);
```
Constructs and returns a `failure` type from a failure value.
Converts a string literal into `std::string`.
# `failure<reference_wrapper<T>>`
Specialization of `failure` for when the failure value is a reference.
```cpp
namespace toml
{
template<typename T>
struct failure<std::reference_wrapper<T>>
{
using value_type = T;
explicit failure(std::reference_wrapper<value_type> v) noexcept;
value_type& get() noexcept {return value.get();}
value_type const& get() const noexcept {return value.get();}
};
}
```
## Member Types
```cpp
using value_type = T;
```
The type of the failure value. It is `T` from `std::reference_wrapper<T>`, not the reference itself.
### `get()`
```cpp
value_type& get() noexcept;
value_type const& get() const noexcept;
```
Accesses the stored value.
# result
A type that holds either a success value or a failure value.
```cpp
namespace toml
{
template<typename T, typename E>
struct result
{
using success_type = success<T>;
using failure_type = failure<E>;
using value_type = typename success_type::value_type;
using error_type = typename failure_type::value_type;
result(success_type s);
result(failure_type f);
template<typename U>
result(success<U> s);
template<typename U>
result(failure<U> f);
result& operator=(success_type s);
result& operator=(failure_type f);
template<typename U>
result& operator=(success<U> s);
template<typename U>
result& operator=(failure<U> f);
~result() noexcept;
result(const result& other);
result(result&& other);
result& operator=(const result& other);
result& operator=(result&& other);
template<typename U, typename F>
result(result<U, F> other);
template<typename U, typename F>
result& operator=(result<U, F> other);
bool is_ok() const noexcept;
bool is_err() const noexcept;
explicit operator bool() const noexcept;
value_type& unwrap(cxx::source_location loc = cxx::source_location::current());
value_type const& unwrap(cxx::source_location loc = cxx::source_location::current()) const;
value_type& unwrap_or(value_type& opt) noexcept;
value_type const& unwrap_or(value_type const& opt) const noexcept;
error_type& unwrap_err(cxx::source_location loc = cxx::source_location::current());
error_type const& unwrap_err(cxx::source_location loc = cxx::source_location::current()) const;
value_type& as_ok() noexcept;
value_type const& as_ok() const noexcept;
error_type& as_err() noexcept;
error_type const& as_err() const noexcept;
};
}
```
## Member Types
### `success_type`
`success<T>`.
### `failure_type`
`failure<E>`.
### `value_type`
The type `T` of the success value, alias for `success_type::value_type`.
If `T` is `std::reference_wrapper<U>`, then it is `U`.
### `error_type`
The type `E` of the failure value, alias for `failure_type::value_type`.
If `E` is `std::reference_wrapper<F>`, then it is `F`.
## Member Functions
### Constructor
```cpp
result() = delete;
```
Cannot construct `result` type by default. Needs to be given either a success or failure type.
```cpp
result(success_type s);
result(failure_type f);
```
Constructs with a `success_type` or `failure_type`.
```cpp
template<typename U>
result(success<U> s);
template<typename U>
result(failure<U> f);
```
Constructs with a `success<U>` or `failure<U>` that is convertible to `value_type` or `error_type`.
```cpp
template<typename U, typename F>
result(result<U, F> other);
template<typename U, typename F>
result& operator=(result<U, F> other);
```
Constructs from or assigns to another `result` with convertible `success` or `failure` types.
### Copy and Move Constructors
```cpp
result(const result& other);
result(result&& other);
```
Can be copy or move constructed.
### `operator=`
```cpp
result& operator=(const result& other);
result& operator=(result&& other);
```
Can be copy or move assigned.
```cpp
template<typename U>
result& operator=(success<U> s);
template<typename U>
result& operator=(failure<U> f);
```
Can be assigned from convertible `success` or `failure` types.
### `is_ok()`
```cpp
bool is_ok() const noexcept;
```
Returns `true` if it holds a success value, `false` otherwise.
### `is_err()`
```cpp
bool is_err() const noexcept;
```
Returns `true` if it holds a failure value, `false` otherwise.
### `operator bool()`
```cpp
explicit operator bool() const noexcept;
```
Returns `true` if it holds a success value, `false` otherwise.
### `unwrap()`
```cpp
value_type& unwrap(cxx::source_location loc = cxx::source_location::current());
value_type const& unwrap(cxx::source_location loc = cxx::source_location::current()) const;
```
Returns the stored success value.
Throws `toml::bad_result_access` if it holds a failure value.
If `std::source_location` or equivalent compiler extension is available, the file name and line number where `unwrap()` occurred are included in the `what()` string.
### `unwrap_or()`
```cpp
value_type& unwrap_or(value_type& opt) noexcept;
value_type const& unwrap_or(value_type const& opt) const noexcept;
```
Returns the stored success value if present, otherwise returns the provided default value.
### `unwrap_err()`
```cpp
error_type& unwrap_err(cxx::source_location loc = cxx::source_location::current());
error_type const& unwrap_err(cxx::source_location loc = cxx::source_location::current()) const;
```
Returns the stored failure value.
Throws `toml::bad_result_access` if it holds a success value.
If `std::source_location` or equivalent compiler extension is available, the file name and line number where `unwrap_err()` occurred are included in the `what()` string.
### `as_ok()`
```cpp
value_type& as_ok() noexcept;
value_type const& as_ok() const noexcept;
```
Returns the success value without checking.
Behavior is undefined if it holds a failure value.
### `as_err()`
```cpp
error_type& as_err() noexcept;
error_type const& as_err() const noexcept;
```
Returns the failure value without checking.
Behavior is undefined if it holds a success value.
# bad_result_access
An exception thrown when `unwrap` or `unwrap_err` fails in a `result`.
```cpp
namespace toml
{
struct bad_result_access : public ::toml::exception
{
public:
explicit bad_result_access(const std::string& what_arg);
virtual ~bad_result_access() noexcept override = default;
virtual const char* what() const noexcept override;
protected:
std::string what_;
};
}
```

View File

@@ -0,0 +1,65 @@
+++
title = "serializer.hpp"
type = "docs"
+++
# serializer.hpp
## `format`
Serializes the data.
```cpp
namespace toml
{
template<typename TC>
std::string format(const basic_value<TC>& v,
const spec s = spec::default_version());
template<typename TC>
std::string format(const typename basic_value<TC>::key_type& k,
const basic_value<TC>& v,
const spec s = spec::default_version());
template<typename TC>
std::string format(const std::vector<typename basic_value<TC>::key_type>& ks,
const basic_value<TC>& v,
const spec s = spec::default_version());
}
```
If there's a conflict between the format information and the `spec`, for example, when using `v1.0.0` with `table_format::multiline_oneline`, the `spec` takes precedence.
### `format(v, spec)`
Formats a `toml::value` according to its format information and the provided `spec`.
If it's a `table_type`, it's formatted as if it were the root table. Otherwise, only the value is formatted.
### `format(k, v, spec)`
Formats a `toml::value` along with the given key.
`v` is interpreted as being defined under that key.
### `format([k,...], v, spec)`
`v` is interpreted as being defined under those keys.
If multiple keys are provided, it's interpreted as a recursively defined table.
## `serialization_error`
Reports errors that occurred during serialization.
```cpp
namespace toml
{
struct serialization_error final : public ::toml::exception
{
public:
explicit serialization_error(std::string what_arg, source_location loc);
~serialization_error() noexcept override = default;
const char* what() const noexcept override;
source_location const& location() const noexcept;
};
}
```

View File

@@ -0,0 +1,235 @@
+++
title = "source_location.hpp"
type = "docs"
+++
# source_location.hpp
`source_location.hpp` defines a class representing a specific area within a TOML file.
This class is used to represent problematic areas in error messages.
# `toml::source_location`
`source_location` is a class representing a specific area within a TOML file.
```cpp
namespace toml
{
struct source_location
{
public:
explicit source_location(/* implementation-defined */);
~source_location() = default;
source_location(source_location const&) = default;
source_location(source_location &&) = default;
source_location& operator=(source_location const&) = default;
source_location& operator=(source_location &&) = default;
bool is_ok() const noexcept;
std::size_t length() const noexcept;
std::size_t first_line_number() const noexcept;
std::size_t first_column_number() const noexcept;
std::size_t last_line_number() const noexcept;
std::size_t last_column_number() const noexcept;
std::string const& file_name() const noexcept;
std::size_t num_lines() const noexcept;
std::string const& first_line() const;
std::string const& last_line() const;
std::vector<std::string> const& lines() const noexcept;
};
template<typename ... Ts>
std::string format_location(const source_location& loc, const std::string& msg, const Ts& ... locs_and_msgs);
} //toml
```
## Member Functions
### Constructor
```cpp
explicit source_location(/* implementation-defined */);
```
`toml::source_location` can only be constructed via `toml::parse` or the `_toml` literal.
### `is_ok()`
```cpp
bool is_ok() const noexcept;
```
Returns `true` if the `source_location` holds a valid value, `false` otherwise.
The result of `location()` from `toml::value` constructed outside of `toml::parse` or `_toml` literals returns `false` for `is_ok` as it points to nothing.
### `length()`
```cpp
std::size_t length() const noexcept;
```
Returns the length of the area pointed to by the `source_location`.
Returns `0` if it does not hold a valid value.
### `first_line_number()`
```cpp
std::size_t first_line_number() const noexcept;
```
Returns the line number of the first line of the area pointed to by the `source_location`.
Returns `1` if it does not hold a valid value.
### `first_column_number()`
```cpp
std::size_t first_column_number() const noexcept;
```
Returns the column number of the first column of the area pointed to by the `source_location`.
Returns `1` if it does not hold a valid value.
### `last_line_number()`
```cpp
std::size_t last_line_number() const noexcept;
```
Returns the line number of the last line of the area pointed to by the `source_location`.
Returns `1` if it does not hold a valid value.
### `last_column_number()`
```cpp
std::size_t last_column_number() const noexcept;
```
Returns the column number of the last column of the area pointed to by the `source_location`.
Returns `1` if it does not hold a valid value.
### `file_name()`
```cpp
std::string const& file_name() const noexcept;
```
Returns the file name containing the area pointed to by the `source_location`.
Returns `"unknown file"` if it does not hold a valid value.
### `num_lines()`
```cpp
std::size_t num_lines() const noexcept;
```
Returns the number of lines in the area pointed to by the `source_location`.
Returns `0` if it does not hold a valid value.
### `first_line()`
```cpp
std::string const& first_line() const;
```
Returns the first line of the area pointed to by the `source_location`.
Throws `std::out_of_range` if it does not hold a valid value.
### `last_line()`
```cpp
std::string const& last_line() const;
```
Returns the last line of the area pointed to by the `source_location`.
Throws `std::out_of_range` if it does not hold a valid value.
### `lines()`
```cpp
std::vector<std::string> const& lines() const noexcept;
```
Returns all lines in the area pointed to by the `source_location`.
Returns a reference to an empty `std::vector` if it does not hold a valid value.
## Non-Member Functions
### `format_location`
```cpp
template<typename ... Ts>
std::string format_location(const source_location& loc, const std::string& msg,
const Ts& ... locs_and_msgs);
```
Formats the specified `source_location` and its associated message as follows:
```
-> {filename.toml}
|
1 | a = 42
| ^-- {message}
```
If colorization is enabled, ANSI escape sequences will be added for coloring.
When multiple `locs_and_msgs` are provided, they must be in the order of `const source_location&` followed by `const std::string&`, and the next pair in the same order, and so on.
#### Example: Multiple `source_location` and `std::string`
When multiple `source_location` and `std::string` pairs are provided, they are formatted as follows:
```cpp
source_location& loc0;
source_location& loc1;
source_location& loc2;
std::string msg0;
std::string msg1;
std::string msg2;
format_location(loc0, msg0,
loc1, msg1,
loc2, msg2);
```
```
-> {filename0.toml}
|
1 | a = 42
| ^-- {message0}
|
-> {filename1.toml}
|
2 | b = 3.14
| ^-- {message1}
|
-> {filename2.toml}
|
3 | c = "foo"
| ^-- {message2}
```
# Related
- [error_info.hpp]({{<ref "error_info.md">}})
- [value.hpp]({{<ref "value.md">}})

View File

@@ -0,0 +1,309 @@
+++
title = "spec.hpp"
type = "docs"
+++
# spec.hpp
`spec.hpp` defines classes for specifying the version of TOML.
# `toml::semantic_version`
`semantic_version` is a class that stores version information.
```cpp
namespace toml
{
struct semantic_version
{
constexpr semantic_version(std::uint32_t mjr, std::uint32_t mnr, std::uint32_t p) noexcept;
std::uint32_t major;
std::uint32_t minor;
std::uint32_t patch;
};
constexpr semantic_version
make_semver(std::uint32_t major, std::uint32_t minor, std::uint32_t patch) noexcept;
constexpr bool operator==(const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator!=(const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator< (const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator<=(const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator> (const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator>=(const semantic_version&, const semantic_version&) noexcept;
std::ostream& operator<<(std::ostream& os, const semantic_version& ver);
} //toml
```
## Member Functions
### Constructor
```cpp
constexpr semantic_version(std::uint32_t mjr, std::uint32_t mnr, std::uint32_t p) noexcept;
```
Constructs a `semantic_version` instance with the specified `major`, `minor`, and `patch` version numbers.
## Non-Member Functions
### Comparison Operators
```cpp
constexpr bool operator==(const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator!=(const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator< (const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator<=(const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator> (const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator>=(const semantic_version&, const semantic_version&) noexcept;
```
Compares two `semantic_version` instances according to semantic versioning rules.
### Stream Operator
```cpp
std::ostream& operator<<(std::ostream& os, const semantic_version& ver);
```
Outputs the version in the format `{major}.{minor}.{patch}`.
### `to_string`
```cpp
std::string to_string(const semantic_version& ver);
```
Converts the version to a string in the format `{major}.{minor}.{patch}`.
# `toml::spec`
`spec` is a class that stores TOML version information.
```cpp
struct spec
{
constexpr static spec default_version() noexcept;
constexpr static spec v(std::uint32_t mjr, std::uint32_t mnr, std::uint32_t p) noexcept;
constexpr explicit spec(const semantic_version& semver) noexcept;
semantic_version version; // toml version
// diff from v1.0.0 -> v1.1.0
bool v1_1_0_allow_control_characters_in_comments;
bool v1_1_0_allow_newlines_in_inline_tables;
bool v1_1_0_allow_trailing_comma_in_inline_tables;
bool v1_1_0_allow_non_english_in_bare_keys;
bool v1_1_0_add_escape_sequence_e;
bool v1_1_0_add_escape_sequence_x;
bool v1_1_0_make_seconds_optional;
// library extensions
bool ext_hex_float; // allow hex float
bool ext_num_suffix; // allow number suffix
bool ext_null_value; // allow null value
};
```
## Member Functions
### Constructor
```cpp
constexpr explicit spec(const semantic_version& semver) noexcept;
```
Constructs a `spec` with the specified TOML version.
Supports TOML v1.0.0 and TOML v1.1.0.
### `default_version()`
```cpp
constexpr static spec default_version() noexcept;
```
Constructs a `spec` with the default version.
Used as the default value for `toml::parse` and `toml::format`.
In toml11 v4.4.0, the value is v1.0.0.
### `v(major, minor, patch)`
```cpp
constexpr static spec v(std::uint32_t mjr, std::uint32_t mnr, std::uint32_t p) noexcept;
```
Constructs a `spec` with the specified version.
## Member Variables
Each flag is automatically set to `true` when the specified version includes the corresponding feature.
You can modify these flags to change the behavior of `toml::parse` and `toml::format`.
{{<hint warning>}}
Some features of TOML v1.1.0 are still under fairly lengthy discussion and may still be reverted.
If they are indeed reverted, toml11 will remove those features in a minor version upgrade or move them to a corresponding later version.
As such, any features related to future versions should be considered unstable.
{{</hint>}}
### Example
```cpp
auto spec = toml::spec::v(1, 0, 0);
// Allow newlines in inline tables in addition to v1.0.0 features.
// Other v1.1.0 features are not enabled.
spec.v1_1_0_allow_newlines_in_inline_tables = true;
auto input = toml::parse("input_file.toml", spec);
```
### `v1_1_0_allow_control_characters_in_comments`
```cpp
bool v1_1_0_allow_control_characters_in_comments;
```
Allows most control characters in comments.
Added in TOML v1.1.0.
### `v1_1_0_allow_newlines_in_inline_tables`
```cpp
bool v1_1_0_allow_newlines_in_inline_tables;
```
Allows newlines in inline tables.
Added in TOML v1.1.0.
### `v1_1_0_allow_trailing_comma_in_inline_tables`
```cpp
bool v1_1_0_allow_trailing_comma_in_inline_tables;
```
Allows trailing commas in inline tables.
Added in TOML v1.1.0.
### `v1_1_0_add_escape_sequence_e`
```cpp
bool v1_1_0_add_escape_sequence_e;
```
Allows `\e` to represent the ESC character.
Added in TOML v1.1.0.
### `v1_1_0_add_escape_sequence_x`
```cpp
bool v1_1_0_add_escape_sequence_x;
```
Allows `\xHH` to represent a single byte character.
Added in TOML v1.1.0.
### `v1_1_0_make_seconds_optional`
```cpp
bool v1_1_0_make_seconds_optional;
```
Makes the seconds component in time optional.
Unspecified seconds default to `0`.
Added in TOML v1.1.0.
### `ext_hex_float`
```cpp
bool ext_hex_float;
```
This is a language extension specific to toml11.
It is initialized to `false` regardless of the specified version.
You must explicitly set it to `true` if you want to use it.
Allows hexadecimal representation of floating-point numbers.
The hexadecimal representation conforms to the `printf` format specifier `%a/%A`.
```
hexf = 0xC0FFEEp-10
```
`toml::format` will format using hexadecimal notation only if the passed `toml::spec` has `ext_hex_float` set to `true`.
If the format specifier indicates `hex` but the `toml::spec` passed to `toml::format` has `ext_hex_float` set to `false`, the hexadecimal specification is ignored, and the number is output in decimal notation with maximum precision.
### `ext_num_suffix`
```cpp
bool ext_num_suffix;
```
This is a language extension specific to toml11.
It is initialized to `false` regardless of the specified version.
You must explicitly set it to `true` if you want to use it.
Allows the addition of suffixes to decimal integers and floating-point numbers. This does not apply to hexadecimal, octal, or binary notations.
There must be an `_` separator between the number and the suffix.
The suffix cannot start with a digit to avoid confusion with the numeric part.
```
distance = 10_m # valid
distance = 10_2m # invalid
distance = 10_2_m # valid
```
The suffix is stored in the format information as `std::string suffix`.
The `_` separating the number from the suffix is not included in the `suffix`.
```cpp
toml::value distance = toml::find(input, "distance");
assert(distance.as_integer_fmt().suffix == std::string("m"));
```
`toml::format` will format the value with the suffix only if the passed `toml::spec` has `ext_num_suffix` set to `true`.
The `suffix` follows the grammar defined as:
```abnf
non-digit-graph = ALPHA / non-ascii
graph = ALPHA / DIGIT / non-ascii
suffix = _ non-digit-graph *( graph / ( _ graph ) )
```
### `ext_null_value`
```cpp
bool ext_null_value;
```
This is a language extension specific to toml11.
Allows the use of `null` as a value.
A `toml::value` specified as `null` will have no value, and `is_empty()` will return `true`.
`toml::format` will format it as `null` only if the passed `toml::spec` has `ext_null_value` set to `true`.
Otherwise, `toml::format` will terminate with an error.

View File

@@ -0,0 +1,13 @@
+++
title = "toml.hpp"
type = "docs"
+++
# toml.hpp
`toml.hpp` includes all other headers.
This allows access to all features of toml11.
This header file and `toml_fwd.hpp` are located under `${TOML11_INCLUDE_DIR}/`,
while other header files are located under `${toml11_include_dir}/toml11/`.

View File

@@ -0,0 +1,18 @@
+++
title = "toml_fwd.hpp"
type = "docs"
+++
# toml_fwd.hpp
`toml_fwd.hpp` contains forward declarations of structures defined in toml11 and macro definitions.
When only forward declarations of toml11 structures are needed and implementation is not required, including `toml_fwd.hpp` instead of `toml.hpp` can reduce compilation time.
{{<hint warning>}}
Since this file only contains forward declarations, you cannot use `toml::table`, defined as `toml::basic_value<toml::type_config>::table_type`, and similarly defined `toml::array`. This is because they require the implementation of `basic_value`.
{{</hint>}}
This header file and `toml.hpp` are located under `${TOML11_INCLUDE_DIR}/`, while other header files are located under `${TOML11_INCLUDE_DIR}/toml11/`.

View File

@@ -0,0 +1,156 @@
+++
title = "types.hpp"
type = "docs"
+++
# types.hpp
This document defines classes that specifies type information.
# `type_config`
`type_config` is a type that encapsulates parameters given to `toml::basic_value`.
When using different types within `toml::basic_value<T>`, you need to define and pass this type separately.
All elements listed are required.
If you use numerical types that cannot use standard stream operators, define and replace the equivalents for `read_int` and `read_float`.
```cpp
namespace toml
{
struct type_config
{
using comment_type = preserve_comments;
using boolean_type = bool;
using integer_type = std::int64_t;
using floating_type = double;
using string_type = std::string;
template<typename T>
using array_type = std::vector<T>;
template<typename K, typename T>
using table_type = std::unordered_map<K, T>;
static result<integer_type, error_info>
parse_int(const std::string& str, const source_location src, const std::uint8_t base);
static result<floating_type, error_info>
parse_float(const std::string& str, const source_location src, const bool is_hex);
};
using value = basic_value<type_config>;
using table = typename value::table_type;
using array = typename value::array_type;
} // toml
```
## `static` Member Functions
### `parse_int(str, src, base)`
```cpp
static result<integer_type, error_info>
parse_int(const std::string& str, const source_location src, const std::uint8_t base);
```
If you use a type as `integer_type` that cannot utilize standard stream operators, implement this function.
Otherwise, use `read_int` described later.
The `str` parameter receives a string with prefixes, leading zeros, and underscores removed.
The `src` parameter receives a `source_location` pointing to where the string was defined.
The `base` parameter receives one of `10`, `2`, `8`, or `16`.
### `parse_float(str, src, is_hex)`
```cpp
static result<floating_type, error_info>
parse_float(const std::string& str, const source_location src, const bool is_hex);
```
If you use a type as `floating_type` that cannot utilize standard stream operators, implement this function.
Otherwise, use `read_float` described later.
The `str` parameter receives a string with prefixes, leading zeros, and underscores removed.
The `src` parameter receives a `source_location` pointing to where the string was defined.
The `is_hex` parameter indicates whether the format is `hexfloat`. If you don't use the `hexfloat` extension, you don't need to implement this.
For details on the `hexfloat` extension, refer to [spec.hpp]({{<ref "spec.md">}}).
## Non-member Functions
### `read_int`
```cpp
template<typename T>
result<T, error_info>
read_int(const std::string& str, const source_location src, const std::uint8_t base);
```
This is the default function used. It parses using `std::istringstream`.
If `operator>>` and manipulators like `std::hex`, and `std::numeric_limits<T>` are defined (such as for `boost::multiprecision`), you can use this without modifications.
### `read_float`
```cpp
template<typename T>
result<T, error_info>
read_float(const std::string& str, const source_location src, const bool is_hex);
```
This is the default function used. It parses decimals using `std::istringstream` and hexfloats using `sscanf()`.
It supports `double` and `float`.
For other types, if `operator>>` is defined and `hex` is not used, you can use this function.
# `ordered_type_config`
`ordered_type_config` is a variation of `toml::type_config` where the table type is replaced with `toml::ordered_map`.
Additionally, it defines the `toml::ordered_value` alias.
Other than these changes, it is identical to `type_config`.
```cpp
namespace toml
{
struct ordered_type_config
{
using comment_type = preserve_comments;
using boolean_type = bool;
using integer_type = std::int64_t;
using floating_type = double;
using string_type = std::string;
template<typename T>
using array_type = std::vector<T>;
template<typename K, typename T>
using table_type = ordered_map<K, T>;
static result<integer_type, error_info>
parse_int(const std::string& str, const source_location src, const std::uint8_t base)
{
return read_int<integer_type>(str, src, base);
}
static result<floating_type, error_info>
parse_float(const std::string& str, const source_location src, const bool is_hex)
{
return read_float<floating_type>(str, src, is_hex);
}
};
using ordered_value = basic_value<ordered_type_config>;
using ordered_table = typename ordered_value::table_type;
using ordered_array = typename ordered_value::array_type;
} // toml
```

View File

@@ -0,0 +1,913 @@
+++
title = "value.hpp"
type = "docs"
+++
# value.hpp
`value.hpp` defines `basic_value`.
# `toml::basic_value`
`basic_value` is a class that stores TOML values.
```cpp
namespace toml
{
template <class TypeConfig>
class basic_value;
// Defined in types.hpp
// using value = basic_value<type_config>;
// using table = typename basic_value<type_config>::table_type;
// using array = typename basic_value<type_config>::array_type;
template<typename TC>
bool operator==(const basic_value<TC>&, const basic_value<TC>&);
template<typename TC>
bool operator!=(const basic_value<TC>&, const basic_value<TC>&);
template<typename TC>
bool operator< (const basic_value<TC>&, const basic_value<TC>&);
template<typename TC>
bool operator<=(const basic_value<TC>&, const basic_value<TC>&);
template<typename TC>
bool operator> (const basic_value<TC>&, const basic_value<TC>&);
template<typename TC>
bool operator>=(const basic_value<TC>&, const basic_value<TC>&);
} //toml
```
## Member Types
The following member types are defined.
You can modify the member types using `TypeConfig`.
See also: [types.hpp]({{<ref "types.md">}})
| Name | Definition |
|:-----------------------|:-------------------------------------|
| `char_type` | `typename TypeConfig::char_type` |
| `key_type` | `typename TypeConfig::string_type` |
| `value_type` | `basic_value<TypeConfig>` |
| `boolean_type` | `typename TypeConfig::boolean_type` |
| `integer_type` | `typename TypeConfig::integer_type` |
| `floating_type` | `typename TypeConfig::floating_type` |
| `string_type` | `typename TypeConfig::string_type` |
| `local_time_type` | `toml::local_time` |
| `local_date_type` | `toml::local_date` |
| `local_datetime_type` | `toml::local_datetime` |
| `offset_datetime_type` | `toml::offset_datetime` |
| `array_type` | `typename TypeConfig::template array_type<value_type>`|
| `table_type` | `typename TypeConfig::template table_type<key_type, value_type>`|
| `comment_type` | `typename TypeConfig::comment_type` |
## Member Functions
### Default Constructor
```cpp
basic_value() noexcept
```
Constructs an empty `toml::value`.
The constructed `toml::value` will be empty.
### Copy and Move Constructors
```cpp
basic_value(const basic_value& v)
basic_value(basic_value&& v)
```
Copies or moves all information including values, format information, comments, and file regions.
### Copy and Move Constructors with Comments
```cpp
basic_value(basic_value v, std::vector<std::string> com)
```
Copies or moves the object while overwriting comments.
### Conversion Constructors
```cpp
template<typename TI>
basic_value(basic_value<TI> other)
template<typename TI>
basic_value(basic_value<TI> other, std::vector<std::string> com)
```
Copies or moves from a `basic_value` with a different `type_config`.
### Constructor (boolean)
```cpp
basic_value(boolean_type x)
basic_value(boolean_type x, boolean_format_info fmt)
basic_value(boolean_type x, std::vector<std::string> com)
basic_value(boolean_type x, boolean_format_info fmt, std::vector<std::string> com)
```
Constructs an object with a `bool`, its format information, and comments.
### Constructor (integer)
```cpp
template<typename T, /* std::is_integral<T> is true */>
basic_value(T x)
template<typename T, /* std::is_integral<T> is true */>
basic_value(T x, integer_format_info fmt)
template<typename T, /* std::is_integral<T> is true */>
basic_value(T x, std::vector<std::string> com)
template<typename T, /* std::is_integral<T> is true */>
basic_value(T x, integer_format_info fmt, std::vector<std::string> com)
```
Constructs an object with an `integer`, its format information, and comments.
### Constructor (floating)
```cpp
template<typename T, /* std::is_floating_point<T> is true */>
basic_value(T x)
template<typename T, /* std::is_floating_point<T> is true */>
basic_value(T x, floating_format_info fmt)
template<typename T, /* std::is_floating_point<T> is true */>
basic_value(T x, std::vector<std::string> com)
template<typename T, /* std::is_floating_point<T> is true */>
basic_value(T x, floating_format_info fmt, std::vector<std::string> com)
```
Constructs an object with a `floating` point number, its format information, and comments.
### Constructor (string)
```cpp
basic_value(string_type x)
basic_value(string_type x, string_format_info fmt)
basic_value(string_type x, std::vector<std::string> com)
basic_value(string_type x, string_format_info fmt, std::vector<std::string> com)
basic_value(const string_type::value_type* x)
basic_value(const string_type::value_type* x, string_format_info fmt)
basic_value(const string_type::value_type* x, std::vector<std::string> com)
basic_value(const string_type::value_type* x, string_format_info fmt, std::vector<std::string> com)
// C++17以降
basic_value(string_view_type x)
basic_value(string_view_type x, string_format_info fmt)
basic_value(string_view_type x, std::vector<std::string> com)
basic_value(string_view_type x, string_format_info fmt, std::vector<std::string> com)
```
Constructs an object with a `string`, its format information, and comments.
`string_view_type` shares the same `value_type` and `traits_type` as `string_type`.
### Constructor (local_date)
```cpp
basic_value(local_date_type x)
basic_value(local_date_type x, local_date_format_info fmt)
basic_value(local_date_type x, std::vector<std::string> com)
basic_value(local_date_type x, local_date_format_info fmt, std::vector<std::string> com)
```
Constructs an object with a `local_date_type`, its format information, and comments.
### Constructor (local_time)
```cpp
basic_value(local_time_type x)
basic_value(local_time_type x, local_time_format_info fmt)
basic_value(local_time_type x, std::vector<std::string> com)
basic_value(local_time_type x, local_time_format_info fmt, std::vector<std::string> com)
template<typename Rep, typename Period>
basic_value(const std::chrono::duration<Rep, Period>& x)
template<typename Rep, typename Period>
basic_value(const std::chrono::duration<Rep, Period>& x, local_time_format_info fmt)
template<typename Rep, typename Period>
basic_value(const std::chrono::duration<Rep, Period>& x, std::vector<std::string> com)
template<typename Rep, typename Period>
basic_value(const std::chrono::duration<Rep, Period>& x, local_time_format_info fmt, std::vector<std::string> com)
```
Constructs an object with a `local_time_type`, its format information, and comments.
For `std::chrono::duration`, constructs as a time span from `00:00:00`.
### Constructor (local_datetime)
```cpp
basic_value(local_datetime_type x)
basic_value(local_datetime_type x, local_date_format_info fmt)
basic_value(local_datetime_type x, std::vector<std::string> com)
basic_value(local_datetime_type x, local_date_format_info fmt, std::vector<std::string> com)
```
Constructs an object with a `local_datetime_type`, its format information, and comments.
### Constructor (offset_datetime)
```cpp
basic_value(offset_datetime_type x)
basic_value(offset_datetime_type x, offset_date_format_info fmt)
basic_value(offset_datetime_type x, std::vector<std::string> com)
basic_value(offset_datetime_type x, offset_date_format_info fmt, std::vector<std::string> com)
basic_value(std::chrono::system_clock::time_point x)
basic_value(std::chrono::system_clock::time_point x, offset_date_format_info fmt)
basic_value(std::chrono::system_clock::time_point x, std::vector<std::string> com)
basic_value(std::chrono::system_clock::time_point x, offset_date_format_info fmt, std::vector<std::string> com)
```
Constructs an object with an `offset_datetime_type`, its format information, and comments.
For `std::chrono::system_clock::time_point`, constructs for the pointed time.
### Constructor (array)
```cpp
basic_value(array_type x)
basic_value(array_type x, integer_format_info fmt)
basic_value(array_type x, std::vector<std::string> com)
basic_value(array_type x, integer_format_info fmt, std::vector<std::string> com)
template<typename T, /* T is array-like */>
basic_value(T x)
template<typename T, /* T is array-like */>
basic_value(T x, array_format_info fmt)
template<typename T, /* T is array-like */>
basic_value(T x, std::vector<std::string> com)
template<typename T, /* T is array-like */>
basic_value(T x, array_format_info fmt, std::vector<std::string> com)
```
Constructs an object with an `array`, its format information, and comments.
`array-like` types must meet the following criteria:
- Has `T::iterator`.
- Has `T::value_type`.
- Does **not** have `T::key_type`.
- Does **not** have `T::mapped_type`.
- Is **not** `std::string`.
- Is **not** `std::string_view` (since C++17).
### Constructor (table)
```cpp
basic_value(table_type x)
basic_value(table_type x, integer_format_info fmt)
basic_value(table_type x, std::vector<std::string> com)
basic_value(table_type x, integer_format_info fmt, std::vector<std::string> com)
template<typename T, /* T is table-like */>
basic_value(T x)
template<typename T, /* T is table-like */>
basic_value(T x, table_format_info fmt)
template<typename T, /* T is table-like */>
basic_value(T x, std::vector<std::string> com)
template<typename T, /* T is table-like */>
basic_value(T x, table_format_info fmt, std::vector<std::string> com)
```
Constructs an object with a `table`, its format information, and comments.
`table-like` types must meet the following criteria:
- Has `T::iterator`.
- Has `T::value_type`.
- Has `T::key_type`.
- Has `T::mapped_type`.
### Constructor (user-defined)
```cpp
template<typename T /* toml::into<T> is defined */>
basic_value(const T& ud);
template<typename T /* toml::into<T> is defined */>
basic_value(const T& ud, std::vector<std::string> com);
template<typename T /* toml::into<T> is not defined, but T{}.into_toml() exists */>
basic_value(const T& ud);
template<typename T /* toml::into<T> is not defined, but T{}.into_toml() exists */>
basic_value(const T& ud, std::vector<std::string> com);
```
If `toml::into<T>` is defined, constructs from the result of `toml::into<T>(ud)`.
If `toml::into<T>` is not defined but `T` has a `into_toml()` member function, constructs from the result of `ud.into_toml()`.
-----
### `operator=(basic_value)`
```cpp
basic_value& operator=(const basic_value& v)
basic_value& operator=(basic_value&& v)
template<typename TI>
basic_value& operator=(basic_value<TI> other)
```
Assigns the right-hand side `basic_value` to the current object.
### `operator=(T)`
```cpp
template<typename T>
basic_value& operator=(T x)
```
Assigns a value corresponding to `T`.
The contents pointed to by `source_location` are discarded.
If the object already holds a value of the same type, the original format information is retained.
-----
### `is<T>()`
```cpp
bool is<T>() const noexcept
```
#### Requirements
`T` must be an exact TOML type, meaning it corresponds to one of the `toml::value::xxx_type`.
#### Return Value
Returns `true` if the stored type matches `T`, otherwise returns `false`.
-----
### `is(toml::value_t)`
```cpp
bool is(toml::value_t t) const noexcept
```
#### Return Value
Returns `true` if the tag of the stored type matches `t`, otherwise returns `false`.
-----
### `is_xxx()`
```cpp
bool is_boolean() const noexcept;
bool is_integer() const noexcept;
bool is_floating() const noexcept;
bool is_string() const noexcept;
bool is_offset_datetime() const noexcept;
bool is_local_datetime() const noexcept;
bool is_local_date() const noexcept;
bool is_local_time() const noexcept;
bool is_array() const noexcept;
bool is_table() const noexcept;
```
#### Return Value
Returns `true` if the stored type matches the corresponding type, otherwise returns `false`.
------
### `is_empty()`
```cpp
bool is_empty() const noexcept;
```
#### Return Value
Returns `true` if the object is default constructed and no value is assigned, otherwise returns `false`.
### `is_array_of_tables()`
```cpp
bool is_array_of_tables() const noexcept;
```
#### Return Value
Returns `true` if the stored type is an array that is not empty and all elements are tables, otherwise returns `false`.
-----
### `type()`
```cpp
toml::value_t type() const noexcept
```
#### Return Value
Returns the tag corresponding to the stored type.
-----
### `as_xxx()`
```cpp
boolean_type const& as_boolean () const;
integer_type const& as_integer () const;
floating_type const& as_floating () const;
string_type const& as_string () const;
offset_datetime_type const& as_offset_datetime() const;
local_datetime_type const& as_local_datetime () const;
local_date_type const& as_local_date () const;
local_time_type const& as_local_time () const;
array_type const& as_array () const;
table_type const& as_table () const;
boolean_type & as_boolean ();
integer_type & as_integer ();
floating_type & as_floating ();
string_type & as_string ();
offset_datetime_type& as_offset_datetime();
local_datetime_type & as_local_datetime ();
local_date_type & as_local_date ();
local_time_type & as_local_time ();
array_type & as_array ();
table_type & as_table ();
```
#### Return Value
Returns a reference to the value of the specified type.
#### Exception
Throws `toml::type_error` if the stored value's type does not match the specified type.
-----
### `as_xxx(std::nothrow)`
Invoke with a `std::nothrow` object.
```cpp
boolean_type const& as_boolean (const std::nothrow_t&) const noexcept;
integer_type const& as_integer (const std::nothrow_t&) const noexcept;
floating_type const& as_floating (const std::nothrow_t&) const noexcept;
string_type const& as_string (const std::nothrow_t&) const noexcept;
offset_datetime_type const& as_offset_datetime(const std::nothrow_t&) const noexcept;
local_datetime_type const& as_local_datetime (const std::nothrow_t&) const noexcept;
local_date_type const& as_local_date (const std::nothrow_t&) const noexcept;
local_time_type const& as_local_time (const std::nothrow_t&) const noexcept;
array_type const& as_array (const std::nothrow_t&) const noexcept;
table_type const& as_table (const std::nothrow_t&) const noexcept;
boolean_type & as_boolean (const std::nothrow_t&) noexcept;
integer_type & as_integer (const std::nothrow_t&) noexcept;
floating_type & as_floating (const std::nothrow_t&) noexcept;
string_type & as_string (const std::nothrow_t&) noexcept;
offset_datetime_type& as_offset_datetime(const std::nothrow_t&) noexcept;
local_datetime_type & as_local_datetime (const std::nothrow_t&) noexcept;
local_date_type & as_local_date (const std::nothrow_t&) noexcept;
local_time_type & as_local_time (const std::nothrow_t&) noexcept;
array_type & as_array (const std::nothrow_t&) noexcept;
table_type & as_table (const std::nothrow_t&) noexcept;
```
#### Return Value
Returns a reference to the value of the specified type.
#### Note
If the type of the stored value does not match the specified type, the behavior is undefined.
-----
### `as_xxx_fmt()`
Accesses format information.
```cpp
boolean_format_info & as_boolean_fmt ();
integer_format_info & as_integer_fmt ();
floating_format_info & as_floating_fmt ();
string_format_info & as_string_fmt ();
offset_datetime_format_info& as_offset_datetime_fmt();
local_datetime_format_info & as_local_datetime_fmt ();
local_date_format_info & as_local_date_fmt ();
local_time_format_info & as_local_time_fmt ();
array_format_info & as_array_fmt ();
table_format_info & as_table_fmt ();
boolean_format_info const& as_boolean_fmt () const;
integer_format_info const& as_integer_fmt () const;
floating_format_info const& as_floating_fmt () const;
string_format_info const& as_string_fmt () const;
offset_datetime_format_info const& as_offset_datetime_fmt() const;
local_datetime_format_info const& as_local_datetime_fmt () const;
local_date_format_info const& as_local_date_fmt () const;
local_time_format_info const& as_local_time_fmt () const;
array_format_info const& as_array_fmt () const;
table_format_info const& as_table_fmt () const;
```
#### Return Value
Returns a reference to the structure holding the format information for the specified type.
#### Exception
Throws `toml::type_error` if the stored value's type does not match the specified type.
-----
### `as_xxx_fmt(std::nothrow)`
Invoke with a `std::nothrow` object.
```cpp
boolean_format_info & as_boolean_fmt (const std::nothrow_t&) noexcept;
integer_format_info & as_integer_fmt (const std::nothrow_t&) noexcept;
floating_format_info & as_floating_fmt (const std::nothrow_t&) noexcept;
string_format_info & as_string_fmt (const std::nothrow_t&) noexcept;
offset_datetime_format_info& as_offset_datetime_fmt(const std::nothrow_t&) noexcept;
local_datetime_format_info & as_local_datetime_fmt (const std::nothrow_t&) noexcept;
local_date_format_info & as_local_date_fmt (const std::nothrow_t&) noexcept;
local_time_format_info & as_local_time_fmt (const std::nothrow_t&) noexcept;
array_format_info & as_array_fmt (const std::nothrow_t&) noexcept;
table_format_info & as_table_fmt (const std::nothrow_t&) noexcept;
boolean_format_info const& as_boolean_fmt (const std::nothrow_t&) const noexcept;
integer_format_info const& as_integer_fmt (const std::nothrow_t&) const noexcept;
floating_format_info const& as_floating_fmt (const std::nothrow_t&) const noexcept;
string_format_info const& as_string_fmt (const std::nothrow_t&) const noexcept;
offset_datetime_format_info const& as_offset_datetime_fmt(const std::nothrow_t&) const noexcept;
local_datetime_format_info const& as_local_datetime_fmt (const std::nothrow_t&) const noexcept;
local_date_format_info const& as_local_date_fmt (const std::nothrow_t&) const noexcept;
local_time_format_info const& as_local_time_fmt (const std::nothrow_t&) const noexcept;
array_format_info const& as_array_fmt (const std::nothrow_t&) const noexcept;
table_format_info const& as_table_fmt (const std::nothrow_t&) const noexcept;
```
#### Return Value
Returns a reference to the structure holding the format information for the specified type.
#### Note
If the type of the stored value does not match the specified type, the behavior is undefined.
-----
### `at(key)`
```cpp
value_type& at(const key_type& key);
value_type const& at(const key_type& key) const;
```
#### Return Value
Casts the current `value` to a `table` and returns the element specified by `key`.
#### Exception
Throws `toml::type_error` if the stored value is not a `table`.
Throws `std::out_of_range` if the `table` does not contain the specified element.
-----
#### `operator[](key)`
```cpp
value_type& operator[](const key_type& k);
```
##### Return Value
Casts the current `value` to a `table` and returns a reference to the element specified by `key`.
If the element specified by `key` does not exist, it is default-constructed.
##### Exception
Throws `toml::type_error` if the stored value is not a `table`.
-----
### `count(key)`
```cpp
std::size_t count(const key_type& key) const;
```
#### Return Value
Casts the current `value` to a `table` and returns `1` if the element corresponding to `key` is present, otherwise returns `0`.
#### Exception
Throws `toml::type_error` if the stored value is not a `table`.
-----
### `contains(key)`
```cpp
bool contains(const key_type& key) const;
```
#### Return Value
Casts the current `value` to a `table` and returns `true` if the element corresponding to `key` is present, otherwise returns `false`.
#### Exception
Throws `toml::type_error` if the stored value is not a `table`.
-----
### `at(idx)`
```cpp
value_type& at(const std::size_t idx);
value_type const& at(const std::size_t idx) const;
```
#### Return Value
Casts the current `value` to an `array` and returns the element specified by `idx`.
#### Exception
Throws `toml::type_error` if the stored value is not an `array`.
Throws `std::out_of_range` if the specified element does not exist in the `array`.
-----
### `operator[](idx)`
```cpp
value_type& operator[](const std::size_t idx) noexcept;
value_type const& operator[](const std::size_t idx) const noexcept;
```
#### Return Value
Casts the current `value` to an `array` and returns a reference to the element specified by `idx`.
#### Note
Performs no checks. Behavior is undefined if the stored value is not an `array` or if the specified element does not exist.
-----
### `push_back(value)`
```cpp
void push_back(const value_type& x);
void push_back(value_type&& x);
```
Casts the current `value` to an `array` and performs `push_back` on the `array`.
#### Return Value
None.
#### Exception
Throws `toml::type_error` if the stored value is not an `array`.
-----
### `emplace_back(args...)`
```cpp
template<typename ... Ts>
value_type& emplace_back(Ts&& ... args)
```
Casts the current `value` to an `array` and performs `emplace_back` on the `array`.
#### Return Value
A reference to the constructed value.
#### Exception
Throws `toml::type_error` if the stored value is not an `array`.
-----
### `size()`
```cpp
std::size_t size() const;
```
#### Return Value
Casts the current `value` to an `array`, `string`, or `table` and returns the number of elements. For a `string`, it returns the number of characters.
#### Exception
Throws `toml::type_error` if the stored value is not an `array`, `string`, or `table`.
-----
### `location()`
```cpp
source_location location() const;
```
#### Return Value
Returns a `source_location` object representing the position within the TOML document where the `value` is defined.
If the `value` was not constructed by parsing a TOML document, returns a `source_location` that points to nowhere.
-----
### `comments()`
```cpp
comment_type const& comments() const noexcept;
comment_type& comments() noexcept;
```
#### Return Value
Returns a reference to the comment container.
-----
### `accessed()`
```cpp
bool accessed() const;
```
#### Return Value
Returns `true` only if the `value` has been accessed via `as_xxx` or `is_xxx`.
Otherwise, it returns `false`.
#### Remarks
It exists only when `TOML11_ENABLE_ACCESS_CHECK` is defined.
## Non-Member Functions
### `operator==`
```cpp
template<typename TC>
bool operator==(const basic_value<TC>&, const basic_value<TC>&);
```
Two `basic_value<T>` instances are considered equal if they satisfy the following conditions:
- The contained type is the same.
- The contained values are identical.
- The comments are identical at the byte level.
### `operator!=`
```cpp
template<typename TC>
bool operator!=(const basic_value<TC>& lhs, const basic_value<TC>& rhs)
{
return !(lhs == rhs);
}
```
### `operator<`
Defined only if `array_type` and `table_type` have `operator<`.
```cpp
template<typename TC>
bool operator<(const basic_value<TC>&, const basic_value<TC>&);
```
Comparison order:
1. TOML type
2. If TOML types are the same, their values
3. If both the TOML types and values are the same, the comments
TOML types have the following order (from smallest to largest):
1. `toml::value_t::empty`
2. `toml::value_t::boolean`
3. `toml::value_t::integer`
4. `toml::value_t::floating`
5. `toml::value_t::string`
6. `toml::value_t::offset_datetime`
7. `toml::value_t::local_datetime`
8. `toml::value_t::local_date`
9. `toml::value_t::local_time`
10. `toml::value_t::array`
11. `toml::value_t::table`
### `operator<=`
Defined only if `array_type` and `table_type` have `operator<`.
```cpp
template<typename TC>
bool operator<=(const basic_value<TC>& lhs, const basic_value<TC>& rhs)
{
return (lhs < rhs) || (lhs == rhs);
}
```
### `operator>`
Defined only if `array_type` and `table_type` have `operator<`.
```cpp
template<typename TC>
bool operator>(const basic_value<TC>& lhs, const basic_value<TC>& rhs)
{
return !(lhs <= rhs);
}
```
### `operator>=`
Defined only if `array_type` and `table_type` have `operator<`.
```cpp
template<typename TC>
bool operator>=(const basic_value<TC>& lhs, const basic_value<TC>& rhs)
{
return !(lhs < rhs);
}
```
# `toml::type_error`
Exception thrown in case of a type error.
Contains the location information of the value that caused the type error.
```cpp
struct type_error final : public ::toml::exception
{
public:
type_error(std::string what_arg, source_location loc);
~type_error() noexcept override = default;
const char* what() const noexcept override;
source_location const& location() const noexcept;
};
```
# `toml::make_error_info`
```cpp
template<typename TC, typename ... Ts>
error_info make_error_info(
std::string title, const basic_value<TC>& v, std::string msg, Ts&& ... tail);
```
Calls `location()` on a `basic_value`, passes the resulting `source_location` to
[`make_error_info`]({{<ref "docs/reference/error_info#make_error_info">}})
to create an `error_info`.
Refer to [`error_info`]({{<ref "docs/reference/error_info">}}) for more details.
# `toml::format_error`
```cpp
template<typename TC, typename ... Ts>
std::string format_error(std::string title,
const basic_value<TC>& v, std::string msg, Ts&& ... tail);
```
Calls `location()` on a `basic_value`, passes the resulting `source_location` to
[`format_error`]({{<ref "docs/reference/error_info#format_error">}})
to create an `error_info`, then converts it to a string and returns it.
Refer to [`error_info`]({{<ref "docs/reference/error_info">}}) for more details.
# Related
- [comments.hpp]({{<ref "comments.md">}})
- [source_location.hpp]({{<ref "source_location.md">}})
- [types.hpp]({{<ref "types.md">}})
- [visit.hpp]({{<ref "visit.md">}})

View File

@@ -0,0 +1,51 @@
+++
title = "value_t.hpp"
type = "docs"
+++
# value_t.hpp
# `value_t`
`value_t` is used to handle the type information of `toml::value`.
```cpp
namespace toml
{
enum class value_t : std::uint8_t
{
empty = 0,
boolean = 1,
integer = 2,
floating = 3,
string = 4,
offset_datetime = 5,
local_datetime = 6,
local_date = 7,
local_time = 8,
array = 9,
table = 10
};
std::ostream& operator<<(std::ostream& os, value_t t);
std::string to_string(value_t t);
} // toml
```
## Non-member Functions
### Stream Operator
```cpp
std::ostream& operator<<(std::ostream& os, value_t t);
```
Outputs the string representation of the `value_t` to the stream.
### `to_string`
```cpp
std::string to_string(value_t t);
```
Returns the string representation of the `value_t`.

View File

@@ -0,0 +1,37 @@
+++
title = "version.hpp"
type = "docs"
+++
# version.hpp
In `version.hpp`, macros related to the version information of toml11 are defined.
## Macros
### `TOML11_VERSION_MAJOR`
The major version of toml11.
### `TOML11_VERSION_MINOR`
The minor version of toml11.
### `TOML11_VERSION_PATCH`
The patch version of toml11.
## Function
### `license_notice`
```cpp
namespace toml
{
const char* license_notice() noexcept;
}
```
Returns the license notice.
Provided for convenience when redistributing without source code.

View File

@@ -0,0 +1,61 @@
+++
title = "visit.hpp"
type = "docs"
+++
# visit.hpp
In `visit.hpp`, `toml::visit` is defined.
# `toml::visit`
## Functions
```cpp
namespace toml
{
template<typename Visitor, typename ... Args>
/* Return value when Visitor is called with a value of basic_value<TC> */
visit(Visitor&& visitor, Args&& ... args);
}
```
`toml::visit` calls the overload of `Visitor` corresponding to the type held by `basic_value<TC>`, and returns the result.
#### Requirements
`Visitor` must be a function or function object callable with any type held by `basic_value<TC>`.
Additionally, the return value must be consistent across all overloads.
#### Example
```cpp
#include <toml.hpp>
#include <iostream>
struct type_name_of
{
std::string operator()(const toml::value::boolean_type &) const {return "boolean";}
std::string operator()(const toml::value::integer_type &) const {return "integer";}
std::string operator()(const toml::value::floating_type &) const {return "floating";}
std::string operator()(const toml::value::string_type &) const {return "string";}
std::string operator()(const toml::value::local_time_type &) const {return "local_time";}
std::string operator()(const toml::value::local_date_type &) const {return "local_date";}
std::string operator()(const toml::value::local_datetime_type &) const {return "local_datetime";}
std::string operator()(const toml::value::offset_datetime_type&) const {return "offset_datetime";}
std::string operator()(const toml::value::array_type &) const {return "array";}
std::string operator()(const toml::value::table_type &) const {return "table";}
};
int main()
{
toml::value v(3.14);
std::cout << toml::visit(type_name_of{}, v) << std::endl; // floating
return 0;
}
```
# Related
- [value.hpp]({{<ref "value.md">}})

25
docs/content.ja/_index.md Normal file
View File

@@ -0,0 +1,25 @@
+++
title = "Introduction"
type = "docs"
+++
# Introduction
English version is [here](../en/)
## [Installation](docs/installation)
toml11のインストール方法について説明します。
## [Features](docs/features)
toml11の機能と使い方を例に沿って説明します。
## [Reference](docs/reference)
toml11が持つ関数・クラスの詳細を説明します。
## [ChangeLog](docs/changelog)
v3系から、そしてリリースごとの変化を説明します。

View File

@@ -0,0 +1,436 @@
+++
title = "changelog"
type = "docs"
weight = 4
+++
# Change Log
# v4.4.0
## Added
- `toml::find_or_default()` を追加 (by Ken Matsui @ken-matsui)
- `ordered_map`から値を削除できるよう変更 (by Sunlight @SunPodder)
- 値がアクセス済みかを調べる`bool basic_value::accessed() const`を追加
- `TOML11_ENABLE_ACCESS_CHECK`が定義されているときのみ有効
- `toml::spec`に比較演算子を追加
## Fixed
- `is_same<T, void>`ではなく`is_void`を使用するように修正 (by Ken Matsui @ken-matsui)
## Changed
- `toml::parse`のパフォーマンスを約2倍向上
- GitHub ActionsでUbuntu 20のイメージの使用を終了
# v4.3.0
## Added
- `toml::find``std::optional<T>`をサポート
- `toml::visit`で複数の引数をサポート
## Fixed
- 初期化前に変数が使われるケースを修正 (by amatej @kontura)
- CMake 3.21以前を使用する際の修正 (by Severin Leonhardt @SeverinLeonhardt)
- 非常に巨大な文字列が作成されるケースを修正 (by @hayt)
- READMEのサンプルコードを修正、ToCを増強 (by somebody @oldoldtea) (by lz)
- 長い行のパースを高速化
- MSVC 2017でのコンパイルエラーを修正
- `source_location::file_name`のヌルチェックを追加
## Changed
- hugo-bookテーマをアップデート
- MSVC 2017をappveyor buildに追加
# v4.2.0
## Added
- `TOML11_DEFINE_CONVERSION_NON_INTRUSIVE``std::optional` なメンバをサポート (by Ken Matsui @ken-matsui)
- `thread_local`だった`color_mode`をデフォルトでグローバルにし、`thread_local`にするオプションを追加 (by Ken Matsui @ken-matsui)
- CPMでの使い方を`README`に追加
- `README``ordered_map`への言及を追加し、ドキュメントでの説明を追加
## Fixed
- ファイルサイズの`std::streamsize`への変換で警告が出ることがある問題を修正 (by Pino Toscano @pinotree)
- `table_format`に不正な値が与えられた際の出力のtypoを修正
- `array`のフォーマットが`array_of_tables`と指定されていてかつ空の場合の出力を修正
- 特定の環境で`include`が足りずにコンパイルできない問題を修正
- ドキュメントに含まれる文法エラーを修正 (by Jack W)
- `toml::find_or` を深くネストされたテーブルに使用した際にコンパイルが失敗する問題を修正
# v4.1.0
## Added
- `std::get<std::u8string>`をサポート
- `toml::value(std::u8string)`をサポート
- `string_type = std::u8string`をサポート
- `operator<<(std::ostream&, toml::value)`をサポート
- `toml::integer_format`に、16進数表示で大文字を使うことを指定する`bool uppercase`を追加
- `template`を使って実装された `into_toml()` をサポート (by 萧迩珀)
## Fixed
- Windowsで`\r\n`が改行に使われた際、出力時に`\r`が重複する問題を修正 (by Andreas Keller)
## Changed
- CIで複数コアを使うことでビルドを高速化
# v4.0.3
## Fixed
- `toml_fwd.hpp`を使用した際にデフォルト引数が重複する問題を修正
- `toml::value`を複数渡した際に`toml::make_error_info`が使えない問題を修正
- `std::reference_wrapper`を持つ`toml::result`をコピー・ムーブする際の問題を修正
- hugoの最新版でドキュメントがビルドできない問題を修正
- コンパイラによる軽微な警告を多数修正
- CMakeの互換性に関する警告を抑制
## Changed
- CIビルドで`-Werror`, `/WX`を追加
- CIビルドでMSVCのwarningレベルを`/W3`から`/W4`に変更
- READMEでより多くの機能を紹介するよう更新
# v4.0.2
## Fixed
- `parse(FILE*)` 内の `fread` の結果をチェック
- `toml11/version.hpp`のマクロを修正
- コンパイルオプションに関するドキュメントの更新
- ファイルオープンモードに関するドキュメントの更新
## Changed
- `CMakeLists.txt`内のバージョン番号を`version.hpp`から取得するように変更
# v4.0.1
## Fixed
- `sematic_version::{major, minor}``<sys/sysmacro.h>` 内で定義されるマクロの衝突を解消
- `discard_comments``operator<<` の定義を修正 (by Egor Pugin)
- `format_location`を使用した際に最初の空行が出ない問題を解決
- 改行文字のみを含む行を指す`source_location`でエラーメッセージを生成した際に、同じ行が二回表示される問題を解決
- `README.md`内のリンクを修正
- `example/unicode`のREADMEのタイトルを修正
## Added
- `main`に変更があったとき、`single_include/toml.hpp`を自動生成するようCIを設定
# v3からv4への変化
## 破壊的変更
### `toml::basic_value`の`template`引数を変更
toml11 v3では、`toml::basic_value`はコメントコンテナ、テーブル型コンテナ、配列型コンテナをそれぞれ取っていました。
```cpp
template<typename Comment,
template<typename ...> class Table = std::unordered_map,
template<typename ...> class Array = std::vector>
class basic_value;
```
ですが、`integer_type`などを変更したいという場合にはこれでは対応できません。
toml11 v4では、`toml::basic_value`は単一の`TypeConfig`を受け取り、より多くの型を変更可能にします。
```cpp
template<typename TypeConfig>
class basic_value;
```
デフォルトでは`toml::value`が格納する型は変わりません。
型を変更する際は、
[`type_config`]({{< ref "/docs/reference/types.md">}})
を参照してください。
### `toml::basic_value`の`std::initializer_list`サポートを削除
toml11 v3では、 `toml::value``std::initializer_list` を取るオーバーロードが用意されていました。
これにより、 `toml::value` を配列やテーブルで初期化する際により直観的な書き方が可能でした。
```cpp
// toml11 v3
toml::value v{1,2,3,4,5};
toml::value v{ {"a", 42}, {"b", "foo"} };
```
しかし、これは同時に以下のような問題を引き起こしました。
一つ目は、1要素の配列と通常の値の区別がつかず、常に配列になってしまうことです。
```cpp
// toml11 v3
toml::value v{1}; // 1 ではなく [1,] になってしまう
```
統一初期化記法が普及した現在、これは非常に不便です。
二つ目は、値が全て文字列のテーブルと、ネストされた配列の区別がつかないことです。
```cpp
// toml11 v3
toml::value v{ {"a", "foo"}, {"b", "bar"} };
// {a = "foo", b = "bar"}
// [["a", "foo"], ["b", "bar"]]
// のどちらでもあり得る
```
これらの問題は言語仕様上解決が困難です。
toml11 v4では、混乱を避けるため、`std::initializer_list`サポートを削除しました。
`toml::value` を配列で初期化する際はexplicitに `toml::array` を、
テーブルで初期化する際はexplicitに `toml::table` を指定する必要があります。
```cpp
// toml11 v4
toml::value v(toml::array{1,2,3,4,5});
toml::value v(toml::table{ {"a", 42}, {"b", "foo"} });
toml::value v{toml::array{1}}; // [1,]
toml::value v{1} // 1
toml::value v{toml::table{{"a", "foo"}, {"b", "bar"}}};
toml::value v{toml::array{toml::array{"a", "foo"}, toml::array{"b", "bar"}}};
```
これにより `toml::value` をテーブルや配列で初期化する際に少し不便になりますが、
explicitに型情報を記述することにより予測不能な値になることは避けることができます。
### `toml::basic_value::is_uninitialized()` を `is_empty()` に変更
toml11 v3では、初期化されていない `basic_value` かどうかを判定する関数は
`is_uninitialized` でした。
しかし、toml11 v4では言語拡張で `null `をサポートするため、意図的に空にされた値が構築される可能性があります。
なので命名を変更し、 `is_empty` としました。
### `toml::string` を廃止、フォーマット情報を陽に格納
toml11 v3では、文字列が `basic``literal` かの情報を保持するため、
格納する文字列型に `toml::string` という `std::string` の薄いラッパーを使用していました。
```cpp
// toml11 v3
namespace toml
{
enum class string_t : std::uint8_t
{
basic = 0,
literal = 1,
};
struct string
{
string_t kind;
std::string str;
};
} // toml
```
toml11 v4では、数値型の基数や配列を複数行にするかどうかなどのより多くのフォーマット情報を持たせるため、
全ての型に `xxx_format` 型を用意し、値とペアで格納することにしました。
```cpp
// toml11 v4
enum class string_format : std::uint8_t
{
basic = 0,
literal = 1,
multiline_basic = 2,
multiline_literal = 3
};
struct string_format_info
{
string_format fmt = string_format::basic;
bool start_with_newline = false;
};
```
これにより、より細かいフォーマット情報を保持することができるようになり、
特に数値型や配列、テーブル型のフォーマット情報がパース後も維持できるようになりました。
### `toml::format`の引数を変更
toml11 v3では、 `toml::format` が数値型の精度や幅などの値を受け取っていました。
しかし、これでは細かなフォーマット指定ができず、予想したようなファイルにシリアライズできませんでした。
toml11 v4では、各 `toml::value` にそれぞれのフォーマット情報を格納したため、
より細かいフォーマット情報を `toml::value` 自体が持ち運べるようになりました。
これにより、 `toml::format` 自体はフォーマット指定を受け取らず、
フォーマット時に使用できる言語機能フラグを持つ `toml::spec` のみを取るようになりました。
### `toml::source_location`のメンバ関数を変更
toml11 v3では、 `toml::source_location` のメンバ型は一行分だけを意識したものでした。
toml11 v4では、 `toml::source_location` のメンバ型は複数行が前提になります。
### `toml::format_underline`を`toml::format_location`に変更
toml11 v3では、 `toml::source_location` を使用して位置情報を文字列化するとき、
`toml::format_underline` を使用していました。
しかしこれは名称としてわかりにくいため、 `toml::format_location` に変更しました。
### `format_error`の引数を変更
toml11 v3ではエラー情報を表すクラスがなかったため、`toml::format_error`の引数が複雑になっていました。
```cpp
template<typename C, template<typename ...> class T, template<typename ...> class A>
std::string format_error(const std::string& err_msg,
const basic_value<C, T, A>& v, const std::string& comment,
std::vector<std::string> hints = {},
const bool colorize = TOML11_ERROR_MESSAGE_COLORIZED);
template<typename C, template<typename ...> class T, template<typename ...> class A>
inline std::string format_error(const std::string& err_msg,
const toml::basic_value<C, T, A>& v1, const std::string& comment1,
const toml::basic_value<C, T, A>& v2, const std::string& comment2,
std::vector<std::string> hints = {},
const bool colorize = TOML11_ERROR_MESSAGE_COLORIZED);
template<typename C, template<typename ...> class T, template<typename ...> class A>
inline std::string format_error(const std::string& err_msg,
const toml::basic_value<C, T, A>& v1, const std::string& comment1,
const toml::basic_value<C, T, A>& v2, const std::string& comment2,
const toml::basic_value<C, T, A>& v3, const std::string& comment3,
std::vector<std::string> hints = {},
const bool colorize = TOML11_ERROR_MESSAGE_COLORIZED);
```
toml11 v4では、`class error_info``make_error_info`を導入し、`format_error`の引数を簡略化しました。
```cpp
std::string format_error(const error_info& err);
std::string format_error(const std::string& errkind, const error_info& err);
template<typename ... Ts>
std::string format_error(std::string title,
source_location loc, std::string msg, Ts&& ... tail);
template<typename TC, typename ... Ts>
std::string format_error(std::string title,
const basic_value<TC>& v, std::string msg, Ts&& ... tail);
```
### `toml::color` の制御を変更
toml11 v3では、出力に色を付けるかどうかに `toml::colorize` というマニピュレータを、
`toml::color::enable/disable` と並列で使用していました。
マニピュレータはストリームごとに色を付けるかどうかを決定できるものでしたが、
v4でストリームを使用する頻度が下がったことと、内部で使用する
`std::ios_base::xalloc` がC++11ではスレッドセーフではないことなどから、
`toml::color::enable/disable` のみを使用するようにし、 `toml::colorize` を削除しました。
## 破壊的でない変更
### `parse_str`の追加
toml11 v3では、文字列そのものを取る`toml::parse`関数はありませんでした。
なので文字列をパースする際には`std::istringstream`を使う必要がありました。
これは不便なので、`toml::parse_str`を追加し、文字列を直接パース出来るようにしました。
### `try_parse`の追加
toml11 v3では、パーサはエラーを発見した際には`toml::syntax_error`を送出していました。
しかし、例外を投げられない環境や、パフォーマンスの都合や記法の都合によって例外を投げたくない場合があります。
toml11 v4では `toml::result` を使用して、例外を投げずにパース失敗を伝える `toml::try_parse` を実装しました。
これも必ず例外を投げないというわけではなく、使用している標準ライブラリの内部でのエラー、
例えばメモリ不足によるアロケーション失敗での `std::bad_alloc` などは送出される可能性があります。
### バイト列のパースをサポート
ファイルなど以外の方法で得られたTOMLコンテンツをパース出来るようにするため、
`std::vector<unsigned char>` を受け取る `toml::parse`, `toml::try_parse` を追加しました。
### `toml::spec`の追加
toml11 v3では、TOML言語側の新機能は全て取り込み、またTOML言語の新バージョンに導入されることが決定した機能も
マクロ `TOML11_USE_UNRELEASED_TOML_FEATURES` によって制御していました。
これは、toml11 v3を開発していた時点では TOML言語は0.4.0から0.5.0で、1.0.0に到達していなかったためです。
最新のTOML言語仕様に全てのユーザーが詳しいわけではないため、
古い言語使用に基づいたエラーメッセージを表示すると、コミュニティ全体を混乱させてしまいます。
よって、v1.0.0に達するまでは、できる限り素早く新しい言語仕様を提供し、かつユーザーにもアップデートを促す必要がありました。
しかし、現在のTOML言語仕様はv1.0.0です。
そのため、TOML v1.1.0がリリースされた後でもv1.0.0を使用する、という選択肢に気を配る必要が生じました。
よって、より柔軟にTOML言語仕様を選択できるよう、`toml::spec`を導入して、TOML言語バージョンを実行時に変更できるようにしました。
また、`toml::spec`では言語機能ごとにフラグを設定し、特定の言語機能のみを試すこともできるようにしました。
これは、toml11 v4特有の言語拡張でも使用します。
### フォーマット情報の追加
toml11 v3では、文字列を除いてフォーマット情報が保存されず、シリアライズ時に考慮できるのは幅と精度だけでした。
しかし、これでは16進数整数がシリアライズ時に10進数になってしまったり、確実にinline tableにする方法がありませんでした。
toml11 v4では、全てのTOML型にフォーマット情報`integer_format` etcを追加し、
パース時とシリアライズ時に考慮するようにしました。
これによって、16進数整数や、インラインテーブル等のフォーマット情報をより細かく、値ごとに設定できるようになりました。
### デフォルトでコメントを維持するよう変更
toml11 v3では、デフォルトではコメントがパースされず、シリアライズもされませんでした。
これは、コメントが後期に導入された機能で、特別なハックによって読み込まれていたためです。
toml11 v4では、デフォルトでコメントをパースし、保存し、シリアライズするようになりました。
また、パーサの実装も大幅に変更され、コメントが他の要素と同様にパースされるようになりました。
### `single_include/toml.hpp` の追加
toml11は多機能なライブラリなので、開発効率のために機能ごとに異なるヘッダファイルを持っています。
ですが、これはインストールにある程度の手間が必要ということでもあります。
そこで、toml11 v4から全てのヘッダファイルを適切な順序で結合した `single_include/toml.hpp` ファイルを追加し、
単一のファイルで完結するライブラリをコピーするだけで導入できるようにしました。
### コンパイル済みライブラリを選択可能に
toml11は `template` を多用しているため、コンパイル時間が長くなります。
toml11 v4では、できるだけコンパイル可能な関数を増やし、それらを先にライブラリとしてコンパイルできるようにしました。
これにより、大規模な開発で使用する際にコンパイル時間を短くできると期待できます。
### リファレンス・ドキュメントの追加
これまでは、READMEにすべてのfeatureを記載しており、関数の詳細な定義を示すリファレンスや、また日本語での資料などがありませんでした。
toml11 v4では、リファレンスを追加したドキュメントを同梱し、また日本語・英語両方で同一の内容を記載します。
ただし、ライブラリ作者は日本語母語話者であるため、日本語の内容を第一とし、英語の内容がそれと異なっていた場合は日本語の内容が正しいものとします。

View File

@@ -0,0 +1,101 @@
+++
title = "features"
type = "docs"
weight = 2
bookCollapseSection = true
+++
# features
ここでは、toml11が提供する主な機能について、例を挙げながら説明します。
## [ファイル・文字列をパースする](parsing_files)
ファイルや文字列をパースする関数と、それが出力するエラーの扱い方について説明します。
以下の内容を含みます。
- ファイルをパースする
- 文字列をパースする
- バイト列をパースする
- 例外を投げずにファイルをパースする
- 例外を投げずに文字列をパースする
- 例外を投げずにバイト列をパースする
## [`toml::value`から値を取り出す](value)
`toml::value`が持つデータの型を調べ、取り出す方法、型変換を行う方法について説明します。
以下の内容を含みます。
- メンバ関数を使って値の型を調べる
- メンバ関数を使って値にアクセスする
- コメントにアクセスする
- インラインテーブル・ドットキーの取り扱い
- 日付情報の取り扱い
- `toml::get<T>`を使って変換する
- `toml::get_or`を使って失敗時の値を指定する
- `toml::find<T>`を使って検索と変換を行う
- `toml::find_or`を使って失敗時の値を指定する
- ユーザー定義型との変換を定義する
- `toml::visit`で関数を適用する
- `toml::value`を構築する
## [エラーメッセージを作る](error_message)
`toml::value`の値を使って、TOMLファイル中の位置情報つきのエラーメッセージを生成する方法について説明します。
以下の内容を含みます。
- `toml::value` の位置情報を取り出す
- エラーメッセージを構築する
- 出力に色を付ける
## [TOMLファイルを出力する](serialize)
`toml::value`の値をフォーマットする方法と、可能なフォーマット指定について説明します。
以下の内容を含みます。
- `toml::value`の値ごとにフォーマットを指定する
- `toml::value`をフォーマットして文字列化する
## [`toml::value`の型を変更する](configure_types)
`toml::value`が格納する型(`integer_type``table_type`をカスタマイズする方法について説明します。
以下の内容を含みます。
- `type_config`の定義
- `ordered_type_config`を使用する
- コメントを保存しないようにする
- `std::deque`などの異なるコンテナを使用する
- `boost::multiprecision`などの異なる数値型を使用する
## [TOMLリテラル](literal)
C++内にTOMLファイルを埋め込むための`_toml`リテラルについて説明します。
以下の内容を含みます。
- TOMLリテラルを使用する
## [TOML言語バージョン](toml_spec)
toml11がサポートするTOML言語のバージョン、主にTOML-v1.1.0で追加された言語機能を制御する方法について説明します。
以下の内容を含みます。
- TOML言語の1.1.0を使用する
- TOML言語の1.1.0の一部の機能のみ使用する
## [TOML言語拡張](extension)
toml11独自のTOML言語拡張について説明します。
以下の内容を含みます。
- `null` をサポートする
- 浮動小数点数の16進数フォーマットをサポートする
- 数値に単位を付けられるようにする

View File

@@ -0,0 +1,224 @@
+++
title = "configuring types"
type = "docs"
weight = 50
+++
# 型をカスタマイズする
`toml::value``integer_type` として `std::int64_t` を、
`table_type` として `std::unordered_map<key_type, value_type>` を使用します。
しかし、場合によっては `boost::multiprecision::int128_t` や、 `std::map` を使用したい場合もあります。
そのため、 `toml::value``template` 引数を取って格納する型を変えられるように実装されています。
`std::string` が実際には `std::basic_string<char, std::char_traits<char>, std::allocator<char>>`
エイリアスであるように、 `toml::value` は実際には `toml::basic_value<toml::type_config>` のエイリアスです。
ここでは、 `toml::type_config` が持つ型と、異なる `config` 型を定義する方法を説明します。
## `type_config`
`type_config` は、以下のメンバ型と`static`メンバ関数を持つクラスです。
```cpp
namespace toml
{
struct type_config
{
using comment_type = preserve_comments;
using boolean_type = bool;
using integer_type = std::int64_t;
using floating_type = double;
using string_type = std::string;
template<typename T>
using array_type = std::vector<T>;
template<typename K, typename T>
using table_type = std::unordered_map<K, T>;
static result<integer_type, error_info>
parse_int(const std::string& str, const source_location src, const std::uint8_t base);
static result<floating_type, error_info>
parse_float(const std::string& str, const source_location src, const bool is_hex);
};
}
```
`toml::basic_value<TypeConfig>` は、格納する `boolean_type``TypeConfig::boolean_type`
格納する `integer_type``TypeConfig::integer_type` 、のようにして定義しています。
また、 `array_type``TypeConfig::array_type<toml::basic_value<TypeConfig>>`
`table_type``TypeConfig::table_type<key_type, toml::basic_value<TypeConfig>>`
定義されます。
これらのメンバ型とメンバ関数を定義したクラスを `toml::basic_value`
渡すことで、その `toml::basic_value` が持つ型を変更できます。
`parse_int``parse_float` は、数値型を独自実装のものに変更した際にパース方法を提供するための関数です。
これらの関数には `0x` などのprefixと桁区切りの `_` が取り除かれた文字列、
例えば `123456``DEADBEEF` が渡されます。
`base` には `10`, `16`, `8`, `2` のいずれかが渡されます。
これらを使って `integer_type``floating_type` をパース出来るような関数を渡してください。
デフォルト実装として、`toml::read_int``toml::read_float` が提供されています。
```cpp
static result<integer_type, error_info>
parse_int(const std::string& str, const source_location src, const std::uint8_t base)
{
return toml::read_int<integer_type>(str, src, base);
}
static result<floating_type, error_info>
parse_float(const std::string& str, const source_location src, const bool is_hex)
{
return toml::read_float<floating_type>(str, src, is_hex);
}
```
`read_int``istream` を使用し、16進と8進の場合は `std::hex`
`std::oct` を使用します。2進の場合は掛け算と足し算で実装されています。
これらをサポートしている型であれば、 `read_int` をそのまま使用できます。
`read_float``istream` を使用します。
16進浮動小数点数は `double``float` の場合しかサポートされておらず、
それ以外の型のときに呼ばれると常にパースエラーを返す実装になっているので、
もし浮動小数点数型をこれら以外の型にし、かつ `hexfloat` を使用する場合は、
それを実装してください。 `hexfloat` を使用しないのであれば、実装する必要はありません。
## テーブル内の値の順序を維持する
デフォルトの `toml::type_config` の他に、 `toml::ordered_type_config` が提供されています。
これは、 `table_type` を [ordered_map]({{< ref "docs/reference/ordered_map" >}}) に変更したものです。
これを使用したものを `toml::ordered_value` 、その配列型とテーブル型のエイリアスを
`toml::ordered_array``toml::ordered_table` と定義しています。
`toml::parse(...)``toml::parse<toml::ordered_type_config>(...)` として呼び出すことで、
`toml::ordered_value` を使用することができます。
```cpp
#include <toml.hpp>
int main()
{
toml::ordered_value input = toml::parse<toml::ordered_type_config>("example.toml");
std::cout << toml::format(input) << std::endl;
return 0;
}
```
## コメントを保存しない
`type_config``comment_type` でコメントを保存するコンテナを定義しています。
コメントに特に情報がなく、パースせずに捨ててしまっていい場合は、 `comment_type`
`toml::discard_comments` を指定してください。
```cpp
struct wo_comment_config
{
using comment_type = toml::discard_comments; // XXX
using boolean_type = bool;
using integer_type = std::int64_t;
using floating_type = double;
using string_type = std::string;
template<typename T>
using array_type = std::vector<T>;
template<typename K, typename T>
using table_type = std::unordered_map<K, T>;
static result<integer_type, error_info>
parse_int(const std::string& str, const source_location src, const std::uint8_t base)
{
return toml::read_int<integer_type>(str, src, base);
}
static result<floating_type, error_info>
parse_float(const std::string& str, const source_location src, const bool is_hex)
{
return toml::read_float<floating_type>(str, src, is_hex);
}
};
```
## 配列に`std::vector`以外のコンテナを使用する
TOML配列の実装に`vector`以外のコンテナ(例:`std::deque`)を使用するには、
`array_type` を以下のように変更してください。
また、テーブル型のコンテナに `unordered_map` 以外のコンテナ(例:`std::map`)を使用するには、
`table_type` を以下のように変更してください。
```cpp
struct deque_map_config
{
using comment_type = toml::preserve_comments;
using boolean_type = bool;
using integer_type = std::int64_t;
using floating_type = double;
using string_type = std::string;
template<typename T>
using array_type = std::deque<T>; // XXX
template<typename K, typename T>
using table_type = std::map<K, T>; // XXX
static result<integer_type, error_info>
parse_int(const std::string& str, const source_location src, const std::uint8_t base)
{
return toml::read_int<integer_type>(str, src, base);
}
static result<floating_type, error_info>
parse_float(const std::string& str, const source_location src, const bool is_hex)
{
return toml::read_float<floating_type>(str, src, is_hex);
}
};
```
## 数値型に `boost::multiprecision` を使用する
`boost::multiprecision::cpp_int``boost::multiprecision::cpp_bin_float_oct`
を使用することで、より幅の広い整数型とより精度の良い浮動小数点数型を使用することができます。
これらの型はストリーム演算子を実装しているため、デフォルト実装の `read_int`
`read_float` をそのまま使用できます。
```cpp
struct large_num_config
{
using comment_type = toml::preserve_comments;
using boolean_type = bool;
using integer_type = boost::multiprecision::cpp_int;
using floating_type = boost::multiprecision::cpp_bin_float_oct;
using string_type = std::string;
template<typename T>
using array_type = std::vector<T>;
template<typename K, typename T>
using table_type = std::unordered_map<K, T>;
static toml::result<integer_type, toml::error_info>
parse_int(const std::string& str, const toml::source_location src, const std::uint8_t base)
{
return toml::read_int<integer_type>(str, src, base);
}
static toml::result<floating_type, toml::error_info>
parse_float(const std::string& str, const toml::source_location src, const bool is_hex)
{
return toml::read_float<floating_type>(str, src, is_hex);
}
};
```

View File

@@ -0,0 +1,237 @@
+++
title = "error message"
type = "docs"
weight = 30
+++
# エラーメッセージを出力する
toml11は `toml::parse``toml::get<T>/find<T>`, `as_integer()` などから
ファイル内の位置情報を含んだエラーメッセージを出力します。
例えば、パース時に整数の文法エラーを発見した場合、
```
[error] bad integer: `_` must be surrounded by digits
--> internal string at line 64 in file main.cpp
|
1 | a = 123__456
| ^-- invalid underscore
Hint: valid : -42, 1_000, 1_2_3_4_5, 0xC0FFEE, 0b0010, 0o755
Hint: invalid: _42, 1__000, 0123
```
あるいは実際に格納されている型と異なる型を要求した場合
```
[error] toml::value::as_string(): bad_cast to string
--> input.toml
|
1 | a = 123_456
| ^^^^^^^-- the actual type is integer
```
toml11は `toml::value` からこのようなエラーメッセージを作成する方法を提供します。
この機能を利用することで、TOMLの文法エラーだけでなく、
例えば正の値でなければならないところに負数が現れた場合などの
アプリケーション固有のエラーメッセージを、TOMLファイル内の位置を指摘しながら
ユーザーに伝えられるということです。
## `toml::value` の位置情報からエラーメッセージを作成する
`toml::value` はそれがパースされた位置の情報を持っています。
その情報は `toml::source_location` にまとめられ、`toml::value::location()` で取得できます。
```cpp
const toml::value& a = input.at("a");
const toml::source_location src = a.location();
```
ファイルを `toml::parse` でパースした場合、そのTOMLファイル名と行数が保存されています。
`toml::parse_str` でパースした場合TOMLファイル名はありませんが、代わりに
`toml::parse_str` を呼び出したC++ソースコードのファイル名と行数がTOMLファイル名として保存されています。
このページの最初の例は `toml::parse_str` から出力された例でした。
ファイル名の部分に注目してください。
詳細は [reference]({{<ref "/docs/reference/source_location">}}) を参照してください。
`toml::source_location` または `toml::value` とそれに付随するエラーメッセージを
`toml::make_error_info` に渡すことで、エラー情報を構築できます。
これを`toml::format_error` に渡すと、エラーメッセージが `std::string` にフォーマットされます。
```cpp
const toml::value& a = input.at("a");
if(a.as_integer() < 0)
{
const toml::error_info err = toml::make_error_info(
"positive integer is required", // エラーのタイトル
a, "but got negative value" // 値の横に書くメッセージ
);
std::cerr << toml::format_error(err) << std::endl;
}
```
これは以下のようになります。
```
[error] positive integer is required
--> input.toml
|
1 | a = -123456
| ^^^^^^^-- but got negative value
```
最後に補足をつけ足すこともできます。これはインデントされません。
```cpp
const toml::value& a = input.at("a");
if(a.as_integer() < 0)
{
const toml::error_info err = toml::make_error_info(
"positive integer is required", // エラーのタイトル
a, "but got negative value", // 値の横に書くメッセージ
"Hint: `a` means length of the data" // 補足
);
std::cerr << toml::format_error(err) << std::endl;
}
```
```
[error] positive integer is required
--> input.toml
|
1 | a = -123456
| ^^^^^^^-- but got negative value
Hint: `a` means length of the data
```
{{<hint info>}}
`toml::value` からファイル内の行を出力できるのは、
パースしたファイルが文字列としてメモリの中に残されているからです。
パースした文字列はその全体が `std::shared_ptr``toml::value` に共有されています。
コピーしてもファイル文字列全体がコピーされることはありません。
また、そのファイルをパースして構築された `toml::value` が全てデストラクトされた時点で、
ファイル情報もメモリ上から解放されます。
ですので、アプリケーションで使用する際には、 `toml::value` を直接保存するのではなく
読み込み中に必要な値を全て取り出して、変換した値を保存した方がよいでしょう。
{{</hint>}}
## 文字列に色を付ける
エラーメッセージにはANSIエスケープコードを使って色を付けることができます。
`TOML11_COLORIZE_ERROR_MESSAGE` をコンパイル時に定義していれば、
toml11の出力するエラーメッセージはデフォルトで色が付くようになります。
そうでない場合は、 `toml::color::enable()` を呼び出すことにより、それ以降で出力される
エラーメッセージには色が付くようになります。
逆に出力先がコンソールではないなどの理由で色をつけたくない場合は、
`toml::color::disable()` を呼び出してください。
その時点で色が付くようになっているかどうかは、
`toml::color::should_color()` の返り値で判定できます。
詳細は [reference]({{<ref "docs/reference/color">}}) を参照してください。
また、エラーのタイトルやエラーメッセージ、補足にはデフォルトで色が付きませんが、
`toml::color` にあるマニピュレータを使って色を付けることも可能です。
```cpp
std::ostringstream oss;
oss << toml::color::red << "but got negative value";
const toml::error_info err = toml::make_error_info(
"positive integer is required", // Error title
a, oss.str(), // Message next to the value
"Hint: `a` means length of the data" // Supplementary message
);
```
こちらも、詳細は [reference]({{<ref "docs/reference/color">}}) を参照してください。
## エラーメッセージのprefixを`[error]`から変更する
エラーには種類があり、デフォルトの `[error]` ではよくない場合もあるでしょう。
`toml::format_error` では、 `toml::error_info` の前に `std::string` を取って、それを
`[error]` の代わりに出力することができます。
例えば、
```cpp
const toml::value& a = input.at("a");
if(a.as_integer() < 0)
{
const toml::error_info err = toml::make_error_info(
"positive integer is required", // エラーのタイトル
a, "but got negative value" // 値の横に書くメッセージ
);
std::ostringstream prefix;
prefix << toml::color::bold << toml::color::yellow << "[warn]";
std::cerr << toml::format_error(prefix.str(), err) << std::endl;
return 0;
}
else
{
return a.as_integer()
}
```
このようにすると、 `[warn]` から始まる警告を出力することができます。
他にも、`toml::format_error` に直接 `error_info` の構成要素を渡すことで、
`[error]` なしのエラーメッセージを作成できます。
```cpp
const toml::value& a = input.at("a");
if(a.as_integer() < 0)
{
std::cerr << toml::format_error(
"[warn] positive integer is required", // エラーのタイトル
a, "but got negative value" // 値の横に書くメッセージ
) << std::endl;
return 0;
}
else
{
return a.as_integer()
}
```
## 複数の `toml::value` を指すエラーメッセージを作成する
アプリケーションの設定では、先に読み込んだ値によって後に読み込んだ値が取れる範囲が変わることがあるでしょう。
そのような場合には、エラーの原因となる別の値を同時に出力したいはずです。
`toml::format_error``toml::make_error_info` は、 `toml::value` とそれに対応するエラーメッセージ `std::string` のペアを任意個取ることができます。
```cpp
std::cerr << toml::format_error(
"[error] invalid range",
a, "minimum value is defined here",
b, "maximum value is defined here",
c, "and it exceeds the range"
) << std::endl;
```
こちらも末尾に補足を追加することができます。
```cpp
std::cerr << toml::format_error(
"[error] invalid range",
a, "minimum value is defined here",
b, "maximum value is defined here",
c, "and it exceeds the range",
"Hint: all the value must be in the range, [a, b)"
) << std::endl;
```
`toml::value` または `toml::source_location` を渡した場合、必ずそれに関する
エラーメッセージが続く必要があります。
そうしない場合、非常にわかりにくいコンパイルエラーになります。

View File

@@ -0,0 +1,136 @@
+++
title = "extension"
type = "docs"
weight = 80
+++
# TOML言語拡張
TOML言語は現在 v1.0.0 が最新版ですが、その後もいくつかの新機能が議論の末マージされ、
v1.1.0に向けて議論が続いています。
そこで議論された機能の中には、有用なケースが少ないと考えられたものや、
提案された際の方向性では導入が難しいもの、導入がされなかったものも多くあります。
toml11では、そのような機能のなかからいくつかを選んで、実験的に実装を行っています。
これらはtoml11ではサポートされていますが、他のパーサではサポートされておらず、また
サポートされる予定もないことに注意してください。
また、これらの機能はデフォルトで使用されない設定になっており、
使用するためには機能フラグをそれぞれ `true` にしなければなりません。
非標準の機能なので、あえて明示的に書かなければ使えないように設計しています。
いくつかの機能は今後TOML言語自体に新機能としてマージされる可能性があります。
もし以下の拡張機能を完全に置き換えられる機能が導入された場合、拡張機能は
本来の機能の実装後にマイナーバージョンアップで削除される可能性があります。
## `null`
TOMLファイル内で値として`null`を使えるようになります。
```
a = null
b = [ 1, 2, 3, null, 5]
```
これを使用するには、 `toml::spec``ext_null_value``true` にします。
パースすると、デフォルト構築した場合と同様の `toml::value_t::empty` となります。
ただし、ファイル内の位置情報は設定されます。
`null` は値の文脈でのみパースされるので、キーに `null` を使用した際はこれまで通り
`"null"` という文字列のキーとして解釈されます。
```cpp
#include <toml.hpp>
int main()
{
toml::spec spec;
spec.ext_null_value = true;
const auto v = toml::parse_str("a = null", spec);
assert(v.at("a").is_empty());
assert(v.at("a").is(toml::value_t::empty));
return 0;
}
```
## 浮動小数点数の16進数フォーマット
TOMLファイル内で浮動小数点数に16進数フォーマットを使用できるようになります。
```
a = 0x1.91eb851eb851fp+1 # 3.14
```
これを使用するには、 `toml::spec``ext_hex_float``true` にします。
フォーマットは `printf``%a/%A` を指定した場合に準拠します。
```cpp
#include <toml.hpp>
int main()
{
toml::spec spec;
spec.ext_hex_float = true;
const auto v = toml::parse_str("a = 0x1.91eb851eb851fp+1", spec);
assert(v.at("a").is_floating());
assert(v.at("a").as_floating() == 3.14);
return 0;
}
```
## 整数・浮動小数点数のsuffix
TOMLファイル内で数値の後ろにsuffixをつけられるようになります。
10進数表記の整数と浮動小数点数で使用できます。
単位を表示するときなどに便利です。
```
a = 86_400_sec
b = 3.1416_rad
c = 10_μm
```
ですが、これらはあくまで単なる `suffix` であり、単位換算は行われません。
単位換算が必要な場合は、ユーザーが `suffix` を参照して実装してください。
これを使用するには、 `toml::spec``ext_num_suffix``true` にします。
数値と接尾辞の間は`_`で区切られている必要があります。
数値部分との区別のため、suffixは数値で始まることはできません。
```
distance = 100_m # valid
distance = 10_0m # invalid
distance = 10_0_m # valid
```
接尾辞は`std::string suffix`としてフォーマット情報に保持されます。
```cpp
#include <toml.hpp>
int main()
{
toml::spec spec;
spec.ext_hex_float = true;
const auto v = toml::parse_str("a = 86_400_sec", spec);
assert(v.at("a").is_integer());
assert(v.at("a").as_integer() == 86400);
assert(v.at("a").as_integer_fmt().suffix == "sec");
return 0;
}
```

View File

@@ -0,0 +1,93 @@
+++
title = "toml literal"
type = "docs"
weight = 60
+++
# `_toml`リテラル
`""_toml`リテラルによって、TOMLファイルをその場でフォーマットできます。
```cpp
#include <toml.hpp>
int main()
{
using namespace toml::literals::toml_literals;
const auto v = "a = 42"_toml;
assert(v.at("a").as_integer() == 42);
return 0;
}
```
改行を含む場合、生文字列リテラルが便利です。
```cpp
#include <toml.hpp>
int main()
{
using namespace toml::literals::toml_literals;
const auto v = R"(
a = 42
b = "foo"
)"_toml;
assert(v.at("a").as_integer() == 42);
assert(v.at("b").as_string() == "foo");
return 0;
}
```
値が単体で書かれていた場合、その値が返されます。
```cpp
#include <toml.hpp>
int main()
{
using namespace toml::literals::toml_literals;
const auto a = "42"_toml;
const auto b = "12:34:56"_toml;
assert(v.at("a").as_integer() == 42);
assert(v.at("b").as_local_time().hour == 12);
assert(v.at("b").as_local_time().minute == 34);
assert(v.at("b").as_local_time().second == 56);
return 0;
}
```
TOMLは数値のみからなるキーを許可しています。
よって、`[1]`はテーブル名として合法です。
`[1]`のようにテーブル定義と配列の区別がつかない場合、テーブル定義が優先されます。
配列として解釈させるには、trailing commaを使用してください。
```cpp
#include <toml.hpp>
int main()
{
using namespace toml::literals::toml_literals;
const auto t = "[1]"_toml; // {1 = {}}
const auto a = "[1,]"_toml; // [1,]
assert(t.is_table());
assert(t.at("1").is_table());
assert(a.is_array());
assert(a.at(0).as_integer() == 1);
return 0;
}
```

View File

@@ -0,0 +1,285 @@
+++
title = "parsing files"
type = "docs"
weight = 10
+++
# ファイル・文字列をパースする
toml11では、`toml::parse``toml::try_parse` を使って、ファイルや文字列、バイト列をパースすることができます。
これらは成功時に `toml::value` を返します。
ファイルは常にテーブルになりますが、返り値が `toml::table` でないことに気を付けてください。
`toml::value` はファイルに関するメタデータを持っており、
`toml::table``std::unordered_map<std::stirng, toml::value>` のエイリアスでしかありません。
メタデータを返すために、 `toml::table` ではなく `toml::value` を返しています。
ファイルのルートに対応する `toml::value` は常に `table_type` を持ちます。
## ファイルをパースする
ファイルをパースする際は、
[`toml::parse`]({{< ref "docs/reference/parser#parse" >}})
または
[`toml::try_parse`]({{< ref "docs/reference/parser#try_parse" >}})
を使います。
### `toml::parse`
#### `std::string`でファイル名を指定する
[`toml::parse`]({{< ref "docs/reference/parser#parse" >}})
は、文字列でファイル名を受け取り、そのファイルを開いてパースします。
以下のサンプルは、`input.toml`というファイルをパースし、`title`という変数を文字列として取り出し、出力するコードです。
```cpp
#include <toml.hpp>
#include <iostream>
int main()
{
const toml::value input = toml::parse("input.toml");
std::cout << input.at("title").as_string() << std::endl;
return 0;
}
```
#### `std::filesystem::path`でファイルを指定する
[`toml::parse`]({{< ref "docs/reference/parser#parse" >}})
には、`std::filesystem::path`を渡すことも可能です。
当然ですが、`<filesystem>`がサポートされるC++17以降でなければ使用できません。
#### `std::istream`で入力ストリームを指定する
[`toml::parse`]({{< ref "docs/reference/parser#parse" >}})
には、`std::istream`を渡すことも可能です。
標準ライブラリが改行文字を自動変換することによるファイルサイズと文字数との不整合を避けるため、
`std::ios::binary`を使ってバイナリモードで開いてください。
その際、ファイル名の情報がなくなるため、エラーメッセージ中では `"unknown file"` となります。
これを避けるため、 `std::istream` を取る場合は第二引数に `std::string` でファイル名を取ることもできます。
`std::ifstream` 以外にも、 `std::istringstream` 等の別の`istream`を受け取ることができます。
ただし、呼び出した時点で内容が全て読み込める必要があります。
```cpp
#include <toml.hpp>
#include <iostream>
int main()
{
std::string filename("input.toml");
std::ifstream ifs(filename);
const toml::value input = toml::parse(ifs, filename);
std::cout << input.at("title").as_string() << std::endl;
return 0;
}
```
#### `FILE*`でファイルを指定する
[`toml::parse`]({{< ref "docs/reference/parser#parse" >}})
には、`FILE*`を渡すことも可能です。
標準ライブラリによる改行文字の自動変換によるファイルサイズと文字数との不整合を避けるため、
`fopen("example.toml", "rb")`のようにしてバイナリモードで開いてください。
この場合も、`std::istream`のときと同様に、第二引数に文字列でファイル名を与える必要があります。
`FILE*`を渡した場合、ファイルの読み込みに失敗した際には`errno`が報告されます。
#### エラー時の挙動
[`toml::parse`]({{< ref "docs/reference/parser#parse" >}})
は、文法エラーを発見した場合
[`toml::syntax_error`]({{<ref "docs/reference/parser#syntax_error">}})
を送出します。
[`toml::syntax_error`]({{<ref "docs/reference/parser#syntax_error">}})
は、
[`toml::exception`]({{<ref "docs/reference/exception">}})
から派生しており、またそれは`std::exception`から派生します。
よって、
[`toml::syntax_error`]({{<ref "docs/reference/parser#syntax_error">}})
からは `what()` メンバ関数を使ってエラーメッセージを取り出すことができます。
また、
[`toml::syntax_error`]({{<ref "docs/reference/parser#syntax_error">}})
[`std::vector<toml::error_info>`]({{<ref "docs/reference/error_info">}})
を持っており、`errors()`メンバ関数を使ってそれにアクセスすることもできます。
`toml::parse` はごく簡単なエラーならスキップして復帰し、複数のエラーを報告しようと努めます。
数値のフォーマットエラー程度なら復帰できることが多いですが、
配列やテーブルの中のエラーは復帰できずに似たようなエラーを複数回報告することもあります。
冗長であると感じた場合は、 `std::vector<toml::error_info>``front()` だけを使用するようにすると、
確実に問題のある個所に関するメッセージを得られます。
```cpp
#include <toml.hpp>
int main()
{
// parse
try {
const toml::value input = toml::parse("input.toml");
std::cout << input.at("title").as_string() << std::endl;
} catch(const toml::syntax_error& err) {
// 全てのエラーを報告
std::cerr << err.what() << std::endl;
// 最初のエラーのみ報告
std::cerr << err.errors().front() << std::endl;
}
}
```
### `toml::try_parse`
`toml::parse` は失敗時に例外を送出しますが、 `toml::try_parse` は失敗時に例外を投げません。
その代わり、返り値が `toml::value` ではなく [`toml::result<toml::value, std::vector<toml::error_info>>`]({{<ref "docs/reference/result#result">}}) になります。
[`result`]({{<ref "docs/reference/result#result">}}) 型は成功値または失敗値のどちらかを持つ型です。
Rustの `Result` やHaskellの `Either` に相当します。
```cpp
#include <toml.hpp>
int main()
{
const auto parse_result = toml::try_parse("input.toml");
if(parse_result.is_ok())
{
std::cout << parse_result.unwrap().at("title").as_string() << std::endl;
}
else
{
std::cerr << parse_result.unwrap_err().at(0) << std::endl;
}
return 0;
}
```
[`result`]({{<ref "docs/reference/result#result">}}) 型がどちらの値を保持しているかは
`is_ok()`, `is_err()` 関数を使って確認できます。
また、 `unwrap()`, `unwrap_err()` によって成功値、失敗値をそれぞれ取り出せます。
`unwrap` が失敗した場合は、 `bad_result_access` 例外が送出されます。
`as_ok()``as_err()` 関数を使用すると、失敗時には例外が送出されず、未定義動作となります。
{{<hint warning>}}
`try_parse``syntax_error``file_io_error` を投げず、同じ `toml::error_info`
`result` の失敗型として返しますが、絶対に例外を投げないわけではありません。
標準ライブラリ内部でエラーが発生した場合、例えばメモリ不足の際に `vector`
`allocate` が失敗した場合などには `std::bad_alloc` が送出されますが、
`toml::try_parse` はこれが送出された場合は `catch` せずに通します。
そのため、それらのような標準ライブラリの内部で発生する例外は送出される恐れがあります。
{{</hint>}}
## 文字列をパースする
### `toml::parse_str`
[`toml::parse_str`]({{<ref "docs/reference/parser#parse_str">}})
は、ファイル名ではなくパースする文字列そのものを受け取ります。
また、エラーメッセージのTOMLファイルの名前に相当する部分には、`std::source_location`
相当のコンパイラ拡張機能が使用できる場合、 `parse_str` を呼び出したC++ファイルの名前と行数が代わりに使用されます。
```cpp
#include <toml.hpp>
#include <iostream>
int main()
{
const toml::value input = toml::parse_str("title = \"parse_str\"");
std::cout << input.at("title").as_string() << std::endl;
return 0;
}
```
### `toml::try_parse_str`
[`toml::try_parse_str`]({{<ref "docs/reference/parser#try_parse_str">}})
は、 `parse_str` と同じくパースする文字列そのものを受け取り、
`try_parse` と同じくエラーの報告に
[`toml::result`]({{<ref "docs/reference/result#result">}})
を使用します。
```cpp
#include <toml.hpp>
#include <iostream>
int main()
{
const auto parse_result = toml::try_parse_str("title = \"parse_str\"");
if(parse_result.is_ok())
{
std::cout << parse_result.unwrap().at("title").as_string() << std::endl;
}
else
{
std::cerr << parse_result.unwrap_err().at(0) << std::endl;
}
return 0;
}
```
## バイト列をパースする
ファイルではなくバイト列をパースすることも可能です。
UTF-8でエンコードされている必要があるため、`unsigned char`を使っています。
### `toml::parse(std::vector<unsigned char>)`
挙動は [`toml::parse`]({{<ref "docs/reference/parser#parse">}}) と同一です。
バイト列をパースする際は、 `filename` を要求します。
```cpp
#include <toml.hpp>
#include <iostream>
int main()
{
std::vector<unsigned char> bytes{/* ... */};
const toml::value input = toml::parse(bytes, "internal bytes");
std::cout << input.at("title").as_string() << std::endl;
return 0;
}
```
### `toml::try_parse(std::vector<unsigned char>)`
挙動は [`toml::try_parse`]({{<ref "docs/reference/parser#try_parse">}}) と同一です。
バイト列をパースする際は、 `filename` を要求します。
```cpp
#include <toml.hpp>
#include <iostream>
int main()
{
std::vector<unsigned char> bytes{/* ... */};
const auto parse_result = toml::try_parse(bytes, "internal bytes");
if(parse_result.is_ok())
{
std::cout << parse_result.unwrap().at("title").as_string() << std::endl;
}
else
{
std::cerr << parse_result.unwrap_err().at(0) << std::endl;
}
return 0;
}
```

View File

@@ -0,0 +1,234 @@
+++
title = "serializing values"
type = "docs"
weight = 40
+++
# TOMLファイルを出力する
`toml::format` を使うと、 `toml::value` を文字列にすることができます。
```cpp
#include <toml.hpp>
#include <cassert>
int main()
{
const toml::value v(toml::table{
{"a", 42},
{"b", "foo"},
});
const std::string s = toml::format(v);
const toml::value u = toml::parse_str(s);
assert(u.at("a").as_integer() == 42);
assert(u.at("b").as_string() == "foo");
return 0;
}
```
`table_type` を格納している `toml::value` が渡されると、それがファイルのルートテーブルとして解釈されます。
もし `table_type` 以外を格納している `toml::value` が渡されると、その値だけがフォーマットされます。
一部のフォーマット指定では、キーが渡されていないとフォーマットできないことがあります。
例えば、 `toml::array_format::array_of_tables``[[array.of.tables]]` の形でフォーマットするので、
キーへのアクセスを要求します。
キーを要求するフォーマット指定の値がキーなしで渡された場合、 `toml::serialization_error` が送出されます。
他にも、フォーマット指定と矛盾する値が含まれる場合には、 `toml::serialization_error` が送出されます。
例えば、 `integer_format::hex` が指定された整数が負の値を持っている場合や、
`string_format::literal` が指定された文字列が改行を含んでいる場合などです。
フォーマットの指定方法は後述します。
## キーを渡して出力する
`toml::format` には `std::string` としてキーを渡すことが可能です。
その場合、ルートテーブルの下にそのキーがあり、渡した値はそのキーに対応すると解釈されます。
キーが複数段になる場合、 `std::vector<std::string>` を渡すことができます。
```cpp
#include <toml.hpp>
#include <cassert>
int main()
{
const toml::value v(toml::table{
{"a", 42},
{"b", "foo"},
});
const std::string s = toml::format("bar", v);
const toml::value u = toml::parse_str(s);
assert(u.at("bar").at("a").as_integer() == 42);
assert(u.at("bar").at("b").as_string() == "foo");
return 0;
}
```
## フォーマットを指定する
`toml::value` のそれぞれの型には、対応するフォーマット情報型があります。
`toml::value::integer_type` には `toml::integer_format_info` が、
`toml::value::table_type` には `toml::table_format_info` があります。
これらは、パースした際に設定され、型が変わらない限り値を変更しても引き継がれます。
また、 `as_integer_fmt()``as_table_fmt()` といったメンバ関数によってアクセスすることができ、
直接編集することが可能です。
以下ではいくつかの例を挙げて使い方を説明します。
フォーマットへのアクセス方法は
[`toml::value`のリファレンス]({{< ref "/docs/reference/value" >}})を、
フォーマット情報クラスの完全なリストと詳細は
[formatのリファレンス]({{< ref "/docs/reference/format" >}})を
参照してください。
### 整数のフォーマットを指定する
整数は、基数と幅、そして `_` の位置を指定することができます。
`hex`, `oct`, `bin` のとき、指定された幅に達するまでゼロで埋められます。
`dec` の場合は幅指定はスペースを追加しますが、これはパースされません。
```cpp
#include <toml.hpp>
int main()
{
toml::value v(0x00C0'FFEE);
v.as_integer_fmt().fmt = toml::integer_format::hex;
v.as_integer_fmt().width = 8;
v.as_integer_fmt().spacer = 4;
const std::stirng s = toml::format(v);
assert(s == "0x00C0_FFEE");
return 0;
}
```
詳細は、[reference]({{< ref "/docs/reference/format#integer_format" >}}) を参照してください。
### 配列を単一行・複数行にする
配列には、 `toml::array_format::oneline``toml::array_format::multiline` を指定できます。
```toml
# oneline
a = [1, 2, 3, 4, 5]
# multiline
a = [
1,
2,
3,
4,
5
]
```
`multiline` のときは、インデントを指定できます。
各要素は `body_indent` の分だけインデントされ、閉じ括弧 `]``closing_indent` の分だけインデントされます。
文字種は `indent_type` で指定され、 `toml::indent_char::space` または `toml::indent_char::tab` が選択できます。
{{<hint warning>}}
インデントに使用する文字種は統一してください。
一つのファイル内でインデントに異なる文字種が指定された場合、結果は未規定になります。
何らかのインデントがされますが、全ての箇所で文字種やインデントの深さは不定となります。
{{</hint>}}
また、 `array` の要素が全て `table_type` を持つ場合、
`toml::array_format::array_of_tables` が指定できます。
`array_of_tables` を指定せずに `multiline` にした場合、テーブルはインラインテーブルになります。
```toml
# multiline
a = [
{foo = 42},
{bar = "hoge"},
]
# array_of_tables
[[a]]
foo = 42
[[a]]
bar = "hoge"
```
デフォルトでは、 `toml::array_format::default_format` が指定されます。
これは適したフォーマットを自動的に選択します。
例えば、 `default_format` で全要素が `table_type` だった場合、 `array_of_tables` が選択されます。
また、十分短い配列は `oneline` に、長い配列またはネストされた配列などの複雑な配列は `multiline` になります。
詳細は、[reference]({{< ref "/docs/reference/format#array_format" >}}) を参照してください。
### テーブルをインラインテーブルにする
テーブルをインラインテーブルにする際は `toml::table_format::oneline` を指定します。
通常のテーブルにする際は、 `toml::table_format::multiline` を指定します。
```toml
oneline = {a = 42, b = "foo"}
[multiline]
a = 42
b = "foo"
```
TOML v1.1.0ではインラインテーブル内での改行が許可されますが、その場合は
`toml::table_format::multiline_oneline` とします。
これは、後述するTOMLバージョン指定で対応する機能フラグが`true`になっていない限り無視されます。
```toml
multiline_oneline = {
a = 42,
b = "foo"
}
```
詳細は、[reference]({{< ref "/docs/reference/format#table_format" >}}) を参照してください。
## TOML言語バージョンを指定して出力する
TOML v1.1.0で許可されたインラインテーブル内の改行や`\x`エスケープシーケンスのように、
TOMLバージョンによって使用できない言語機能があります。
`toml::format` は最後の引数に `toml::spec` を取ることができます。
これにより、シリアライズ時に使用するTOMLのバージョンを指定することができます。
特に、 `toml::parse``toml::spec` を使用して新機能を使用した場合は、
パースした値がそのバージョンでしか使えないフォーマット情報を持つ場合があるので、
`toml::format` にも同じ `toml::spec` を渡すことを忘れないようにしてください。
```cpp
#include <toml.hpp>
#include <iostream>
int main()
{
const auto spec = toml::spec::v(1, 1, 0)
const toml::value v = toml::parse("input.toml", spec);
std::cout << toml::format(v, spec);
return 0;
}
```

View File

@@ -0,0 +1,116 @@
+++
title = "toml spec"
type = "docs"
weight = 70
+++
# TOML言語バージョン
[`toml::spec`]({{< ref "docs/reference/spec#tomlspec" >}})
によって、 `toml::parse``toml::format` で使用するTOML言語のバージョンや、個別の機能フラグを指定することができます。
## TOMLのバージョンを指定する
[`toml::spec`]({{< ref "docs/reference/spec#tomlspec" >}})
[`toml::semantic_version`]({{< ref "docs/reference/spec#tomlsemantic_version" >}})
から構築できます。
```cpp
#include <toml.hpp>
int main()
{
toml::spec spec(toml::semantic_version(1, 1, 0));
return 0;
}
```
ですがこれは長いので、`toml::spec::v()`関数が用意されています。
```cpp
#include <toml.hpp>
int main()
{
toml::spec spec = toml::spec::v(1, 1, 0);
return 0;
}
```
特に指定しない場合、デフォルトの値で構築する `toml::spec::default_version()` が使用されます。
デフォルトの値はtoml11のバージョンによって変わりますが、その時点でリリースされているTOML言語の最新バージョンに追従します。
v4.4.0現在、TOML v1.1.0はまだリリースされていないため、デフォルトのTOMLバージョンはv1.0.0です。
{{<hint warning>}}
TOML v1.1.0の一部の機能にはかなり長い議論が続いており、まだ差し戻される可能性があります。
実際に差し戻された場合、toml11はマイナーバージョンアップでそれらの機能を削除、もしくは対応するそれ以降のバージョンに移動します。
そのような意味で、将来のバージョンに関する機能は全て不安定なものと考えてください。
{{</hint>}}
### バージョン指定でパースする
[`toml::parse`]({{< ref "docs/reference/parser" >}})
のオーバーロードは、ファイル名に続いて`toml::spec`を受け取ります。
これによって、使用するTOMLバージョンを変更できます。
```cpp
#include <toml.hpp>
int main()
{
toml::value input = toml::parse("input.toml", toml::spec::v(1, 1, 0));
return 0;
}
```
### バージョン指定でシリアライズする
[`toml::format`]({{< ref "docs/reference/serializer" >}})
のオーバーロードは、 `toml::value` に続いて `toml::spec` を受け取ります。
これによって、使用するTOMLバージョンを変更できます。
```cpp
#include <toml.hpp>
int main()
{
toml::value v = toml::parse("input.toml", toml::spec::v(1, 1, 0));
std::cout << toml::format(v, toml::spec::v(1, 1, 0)) << std::endl;
return 0;
}
```
もしフォーマット変数などによって指定されているフォーマットが渡された `toml::spec`
では許可されていないものだった場合、指定は無視されて他のフォーマットにフォールバックされます。
## TOMLに追加された新機能を個別に指定する
TOMLのバージョンアップで追加された機能は複数あり、そのうちの一部だけを有効にすることが可能です。
```cpp
#include <toml.hpp>
int main()
{
toml::spec spec = toml::spec::v(1, 0, 0);
// インラインテーブル内での改行を許可
spec.v1_1_0_allow_newlines_in_inline_tables = true;
toml::value input = toml::parse("input.toml", spec);
return 0;
}
```
全てのフラグのリストは、
[`toml::spec`]({{< ref "docs/reference/spec#tomlspec" >}})
を参照してください。

View File

@@ -0,0 +1,933 @@
+++
title = "getting values"
type = "docs"
weight = 20
+++
# 値を取り出す
ここでは、 `toml::value` が格納している値にアクセスする方法を説明します。
## メンバ関数を使って値にアクセスする
### `is_something` と `as_something`
`toml::value``is_boolean()``is_integer()` などのメンバ関数を持っており、
これらを使うと持っている型を調べることができます。
また、 `as_boolean()`, `as_integer()` などのメンバ関数も持っており、
これらを使ってその型にアクセスすることができます。
完全なリストは [`toml::value` のリファレンス]({{<ref "docs/reference/value#is_xxx">}}) を参照してください。
```cpp
toml::value v = /* ... */;
if(v.is_integer())
{
std::cout << v.as_integer() << std::endl;
}
```
指定された値と異なる型が格納されていた場合、 [`toml::type_error`]({{<ref "docs/reference/value#tomltype_error">}}) が送出されます。
その `what()` は以下のようなメッセージを含みます。
```
[error] toml::value::as_string(): bad_cast to string
--> input.toml
|
1 | a = 123_456
| ^^^^^^^-- the actual type is integer
```
### `toml::value_t`
型情報は [`enum class toml::value_t`]({{<ref "docs/reference/value_t">}}) で識別できます。
[`type()`]({{<ref "docs/reference/value#type">}}) メンバ関数は、現時点で格納している値の型情報を返します。
```cpp
toml::value v = /* ... */;
switch(v.type())
{
case toml:value_t::empty : { /*...*/ break; }
case toml:value_t::boolean : { /*...*/ break; }
case toml:value_t::integer : { /*...*/ break; }
case toml:value_t::floating : { /*...*/ break; }
case toml:value_t::string : { /*...*/ break; }
case toml:value_t::offset_datetime: { /*...*/ break; }
case toml:value_t::local_datetime : { /*...*/ break; }
case toml:value_t::local_date : { /*...*/ break; }
case toml:value_t::local_time : { /*...*/ break; }
case toml:value_t::array : { /*...*/ break; }
case toml:value_t::table : { /*...*/ break; }
default: {break;}
}
```
[`is(toml::value_t)`]({{<ref "docs/reference/value#istomlvalue_t">}}) メンバ関数は、渡された `value_t` と同じ型の値を格納している場合 `true` を、
それ以外の場合 `false` を返します。
```cpp
toml::value v = /* ... */;
if(v.is(toml::value_t::integer))
{
std::cout << v.as_integer() << std::endl;
}
```
### `at`, `[]`, `contains`, `size`, `push_back`, `emplace_back`
標準ライブラリコンテナが持つメンバ関数の一部は、 `toml::value` も提供しています。
これらは、内部で `toml::value` を対応する型に変換し、そのメンバ関数を呼び出します。
#### `at(std::size_t i)`, `operator[](std::size_t i)`
`as_array().at(i)`, `as_array()[i]` と同等です。
`toml::value` はデフォルトで `std::vector<toml::value>``array_type` に使うので、
エラーが発生した際には `at``std::out_of_range` を送出し、`operator[]` は未定義動作となります。
```cpp
toml::value v(toml::array{1,2,3});
std::cout << v.at(1);
```
格納している型が `array_type` ではなかった場合、 `type_error` を送出します。
#### `at(std::string key)`, `operator[](std::string key)`
`as_table().at(key)`, `as_table()[key]` と同等です。
`toml::value` はデフォルトで `std::unordered_map<std::string, toml::value>``table_type` に使うので、
対応する値が存在しない場合は `at``std::out_of_range` を送出し、 `operator[]` は新しく `toml::value` を構築してそれへの参照を返します。
そのため、`operator[]``const` 版はありません。
```cpp
toml::value v(toml::table{});
v["a"] = 42;
```
格納している型が `table_type` ではなかった場合、 `type_error` を送出します。
#### `size()`
長さを返します。
`array_type` または `table_type` の場合は要素数、 `string_type` の場合は文字数を返します。
格納している型がどれでもなかった場合、 `type_error` を送出します。
#### `push_back()`, `emplace_back()`
`as_array().push_back()`, `as_array().emplace_back()` と同一です。
格納している型が `array_type` ではなかった場合、 `type_error` を送出します。
## コメントにアクセスする
toml11では、デフォルトでコメントがパースされ、対応する値に行ごとに保存されます。
対応する値は、連続するコメント行の直後に来る値か、もしくはそのコメントと同じ行に描かれている値です。
直前または直後に値がなければ、そのコメントはどこにも紐づけられず、無視されます。
```toml
# input.toml
# これはaに関するコメントです。
a = 42
b = 3.14 # これはbに関するコメントです。
# このコメントには対応する値がないため無視されます。
# これは1番目のcに関するコメントです。
# これは2番目のcに関するコメントです。
c = "foo" # これは最後のcに関するコメントです。
```
値に対応するコメントには、`toml::value``comments()` メンバ関数を使ってアクセスします。
`comments()``std::vector<std::string>` と同じメンバ関数を持つコンテナを返します。
```cpp
const auto v = toml::parse("input.toml");
const auto& a = v.at("a");
const auto& b = v.at("b");
const auto& c = v.at("c");
assert(a.comments().size() == 1);
assert(a.comments().at(0) == "# これはaに関するコメントです。");
assert(b.comments().size() == 1);
assert(b.comments().at(0) == "# これはbに関するコメントです。");
assert(c.comments().size() == 3);
assert(c.comments().at(0) == "# これは1番目のcに関するコメントです。");
assert(c.comments().at(1) == "# これは2番目のcに関するコメントです。");
assert(c.comments().at(2) == "# これは最後のcに関するコメントです。");
```
ファイル全体に対応するルートテーブルに関するコメントは、ファイルの先頭に書きます。
```toml
# ルートテーブルに関するコメントです。
# これもルートテーブルに関するコメントです。
# これはaに関するコメントです。
a = 42
```
ただし、もしファイルの先頭のコメントの直後に値が来た場合、
そのコメントはその値に関するコメントと解釈され、ルートテーブルのコメントはなくなります。
```toml
# これはaに関するコメントです。
# これもaに関するコメントです。
a = 42
```
## インラインテーブル・ドットキーの取り扱い
インラインテーブルは単にテーブルで、C++コード上で他のテーブルと異なる点はありません。
```toml
a = {b = 42, c = "foo"}
```
ドットキーも単にテーブルで、C++コード上で他のテーブルと異なる点はありません。
```toml
a.b = 42
a.c = "foo"
```
これらは以下のファイルと全く同じ構造を持ちます。
```toml
[a]
b = 42
c = "foo"
```
なので、どの記法でも以下の全く同一のコードで処理できます。
```cpp
const auto input = toml::parse("input.toml");
assert(input.at("a").at("b").as_integer() == 42);
assert(input.at("a").at("c").as_string() == "foo");
```
ただし、フォーマット情報によって区別することは可能です。
```cpp
const auto input = toml::parse("input.toml");
switch(input.at("a").as_table_fmt().fmt)
{
case toml::table_format::oneline:
{
std::cout << "inline table" << std::endl;
break;
}
case toml::table_format::multiline:
{
std::cout << "normal table" << std::endl;
break;
}
case toml::table_format::dotted:
{
std::cout << "dotted keys" << std::endl;
break;
}
}
```
このフォーマット情報は後述するシリアライズの際も考慮されます。
## 日付情報の取り扱い
[`local_date`]({{<ref "docs/reference/datetime#local_date">}}),
[`local_time`]({{<ref "docs/reference/datetime#local_time">}}),
[`local_datetime`]({{<ref "docs/reference/datetime#local_datetime">}}), そして
[`offset_datetime`]({{<ref "docs/reference/datetime#offset_datetime">}}) は、
toml11では対応するメンバ変数を持つ専用の構造体にパースされます。
使用する際は、直接値を取り出す他にも、後述する `toml::get``toml::find` を使用して、
`std::chrono::system_clock::time_point``std::tm` 等の型に変換することができます。
## `toml::get<T>`を使って変換する
`toml::get<T>` は、 `toml::value` の持つ値を変換して取り出す関数です。
`T` に変換先に指定したい型を指定します。
```cpp
const toml::value v = /*...*/;
std::cout << toml::get<int>(v) << std::endl;
```
後述する `toml::find<T>` も、型変換の部分は同一の機能を持ちます。
格納されている型のそれぞれについて、
変換ができない型が指定された場合、 `toml::type_error` が送出されます。
### 単純な変換
#### boolean_type
`boolean_type` から変換が可能なのは、 `bool` のみです。
#### integer_type
`bool` 以外で `std::is_integral<T>``true` になる型は、 `integer_type` から変換できます。
```cpp
toml::value v(42);
const auto u32 = toml::get<std::uint32_t>(v);
const auto i16 = toml::get<short>(v);
```
#### floating_type
`std::is_floating_point<T>``true` になる型は、`floating_type` から変換できます。
```cpp
toml::value v(3.14);
const auto f64 = toml::get<double>(v);
const auto f32 = toml::get<float >(v);
```
#### string_type
`string_type` からは `std::string` へ変換できます。
また、C++17以降では、`std::string_view` へも変換できます。
```cpp
toml::value v("foo");
const auto s = toml::get<std::string>(v);
// C++17以降
const auto sv = toml::get<std::string_view>(v);
```
#### datetime variants
[`local_date`]({{<ref "docs/reference/datetime#local_date">}}),
[`local_datetime`]({{<ref "docs/reference/datetime#local_datetime">}}),
[`offset_datetime`]({{<ref "docs/reference/datetime#offset_datetime">}}) は
ある日付と時刻を指しているため、
`std::chrono::system_clock::time_point` への変換が可能です。
ただし、[`local_time`]({{<ref "docs/reference/datetime#local_time">}}) は
日付の情報がないため、0時0分からの経過時刻として `std::chrono::duration` への
変換をサポートします。
また、 `local_date``local_datetime` は実行中のマシンのタイムゾーンを取得して変換を行います。
```toml
date = 2024-01-23
time = 12:30:00
l_dt = 2024-01-23T12:30:00
o_dt = 2024-01-23T12:30:00+09:00
```
```cpp
const auto input = toml::parse("input.toml");
const auto date = toml::get<std::chrono::system_clock::time_point>(input.at("date"));
const auto l_dt = toml::get<std::chrono::system_clock::time_point>(input.at("l_dt"));
const auto o_dt = toml::get<std::chrono::system_clock::time_point>(input.at("o_dt"));
const auto time = toml::get<std::chrono::minutes>(input.at("time")); // 12 * 60 + 30 min
```
### 参照を取得できる条件
`toml::get<T>` は、 `T``toml::value` が格納する型そのものだった場合、参照を返すことができます。
逆に、変換が必要な場合( `std::int64_t` で格納されている整数を `std::uint32_t` で取り出そうとした場合)は、
変換後の型への参照を返すことは不可能です。
変換が必要ない型の場合、返された参照を経由して値を書き換えることも可能です。
```cpp
toml::value v(42);
toml::get<toml::value::integer_type>(v) = 6 * 9;
assert(v.as_integer() == 54);
```
### 配列をSTLコンテナに
配列の要素型が全て同じ場合、要素型が `T` に変換可能であれば、 `std::vector<T>` に変換可能です。
```toml
a = [1, 2, 3, 4, 5]
```
```cpp
const auto a = toml::get<std::vector<int>>(input.at("a"));
```
他のSTLコンテナにも変換可能です。
```cpp
const auto a1 = toml::get<std::deque<int>>(input.at("a"));
const auto a2 = toml::get<std::list <int>>(input.at("a"));
const auto a3 = toml::get<std::array<int, 5>>(input.at("a"));
```
`std::array` に変換する場合、要素数が一致している必要があります。
もし要素数が一致しなかった場合、 `std::out_of_range` が送出されます。
STL以外のコンテナであっても、デフォルトコンストラクタと `push_back` を持っている場合、
`toml::get` で変換が可能です。
```cpp
const auto a = toml::get<boost::container::small_vector<int, 8>>(input.at("a"));
```
### 配列を `std::pair`, `std::tuple` に
配列の要素型が異なる場合、 `std::pair``std::tuple` に変換が可能です。
```toml
a = [true, 3.14]
b = [42, 2.718, "foo"]
```
```cpp
const auto a = toml::get<std::pair<bool, double>>(input.at("a"));
const auto b = toml::get<std::tuple<int, double, std::string>>(input.at("b"));
```
`std::array` の場合と同様に、配列の長さは `std::pair`, `std::tuple` の要素数と一致している必要があります。
もし要素数が一致しなかった場合、 `std::out_of_range` が送出されます。
また、各要素は対応する要素に変換できる必要があります。
変換できない場合、 `toml::type_error` が送出されます。
### ネストされた配列の変換
ネストされた配列は、ネストされたコンテナに変換可能です。
```toml
a = [ [1, 2, 3], [4, 5, 6] ]
```
```cpp
const auto a = toml::get<std::vector<std::vector<int>>>(input.at("a"));
```
型が異なる場合には、 `std::pair/tuple` が便利です。
```toml
a = [ [1, 2, 3], ["foo", "bar"] ]
```
```cpp
const auto a = toml::get<
std::pair<std::vector<int>, std::vector<std::string>>
>(input.at("a"));
```
### テーブルを `std::map` に変換
テーブルに含まれる値の型が全て同じであれば、 `std::map``std::unordered_map` に変換が可能です。
```toml
t = {a = 1, b = 2}
```
```cpp
const auto t = toml::get<std::map<std::string, int>>(input.at("t"));
```
STL以外のコンテナであっても、デフォルトコンストラクタと `emplace(key, mapped)` を持っている場合、
`toml::get` で変換が可能です。
```cpp
const auto t = toml::get<boost::container::flat_map<std::string, int>>(input.at("t"));
```
要素型の変換に失敗した場合は `toml::type_error` が送出されます。
## `toml::get_or`を使って失敗時の値を指定する
`toml::get` は変換に失敗した際に `toml::type_error` 例外を送出します。
`toml::get_or` を使用することで、変換に失敗した際に例外ではなくデフォルト値を返せるようになります。
`toml::get<T>` とは異なり、 `get_or` は引数から変換先の型を推論するため、 `<T>` の指定は不要です。
```cpp
const auto a = toml::get_or(input.at("a"), 42);
```
変換可能な型は `toml::get` と同様です。
`toml::value::xxx_type`を指定した場合は、参照を取り出すことも可能ですが、その場合は引数も参照である必要があります。
```cpp
toml::value::integer_type a_default = 42;
auto a& = toml::get_or(input.at("a"), a_default);
```
## `toml::find<T>`を使って検索と変換を同時に行う
`toml::find<T>` は、テーブルを持つ `toml::value` から値を検索し、同時に
`toml::get` と同じ型変換を行って取り出す関数です。
```cpp
const auto a = toml::find<int>(input, "a");
// const auto a = toml::get<int>(input.at("a")); と同じ
```
`toml::find<T>` は配列にも使用できます。
```cpp
const auto a = input.at("a");
const auto a2 = toml::find<int>(a, 2);
// const auto a2 = toml::get<int>(input.at("a").at(2)); と同じ
```
型変換の際にエラーが起きた場合、 `toml::get` と同じ `toml::type_error`
送出します。
キーが見つからなかった場合またはインデックスが存在しない場合は、
`std::out_of_range` を送出します。
型を指定しなかった場合、型変換を行わず `toml::value` を取り出します。
```cpp
const auto a = toml::find(input, "a");
// const auto a = input.at("a"); と同じ
```
`toml::find<T>` は再帰的に値にアクセスることもできます。
```toml
a = {b = {c = 42}}
```
```cpp
const auto a_b_c = toml::find<int>(input, "a", "b", "c");
// const auto a = toml::get<int>(input.at("a").at("b").at("c")); と同じ
```
このとき、キーとインデックスを混ぜることができます。
```toml
a = [ {b = 1}, {b = 2}, {b = 3} ]
```
```cpp
const auto a_2_b = toml::find<int>(input, "a", 2, "b");
// const auto a = toml::get<int>(input.at("a").at(2).at("c")); と同じ
```
{{<hint info>}}
TOMLはquoted keyという機能を持っています。
これは、 `""``''` を使うことで通常許可されない文字をキーに使えるというもので、
この中では `.` はテーブルを導入**しません**。
```toml
"127.0.0.1" = "value"
site."google.com" = true
```
このTOMLファイルは以下のようにして読みます。
```cpp
const auto input = toml::parse("input.toml");
assert(input.at("127.0.0.1").as_string() == "value");
assert(input.at("site").at("google.com").as_boolean());
```
このような場合にも違和感なく対応するため、toml11ではキーに `.` が含まれていても
自動で分割はしません。
テーブルの階層構造を陽に指定することが、適切な入力ファイルの構造化に資すると考えているからです。
参考: [toml.io キー](https://toml.io/ja/v1.0.0#%E3%82%AD%E3%83%BC)
{{</hint>}}
## `toml::find_or`を使って失敗時の値を指定する
`toml::find_or` は、 `toml::get_or` と同様に、失敗時のデフォルト値を渡します。
```cpp
const auto a = toml::find_or(input, "a", 42);
```
型変換の失敗だけでなく、キーが見つからなかった場合もデフォルト値を返します。
## `toml::find_or_default`を使って失敗時の値を指定する
`toml::find_or_default` は、 `toml::find_or` と同様に、失敗時にデフォルトコンストラクタの結果を返します。デフォルトコンストラクタは失敗時のみに呼ばれるため、特にそれが高価な時に有効です。
```cpp
const auto a = toml::find_or(input, "a", expensive()); // 関数呼出前にコンストラクタ呼出
const auto a = toml::find_or_default<expensive>(input, "a"); // 失敗時にのみコンストラクタ呼出
```
型変換の失敗だけでなく、キーが見つからなかった場合もデフォルトコンストラクタの結果を返します。
## `toml::find<std::optional<T>>`
C++17以降の場合、`std::optional``toml::find`に指定することができます。
`find`と同様に、再帰的なアクセスも可能です。
```cpp
const auto input = toml::parse_str(R"(
integer = 1
[table]
key = 2
[[array-of-tables]]
key = 3
)");
const auto a = toml::find<std::optional<int>>(input, "integer");
const auto b = toml::find<std::optional<int>>(input, "table", "key");
const auto c = toml::find<std::optional<int>>(input, "array-of-tables", 0, "key");
```
キーが存在しなかった場合、例外は投げられず、`std::nullopt`が返却されます。
ただし、型変換が失敗した場合や、テーブルではない値にキーでアクセスしようとした場合、配列でない値にインデックスでアクセス仕様とした場合は、`toml::type_error`が送出されます。
## ユーザー定義型との変換を定義する
`toml::get``toml::find` では、以下のどれかの方法を使うことで
ユーザー定義型を使用することができます。
### `toml::from` の定義
toml11には `toml::from` という型があり、以下のように特殊化することでユーザー定義型からの
変換をサポートできます。
```cpp
namespace extlib
{
struct foo
{
int a;
std::string b;
};
} // extlib
namespace toml
{
template<>
struct from<extlib::foo>
{
static extlib::foo from_toml(const toml::value& v)
{
return extlib::foo{
toml::find<int>(v, "a"),
toml::find<std::string>(v, "b")
};
}
};
} // toml
```
後述する型設定を変更した `toml::value` もサポートする場合、以下のようにしてください。
```cpp
namespace extlib
{
struct foo
{
int a;
std::string b;
};
} // extlib
namespace toml
{
template<>
struct from<extlib::foo>
{
template<typename TC>
static extlib::foo from_toml(const toml::basic_value<TC>& v)
{
return extlib::foo{
toml::find<int>(v, "a"),
toml::find<std::string>(v, "b")
};
}
};
} // toml
```
この定義は、 `TOML11_DEFINE_CONVERSION_NON_INTRUSIVE` によって自動的に定義できます。
```cpp
namespace extlib
{
struct foo
{
int a;
std::string b;
};
} // extlib
TOML11_DEFINE_CONVERSION_NON_INTRUSIVE(extlib::foo, a, b)
```
あるいは、リフレクションライブラリを使用することもできます。
`example``boost-ext/reflect` を使用したサンプルも参照してください。
### `from_toml` メンバ関数の定義
`from_toml` メンバ関数を定義することによっても変換を定義することができます。
これを使用する場合、デフォルトコンストラクタが必要です。
```cpp
struct bar
{
int a;
std::string b;
void from_toml(const toml::value& v)
{
this->a = toml::find<int>(v, "a");
this->b = toml::find<std::string>(v, "b");
return ;
}
};
```
両方が定義されていた場合、 `toml::from` が優先されます。
### `toml::value` を受け取るコンストラクタ
`toml::value` を受け取るコンストラクタがあれば、 `toml::get` による変換ができます。
```cpp
struct baz
{
explicit baz(const toml::value& v)
: a(toml::find<int>(v, "a")), b(toml::find<std::string>(v, "b"))
{}
int a;
std::string b;
};
```
両方が定義されていた場合、`toml::from``from_toml` が優先されます。
## `toml::visit`で関数を適用する
`toml::value` が格納する型すべてに適用できる関数オブジェクトがあれば、
`toml::visit` によって型変換を経ずに直接その関数を呼ぶことができます。
```cpp
struct type_name_of
{
std::string operator()(const toml::value::boolean_type &) const {return "boolean";}
std::string operator()(const toml::value::integer_type &) const {return "integer";}
std::string operator()(const toml::value::floating_type &) const {return "floating";}
std::string operator()(const toml::value::string_type &) const {return "string";}
std::string operator()(const toml::value::local_time_type &) const {return "local_time";}
std::string operator()(const toml::value::local_date_type &) const {return "local_date";}
std::string operator()(const toml::value::local_datetime_type &) const {return "local_datetime";}
std::string operator()(const toml::value::offset_datetime_type&) const {return "offset_datetime";}
std::string operator()(const toml::value::array_type &) const {return "array";}
std::string operator()(const toml::value::table_type &) const {return "table";}
};
toml::value v(3.14);
std::cout << toml::visit(type_name_of{}, v) << std::endl; // floating
```
## `toml::value` を構築する
`toml::value` はパーサの内部だけでなく、ユーザーコードで構築することも可能です。
`toml::value` が格納する型と同じか変換可能な型を渡しての構築が可能です。
```cpp
toml::value v1(true);
toml::value v2(42);
toml::value v3(3.14);
```
配列の場合、 `toml::array` を使うか、
```cpp
toml::value v(toml::array{1, 2, 3});
```
配列の場合、 `std::vector` などのコンテナを直接渡すことが可能です。
```cpp
const std::vector<toml::value> a{1,2,3};
toml::value v(a);
```
このコンテナには、 `toml::get` で変換可能なコンテナが使用できます。
テーブルの場合も同様に、 `toml::table` を使うか、
```cpp
toml::value v(toml::table{{"foo", 1}, {"bar", 2}, {"baz", 3}});
```
`std::map` などのコンテナを直接渡します。
```cpp
const std::map<std::string, toml::value> t{
{"foo", 1}, {"bar", 2}, {"baz", 3}
}
toml::value v(t);
```
コンストラクタには、 `format_info` と コメントを渡すことができます。
コメントの型は `std::vector<std::string>` です。
各要素が一行分に相当します。
```cpp
toml::integer_format_info fmt;
fmt.fmt = toml::integer_format::hex;
fmt.spacer = 4;
toml::value v1(0xDEADBEEF, fmt);
toml::value v2(0xC0FFEE, fmt, {"hex value!"});
```
## `toml::value` に変換する
ユーザー定義型から `toml::value` を構築する際に、 `toml::into``into_toml`
定義することで、その挙動をカスタマイズできます。
特に、別のライブラリの型などを変換する際に `toml::into` が便利です。
### `toml::into`を定義する
`toml::into` を特殊化することで `toml::value` への変換が可能になります。
`toml::value` への変換が用意されていない外部ライブラリの型などに対して有効です。
`toml::value` が変換時に `type_config` を渡すため、`basic_value``template` 引数を受け取る必要があります。
```cpp
namespace extlib
{
struct foo
{
int a;
std::string b;
};
} // extlib
template<>
struct into<extlib::foo>
{
template<typename TC>
static toml::basic_value<TC> into_toml(const extlib::foo& f)
{
return toml::basic_value<TC>(typename toml::basic_value<TC>::table_type{{"a", f.a}, {"b", f.b}});
}
};
```
### `into_toml` メンバ関数を定義する
`from_toml` と同様、メンバ関数によっても変換を定義することができます。
`toml::into` が定義されていた場合、そちらが優先されます。
```cpp
struct bar
{
int a;
std::string b;
toml::value into_toml() const
{
return toml::value(toml::table{{"a", this->a}, {"b", this->b}});
}
};
```
# 値がアクセス済みかどうかチェックする
{{% hint warning %}}
この機能はデフォルトでは有効化されず、使用する際には`TOML11_ENABLE_ACCESS_CHECK`を定義する必要があります。
また、この機能はパースした値に対して追加の処理を行うため、実行時パフォーマンスが低下する可能性があります。
{{% /hint %}}
`TOML11_ENABLE_ACCESS_CHECK`マクロを定義してコンパイルすると、`toml::value``bool accessed() const`メソッドが追加され、パース後にその値にアクセスしたかどうかが確認できるようになります。
```console
$ g++ -std=c++17 -O2 -DTOML11_ENABLE_ACCESS_CHECK -I/path/to/toml11/include main.cpp
```
```console
$ cmake -B ./build -DTOML11_ENABLE_ACCESS_CHECK=ON
```
```cmake
CPMAddPackage(
NAME toml11
GITHUB_REPOSITORY "ToruNiina/toml11"
VERSION 4.4.0
OPTIONS "CMAKE_CXX_STANDARD 17" "TOML11_PRECOMPILE ON" "TOML11_ENABLE_ACCESS_CHECK ON"
)
```
この機能によって、テーブル内に定義されているものの使用されなかった値についての警告を表示することが可能になります。
```cpp
#include <toml.hpp>
namespace yours
{
Config read_config(const toml::value& v)
{
const auto cfg = read_your_config(input);
for(const auto& [k, v] : input.as_table())
{
if( ! v.accessed())
{
std::cerr << toml::format_error("value defined but not used",
v.source_location(), "not used");
}
}
return cfg;
}
} // yours
```
この機能は、必要な場合のみ定義されるような値を、名称を間違えて定義してしまった際に役に立つでしょう。
例えば、
```toml
# 正しくは reactions
# reactions = [ ":+1:", "star" ]
# 名前が違うので読み込めない
reaction = [ ":+1:", "star" ]
```
このファイルを上記のコードで読んだ場合、`read_your_config``reactions`を探し、定義されていなかったので空の配列として処理するでしょう。
その場合、`reaction``accessed()``true`にならないため、エラーとして検出できます。

View File

@@ -0,0 +1,153 @@
+++
title = "installation"
type = "docs"
weight = 1
+++
# installation
## `single_include`を使用する
`single_include/toml.hpp`は、`toml11`が持つ全ての機能を単一のファイルにまとめたシングルファイル・ヘッダオンリーライブラリです。
これを`INCLUDE_PATH`が通っている箇所にコピーして`#include <toml.hpp>`とするのが最も単純な使用方法です。
MITライセンスの許諾表示はコメントと`toml:license_notice()`関数の両方に含まれます。
ソースコードを公開せずに再頒布する場合は、toml11のライセンスファイルをコピーして同梱するか、この関数を呼び出せるようにしておいてください。
## toml11をクローンし、`cmake`を使って使用する
`toml11``git submodule`などによって自身のレポジトリ下に配置した場合、`cmake`を使用している場合は`add_subdirectory(toml11)`のようにすることで使用可能になります。
```cmake
add_subdirectory(toml11)
add_executable(main main.cpp)
target_link_libraries(main PUBLIC toml11::toml11)
```
`toml11`は自身がルートプロジェクトのときのみ、テストとインストールを行います。
### CMake `FetchContent`
CMakeの `FetchContent`を使用することで、`build`ディレクトリに自動でダウンロードすることができます。
```cmake
include(FetchContent)
FetchContent_Declare(
toml11
GIT_REPOSITORY https://github.com/ToruNiina/toml11.git
GIT_TAG v4.4.0
)
FetchContent_MakeAvailable(toml11)
add_executable(main main.cpp)
target_link_libraries(main PRIVATE toml11::toml11)
```
### CMake Package Manager (CPM)
[CMake package manager](https://github.com/cpm-cmake/CPM.cmake)を導入すると、以下のようにして使用することができます。
```cmake
include(cmake/CPM.cmake)
CPMAddPackage("gh:ToruNiina/toml11@4.4.0")
# OR
CPMAddPackage(
NAME toml11
GITHUB_REPOSITORY "ToruNiina/toml11"
VERSION 4.4.0
OPTIONS
"TOML11_PRECOMPILE ON" # to pre-compile
"TOML11_ENABLE_ACCESS_CHECK ON" # to use value.accessed()
)
add_executable(main main.cpp)
target_link_libraries(main PUBLIC toml11::toml11)
```
## `cmake`を使用してインストールする
`toml11`をクローンしたのち、`cmake`を使ってインストールすることができます。
```console
$ cmake -B ./build/ -DTOML11_BUILD_TESTS=ON
$ cmake --install ./build/ --prefix=/opt/toml11
```
インストールの前にテストプログラムを実行する際は、最初に`-DTOML11_BUILD_TESTS=ON`を設定してください。
インストールが完了すれば、以下のようにして使用できます。
```cmake
find_package(toml11)
add_executable(main main.cpp)
target_link_libraries(main PRIVATE toml11::toml11)
```
## `cmake`を使用してコンパイルし、静的ライブラリを作成する
`cmake`の実行時に`-DTOML11_PRECOMPILE=ON`を定義することで、`toml11`の関数のうちコンパイルできるものを先にコンパイルして、全体のコンパイル時間を短縮することができます。
```console
$ cmake -B ./build/ -DTOML11_PRECOMPILE=ON
```
ライブラリをリンクする場合は、CMakeで
```cmake
target_link_libraries(your_target PUBLIC toml11::toml11)
```
とするか、ヘッダ内の関数の`inline`化を避けるためにコンパイラに`-DTOML11_COMPILE_SOURCES`を渡してください。
ただし、toml11は複数のC++バージョンに対応するため、`__cplusplus`の値などによって型を切り替えることがあります。
そのため、ビルドした際のバージョンと使用時のバージョンが異なる場合、リンクに失敗する可能性があります。
問題が生じた場合は`CMAKE_CXX_STANDARD`によって必要なバージョンを設定してコンパイルしてください。
それが難しい場合は、通常通りヘッダオンリーライブラリとして使用してください。
`find_package(toml11)`によって`TOML11_INCLUDE_DIR`が定義されます。
コンパイル済みライブラリとしてインストールした場合でも、 `TOML11_INCLUDE_DIR`
`include_directories` に追加した上で `target_link_libraries`
使用しないようにすれば、ヘッダオンリーライブラリとして使用可能です。
```cmake
find_package(toml11)
add_executable(main main.cpp)
# インクルードのみ可能にし、リンクを行わない
target_include_directories(main PRIVATE ${TOML11_INCLUDE_DIR})
```
## examplesをコンパイルする
`-DTOML11_BUILD_EXAMPLES=ON`とすることで、`examples/`をコンパイルできます。
```console
$ cmake -B ./build/ -DTOML11_BUILD_EXAMPLES=ON
$ cmake --build ./build/
```
`examples`の実行バイナリは`examples/`に生成されます。
## テストを実行する
テストをビルドするためには、`-DTOML11_BUILD_TESTS=ON`とします。
```console
$ git submodule update --init --recursive
$ cmake -B ./build/ -DTOML11_BUILD_TESTS=ON
$ cmake --build ./build/
$ ctest --test_dir ./build/
```
toml-lang/toml-testsを実行するには、`-DTOML11_BUILD_TOML_TESTS=ON`とします。
すると、`tests/``toml11_decoder``toml11_encoder`がビルドされます。
```console
$ git submodule update --init --recursive
$ cmake -B ./build/ -DTOML11_BUILD_TOML_TESTS=ON
$ cmake --build ./build/
$ ctest --test_dir ./build/
```

View File

@@ -0,0 +1,124 @@
+++
title = "reference"
type = "docs"
weight = 3
bookCollapseSection = true
+++
# Reference
以下では、toml11が公開するクラスと関数の効果を説明します。
## ディレクトリ構造
`toml.hpp``toml_fwd.hpp``${TOML11_INCLUDE_DIR}` にあります。
他のファイルは、`${TOML11_INCLUDE_DIR}/toml11` にあります。
もし各機能のファイルを個別に `#include` したい場合は、 `#include <toml11/color.hpp>` としてください。
全てを一度に `#include` する場合は、 `#include <toml.hpp>` としてください。
## [color.hpp](color)
エラーメッセージの色付けに関する関数を定義します。
## [comments.hpp](comments)
コメントを持つ`preserve_comment`型と`discard_comment`型を定義します。
## [conversion.hpp](conversion)
`toml::value`とユーザー定義クラスを自動的に変換するマクロを定義します。
## [datetime.hpp](datetime)
日時情報を持つクラスを定義します。
## [error_info.hpp](error_info)
エラー情報を持つクラスを定義します。
## [exception.hpp](exception)
toml11で使用される例外の基底クラス、`toml::exception`を定義します。
## [find.hpp](find)
値を探し変換する`toml::find`関数を定義します。
## [format.hpp](format)
値のフォーマット情報を持つクラスを定義します。
## [from.hpp](from)
ユーザー定義型を変換するための`from<T>`型の前方宣言です。
## [get.hpp](get)
`toml::value`の値を取り出し変換する`toml::get<T>`関数を定義します。
## [into.hpp](into)
ユーザー定義型を変換するための`into<T>`型の前方宣言です。
## [literal.hpp](literal)
`operator"" _toml`リテラルを定義します。
## [ordered_map.hpp](ordered_map)
`toml::ordered_map`を定義します。
## [parser.hpp](parser)
ファイルまたは文字列をパースする関数を定義します。
## [result.hpp](result)
他の関数の返り値として使われる、成功値または失敗値を持つ`result<T, E>`型を定義します。
## [serializer.hpp](serializer)
シリアライズに用いる`toml::format`関数と`toml::serializer`を定義します。
## [source_location.hpp](source_location)
エラー情報に用いられる、ファイル内のある領域を指す`source_location`型を定義します。
## [spec.hpp](spec)
TOML言語のバージョン情報と機能フラグを制御する、`toml::semantic_version`型と`toml::spec`型を定義します。
## [toml.hpp](toml)
`toml.hpp`は、他の全てのヘッダを `include` します。
toml11の全機能が使用可能になります。
## [toml_fwd.hpp](toml_fwd)
`toml_fwd.hpp`は、toml11で定義される構造体の前方宣言と、マクロ定義を持ちます。
## [types.hpp](types)
`toml::value`の持つ型を制御するための`toml::type_config`型を定義します。
## [value.hpp](value)
`toml::value`型を定義します。
## [value_t.hpp](value_t)
列挙型`toml::value_t`を定義します。
## [version.hpp](version)
toml11のバージョン情報を定義します。
## [visit.hpp](visit)
`toml::value`の持つ値に関数を適用する`toml::visit`関数を定義します。
## 備考
ここで明記されない関数(主に`namespace toml::detail``namespace toml::cxx`以下に定義されるもの)は、
ソースコードを見ることで利用可能ではあるものの、そのインターフェースは今後のいかなるバージョンアップでも(パッチバージョンアップを含む)維持される保証はありません。

View File

@@ -0,0 +1,150 @@
+++
title = "color.hpp"
type = "docs"
+++
# color.hpp
`color.hpp`では、エラーメッセージの色付けに関する関数が定義されます。
色はANSIエスケープシーケンスによって指定されます。
ANSIエスケープシーケンスをサポートしていないターミナルやその他の出力先では、読みにくくなる可能性があります。
## マクロ
### `TOML11_COLORIZE_ERROR_MESSAGE`
コンパイル時にこのマクロが定義されていた場合(`-DTOML11_COLORIZE_ERROR_MESASGE`)、
デフォルトでエラーメッセージに色が付きます。
定義されていなかった場合、デフォルトでは色は付きません。以下の `toml::color::enable()`
使用して指定する必要があります。
### `TOML11_USE_THREAD_LOCAL_COLORIZATION`
コンパイル時にこのマクロが定義されていた場合(`-DTOML11_COLORIZE_ERROR_MESASGE`)、
`toml::color::enable`の設定が`thread_local`になります。
この場合、`toml::color::enable()``toml::color::disable()`は、それを呼び出したスレッドでの設定しか変更しません。
つまり、新しいスレッドを起動した際にデフォルトと異なる設定にしたい場合は、再度設定が必要になります。
その代わり、`toml::color::enable()``toml::color::disable()`はスレッドセーフになります。
デフォルトでは設定はグローバルです。
グローバルの場合、一つのスレッドが`toml::color::enable()`を実行した場合、すべてのスレッドで色が付きます。
ただし、あるスレッドが`enable()`または`disable()`を実行している間に別のスレッドが`enable()``disable()``should_color()`を実行した場合、その結果は未定義です。
## 関数
### `enable()`
```cpp
namespace toml {
namespace color {
void enable();
} // color
} // toml
```
ANSIエスケープシーケンスによる色付けを行うよう設定します。
#### 例
```cpp
#include <toml.hpp>
int main()
{
toml::color::enable(); // この後の全てのエラーがカラーになります。
const auto input = toml::parse("input.toml");
return 0;
}
```
### `disable()`
```cpp
namespace toml {
namespace color {
void disable();
} // color
} // toml
```
ANSIエスケープシーケンスによる色付けを行わないよう設定します。
#### 例
```cpp
#include <toml.hpp>
int main()
{
toml::color::enable(); // この後の全てのエラーがカラーになります。
const auto input = toml::parse("input.toml");
return 0;
}
```
### `should_color()`
```cpp
namespace toml {
namespace color {
bool should_color();
} // color
} // toml
```
色付けを行う設定になっている場合`true`が、そうでない場合`false`が返されます。
#### 例
```cpp
#include <toml.hpp>
#include <iomanip>
#include <iostream>
int main()
{
std::cout << "colorized? : " << std::boolalpha << toml::color::should_color() << std::endl;
return 0;
}
```
## マニピュレータ
```cpp
namespace toml {
namespace color {
std::ostream& reset (std::ostream&);
std::ostream& bold (std::ostream&);
std::ostream& grey (std::ostream&);
std::ostream& gray (std::ostream&);
std::ostream& red (std::ostream&);
std::ostream& green (std::ostream&);
std::ostream& yellow (std::ostream&);
std::ostream& blue (std::ostream&);
std::ostream& magenta(std::ostream&);
std::ostream& cyan (std::ostream&);
std::ostream& white (std::ostream&);
} // color
} // toml
```
ANSIエスケープシーケンスによって、`fg`を色付けします。
#### 例
```cpp
#include <toml.hpp>
#include <iostream>
int main()
{
std::cout << toml::color::red << "red!" << std::endl;
return 0;
}
```
# 関連項目
- [error_info.hpp]({{<ref "error_info.md">}})

View File

@@ -0,0 +1,773 @@
+++
title = "comments.hpp"
type = "docs"
+++
# comments.hpp
`color.hpp`では、コメントを保持するクラスが提供されます。
# `toml::preserve_comments`
`preserve_comments`は、コメントを保持するコンテナです。
`std::vector<std::string>`が持つメンバ関数を全て持っています。
コメントは`std::string`として保持されます。
先頭が`#`でない場合、出力時に`#`が補われます。コンテナに要素として追加する段階では補われません。
スペースは補われないため、`#`の直後にスペースを入れたい場合、コメントをスペースから始めるか、`#`を含めたコメントを渡す必要があります。
```cpp
namespace toml
{
class preserve_comments;
bool operator==(const preserve_comments&, const preserve_comments&);
bool operator!=(const preserve_comments&, const preserve_comments&);
bool operator< (const preserve_comments&, const preserve_comments&);
bool operator<=(const preserve_comments&, const preserve_comments&);
bool operator> (const preserve_comments&, const preserve_comments&);
bool operator>=(const preserve_comments&, const preserve_comments&);
void swap(preserve_comments&, preserve_comments&);
void swap(preserve_comments&, std::vector<std::string>&);
void swap(std::vector<std::string>&, preserve_comments&);
std::ostream& operator<<(std::ostream&, const preserve_comments&);
} //toml
```
## メンバ型
```cpp
using container_type = std::vector<std::string>;
using size_type = container_type::size_type;
using difference_type = container_type::difference_type;
using value_type = container_type::value_type;
using reference = container_type::reference;
using const_reference = container_type::const_reference;
using pointer = container_type::pointer;
using const_pointer = container_type::const_pointer;
using iterator = container_type::iterator;
using const_iterator = container_type::const_iterator;
using reverse_iterator = container_type::reverse_iterator;
using const_reverse_iterator = container_type::const_reverse_iterator;
```
## メンバ関数
### デフォルトコンストラクタ
```cpp
preserve_comments() = default;
```
空の`preserve_comments`を構築します。
### コピー・ムーブコンストラクタ
```cpp
preserve_comments(preserve_comments const&) = default;
preserve_comments(preserve_comments &&) = default;
```
`preserve_comments`をコピー・ムーブ構築します。
### コンストラクタ(`std::vector<std::string>`)
```cpp
explicit preserve_comments(const std::vector<std::string>& c);
explicit preserve_comments(std::vector<std::string>&& c);
```
`std::vector<std::string>`の内容を持つ`preserve_comments`を構築します。
### コンストラクタ(`discard_comments`)
```cpp
explicit preserve_comments(const discard_comments&);
```
空の`preserve_comments`を構築します。
### コンストラクタ(`Iterator`)
```cpp
template<typename InputIterator>
preserve_comments(InputIterator first, InputIterator last);
```
`std::string`を指す`InputIterator`が表す範囲から`preserve_comments`を構築します。
### コンストラクタ(`std::initializer_list`)
```cpp
preserve_comments(std::initializer_list<std::string> x);
```
`std::initializer_list<std::string>`が表す範囲から`preserve_comments`を構築します。
### コンストラクタ(サイズ指定)
```cpp
explicit preserve_comments(size_type n);
preserve_comments(size_type n, const std::string& x);
```
`n`個のコメントを持つ`preserve_comments`を構築します。
`std::string`を渡した場合、そのコメントを`n`個に複製します。
### デストラクタ
```cpp
~preserve_comments() = default;
```
`preserve_comments`を破棄します。
### `operator=(preserve_comments)`
```cpp
preserve_comments& operator=(preserve_comments const&) = default;
preserve_comments& operator=(preserve_comments &&) = default;
```
`preserve_comments`をコピー・ムーブ代入します。
### `operator=(std::vector<std::string>)`
```cpp
preserve_comments& operator=(const std::vector<std::string>& c);
preserve_comments& operator=(std::vector<std::string>&& c);
```
`std::vector<std::string>`をコピー・ムーブ代入します。
### `assign`
```cpp
template<typename InputIterator>
void assign(InputIterator first, InputIterator last);
void assign(std::initializer_list<std::string> ini);
void assign(size_type n, const std::string& val);
```
`std::vector<std::string>::assign`と同等の効果を持ちます。
### `insert`
```cpp
iterator insert(const_iterator p, const std::string& x);
iterator insert(const_iterator p, std::string&& x);
iterator insert(const_iterator p, size_type n, const std::string& x);
template<typename InputIterator>
iterator insert(const_iterator p, InputIterator first, InputIterator last);
iterator insert(const_iterator p, std::initializer_list<std::string> ini);
```
`std::vector<std::string>::insert`と同等の効果を持ちます。
### `emplace`
```cpp
template<typename ... Ts>
iterator emplace(const_iterator p, Ts&& ... args);
```
`std::vector<std::string>::insert`と同等の効果を持ちます。
### `erase`
```cpp
iterator erase(const_iterator pos);
iterator erase(const_iterator first, const_iterator last);
```
`std::vector<std::string>::insert`と同等の効果を持ちます。
### `swap`
```cpp
void swap(preserve_comments& other);
```
他の`preserve_comments`と内容を交換します。
### `push_back`
```cpp
void push_back(const std::string& v);
void push_back(std::string&& v);
```
`std::vector<std::string>::push_back`と同等の効果を持ちます。
### `pop_back`
```cpp
void pop_back();
```
`std::vector<std::string>::pop_back`と同等の効果を持ちます。
### `emplace_back`
```cpp
template<typename ... Ts>
void emplace_back(Ts&& ... args);
```
`std::vector<std::string>::emplace_back`と同等の効果を持ちます。
### `clear`
```cpp
void clear();
```
`std::vector<std::string>::clear`と同等の効果を持ちます。
### `size`
```cpp
size_type size() const noexcept;
```
`std::vector<std::string>::size`と同等の効果を持ちます。
### `max_size`
```cpp
size_type max_size() const noexcept;
```
`std::vector<std::string>::max_size`と同等の効果を持ちます。
### `capacity`
```cpp
size_type capacity() const noexcept;
```
`std::vector<std::string>::capacity`と同等の効果を持ちます。
### `empty`
```cpp
bool empty() const noexcept;
```
`std::vector<std::string>::empty`と同等の効果を持ちます。
### `reserve`
```cpp
void reserve(size_type n);
```
`std::vector<std::string>::reserve`と同等の効果を持ちます。
### `resize`
```cpp
void resize(size_type n);
void resize(size_type n, const std::string& c);
```
`std::vector<std::string>::resize`と同等の効果を持ちます。
### `shrink_to_fit`
```cpp
void shrink_to_fit();
```
`std::vector<std::string>::shrink_to_fit`と同等の効果を持ちます。
### `operator[]`
```cpp
reference operator[](const size_type n) noexcept;
const_reference operator[](const size_type n) const noexcept;
```
`std::vector<std::string>::operator[]`と同等の効果を持ちます。
### `at`
```cpp
reference at(const size_type n) ;
const_reference at(const size_type n) const;
```
`std::vector<std::string>::at`と同等の効果を持ちます。
### `front`
```cpp
reference front() noexcept;
const_reference front() const noexcept;
```
`std::vector<std::string>::front`と同等の効果を持ちます。
### `back`
```cpp
reference back() noexcept;
const_reference back() const noexcept;
```
`std::vector<std::string>::back`と同等の効果を持ちます。
### `data`
```cpp
pointer data() noexcept;
const_pointer data() const noexcept;
```
`std::vector<std::string>::data`と同等の効果を持ちます。
### `begin/end`
```cpp
iterator begin() noexcept;
iterator end() noexcept;
const_iterator begin() const noexcept;
const_iterator end() const noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
```
`std::vector<std::string>::begin/end`と同等の効果を持ちます。
### `rbegin/rend`
```cpp
reverse_iterator rbegin() noexcept;
reverse_iterator rend() noexcept;
const_reverse_iterator rbegin() const noexcept;
const_reverse_iterator rend() const noexcept;
const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept;
```
`std::vector<std::string>::rbegin/rend`と同等の効果を持ちます。
## 非メンバ関数
### 比較演算子
```cpp
bool operator==(const preserve_comments&, const preserve_comments&);
bool operator!=(const preserve_comments&, const preserve_comments&);
bool operator< (const preserve_comments&, const preserve_comments&);
bool operator<=(const preserve_comments&, const preserve_comments&);
bool operator> (const preserve_comments&, const preserve_comments&);
bool operator>=(const preserve_comments&, const preserve_comments&);
```
`std::vector<std::string>`と同様に比較を行います。
### `swap`
```cpp
void swap(preserve_comments&, preserve_comments&);
void swap(preserve_comments&, std::vector<std::string>&);
void swap(std::vector<std::string>&, preserve_comments&);
```
### ストリーム演算子
```cpp
std::ostream& operator<<(std::ostream&, const preserve_comments&);
```
コメントとして出力します。
先頭が`#`でない場合、`#`が補われます。
# `toml::discard_comments`
`discard_comments`は、コメントを破棄するコンテナです。
`std::vector<std::string>`が持つメンバ関数を全て持っていますが、内容を変更する関数を呼び出しても何も効果はなく、常に空になります。
```cpp
namespace toml
{
class discard_comments;
bool operator==(const discard_comments&, const discard_comments&);
bool operator!=(const discard_comments&, const discard_comments&);
bool operator< (const discard_comments&, const discard_comments&);
bool operator<=(const discard_comments&, const discard_comments&);
bool operator> (const discard_comments&, const discard_comments&);
bool operator>=(const discard_comments&, const discard_comments&);
void swap(discard_comments&, discard_comments&);
std::ostream& operator<<(std::ostream&, const discard_comments&);
} //toml
```
## メンバ型
```cpp
// container_type is not defined
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using value_type = std::string;
using reference = std::string&;
using const_reference = std::string const&;
using pointer = std::string*;
using const_pointer = std::string const*;
using iterator = /* internal type: empty-iterator */
using const_iterator = /* internal type: empty-iterator */
using reverse_iterator = /* internal type: empty-iterator */
using const_reverse_iterator = /* internal type: empty-iterator */
```
### デフォルトコンストラクタ
```cpp
discard_comments() = default;
```
空の`discard_comments`を構築します。
### コピー・ムーブコンストラクタ
```cpp
discard_comments(discard_comments const&) = default;
discard_comments(discard_comments &&) = default;
```
`discard_comments`をコピー・ムーブ構築します。
### コンストラクタ(`std::vector<std::string>`)
```cpp
explicit discard_comments(const std::vector<std::string>& c);
explicit discard_comments(std::vector<std::string>&& c);
```
空の`discard_comments`を構築します。引数の内容は無視されます。
### コンストラクタ(`preserve_comments`)
```cpp
explicit discard_comments(const preserve_comments&);
```
空の`discard_comments`を構築します。引数の内容は無視されます。
### コンストラクタ(`Iterator`)
```cpp
template<typename InputIterator>
discard_comments(InputIterator first, InputIterator last);
```
空の`discard_comments`を構築します。引数の内容は無視されます。
### コンストラクタ(`std::initializer_list`)
```cpp
discard_comments(std::initializer_list<std::string> x);
```
空の`discard_comments`を構築します。引数の内容は無視されます。
### コンストラクタ(サイズ指定)
```cpp
explicit discard_comments(size_type n);
discard_comments(size_type n, const std::string& x);
```
空の`discard_comments`を構築します。引数の内容は無視されます。
### デストラクタ
```cpp
~discard_comments() = default;
```
`discard_comments`を破棄します。
### `operator=(discard_comments)`
```cpp
discard_comments& operator=(discard_comments const&) = default;
discard_comments& operator=(discard_comments &&) = default;
```
`discard_comments`をコピー・ムーブ代入します。
### `operator=(std::vector<std::string>)`
```cpp
discard_comments& operator=(const std::vector<std::string>& c);
discard_comments& operator=(std::vector<std::string>&& c);
```
何もしません。引数の内容は無視されます。
### `assign`
```cpp
template<typename InputIterator>
void assign(InputIterator first, InputIterator last);
void assign(std::initializer_list<std::string> ini);
void assign(size_type n, const std::string& val);
```
何もしません。引数の内容は無視されます。
### `insert`
```cpp
iterator insert(const_iterator p, const std::string& x);
iterator insert(const_iterator p, std::string&& x);
iterator insert(const_iterator p, size_type n, const std::string& x);
template<typename InputIterator>
iterator insert(const_iterator p, InputIterator first, InputIterator last);
iterator insert(const_iterator p, std::initializer_list<std::string> ini);
```
何もしません。引数の内容は無視されます。
### `emplace`
```cpp
template<typename ... Ts>
iterator emplace(const_iterator p, Ts&& ... args);
```
何もしません。引数の内容は無視されます。
### `erase`
```cpp
iterator erase(const_iterator pos);
iterator erase(const_iterator first, const_iterator last);
```
何もしません。引数の内容は無視されます。
### `swap`
```cpp
void swap(discard_comments& other);
```
他の`discard_comments`と内容を交換します。
### `push_back`
```cpp
void push_back(const std::string& v);
void push_back(std::string&& v);
```
何もしません。引数の内容は無視されます。
### `pop_back`
```cpp
void pop_back();
```
何もしません。引数の内容は無視されます。
### `emplace_back`
```cpp
template<typename ... Ts>
void emplace_back(Ts&& ... args);
```
何もしません。引数の内容は無視されます。
### `clear`
```cpp
void clear();
```
何もしません。引数の内容は無視されます。
### `size`
```cpp
size_type size() const noexcept;
```
常に`0`を返します。
### `max_size`
```cpp
size_type max_size() const noexcept;
```
常に`0`を返します。
### `capacity`
```cpp
size_type capacity() const noexcept;
```
常に`0`を返します。
### `empty`
```cpp
bool empty() const noexcept;
```
常に`true`を返します。
### `reserve`
```cpp
void reserve(size_type n);
```
何もしません。引数の内容は無視されます。
### `resize`
```cpp
void resize(size_type n);
void resize(size_type n, const std::string& c);
```
何もしません。引数の内容は無視されます。
### `shrink_to_fit`
```cpp
void shrink_to_fit();
```
何もしません。引数の内容は無視されます。
### `operator[]`
```cpp
reference operator[](const size_type n) noexcept;
const_reference operator[](const size_type n) const noexcept;
```
未定義動作です。
### `at`
```cpp
reference at(const size_type n) ;
const_reference at(const size_type n) const;
```
`std::out_of_range`を送出します。
### `front`
```cpp
reference front() noexcept;
const_reference front() const noexcept;
```
未定義動作です。
### `back`
```cpp
reference back() noexcept;
const_reference back() const noexcept;
```
未定義動作です。
### `data`
```cpp
pointer data() noexcept;
const_pointer data() const noexcept;
```
常に`nullptr`を返します。
### `begin/end`
```cpp
iterator begin() noexcept;
iterator end() noexcept;
const_iterator begin() const noexcept;
const_iterator end() const noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
```
内部で定義された`empty-iterator`を返します。
`empty-iterator`はインクリメントやデクリメントしても同じ値でとどまり、全ての値が同値です。
`empty-iterator`が指す先にアクセスすると常に`std::terminate`が呼び出されます。
### `rbegin/rend`
```cpp
reverse_iterator rbegin() noexcept;
reverse_iterator rend() noexcept;
const_reverse_iterator rbegin() const noexcept;
const_reverse_iterator rend() const noexcept;
const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept;
```
内部で定義された`empty-iterator`を返します。
`empty-iterator`はインクリメントやデクリメントしても同じ値でとどまり、全ての値が同値です。
`empty-iterator`が指す先にアクセスすると常に`std::terminate`が呼び出されます。
## 非メンバ関数
### 比較演算子
```cpp
bool operator==(const discard_comments&, const discard_comments&);
bool operator!=(const discard_comments&, const discard_comments&);
bool operator< (const discard_comments&, const discard_comments&);
bool operator<=(const discard_comments&, const discard_comments&);
bool operator> (const discard_comments&, const discard_comments&);
bool operator>=(const discard_comments&, const discard_comments&);
```
`discard_comments`は全て同じ値です。`==`には常に`true`を、`!=`には常に`false`を返します。
### `swap`
```cpp
void swap(discard_comments&, discard_comments&);
```
二つの`discard_comments`を交換します。
### ストリーム演算子
```cpp
std::ostream& operator<<(std::ostream&, const discard_comments&);
```
何も出力しません。
# 関連項目
- [value.hpp]({{<ref "value.md">}})

View File

@@ -0,0 +1,33 @@
+++
title = "conversion.hpp"
type = "docs"
+++
# conversion.hpp
`toml::get``toml::find`でユーザー定義型をサポートするための変換関数を自動定義するマクロを提供します。
```cpp
TOML11_DEFINE_CONVERSION_NON_INTRUSIVE(NAME, ...)
```
## 例
```cpp
namespace foo
{
struct Foo
{
std::string s;
double d;
int i;
};
} // foo
TOML11_DEFINE_CONVERSION_NON_INTRUSIVE(foo::Foo, s, d, i)
```
# 関連項目
- [from.hpp]({{<ref "from.md">}})
- [into.hpp]({{<ref "into.md">}})

View File

@@ -0,0 +1,779 @@
+++
title = "datetime.hpp"
type = "docs"
+++
# datetime.hpp
TOMLの`datetime`で使用される、日時情報を保存するクラスを定義します。
# `enum class month_t`
月を指定する`enum class`です。
`std::tm`との関係で、`local_date`は1月を`0`としています。
混乱を避けるため、月の名前で指定できるよう`month_t`が用意されています。
```cpp
namespace toml
{
enum class month_t : std::uint8_t
{
Jan = 0,
Feb = 1,
Mar = 2,
Apr = 3,
May = 4,
Jun = 5,
Jul = 6,
Aug = 7,
Sep = 8,
Oct = 9,
Nov = 10,
Dec = 11
};
}
```
# `local_date`
日付を保持する構造体です。
`year`は西暦を、`month``std::tm`との対応のため1月を`0`として、`day`は日付を保持します。
```cpp
namespace toml
{
struct local_date
{
std::int16_t year;
std::uint8_t month;
std::uint8_t day;
local_date() = default;
~local_date() = default;
local_date(local_date const&) = default;
local_date(local_date&&) = default;
local_date& operator=(local_date const&) = default;
local_date& operator=(local_date&&) = default;
local_date(int y, month_t m, int d);
explicit local_date(const std::tm& t);
explicit local_date(const std::chrono::system_clock::time_point& tp);
explicit local_date(const std::time_t t);
operator std::chrono::system_clock::time_point() const;
operator std::time_t() const;
};
bool operator==(const local_date&, const local_date&);
bool operator!=(const local_date&, const local_date&);
bool operator< (const local_date&, const local_date&);
bool operator<=(const local_date&, const local_date&);
bool operator> (const local_date&, const local_date&);
bool operator>=(const local_date&, const local_date&);
std::ostream& operator<<(std::ostream& os, const local_date& date);
std::string to_string(const local_date& date);
}
```
## メンバ変数
### `year`
```cpp
std::int16_t year;
```
西暦です。オフセットはありません。`2024`年は`2024`です。
### `month`
```cpp
std::uint8_t month;
```
月を表します。`std::tm`との対応のため、1月は`0`, 2月は`1`と続きます。
混乱を避けるため、構築の際は`month_t`を使用します。
### `day`
```cpp
std::uint8_t day;
```
日付を表します。1日は`1`です。
## メンバ関数
### コンストラクタ
```cpp
local_date() = default;
```
デフォルト実装を使用します。
### デストラクタ
```cpp
~local_date() = default;
```
デフォルト実装を使用します。
### コピー・ムーブコンストラクタ
```cpp
local_date(local_date const&) = default;
local_date(local_date&&) = default;
```
デフォルト実装を使用します。
### コピー・ムーブ代入演算子
```cpp
local_date& operator=(local_date const&) = default;
local_date& operator=(local_date&&) = default;
```
デフォルト実装を使用します。
### コンストラクタ(`int year, month_t month, int day`)
```cpp
local_date(int y, month_t m, int d);
```
指定した値から`local_date`を構築します。
境界チェックなどは行いません。
### コンストラクタ(`std::tm`)
```cpp
local_date(const std::tm&);
```
指定した値から`local_date`を構築します。
### コンストラクタ(`std::chrono::system_clock::time_point`)
```cpp
local_date(const std::chrono::system_clock::time_point&);
```
指定した値から`local_date`を構築します。
タイムゾーンは実行環境でのものが選択されます。
### コンストラクタ(`std::time_t`)
```cpp
local_date(const std::time_t);
```
指定した値から`local_date`を構築します。
タイムゾーンは実行環境でのものが選択されます。
### `operator std::chrono::system_clock::time_point`
```cpp
operator std::chrono::system_clock::time_point() const;
```
`std::chrono::system_clock::time_point`に変換します。
タイムゾーンは実行環境でのものが選択されます。
時刻は0時00分とします。
### `operator std::time_t`
```cpp
operator std::time_t() const;
```
`std::time_t`に変換します。
タイムゾーンは実行環境でのものが選択されます。
時刻は0時00分とします。
## 非メンバ関数
### 比較演算子
```cpp
bool operator==(const local_date&, const local_date&);
bool operator!=(const local_date&, const local_date&);
bool operator< (const local_date&, const local_date&);
bool operator<=(const local_date&, const local_date&);
bool operator> (const local_date&, const local_date&);
bool operator>=(const local_date&, const local_date&);
```
日付の順序によって比較します。
### ストリーム出力演算子
```cpp
std::ostream& operator<<(std::ostream& os, const local_date& date);
```
TOMLのデフォルトのフォーマットで出力を行います。
### `to_string`
```cpp
std::string to_string(const local_date& date);
```
TOMLのデフォルトのフォーマットで文字列化します。
# `local_time`
```cpp
namespace toml
{
struct local_time
{
std::uint8_t hour; // [0, 23]
std::uint8_t minute; // [0, 59]
std::uint8_t second; // [0, 60]
std::uint16_t millisecond; // [0, 999]
std::uint16_t microsecond; // [0, 999]
std::uint16_t nanosecond; // [0, 999]
local_time(int h, int m, int s, int ms = 0, int us = 0, int ns = 0);
explicit local_time(const std::tm& t);
template<typename Rep, typename Period>
explicit local_time(const std::chrono::duration<Rep, Period>& t);
operator std::chrono::nanoseconds() const;
local_time() = default;
~local_time() = default;
local_time(local_time const&) = default;
local_time(local_time&&) = default;
local_time& operator=(local_time const&) = default;
local_time& operator=(local_time&&) = default;
};
bool operator==(const local_time& lhs, const local_time& rhs);
bool operator!=(const local_time& lhs, const local_time& rhs);
bool operator< (const local_time& lhs, const local_time& rhs);
bool operator<=(const local_time& lhs, const local_time& rhs);
bool operator> (const local_time& lhs, const local_time& rhs);
bool operator>=(const local_time& lhs, const local_time& rhs);
std::ostream& operator<<(std::ostream& os, const local_time& time);
std::string to_string(const local_time& time);
}
```
## メンバ変数
### `hour`
```cpp
std::uint8_t hour;
```
時間を表します。`0`から`23`の値を取ります。
### `minute`
```cpp
std::uint8_t minute; // [0, 59]
```
分を表します。`0`から`59`の値を取ります。
### `second`
```cpp
std::uint8_t second; // [0, 60]
```
秒を表します。`0`から`60`の値を取ります。
### `millisecond`
```cpp
std::uint16_t millisecond; // [0, 999]
```
ミリ秒を表します。`0`から`999`の値を取ります。
### `microsecond`
```cpp
std::uint16_t microsecond; // [0, 999]
```
マイクロ秒を表します。`0`から`999`の値を取ります。
### `nanosecond`
```cpp
std::uint16_t nanosecond; // [0, 999]
```
ナノ秒を表します。`0`から`999`の値を取ります。
## メンバ関数
### デフォルトコンストラクタ
```cpp
local_time() = default;
```
全ての値を`0`で初期化します。
### コンストラクタ(h, m, s, ms = 0, us = 0, ns = 0)
```cpp
local_time(int h, int m, int s, int ms = 0, int us = 0, int ns = 0);
```
指定された時刻を使って構築します。
境界チェックは行われません。
### コンストラクタ(`std::tm`)
```cpp
explicit local_time(const std::tm& t);
```
`std::tm``tm_hour`, `tm_min`, `tm_sec`を使って構築します。
サブセコンドは全て`0`で初期化されます。
### コンストラクタ(`std::chrono::duration`)
```cpp
template<typename Rep, typename Period>
explicit local_time(const std::chrono::duration<Rep, Period>& t);
```
`duration`をその日の0時からの時間として構築します。
### `operator std::chrono::nanoseconds`
```cpp
operator std::chrono::nanoseconds() const;
```
`std::chrono::nanoseconds`へ変換します。
## 非メンバ関数
### 比較演算子
```cpp
bool operator==(const local_time& lhs, const local_time& rhs);
bool operator!=(const local_time& lhs, const local_time& rhs);
bool operator< (const local_time& lhs, const local_time& rhs);
bool operator<=(const local_time& lhs, const local_time& rhs);
bool operator> (const local_time& lhs, const local_time& rhs);
bool operator>=(const local_time& lhs, const local_time& rhs);
```
時刻の値によって比較を行います。
### ストリーム演算子
```cpp
std::ostream& operator<<(std::ostream& os, const local_time& time);
```
TOMLのデフォルトのフォーマットで出力を行います。
### `to_string`
```cpp
std::string to_string(const local_time& time);
```
TOMLのデフォルトのフォーマットで文字列化します。
# `time_offset`
```cpp
namespace toml
{
struct time_offset
{
std::int8_t hour{0}; // [-12, 12]
std::int8_t minute{0}; // [-59, 59]
time_offset(int h, int m);
operator std::chrono::minutes() const;
time_offset() = default;
~time_offset() = default;
time_offset(time_offset const&) = default;
time_offset(time_offset&&) = default;
time_offset& operator=(time_offset const&) = default;
time_offset& operator=(time_offset&&) = default;
};
bool operator==(const time_offset&, const time_offset&);
bool operator!=(const time_offset&, const time_offset&);
bool operator< (const time_offset&, const time_offset&);
bool operator<=(const time_offset&, const time_offset&);
bool operator> (const time_offset&, const time_offset&);
bool operator>=(const time_offset&, const time_offset&);
std::ostream& operator<<(std::ostream& os, const time_offset& offset);
std::string to_string(const time_offset& offset);
}
```
## メンバ変数
### `hour`
```cpp
std::int8_t hour{0}; // [-12, 12]
```
時間のオフセットです。-12から+12の範囲の値を取ります。
### `minute`
```cpp
std::int8_t minute{0}; // [-59, 59]
```
分のオフセットです。-59から+59の範囲の値を取ります。
## メンバ関数
### コンストラクタ
```cpp
time_offset(int h, int m);
```
時間と分を取って構築します。
境界チェックは行いません。
### `operator std::chrono::minutes`
```cpp
operator std::chrono::minutes() const;
```
`std::chrono::minutes`への変換を行います。
## 非メンバ関数
### 比較演算子
```cpp
bool operator==(const time_offset&, const time_offset&);
bool operator!=(const time_offset&, const time_offset&);
bool operator< (const time_offset&, const time_offset&);
bool operator<=(const time_offset&, const time_offset&);
bool operator> (const time_offset&, const time_offset&);
bool operator>=(const time_offset&, const time_offset&);
```
時刻の長さで比較します。
### ストリーム出力演算子
```cpp
std::ostream& operator<<(std::ostream& os, const time_offset&);
```
TOMLのデフォルトのフォーマットで出力を行います。
### `to_string`
```cpp
std::string to_string(const time_offset&);
```
TOMLのデフォルトのフォーマットで文字列化します。
# `local_datetime`
```cpp
namespace toml
{
struct local_datetime
{
local_date date;
local_time time;
local_datetime(local_date d, local_time t);
explicit local_datetime(const std::tm& t);
explicit local_datetime(const std::chrono::system_clock::time_point& tp);
explicit local_datetime(const std::time_t t);
operator std::chrono::system_clock::time_point() const;
operator std::time_t() const;
local_datetime() = default;
~local_datetime() = default;
local_datetime(local_datetime const&) = default;
local_datetime(local_datetime&&) = default;
local_datetime& operator=(local_datetime const&) = default;
local_datetime& operator=(local_datetime&&) = default;
};
bool operator==(const local_datetime&, const local_datetime&);
bool operator!=(const local_datetime&, const local_datetime&);
bool operator< (const local_datetime&, const local_datetime&);
bool operator<=(const local_datetime&, const local_datetime&);
bool operator> (const local_datetime&, const local_datetime&);
bool operator>=(const local_datetime&, const local_datetime&);
std::ostream& operator<<(std::ostream& os, const local_datetime& dt);
std::string to_string(const local_datetime& dt);
}
```
## メンバ変数
### `local_date date`
```cpp
local_date date;
```
日付部分のデータを保持します。
### `local_time time`
```cpp
local_time time;
```
時刻部分のデータを保持します。
## メンバ関数
### デフォルトコンストラクタ
`date`, `time`の双方をデフォルト構築します。
### コンストラクタ(`local_date, local_time`)
指定された`date``time`で構築します。
### コンストラクタ(`std::tm`)
`std::tm`から構築します。
タイムゾーンは実行環境でのものが選択されます。
### コンストラクタ(`std::chrono::system_clock::time_point`)
`std::chrono::system_clock::time_point`から構築します。
タイムゾーンは実行環境でのものが選択されます。
### コンストラクタ(`std::time_t`)
`std::time_t`から構築します。
タイムゾーンは実行環境でのものが選択されます。
### `operator std::chrono::system_clock::time_point`
`std::chrono::system_clock::time_point`へ変換します。
### `operator std::time_t`
`std::time_t`へ変換します。
## 非メンバ関数
### 比較演算子
```cpp
bool operator==(const local_datetime&, const local_datetime&);
bool operator!=(const local_datetime&, const local_datetime&);
bool operator< (const local_datetime&, const local_datetime&);
bool operator<=(const local_datetime&, const local_datetime&);
bool operator> (const local_datetime&, const local_datetime&);
bool operator>=(const local_datetime&, const local_datetime&);
```
日付順で比較します。
### ストリーム出力演算子
```cpp
std::ostream& operator<<(std::ostream& os, const local_datetime&);
```
TOMLのデフォルトのフォーマットで出力を行います。
### `to_string`
```cpp
std::string to_string(const local_datetime&);
```
TOMLのデフォルトのフォーマットで文字列化します。
# `offset_datetime`
```cpp
namespace toml
{
struct offset_datetime
{
local_date date;
local_time time;
time_offset offset;
offset_datetime(local_date d, local_time t, time_offset o);
offset_datetime(const local_datetime& dt, time_offset o);
explicit offset_datetime(const local_datetime& ld);
explicit offset_datetime(const std::chrono::system_clock::time_point& tp);
explicit offset_datetime(const std::time_t& t);
explicit offset_datetime(const std::tm& t);
operator std::chrono::system_clock::time_point() const;
operator std::time_t() const;
offset_datetime() = default;
~offset_datetime() = default;
offset_datetime(offset_datetime const&) = default;
offset_datetime(offset_datetime&&) = default;
offset_datetime& operator=(offset_datetime const&) = default;
offset_datetime& operator=(offset_datetime&&) = default;
};
bool operator==(const offset_datetime&, const offset_datetime&);
bool operator!=(const offset_datetime&, const offset_datetime&);
bool operator< (const offset_datetime&, const offset_datetime&);
bool operator<=(const offset_datetime&, const offset_datetime&);
bool operator> (const offset_datetime&, const offset_datetime&);
bool operator>=(const offset_datetime&, const offset_datetime&);
std::ostream& operator<<(std::ostream& os, const offset_datetime& dt);
std::string to_string(const offset_datetime& dt);
}
```
## メンバ変数
### `date`
```cpp
local_date date;
```
日付部分のデータを保持します。
### `time`
```cpp
local_time time;
```
時刻部分のデータを保持します。
### `offset`
```cpp
time_offset offset;
```
オフセット部分のデータを保持します。
## メンバ関数
### デフォルトコンストラクタ
`date`, `time`, `offset`を全てデフォルト構築します。
### コンストラクタ(`local_date, local_time, time_offset`)
指定された`date`, `time`, `offset`で構築します。
### コンストラクタ(`local_datetime, time_offset`)
`local_datetime``offset`から構築します。
### コンストラクタ(`std::tm`)
`std::tm`から構築します。
タイムゾーンはUTC(00:00)になります。
### コンストラクタ(`std::chrono::system_clock::time_point`)
`std::chrono::system_clock::time_point`から構築します。
タイムゾーンはUTC(00:00)になります。
### コンストラクタ(`std::time_t`)
`std::time_t`から構築します。
タイムゾーンはUTC(00:00)になります。
### `operator std::chrono::system_clock::time_point`
`std::chrono::system_clock::time_point`へ変換します。
タイムゾーンはUTC(00:00)になります。
### `operator std::time_t`
`std::time_t`へ変換します。
タイムゾーンはUTC(00:00)になります。
## 非メンバ関数
### 比較演算子
```cpp
bool operator==(const offset_datetime&, const offset_datetime&);
bool operator!=(const offset_datetime&, const offset_datetime&);
bool operator< (const offset_datetime&, const offset_datetime&);
bool operator<=(const offset_datetime&, const offset_datetime&);
bool operator> (const offset_datetime&, const offset_datetime&);
bool operator>=(const offset_datetime&, const offset_datetime&);
```
日付順で比較します。
同じ日付の場合、タイムゾーン順で比較されます。
### ストリーム出力演算子
```cpp
std::ostream& operator<<(std::ostream& os, const offset_datetime&);
```
TOMLのデフォルトのフォーマットで出力を行います。
### `to_string`
```cpp
std::string to_string(const offset_datetime&);
```
TOMLのデフォルトのフォーマットで文字列化します。

View File

@@ -0,0 +1,151 @@
+++
title = "error_info.hpp"
type = "docs"
+++
# error_info.hpp
`error_info.hpp`では、`error_info`と、それをフォーマットする関数が定義されます。
# `toml::error_info`
```cpp
namespace toml
{
struct error_info
{
error_info(std::string t, source_location l, std::string m, std::string s = "");
error_info(std::string t, std::vector<std::pair<source_location, std::string>> l, std::string s = "");
std::string const& title() const noexcept;
std::string & title() noexcept;
std::vector<std::pair<source_location, std::string>> const& locations() const noexcept;
void add_locations(source_location loc, std::string msg) noexcept;
std::string const& suffix() const noexcept;
std::string & suffix() noexcept;
};
template<typename ... Ts>
error_info make_error_info(
std::string title, source_location loc, std::string msg, Ts&& ... tail);
std::string format_error(const std::string& errkind, const error_info& err);
std::string format_error(const error_info& err);
template<typename ... Ts>
std::string format_error(std::string title,
source_location loc, std::string msg, Ts&& ... tail);
std::ostream& operator<<(std::ostream& os, const error_info& e);
}
```
## メンバ関数
### コンストラクタ(`title, loc, msg, suffix`)
指定されたタイトル、位置情報、メッセージ、suffixから`error_info`を構築します。
`suffix`はデフォルトで空です。
### コンストラクタ(`title, [{loc, msg}, ...], suffix`)
指定されたタイトル、位置情報とメッセージの配列、そして`suffix`から`error_info`を構築します。
`suffix`はデフォルトで空です。
## メンバ関数
### `std::string title()`
エラーメッセージのタイトルです。
### `std::vector<std::pair<source_location, std::string>> locations()`
エラーの発生した位置とそれに関するメッセージです。
複数指定可能です。
### `std::string suffix()`
最後に表示するメッセージです。ヒントや補足を表示します。
## 非メンバ関数
### `make_error_info`
```cpp
template<typename ... Ts>
error_info make_error_info(
std::string title, source_location loc, std::string msg, Ts&& ... tail);
```
新しく`error_info`を構築します。
`source_location`または`basic_value`の後には、それに関する`msg`が続かなければなりません。
[`value.hpp`]({{<ref "docs/reference/value#tomlmake_error_info">}})
では、 `source_location` の代わりに `toml::basic_value` を渡した際のオーバーロードが追加されます。
末尾には`suffix`を渡すことが可能です。
### `format_error`
`error_info` を以下のようにフォーマットします。
```
{title}
--> {locations().at(0).first.file_name()}
|
1 | {locations().at(0).first.line()}
| ^-- {locations().at(0).second}
|
2 | {locations().at(1).first.line()}
| ^-- {locations().at(1).second}
{suffix}
```
二つの `source_location` のファイル名が異なる場合は、ファイル名が再度表示されます。
```cpp
std::string format_error(const std::string& errkind, const error_info& err);
std::string format_error(const error_info& err);
```
`error_info`をフォーマットします。
`errkind`が与えられなかった場合、赤色太字の`[error]``title`の前につけ足されます。
`errkind`が与えられた場合(空文字列の場合も含みます)、それが`[error]`の代わりに表示されます。
```cpp
namespace toml
{
template<typename ... Ts>
std::string format_error(std::string title,
source_location loc, std::string msg, Ts&& ... tail);
} // toml
```
`make_error_info` を使って作成した `error_info``format_error` でフォーマットした文字列を返します。
[`value.hpp`]({{<ref "docs/reference/value#tomlformat_error">}})
では、 `source_location` の代わりに `toml::basic_value` を渡した際のオーバーロードが追加されます。
### ストリーム演算子
```cpp
std::ostream& operator<<(std::ostream& os, const error_info& e);
```
`format_error(e)`を呼び出し、それを出力します。
# 関連項目
- [color.hpp]({{<ref "color.md">}})
- [parser.hpp]({{<ref "parser.md">}})
- [source_location.hpp]({{<ref "source_location.md">}})

View File

@@ -0,0 +1,41 @@
+++
title = "exception.hpp"
type = "docs"
+++
# exception.hpp
# `toml::exception`
toml11で定義される例外型の基底クラスです。
```cpp
namespace toml
{
struct exception : public std::exception
{
public:
virtual ~exception() noexcept override = default;
virtual const char* what() const noexcept override {return "";}
};
} // toml
```
## メンバ関数
### デストラクタ
```cpp
virtual ~exception() noexcept override = default;
```
派生する際に上書きします。
### `what`
```cpp
virtual const char* what() const noexcept override {return "";}
```
エラーメッセージを返します。派生する際に上書きします。

View File

@@ -0,0 +1,251 @@
+++
title = "find.hpp"
type = "docs"
+++
# find.hpp
`toml::value`から値を検索し、同時に(必要な場合)型変換を行う関数です。
{{< hint info >}}
`toml::value` は格納する型を変更でき、`toml::find`はそれらに対応しているので、
厳密には全て `toml::basic_value<TC>` が使われています。ただしこれでは冗長なので、
関数の宣言と特に区別しなければならない場合を除いて、簡単のため説明文では `toml::value` と書きます。
説明文では、テンプレートパラメータ`TC`を変更して型が変更されていれば
`toml::value::integer_type` などの型は追従して変更されると解釈してください。
{{< /hint >}}
# `toml::find`
## 概要
`toml::find`には、取り出したい型をテンプレート引数で、検索したい値のキーを引数で与えます。
```cpp
template<typename T, typename TC, typename ... Keys>
T find(const basic_value<TC>& v, Keys ... keys);
```
サポートされている `T` の種類と変換の挙動に関しては、 `toml::get` と同様です。
`T` が指定されなかった場合、 `toml::value` が返されます。
キーは、 `toml::value::key_type` または `std::size_t` です。
複数個のキーが与えられた場合は、サブテーブルや配列に対して再帰的に検索が行われます。
`toml::value::key_type` が与えられた場合は `toml::table` として、 `std::size_t` が与えられた場合は `toml::array` として解釈されます。
### 再帰的な検索に関しての注意
TOMLには通常の bare key の他に、 `"``'` で囲まれた quoted key というものがあります。
quoted key を使うと、 `"foo.bar" = "baz"` というようなキーを書くことができ、この場合はサブテーブルは構築されず、キーは `foo.bar`となります。
このようなパターンに対応するため、toml11ではキーの中に`.`が含まれていても分割は行わず、そのままの文字列で検索を行います。
以下のTOMLファイルを考えます。
```toml
[foo]
[foo.bar]
baz = "hoge"
["foo.bar"]
baz = "fuga"
```
これに対応する`toml::find`の書き方は以下の通りです。
```cpp
const auto input = toml::parse("input.toml");
const auto baz1 = toml::find<std::string>(input, "foo", "bar", "baz"); // hoge
const auto baz2 = toml::find<std::string>(input, "foo.bar", "baz"); // fuga
```
参考:[toml.io/ja/v1.0.0#キー](https://toml.io/ja/v1.0.0#%E3%82%AD%E3%83%BC)
## `toml::find(value, key)`
`value``toml::table` として `key` を検索したあと、 `toml::get` で変換を行います。
```cpp
template<typename T, typename TC>
/* toml::get<T>(const value&) と同等 */ find(
const basic_value<TC>& v, const typename basic_value<TC>::key_type& ky);
template<typename T, typename TC>
/* toml::get<T>(value&) と同等 */ find(
basic_value<TC>& v, const typename basic_value<TC>::key_type& ky);
template<typename T, typename TC>
/* toml::get<T>(value&&) と同等 */ find(
basic_value<TC>&& v, const typename basic_value<TC>::key_type& ky);
```
`T`が指定されない場合は、変換を行わず`toml::value`を返します。
```cpp
template<typename TC>
basic_value<TC> const& find(
basic_value<TC> const& v, const typename basic_value<TC>::key_type& ky);
template<typename TC>
basic_value<TC>& find(
basic_value<TC>& v, const typename basic_value<TC>::key_type& ky);
template<typename TC>
basic_value<TC> find(
basic_value<TC>&& v, const typename basic_value<TC>::key_type& ky);
```
### 例外
`toml::value``table` を保持していなかった場合、 `toml::type_error` が送出されます。
格納している `table` が指定された要素を持っていなかった場合、 `std::out_of_range` が送出されます。
指定された要素が `T` に変換できない場合 `toml::get` が変換に失敗する場合) 、
`toml::type_error` が送出されます。
## `toml::find(value, index)`
`value``toml::array` として `index` 番目にアクセスし、 `toml::get` で変換を行います。
```cpp
template<typename T, typename TC>
/* toml::get<T>(const value&) と同等 */ find(
const basic_value<TC>& v, const std::size_t index);
template<typename T, typename TC>
/* toml::get<T>(value&) と同等 */ find(
basic_value<TC>& v, const std::size_t index);
template<typename T, typename TC>
/* toml::get<T>(value&&) と同等 */ find(
basic_value<TC>&& v, const std::size_t index);
```
`T`が指定されない場合は、変換を行わず`toml::value`を返します。
```cpp
template<typename TC>
basic_value<TC> const& find(basic_value<TC> const& v, const std::size_t ky);
template<typename TC>
basic_value<TC>& find(basic_value<TC>& v, const std::size_t ky);
template<typename TC>
basic_value<TC> find(basic_value<TC>&& v, const std::size_t ky);
```
### 例外
`toml::value``array` を保持していなかった場合、 `toml::type_error` が送出されます。
格納している `array` が指定された数の要素を持っていなかった場合、`std::out_of_range`が送出されます。
指定された要素が `T` に変換できない場合 `toml::get` が変換に失敗する場合) 、
`toml::type_error` が送出されます。
## `toml::find(value, keys...)`
```cpp
template<typename T, typename TC, typename K1, typename K2, typename ... Ks>
/* toml::get<T>(const value&) と同等 */ find(
const basic_value<TC>& v, const K1& k1, const K2& k2, const Ks& ... ks);
template<typename T, typename TC, typename K1, typename K2, typename ... Ks>
/* toml::get<T>(value&) と同等 */ find(
basic_value<TC>& v, const K1& k1, const K2& k2, const Ks& ... ks);
template<typename T, typename TC, typename K1, typename K2, typename ... Ks>
/* toml::get<T>(value&&) と同等 */ find(
basic_value<TC>&& v, const K1& k1, const K2& k2, const Ks& ... ks);
```
再帰的に`toml::find`が呼び出されます。
失敗する条件とその際に送出される例外は `toml::find` と同じです。
# `toml::find_or(value, key, fallback)`
```cpp
template<typename T, typename TC, typename Key>
T find_or(const basic_value<TC>& v, const Key& key, T&& opt);
```
`find_or` は失敗した際のためのデフォルト値を受け取ることで、失敗時に例外を投げないようにします。
このデフォルト値は受け取る型`T`と同じ型でなければなりません。
よって、 `toml::find<T>` とは違って、 `find_or` では `T` を指定せずとも推論されます。
`find_or<T>`のように `T` を指定することもできますが、その場合は常に新規な値が返されます。
参照を取得したい場合は、 `T` を指定しないでください。
## `T`が`basic_value`である場合
```cpp
template<typename TC, typename K>
basic_value<TC>& find_or(basic_value<TC>& v, const K& key, basic_value<TC>& opt) noexcept
template<typename TC, typename K>
basic_value<TC> const& find_or(const basic_value<TC>& v, const K& key, const basic_value<TC>& opt) noexcept
```
対応する値を検索し、変換せずに返します。変換が必要ないため、参照を返すことができます。
値が見つからなかった場合、デフォルト値を返します。
## `T`が`toml::value::{some_type}`である場合
```cpp
template<typename T, typename TC, typename K>
T& find_or(basic_value<TC>& v, const K& key, T& opt) noexcept
template<typename T, typename TC, typename K>
T const& find_or(const basic_value<TC>& v, const K& key, const T& opt) noexcept
```
対応する値を検索し、変換せずに返します。変換が必要ないため、参照を返すことができます。
値が見つからなかった場合、あるいは異なる型が格納されていた場合、デフォルト値を返します。
## `T`が`const char*`である場合
```cpp
template<typename TC, typename K>
std::string find_or(const basic_value<TC>& v, const K& k, const char* opt)
```
対応する値を検索し、 `std::string` として返します。
失敗時に `const char*` から `std::string` を構築するため、参照を返すことはできません。
## `T`がその他の型である場合
```cpp
template<typename T, typename TC, typename K>
T find_or(const basic_value<TC>& v, const K& key, T opt)
```
対応する値を検索し、 `T` に変換して返します。
変換を行うため、参照を返すことはできません。
## 複数のキーが与えられた場合
```cpp
template<typename Value, typename K1, typename K2, typename K3, typename ... Ks>
auto find_or(Value&& v, const K1& k1, const K2& k2, K3&& k3, Ks&& ... keys) noexcept
-> decltype(find_or(v, k2, std::forward<K3>(k3), std::forward<Ks>(keys)...))
```
キーの列の最後の要素がデフォルト値であると解釈して、再帰的に`find_or`を適用します。
`T` の推論結果が `toml::value` または `toml::value::some_type` になる場合、参照を返すことができます。
`T` を明示的に指定した場合、常に変換を行います。
# 関連項目
- [get.hpp]({{<ref "get.md">}})
- [value.hpp]({{<ref "value.md">}})

View File

@@ -0,0 +1,453 @@
+++
title = "format.hpp"
type = "docs"
+++
# format.hpp
`toml::value`のフォーマット情報を持つ構造体と列挙型を定義します。
# `indent_char`
インデント情報を表す列挙体です。
```cpp
enum class indent_char : std::uint8_t
{
space, // use space
tab, // use tab
none // no indent
};
std::ostream& operator<<(std::ostream& os, const indent_char& c);
std::string to_string(const indent_char);
```
`none`を選んだ場合、super tableでの値によらず、インデントは使用されません。
シリアライズ対象の値のなかに`space``tab`を指定する値が同時に存在していた場合、その動作は未規定で、指定していない方の文字が出現する可能性があります。
# `boolean_format_info`
`boolean`のフォーマット情報です。
```cpp
struct boolean_format_info {};
bool operator==(const boolean_format_info&, const boolean_format_info&) noexcept;
bool operator!=(const boolean_format_info&, const boolean_format_info&) noexcept;
```
`boolean`のフォーマット方法は一通りしかないため、設定できる値を持ちません。
# `integer_format`
```cpp
enum class integer_format : std::uint8_t
{
dec = 0,
bin = 1,
oct = 2,
hex = 3,
};
std::ostream& operator<<(std::ostream& os, const integer_format f);
std::string to_string(const integer_format);
```
`integer`の基数を指定します。
# `integer_format_info`
```cpp
struct integer_format_info
{
integer_format fmt = integer_format::dec;
bool uppercase = true; // use uppercase letters
std::size_t width = 0; // minimal width (may exceed)
std::size_t spacer = 0; // position of `_` (if 0, no spacer)
std::string suffix = ""; // _suffix (library extension)
};
bool operator==(const integer_format_info&, const integer_format_info&) noexcept;
bool operator!=(const integer_format_info&, const integer_format_info&) noexcept;
```
## メンバ変数
### `integer_format fmt`
基数を指定します。
### `bool uppercase`
16進数表記で大文字を使用します。
### `std::size_t width`
最小の幅を指定します。値によってはこの幅を超えることがあります。
フォーマットした値がこの幅よりも小さい場合、`integer_format::dec`の場合は効果はありませんが、それ以外の場合は先頭にリーディング`0`が追加されます。
### `std::size_t spacer`
アンダースコア`_`を追加する幅を指定します。
`3`の場合`1_234_567`のように、`4`の場合`0xdead_beef`のようにフォーマットされます。
`0`の場合、アンダースコアは挿入されません。
不規則な幅を指定することはできません。
### `std::string suffix`
toml11拡張の`spec::ext_num_suffix``true`にしている場合、その`suffix`がここに保存されます。
参考:[spec.hpp]({{<ref "spec.md">}})
# `floating_format`
```cpp
enum class floating_format : std::uint8_t
{
defaultfloat = 0,
fixed = 1, // does not include exponential part
scientific = 2, // always include exponential part
hex = 3 // hexfloat extension
};
std::ostream& operator<<(std::ostream& os, const floating_format f);
std::string to_string(const floating_format);
```
`floating`のフォーマット形式を指定します。
それぞれ、`std::defaultfloat`, `std::fixed`, `std::scientific`, `std::hexfloat`に対応します。
`hexfloat`は、`toml::spec::ext_hex_float``true`の場合のみ使用可能です。
参考:[spec.hpp]({{<ref "spec.md">}})
# `floating_format_info`
```cpp
struct floating_format_info
{
floating_format fmt = floating_format::defaultfloat;
std::size_t prec = 0; // precision (if 0, use the default)
std::string suffix = ""; // 1.0e+2_suffix (library extension)
};
bool operator==(const floating_format_info&, const floating_format_info&) noexcept;
bool operator!=(const floating_format_info&, const floating_format_info&) noexcept;
```
## メンバ変数
### `floating_format fmt`
フォーマット形式を指定します。
### `std::size_t prec`
小数点以下の精度を指定します。
### `std::string suffix`
toml11拡張の`spec::ext_num_suffix``true`にしている場合、その`suffix`がここに保存されます。
参考:[spec.hpp]({{<ref "spec.md">}})
# `string_format`
```cpp
enum class string_format : std::uint8_t
{
basic = 0,
literal = 1,
multiline_basic = 2,
multiline_literal = 3
};
std::ostream& operator<<(std::ostream& os, const string_format f);
std::string to_string(const string_format);
```
文字列のフォーマット形式を指定します。
# `string_format_info`
```cpp
struct string_format_info
{
string_format fmt = string_format::basic;
bool start_with_newline = false;
};
bool operator==(const string_format_info&, const string_format_info&) noexcept;
bool operator!=(const string_format_info&, const string_format_info&) noexcept;
```
## メンバ変数
### `string_format fmt`
文字列のフォーマット情報を指定します。
### `bool start_with_newline`
`multiline_basic`または`multiline_literal`の場合、最初の`"""``'''`の後に改行を入れるかどうかを指定します。
# `datetime_delimiter_kind`
```cpp
enum class datetime_delimiter_kind : std::uint8_t
{
upper_T = 0,
lower_t = 1,
space = 2,
};
std::ostream& operator<<(std::ostream& os, const datetime_delimiter_kind d);
std::string to_string(const datetime_delimiter_kind);
```
`datetime`で日付と時刻の間のデリミタにどの文字を使うかを指定します。
`T`, `t`, ` `が使用可能です。
# `offset_datetime_format_info`
```cpp
struct offset_datetime_format_info
{
datetime_delimiter_kind delimiter = datetime_delimiter_kind::upper_T;
bool has_seconds = true;
std::size_t subsecond_precision = 6; // [us]
};
bool operator==(const offset_datetime_format_info&, const offset_datetime_format_info&) noexcept;
bool operator!=(const offset_datetime_format_info&, const offset_datetime_format_info&) noexcept;
```
## メンバ変数
### `datetime_delimiter_kind delimiter`
使用するデリミタを指定します。
### `bool has_seconds`
秒数を省略するかどうかを指定します。
### `std::size_t subsecond_precision`
秒以下の精度を何桁出力するかを指定します。
# `local_datetime_format_info`
```cpp
struct local_datetime_format_info
{
datetime_delimiter_kind delimiter = datetime_delimiter_kind::upper_T;
bool has_seconds = true;
std::size_t subsecond_precision = 6; // [us]
};
bool operator==(const local_datetime_format_info&, const local_datetime_format_info&) noexcept;
bool operator!=(const local_datetime_format_info&, const local_datetime_format_info&) noexcept;
```
## メンバ変数
### `datetime_delimiter_kind delimiter`
使用するデリミタを指定します。
### `bool has_seconds`
秒数を省略するかどうかを指定します。
### `std::size_t subsecond_precision`
秒以下の精度を何桁出力するかを指定します。
# `local_date_format_info`
```cpp
struct local_date_format_info
{
// nothing, for now
};
bool operator==(const local_date_format_info&, const local_date_format_info&) noexcept;
bool operator!=(const local_date_format_info&, const local_date_format_info&) noexcept;
```
`local_datetime`にはフォーマット指定するパラメータはありません。
# `local_time_format_info`
```cpp
struct local_time_format_info
{
bool has_seconds = true;
std::size_t subsecond_precision = 6; // [us]
};
bool operator==(const local_time_format_info&, const local_time_format_info&) noexcept;
bool operator!=(const local_time_format_info&, const local_time_format_info&) noexcept;
```
## メンバ変数
### `bool has_seconds`
秒数を省略するかどうかを指定します。
### `std::size_t subsecond_precision`
秒以下の精度を何桁出力するかを指定します。
# `array_format`
```cpp
enum class array_format : std::uint8_t
{
default_format = 0,
oneline = 1,
multiline = 2,
array_of_tables = 3 // [[format.in.this.way]]
};
std::ostream& operator<<(std::ostream& os, const array_format f);
std::string to_string(const array_format);
```
- `default_format`
- 適したフォーマットを自動的に選択します。ある程度長い配列は複数行になります。
- `oneline`
- 全ての要素を一行でフォーマットします。
- `multiline`
- 一行ごとに一つの要素を出力します。
- `array_of_tables`
- `[[array.of.tables]]`の形式でフォーマットします。`table`以外の要素を含むことはできません。
# `array_format_info`
```cpp
struct array_format_info
{
array_format fmt = array_format::default_format;
indent_char indent_type = indent_char::space;
std::int32_t body_indent = 4; // indent in case of multiline
std::int32_t closing_indent = 0; // indent of `]`
};
bool operator==(const array_format_info&, const array_format_info&) noexcept;
bool operator!=(const array_format_info&, const array_format_info&) noexcept;
```
## メンバ変数
### `array_format fmt`
フォーマット形式を指定します。
### `indent_char indent_type`
インデントに使用する文字の種類を選択します。
### `std::int32_t body_indent`
`array_format::multiline`の場合、要素の前に出力するインデントの文字数を指定します。
### `std::int32_t closing_indent`
`array_format::multiline`の場合、閉じ括弧`]`の前に出力するインデントの文字数を指定します。
# `table_format`
```cpp
enum class table_format : std::uint8_t
{
multiline = 0, // [foo] \n bar = "baz"
oneline = 1, // foo = {bar = "baz"}
dotted = 2, // foo.bar = "baz"
multiline_oneline = 3, // foo = { \n bar = "baz" \n }
implicit = 4 // [x] defined by [x.y.z]. skip in serializer.
};
std::ostream& operator<<(std::ostream& os, const table_format f);
std::string to_string(const table_format);
```
- `multiline`
- 複数行の通常のテーブルとしてフォーマットします。
- `oneline`
- インラインテーブルとしてフォーマットします。
- `dotted`
- `a.b.c = "d"`の形式でフォーマットします。
- `multiline_oneline`
- 改行を含むインラインテーブルとしてフォーマットします。TOML v1.1.0以降で使用可能です。
- 参考:[spec.hpp]({{<ref "spec.md">}})
- `implicit`
- `[x.y.z.w]`だけが定義されている際の`[x]`, `[x.y]`, `[x.y.z]`のように、暗黙定義としてスキップします。
{{< hint warning >}}
TOMLの文法上、`dotted`はサブテーブルを持つことができます。
```toml
[fruit]
apple.color = "red"
apple.taste.sweet = true
# [fruit.apple] # INVALID
# [fruit.apple.taste] # INVALID
[fruit.apple.texture] # you can add sub-tables
smooth = true
```
toml11は現時点ではこのフォーマットに対応していません。
`dotted`テーブルの下にあるテーブルは全て`dotted`になり、テーブルは強制的にインラインテーブルになります。
{{< /hint >}}
# `table_format_info`
```cpp
struct table_format_info
{
table_format fmt = table_format::multiline;
indent_char indent_type = indent_char::space;
std::int32_t body_indent = 0; // indent of values
std::int32_t name_indent = 0; // indent of [table]
std::int32_t closing_indent = 0; // in case of {inline-table}
};
bool operator==(const table_format_info&, const table_format_info&) noexcept;
bool operator!=(const table_format_info&, const table_format_info&) noexcept;
```
## メンバ変数
### `table_format fmt`
フォーマット方法を指定します。
### `indent_char indent_type`
インデントに使用する文字を指定します。
### `std::int32_t body_indent`
キーの前に出力するインデントの幅を指定します。
スーパーテーブルのインデント幅は加算されません。
### `std::int32_t name_indent`
`[table]`形式のキーのインデントを指定します。
スーパーテーブルのインデント幅は加算されません。
### `std::int32_t closing_indent`
`multiline_oneline`の場合に、閉じ括弧`}`の前のインデント幅を指定します。

View File

@@ -0,0 +1,55 @@
+++
title = "from.hpp"
type = "docs"
+++
# from.hpp
`toml::get``toml::find`で使用する、`toml::value`からの変換を定義する構造体です。
メンバ関数に`from_toml`を追加することによっても同じ機能を追加できますが、メンバ関数を追加できないクラスに対しては`from<T>`を使用してください。
このファイルでは特定の実装は提供しません。使用する際に、この構造体を特殊化してください。
```cpp
namespace toml
{
template<typename T>
struct from;
} // toml
```
## 例
```cpp
namespace extlib
{
struct foo
{
int a;
std::string b;
};
} // extlib
#include <toml11/from.hpp>
namespace toml
{
template<>
struct from<extlib::foo>
{
template<typename TC>
static extlib::foo from_toml(const toml::basic_value<TC>& v)
{
return extlib::foo{toml::find<int>(v, "a"), toml::find<std::string>(v, "b")};
}
};
} // toml
```
# 関連項目
- [conversion.hpp]({{<ref "conversion.md">}})
- [into.hpp]({{<ref "into.md">}})

View File

@@ -0,0 +1,444 @@
+++
title = "get.hpp"
type = "docs"
+++
# get.hpp
`toml::value`から値を取り出し、同時に(必要な場合)型変換を行う関数です。
{{< hint info >}}
`toml::value` は格納する型を変更でき、`toml::get`はそれらに対応しているので、
厳密には全て `toml::basic_value<TC>` が使われています。ただしこれでは冗長なので、
関数の宣言と特に区別しなければならない場合を除いて、簡単のため説明文では `toml::value` と書きます。
説明文では、テンプレートパラメータ`TC`を変更して型が変更されていれば
`toml::value::integer_type` などの型は追従して変更されると解釈してください。
{{< /hint >}}
# `toml::get<T>`
## 概要
基本的に、`toml::get`は以下のような関数として振る舞います。
`T``toml::get<int>(v)`のようにして与えます。
```cpp
template<typename T, typename TC>
T get(const basic_value<TC>& v);
```
ただし、`T`がどのような型であるかによって、`toml::get`は異なる挙動をします。
`T`の型の種類は、
1. 変換が必要ない型
2. 変換する必要がある型
に分けられます。
細かい条件と、特別にサポートしている具体的な型については後述します。
### 変換が必要ない型
変換が必要ないのは、渡された `toml::value` が格納している型です。
例えば、 `toml::value::integer_type``std::int64_t` のエイリアスなので、
`toml::get<std::int64_t>(v)` は変換を必要としません。
この場合、 `toml:get``integer` の値を `toml::value` から取り出し、その参照を返します。
渡された`toml::value`が可変参照(`&`)である場合、返す値も可変参照(`&`)です。
不変参照(`const&`)の場合、返す値も不変参照(`const&`)となります。
可変参照を返した場合、その参照を通して`toml::value`に格納されている値に上書きできます。
### 変換が必要な型
上記の型以外については変換が必要です。
例えば、`toml::value::integer_type``std::int64_t`のエイリアスなので、`toml::get<std::size_t>(toml::value&)`は変換が必要です。
この場合、`toml:get``integer`の値を`toml::value`から取り出し、それをキャストして返します。
toml11は簡単なキャストだけでなく、
`toml::array`からや`std::tuple<int, double, std::string>``std::array<double, 4>`
`toml::table`から`std::map<std::string, int>`などの複雑な型変換をサポートします。
具体的には、続くセクションを参照してください。
### 失敗した場合
期待した型変換を行えない場合があります。例えば、`table`を持っている`toml::value``toml::get<int>(v)`を適用した場合などです。
このような場合は、取り出そうとした型に最も似ている型への変換(今回は`int`なので、`as_integer`)が失敗したとして、`toml::type_error`が送出されます。
ファイルからパースした場合、以下のようなエラーメッセージが出力されます。
```
terminate called after throwing an instance of 'toml::type_error'
what(): toml::value::as_integer(): bad_cast to integer
--> input.toml
|
6 | [fruit]
| ^^^^^^^-- the actual type is table
```
## `T`が`toml::value`と同一のとき
```cpp
template< T, typename TC>
T& get(basic_value<TC>& v);
template<typename T, typename TC>
T const& get(const basic_value<TC>& v);
template<typename T, typename TC>
T get(basic_value<TC>&& v);
```
条件:
- `std::is_same<T, basic_value<TC>>` を満たす
`toml::value`から`toml::value`なので、変換は行われず、そのままの値が返されます。
他の関数の実装を一般化するためだけに存在しています。
失敗しません。
## `T`が`toml::value::{some_type}`のいずれかのとき
```cpp
template<typename T, typename TC>
T& get(basic_value<TC>& v);
template<typename T, typename TC>
T const& get(const basic_value<TC>& v);
template<typename T, typename TC>
T get(basic_value<TC>&& v);
```
条件:
- `T``toml::value`が格納できる型(`toml::value::boolean_type`など)のどれかと同一であること
`toml::value` が格納している型と同じ型、例えば `toml::value::integer_type`
`toml::get<T>``T` として指定されたとき、型変換の必要がないため参照を返すことが可能です。
異なる型が格納されていた場合、`toml::type_error` が送出されます。
## `T`が異なる`TypeConfig`を持つ`basic_value<OtherTC>`のとき
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
条件:
- `T``toml::basic_value<TC>`ではない
- `T``toml::basic_value<OtherTC>`である
異なる型を格納し得る`basic_value`が指定された場合、変換が行われます。
型変換が発生するので、返す値は新規な値であり、参照ではありません。
失敗しません(メモリ枯渇などの場合を除く)。
## `T`が整数型の場合
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
条件:
- `std::is_integral<T>` を満たす
- `std::is_same<T, bool>` ではない
- `toml::value::integer_type` ではない
`toml::value``integer_type` を保持しているとしてその値を取得し、それを `T` に変換して返します。
`toml::value::integer_type` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。
## `T`が浮動小数点数型の場合
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
条件:
- `std::is_floating_point<T>` を満たす
- `toml::value::floating_type` ではない
`toml::value``floating_type`を保持しているとしてその値を取得し、それを`T`に変換して返します。
`toml::value::floating_type` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。
## `T`が`std::string_view`の場合
C++17以降でのみ使用可能です。
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
条件:
- `std::is_same<std::string_view, T>` を満たす
`toml::value``string_type`を保持しているとしてその値を取得し、それから`std::string_view`を構築して返します。
`toml::value::string_type` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。
## `T`が`std::chrono::duration`の場合
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
条件:
- `T``std::chrono::duration<Rep, Period>`である
`toml::value``local_time`を保持しているとしてその値を取得し、それを`std::chrono::duration`に変換して返します。
`toml::value::local_time` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。
## `T`が`std::chrono::system_clock::time_point`の場合
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
条件:
- `std::is_same<T, std::chrono::system_clock::time_point>`を満たす
`toml::value``local_date`, `local_datetime`, `offset_datetime`のどれかを保持しているとしてその値を取得し、それを`std::chrono::system_clock::time_point`に変換して返します。
`local_date`, `local_datetime`, `offset_datetime` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。
## `T`が`array-like`である場合
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
条件:
- `T``T::iterator`を持つ
- `T``T::value_type`を持つ
- `T``T::push_back(x)`を持つ
- `T``toml::value::array_type`ではない
- `T``std::string`ではない
- `T``std::string_view`ではない
- `T``map-like`ではない
- `T``from_toml()`メンバ関数を持たない
- `toml::from<T>`が定義されていない
- `toml::basic_value<TC>`からのコンストラクタが定義されていない
`std::vector<int>``std::deque<std::string>`などが該当します。
`toml::value``array`を保持しているとしてその値を取得し、それを指定されたコンテナに変換して返します。
`toml::value::array_type` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。
## `T`が`std::array`である場合
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
条件:
- `T``std::array<U, N>`である
`toml::value``array`を保持しているとしてその値を取得し、それを指定されたコンテナに変換して返します。
`toml::value::array_type` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。
`toml::value` が持つ `array` が十分な数の要素を持っていなかった場合、`std::out_of_range`が送出されます。
## `T`が`std::forward_list`である場合
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
条件:
- `T``std::forward_list<U>`である
`toml::value``array`を保持しているとしてその値を取得し、それを`std::forward_list`に変換して返します。
`toml::value::array_type` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。
`forward_list``push_back`を持たないので、別に実装されています。
## `T`が`std::pair`である場合
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
条件:
- `T``std::pair<T1, T2>`である
`toml::value``array`を保持しているとしてその値を取得し、それを`std::pair<T1, T2>`に変換して返します。
`first``second` はそれぞれ再帰的に変換されます。
`toml::value::array_type` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。
`toml::value` が持つ `array` の要素数がちょうど2個でなかった場合、`std::out_of_range`が送出されます。
## `T`が`std::tuple`である場合
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
条件:
- `T``std::tuple<T1, T2, ... TN>`である
`toml::value``array`を保持しているとしてその値を取得し、それを`std::tuple<T1, T2, ...TN>`に変換して返します。
各要素はそれぞれ再帰的に変換されます。
`toml::value::array_type` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。
`toml::value` が持つ `array` の要素数がちょうど `std::tuple_size<T>::value` 個でなかった場合、`std::out_of_range`が送出されます。
## `T`が`map-like`である場合
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
条件:
- `T``T::iterator`を持つ
- `T``T::key_type`を持つ
- `T``T::value_type`を持つ
- `T``T::mapped_type`を持つ
- `T``toml::value::table_type`ではない
- `T``from_toml()`メンバ関数を持たない
- `toml::from<T>`が定義されていない
- `toml::basic_value<TC>`からのコンストラクタが定義されていない
`std::map<std::string, int>``std::unordered_map<std::string, float>`などが該当します。
`toml::value``table`を保持しているとしてその値を取得し、それを `T` に変換して返します。
各要素はそれぞれ再帰的に変換されます。
`basic_value::table_type` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。
## `T`が`toml::from<T>`の特殊化を持つユーザー定義型である場合
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
条件:
- `toml::from<T>`が定義されている
`toml::from``T` に対する特殊化が定義されていた場合、それを使用した型変換が行われます。
個別にサポートされる型( `std::array`, `std::pair`, `std::tuple` )と衝突しないようにしてください。
## `T`が`T::from_toml`メンバ関数を持つユーザー定義型である場合
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
条件:
- `toml::from<T>`が定義されていない
- `T``from_toml()`メンバ関数を持つ
`T``from_toml(toml::basic_value<TC>)` メンバ関数が定義されていた場合、それを使用した型変換が行われます。
`toml::from<T>` が定義されていると、そちらが優先されます。
## `T`が`toml::basic_value<TC>`を取るコンストラクタを持つユーザー定義型である場合
```cpp
template<typename T, typename TC>
T get(basic_value<TC>& v);
```
条件:
- `toml::from<T>`が定義されていない
- `T``from_toml()`メンバ関数を持たない
- `T``toml::basic_value<TC>`を取るコンストラクタを持つ
`T``toml::basic_value<TC>` を取るコンストラクタが定義されていた場合、それを使用した型変換が行われます。
`toml::from<T>` または `T::from_toml` が定義されていると、そちらが優先されます。
# `toml::get_or<T>`
`get_or` は失敗した際のためのデフォルト値を受け取ることで、失敗時に例外を投げないようにします。
このデフォルト値は受け取る型`T`と同じ型でなければなりません。
よって、 `toml::get<T>` とは違って、 `get_or` では `T` を指定せずとも推論されます。
## `T`が`basic_value<TC>`である場合
```cpp
template<typename TC>
basic_value<TC> const& get_or(const basic_value<TC>& v, const basic_value<TC>& opt)
template<typename TC>
basic_value<TC> & get_or(basic_value<TC>& v, basic_value<TC>& opt)
template<typename TC>
basic_value<TC> get_or(basic_value<TC>&& v, basic_value<TC>&& opt)
```
変換先は同一の`toml::value`なので、失敗しません。
他の関数の実装を一般化するためだけに存在しています。
## `T`が`basic_value<TC>::{some_type}`である場合
```cpp
template<typename T, typename TC>
T const& get_or(const basic_value<TC>& v, const T& opt) noexcept
template<typename T, typename TC>
T & get_or(basic_value<TC>& v, T& opt) noexcept
template<typename T, typename TC>
T get_or(basic_value<TC>&& v, T&& opt) noexcept
```
`toml::get<T>`と同様の変換を行います。失敗した場合は第二引数が返されます。
## `T`が`const char*`である場合
```cpp
template<typename TC>
typename basic_value<TC>::string_type
get_or(const basic_value<TC>& v,
const typename basic_value<TC>::string_type::value_type* opt);
```
`const char*` が渡された場合、変換先は `std::string` として解釈されます。
## `T`がその他の場合
```cpp
template<typename TC>
typename std::remove_cv<typename std::remove_reference<T>::type>::type
get_or(const basic_value<TC>& v, T&& opt);
```
`toml::get<T>`と同様の変換を行います。失敗した場合は第二引数が返されます。
# 関連項目
- [find.hpp]({{<ref "find.md">}})
- [from.hpp]({{<ref "from.md">}})
- [value.hpp]({{<ref "value.md">}})

View File

@@ -0,0 +1,57 @@
+++
title = "into.hpp"
type = "docs"
+++
# into.hpp
`toml::value`のコンストラクタで使用する、ユーザー定義型からの変換を定義する構造体です。
メンバ関数に`into_toml`を追加することによっても同じ機能を追加できますが、メンバ関数を追加できないクラスに対しては`into<T>`を使用してください。
このファイルでは特定の実装は提供しません。使用する際に、この構造体を特殊化してください。
```cpp
namespace toml
{
template<typename T>
struct into;
} // toml
```
## 例
```cpp
namespace extlib
{
struct foo
{
int a;
std::string b;
};
} // extlib
#include <toml11/into.hpp>
namespace toml
{
template<>
struct into<extlib::foo>
{
template<typename TC>
static toml::basic_value<TC> into_toml(const extlib::foo& f)
{
using value_type = toml::basic_value<TC>;
using table_type = typename value_type::table_type;
return value_type(table_type{{"a", f.a}, {"b", f.b}});
}
};
} // toml
```
# 関連項目
- [conversion.hpp]({{<ref "conversion.md">}})
- [from.hpp]({{<ref "from.md">}})

View File

@@ -0,0 +1,83 @@
+++
title = "literal.hpp"
type = "docs"
+++
# literal.hpp
`literal.hpp`では、`_toml`リテラルが定義されます。
`_toml`リテラルは、文字列リテラルをパースして`toml::value`に変換します。
```cpp
namespace toml
{
inline namespace literals
{
inline namespace toml_literals
{
toml::value operator"" _toml(const char* str, std::size_t len);
toml::value operator"" _toml(const char8_t* str, std::size_t len); // C++20以降
} // toml_literals
} // literals
} // toml
```
## 自由関数
### `operator"" _toml(char)`
```cpp
toml::value operator"" _toml(const char* str, std::size_t len);
```
文字列リテラルをパースして`toml::value`に変換します。
通常のTOMLファイルの場合、`toml::parse`と同等の処理が行われます。
```cpp
const auto v1 = "a = 'foo'"_toml; // v1: {a = 'foo'}
```
改行を含む場合、生文字列リテラルが便利です。
```cpp
const auto v1 = R"(
a = 42
b = "foo"
)"_toml;
```
値が単体で書かれていた場合、その値になります。
```cpp
const auto v2 = "'foo'"_toml; // v2: 'foo'
```
TOMLは数値のみからなるキーを許可しています。
`[1]`のように、テーブル定義と配列の区別がつかない場合、テーブル定義が優先されます。
配列として解釈させるには、trailing commaを使用してください。
```cpp
const auto v3 = "[1]"_toml; // v3: {1 = {}}
const auto v4 = "[1,]"_toml; // v4: [1,]
```
### `operator"" _toml(char8_t)`
`char8_t`が利用可能な場合に定義されます。引数の型のほかに違いはありません。
# 例
```cpp
#include <toml.hpp>
int main()
{
using namespace toml::literals::toml_literals;
const auto v = "a = \"foo\""_toml;
assert(v.at("a").as_string() == "foo");
return 0;
}
```

View File

@@ -0,0 +1,370 @@
+++
title = "ordered_map.hpp"
type = "docs"
+++
# ordered_map.hpp
ファイル中の値の順番を維持するために使用する`toml::ordered_map`を定義します。
# `class ordered_map`
```cpp
namespace toml
{
template<typename Key, typename Val, typename Cmp = std::equal_to<Key>,
typename Allocator = std::allocator<std::pair<Key, Val>>>
class ordered_map;
}
```
`ordered_map`は、値を追加した順序を保ったまま値を保持し、その順でイテレートできる `map` 型です。
線形コンテナなので、検索には要素数に対して `O(n)` の時間がかかります。
検索を行う機会が少なく、値の順序を守る必要がある場合に使用してください。
## 非メンバ型
```cpp
namespace toml
{
struct ordered_type_config;
using ordered_value = basic_value<ordered_type_config>;
using ordered_table = typename ordered_value::table_type;
using ordered_array = typename ordered_value::array_type;
}
```
`toml::type_config``toml::value` の代わりに使用します。
{{< hint info >}}
`toml::parse` はデフォルトで `type_config` を使用するので、パースする際に
```cpp
const auto input = toml::parse<toml::ordered_type_config>("input.toml");
```
としてください。
{{< /hint >}}
## メンバ型
```cpp
using key_type = Key;
using mapped_type = Val;
using value_type = std::pair<Key, Val>;
using key_compare = Cmp;
using allocator_type = Allocator;
using container_type = std::vector<value_type, Allocator>;
using reference = typename container_type::reference;
using pointer = typename container_type::pointer;
using const_reference = typename container_type::const_reference;
using const_pointer = typename container_type::const_pointer;
using iterator = typename container_type::iterator;
using const_iterator = typename container_type::const_iterator;
using size_type = typename container_type::size_type;
using difference_type = typename container_type::difference_type;
```
## メンバ関数
### コンストラクタ
```cpp
ordered_map() = default;
```
空の `ordered_map` を構築します。
### コンストラクタ(コンパレータ、アロケータ)
```cpp
explicit ordered_map(const Cmp& cmp, const Allocator& alloc = Allocator());
explicit ordered_map(const Allocator& alloc);
```
キーの比較に使用するコンパレータや、コンテナのメモリ確保に使用するアロケータを指定して構築します。
### コピー・ムーブコンストラクタ
```cpp
ordered_map(const ordered_map&) = default;
ordered_map(ordered_map&&) = default;
ordered_map(const ordered_map& other, const Allocator& alloc);
ordered_map(ordered_map&& other, const Allocator& alloc);
```
別の `ordered_map` の内容をコピー・ムーブして構築します。
コンテナのメモリ確保に使用するアロケータを指定することも可能です。
### コンストラクタ(`Iterator`
```cpp
template<typename InputIterator>
ordered_map(InputIterator first, InputIterator last, const Cmp& cmp = Cmp(), const Allocator& alloc = Allocator());
template<typename InputIterator>
ordered_map(InputIterator first, InputIterator last, const Allocator& alloc = Allocator());
```
イテレータ範囲を受け取って構築します。
順序は、イテレータの順序に従います。
### コンストラクタ(`std::initializer_list`
```cpp
ordered_map(std::initializer_list<value_type> v, const Cmp& cmp = Cmp(), const Allocator& alloc = Allocator());
ordered_map(std::initializer_list<value_type> v, const Allocator& alloc);
```
`ordered_map{...}`の形式で初期化します。
### コピー・ムーブ代入演算子
```cpp
ordered_map& operator=(const ordered_map&) = default;
ordered_map& operator=(ordered_map&&) = default;
```
別の `ordered_map` の内容をコピー・ムーブ代入します。
### 代入演算子(`std::initializer_list`
```cpp
ordered_map& operator=(std::initializer_list<value_type> v);
```
`std::initializer_list` の内容を代入します。
### デストラクタ
```cpp
~ordered_map() = default;
```
`ordered_map` を破棄します。
### `begin()`, `end()`
```cpp
iterator begin() noexcept;
iterator end() noexcept;
const_iterator begin() const noexcept;
const_iterator end() const noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
```
コンテナの内容を順序通りにイテレートします。
### `empty()`
```cpp
bool empty() const noexcept;
```
`ordered_map` が空の場合 `true` を、そうでない場合 `false` を返します。
### `size()`
```cpp
std::size_t size() const noexcept;
```
`ordered_map` の要素数を返します。
### `max_size()`
```cpp
std::size_t max_size() const noexcept;
```
`ordered_map` が持つことのできる最大の要素数を返します。
### `clear()`
```cpp
void clear();
```
内容を消去します。
### `push_back(kv)`
```cpp
void push_back(const value_type&);
void push_back(value_type&&);
```
キーと値のペアを末尾に追加します。
### `emplace_back(k, v)`
```cpp
void emplace_back(key_type, mapped_type);
```
キーと値のペアを末尾に追加します。
### `pop_back()`
```cpp
void pop_back();
```
末尾の値を削除します。
### `insert(kv)`
```cpp
void insert(value_type);
```
キーと値のペアを末尾に追加します。
### `emplace(k, v)`
```cpp
void emplace(key_type, mapped_type);
```
キーと値のペアを末尾に追加します。
### `count(k)`
```cpp
std::size_t count(const key_type&) const noexcept;
```
キーに対応する値の数を返します。
同じキーに複数の値を代入することはできないので、値が存在する場合は `1`, そうでない場合は `0` を返します。
### `contains(k)`
```cpp
bool contains(const key_type&) const noexcept;
```
キーに対応する値が存在するなら `true` を、そうでないなら `false` を返します。
### `find(k)`
```cpp
iterator find(const key_type& key) noexcept;
const_iterator find(const key_type& key) const noexcept;
```
キーに対応する値を検索し、それを指すイテレータを返します。
存在しなかった場合、`end()`を返します。
### `at(k)`
```cpp
mapped_type& at(const key_type& k);
mapped_type const& at(const key_type& k) const;
```
キーに対応する値を検索して返します。
存在しなかった場合、`std::out_of_range`を送出します。
### `operator[](k)`
```cpp
mapped_type& operator[](const key_type& k);
mapped_type const& operator[](const key_type& k) const;
```
キーに対応する値を検索して返します。
存在しなかった場合、新規な値を構築して返します。
`ordered_map``const` の場合は新規な値を構築できないので、 `std::out_of_range` を送出します。
### `erase(...)`
```cpp
iterator erase(iterator pos);
iterator erase(const_iterator pos);
iterator erase(const_iterator first, const_iterator last);
size_type erase(const key_type& key);
```
イテレータの指す位置の値、あるいはキーに該当する値を削除します。
### `key_comp()`
```cpp
key_compare key_comp() const;
```
比較に使用するコンパレータを返します。
## 使用上の注意
### キーの書き換え
{{< hint warning >}}
`ordered_map``value_type``std::pair<Key, Val>` を使用しているので、イテレータを介してキーを書き換えることが可能になってしまっています。
この方法でキーを書き換えることは推奨されません。
キーを書き換えて既存のキーと衝突した場合、衝突したうちの片方が検索できなくなります。
`operator[]``push_back`, `insert` による書き込みの場合は、既存のキーとの衝突が検出されます。
{{< /hint >}}
### 保たれる順序の詳細
{{< hint warning >}}
`ordered_map` はキーの順序を保ちますが、ここで保たれる順序は同じテーブルで定義されたキーの順序のみです。
よって、テーブルをまたいだ順序は保たれないことに注意してください。
例えば、以下のファイルの順序は保たれます。
```cpp
apple.type = "fruit"
apple.skin = "thin"
apple.color = "red"
orange.type = "fruit"
orange.skin = "thick"
orange.color = "orange"
```
対して以下のファイルの順序は保たれません。
```cpp
apple.type = "fruit"
orange.type = "fruit"
apple.skin = "thin"
orange.skin = "thick"
apple.color = "red"
orange.color = "orange"
```
`ordered_map` が保つ順序は、rootテーブルに定義された `apple``orange` の順序と、
`apple` 内で定義された `type`, `skin`, `color` の順序、
また `orange` 内で定義された `type`, `skin`, `color` の順序のみです。
{{< /hint >}}
## 関連項目
- [parser.hpp]({{<ref "parser.md">}})
- [types.hpp]({{<ref "types.md">}})
- [value.hpp]({{<ref "value.md">}})

View File

@@ -0,0 +1,391 @@
+++
title = "parser.hpp"
type = "docs"
+++
# parser.hpp
ファイルまたは文字列をパースする関数と、それが用いる例外を定義します。
`parse`は失敗した場合に例外を送出しますが、`try_parse`はエラー情報を返します。
# `parse`
与えられたファイルの内容をパースし、`toml::basic_value`を返します。
失敗した場合は`toml::syntax_error`が送出されます。
`basic_value`の持つ型情報は`template`で、TOML言語のバージョンは`toml::spec`で指定します。
### `parse(std::string filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
basic_value<TC>
parse(std::string fname,
spec s = spec::default_version());
}
```
ファイル名を受け取って、その内容をパースします。
ファイルの読み込みに失敗した場合、`file_io_error`が送出されます。
パースに失敗した場合、`syntax_error`が送出されます。
### `parse(const char (&)[N] filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config, std::size_t N>
basic_value<TC>
parse(const char (&fname)[N],
spec s = spec::default_version());
}
```
文字列リテラルを受け取って、そのファイルの内容をパースします。
ファイルの読み込みに失敗した場合、`file_io_error`が送出されます。
パースに失敗した場合、`syntax_error`が送出されます。
### `parse(std::filesystem::path, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
basic_value<TC>
parse(const std::filesystem::path& fpath,
spec s = spec::default_version());
}
```
`<filesystem>`が利用可能な場合のみ定義されます。
ファイルパスを受け取って、そのファイルの内容をパースします。
ファイルの読み込みに失敗した場合、`file_io_error`が送出されます。
パースに失敗した場合、`syntax_error`が送出されます。
### `parse(std::istream&, std::string filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
basic_value<TC>
parse(std::istream& is,
std::string fname = "unknown file",
spec s = spec::default_version());
}
```
`std::istream&`を受け取ってその内容をパースします。
標準ライブラリが改行文字を自動変換することによるファイルサイズと文字数との不整合を避けるため、
`std::ios::binary`を使ってバイナリモードで開いてください。
ファイル名の情報は第三引数で受け取ります。ファイル名が渡されなかった場合、`"unknown file"`になります。
### `parse(FILE*, std::string filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
result<basic_value<TC>, std::vector<error_info>>
parse(FILE* fp,
std::string filename,
spec s = spec::default_version());
}
```
`FILE*`が指すファイルを読み込んでパースします。
標準ライブラリが改行文字を自動変換することによるファイルサイズと文字数との不整合を避けるため、
`fopen`には`"rb"`などを渡してバイナリモードで開いてください。
ファイルの読み込みに失敗した場合、`errno`が含まれた`file_io_error`が送出されます。
パースに失敗した場合、`syntax_error`が送出されます。
### `parse(std::vector<unsigned char>, std::string filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
basic_value<TC>
parse(std::vector<unsigned char> content,
std::string filename,
spec s = spec::default_version());
}
```
バイト列をTOMLファイルとしてパースします。
パースに失敗した場合、`syntax_error`が送出されます。
# `parse_str`
### `parse_str(std::string, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
basic_value<TC>
parse_str(std::string content,
spec s = spec::default_version(),
cxx::source_location loc = cxx::source_location::current());
}
```
文字列をTOMLファイルとしてパースします。
失敗した場合は`toml::syntax_error`が送出されます。
`basic_value`の持つ型情報は`template`で、TOML言語のバージョンは`toml::spec`で指定します。
第三引数の`cxx::source_location`を手動で設定する必要は通常ありません。
`std::source_location`, `std::experimental::source_location`, `__builtin_FILE`のいずれかが利用可能な場合、
`parse_str`が呼ばれた地点の情報が位置情報として保存されます。
# `try_parse`
与えられたファイルの内容をパースし、成功した場合は`toml::basic_value`を、失敗した場合は`std::vector<toml::error_info>`を返します。
`basic_value`の持つ型情報は`template`で、TOML言語のバージョンは`toml::spec`で指定します。
{{< hint warning >}}
`try_parse``parse`と異なり`syntax_error`などのtoml11で定義された例外は投げませんが、
標準ライブラリから送出される例外はそのまま送出されることに注意してください。
例えば、`std::ifstream`の内部で起きたエラーや、`std::vector`でのメモリ枯渇などは例外を送出します。
{{< /hint >}}
### `try_parse(std::string filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
result<basic_value<TC>, std::vector<error_info>>
try_parse(std::string fname,
spec s = spec::default_version());
}
```
ファイル名を受け取って、その内容をパースします。
パースに失敗した場合、エラー型である`std::vector<error_info>`を持つ`result`が返されます。
成功した場合、`basic_value`を持つ`result`が返されます。
### `try_parse(const char (&)[N] filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config, std::size_t N>
result<basic_value<TC>, std::vector<error_info>>
try_parse(const char (&fname)[N],
spec s = spec::default_version());
}
```
文字列リテラルをファイル名として受け取って、その内容をパースします。
パースに失敗した場合、エラー型である`std::vector<error_info>`を持つ`result`が返されます。
成功した場合、`basic_value`を持つ`result`が返されます。
### `try_parse(std::filesystem::path, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
result<basic_value<TC>, std::vector<error_info>>
try_parse(const std::filesystem::path& fpath,
spec s = spec::default_version());
}
```
ファイルパスを受け取って、その内容をパースします。
パースに失敗した場合、エラー型である`std::vector<error_info>`を持つ`result`が返されます。
成功した場合、`basic_value`を持つ`result`が返されます。
### `try_parse(std::istream&, std::string filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
result<basic_value<TC>, std::vector<error_info>>
try_parse(std::istream& is,
std::string fname = "unknown file",
spec s = spec::default_version());
}
```
`std::istream&`を受け取ってその内容をパースします。
標準ライブラリが改行文字を自動変換することによるファイルサイズと文字数との不整合を避けるため、
`std::ios::binary`を使ってバイナリモードで開いてください。
ファイル名の情報は第二引数で受け取ります。ファイル名が渡されなかった場合、`"unknown file"`になります。
パースに失敗した場合、エラー型である`std::vector<error_info>`を持つ`result`が返されます。
成功した場合、`basic_value`を持つ`result`が返されます。
### `try_parse(FILE*, std::string filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
result<basic_value<TC>, std::vector<error_info>>
try_parse(FILE* fp,
std::string filename,
spec s = spec::default_version());
}
```
`FILE*`を受け取って、そのファイルの内容をパースします。
標準ライブラリが改行文字を自動変換することによるファイルサイズと文字数との不整合を避けるため、
`fopen`には`"rb"`などを渡してバイナリモードで開いてください。
パースに失敗した場合、エラー型である`std::vector<error_info>`を持つ`result`が返されます。
成功した場合、`basic_value`を持つ`result`が返されます。
### `try_parse(std::vector<unsigned char>, std::string filename, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
result<basic_value<TC>, std::vector<error_info>>
try_parse(std::vector<unsigned char> content,
std::string filename,
spec s = spec::default_version());
}
```
バイト列を受け取って、その内容をTOMLファイルとしてパースします。
パースに失敗した場合、エラー型である`std::vector<error_info>`を持つ`result`が返されます。
成功した場合、`basic_value`を持つ`result`が返されます。
# `try_parse_str`
### `try_parse_str(std::string, toml::spec)`
```cpp
namespace toml
{
template<typename TC = type_config>
result<basic_value<TC>, std::vector<error_info>>
try_parse_str(std::string content,
spec s = spec::default_version(),
cxx::source_location loc = cxx::source_location::current());
}
```
文字列をTOMLファイルとしてパースし、成功した場合は`toml::basic_value`を、失敗した場合は`std::vector<toml::error_info>`を返します。
`parse_str`と異なり、`syntax_error`を送出せず、エラー情報を`result`の失敗型として返します。
`std::source_location`, `std::experimental::source_location`, `__builtin_FILE`のどれかが利用可能な場合、それを位置情報に記録します。
第三引数の`cxx::source_location`を手動で設定する必要は通常ありません。
`std::source_location`, `std::experimental::source_location`, `__builtin_FILE`のいずれかが利用可能な場合、
`parse_str`が呼ばれた地点の情報が位置情報として保存されます。
{{< hint warning >}}
`try_parse``parse`と異なり`syntax_error`などのtoml11で定義された例外は投げませんが、
標準ライブラリから送出される例外はそのまま送出されることに注意してください。
例えば、`std::ifstream`の内部で起きたエラーや、`std::vector`でのメモリ枯渇などは例外を送出します。
{{< /hint >}}
# `syntax_error`
```cpp
namespace toml
{
struct syntax_error final : public ::toml::exception
{
public:
syntax_error(std::string what_arg, std::vector<error_info> err);
~syntax_error() noexcept override = default;
const char* what() const noexcept override;
std::vector<error_info> const& errors() const noexcept
};
}
```
TOML言語の文法エラーが発見された場合に送出される例外です。
`parse`からは送出されますが、`try_parse`からは送出されません。
# `file_io_error`
```cpp
namespace toml
{
struct file_io_error final : public ::toml::exception
{
public:
file_io_error(const std::string& msg, const std::string& fname);
file_io_error(int errnum, const std::string& msg, const std::string& fname);
~file_io_error() noexcept override = default;
const char* what() const noexcept override;
bool has_errno() const noexcept;
int get_errno() const noexcept;
};
}
```
ファイルの内容を読むのに失敗した場合に送出される例外です。
`FILE*`を使ってファイルを読み込んだ場合は`errno`が設定されます。
### `has_errno`
`std::ifstream`が失敗した場合は`errno`は設定されません。
このとき、`has_errno``false`になります。
### `get_errno`
特に`FILE*`を渡していた場合に、`errno`の値を取得します。
`has_errno``false`の場合は`0`となります。
# 関連項目
- [error_info.hpp]({{<ref "error_info.md">}})
- [result.hpp]({{<ref "result.md">}})
- [spec.hpp]({{<ref "spec.md">}})
- [value.hpp]({{<ref "value.md">}})

View File

@@ -0,0 +1,529 @@
+++
title = "result.hpp"
type = "docs"
+++
# result.hpp
`result.hpp`は、成功値か失敗値かのどちらかを持つ`result`型を定義します。
これは、例外を投げない`toml::try_parse`の返り値として使用されます。
# success
成功値を持つ型です。
```cpp
namespace toml
{
template<typename T>
struct success
{
using value_type = T;
explicit success(value_type v);
~success() = default;
success(const success&) = default;
success(success&&) = default;
success& operator=(const success&) = default;
success& operator=(success&&) = default;
template<typename U>
explicit success(U&& v);
template<typename U>
explicit success(success<U> v);
value_type& get() noexcept;
value_type const& get() const noexcept;
};
template<typename T>
success<typename std::decay<T>::type> ok(T&& v);
template<std::size_t N>
success<std::string> ok(const char (&literal)[N])
}
```
## メンバ型
```cpp
using value_type = T;
```
成功値の型です。
## メンバ関数
### コンストラクタ
```cpp
explicit success(value_type v);
```
`value_type`を受け取って構築します。
```cpp
template<typename U>
explicit success(U&& v);
```
`value_type`に変換可能な他の型を受け取って構築します。
```cpp
template<typename U>
explicit success(success<U> v);
```
`value_type`に変換可能な他の型を持つ`success`型を受け取って構築します。
### `get()`
```cpp
value_type& get() noexcept;
value_type const& get() const noexcept;
```
値にアクセスします。
## 非メンバ関数
### `ok(T)`
```cpp
template<typename T>
success<typename std::decay<T>::type> ok(T&& v);
template<std::size_t N>
success<std::string> ok(const char (&literal)[N])
```
成功値から`success`型を構築して返します。
文字列リテラルを与えた場合は、`std::string`にして返します。
# `success<reference_wrapper<T>>`
`success`の特殊化。成功値が参照であるときに使用されます。
```cpp
namespace toml
{
template<typename T>
struct success<std::reference_wrapper<T>>
{
using value_type = T;
explicit success(std::reference_wrapper<value_type> v) noexcept;
value_type& get() noexcept;
value_type const& get() const noexcept;
};
}
```
## メンバ型
```cpp
using value_type = T;
```
成功値の型です。参照ではなく、`std::reference_wrapper<T>``T`です。
### `get()`
```cpp
value_type& get() noexcept;
value_type const& get() const noexcept;
```
値にアクセスします。
# failure
失敗値を持つ型です。
```cpp
namespace toml
{
template<typename T>
struct failure
{
using value_type = T;
explicit failure(value_type v);
~failure() = default;
failure(const failure&) = default;
failure(failure&&) = default;
failure& operator=(const failure&) = default;
failure& operator=(failure&&) = default;
template<typename U>
explicit failure(U&& v);
template<typename U>
explicit failure(failure<U> v);
value_type& get() noexcept;
value_type const& get() const noexcept;
};
template<typename T>
failure<typename std::decay<T>::type> err(T&& v);
template<std::size_t N>
failure<std::string> err(const char (&literal)[N]);
}
```
## メンバ型
```cpp
using value_type = T;
```
失敗値の型です。
## メンバ関数
### コンストラクタ
```cpp
explicit failure(value_type v);
```
`value_type`を受け取って構築します。
```cpp
template<typename U>
explicit failure(U&& v);
```
`value_type`に変換可能な他の型を受け取って構築します。
```cpp
template<typename U>
explicit failure(failure<U> v);
```
`value_type`に変換可能な他の型を持つ`failure`型を受け取って構築します。
### `get()`
```cpp
value_type& get() noexcept;
value_type const& get() const noexcept;
```
値にアクセスします。
## 非メンバ関数
### `err(T)`
```cpp
template<typename T>
failure<typename std::decay<T>::type> err(T&& v);
template<std::size_t N>
failure<std::string> err(const char (&literal)[N]);
```
失敗値から`failure`型を構築して返します。
文字列リテラルを与えた場合は、`std::string`にして返します。
# `failure<reference_wrapper<T>>`
`failure`の特殊化。失敗値が参照であるときに使用されます。
```cpp
namespace toml
{
template<typename T>
struct failure<std::reference_wrapper<T>>
{
using value_type = T;
explicit failure(std::reference_wrapper<value_type> v) noexcept;
value_type& get() noexcept {return value.get();}
value_type const& get() const noexcept {return value.get();}
};
}
```
## メンバ型
```cpp
using value_type = T;
```
失敗値の型です。参照ではなく、`std::reference_wrapper<T>``T`です。
### `get()`
```cpp
value_type& get() noexcept
value_type const& get() const noexcept
```
値にアクセスします。
# result
成功値か失敗値かのどちらかを持つ型です。
```cpp
namespace toml
{
template<typename T, typename E>
struct result
{
using success_type = success<T>;
using failure_type = failure<E>;
using value_type = typename success_type::value_type;
using error_type = typename failure_type::value_type;
result(success_type s);
result(failure_type f);
template<typename U>
result(success<U> s);
template<typename U>
result(failure<U> f);
result& operator=(success_type s);
result& operator=(failure_type f);
template<typename U>
result& operator=(success<U> s);
template<typename U>
result& operator=(failure<U> f);
~result() noexcept;
result(const result& other);
result(result&& other);
result& operator=(const result& other);
result& operator=(result&& other);
template<typename U, typename F>
result(result<U, F> other);
template<typename U, typename F>
result& operator=(result<U, F> other);
bool is_ok() const noexcept;
bool is_err() const noexcept;
explicit operator bool() const noexcept;
value_type& unwrap(cxx::source_location loc = cxx::source_location::current());
value_type const& unwrap(cxx::source_location loc = cxx::source_location::current()) const;
value_type& unwrap_or(value_type& opt) noexcept;
value_type const& unwrap_or(value_type const& opt) const noexcept;
error_type& unwrap_err(cxx::source_location loc = cxx::source_location::current());
error_type const& unwrap_err(cxx::source_location loc = cxx::source_location::current()) const;
value_type& as_ok() noexcept;
value_type const& as_ok() const noexcept;
error_type& as_err() noexcept;
error_type const& as_err() const noexcept;
};
}
```
## メンバ型
### `success_type`
`success<T>`です。
### `failure_type`
`failure<E>`です。
### `value_type`
成功型`T`です。`success_type::value_type`のエイリアスです。
成功型`T`として`std::reference_wrapper<U>`が渡された場合、その引数型の`U`になります。
### `error_type`
失敗型`E`です。`failure_type::value_type`のエイリアスです。
失敗型`E`として`std::reference_wrapper<F>`が渡された場合、その引数型の`F`になります。
## メンバ関数
### コンストラクタ
```cpp
result() = delete;
```
`result`型はデフォルトでは構築できません。
成功型か失敗型を与える必要があります。
```cpp
result(success_type s);
result(failure_type f);
```
成功型、失敗型を受け取って構築します。
```cpp
template<typename U>
result(success<U> s);
template<typename U>
result(failure<U> f);
```
`value_type``error_type`に変換可能な成功型、失敗型を受け取って構築します。
```cpp
template<typename U, typename F>
result(result<U, F> other);
template<typename U, typename F>
result& operator=(result<U, F> other);
```
変換可能な成功型、失敗型を持つ`result`から構築します。
### コピー・ムーブコンストラクタ
```cpp
result(const result& other);
result(result&& other);
```
コピー・ムーブ構築可能です。
### `operator=`
```cpp
result& operator=(const result& other);
result& operator=(result&& other);
```
コピー・ムーブ代入可能です。
```cpp
template<typename U>
result& operator=(success<U> s);
template<typename U>
result& operator=(failure<U> f);
```
変換可能な型を持つ成功型、失敗型は代入可能です。
### `is_ok()`
```cpp
bool is_ok() const noexcept;
```
成功値を持っている場合`true`を、そうでない場合`false`を返します。
### `is_err()`
```cpp
bool is_err() const noexcept;
```
失敗値を持っている場合`true`を、そうでない場合`false`を返します。
### `operator bool()`
```cpp
explicit operator bool() const noexcept;
```
成功値を持っている場合`true`を、そうでない場合`false`を返します。
### `unwrap()`
```cpp
value_type& unwrap(cxx::source_location loc = cxx::source_location::current());
value_type const& unwrap(cxx::source_location loc = cxx::source_location::current()) const;
```
成功値を取り出します。
成功値を持っていない場合、`toml::bad_result_access`が送出されます。
`std::source_location`または`std::experimental::source_location`が利用可能か、
あるいはコンパイラ拡張によって同等の情報が利用可能な場合、`what()`文字列に
`unwrap()`が発生したソースコードのファイル名と行数が表示されます。
利用可能でない場合、位置情報は表示されません。
### `unwrap_or()`
```cpp
value_type& unwrap_or(value_type& opt) noexcept;
value_type const& unwrap_or(value_type const& opt) const noexcept;
```
成功値を持っていた場合それを、持っていなかった場合は引数で与えられた値を返します。
### `unwrap_err()`
```cpp
error_type& unwrap_err(cxx::source_location loc = cxx::source_location::current());
error_type const& unwrap_err(cxx::source_location loc = cxx::source_location::current()) const;
```
失敗値を取り出します。
失敗値を持っていない場合、`toml::bad_result_access`が送出されます。
`std::source_location`または`std::experimental::source_location`が利用可能か、
あるいはコンパイラ拡張によって同等の情報が利用可能な場合、`what()`文字列に
`unwrap()`が発生したソースコードのファイル名と行数が表示されます。
利用可能でない場合、位置情報は表示されません。
### `as_ok()`
```cpp
value_type& as_ok() noexcept;
value_type const& as_ok() const noexcept;
```
チェックなしで成功値を返します。
成功値を持っていなかった場合、その動作は未定義となります。
### `as_err()`
```cpp
error_type& as_err() noexcept;
error_type const& as_err() const noexcept;
```
チェックなしで失敗値を返します。
失敗値を持っていなかった場合、その動作は未定義となります。
# bad_result_access
`result``unwrap`または`unwrap_err`で失敗した際に送出される例外です。
```cpp
namespace toml
{
struct bad_result_access : public ::toml::exception
{
public:
explicit bad_result_access(const std::string& what_arg);
virtual ~bad_result_access() noexcept override = default;
virtual const char* what() const noexcept override;
protected:
std::string what_;
};
}
```

View File

@@ -0,0 +1,66 @@
+++
title = "serializer.hpp"
type = "docs"
+++
# serializer.hpp
# `format`
シリアライズを行います。
```cpp
namespace toml
{
template<typename TC>
std::string format(const basic_value<TC>& v,
const spec s = spec::default_version());
template<typename TC>
std::string format(const typename basic_value<TC>::key_type& k,
const basic_value<TC>& v,
const spec s = spec::default_version());
template<typename TC>
std::string format(const std::vector<typename basic_value<TC>::key_type>& ks,
const basic_value<TC>& v,
const spec s = spec::default_version());
}
```
フォーマット情報と`spec`が矛盾する場合、例えば`v1.0.0``table_format::multiline_oneline`が指定されているときなどは、`spec`が優先されます。
### `format(v, spec)`
`toml::value`を、それが持つフォーマット情報と`spec`に従ってフォーマットします。
`table_type`だった場合、それがルートであるとしてフォーマットします。
それ以外の値だった場合、値のみをフォーマットします。
### `format(k, v, spec)`
`toml::value`を、与えられたキーと同時にフォーマットします。
`v`はそのキー以下に定義されていると解釈されます。
### `format([k,...], v, spec)`
`v`はそのキー以下に定義されていると解釈されます。
キーが複数与えられた場合、再帰的に定義されたテーブルとして解釈されます。
# `serialization_error`
シリアライズ中に発生したエラーを報告します。
```cpp
namespace toml
{
struct serialization_error final : public ::toml::exception
{
public:
explicit serialization_error(std::string what_arg, source_location loc);
~serialization_error() noexcept override = default;
const char* what() const noexcept override;
source_location const& location() const noexcept;
};
}
```

View File

@@ -0,0 +1,233 @@
+++
title = "source_location.hpp"
type = "docs"
+++
# source_location.hpp
`source_location.hpp`では、TOMLファイル内のある領域を指すクラスが定義されます。
このクラスは、エラーメッセージで問題の箇所を指摘するために使われます。
# `toml::source_location`
`source_location`は、TOMLファイル内のある領域を指すクラスです。
```cpp
namespace toml
{
struct source_location
{
public:
explicit source_location(/* implementation-defined */);
~source_location() = default;
source_location(source_location const&) = default;
source_location(source_location &&) = default;
source_location& operator=(source_location const&) = default;
source_location& operator=(source_location &&) = default;
bool is_ok() const noexcept;
std::size_t length() const noexcept;
std::size_t first_line_number() const noexcept;
std::size_t first_column_number() const noexcept;
std::size_t last_line_number() const noexcept;
std::size_t last_column_number() const noexcept;
std::string const& file_name() const noexcept;
std::size_t num_lines() const noexcept;
std::string const& first_line() const;
std::string const& last_line() const;
std::vector<std::string> const& lines() const noexcept;
};
template<typename ... Ts>
std::string format_location(const source_location& loc, const std::string& msg, const Ts& ... locs_and_msgs);
} //toml
```
## メンバ関数
### コンストラクタ
```cpp
explicit source_location(/* implementation-defined */);
```
`toml::source_location``toml::parse`または`_toml`リテラル以外で構築することはできません。
### `is_ok()`
```cpp
bool is_ok() const noexcept;
```
`source_location`が有効な値を保持している場合、`true`を、そうでない場合`false`を返します。
`toml::parse``_toml`リテラル以外から構築した`toml::value``location()`の結果は、指す対象がないため、`is_ok``false`を返します。
### `length()`
```cpp
std::size_t length() const noexcept;
```
`source_location`が指す領域の長さを返します。
有効な値を保持していない場合、`0`を返します。
### `first_line_number()`
```cpp
std::size_t first_line_number() const noexcept;
```
`source_location`が指す領域の最初の行の行番号を返します。
有効な値を保持していない場合、`1`を返します。
### `first_column_number()`
```cpp
std::size_t first_column_number() const noexcept;
```
`source_location`が指す領域の最初の列の列番号を返します。
有効な値を保持していない場合、`1`を返します。
### `last_line_number()`
```cpp
std::size_t last_line_number() const noexcept;
```
`source_location`が指す領域の最後の行の行番号を返します。
有効な値を保持していない場合、`1`を返します。
### `last_column_number()`
```cpp
std::size_t last_column_number() const noexcept;
```
`source_location`が指す領域の最後の列の列番号を返します。
有効な値を保持していない場合、`1`を返します。
### `file_name()`
```cpp
std::string const& file_name() const noexcept;
```
`source_location`が指す領域を含むファイルのファイル名を返します。
有効な値を保持していない場合、`"unknown file"`を返します。
### `num_lines()`
```cpp
std::size_t num_lines() const noexcept;
```
`source_location`が指す領域の行数を返します。
有効な値を保持していない場合、`0`を返します。
### `first_line()`
```cpp
std::string const& first_line() const;
```
`source_location`が指す領域の最初の行を返します。
有効な値を保持していない場合、`std::out_of_range`例外が送出されます。
### `last_line()`
```cpp
std::string const& last_line() const;
```
`source_location`が指す領域の最後の行を返します。
有効な値を保持していない場合、`std::out_of_range`例外が送出されます。
### `lines()`
```cpp
std::vector<std::string> const& lines() const noexcept;
```
`source_location`が指す領域の全ての行を返します。
有効な値を保持していない場合、空の`std::vector`への参照を返します。
## 非メンバ関数
### `format_location`
```cpp
template<typename ... Ts>
std::string format_location(const source_location& loc, const std::string& msg, const Ts& ... locs_and_msgs);
```
`source_location`が指す箇所と、それについてのメッセージを以下のようにフォーマットします。
```
-> {filename.toml}
|
1 | a = 42
| ^-- {message}
```
この時、色付けがONになっている場合、ANSIエスケープシーケンスによって色情報が追加されます。
locs_and_msgsが複数個ある場合、それらは`const source_location&``const std::string&`の順である必要があります。
#### 例:複数の`source_location`と`std::string`
複数の`source_location``std::string`を渡した場合、以下のようにフォーマットされます。
```cpp
source_location& loc0;
source_location& loc1;
source_location& loc2;
std::string msg0;
std::string msg1;
std::string msg2;
format_location(loc0, msg0,
loc1, msg1,
loc2, msg2);
```
```
-> {filename0.toml}
|
1 | a = 42
| ^-- {message0}
|
-> {filename1.toml}
|
2 | b = 3.14
| ^-- {message1}
|
-> {filename2.toml}
|
3 | c = "foo"
| ^-- {message2}
```
# 関連項目
- [error_info.hpp]({{<ref "error_info.md">}})
- [value.hpp]({{<ref "value.md">}})

View File

@@ -0,0 +1,314 @@
+++
title = "spec.hpp"
type = "docs"
+++
# spec.hpp
`spec.hpp`では、TOMLのバージョンを指定するためのクラスが定義されます。
# `toml::semantic_version`
`semantic_version`は、バージョン情報を格納するクラスです。
```cpp
namespace toml
{
struct semantic_version
{
constexpr semantic_version(std::uint32_t mjr, std::uint32_t mnr, std::uint32_t p) noexcept;
std::uint32_t major;
std::uint32_t minor;
std::uint32_t patch;
};
constexpr semantic_version
make_semver(std::uint32_t major, std::uint32_t minor, std::uint32_t patch) noexcept;
constexpr bool operator==(const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator!=(const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator< (const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator<=(const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator> (const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator>=(const semantic_version&, const semantic_version&) noexcept;
std::ostream& operator<<(std::ostream& os, const semantic_version& ver);
} //toml
```
## メンバ関数
### コンストラクタ
```cpp
constexpr semantic_version(std::uint32_t mjr, std::uint32_t mnr, std::uint32_t p) noexcept;
```
`major`, `minor`, `patch`バージョンを指定して構築します。
## 非メンバ関数
### 比較演算子
```cpp
constexpr bool operator==(const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator!=(const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator< (const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator<=(const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator> (const semantic_version&, const semantic_version&) noexcept;
constexpr bool operator>=(const semantic_version&, const semantic_version&) noexcept;
```
semantic versioningに従って比較します。
### ストリーム演算子
```cpp
std::ostream& operator<<(std::ostream& os, const semantic_version& ver);
```
`{major}.{minor}.{patch}`の形式で出力します。
### `to_string`
```cpp
std::string to_string(const semantic_version& ver);
```
`{major}.{minor}.{patch}`の形式で文字列化します。
# `toml::spec`
`spec`は、TOMLのバージョン情報を格納するクラスです。
```cpp
struct spec
{
constexpr static spec default_version() noexcept;
constexpr static spec v(std::uint32_t mjr, std::uint32_t mnr, std::uint32_t p) noexcept;
constexpr explicit spec(const semantic_version& semver) noexcept;
semantic_version version; // toml version
// diff from v1.0.0 -> v1.1.0
bool v1_1_0_allow_control_characters_in_comments;
bool v1_1_0_allow_newlines_in_inline_tables;
bool v1_1_0_allow_trailing_comma_in_inline_tables;
bool v1_1_0_allow_non_english_in_bare_keys;
bool v1_1_0_add_escape_sequence_e;
bool v1_1_0_add_escape_sequence_x;
bool v1_1_0_make_seconds_optional;
// library extensions
bool ext_hex_float; // allow hex float
bool ext_num_suffix; // allow number suffix
bool ext_null_value; // allow null value
};
```
## メンバ関数
### コンストラクタ
```cpp
constexpr explicit spec(const semantic_version& semver) noexcept;
```
指定されたTOMLバージョンで`spec`を構築します。
TOML v1.0.0と、TOML v1.1.0に対応しています。
### `default_version()`
```cpp
constexpr static spec default_version() noexcept;
```
デフォルトのバージョンで`spec`を構築します。
`toml::parse``toml::format`でのデフォルト値として使われます。
toml11 v4.4.0での値は、v1.0.0です。
### `v(major, minor, patch)`
```cpp
constexpr static spec v(std::uint32_t mjr, std::uint32_t mnr, std::uint32_t p) noexcept;
```
指定されたバージョンで`spec`を構築します。
## メンバ変数
各フラグは機能追加がされたバージョンを指定されたとき、自動的に`true`になります。
変更して渡すことで、`toml::parse``toml::format`の挙動を変更できます。
{{<hint warning>}}
TOML v1.1.0の一部の機能にはかなり長い議論が続いており、まだ差し戻される可能性があります。
実際に差し戻された場合、toml11はマイナーバージョンアップでそれらの機能を削除、もしくは対応するそれ以降のバージョンに移動します。
そのような意味で、将来のバージョンに関する機能は全て不安定なものと考えてください。
{{</hint>}}
### 例
```cpp
auto spec = toml::spec::v(1, 0, 0);
// v1.0.0の機能に追加して、inline table内の改行を許可する。
// それ以外のv1.1.0の機能は有効化されない。
spec.v1_1_0_allow_newlines_in_inline_tables = true;
auto input = toml::parse("input_file.toml", spec);
```
### `v1_1_0_allow_control_characters_in_comments`
```cpp
bool v1_1_0_allow_control_characters_in_comments;
```
ほとんどの制御文字をコメントに含むことを許可します。
toml v1.1.0で追加。
### `v1_1_0_allow_newlines_in_inline_tables`
```cpp
bool v1_1_0_allow_newlines_in_inline_tables;
```
inline table内で改行することを許可します。
toml v1.1.0で追加。
### `v1_1_0_allow_trailing_comma_in_inline_tables`
```cpp
bool v1_1_0_allow_trailing_comma_in_inline_tables;
```
inline table内での末尾コンマを許可します。
toml v1.1.0で追加。
### `v1_1_0_add_escape_sequence_e`
```cpp
bool v1_1_0_add_escape_sequence_e;
```
`\e`でESC文字を指定できるようになります。
toml v1.1.0で追加。
### `v1_1_0_add_escape_sequence_x`
```cpp
bool v1_1_0_add_escape_sequence_x;
```
`\xHH`で1バイトの文字を指定できるようになります。
toml v1.1.0で追加。
### `v1_1_0_make_seconds_optional`
```cpp
bool v1_1_0_make_seconds_optional;
```
時刻での秒数指定を省略可能にします。
指定されなかった秒数は`0`で初期化されます。
toml v1.1.0で追加。
### `ext_hex_float`
```cpp
bool ext_hex_float;
```
toml11限定の言語拡張です。
どのバージョンを指定しても、`false`で初期化されます。
使用する際は個別に`true`にしてください。
浮動小数点数の16進数表記を許可します。
16進数表記は`printf``%a/%A`を指定した場合に準拠します。
```
hexf = 0xC0FFEEp-10
```
`toml::format` は、渡された `toml::spec``ext_hex_format``true` の場合のみ
16進表記でフォーマットします。
フォーマット情報で `hex` が指定されているにも関わらず `toml::format` に渡された
`toml::spec``ext_hex_float``false` だった場合、16進数指定は無視され、
10進表記で最大の精度で出力されます。
### `ext_num_suffix`
```cpp
bool ext_num_suffix;
```
toml11限定の言語拡張です。
どのバージョンを指定しても、`false`で初期化されます。
使用する際は個別に`true`にしてください。
10進数の整数と浮動小数点数に接尾辞を追加します。型を問わず、16進や8進、2進表記には適用されません。
数値と接尾辞の間は`_`で区切られている必要があります。
数値部分との区別のため、接尾辞は数値で始まることはできません。
```
distance = 10_m # valid
distance = 10_2m # invalid
distance = 10_2_m # valid
```
接尾辞は `std::string suffix` としてフォーマット情報に保持されます。
数値部分とを分ける `_``suffix` に含まれません。
```cpp
toml::value distance = toml::find(input, "distance");
assert(distance.as_integer_fmt().suffix == std::string("m"));
```
`toml::format` は、渡された `toml::spec``ext_num_suffix``true` の場合のみ
これをフォーマットします。
`suffix`は以下のような文法を持ちます。
```abnf
non-digit-graph = ALPHA / non-ascii
graph = ALPHA / DIGIT / non-ascii
suffix = _ non-digit-graph *( graph / ( _ graph ) )
```
### `ext_null_value`
```cpp
bool ext_null_value;
```
toml11限定の言語拡張です。
値として `null` を許可します。
`null` を指定された `toml::value` は値を持たず、 `is_empty()``true` になります。
`toml::format` は、渡された `toml::spec``ext_null_value``true` の場合のみ
`null` としてフォーマットします。
そうでない場合、 `toml::format` がエラーで終了します。

View File

@@ -0,0 +1,14 @@
+++
title = "toml.hpp"
type = "docs"
+++
# toml.hpp
`toml.hpp`は、他の全てのヘッダを `include` します。
これによって、toml11の全機能が使用可能になります。
このヘッダファイルと `toml_fwd.hpp``${TOML11_INCLUDE_DIR}/` 以下に、
他のヘッダファイルは `${toml11_include_dir}/toml11/` 以下にあります。

View File

@@ -0,0 +1,24 @@
+++
title = "toml_fwd.hpp"
type = "docs"
+++
# toml_fwd.hpp
`toml_fwd.hpp`は、toml11で定義される構造体の前方宣言と、マクロ定義を持ちます。
toml11の構造体についての前方宣言しか必要なく実装が必要ない場合、
`toml.hpp` のかわりにこちらを `include` することでコンパイル時間を短縮できます。
{{<hint warning>}}
このファイルには前方宣言しか含まれていないため、
`toml::basic_value<toml::type_config>::table_type` として定義される
`toml::table` と、同様に定義される `toml::array` は使用できません。
それらには `basic_value` の実装が必要だからです。
{{</hint>}}
このヘッダファイルと `toml.hpp``${TOML11_INCLUDE_DIR}/` 以下に、
他のヘッダファイルは `${TOML11_INCLUDE_DIR}/toml11/` 以下にあります。

View File

@@ -0,0 +1,154 @@
+++
title = "types.hpp"
type = "docs"
+++
# types.hpp
型情報を与えるクラスが定義されます。
# `type_config`
`type_config`は、`toml::basic_value`に与えられるパラメータをまとめた型です。
`toml::basic_value<T>`内で異なる型を使用する場合、これを別に定義して渡します。
記載のある要素は全て必須の要素です。
通常のストリーム演算子を使用できない数値型を使用する場合、`read_int``read_float`に相当するものを定義し、置き換えてください。
```cpp
namespace toml
{
struct type_config
{
using comment_type = preserve_comments;
using boolean_type = bool;
using integer_type = std::int64_t;
using floating_type = double;
using string_type = std::string;
template<typename T>
using array_type = std::vector<T>;
template<typename K, typename T>
using table_type = std::unordered_map<K, T>;
static result<integer_type, error_info>
parse_int(const std::string& str, const source_location src, const std::uint8_t base);
static result<floating_type, error_info>
parse_float(const std::string& str, const source_location src, const bool is_hex);
};
using value = basic_value<type_config>;
using table = typename value::table_type;
using array = typename value::array_type;
} // toml
```
## `static` メンバ関数
### `parse_int(str, src, base)`
```cpp
static result<integer_type, error_info>
parse_int(const std::string& str, const source_location src, const std::uint8_t base);
```
通常のストリーム演算子などを使用できない型を`integer_type`として使用する場合、この関数を実装してください。
`str`には、prefix、`0x`などの場合leading zero、underscoreが取り除かれた文字列が渡されます。
`src`には、その文字列が定義されていた箇所を指す`source_location`が渡されます。
`base`には、`10`, `2`, `8`, `16`のいずれかが渡されます。
### `parse_float(str, src, is_hex)`
```cpp
static result<floating_type, error_info>
parse_float(const std::string& str, const source_location src, const bool is_hex);
```
通常のストリーム演算子などを使用できない型を`floating_type`として使用する場合、この関数を実装してください。
`str`には、prefix、leading zero、underscoreが取り除かれた文字列が渡されます。
`src`には、その文字列が定義されていた箇所を指す`source_location`が渡されます。
`is_hex`には、フォーマットが`hexfloat`であるかどうかが渡されます。`hexfloat`拡張を使用しない場合は使われないので、実装する必要はありません。
`hexfloat`拡張に関しては、[spec.hpp]({{<ref "spec.md">}})を参照してください。
## 非メンバ関数
### `read_int`
```cpp
template<typename T>
result<T, error_info>
read_int(const std::string& str, const source_location src, const std::uint8_t base);
```
デフォルトで使用される関数です。`std::istringstream`を使用してパースします。
`operator>>``std::hex`等のマニピュレータ、`std::numeric_limits<T>`が定義されている場合(`boost::multiprecision`など)、特に変更なしにこれを使用できます。
### `read_float`
```cpp
template<typename T>
result<T, error_info>
read_float(const std::string& str, const source_location src, const bool is_hex);
```
デフォルトで使用される関数です。decimalの場合は`std::istringstream`を、hexfloatの場合は`sscanf()`を使用してパースします。
`double``float`に対応しています。
それ以外の型の場合、`operator>>`が定義されていて、かつ`hex`を使用しないなら、これを使用できます。
# `ordered_type_config`
`ordered_type_config`は、`toml::type_config`のテーブル型を`toml::ordered_map`に変更したものです。
また、`toml::ordered_value`エイリアスを定義します。
そのほかに`type_config`との違いはありません。
```cpp
namespace toml
{
struct ordered_type_config
{
using comment_type = preserve_comments;
using boolean_type = bool;
using integer_type = std::int64_t;
using floating_type = double;
using string_type = std::string;
template<typename T>
using array_type = std::vector<T>;
template<typename K, typename T>
using table_type = ordered_map<K, T>;
static result<integer_type, error_info>
parse_int(const std::string& str, const source_location src, const std::uint8_t base)
{
return read_int<integer_type>(str, src, base);
}
static result<floating_type, error_info>
parse_float(const std::string& str, const source_location src, const bool is_hex)
{
return read_float<floating_type>(str, src, is_hex);
}
};
using ordered_value = basic_value<ordered_type_config>;
using ordered_table = typename ordered_value::table_type;
using ordered_array = typename ordered_value::array_type;
} // toml
```

View File

@@ -0,0 +1,913 @@
+++
title = "value.hpp"
type = "docs"
+++
# value.hpp
`value.hpp`では、`basic_value`が定義されます。
# `toml::basic_value`
`basic_value`は、TOMLの値を格納するクラスです。
```cpp
namespace toml
{
template <class TypeConfig>
class basic_value;
// 以下はtypes.hppで定義される
// using value = basic_value<type_config>;
// using table = typename basic_value<type_config>::table_type;
// using array = typename basic_value<type_config>::array_type;
template<typename TC>
bool operator==(const basic_value<TC>&, const basic_value<TC>&);
template<typename TC>
bool operator!=(const basic_value<TC>&, const basic_value<TC>&);
template<typename TC>
bool operator< (const basic_value<TC>&, const basic_value<TC>&);
template<typename TC>
bool operator<=(const basic_value<TC>&, const basic_value<TC>&);
template<typename TC>
bool operator> (const basic_value<TC>&, const basic_value<TC>&);
template<typename TC>
bool operator>=(const basic_value<TC>&, const basic_value<TC>&);
} //toml
```
## メンバ型
以下のメンバ型が定義されます。
`TypeConfig`を使って、メンバ型を変更することができます。
参考: [types.hpp]({{<ref "types.md">}})
| 名前 | 定義 |
|:-----------------------|:-------------------------------------|
| `char_type` | `typename TypeConfig::char_type` |
| `key_type` | `typename TypeConfig::string_type` |
| `value_type` | `basic_value<TypeConfig>` |
| `boolean_type` | `typename TypeConfig::boolean_type` |
| `integer_type` | `typename TypeConfig::integer_type` |
| `floating_type` | `typename TypeConfig::floating_type` |
| `string_type` | `typename TypeConfig::string_type` |
| `local_time_type` | `toml::local_time` |
| `local_date_type` | `toml::local_date` |
| `local_datetime_type` | `toml::local_datetime` |
| `offset_datetime_type` | `toml::offset_datetime` |
| `array_type` | `typename TypeConfig::template array_type<value_type>`|
| `table_type` | `typename TypeConfig::template table_type<key_type, value_type>`|
| `comment_type` | `typename TypeConfig::comment_type` |
## メンバ関数
### デフォルトコンストラクタ
```cpp
basic_value() noexcept
```
空の`toml::value`を構築します。
構築された`toml::value`は空になります。
### コピー・ムーブコンストラクタ
```cpp
basic_value(const basic_value& v)
basic_value(basic_value&& v)
```
値、フォーマット情報、コメント、ファイル領域の全ての情報をコピー・ムーブします。
### コピー・ムーブコンストラクタ(コメント指定)
```cpp
basic_value(basic_value v, std::vector<std::string> com)
```
コメントを上書きしながらコピー・ムーブします。
### 変換コンストラクタ
```cpp
template<typename TI>
basic_value(basic_value<TI> other)
template<typename TI>
basic_value(basic_value<TI> other, std::vector<std::string> com)
```
異なる`type_config`を持つ`basic_value`からコピー・ムーブします。
### コンストラクタ (boolean)
```cpp
basic_value(boolean_type x)
basic_value(boolean_type x, boolean_format_info fmt)
basic_value(boolean_type x, std::vector<std::string> com)
basic_value(boolean_type x, boolean_format_info fmt, std::vector<std::string> com)
```
`bool`と、そのフォーマット情報、コメントを受け取って構築します。
### コンストラクタ (integer)
```cpp
basic_value(integer_type x)
basic_value(integer_type x, integer_format_info fmt)
basic_value(integer_type x, std::vector<std::string> com)
basic_value(integer_type x, integer_format_info fmt, std::vector<std::string> com)
```
`integer`と、そのフォーマット情報、コメントを受け取って構築します。
### コンストラクタ(floating)
```cpp
template<typename T, /* T は std::is_floating_point<T> を満たす */>
basic_value(T x)
template<typename T, /* T は std::is_floating_point<T> を満たす */>
basic_value(T x, floating_format_info fmt)
template<typename T, /* T は std::is_floating_point<T> を満たす */>
basic_value(T x, std::vector<std::string> com)
template<typename T, /* T は std::is_floating_point<T> を満たす */>
basic_value(T x, floating_format_info fmt, std::vector<std::string> com)
```
`floating`と、そのフォーマット情報、コメントを受け取って構築します。
### コンストラクタ(string)
```cpp
basic_value(string_type x)
basic_value(string_type x, string_format_info fmt)
basic_value(string_type x, std::vector<std::string> com)
basic_value(string_type x, string_format_info fmt, std::vector<std::string> com)
basic_value(const string_type::value_type* x)
basic_value(const string_type::value_type* x, string_format_info fmt)
basic_value(const string_type::value_type* x, std::vector<std::string> com)
basic_value(const string_type::value_type* x, string_format_info fmt, std::vector<std::string> com)
// C++17以降
basic_value(string_view_type x)
basic_value(string_view_type x, string_format_info fmt)
basic_value(string_view_type x, std::vector<std::string> com)
basic_value(string_view_type x, string_format_info fmt, std::vector<std::string> com)
```
`string`と、そのフォーマット情報、コメントを受け取って構築します。
`string_view_type`は、`string_type`と同じ`value_type``traits_type`を持ちます。
### コンストラクタ(local_date)
```cpp
basic_value(local_date_type x)
basic_value(local_date_type x, local_date_format_info fmt)
basic_value(local_date_type x, std::vector<std::string> com)
basic_value(local_date_type x, local_date_format_info fmt, std::vector<std::string> com)
```
`local_date_type`と、そのフォーマット情報、コメントを受け取って構築します。
### コンストラクタ(local_time)
```cpp
basic_value(local_time_type x)
basic_value(local_time_type x, local_time_format_info fmt)
basic_value(local_time_type x, std::vector<std::string> com)
basic_value(local_time_type x, local_time_format_info fmt, std::vector<std::string> com)
template<typename Rep, typename Period>
basic_value(const std::chrono::duration<Rep, Period>& x)
template<typename Rep, typename Period>
basic_value(const std::chrono::duration<Rep, Period>& x, local_time_format_info fmt)
template<typename Rep, typename Period>
basic_value(const std::chrono::duration<Rep, Period>& x, std::vector<std::string> com)
template<typename Rep, typename Period>
basic_value(const std::chrono::duration<Rep, Period>& x, local_time_format_info fmt, std::vector<std::string> com)
```
`local_time_type`と、そのフォーマット情報、コメントを受け取って構築します。
`std::chrono::duration`は、`00:00:00`からの時間幅として構築します。
### コンストラクタ(local_datetime)
```cpp
basic_value(local_datetime_type x)
basic_value(local_datetime_type x, local_date_format_info fmt)
basic_value(local_datetime_type x, std::vector<std::string> com)
basic_value(local_datetime_type x, local_date_format_info fmt, std::vector<std::string> com)
```
`local_datetime_type`と、そのフォーマット情報、コメントを受け取って構築します。
### コンストラクタ(offset_datetime)
```cpp
basic_value(offset_datetime_type x)
basic_value(offset_datetime_type x, offset_date_format_info fmt)
basic_value(offset_datetime_type x, std::vector<std::string> com)
basic_value(offset_datetime_type x, offset_date_format_info fmt, std::vector<std::string> com)
basic_value(std::chrono::system_clock::time_point x)
basic_value(std::chrono::system_clock::time_point x, offset_date_format_info fmt)
basic_value(std::chrono::system_clock::time_point x, std::vector<std::string> com)
basic_value(std::chrono::system_clock::time_point x, offset_date_format_info fmt, std::vector<std::string> com)
```
`offset_datetime_type`と、そのフォーマット情報、コメントを受け取って構築します。
`std::chrono::system_clock::time_point`の場合、それが指す時点として構築します。
### コンストラクタ(array)
```cpp
basic_value(array_type x)
basic_value(array_type x, integer_format_info fmt)
basic_value(array_type x, std::vector<std::string> com)
basic_value(array_type x, integer_format_info fmt, std::vector<std::string> com)
template<typename T, /* T is array-like */>
basic_value(T x)
template<typename T, /* T is array-like */>
basic_value(T x, array_format_info fmt)
template<typename T, /* T is array-like */>
basic_value(T x, std::vector<std::string> com)
template<typename T, /* T is array-like */>
basic_value(T x, array_format_info fmt, std::vector<std::string> com)
```
`array`と、そのフォーマット情報、コメントを受け取って構築します。
`array-like`は、以下の条件を満たす型です。
- `T::iterator` を持つ。
- `T::value_type` を持つ。
- `T::key_type` を持た**ない**。
- `T::mapped_type` を持た**ない**。
- `std::string` では**ない**。
- `std::string_view` では**ない**。(C++17以降)
### コンストラクタ(table)
```cpp
basic_value(table_type x)
basic_value(table_type x, integer_format_info fmt)
basic_value(table_type x, std::vector<std::string> com)
basic_value(table_type x, integer_format_info fmt, std::vector<std::string> com)
template<typename T, /* T is table-like */>
basic_value(T x)
template<typename T, /* T is table-like */>
basic_value(T x, table_format_info fmt)
template<typename T, /* T is table-like */>
basic_value(T x, std::vector<std::string> com)
template<typename T, /* T is table-like */>
basic_value(T x, table_format_info fmt, std::vector<std::string> com)
```
`table`と、そのフォーマット情報、コメントを受け取って構築します。
`table-like`は、以下の条件を満たす型です。
- `T::iterator` を持つ。
- `T::value_type` を持つ。
- `T::key_type` を持つ。
- `T::mapped_type` を持つ。
### コンストラクタ(user-defined)
```cpp
template<typename T /* toml::into<T>が定義されていること */>
basic_value(const T& ud);
template<typename T /* toml::into<T>が定義されていること */>
basic_value(const T& ud, std::vector<std::string> com);
template<typename T /* into<T>は定義されておらず、T{}.into_toml()が存在すること */>
basic_value(const T& ud);
template<typename T /* into<T>は定義されておらず、T{}.into_toml()が存在すること */>
basic_value(const T& ud, std::vector<std::string> com);
```
`toml::into<T>` が定義されていた場合、 `toml::into<T>(ud)` の結果から構築します。
`toml::into<T>` が定義されておらず、 `T``into_toml()` メンバ関数が定義されていた場合、
`ud.into_toml()`の結果から構築します。
-----
### `operator=(basic_value)`
```cpp
basic_value& operator=(const basic_value& v)
basic_value& operator=(basic_value&& v)
template<typename TI>
basic_value& operator=(basic_value<TI> other)
```
右辺の`basic_value`を代入します。
### `operator=(T)`
```cpp
template<typename T>
basic_value& operator=(T x)
```
Tに対応する値を代入します。
`source_location`の指す内容は破棄されます。
もし同じ型の値を持っていたなら、元のフォーマット情報が保持されます。
-----
### `is<T>()`
```cpp
bool is<T>() const noexcept
```
#### 条件
`T`は厳密にTOML型であること。つまり、値に対応する`toml::value::xxx_type`のいずれかであること。
#### 戻り値
格納している型が`T`と一致した場合`true`を、そうでない場合は`false`を返します。
-----
### `is(toml::value_t)`
```cpp
bool is(toml::value_t t) const noexcept
```
#### 戻り値
格納している型のタグが`t`と一致した場合`true`を、そうでない場合は`false`を返します。
-----
### `is_xxx()`
```cpp
bool is_boolean() const noexcept;
bool is_integer() const noexcept;
bool is_floating() const noexcept;
bool is_string() const noexcept;
bool is_offset_datetime() const noexcept;
bool is_local_datetime() const noexcept;
bool is_local_date() const noexcept;
bool is_local_time() const noexcept;
bool is_array() const noexcept;
bool is_table() const noexcept;
```
#### 戻り値
格納している型がその型である場合`true`を、そうでない場合は`false`を返します。
-----
### `is_empty()`
```cpp
bool is_empty() const noexcept;
```
#### 戻り値
デフォルト構築され値が代入されていない場合`true`を、そうでない場合は`false`を返します。
### `is_array_of_tables()`
```cpp
bool is_array_of_tables() const noexcept;
```
#### 戻り値
格納している型が配列であり、空ではなく、全要素がテーブルの場合は`true`を、そうでない場合は`false`を返します。
-----
### `type()`
```cpp
toml::value_t type() const noexcept
```
#### 戻り値
格納している型に対応するタグを返します。
-----
### `as_xxx()`
```cpp
boolean_type const& as_boolean () const;
integer_type const& as_integer () const;
floating_type const& as_floating () const;
string_type const& as_string () const;
offset_datetime_type const& as_offset_datetime() const;
local_datetime_type const& as_local_datetime () const;
local_date_type const& as_local_date () const;
local_time_type const& as_local_time () const;
array_type const& as_array () const;
table_type const& as_table () const;
boolean_type & as_boolean ();
integer_type & as_integer ();
floating_type & as_floating ();
string_type & as_string ();
offset_datetime_type& as_offset_datetime();
local_datetime_type & as_local_datetime ();
local_date_type & as_local_date ();
local_time_type & as_local_time ();
array_type & as_array ();
table_type & as_table ();
```
#### 戻り値
指定された型への参照を返します。
#### 例外
格納されている値の型が指定と異なる場合、`toml::type_error`を送出します。
-----
### `as_xxx(std::nothrow)`
`std::nothrow`オブジェクトを渡して呼び出します。
```cpp
boolean_type const& as_boolean (const std::nothrow_t&) const noexcept;
integer_type const& as_integer (const std::nothrow_t&) const noexcept;
floating_type const& as_floating (const std::nothrow_t&) const noexcept;
string_type const& as_string (const std::nothrow_t&) const noexcept;
offset_datetime_type const& as_offset_datetime(const std::nothrow_t&) const noexcept;
local_datetime_type const& as_local_datetime (const std::nothrow_t&) const noexcept;
local_date_type const& as_local_date (const std::nothrow_t&) const noexcept;
local_time_type const& as_local_time (const std::nothrow_t&) const noexcept;
array_type const& as_array (const std::nothrow_t&) const noexcept;
table_type const& as_table (const std::nothrow_t&) const noexcept;
boolean_type & as_boolean (const std::nothrow_t&) noexcept;
integer_type & as_integer (const std::nothrow_t&) noexcept;
floating_type & as_floating (const std::nothrow_t&) noexcept;
string_type & as_string (const std::nothrow_t&) noexcept;
offset_datetime_type& as_offset_datetime(const std::nothrow_t&) noexcept;
local_datetime_type & as_local_datetime (const std::nothrow_t&) noexcept;
local_date_type & as_local_date (const std::nothrow_t&) noexcept;
local_time_type & as_local_time (const std::nothrow_t&) noexcept;
array_type & as_array (const std::nothrow_t&) noexcept;
table_type & as_table (const std::nothrow_t&) noexcept;
```
#### 戻り値
指定された型への参照を返します。
#### 備考
格納されている値の型が指定と異なる場合、未定義動作となります。
-----
### `as_xxx_fmt()`
フォーマット情報にアクセスします。
```cpp
boolean_format_info & as_boolean_fmt ();
integer_format_info & as_integer_fmt ();
floating_format_info & as_floating_fmt ();
string_format_info & as_string_fmt ();
offset_datetime_format_info& as_offset_datetime_fmt();
local_datetime_format_info & as_local_datetime_fmt ();
local_date_format_info & as_local_date_fmt ();
local_time_format_info & as_local_time_fmt ();
array_format_info & as_array_fmt ();
table_format_info & as_table_fmt ();
boolean_format_info const& as_boolean_fmt () const;
integer_format_info const& as_integer_fmt () const;
floating_format_info const& as_floating_fmt () const;
string_format_info const& as_string_fmt () const;
offset_datetime_format_info const& as_offset_datetime_fmt() const;
local_datetime_format_info const& as_local_datetime_fmt () const;
local_date_format_info const& as_local_date_fmt () const;
local_time_format_info const& as_local_time_fmt () const;
array_format_info const& as_array_fmt () const;
table_format_info const& as_table_fmt () const;
```
#### 戻り値
指定された型のフォーマット情報を持つ構造体への参照を返します。
#### 例外
格納されている値の型が指定と異なる場合、`toml::type_error`を送出します。
-----
### `as_xxx_fmt(std::nothrow)`
`std::nothrow`オブジェクトを渡して呼び出します。
```cpp
boolean_format_info & as_boolean_fmt (const std::nothrow_t&) noexcept;
integer_format_info & as_integer_fmt (const std::nothrow_t&) noexcept;
floating_format_info & as_floating_fmt (const std::nothrow_t&) noexcept;
string_format_info & as_string_fmt (const std::nothrow_t&) noexcept;
offset_datetime_format_info& as_offset_datetime_fmt(const std::nothrow_t&) noexcept;
local_datetime_format_info & as_local_datetime_fmt (const std::nothrow_t&) noexcept;
local_date_format_info & as_local_date_fmt (const std::nothrow_t&) noexcept;
local_time_format_info & as_local_time_fmt (const std::nothrow_t&) noexcept;
array_format_info & as_array_fmt (const std::nothrow_t&) noexcept;
table_format_info & as_table_fmt (const std::nothrow_t&) noexcept;
boolean_format_info const& as_boolean_fmt (const std::nothrow_t&) const noexcept;
integer_format_info const& as_integer_fmt (const std::nothrow_t&) const noexcept;
floating_format_info const& as_floating_fmt (const std::nothrow_t&) const noexcept;
string_format_info const& as_string_fmt (const std::nothrow_t&) const noexcept;
offset_datetime_format_info const& as_offset_datetime_fmt(const std::nothrow_t&) const noexcept;
local_datetime_format_info const& as_local_datetime_fmt (const std::nothrow_t&) const noexcept;
local_date_format_info const& as_local_date_fmt (const std::nothrow_t&) const noexcept;
local_time_format_info const& as_local_time_fmt (const std::nothrow_t&) const noexcept;
array_format_info const& as_array_fmt (const std::nothrow_t&) const noexcept;
table_format_info const& as_table_fmt (const std::nothrow_t&) const noexcept;
```
#### 戻り値
指定された型のフォーマット情報を持つ構造体への参照を返します。
#### 備考
格納されている値の型が指定と異なる場合、未定義動作となります。
-----
### `at(key)`
```cpp
value_type& at(const key_type& key);
value_type const& at(const key_type& key) const;
```
#### 戻り値
今の`value``table`にキャストしたあと、`key`によって指定される要素を返します。
#### 例外
もし格納している値が`table`ではなかった場合、`toml::type_error`を送出します。
もし格納している`table`が指定された要素を持っていなかった場合、`std::out_of_range`を送出します。
-----
#### `operator[](key)`
```cpp
value_type& operator[](const key_type& k);
```
##### 戻り値
今の`value``table`にキャストしたあと、`key`によって指定される要素への参照です。
もし`key`によって指定される要素が存在しない場合、デフォルト構築されます。
##### 例外
もし格納している値が`table`ではなかった場合、`toml::type_error`を送出します。
-----
### `count(key)`
```cpp
std::size_t count(const key_type& key) const;
```
#### 戻り値
今の`value``table`にキャストしたあと、`key`に対応する要素が含まれていれば`1`、そうでなければ`0`を返します。
#### 例外
もし格納している値が`table`ではなかった場合、`toml::type_error`を送出します。
-----
### `contains(key)`
```cpp
bool contains(const key_type& key) const;
```
#### 戻り値
今の`value``table`にキャストしたあと、`key`に対応する要素が含まれていれば`true`、そうでなければ`false`を返します。
#### 例外
もし格納している値が`table`ではなかった場合、`toml::type_error`を送出します。
-----
### `at(idx)`
```cpp
value_type& at(const std::size_t idx);
value_type const& at(const std::size_t idx) const;
```
#### 戻り値
今の`value``array`にキャストしたあと、`idx`によって指定される要素を返します。
#### 例外
もし格納している値が`array`ではなかった場合、`toml::type_error`を送出します。
もし格納している`array`が指定された要素を持っていなかった場合、`std::out_of_range`を送出します。
-----
### `operator[](idx)`
```cpp
value_type& operator[](const std::size_t idx) noexcept;
value_type const& operator[](const std::size_t idx) const noexcept;
```
#### 戻り値
今の`value``array`にキャストしたあと、`idx`によって指定される要素への参照を返します。
#### 備考
一切のチェックを行いません。
もし格納している値が`array`ではなかった場合、あるいは`idx`によって指定される要素が存在しない場合、未定義動作となります。
-----
### `push_back(value)`
```cpp
void push_back(const value_type& x);
void push_back(value_type&& x);
```
`value``array`にキャストしたのち、その`array`に対して`push_back`を実行します。
#### 戻り値
なし。
#### 例外
格納している値が`array`ではなかった場合、`toml::type_error`を送出します。
-----
### `emplace_back(args...)`
```cpp
template<typename ... Ts>
value_type& emplace_back(Ts&& ... args)
```
`value``array`にキャストしたのち、その`array`に対して`emplace_back`を実行します。
#### 戻り値
構築した値への参照。
#### 例外
格納している値が`array`ではなかった場合、`toml::type_error`を送出します。
-----
### `size()`
```cpp
std::size_t size() const;
```
#### 戻り値
今の`value``array``string``table`のどれかにキャストしたあと、その要素数を返します。
`string`の場合、文字数を返します。
#### 例外
格納している値が`array`, `string`, `table`のどれでもなかった場合、`toml::type_error`を送出します。
-----
### `location()`
```cpp
source_location location() const;
```
#### 戻り値
その`value`が定義されたTOML文書内の位置を表す`source_location`オブジェクトを返します。
もしTOML文書のパースによって構築されたものでない場合、どこも指示さない`source_location`を返します。
-----
### `comments()`
```cpp
comment_type const& comments() const noexcept;
comment_type& comments() noexcept;
```
#### 戻り値
コメント用コンテナへの参照を返します。
-----
### `accessed()`
```cpp
bool accessed() const;
```
#### 戻り値
その`value`がパース後に一度でも`as_xxx``is_xxx`でアクセスされていた場合、`true`を返します。
それ以外の場合、`false`を返します。
#### 備考
`TOML11_ENABLE_ACCESS_CHECK`が定義されている場合にのみ存在します。
## 非メンバ関数
### `operator==`
```cpp
template<typename TC>
bool operator==(const basic_value<TC>&, const basic_value<TC>&);
```
以下を満たすとき、2つの`basic_value<T>`は同値となります。
- TOML型が同一
- 含む値が同一
- コメントがバイト単位で同一
### `operator!=`
```cpp
template<typename TC>
bool operator!=(const basic_value<TC>& lhs, const basic_value<TC>& rhs)
{
return !(lhs == rhs);
}
```
### `operator<`
`array_type``table_type``operator<`を持っている場合のみ定義されます。
```cpp
template<typename TC>
bool operator<(const basic_value<TC>&, const basic_value<TC>&);
```
以下の順番で比較されます。
1. TOML型
2. TOML型が同一の場合、その値
3. TOML型とその値が同一の場合、コメント
TOML型は、以下の順に小さい値を持ちます。
1. `toml::value_t::empty`
2. `toml::value_t::boolean`
3. `toml::value_t::integer`
4. `toml::value_t::floating`
5. `toml::value_t::string`
6. `toml::value_t::offset_datetime`
7. `toml::value_t::local_datetime`
8. `toml::value_t::local_date`
9. `toml::value_t::local_time`
10. `toml::value_t::array`
11. `toml::value_t::table`
### `operator<=`
`array_type``table_type``operator<`を持っている場合のみ定義されます。
```cpp
template<typename TC>
bool operator<=(const basic_value<TC>& lhs, const basic_value<TC>& rhs)
{
return (lhs < rhs) || (lhs == rhs);
}
```
### `operator>`
`array_type``table_type``operator<`を持っている場合のみ定義されます。
```cpp
template<typename TC>
bool operator>(const basic_value<TC>& lhs, const basic_value<TC>& rhs)
{
return !(lhs <= rhs);
}
```
### `operator>=`
`array_type``table_type``operator<`を持っている場合のみ定義されます。
```cpp
template<typename TC>
bool operator>=(const basic_value<TC>& lhs, const basic_value<TC>& rhs)
{
return !(lhs < rhs);
}
```
# `toml::type_error`
型エラーの際に送出される例外です。
型エラーが生じた値の位置情報が格納されています。
```cpp
struct type_error final : public ::toml::exception
{
public:
type_error(std::string what_arg, source_location loc);
~type_error() noexcept override = default;
const char* what() const noexcept override;
source_location const& location() const noexcept;
};
```
# `toml::make_error_info`
```cpp
template<typename TC, typename ... Ts>
error_info make_error_info(
std::string title, const basic_value<TC>& v, std::string msg, Ts&& ... tail);
```
`basic_value``location()` を呼び出して、その `source_location`
[`make_error_info`]({{<ref "docs/reference/error_info#make_error_info">}})
に渡して `error_info` を作成します。
詳しくは [`error_info`]({{<ref "docs/reference/error_info">}}) を参照してください。
# `toml::format_error`
```cpp
template<typename TC, typename ... Ts>
std::string format_error(std::string title,
const basic_value<TC>& v, std::string msg, Ts&& ... tail);
```
`basic_value``location()` を呼び出して、その `source_location`
[`format_error`]({{<ref "docs/reference/error_info#format_error">}})
に渡して `error_info` を作成し、それを文字列化して返します。
詳しくは [`error_info`]({{<ref "docs/reference/error_info">}}) を参照してください。
# 関連項目
- [comments.hpp]({{<ref "comments.md">}})
- [source_location.hpp]({{<ref "source_location.md">}})
- [types.hpp]({{<ref "types.md">}})
- [visit.hpp]({{<ref "visit.md">}})

View File

@@ -0,0 +1,54 @@
+++
title = "value_t.hpp"
type = "docs"
+++
# value_t.hpp
型情報を表す列挙型です。
# `value_t`
`value_t`は、`toml::value`が持つ型情報を扱う際に使用します。
```cpp
namespace toml
{
enum class value_t : std::uint8_t
{
empty = 0,
boolean = 1,
integer = 2,
floating = 3,
string = 4,
offset_datetime = 5,
local_datetime = 6,
local_date = 7,
local_time = 8,
array = 9,
table = 10
};
std::ostream& operator<<(std::ostream& os, value_t t);
std::string to_string(value_t t);
} // toml
```
## 非メンバ関数
### ストリーム演算子
```cpp
std::ostream& operator<<(std::ostream& os, value_t t);
```
`value_t`の値を文字列化してストリームへ出力します。
### `to_string`
```cpp
std::string to_string(value_t t);
```
`value_t`の値を文字列化して返します。

View File

@@ -0,0 +1,37 @@
+++
title = "version.hpp"
type = "docs"
+++
# version.hpp
`version.hpp`では、toml11とC++のバージョン情報に関係するマクロが定義されます。
## マクロ
### `TOML11_VERSION_MAJOR`
toml11のメジャーバージョンです。
### `TOML11_VERSION_MINOR`
toml11のマイナーバージョンです。
### `TOML11_VERSION_PATCH`
toml11のパッチバージョンです。
## 関数
### `license_notice`
```cpp
namespace toml
{
const char* license_notice() noexcept;
}
```
ライセンス条項を返します。
ソースコードを公開せずに頒布する際の利便性のために用意されています。

View File

@@ -0,0 +1,63 @@
+++
title = "visit.hpp"
type = "docs"
+++
# visit.hpp
`visit.hpp`では、`toml::visit`が定義されます。
# `toml::visit`
## 関数
```cpp
namespace toml
{
template<typename Visitor, typename ... Args>
/* visitor にArgsの中身を渡した際の返り値 */
visit(Visitor&& visitor, Args&& ... args);
} // toml
```
`basic_value<TC>`が保持している型に対応する`Visitor`のオーバーロードを呼び出し、その結果を返します。
#### 条件
`Visitor`は、`basic_value<TC>`が保持している型のどれに対しても呼び出し可能な関数または関数オブジェクトでなければなりません。
また、それぞれのオーバーロードで返り値は同じであることが要求されます。
#### 例
```cpp
#include <toml.hpp>
#include <iostream>
struct type_name_of
{
std::string operator()(const toml::value::boolean_type &) const {return "boolean";}
std::string operator()(const toml::value::integer_type &) const {return "integer";}
std::string operator()(const toml::value::floating_type &) const {return "floating";}
std::string operator()(const toml::value::string_type &) const {return "string";}
std::string operator()(const toml::value::local_time_type &) const {return "local_time";}
std::string operator()(const toml::value::local_date_type &) const {return "local_date";}
std::string operator()(const toml::value::local_datetime_type &) const {return "local_datetime";}
std::string operator()(const toml::value::offset_datetime_type&) const {return "offset_datetime";}
std::string operator()(const toml::value::array_type &) const {return "array";}
std::string operator()(const toml::value::table_type &) const {return "table";}
};
int main()
{
toml::value v(3.14);
std::cout << toml::visit(type_name_of{}, v) << std::endl; // floating
return 0;
}
```
# 関連項目
- [value.hpp]({{<ref "value.md">}})

1
docs/themes/hugo-book vendored Submodule

Submodule docs/themes/hugo-book added at 2f64607bc9

6
examples/CMakeLists.txt Normal file
View File

@@ -0,0 +1,6 @@
add_subdirectory(boost_container)
add_subdirectory(boost_multiprecision)
add_subdirectory(parse_file)
add_subdirectory(reflect)
add_subdirectory(u8string)
add_subdirectory(unicode)

1
examples/boost_container/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
container

Some files were not shown because too many files have changed in this diff Show More