std::map で remove_if をする
いろいろと考えていたんですが Boost.Range の filter でそれっぽく処理することが出来ました。
[ソース]
#include <boost/range/algorithm/for_each.hpp> #include <boost/range/adaptor/filtered.hpp> #include <boost/typeof/typeof.hpp> #include <boost/bind.hpp> #include <map> #include <string> #include <iostream> bool over_three(std::pair<int, std::string> const& pair){ return pair.first >= 3; } void disp(std::pair<int, std::string> const& pair){ std::cout << pair.first << ":" << pair.second << std::endl; } int main(){ using boost::adaptors::filter; std::map<int, std::string> data; data[0] = "zero"; data[1] = "one"; data[2] = "two"; data[3] = "three"; data[4] = "four"; data[5] = "five"; // ! を使いたかったので、boost::bind でラップ BOOST_AUTO(result_range, filter(data, !boost::bind(&over_three, _1)) ); std::map<int, std::string> result(result_range.begin(), result_range.end()); std::cout << ">result" << std::endl; boost::for_each(result, disp); std::cout << ">data" << std::endl; boost::for_each(data, disp); return 0; }
[出力]
>result 0:zero 1:one 2:two >data 0:zero 1:one 2:two 3:three 4:four 5:five
んーこれでいいかしら。
range から map にコピーするのがちょっとめんどくさいですね…。
もっとスマートなやり方はあるかな。
[boost]
- ver 1.47.0
Boost.Phoenix で、std::map の remove_if を書いてみた
Boost.Range を思いつく前に書いたボツネタ。
iterator を回して直接、値を削除しています。
Boost.Phoenix に first と second が欲しいですね。
[ソース]
#include <boost/phoenix.hpp> #include <boost/typeof/typeof.hpp> #include <map> #include <string> #include <iostream> template<typename T> typename T::first_type first_impl(T& pair){ return pair.first; } template<typename T> typename T::second_type second_impl(T& pair){ return pair.second; } BOOST_PHOENIX_ADAPT_FUNCTION( typename boost::remove_reference<A0>::type::first_type, first, first_impl, 1 ) BOOST_PHOENIX_ADAPT_FUNCTION( typename boost::remove_reference<A0>::type::second_type, second, second_impl, 1 ) int main(){ namespace phx = boost::phoenix; using phx::arg_names::arg1; using phx::arg_names::arg2; using phx::local_names::_b; std::map<int, std::string> data; data[0] = "zero"; data[1] = "one"; data[2] = "two"; data[3] = "three"; data[4] = "four"; data[5] = "five"; boost_auto(remove_if, phx::let(_b = phx::begin(arg1))[ phx::while_(_b != phx::end(arg1))[ phx::if_(phx::bind(arg2, *_b))[ phx::erase(arg1, _b++) ] .else_[ ++_b ] ] ] ); remove_if(data, first(arg1) >= 3); std::for_each(data.begin(), data.end(), std::cout << first(arg1) << ":" << second(arg1) << std::endl); return 0; }
[出力]
0:zero 1:one 2:two
[boost]
- ver 1.47.0