Boost.Phoenix はじまりました

Phoenix ハジマタ。
と、いうことで簡単に Starter Kit を読んだのでそれの覚え書きなど。

[ソース]

#include <boost/phoenix.hpp>
#include <boost/array.hpp>
#include <iostream>
#include <string>
#include <algorithm>

namespace phx = boost::phoenix;

struct is_even_impl{
    typedef bool result_type;
    template<typename Arg>
    bool operator ()(Arg arg1) const{
        return arg1 % 2 == 0;
    }
};

struct equal_impl{
    equal_impl(int value) : value_(value){}
    typedef bool result_type;
    template<typename Arg>
    bool operator ()(Arg arg1){
        return arg1 == value_;
    }
private:
    int value_;
};

int
main(){
    using phx::arg_names::arg1;
    using phx::arg_names::arg2;

    int n = 10;
    char const* str = "hello world";
    
    // value を返す
    std::cout << phx::val(str)() << std::endl;
    // value の参照を返す
    std::cout << phx::ref(n)() << std::endl;
    // 第一引数を返す
    std::cout << arg1(n, str) << std::endl;
    // 第二引数を返す
    std::cout << arg2(n, str) << std::endl;
    // 演算したり
    std::cout << (phx::ref(n) + 10)() << std::endl;
    
    // 代入式を定義する
    boost::function<int()> f = (phx::ref(n) = 20);
    // まだ代入されていない
    std::cout << n << std::endl;
    // 代入する
    f();
    // 代入された!
    std::cout << n << std::endl;
    
    // arg1 に対して処理する
    boost::array<int, 10> v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    std::cout << *std::find_if(v.begin(), v.end(), arg1 % 2 != 0) << std::endl;
    
    // if 文のように定義
    std::for_each(v.begin(), v.end(),
        phx::if_(arg1 % 2 == 0)[
            std::cout << arg1 << ","
        ]
    );
    std::cout << "\n";
    
    // new したり delete したり
    boost::function<std::string*(char const*)> create_string
        = phx::new_<std::string>(arg1);
    boost::function<void(std::string*)> delete_string 
        = phx::delete_(arg1);
    std::string* str2 = create_string("create string");
    std::cout << (*str2) << std::endl;
    delete_string(str2);
    
    // arg1 を引数に受け取る、関数オブジェクトを定義する
    phx::function<is_even_impl> is_even;
    std::cout << is_even(arg1)(2) << std::endl;
    std::cout << *std::find_if(v.begin(), v.end(), is_even(arg1)) << std::endl;
    // コンストラクタの引数に渡してみたり
    phx::function<equal_impl>   equal_5(5);
    std::cout << *std::find_if(v.begin(), v.end(), equal_5(arg1)) << std::endl;

    return 0;
}

[出力]

hello world
10
10
hello world
20
10
20
1
0,2,4,6,8,
create string
1
0
5

とりあえず、さわりとしてはこんな感じですかね。
Boost.Lambda を使ったことがあればそんなに難しくない気がしますね。
is_even(arg1) みたいな書き方が出来るのがちょっと興味を引く。
まだ、はじまったばかりなのでもうちょっと読み進めていきたいです。

[boost]

  • ver 1.47.0