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