style: just add newlines to README

This commit is contained in:
ToruNiina 2019-02-14 16:26:48 +09:00
parent c4aecc8e4b
commit 0aa50e9439

View File

@ -9,9 +9,13 @@ toml11
C++11 header-only toml parser depending only on C++ standard library.
compatible to the latest version of [TOML v0.5.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.5.0.md) after version 2.0.0.
compatible to the latest version of
[TOML v0.5.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.5.0.md)
after version 2.0.0.
Are you looking for pre-C++11 compatible toml parser? Try [Boost.toml](https://github.com/ToruNiina/Boost.toml)! It has almost the same functionality as this library and works with C++98 & Boost.
Are you looking for pre-C++11 compatible toml parser?
Try [Boost.toml](https://github.com/ToruNiina/Boost.toml)!
It has almost the same functionality as this library and works with C++98 & Boost.
## How to use
@ -55,13 +59,16 @@ assert(ifs.good());
const auto data = toml::parse(ifs /*, "filename" (optional)*/);
```
To show a better error message, it is recommended to pass a filename with `istream`. See also [in the case of syntax error](#in-the-case-of-syntax-error) and [passing invalid type to toml::get](#passing-invalid-type-to-tomlget).
To show a better error message, it is recommended to pass a filename with `istream`.
See also [in the case of syntax error](#in-the-case-of-syntax-error)
and [passing invalid type to toml::get](#passing-invalid-type-to-tomlget).
### In the case of syntax error
If there is a syntax error in a toml file, `toml::parse` will throw `toml::syntax_error`.
toml11 now has clean and informative error messages inspired by Rust and it looks like the following (comment after hash sign are actually not shown).
toml11 now has clean and informative error messages inspired by Rust and
it looks like the following (comment after hash sign are actually not shown).
```console
terminate called after throwing an instance of 'toml::syntax_error'
@ -71,7 +78,8 @@ terminate called after throwing an instance of 'toml::syntax_error'
| ^------ expected newline, but got '='. # error reason
```
If you (mistakenly) duplicate tables and got an error, you may want to see where the other is. toml11 shows both at the same time.
If you (mistakenly) duplicate tables and got an error, you may want to see
where the other is. toml11 shows both at the same time.
```console
terminate called after throwing an instance of 'toml::syntax_error'
@ -84,11 +92,14 @@ terminate called after throwing an instance of 'toml::syntax_error'
| ~~~~~~~ table defined twice
```
Since the error message generation is generally a difficult task, the current status is not ideal. toml11 needs your help. If you encounter a weird error message, please let us know and contribute to improve the quality!
Since the error message generation is generally a difficult task, the current
status is not ideal. toml11 needs your help. If you encounter a weird error message,
please let us know and contribute to improve the quality!
### Getting a toml value
After parsing successfully, you can obtain the values from the result of `toml::parse` (here, `data`) using `toml::get` function.
After parsing successfully, you can obtain the values from the result of
`toml::parse` (here, `data`) using `toml::get` function.
```toml
answer = 42
@ -108,18 +119,22 @@ const auto tab = toml::get<toml::Table>(data.at("tab"));
const auto key = toml::get<std::string>( tab.at("key"));
```
When you pass an exact TOML type that does not require type conversion, `toml::get` returns also a reference through which you can modify the content.
When you pass an exact TOML type that does not require type conversion,
`toml::get` returns also a reference through which you can modify the content.
```cpp
toml::get<toml::integer>(data["answer"]) = 6 * 9;
std::cout << toml::get<int>(data.at("answer")) << std::endl; // 54
```
If the specified type requires conversion, you can't take a reference to the value. See also [underlying types](#underlying-types).
If the specified type requires conversion, you can't take a reference to the value.
See also [underlying types](#underlying-types).
#### Passing invalid type to toml::get
If you choose the invalid type, `toml::type_error` will be thrown. Similar to the `syntax_error`, toml11 also displays informative error messages. The error message when you choose `int` to get `string` value would be like this.
If you choose the invalid type, `toml::type_error` will be thrown.
Similar to the `syntax_error`, toml11 also displays informative error messages.
The error message when you choose `int` to get `string` value would be like this.
```console
terminate called after throwing an instance of 'toml::type_error'
@ -129,7 +144,9 @@ terminate called after throwing an instance of 'toml::type_error'
| ~~~~~~~~~~~~~~ the actual type is string
```
NOTE: In order to show this kind of error message, all the toml values have 1 shared_ptr that points the corresponding byte sequence and 2 iterators that point the range. It is recommended to destruct all the `toml::value` classes after configuring your application to save memory resources.
NOTE: In order to show this kind of error message, all the toml values have 1
`shared_ptr` that points the corresponding byte sequence and 2 iterators that point the range.
It is recommended to destruct all the `toml::value` classes after configuring your application to save memory resources.
### Getting arrays
@ -164,20 +181,25 @@ const auto aofa = toml::get<
>(data.at("aofa"));
```
If you don't know what the type is inside the array, you can use `toml::array`, which is a `std::vector` of `toml::value`, instead.
If you don't know what the type is inside the array, you can use `toml::array`,
which is a `std::vector` of `toml::value`, instead.
```cpp
const auto aofa = toml::get<toml::array>(data.at("aofa"));
const auto first = toml::get<toml::array>(aofa.at(0));
```
See also [expecting conversion](#expecting-conversion) and [checking-value-type](#checking-value-type).
See also [expecting conversion](#expecting-conversion)
and [checking-value-type](#checking-value-type).
### Getting tables
`toml::table` is a key component of this library, which is an alias of a `std::unordered_map` from `toml::key (a.k.a. std::string)` to `toml::value`. `toml::parse` returns this as a result.
`toml::table` is a key component of this library, which is an alias of
a `std::unordered_map` from `toml::key (a.k.a. std::string)` to `toml::value`.
`toml::parse` returns this.
Since it is just an alias of `std::unordered_map`, it has all the functionalities that `std::unordered_map` has, e.g. `operator[]`, `count`, and `find`.
Since it is just an alias of `std::unordered_map`, it has all the functionalities
that `std::unordered_map` has, e.g. `operator[]`, `count`, and `find`.
```cpp
toml::table data = toml::parse("example.toml");
@ -187,7 +209,8 @@ if(data.count("title") != 0)
}
```
When all the values of the table have the same type, toml11 allows you to convert a `toml::table` to a `map` that contains the convertible type.
When all the values of the table have the same type, toml11 allows you to
convert a `toml::table` to a `map` that contains the convertible type.
```toml
[tab]
@ -203,7 +226,8 @@ std::cout << tab["key2"] << std::endl; // bar
### Dotted keys
TOML v0.5.0 has a new feature named "dotted keys". You can chain keys to represent the structure of the data.
TOML v0.5.0 has a new feature named "dotted keys".
You can chain keys to represent the structure of the data.
```toml
physical.color = "orange"
@ -227,7 +251,8 @@ const auto color = toml::get<std::string>(physical.at("color"));
### An array of tables
An array of tables is just an array of tables. You can get it completely in the same way as the other arrays and tables.
An array of tables is just an array of tables.
You can get it completely in the same way as the other arrays and tables.
```toml
array_of_inline_table = [{key = "value1"}, {key = "value2"}, {key = "value3"}]
@ -247,7 +272,9 @@ const auto aot2 = toml::get<std::vector<toml::table>>(data.at("array_of_table"))
### Cost of conversion
Although `toml::get` is convenient, it has additional copy-cost because it copies data contained in `toml::value` to the user-specified type. Of course in some case this overhead is not ignorable.
Although `toml::get` is convenient, it has additional copy-cost because
it copies data contained in `toml::value` to the user-specified type.
Of course in some case this overhead is not ignorable.
By passing the exact types, `toml::get` returns reference that has nealy zero overhead.
@ -256,7 +283,8 @@ const auto& tab = toml::get<toml::array>(data.at("tab"));
const auto& numbers = toml::get<toml::table>(data.at("numbers"));
```
Unfortunately, in this case you need to call `toml::get` each time you access to the element of `toml::array` because `toml::array` is an array of `toml::value`.
Unfortunately, in this case you need to call `toml::get` each time you access to
the element of `toml::array` because `toml::array` is an array of `toml::value`.
```cpp
const auto& num0 = toml::get<toml::integer>(numbers.at(0));
@ -266,7 +294,9 @@ const auto& num2 = toml::get<toml::integer>(numbers.at(2));
### Datetime and its variants
TOML v0.5.0 has 4 different datetime objects, `local_date`, `local_time`, `local_datetime`, and `offset_datetime`. With toml11, you can convert `local_time` to your favorite `std::chrono::duration` and others to `std::chrono::system_clock::time_point`.
TOML v0.5.0 has 4 different datetime objects, `local_date`, `local_time`,
`local_datetime`, and `offset_datetime`. With toml11, you can convert `local_time`
to your favorite `std::chrono::duration` and others to `std::chrono::system_clock::time_point`.
```toml
time = 12:30:00
@ -291,7 +321,8 @@ const auto value = toml::get_or(data, "key", 42); // value => int 42.
### Expecting conversion
By using `toml::expect`, you will get your expected value or an error message without throwing `toml::type_error`.
By using `toml::expect`, you will get your expected value or an error message
without throwing `toml::type_error`.
```cpp
const auto value = toml::expect<std::string>(data.at("title"));
@ -314,7 +345,9 @@ const auto value = toml::expect<int>(data.at("number"))
### Finding value from table
toml11 provides utility function to find a value from `toml::table`. Of course, you can do this in your own way with `toml::get` because it just searches an `unordered_map` and returns a value if it exists.
toml11 provides utility function to find a value from `toml::table`.
Of course, you can do this in your own way with `toml::get` because
it just searches an `unordered_map` and returns a value if it exists.
```cpp
const auto data = toml::parse("example.toml");
@ -328,7 +361,8 @@ terminate called after throwing an instance of 'std::out_of_range'
what(): [error] key "num" not found in example.toml
```
You can use this with a `toml::value` that is expected to be a `toml::table`. It automatically casts the value to table.
You can use this with a `toml::value` that is expected to be a `toml::table`.
It automatically casts the value to table.
```cpp
const auto data = toml::parse("example.toml");
@ -338,7 +372,8 @@ const auto num = toml::find<int>(data.at("table"), "num");
// num = 42
```
In this case, because the value `data.at("table")` knows the locatoin of itself, you don't need to pass where you find the value. `toml::find` will show you a great error message.
In this case, because the value `data.at("table")` knows the locatoin of itself,
you don't need to pass where you find the value. `toml::find` will show you a great error message.
```console
terminate called after throwing an instance of 'std::out_of_range'
@ -390,7 +425,8 @@ toml::from_toml(i, data.at("something"));
### Sanitizing UTF-8 codepoints
toml11 shows warning if a value of an escape sequence used to represent unicode character exceeds the unicode range.
toml11 shows warning if a value of an escape sequence used
to represent unicode character exceeds the unicode range.
```console
[warning] input codepoint (0011FFFF) is too large to decode as a unicode character. The result may not be able to render to your screen.
@ -479,9 +515,14 @@ The toml types (can be used as `toml::*` in this library) and corresponding `enu
| Array | `std::vector<toml::value>` | `toml::value_t::Array` |
| Table | `std::unordered_map<std::string, toml::key>` | `toml::value_t::Table` |
`toml::string` is effectively the same as `std::string` but has an additional flag that represents a kind of a string, `string_t::basic` and `string_t::literal`. Although `std::string` is not an exact toml type, still you can get a reference that points to internal `std::string` by using `toml::get<std::string>()` for convenience.
`toml::string` is effectively the same as `std::string` but has an additional
flag that represents a kind of a string, `string_t::basic` and `string_t::literal`.
Although `std::string` is not an exact toml type, still you can get a reference
that points to internal `std::string` by using `toml::get<std::string>()` for convenience.
`Datetime` variants are `struct` that are defined in this library. Because `std::chrono::system_clock::time_point` is a __time point__, not capable of representing a Local Time independent from a specific day.
`Datetime` variants are `struct` that are defined in this library.
Because `std::chrono::system_clock::time_point` is a __time point__,
not capable of representing a Local Time independent from a specific day.
It is recommended to get `Datetime`s as `std::chrono` classes through `toml::get`.