C++0xでOvenのregular書いた。

関数(オブジェクト)をshared_ptrでラップしてindirectするだけだろ、と思ってたらものすごくたいへんでしたの巻。

// gcc-4.6-20100911, std=c++0x
#include <iostream>
#include <vector>
#include <utility>
#include <boost/shared_ptr.hpp>
#include <boost/range.hpp>
#include <boost/range/adaptor/filtered.hpp>

namespace shand {

template <class F>
struct indirect_functor {
    F f;
    indirect_functor() {}
    indirect_functor(F f) : f(f) {}

    template <class... Args>
    auto operator()(Args&&... args) const ->
        decltype((*f)(std::forward<Args>(args)...))
        { return (*f)(std::forward<Args>(args)...); }

    template <class... Args>
    auto operator()(Args&&... args) ->
        decltype((*f)(std::forward<Args>(args)...))
        { return (*f)(std::forward<Args>(args)...); }
};

template <class F>
inline indirect_functor<boost::shared_ptr<F> > regular(F f)
{
    return indirect_functor<boost::shared_ptr<F> >(boost::shared_ptr<F>(new F(f)));
}

} // namespace shand

template <class InputIterator, class F>
void for_each_dummy(InputIterator first, InputIterator last, F f)
{
    InputIterator it;
    it = first;
    for (; it != last; ++it)
        f(*it);
}

template <class InputRange, class F>
void for_each_dummy(const InputRange& r, F f)
{
    for_each_dummy(boost::begin(r), boost::end(r), f);
}

int main()
{
    const std::vector<int> v = {1, 2, 3, 4, 5};
    for_each_dummy(v | boost::adaptors::filtered(shand::regular([](int x) { return x % 2 == 0; })),
                    [](int x) { std::cout << x << std::endl; });
}
sorry, unimplemented: use of 'type_pack_expansion' in template


(´・ω・`).;:…(´・ω...:.;::..(´・;::: .:.;: サラサラ..



・・・たぶん、そのうち動くようになります・・・。
戻り値の型をとるのはたいへんです・・・Eggのすごさがわかりました。