以下のコードでやっていることの説明.
EXCEPTION_HOOK((expr))
と書いておけば, (expr) という C++ の式を実行したら急に例外が来たので……というときに, call stack のようなもので殴られた跡 (この hook が仕掛けられている場所に関する情報) を boost::exception に乗せていきます. call stack の生成ぐらい言語でサポートして欲しいよね,うんうん.終わり. Microsoft Visual C++ 2010 と GCC 4.5.0 で動作を確認済みです.
工夫として,
EXCEPTION_HOOK((expr))
という文字列が式 expr と同等な C++ の expression として透過的に機能するように見せかけてあります.つまり,たとえば
std::string s("42"); int i = EXCEPTION_HOOK((boost:lexical_cast<int>(s)));
などと書けるようにしてあり,もちろん例外が通知されなければこのコードは
std::string s("42"); int i = boost::lexical_cast<int>(s);
と同じ挙動を示します.終わり.
透過性という点で重要な別の特徴として, preprocessing-time でこの hook を完全に無効化できます.無効化して,字句レベルで (expr) という構文として振舞わせるのは赤子の手をひねる (それをするなんてとんでもない!) よりも造作のないことよ,クックック…….
以下のコードの要点 ([&] な lambda-introducer を伴う lambda-expression を用いて, hook を仕掛けた場所のスコープの文脈を持ち込みつつコールバック化する点) さえ抑えておけば,任意の expression に対して,透過的に preprocessing-time, compile-time, runtime レベルの pre-hook, post-hook および例外送出時 hook を仕掛けるようなマクロ (「えーマジマクロ?」「マクロが許されるのは……」) を構築できるんじゃないんでしょうか,知らんけど?
細かいこと言うと hook を仕掛ける対象となる式の型が void でない場合は MoveConstructible でないといけないという制約がががが.ただし,過去,似たようなものはいくつか提示されていますが (Bjarne が昔書いていた operator-> で hook を書く記事どこいったっぽ? *1 ) ,「hook を仕掛ける構文がそのまま expression として透過的に扱える」かつ「例外送出イベントにも hook を仕掛けられる」というのを C++ で達成したものはなかったはずなのでにょほほほほ.
以下,とても長〜いコードと出力例.
*1:追記:あった. リンク先 PDF 注意 http://www2.research.att.com/~bs/wrapper.pdf