Boost.Fusion 1.58 updates
Boost.Fusion 1.58は頑張ったし、Damien Buhlも頑張ったのでそれなりな更新がいくつかあります。 まだBeta出てない*1けどそろそろmasterがcloseしてbugfixのみになるので機能としてはfixした感じ。
主な新機能
- GitHub PR #12 Fusionのシーケンスを
boost::hash
で使えるように - GitHub PR #51
std::reference_wrapper
をサポート std::tuple
のサポート- GitHub PR #54 Fusionアダプタでの暗黙的な型推論をサポート
- ticket 9813, GitHub PR #14, GitHub PR #23, GitHub PR #26, GitHub PR #58 C++11/14 constexprのサポート
- いくつかのresult_ofをSFINAE-friendlyに
- ticket 10443
fusion::result_of::invoke
- GitHub PR #35
fusion::result_of::copy
fusion::result_of::move
fusion::result_of::swap
- GitHub PR #41
fusion::result_of::at_c
fusion::result_of::at
- ticket 10443
boost::hashのサポート
これまではFusionシーケンスは boost::hash
をサポートしていなかったので、Unordered Associative Containerに投げることができませんでした。
今回、新たに hash.hpp
が導入され、Boost.UnorderedへFusionシーケンスを投げることが出来るようになりました。
これはForward Sequenceであれば受け付けるので、アダプトしたシーケンスにも使えます。
#include <boost/unordered_set.hpp> #include <boost/fusion/include/vector.hpp> #include <boost/fusion/include/make_vector.hpp> #include <boost/fusion/include/equal_to.hpp> #include <boost/fusion/include/hash.hpp> // new int main() { boost::unordered_set<boost::fusion::vector<int>> m; m.insert(boost::fusion::make_vector(0)); m.insert(boost::fusion::make_vector(1)); }
今のところ、std::hash
は特殊化されていないので、std::unordered_{multi,}{map,set}
には直接使えませんが、boost::hash
を渡すことで同様のことが出来るようになります。
#include <unordered_set> #include <boost/fusion/include/vector.hpp> #include <boost/fusion/include/make_vector.hpp> #include <boost/fusion/include/equal_to.hpp> #include <boost/fusion/include/hash.hpp> // new int main() { std::unordered_set<boost::fusion::vector<int>, boost::hash<boost::fusion::vector<int>>> m; m.insert(boost::fusion::make_vector(0)); m.insert(boost::fusion::make_vector(1)); }
1.59には入れたいと思います。
std::reference_wrapper
boost::reference_wrapper
は前々から渡されたら通常の参照に展開するようになっていたんだけど、今回std::reference_wrapper
もそうなるようになった。
#include <functional> #include <cassert> #include <boost/fusion/include/vector.hpp> #include <boost/fusion/include/make_vector.hpp> #include <boost/fusion/include/at_c.hpp> int main() { int i = 0; auto v = boost::fusion::make_vector(std::ref(i)); boost::fusion::at_c<0>(v) = 1; }
reference_wrapper
のままでもええやんって思うかもだけど、reference_wrapper
のまま格納されると上のコードはコンパイルできない。
std::tuple
std::tuple
のサポートは実は前々から存在してはいたんだけど、ドキュメントが無かったり、一分実装が抜けていたりした。
今回ドキュメントを用意したし、大体実装されているはず。
いくつかのresult_ofをSFINAE-friendlyに
いくつかというのがミソ。1.59には全部をSFINAE-friendlyにしたい
アダプタでの暗黙的な型推論をサポート
これまでは構造体をアダプトするには型を書かないといけませんでした。
#include <boost/fusion/include/adapt_struct.hpp> #include <boost/fusion/include/at_c.hpp> namespace foo { namespace very_very_cool_namespace { typedef int how_quite_greatest_awesome_type; } struct bar { very_very_cool_namespace::how_quite_greatest_awesome_type hoge; very_very_cool_namespace::how_quite_greatest_awesome_type fuga; }; } BOOST_FUSION_ADAPT_STRUCT( foo::bar, (foo::very_very_cool_namespace::how_quite_greatest_awesome_type, hoge) (foo::very_very_cool_namespace::how_quite_greatest_awesome_type, fuga) ) int main() { foo::bar x = { 0 }; boost::fusion::at_c<0>(x) = 0xdeadbeef; }
very_very_cool_namespace::how_quite_greatest_awesome_type
を書くのは非常にだるいですし、構造体の変更に対して柔軟に対応できません。
一応これまでであっても型名の代わりにBOOST_FUSION_ADAPT_AUTO
を使えばBoost.TypeOfでの推論を使用できていましたが、依然として書かないといけないのは面倒です。
今回、Damienが頑張ってプリプロセッサしたところ、Variadic Macrosをサポートした環境では更に省略出来るようになりました。
#include <boost/fusion/include/adapt_struct.hpp> #include <boost/fusion/include/at_c.hpp> namespace foo { namespace very_very_cool_namespace { typedef int how_quite_greatest_awesome_type; } struct bar { very_very_cool_namespace::how_quite_greatest_awesome_type hoge; very_very_cool_namespace::how_quite_greatest_awesome_type fuga; }; } BOOST_FUSION_ADAPT_STRUCT( foo::bar, hoge, fuga ) int main() { foo::bar x = { 0 }; boost::fusion::at_c<0>(x) = 0xdeadbeef; }
C++11/14 constexprのサポート
#include <boost/fusion/include/vector.hpp> #include <boost/fusion/include/make_vector.hpp> #include <boost/fusion/include/at_c.hpp> int main() { constexpr auto v = boost::fusion::make_vector("foo", 0xdeadbeef); static_assert(boost::fusion::at_c<1>(v) == 0xdeadbeef, "Sadly, beef is daed ..."); }
見たまんまですね。これで不幸にも実行ができなくなってしまった環境であってもコンパイル時に計算できるので安心ですね。
C++14なら基本的にconstexprになってるはずです。C++11だといくつかがまだ対応出来てないです。少しずつなんとかしたいですね。
*1:3/11予定