TOMLファイルを出力する #
toml::format
を使うと、 toml::value
を文字列にすることができます。
#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>
を渡すことができます。
#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
のリファレンスを、
フォーマット情報クラスの完全なリストと詳細は
formatのリファレンスを
参照してください。
整数のフォーマットを指定する #
整数は、基数と幅、そして _
の位置を指定することができます。
hex
, oct
, bin
のとき、指定された幅に達するまでゼロで埋められます。
dec
の場合は幅指定はスペースを追加しますが、これはパースされません。
#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 を参照してください。
配列を単一行・複数行にする #
配列には、 toml::array_format::oneline
や toml::array_format::multiline
を指定できます。
# 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
が選択できます。
インデントに使用する文字種は統一してください。
一つのファイル内でインデントに異なる文字種が指定された場合、結果は未規定になります。 何らかのインデントがされますが、全ての箇所で文字種やインデントの深さは不定となります。
また、 array
の要素が全て table_type
を持つ場合、
toml::array_format::array_of_tables
が指定できます。
array_of_tables
を指定せずに multiline
にした場合、テーブルはインラインテーブルになります。
# 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 を参照してください。
テーブルをインラインテーブルにする #
テーブルをインラインテーブルにする際は toml::table_format::oneline
を指定します。
通常のテーブルにする際は、 toml::table_format::multiline
を指定します。
oneline = {a = 42, b = "foo"}
[multiline]
a = 42
b = "foo"
TOML v1.1.0ではインラインテーブル内での改行が許可されますが、その場合は
toml::table_format::multiline_oneline
とします。
これは、後述するTOMLバージョン指定で対応する機能フラグがtrue
になっていない限り無視されます。
multiline_oneline = {
a = 42,
b = "foo"
}
詳細は、reference を参照してください。
TOML言語バージョンを指定して出力する #
TOML v1.1.0で許可されたインラインテーブル内の改行や\x
エスケープシーケンスのように、
TOMLバージョンによって使用できない言語機能があります。
toml::format
は最後の引数に toml::spec
を取ることができます。
これにより、シリアライズ時に使用するTOMLのバージョンを指定することができます。
特に、 toml::parse
で toml::spec
を使用して新機能を使用した場合は、
パースした値がそのバージョンでしか使えないフォーマット情報を持つ場合があるので、
toml::format
にも同じ toml::spec
を渡すことを忘れないようにしてください。
#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;
}