わんくま同盟 横浜勉強会 #1 - C++ Day Boost とその実装技術 ~ Boost の薄い話から濃い話まで~

Slides:



Advertisements
Similar presentations
Tt_clown ( 津川 知朗) 俺 Tokenizer を作る ~ Boost.Tokenizer のカスタマイズ~ 2009/12/121 Boost 勉強会.
Advertisements

プログラミング言語論 第10回(演習) 情報工学科 木村昌臣   篠埜 功.
JavaScript プログラミング入門 2006/11/10 神津.
コンパイラ 2011年10月17日
プログラミング言語としてのR 情報知能学科 白井 英俊.
επιστημη さん 提供の VB.NETプログラムを丸裸にする!?
1.1 C/C++言語 Hello.ccを作りコンパイルしてa.outを作り出し実行する
2008/03/01 D-BOF k.inaba はじめての initial D 2008/03/01 D-BOF k.inaba
とても使いやすい Boost の serialization
とても使いやすい Boost の serialization
プログラミング基礎I(再) 山元進.
Myoungkyu Song and Eli Tilevich 発表者: 石尾 隆(大阪大学)
プログラミング言語論 第6回 型 情報工学科 篠埜 功.
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
アルゴリズムとデータ構造 2011年6月13日
プログラミング演習II 2004年12月 21日(第8回) 理学部数学科・木村巌.
プログラミング論 II 電卓,逆ポーランド記法電卓
コンパイラ 2012年10月15日
コンパイラ 2012年10月22日
ML 演習 第 7 回 新井淳也、中村宇佑、前田俊行 2011/05/31.
コンパイラ 2011年10月24日
補足説明.
細かい粒度でコードの再利用を可能とするメソッド内メソッドのJava言語への導入
プログラミング言語入門 手続き型言語としてのJava
第9章 例外処理,パッケージ 9.1 例外処理 9.2 ガーベッジコレクション.
暗黙的に型付けされる構造体の Java言語への導入
第3回 2007年4月27日 応用Java (Java/XML).
独習XML 第2章 XML文書の構成要素 2.1 XMLの文字と文字列 2.2 コメント
オブジェクト指向プログラムにおける エイリアス解析手法の提案と実現
プログラミング 4 記憶の割り付け.
ソフトウェア制作論 平成30年10月3日.
プログラミング 3 構造体(2).
Null ヤバイのでなんとかする takeshik.
Null ヤバイのでなんとかする takeshik.
アルゴリズムとデータ構造1 2009年6月29日
アルゴリズムとデータ構造1 2005年7月5日
アルゴリズムとデータ構造 2010年6月21日
フロントエンドとバックエンドのインターフェース
コンパイラ 2011年10月20日
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
B演習(言語処理系演習)第2回 田浦.
JavaScriptを含んだHTML文書に対する データフロー解析を用いた構文検証手法の提案
アルゴリズムとプログラミング (Algorithms and Programming)
C++ 構文解析 構文解析器の状態保存と復元
プログラミング言語論 第十一回 理工学部 情報システム工学科 新田直也.
Boostのスマートなポインタを使ってみる
C#プログラミング実習 第3回.
計算機プログラミングI 第3回 プリミティブ値 クラスメソッド クラス変数 式と演算 変数の利用
アルゴリズムとデータ構造 2012年6月11日
アルゴリズムとデータ構造1 2006年6月23日
nativeの基礎知識 「ポインタ」てなによ!?
アルゴリズムとデータ構造1 2009年6月15日
高度プログラミング演習 (11).
情報処理Ⅱ 第7回 2004年11月16日(火).
統合開発環境のための プログラミング言語拡張 フレームワーク
cp-3. サブクラス,継承 (C++ オブジェクト指向プログラミング入門)
cp-2. 属性,アクセサ (C++ オブジェクト指向プログラミング入門)
コンパイラ 2012年10月11日
プログラミング 4 文字列.
アルゴリズムとデータ構造 2010年6月17日
フレンド関数とフレンド演算子.
演算子のオーバーロード.
プログラミング演習I 2003年6月11日(第9回) 木村巌.
:: の扱い 長谷川啓.
オブジェクト指向言語における セキュリティ解析アルゴリズムの提案と実現
情報処理Ⅱ 2005年11月25日(金).
値渡しと参照渡しについて.
計算技術研究会 第5回 C言語勉強会 関数(function)を使う
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
俺 Tokenizer を作る ~Boost.Tokenizer のカスタマイズ~
Presentation transcript:

わんくま同盟 横浜勉強会 #1 - C++ Day Boost とその実装技術 ~ Boost の薄い話から濃い話まで~

