おはようございます、高木です。

今年になってから「C++でTcl/Tkのラッパーを作る」の連載を開始しています。
本日初めて目にする方もいらっしゃるかと思いますので、あらためて簡単に趣旨を紹介しておきます。

Tcl/Tkというのは、すごく乱暴に説明すれば、簡単にGUIを作ることができるスクリプト言語環境のことです。
詳細はウィキペディアの記事でも参照してください。

Tcl/Tkのスクリプト言語の環境ですが、本来はCのライブラリです。
これをC++でラッピングしてあげて、お手軽にGUIを作れるようにしようというのが今回の趣旨です。

過去の記事については、専用のカテゴリを作っていますので、順に読んでいくことができるかと思います。

さて、ここからが本題です。
今回の話題はヘッダーファイルと名前空間の構成についてです。

先日の記事で、header-onlyライブラリにする方針に決定したことを書きました。
ライブラリなら何でもそうですが、header-onlyならなおのことヘッダーファイルの構成をどうするかが重要です。

普通に考えると3通りの案が思いつきます。

  1. Tcl_ObjやTcl_Interpなど、Tcl/Tkのデータ構造ごとにラッパークラスとそれを宣言・定義するヘッダーファイルを作る。
  2. 今回の目的がお手軽にGUIを作れるようにすることなので、ヘッダーファイルを1つに統合してしまう。
  3. オリジナルのTcl/Tkがtcl.hとtk.hの2つのヘッダーファイルで構成されているので、それに合わせてTcl用とTk用のヘッダーファイルを作る。

案1.は一番素直な案で、実際、私も最初に試みました。
しかし、クラス間の相互参照が多数発生してしまい、heade-onlyライブラリであれば、結局すべてのほぼすべてのヘッダーファイルをインクルードしないと使えないような状況に陥ってしまったのです。
これではあまりうれしくありませんので、案1.は断念しました。

案2.は簡便さという意味では一番目的にかなっています。
しかしながら、ヘッダーファイルがあまりにも大きくなりすぎるのと、後述する名前空間の構成との関係でやはり断念しました。

結局残った案3.を採用し、tcl.hhとtk.hhの2つのヘッダーファイルを作成することにしました。

ちなみにヘッダーファイルのサフィックス(拡張子)ですが、最近は.hhと.ccを使うようにしています。
加齢のせいもあって目も悪くなってきましたので、.hppと.cppでは見間違えることが多いからです。
.hと.cppというのもありますが、.hではCのヘッダーファイルと区別がつかなくなりますので、これもやめています。
このあたりは好みもありますので、何が正しいということではありませんが、あくまでも私はそうしているということです。

次に名前空間の構成についてです。
名前空間の構成も3案考えました。

  1. tk名前空間に統合する。
  2. tclおよびtk名前空間の2つを作り、ttkはtk::ttkとする。
  3. tcl、tk、およびttk名前空間の3つを作る。

ここで、ttkというのは、外観を設定する「テーマ」を使うことができるウィジェット(GUI部品)群です。
もとはTileという拡張パッケージでしたが、現在はTkに統合されています。

もとのCのライブラリが、Tcl_またはTk_というプレフィックスを付けていましたので、さすがに案1.は違和感が大きく、真っ先に脱落しました。

案2.と3.は迷いましたが、あまりトップレベルの名前空間を増やすのも嫌だったので、結局案2.に落ち着きました。
ただ、念のための保険として、tclやtkをトップレベルの名前空間とするのはやめ、cpp14tk::tclとcpp14tk::tkとした上でcpp14tkはインライン名前空間にしました。

cpp14tkという名前ですが、今回のラッパーライブラリの企画が出た時点での仮称が「C++14/Tk」だったためです。
これは「C++/Tk」と区別するためであり、「C++/Tk」は古いC++規格を前提としていたため、ラムダ式などを積極的に使える仕様を目指す意味でC++14としたのです(C++11でもよかったのですが……)。

これで、ヘッダーファイルと名前空間の構成がひととおり決まりました。
次回からは実際のラッパーの内容に触れていけたらと思います。