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() << ", "; }
|