aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--COPYING.md24
-rw-r--r--libraries/README.md7
-rw-r--r--libraries/toml11/CMakeLists.txt5
-rw-r--r--libraries/toml11/LICENSE21
-rw-r--r--libraries/toml11/README.md1918
-rw-r--r--libraries/toml11/include/toml.hpp46
-rw-r--r--libraries/toml11/include/toml/color.hpp64
-rw-r--r--libraries/toml11/include/toml/combinator.hpp306
-rw-r--r--libraries/toml11/include/toml/comments.hpp466
-rw-r--r--libraries/toml11/include/toml/datetime.hpp631
-rw-r--r--libraries/toml11/include/toml/exception.hpp65
-rw-r--r--libraries/toml11/include/toml/from.hpp20
-rw-r--r--libraries/toml11/include/toml/get.hpp1068
-rw-r--r--libraries/toml11/include/toml/into.hpp20
-rw-r--r--libraries/toml11/include/toml/lexer.hpp270
-rw-r--r--libraries/toml11/include/toml/literal.hpp112
-rw-r--r--libraries/toml11/include/toml/macros.hpp121
-rw-r--r--libraries/toml11/include/toml/parser.hpp2177
-rw-r--r--libraries/toml11/include/toml/region.hpp417
-rw-r--r--libraries/toml11/include/toml/result.hpp717
-rw-r--r--libraries/toml11/include/toml/serializer.hpp853
-rw-r--r--libraries/toml11/include/toml/source_location.hpp233
-rw-r--r--libraries/toml11/include/toml/storage.hpp43
-rw-r--r--libraries/toml11/include/toml/string.hpp224
-rw-r--r--libraries/toml11/include/toml/traits.hpp300
-rw-r--r--libraries/toml11/include/toml/types.hpp150
-rw-r--r--libraries/toml11/include/toml/utility.hpp93
-rw-r--r--libraries/toml11/include/toml/value.hpp2023
29 files changed, 12395 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1c93e7a9..cfba3430 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -265,6 +265,7 @@ add_subdirectory(libraries/iconfix) # fork of Qt's QIcon loader
add_subdirectory(libraries/LocalPeer) # fork of a library from Qt solutions
add_subdirectory(libraries/classparser) # google analytics library
add_subdirectory(libraries/optional-bare)
+add_subdirectory(libraries/toml11) # toml parser
############################### Built Artifacts ###############################
diff --git a/COPYING.md b/COPYING.md
index c0c98606..ea8fe479 100644
--- a/COPYING.md
+++ b/COPYING.md
@@ -251,3 +251,27 @@
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
+
+# toml11
+
+ The MIT License (MIT)
+
+ Copyright (c) 2017 Toru Niina
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
diff --git a/libraries/README.md b/libraries/README.md
index cdc72004..76ee8c46 100644
--- a/libraries/README.md
+++ b/libraries/README.md
@@ -158,3 +158,10 @@ A Google Analytics library for Qt.
BSD licensed, derived from [qt-google-analytics](https://github.com/HSAnet/qt-google-analytics).
Modifications include better handling of IP anonymization (can be enabled) and general improvements of the API (application handles persistence and ID generation instead of the library).
+
+## toml11
+A C++11 TOML language parser. Used by Forge 1.14+ to store mod metadata.
+
+See [github repo](https://github.com/ToruNiina/toml11).
+
+Licenced under the MIT licence.
diff --git a/libraries/toml11/CMakeLists.txt b/libraries/toml11/CMakeLists.txt
new file mode 100644
index 00000000..556ec150
--- /dev/null
+++ b/libraries/toml11/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.1)
+project(toml11)
+
+add_library(toml11 INTERFACE)
+target_include_directories(toml11 INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include")
diff --git a/libraries/toml11/LICENSE b/libraries/toml11/LICENSE
new file mode 100644
index 00000000..f55c511d
--- /dev/null
+++ b/libraries/toml11/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2017 Toru Niina
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/libraries/toml11/README.md b/libraries/toml11/README.md
new file mode 100644
index 00000000..d5bc1c81
--- /dev/null
+++ b/libraries/toml11/README.md
@@ -0,0 +1,1918 @@
+toml11
+======
+
+[![Build Status on GitHub Actions](https://github.com/ToruNiina/toml11/workflows/build/badge.svg)](https://github.com/ToruNiina/toml11/actions)
+[![Build Status on TravisCI](https://travis-ci.org/ToruNiina/toml11.svg?branch=master)](https://travis-ci.org/ToruNiina/toml11)
+[![Build status on Appveyor](https://ci.appveyor.com/api/projects/status/m2n08a926asvg5mg/branch/master?svg=true)](https://ci.appveyor.com/project/ToruNiina/toml11/branch/master)
+[![Build status on CircleCI](https://circleci.com/gh/ToruNiina/toml11/tree/master.svg?style=svg)](https://circleci.com/gh/ToruNiina/toml11/tree/master)
+[![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 is a C++11 (or later) header-only toml parser/encoder depending only on C++ standard library.
+
+- It is compatible to the latest version of [TOML v1.0.0](https://toml.io/en/v1.0.0).
+- It is one of the most TOML standard compliant libraries, tested with [the language agnostic test suite for TOML parsers by BurntSushi](https://github.com/BurntSushi/toml-test).
+- It shows highly informative error messages. You can see the error messages about invalid files at [CircleCI](https://circleci.com/gh/ToruNiina/toml11).
+- It has configurable container. You can use any random-access containers and key-value maps as backend containers.
+- It optionally preserves comments without any overhead.
+- It has configurable serializer that supports comments, inline tables, literal strings and multiline strings.
+- It supports user-defined type conversion from/into toml values.
+- It correctly handles UTF-8 sequences, with or without BOM, both on posix and Windows.
+
+## Example
+
+```cpp
+#include <toml.hpp>
+#include <iostream>
+
+int main()
+{
+ // ```toml
+ // title = "an example toml file"
+ // nums = [3, 1, 4, 1, 5]
+ // ```
+ auto data = toml::parse("example.toml");
+
+ // find a value with the specified type from a table
+ std::string title = toml::find<std::string>(data, "title");
+
+ // convert the whole array into any container automatically
+ std::vector<int> nums = toml::find<std::vector<int>>(data, "nums");
+
+ // access with STL-like manner
+ if(not data.contains("foo"))
+ {
+ data["foo"] = "bar";
+ }
+
+ // pass a fallback
+ std::string name = toml::find_or<std::string>(data, "name", "not found");
+
+ // width-dependent formatting
+ std::cout << std::setw(80) << data << std::endl;
+
+ return 0;
+}
+```
+
+## Table of Contents
+
+- [Integration](#integration)
+- [Decoding a toml file](#decoding-a-toml-file)
+ - [In the case of syntax error](#in-the-case-of-syntax-error)
+ - [Invalid UTF-8 Codepoints](#invalid-utf-8-codepoints)
+- [Finding a toml value](#finding-a-toml-value)
+ - [Finding a value in a table](#finding-a-value-in-a-table)
+ - [In case of error](#in-case-of-error)
+ - [Dotted keys](#dotted-keys)
+- [Casting a toml value](#casting-a-toml-value)
+- [Checking value type](#checking-value-type)
+- [More about conversion](#more-about-conversion)
+ - [Converting an array](#converting-an-array)
+ - [Converting a table](#converting-a-table)
+ - [Getting an array of tables](#getting-an-array-of-tables)
+ - [Cost of conversion](#cost-of-conversion)
+ - [Converting datetime and its variants](#converting-datetime-and-its-variants)
+- [Getting with a fallback](#getting-with-a-fallback)
+- [Expecting conversion](#expecting-conversion)
+- [Visiting a toml::value](#visiting-a-tomlvalue)
+- [Constructing a toml::value](#constructing-a-tomlvalue)
+- [Preserving Comments](#preserving-comments)
+- [Customizing containers](#customizing-containers)
+- [TOML literal](#toml-literal)
+- [Conversion between toml value and arbitrary types](#conversion-between-toml-value-and-arbitrary-types)
+- [Formatting user-defined error messages](#formatting-user-defined-error-messages)
+- [Obtaining location information](#obtaining-location-information)
+- [Exceptions](#exceptions)
+- [Colorize Error Messages](#colorize-error-messages)
+- [Serializing TOML data](#serializing-toml-data)
+- [Underlying types](#underlying-types)
+- [Unreleased TOML features](#unreleased-toml-features)
+- [Breaking Changes from v2](#breaking-changes-from-v2)
+- [Running Tests](#running-tests)
+- [Contributors](#contributors)
+- [Licensing Terms](#licensing-terms)
+
+## Integration
+
+Just include the file after adding it to the include path.
+
+```cpp
+#include <toml.hpp> // that's all! now you can use it.
+#include <iostream>
+
+int main()
+{
+ const auto data = toml::parse("example.toml");
+ const auto title = toml::find<std::string>(data, "title");
+ std::cout << "the title is " << title << std::endl;
+ return 0;
+}
+```
+
+The convenient way is to add this repository as a git-submodule or to install
+it in your system by CMake.
+
+Note for MSVC: We recommend to set `/Zc:__cplusplus` to detect C++ version correctly.
+
+## Decoding a toml file
+
+To parse a toml file, the only thing you have to do is
+to pass a filename to the `toml::parse` function.
+
+```cpp
+const std::string fname("sample.toml");
+const toml::value data = toml::parse(fname);
+```
+
+As required by the TOML specification, the top-level value is always a table.
+You can find a value inside it, cast it into a table explicitly, and insert it as a value into other `toml::value`.
+
+If it encounters an error while opening a file, it will throw `std::runtime_error`.
+
+You can also pass a `std::istream` to the `toml::parse` function.
+To show a filename in an error message, however, it is recommended to pass the
+filename with the stream.
+
+```cpp
+std::ifstream ifs("sample.toml", std::ios_base::binary);
+assert(ifs.good());
+const auto data = toml::parse(ifs, /*optional -> */ "sample.toml");
+```
+
+**Note**: When you are **on Windows, open a file in binary mode**.
+If a file is opened in text-mode, CRLF ("\r\n") will automatically be
+converted to LF ("\n") and this causes inconsistency between file size
+and the contents that would be read. This causes weird error.
+
+### In the case of syntax error
+
+If there is a syntax error in a toml file, `toml::parse` will throw
+`toml::syntax_error` that inherits `std::exception`.
+
+toml11 has clean and informative error messages inspired by Rust and
+it looks like the following.
+
+```console
+terminate called after throwing an instance of 'toml::syntax_error'
+ what(): [error] toml::parse_table: invalid line format # error description
+ --> example.toml # file name
+ 3 | a = 42 = true # line num and content
+ | ^------ expected newline, but got '='. # error reason
+```
+
+If you (mistakenly) duplicate tables and got an error, it is helpful to see
+where they are. toml11 shows both at the same time like the following.
+
+```console
+terminate called after throwing an instance of 'toml::syntax_error'
+ what(): [error] toml::insert_value: table ("table") already exists.
+ --> duplicate-table.toml
+ 1 | [table]
+ | ~~~~~~~ table already exists here
+ ...
+ 3 | [table]
+ | ~~~~~~~ table defined twice
+```
+
+When toml11 encounters a malformed value, it tries to detect what type it is.
+Then it shows hints to fix the format. An error message while reading one of
+the malformed files in [the language agnostic test suite](https://github.com/BurntSushi/toml-test).
+is shown below.
+
+```console
+what(): [error] bad time: should be HH:MM:SS.subsec
+ --> ./datetime-malformed-no-secs.toml
+ 1 | no-secs = 1987-07-05T17:45Z
+ | ^------- HH:MM:SS.subsec
+ |
+Hint: pass: 1979-05-27T07:32:00, 1979-05-27 07:32:00.999999
+Hint: fail: 1979-05-27T7:32:00, 1979-05-27 17:32
+```
+
+You can find other examples in a job named `output_result` on
+[CircleCI](https://circleci.com/gh/ToruNiina/toml11).
+
+Since the error message generation is generally a difficult task, the current
+status is not ideal. If you encounter a weird error message, please let us know
+and contribute to improve the quality!
+
+### Invalid UTF-8 codepoints
+
+It throws `syntax_error` if a value of an escape sequence
+representing unicode character is not a valid UTF-8 codepoint.
+
+```console
+ what(): [error] toml::read_utf8_codepoint: input codepoint is too large.
+ --> utf8.toml
+ 1 | exceeds_unicode = "\U0011FFFF example"
+ | ^--------- should be in [0x00..0x10FFFF]
+```
+
+## Finding a toml value
+
+After parsing successfully, you can obtain the values from the result of
+`toml::parse` using `toml::find` function.
+
+```toml
+# sample.toml
+answer = 42
+pi = 3.14
+numbers = [1,2,3]
+time = 1979-05-27T07:32:00Z
+```
+
+``` cpp
+const auto data = toml::parse("sample.toml");
+const auto answer = toml::find<std::int64_t >(data, "answer");
+const auto pi = toml::find<double >(data, "pi");
+const auto numbers = toml::find<std::vector<int>>(data, "numbers");
+const auto timepoint = toml::find<std::chrono::system_clock::time_point>(data, "time");
+```
+
+By default, `toml::find` returns a `toml::value`.
+
+```cpp
+const toml::value& answer = toml::find(data, "answer");
+```
+
+When you pass an exact TOML type that does not require type conversion,
+`toml::find` returns a reference without copying the value.
+
+```cpp
+const auto data = toml::parse("sample.toml");
+const auto& answer = toml::find<toml::integer>(data, "answer");
+```
+
+If the specified type requires conversion, you can't take a reference to the value.
+See also [underlying types](#underlying-types).
+
+**NOTE**: For some technical reason, automatic conversion between `integer` and
+`floating` is not supported. If you want to get a floating value even if a value
+has integer value, you need to convert it manually after obtaining a value,
+like the followings.
+
+```cpp
+const auto vx = toml::find(data, "x");
+double x = vx.is_floating() ? vx.as_floating(std::nothrow) :
+ static_cast<double>(vx.as_integer()); // it throws if vx is neither
+ // floating nor integer.
+```
+
+### Finding a value in a table
+
+There are several way to get a value defined in a table.
+First, you can get a table as a normal value and find a value from the table.
+
+```toml
+[fruit]
+name = "apple"
+[fruit.physical]
+color = "red"
+shape = "round"
+```
+
+``` cpp
+const auto data = toml::parse("fruit.toml");
+const auto& fruit = toml::find(data, "fruit");
+const auto name = toml::find<std::string>(fruit, "name");
+
+const auto& physical = toml::find(fruit, "physical");
+const auto color = toml::find<std::string>(physical, "color");
+const auto shape = toml::find<std::string>(physical, "shape");
+```
+
+Here, variable `fruit` is a `toml::value` and can be used as the first argument
+of `toml::find`.
+
+Second, you can pass as many arguments as the number of subtables to `toml::find`.
+
+```cpp
+const auto data = toml::parse("fruit.toml");
+const auto color = toml::find<std::string>(data, "fruit", "physical", "color");
+const auto shape = toml::find<std::string>(data, "fruit", "physical", "shape");
+```
+
+### Finding a value in an array
+
+You can find n-th value in an array by `toml::find`.
+
+```toml
+values = ["foo", "bar", "baz"]
+```
+
+``` cpp
+const auto data = toml::parse("sample.toml");
+const auto values = toml::find(data, "values");
+const auto bar = toml::find<std::string>(values, 1);
+```
+
+`toml::find` can also search array recursively.
+
+```cpp
+const auto data = toml::parse("fruit.toml");
+const auto bar = toml::find<std::string>(data, "values", 1);
+```
+
+Before calling `toml::find`, you can check if a value corresponding to a key
+exists. You can use both `bool toml::value::contains(const key&) const` and
+`std::size_t toml::value::count(const key&) const`. Those behaves like the
+`std::map::contains` and `std::map::count`.
+
+```cpp
+const auto data = toml::parse("fruit.toml");
+if(data.contains("fruit") && data.at("fruit").count("physical") != 0)
+{
+ // ...
+}
+```
+
+### In case of error
+
+If the value does not exist, `toml::find` throws `std::out_of_range` with the
+location of the table.
+
+```console
+terminate called after throwing an instance of 'std::out_of_range'
+ what(): [error] key "answer" not found
+ --> example.toml
+ 6 | [tab]
+ | ~~~~~ in this table
+```
+
+----
+
+If the specified type differs from the actual value contained, it throws
+`toml::type_error` that inherits `std::exception`.
+
+Similar to the case of syntax error, toml11 also displays clean 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'
+ what(): [error] toml::value bad_cast to integer
+ --> example.toml
+ 3 | title = "TOML Example"
+ | ~~~~~~~~~~~~~~ the actual type is string
+```
+
+**NOTE**: In order to show this kind of error message, all the toml values have
+a pointer to represent its range in a file. The entire contents of a file is
+shared by `toml::value`s and remains on the heap memory. It is recommended to
+destruct all the `toml::value` classes after configuring your application
+if you have a large TOML file compared to the memory resource.
+
+### 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
+physical.color = "orange"
+physical.shape = "round"
+```
+
+This is equivalent to the following.
+
+```toml
+[physical]
+color = "orange"
+shape = "round"
+```
+
+You can get both of the above tables with the same c++ code.
+
+```cpp
+const auto physical = toml::find(data, "physical");
+const auto color = toml::find<std::string>(physical, "color");
+```
+
+The following code does not work for the above toml file.
+
+```cpp
+// XXX this does not work!
+const auto color = toml::find<std::string>(data, "physical.color");
+```
+
+The above code works with the following toml file.
+
+```toml
+"physical.color" = "orange"
+# equivalent to {"physical.color": "orange"},
+# NOT {"physical": {"color": "orange"}}.
+```
+
+
+## Casting a toml value
+
+### `toml::get`
+
+`toml::parse` returns `toml::value`. `toml::value` is a union type that can
+contain one of the following types.
+
+- `toml::boolean` (`bool`)
+- `toml::integer` (`std::int64_t`)
+- `toml::floating` (`double`)
+- `toml::string` (a type convertible to std::string)
+- `toml::local_date`
+- `toml::local_time`
+- `toml::local_datetime`
+- `toml::offset_datetime`
+- `toml::array` (by default, `std::vector<toml::value>`)
+ - It depends. See [customizing containers](#customizing-containers) for detail.
+- `toml::table` (by default, `std::unordered_map<toml::key, toml::value>`)
+ - It depends. See [customizing containers](#customizing-containers) for detail.
+
+To get a value inside, you can use `toml::get<T>()`. The usage is the same as
+`toml::find<T>` (actually, `toml::find` internally uses `toml::get` after casting
+a value to `toml::table`).
+
+``` cpp
+const toml::value data = toml::parse("sample.toml");
+const toml::value answer_ = toml::get<toml::table >(data).at("answer");
+const std::int64_t answer = toml::get<std::int64_t>(answer_);
+```
+
+When you pass an exact TOML type that does not require type conversion,
+`toml::get` returns a reference through which you can modify the content
+(if the `toml::value` is `const`, it returns `const` reference).
+
+```cpp
+toml::value data = toml::parse("sample.toml");
+toml::value answer_ = toml::get<toml::table >(data).at("answer");
+toml::integer& answer = toml::get<toml::integer>(answer_);
+answer = 6 * 9; // write to data.answer. now `answer_` contains 54.
+```
+
+If the specified type requires conversion, you can't take a reference to the value.
+See also [underlying types](#underlying-types).
+
+It also throws a `toml::type_error` if the type differs.
+
+### `as_xxx`
+
+You can also use a member function to cast a value.
+
+```cpp
+const std::int64_t answer = data.as_table().at("answer").as_integer();
+```
+
+It also throws a `toml::type_error` if the type differs. If you are sure that
+the value `v` contains a value of the specified type, you can suppress checking
+by passing `std::nothrow`.
+
+```cpp
+const auto& answer = data.as_table().at("answer");
+if(answer.is_integer() && answer.as_integer(std::nothrow) == 42)
+{
+ std::cout << "value is 42" << std::endl;
+}
+```
+
+If `std::nothrow` is passed, the functions are marked as noexcept.
+
+By casting a `toml::value` into an array or a table, you can iterate over the
+elements.
+
+```cpp
+const auto data = toml::parse("example.toml");
+std::cout << "keys in the top-level table are the following: \n";
+for(const auto& [k, v] : data.as_table())
+{
+ std::cout << k << '\n';
+}
+
+const auto& fruits = toml::find(data, "fruits");
+for(const auto& v : fruits.as_array())
+{
+ std::cout << toml::find<std::string>(v, "name") << '\n';
+}
+```
+
+The full list of the functions is below.
+
+```cpp
+namespace toml {
+class value {
+ // ...
+ const boolean& as_boolean() const&;
+ const integer& as_integer() const&;
+ const floating& as_floating() const&;
+ const string& as_string() const&;
+ const offset_datetime& as_offset_datetime() const&;
+ const local_datetime& as_local_datetime() const&;
+ const local_date& as_local_date() const&;
+ const local_time& as_local_time() const&;
+ const array& as_array() const&;
+ const table& as_table() const&;
+ // --------------------------------------------------------
+ // non-const version
+ boolean& as_boolean() &;
+ // ditto...
+ // --------------------------------------------------------
+ // rvalue version
+ boolean&& as_boolean() &&;
+ // ditto...
+
+ // --------------------------------------------------------
+ // noexcept versions ...
+ const boolean& as_boolean(const std::nothrow_t&) const& noexcept;
+ boolean& as_boolean(const std::nothrow_t&) & noexcept;
+ boolean&& as_boolean(const std::nothrow_t&) && noexcept;
+ // ditto...
+};
+} // toml
+```
+
+### `at()`
+
+You can access to the element of a table and an array by `toml::basic_value::at`.
+
+```cpp
+const toml::value v{1,2,3,4,5};
+std::cout << v.at(2).as_integer() << std::endl; // 3
+
+const toml::value v{{"foo", 42}, {"bar", 3.14}};
+std::cout << v.at("foo").as_integer() << std::endl; // 42
+```
+
+If an invalid key (integer for a table, string for an array), it throws
+`toml::type_error` for the conversion. If the provided key is out-of-range,
+it throws `std::out_of_range`.
+
+Note that, although `std::string` has `at()` member function, `toml::value::at`
+throws if the contained type is a string. Because `std::string` does not
+contain `toml::value`.
+
+### `operator[]`
+
+You can also access to the element of a table and an array by
+`toml::basic_value::operator[]`.
+
+```cpp
+const toml::value v{1,2,3,4,5};
+std::cout << v[2].as_integer() << std::endl; // 3
+
+const toml::value v{{"foo", 42}, {"bar", 3.14}};
+std::cout << v["foo"].as_integer() << std::endl; // 42
+```
+
+When you access to a `toml::value` that is not initialized yet via
+`operator[](const std::string&)`, the `toml::value` will be a table,
+just like the `std::map`.
+
+```cpp
+toml::value v; // not initialized as a table.
+v["foo"] = 42; // OK. `v` will be a table.
+```
+
+Contrary, if you access to a `toml::value` that contains an array via `operator[]`,
+it does not check anything. It converts `toml::value` without type check and then
+access to the n-th element without boundary check, just like the `std::vector::operator[]`.
+
+```cpp
+toml::value v; // not initialized as an array
+v[2] = 42; // error! UB
+```
+
+Please make sure that the `toml::value` has an array inside when you access to
+its element via `operator[]`.
+
+## Checking value type
+
+You can check the type of a value by `is_xxx` function.
+
+```cpp
+const toml::value v = /* ... */;
+if(v.is_integer())
+{
+ std::cout << "value is an integer" << std::endl;
+}
+```
+
+The complete list of the functions is below.
+
+```cpp
+namespace toml {
+class value {
+ // ...
+ 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;
+ bool is_uninitialized() const noexcept;
+ // ...
+};
+} // toml
+```
+
+Also, you can get `enum class value_t` from `toml::value::type()`.
+
+```cpp
+switch(data.at("something").type())
+{
+ case toml::value_t::integer: /*do some stuff*/ ; break;
+ case toml::value_t::floating: /*do some stuff*/ ; break;
+ case toml::value_t::string : /*do some stuff*/ ; break;
+ default : throw std::runtime_error(
+ "unexpected type : " + toml::stringize(data.at("something").type()));
+}
+```
+
+The complete list of the `enum`s can be found in the section
+[underlying types](#underlying-types).
+
+The `enum`s can be used as a parameter of `toml::value::is` function like the following.
+
+```cpp
+toml::value v = /* ... */;
+if(v.is(toml::value_t::boolean)) // ...
+```
+
+## More about conversion
+
+Since `toml::find` internally uses `toml::get`, all the following examples work
+with both `toml::get` and `toml::find`.
+
+### Converting an array
+
+You can get any kind of `container` class from a `toml::array`
+except for `map`-like classes.
+
+``` cpp
+// # sample.toml
+// numbers = [1,2,3]
+
+const auto numbers = toml::find(data, "numbers");
+
+const auto vc = toml::get<std::vector<int> >(numbers);
+const auto ls = toml::get<std::list<int> >(numbers);
+const auto dq = toml::get<std::deque<int> >(numbers);
+const auto ar = toml::get<std::array<int, 3>>(numbers);
+// if the size of data.at("numbers") is larger than that of std::array,
+// it will throw toml::type_error because std::array is not resizable.
+```
+
+Surprisingly, you can convert `toml::array` into `std::pair` and `std::tuple`.
+
+```cpp
+// numbers = [1,2,3]
+const auto tp = toml::get<std::tuple<short, int, unsigned int>>(numbers);
+```
+
+This functionality is helpful when you have a toml file like the following.
+
+```toml
+array_of_arrays = [[1, 2, 3], ["foo", "bar", "baz"]] # toml allows this
+```
+
+What is the corresponding C++ type?
+Obviously, it is a `std::pair` of `std::vector`s.
+
+```cpp
+const auto array_of_arrays = toml::find(data, "array_of_arrays");
+const auto aofa = toml::get<
+ std::pair<std::vector<int>, std::vector<std::string>>
+ >(array_of_arrays);