doc: add reference manual

This commit is contained in:
ToruNiina
2024-06-15 19:27:42 +09:00
parent 7210e708a6
commit 64197caa05
77 changed files with 18139 additions and 0 deletions

View File

@@ -0,0 +1,313 @@
+++
title = "changelog"
type = "docs"
weight = 4
+++
# Change Log
# v3からの変化
## 破壊的変更
### `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では、リファレンスを追加したドキュメントを同梱し、また日本語・英語両方で同一の内容を記載します。
ただし、ライブラリ作者は日本語母語話者であるため、日本語の内容を第一とし、英語の内容がそれと異なっていた場合は日本語の内容が正しいものとします。