わんくま同盟 横浜勉強会 #1 - C++ Day 自己紹介 ・ C++ スキー ・吉田秀彦モドキ ・ Boost スキー ・ D&E 未読 ・猫スキー

わんくま同盟 横浜勉強会 #1 - C++ Day アジェンダ ・ Boost.SharedPtr ・ Boost.Spirit ・ Boost.SharedPtr の実装技術 ・ Boost.Spirit の実装技術 ・ Boost について

わんくま同盟 横浜勉強会 #1 - C++ Day Boost について ・ Boost とは →Wikipedia 「 C++ の先駆的な開発者のコミュニティ、 及びそのコミュニティによって公開されているオープ ンソースライブラリのこと」 → 便利な C++ のライブラリ →Boost の一部が C++0x に入る

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.SharedPtr

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.SharedPtr ・ Boost.SharedPtr とは { boost::shared_ptr p(new Hoge); { boost::shared_ptr p2(new Hoge); p = p2; } インスタンスの所有権を共有したポインタ 誰も所有しなくなれば自動的に解放される

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.SharedPtr ・インスタンスが所有されている限り解放されな い。 ・誰がインスタンスを所有しているか気にする必要が 無い。 ・責任を明確にしなくて良い。 ・上手に使えばリソースリークが無くなる。

わんくま同盟 横浜勉強会 #1 - C++ Day 内部実装

わんくま同盟 横浜勉強会 #1 - C++ Day ・内部でインスタンスの参照数をカウントしてい る。 Boost.SharedPtr コピーするたびに参照数を増やす デストラクタが呼ばれるたびに参照数を減らす 参照数が 0 になったら解放

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.SharedPtr template class shared_ptr { T* p_; int* count_; void release() { if (--*count_ == 0) { delete p_; delete count_; } public: explicit shared_ptr(T* p) : p_(p), count_(new int(1)) { } shared_ptr & operator=(const shared_ptr & s) { release(); p_ = s.p_; count_ = s.count_; ++*count_; return *this; } ~shared_ptr() { release(); } };

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.SharedPtr ・デフォルトでは delete で解放される。 Hoge* AllocHoge(); void DeallocHoge(Hoge* p); struct HogeDeleter { void operator()(Hoge* p) { DeallocateHoge(p); } }; { boost::shared_ptr hoge(AllocHoge(), DeallocHoge); boost::shared_ptr hoge2(AllocHoge(), HogeDeleter()); } delete p_; 自作のアロケータでも対応可能。

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.SharedPtr template class shared_ptr { T* p_; Deleter d_; public: template shared_ptr(T* p, Deleter d) : p_(p), d_(d) { } ~shared_ptr() { d_(p_); } }; ↓ Type Erasure ・ Deleter をメンバに持てないので不可

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.SharedPtr struct placeholder { virtual ~placeholder() { } virtual void destroy() = 0; }; template struct holder : public placeholder { T* p_; Deleter d_; holder(T* p, Deleter d) : p_(p), d_(d) { } virtual void destroy() { d_(p_); } }; Hoge* p; HogeDeleter d; placeholder* holder( new holder (p, d));... holder->destroy();

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.SharedPtr template class shared_ptr { T* p_; int* count_; placeholder* holder_; public: template shared_ptr(T* p, Deleter d) : p_(p), count_(new int(1)), holder_(new holder (p, d)) { }... ~shared_ptr() { if (--*count_ == 0) { holder_->destroy(); delete holder_; delete count_; } };

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.SharedPtr ・ Boost.SharedPtr まとめ 参照カウント方式 任意の削除方法を指定可能 Type Erasure という技法を使っている コピーコンストラクタ・代入演算子やデストラクタ を使ってカウントしている ・ Boost.SharedPtr おまけ ・ boost::shared_ptr 同士のキャストが可能 ・ポインタと同程度にスレッドセーフ ・例外安全の保証

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.Spirit

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.Spirit ・ Boost.Spirit とは →C++ で書くことのできる構文解析器 ・構文解析とは →k.inaba 「 プログラミング言語や設定ファイルなどの構造を 持ったテキストデータを、ただの文字列として与えられた状態か ら、言語の文法などにしたがって構造を取り出す作業 」 (Boost C++ Libraries 第2版より引用 ) →Wikipedia 「ある文章の文法的な関係を説明するこ と」

わんくま同盟 横浜勉強会 #1 - C++ Day ・文法 例 )XML タグの文法 (1) 最初に '<' が来る必要がある Boost.Spirit (2) その次にタグ名が来る必要がある (3) 次に [ 空白 属性 ] というパターンが 0 回以上連続す る (4) 次には空白があっても無くても良くて (5) 最後は '>' で終わる という感じで定義されている。 ↑ こういう規則のことを文法という

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.Spirit ・文法の表現方法 日本語 「 a の次に B が続き、その次は d になる。 ただし B は b または b の次に c が続くという意味である。」 BNF ::= a d ::= b|bc 正規右辺文法(正規表現) a(b|(bc))d Boost.Spirit rule = ch_p('a') >> B >> 'd'; B = ch_p('b') | (ch_p('b') >> 'c');

わんくま同盟 横浜勉強会 #1 - C++ Day デモ

わんくま同盟 横浜勉強会 #1 - C++ Day 内部実装

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.Spirit ・式の構造を記憶している ch_p('a') >> B ‘a’ と B が >> で繋がれたことを覚えている →’a’ の次に B が来るかどうか、という解析が出来 る →’a’ になるか B になるか、という解析ができる ch_p('a') | B ‘a’ と B が | で繋がれたことを覚えている B = ch_p('b') | (ch_p('b') >> 'c'); B も式になっている → 再帰的な構造になっている

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.Spirit ・再帰的な構造をクラスで定義するパター ン Composite パターン ・代表的な例 ディレクトリ構造

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.Spirit class parser { virtual bool parse(Input in) = 0; }; parser* rule; parser* B; rule = ch_p('a') >> B >> ch_p('d'); B = ch_p('b') | (ch_p('b') >> ch_p('c')); bool result = rule->parse(Input("abcd"));

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.Spirit class chlit : public parser { char c_; public: chlit(char c) : c_(c) { } virtual bool parse(Input in) { returm in.read() == c_; } }; parser* ch_p(char c) { return new chlit(c); }

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.Spirit class sequence : public parser { parser* left_; parser* right_; public: sequence(parser* l, parser* r) : left_(l), right_(r) { } virtual bool parse(Input in) { if (!left_->parse(in)) return false; if (!right_->parse(in)) return false; return true; } }; parser* operator>>(parser* left, parser* right) { return new sequence(left, right); }

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.Spirit class alternative : public parser { … virtual bool parse(Input in) { Input save(in); if (l_->parse(in)) return true; in = save; if (r_->parse(in)) return true; return false; } }; parser* operator|(parser* left, parser* right) { return new alternative(left, right); }

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.Spirit ↓ Expression Template 仮想関数経由なので遅い 型情報が消える ・式の構造をインスタンスで表現する方法

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.Spirit class chlit { char c_; public: chlit(char c) : c_(c) { } bool parse(Input in) { returm in.read() == c_; } }; chlit ch_p(char c) { return chlit(c); }

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.Spirit template class sequence { Left left_; Right right_; public: sequence(Left l, Right r) : left_(l), right_(r) { } bool parse(Input in) { if (!l_.parse(in)) return false; if (!r_.parse(in)) return false; return true; } }; template sequence operator>>(Left left, Right right) { return sequence (left, right); }

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.Spirit template class alternative {... bool parse(Input in) { Input save(in); if (l_.parse(in)) return true; in = save; if (r_.parse(in)) return true; return false; } }; template alternative operator|(Left left, Right right) { return alternative (left, right); }

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.Spirit bool result = (ch_p('b') | (ch_p('b') >> ch_p('c'))).parse(Input("bc")); alternative > ・式の構造を型で表現している →Expression Template ↓

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.Spirit ?? B = (ch_p('b') | (ch_p('b') >> ch_p('c'))); ・戻り値の型が難しくて代入できない。 ・ Type Erasure を使う ・仮想関数経由になるから遅くなる ・ケースバイケース

わんくま同盟 横浜勉強会 #1 - C++ Day Boost.Spirit ・ Boost.Spirit まとめ 式の構造を型で表現している Expression Template 複雑になる型 Type Erasure ・ Boost.Spirit おまけ ・実際は CRTP (Curiously Recurring Template Pattern) が使われていたりしてもっと複雑 ・ Boost.Spirit は LL(k) の構文解析器

わんくま同盟 横浜勉強会 #1 - C++ Day 時間が余った時用 構文解析の手法 下降型 ルートのルールを展開していって、入力した文字列と一番下のルー ルの文字が一致するかどうかを調べる。 上昇型 入力の文字列がルールに変換できるかを調べ、最終的にルートの ルールになるかどうかを調べる。 R→aBd B→b|bc Boost.Spirit は下降型

わんくま同盟 横浜勉強会 #1 - C++ Day 参考 ・ Boost C++ Libraries プログラミング 第 2 版 ・ Boost 本家 ・ Boost.SharedPtr ( 日本語 ) ・ Boost.Spirit ( ちょっとだけ日本語 ) ・コンパイラの構成と最適化

わんくま同盟 横浜勉強会 #1 - C++ Day おわり