toml11以前「やりたいな〜」と書いた通りの変更をゴリっと入れてみた。マージしていないが、v3ブランチがpushされている。今まで通していたテストは全て通った。追加機能のテストも最低限は通った。テストの拡充をしてからベータ版を出すつもりでいる。github.com主な変更点は以下の通りだ。value_tの名前、is_xxxやas_xxxの名前がsnake_caseに統一されるいくつかの便利関数のtoml::table向けオーバーロードが消え、toml::value版に統一されるコメント取得に関わるインターフェースが整理されるあまり使い勝手のよくなかった古の隠し機能、froml_tomlとinto_tomlが消される(ユーザー定義型変換サポートが入ったので)シンプルな使い方をしていたなら乗り換えコストは小さい方だと思う。事実、以下のコードは一切の乗り換えコストがない。どちらのバージョンでも動く。"vals");が、とはいえこれは結構大きな変更なので、どうしてこうなったのか理由を書いておきたい。toml11の歴史はたった3年だが、私のC++の経験(今年で5年め)と比べるとこの3年は長いのだ。最初期はUpperCamelCaseを使っていたこれがまずある。してsnake_caseの方を好むようになってしまって、段階的に移行したいと思うようになった。そのためにバージョン2では型名にエイリアスを貼って両方サポートするようにし、READMEではsnake_caseを推していくことで移行を狙っていた。これのせいで少し厄介なことが起きていた。TOML公式レポジトリでは浮動小数点数はFloatと呼ばれている。キャメルケースを使っているならこれをそのまま使えばよかったのだが、困ったことにfloatはキーワードだ。スネークケースの型名はfloatingになるしかない。すると、is_floatやas_floatがややこしい。自分でもどっちだったか忘れることがあるのに、ユーザーが使いやすいわけがない。型情報のenumは(エイリアスが作れないので)キャメルケースのままだった。使いにくいことこの上ない。何かメジャーアップデートをすることがあればぜひ直したいと思っていた。ユーザーインターフェースの統一感は何より重要だと思っている。この名前を完全に統一するのは良いライブラリの必要条件だ。いうわけで、思い切って型名は全て統一するようにした。書くと当たり前のことすぎて「何行ってんだこいつ」だが......。v2で始まった型名の移行を完了する、と表現した方が妥当かも知れない。unionという存在で、ほとんど機能を持っていなかった。これは、私が何かを提供するよりも、慣れ親しんだSTLコンテナに即変換できる型を使うことで学習コストが減るのではないかと期待してのことだった。使ってみると、少なくとも私にとっては、ユーザー(私だが)定義関数を使って呼ぶのは少し面倒だし見た目も少し不恰好な気がして、大半の用途ならそれだけで事足りるような便利関数をいくつか用意してもいいかもなと思うようになった。いうわけで実装していったのだが、バージョン2で新機能を一つ追加するたびにtoml::valueの重要性が増していく。そのままの流れで、toml::valueはこのライブラリの中で重要な位置を占めるようになり、逆にそれ単体での機能の弱さや、他の関数で中心に据えられていないのがアンバランスになった。toml::value中心に据えられていない一番アンバランスな箇所は、toml::parseの戻り値だ。これはtoml::tableを返す。確かにTOMLのファイルはテーブルと一対一対応するような構造になっているが、toml::tableはtoml::valueが持つような追加の情報を一切持てない上、このせいで関数のオーバーロードを多めに持たないといけなかったり、型変換のせいでオーバーロード解決が曖昧になったりして目の上のたんこぶだった。勇気が出ていなかったが、逆に変更するなら今しかないので、これも思い切って入れた。toml::valueをカスタマイズできるようにした実を言うと上の二つは大きな要因ではあるがバージョンアップを決意した直接の要因ではない。勇気が出た理由はこれだ。何ができるようになったかと言うと、テーブルや配列型として使えるコンテナクラスが交換可能になり、さらにコメントを保持するかどうかも決められるようになった。これは「コメント保持して変更してシリアライズできない?」と言うIssueに対して考えた策を発展させたものだ。コメントを持つとなると、追加の文字列か何かを持つ必要がある。文字列は無視できるほど軽いものではない。コメントなんかいらねーよ、と言うユーザーには負担を掛けずにコメントを使う理由のあるユーザーのサポートをするには、toml::valueを分裂させる他なかった。basic_string<char>;のように、テンプレート化されたクラスのデフォルト型を使うというものにしかならないと思う。あ、いや継承してもいいのか。コメントを入れられるコンテナを二つ用意しておいて、片方は普通に一行ずつコメントが入っているコンテナ、もう片方は永遠に空のままで無視できるサイズしかないコンテナにする。これを使い分ければ、どちらにも必要最低限の負担しかかからない。以下のようなインターフェースにすればわかりやすかろう。toml::parse<toml::preserve_comments>("sample.toml");こうすると今までと違ってコメント専用コンテナが(保持することを選んだ場合のみ)toml::valueに追加されることになるので、あとで変更できるし、シリアライズもできる。実際、シリアライズするときにコメントが保持されているかのテストも行なっている。使い道の幅が広がるのではないだろうか。これを入れるなら、ついでに他の型も変えられるようにするといいだろう。Boost.Container、使えるんじゃないかと思う)、アレイの実装をstd::vectorとstd::dequeを選べるように(他はテストしていないが(略))した。なってくると、新バージョンの目玉機能ができることになるので、整理だけのためにユーザーに不便を強いることにはならない。考えるとここでいっちょ整理してもいいのではないかと思ったのだ。これが、toml::parseの戻り値型を変えたいと思った最後のひと押しになった。toml::tableはただのunordered_mapなので、追加の情報は持てない。実際には、「ファイルの先頭のコメント」のようなそこにしか入れられない情報というものはある。toml::valueを返すようにすれば、ファイルのルートにもこのような情報を持たせることができるようになる。この後押しがあったので、続く一連のインターフェースの整理を始める気になった。整理のメリットまず、これまではtoml::tableとtoml::valueの暗黙変換を許していた。これは、何度も葛藤があったのだが、やはりexplicitにすると様々なところで「えっこれできないの!?」となってしまったので、渋々implicitにしていた。これはv3でも変わらない。これのせいで、いくつかの便利関数のオーバーロードが複雑になっていた。toml::findはtoml::valueもtoml::tableも受け取る。これもtoml::parseがtoml::tableを返すためだ。対してtoml::findは型を指定しなかった場合はtoml::valueを返すので、以下のようなコードを実現するにはそうせざるを得なかった。toml::valueの暗黙型変換をすればマッチするようなオーバーロード」がオーバーロード解決に参戦してくる。これが非常に厄介だった。頑張ったが、避けられない部分は出てきて、実際にIssueも立っている。toml::parseがtoml::valueを返すようになっていたらtoml::tableのサポートは最低限で済んだのに、と何回も思った。toml::tableはstd::unordered_mapなので、理論上はユーザーは(私が提供できるような)どんな便利関数も自分で実装できる。toml::valueは私が定義した型なので、それを外部から使うにはまともなAPIによる十分なサポートが不可欠だ。この問題は、全ての箇所でtoml::valueを優先することによって一応の解決を見た。逆にtoml::tableのサポートはほぼdropされる。いえ上に書いたコード片は(全ての箇所でautoを使っているので)そのまま動く。聞いた印象よりは、実際の影響範囲は少ないと思う。その他雑多なことあとやらないとなーと思っていることとして、以下のようなのがある。ビルド済みライブラリを作れるようにするメタ関数を結構使っている上にSFINAEでオーバーロードを操作したりしているので、コンパイル時間が結構長い。コンパイル時間を短縮するためにライブラリをビルドできるようにしてもいいかもしれない。templateみたいなのをマクロで出し分けて、必要な人だけリンクするようにすればいいのではないかなあと思っている。これは新機能なので別にv3を出してから追加しても構わないだろうと思っている。Boost.Testのバージョンアップに追従する以前やろうとして、CIがうまく行かなくてやめていたのだが、CI力が付いてきているので多分今ならいける。テストを書いてしまっているので、いちいち関数を変更していくのがタルい。自分のライブラリはメジャーアップデートしようとしておきながら中で古いバージョンのライブラリを使い続けてるのちょっとダメな気がするので、これは(ユーザーには何の違いももたらさない割には)実は自分の中では比較的優先度が高い。まとめ数ヶ月中を目標にv3ででかい変更が来るよ新機能としてtoml::valueがかなりカスタマイズできるようになるよコメントを取得していじり回した後にシリアライズできるようになるよインターフェースが整理されて、統一感が上がってついでに既知のバグも解決したよ実はちょっと前にv2系のマイナーアップデートを出してて、バグ修正とか、エラーメッセージにヒントを足したり、v3で廃止される関数のいくつかがdeprecatedされたりしてるよまあ多分、今回みたいな変更は向こう数年は入らないと思う。だいたい不満だったことは解決してしまったので、TOML側がすごい変更を入れて来たりするか、私が過激派になってビルドにC++20を要求するようになったりしない限り、内部実装を除けばこれで概ね色々解決しただろうと思う。細かいアップデートはまた入ると思うけど。使ってくれてる人は、これからもちょいちょいレポジトリを見に行ってやってください。v3ができてきたTweet広告を非表示にする関連記事2019-10-19toml11をマイナーアップデートしたしばらく前だが、アップデートした。(7)はてなブログをはじめよう!tniinaさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。