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 work with C++98 & Boost.
To show a better error message, it is recommended to pass 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).
Since the error message generation is generally a difficult task, the current status is not ideal. toml11 need your help. If you encounter a weird error message, please let us know and improve the quality!
If you choose the invalid type, `toml::type_error` will be thrown. Similar to the `syntax_error`, toml11 also displays informative error message. The error message when you choose `int` to get `string` value would be like this.
NOTE: In order to show this kind of error message, all the toml values has 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 the memory resource.
`toml::table` is a key component of this library, that 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.
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`.
For the case that all the values of the table have the same type, toml11 allows you to convert `toml::table` to `map`s that contains the convertible type.
```toml
[tab]
key1 = "foo" # all the values are
key2 = "bar" # toml String
```
```cpp
const auto tab = toml::get<std::map<std::string,std::string>>(data.at("tab"));
const auto aot1 = toml::get<std::vector<toml::table>>(data.at("array_of_inline_table"));
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 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.
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`.
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`.
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 `unordered_map` and returns a value if exists.
```cpp
const auto data = toml::parse("example.toml");
const auto num = toml::find<int>(data, "num", /*for err msg*/"example.toml");
```
If the value does not exist, it throws `std::out_of_range` with informative error message.
```console
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.
```cpp
const auto data = toml::parse("example.toml");
const auto num = toml::find<int>(data.at("table"), "num");
// expecting the following example.toml
// [table]
// 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.
```console
terminate called after throwing an instance of 'std::out_of_range'
what(): [error] key "num" not found
--> example.toml
3 | [table]
| ~~~~~~~ in this table
```
If it's not a `toml::table`, the same error as "invalid type" would be thrown.
`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, but still you can get a reference that points internal `std::string` by using `toml::get<std::string>()` for the 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.
It is recommended to get `Datetime`s as `std::chrono` classes through `toml::get`.