こんにちは、高木です。
ちょっと前に関数宣言をC++にも対応するように拡張しました。今回は同様にして構造体の生成も拡張することにします。基本的な方向性は関数のときと同じですので、まずは以前に作った構造体の型情報を定義した配列を次のように拡張します。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php $person_type = [ 'name' => 'person_t', 'typedef' => false, 'template' => [ 'String' => [ 'class', '文字列の型' ], ], 'type' => [ 'name' => [ 'String', '名前' ], 'age' => [ 'int', '年齢' ], ], ]; ?> |
大体は見ればわかると思いますが、1箇所だけ説明が必要です。キー’typedef’のところで、これは以前のC言語の構造体のときのように、typedefで名前を付けるかどうかのフラグです。キー’template’とは両立しませんので、’template’を使うときは’typedef’はfalseにしなければなりません。
では、次にこの配列を使ってC++の構造体を自動生成させるコードをPHPで作ります。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<?php function make_structure(array $info): string { $r = ''; // テンプレートの生成 if (array_key_exists('template', $info)) { $r .= 'template <'; $tparam = []; foreach ($info['template'] as $key => $value) $tparam[] = "{$value[0]} {$key}"; $r .= implode(', ', $tparam) . '>' . PHP_EOL; } $r .= 'struct '; if ($info['typedef']) $r = "typedef $r {" . PHP_EOL; else $r .= "{$info['name']} {" . PHP_EOL; // メンバーの生成 foreach ($info['type'] as $key => $value) { if (is_array($value[0])) $r .= " {$value[0][0]} {$key}[{$value[0][1]}];"; else $r .= " $value[0] $key;"; $r .= " // {$value[1]}" . PHP_EOL; } if ($info['typedef']) $r .= "} {$info['name']};" . PHP_EOL; else $r .= '};' . PHP_EOL; return $r; } ?> |
各メンバーにはコメントを埋め込んでいます(このコメントは説明用なのでごく簡単な内容にしています。実践的なプログラムではもっとまともなコメントにすべきです)。例によってはエラー処理は省略しています。キー’typedef’とキー’template’の排他チェックもやっていませんので要注意です。
このmake_structure関数に$person_typeを渡すと、次のようなC++のコードが生成されます。
0 1 2 3 4 5 6 |
template <class String> struct person_t { String name; // 名前 int age; // 年齢 }; |
C++では構造体も一種のクラスですので、本格的な自動生成に対応しようとすればコンストラクタやデストラクタ、メンバー関数などにも対応しなければなりませんし、アクセス指定子や各データメンバーの初期値にも対応する必要が出てきます。それらについてはいずれ機会があれば作ってみたいと思います。