@egtraイグトランスの頭の中(のかけら)ActiveBasicを中心にプログラミングの話をぼちぼちと。EAWebKit.コメントなしEAWebKit勉強会というところに行ってきました。(以下EA)がオープンソースで公開しているライブラリです。Chromeで使われているWebKitをEAが改造?移植?したものということでこの名前のようです。注目すべきはWebKit以外にも様々なライブラリが含まれており、特にあのEASTLも含まれているというのです。EASTLで明らかにされた、EAによるSTL風のライブラリです(N2271の時点では実装は公開されていなかった)。勉強会の午後の時間は、各々がやりたいことをやりましょうということだったので、私は黙々とEASTLのvector.hを読んでいました。いうわけで、vector.hから4つ取り上げます。1つ目、ファイル冒頭です。「結局EASTLのライセンスって何よ?」という話がありましたが、EASTLでは各ファイル先頭にライセンスが書かれてあります。(以下省略)3条項版BSDライセンスです。BSDらしいという話があったので、家に帰ってから探してみました。Licenseのテンプレートにピッタリはまります。他のEASTLの各ファイルも同様に3条項BSDライセンスですが、LGPLであるWebKitを同梱しているEAWebKit全体としてはLGPLなのでは、という懸念が拭えないのが私の気にするところです。2つ目、ライセンスの次に現れるeast::vectorについての文章です。vector<SomeClass>(x).swap(x);///////////////////////////////////////////////////////////////////////////////おそらく、こんな感じでしょうか。このファイルはC++のstd::vectorによく似たvector(配列風のコンテナ)を実装している。std::vectorと比べ、主に次のような相違がある。性能向上のため、対の拡張関数がある(訳注:resizeの2番目の引数があるものとないものを用意していることでしょうか?)。アラインメント要求のあるオブジェクトを保持できる。std::vectorで同様のことをやるには、移植性のない手法を使わないと実現できない。デバッグ用としてメモリに名前を付けられる機能をネイティブに持っている。読み取り、デバッグ、可視化が容易。コンソールや組込など例外処理のない環境を考慮。深くネストした関数呼出を避けている。このため、デバッグビルドでもインライン化(によるコードの膨張を抑えること)が可能。vector<bool>はboolのvector。変な小細工はしていない。要素を保持するメモリの連続性はあるうえ、イテレータはただのTへのポインタ。先頭要素へのポインタを返すdata()メンバ関数がある。&*v.begin()などと違って要素が空でも安全。size_typeは、size_tではなくeastl_size_tのtypedef。メモリの節約かつ64ビット環境での高速化に繋がる(訳注:east_size_tは32ビット符号なし整数型)。余分なcapacityを減らすためのset_capacity()メンバ関数がある。std::vectorではvector<SomeClass>(x).swap(x);というわけわからないコードを書く必要がしかなかった。例外処理やアラインメント、size_typeなどはなるほど納得です。今となっては微妙なものもちらほらとあります。2010などが対応済み)。N2271でC++標準化委員会へEASTLが紹介されたことも遠因にあるのでしょうか。ネストした関数呼出をしないというのは、最適化能力の低いコンパイラにも有効でしょうが、正直PC向けならあまり気にする必要がないと思いました。要素の連続を謳っているのは、std::vectorにその保証がなかったC++98を意識しているように見受けられます(C++03でstd::vectorでも同じことが規定されました)。アラインメント対応やメモリへの名前付けなのはアロケータの役割なので、vector.hだけではあまりその周りの実装は分かりません。3つ目、VectorBaseクラステンプレート(vectorの基底クラス)とvectorクラステンプレートのクラス定義です。ここでの基底クラスの意義は、テンプレートでのコード膨張を抑制するためかなと思ったら違いました。答えはVectorBase手前のコメントに書いてあり、メモリ確保(VectorBaseコンストラクタ)と初期化(vectorコンストラクタ)を分離したいため、とのことです。メモリ確保に成功したけど初期化に失敗した場合、vectorのコンストラクタで例外を投げることになります。この場合、VectorBaseはコンストラクトが完了しているのでVectorBaseのデストラクタが走り、メモリが解放されます。catchを書く必要があるので、例外無し環境で使えないコードになってしまうということだそうです。catchを書かずに済ませることで例外無し環境への対応が楽にになるというわけです(これにはちょっとしたオチがありますがそれは次回以降のエントリで改めて)。VectorBaseクラス定義はtypedefやメンバ関数とメンバ変数の宣言など、特に変哲はありません(なお、EASTLのソースはメンバ関数の定義をその場に書かない派です)。し、以下のprotectedメンバに注目です。currentCapacity);次はvectorクラスの定義です。これもstd::vector互換のtypedefとメンバ関数の並ぶ(一部eastl固有のものあり)特徴のないものです。言いたいところですが、typedefに混じって「publicな領域」にこんな宣言があります。base_type::DoFree;基底クラスのメンバをusing宣言です。久々に見ましたこの構文、というところではなく、堂々とpublicにしているところが驚くべきところです。この「必要とあらばvectorの中身を自由にいじれるように公開している」という点がstd::vectorにはない(std::vectorはまねしない・できない)特徴だと思います。4つ目、swapメンバ関数です。ほとんど関数の実装は素直なものですが、ところどころ特徴的なものがあります。その代表例としてswapを取り上げます。コンテナのswapではアロケータは交換しないという方針だそうで、その場合は中身をコピーしてswapする実装です。本当は、EAWebKit勉強会の全体的な感想なども書きたいのですが、これだけで分量がいっぱいなのでこのエントリではこれまでとします。コメントをキャンセルメールアドレスが公開されることはありません。WPThemes.Info。