こんにちは、高木です。

前回、ジオメトリーマネージャーのサブコマンドであるinfoやslavesに対応するメンバー関数を実装しましたが、それらが結果として返すのはリストでした。今回はそのリストの扱いについて考えていくことにします。

前回も少しだけ触れたように、リストの要素数と要素の列を取得するにはTcl_ListObjGetElements関数を使います。ほかにもTcl_ListObjLength関数を使えば要素数だけを取得できますし、Tcl_ListObjIndex関数を使えば1要素ずつ取り出せるのですが、Tcl_ListObjGetElements関数を常に使っても問題ないと思います。

まずはTcl_ListObjGetElements関数の使い方を簡単に見ていくことにしましょう。

こういう感じで呼び出せば、objcにリストの要素数が、objvにリストの要素の列が格納されます。

objvに格納されるのはあくまでも生のTcl_Obj*の列ですので、tcl::obj型の列に直すには自分でコードを書く必要があります。

ただ、実際には生のTcl_Obj*が必要になるケースの方が多いように思いますので、変にラッパー関数を作らない方がいいのかもしれませんね。

tcl::obj型として要素を取り出したいのであれば、生のTcl_Obj*型からtcl::obj型には暗黙的に変換されますので、取り出した結果をtcl::obj型の変数に代入すればOKです。

ところで、objvに格納されるポインター値ですが、Tcl_Obj型が内部で保持している配列の先頭要素へのポインターなので自分で明示的に解放する必要は内容です。

得られたTcl_Obj*の列を明示的に解放する必要がないのであれば、std::spanを使って前回作ったメンバー関数を次のように書き換えてもいいかもしれません。

結果をtcl::obj型で返すと、それがリストかどうかがパッと見ではわかりにくいので、こっちの方がいいでしょうね。slavesメンバー関数も同様に変更していいと思います。

次回からは個別のジオメトリーマネージャーについて考えていくことにします。まずはpackerから手をつけていく予定です。