Thiago R. Adams website

Home CodeBlog Articles Downloads Links Books About

Websites

Fun with Lambdas



//Compiled with VC++ 10 RC

#include "stdafx.h"
#include <vector>
#include <iostream>

using namespace std;

template<class EnumerateType, class ConvertionType, class R>
struct EnumerableSelect
{
    EnumerateType en;
    ConvertionType convert;

    EnumerableSelect(const EnumerateType& e,
                     const ConvertionType& ss)
            : en(e),
            convert(ss)
    {
    }

    bool Next() { return en.Next(); }

    R Current() const {
        return convert(en.Current());
    }
};


template<class EnumerateType, class Predicate>
struct EnumerableWhere
{
    typedef typename EnumerateType::ValueType ValueType;

    EnumerateType en;
    Predicate m_p;

    EnumerableWhere(EnumerateType e, const Predicate& p) : en(e), m_p(p)
    {
    }

    bool Next()
    {
        bool b;
        for (;;)
        {
            b = en.Next();
            if (!b || m_p(en.Current()))
                break;
        }
        return b;
    }

    ValueType Current() const
    {
        return en.Current();
    }
    
    template<class T>
    EnumerableSelect<EnumerableWhere, T, decltype(t(Current()))> Select(T t)    
    {
        return EnumerableSelect<EnumerableWhere, T, decltype(t(Current()))>(*this, t);
    }
};

template<class EnumerateType, class Predicate>
EnumerableWhere<EnumerateType, Predicate>
Where(EnumerateType& e, const Predicate& pp) {
    return EnumerableWhere<EnumerateType, Predicate>(e, pp);
}

template<class Iterator>
struct EnumerableAll
{
    typedef typename Iterator::value_type T;
    typedef T ValueType;

    Iterator it;
    Iterator end;
    bool first;

    EnumerableAll(const Iterator& begin, const Iterator& e)
    {
        first = true;
        it = begin;
        end =  e;
    }

    bool Next()
    {
        if (first)
        {
            first = false;
        }
        else
            it++;

        return it != end;
    }

    T Current() const
    {
        return *it;
    }

    template<class Predicate>
    EnumerableWhere<EnumerableAll, Predicate> Where(const Predicate& pp) {
            return EnumerableWhere<EnumerableAll, Predicate>(*this, pp);
    }
};

template<class T>
EnumerableAll<typename T::iterator> From(T& v) {
    return EnumerableAll<typename T::iterator>(v.begin(), v.end());
}

////Sample

struct Point
{
    int x;
    int y;
    Point(int xx, int yy) : x(xx), y(yy) {}
};


int main()
{
    std::vector<Point> v;
    v.push_back(Point(1, 1));
    v.push_back(Point(2, 1));
    v.push_back(Point(3, 1));

    auto e = From(v).Where([](Point& p) { return p.x > 1; }).Select( [] (Point& p) {return p.x;});
    while (e.Next())
        std::cout << e.Current() << ", ";

}

Want to see more? Go to the CodeBlog section.

About the author: I am Thiago Adams. I work as a professional C++ software engineer. I have created this website to share ideas and source code with other people with similar interests.
I would like to hear from you comments, critics, questions and suggestions about this topic or any other part of this website. Email: thiago.adams at gmail dot com