shonen.hateblo.jp

やったこと,しらべたことを書く.

Enumerable を c++で

クソコード注意

実用性は全く考えてない.思い付きで書いた.

もし実用性を意識するなら,どんな感じに書けばいいんだろう.

なにこれ

c#RubyにあるEnumerableクラス(モジュール,インターフェース)をc++で模倣したものです.

map,reduce,filter,sort,eachなどなど.

#include "bits/stdc++.h"

using namespace std;



template<typename T>
class E {
    vector<T> vec;
public:
    E(const vector<T>& _v) :vec(_v) {}
    E() {}

    template<typename U = T>
    E<U> map(function<U(const T&)> func) const {
        E<U> new_e;
        new_e.vec.resize(vec.size());
        auto iter1 = vec.begin();
        auto iter2 = new_e.vec.begin();
        for (; iter1 != vec.end(); ++iter1, ++iter2)
            *iter2 = func(*iter1);
        return new_e;
    }

    T reduce(function<T(const T&, const T&)> func) const {
        auto it = vec.begin();
        T sum = *it;
        ++it;
        for (; it != vec.end(); ++it)
            sum = func(sum, *it);
        return sum;
    }
    template<typename U = T>
    U reduce(function<U(const U&, const T&)> func, U init) const {
        auto it = vec.begin();
        U sum = init;
        ++it;
        for (auto& item : vec)
            sum = func(sum, item);
        return sum;
    }

    E filter(function<bool(const T&)> func) const {
        E<T> new_e;
        for (auto& item : vec)
            if (func(item))
                new_e.vec.push_back(item);
        return new_e;
    }

    E sort() const {
        E new_e = *this;
        std::sort(new_e.vec.begin(), new_e.vec.end());
        return new_e;
    }

    const E& each(function<void(const T&)> func) const {
        for (auto& item : vec)
            func(item);
        return *this;
    }
    E& each(function<void(const T&)> func) {
        for (auto& item : vec)
            func(item);
        return *this;
    }

    vector<T> to_v() const { return vec; }


    static E<int> range(int begin, int last) {
        assert(begin <= last);
        E<int> new_e;
        new_e.vec.reserve(last - begin + 1);
        for (; begin <= last; ++begin)
            new_e.vec.push_back(begin);

        return new_e;
    }
};



int main() {

    auto sum =
        E<int>(vector<int>{3, 1, 4, 1, 5, 9, 2}).reduce([](int s, int e) {return s + e; });
    cout << sum << endl;
        
    E<int>::range(1, 20)
        .map<int>([](int e) {return e*e; })
        .map<int>([](int e) {return e % 11; })
        .sort()
        .filter([](int e) {return e % 2 == 1; })
        .each([](int e) {cout << e << ' '; });
    cout << endl;

    return 0;
}

なんか昔にも書いた気がする http://shonen9th.blog.fc2.com/blog-entry-130.html