Similar (not equal) functionality of C# LINQ in C++
#include "stdafx.h"
#include <vector>
#include <iostream>
#include <functional>
using namespace std;
template<class T>
struct IEnumerable
{
typedef T ValueType;
virtual bool Next() = 0;
virtual T Current() const = 0;
};
template<class Iterator>
struct EnumerableAll : public IEnumerable<typename Iterator::value_type>
{
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 EnumerateType, class Predicate>
struct EnumerableWhere : public IEnumerable< typename EnumerateType::ValueType >
{
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 EnumerateType, class ConvertionType>
struct EnumerableSelect : public IEnumerable< typename ConvertionType::To >
{
typedef typename ConvertionType::To ValueType;
EnumerateType en;
ConvertionType convert;
EnumerableSelect(const EnumerateType& e,
const ConvertionType& ss)
: en(e),
convert(ss)
{
}
bool Next() { return en.Next(); }
ValueType Current() const {
return convert(en.Current());
}
};
template<class T>
EnumerableAll<typename T::iterator> From(T& v) {
return EnumerableAll<typename T::iterator>(v.begin(), v.end());
}
template<class Predicate>
struct WhereType
{
typedef Predicate PredicateType;
const Predicate &p;
WhereType(const Predicate& pp) : p(pp) { }
};
template<class Predicate>
WhereType<Predicate> Where(const Predicate& pp) {
return WhereType<Predicate>(pp);
}
template<class EnumerableType, class Predicate>
EnumerableWhere<EnumerableType, Predicate>
operator >> (const EnumerableType& en, const WhereType<Predicate>& were)
{
return EnumerableWhere<EnumerableType, Predicate>(en, were.p);
}
//primary
template<class From, class To> struct ConvertType;
template<class ClassType, class DataType>
struct ConvertDataMemberType
{
typedef ClassType From;
typedef DataType To;
DataType ClassType::*m_p;
ConvertDataMemberType(DataType ClassType::*p) : m_p(p) {}
To operator()(const From& from) const {
return from.*m_p;
}
};
template <class AnyConverter>
AnyConverter Select(const AnyConverter& c) { return c; }
template <class ClassType, class DataType>
ConvertDataMemberType<ClassType, DataType> Select(DataType ClassType::*p)
{
return ConvertDataMemberType<ClassType, DataType>(p);
}
template<class EnumerableType, class ConvertType>
EnumerableSelect<EnumerableType, ConvertType>
operator >> (const ConvertType& converter, const EnumerableType& en)
{
return EnumerableSelect<EnumerableType, ConvertType>(en, converter);
}
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));
IEnumerable<Point> & en1 = From(v);
while (en1.Next())
cout << en1.Current().x << ", ";
cout << endl;
IEnumerable<int>& en = Select(&Point::x) >>
From(v) >>
Where(std::bind2nd(std::less<int>(), 3));
while (en.Next())
cout << en.Current() << ", ";
return 0;
}
}}}
Using auto from C++ 0x
{{{cpp
#include <vector>
#include <iostream>
#include <functional>
using namespace std;
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 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 EnumerateType, class ConvertionType>
struct EnumerableSelect
{
typedef typename ConvertionType::To ValueType;
EnumerateType en;
ConvertionType convert;
EnumerableSelect(const EnumerateType& e,
const ConvertionType& ss)
: en(e),
convert(ss)
{
}
bool Next() { return en.Next(); }
ValueType Current() const {
return convert(en.Current());
}
};
template<class T>
EnumerableAll<typename T::iterator> From(T& v) {
return EnumerableAll<typename T::iterator>(v.begin(), v.end());
}
template<class Predicate>
struct WhereType
{
typedef Predicate PredicateType;
const Predicate &p;
WhereType(const Predicate& pp) : p(pp) { }
};
template<class Predicate>
WhereType<Predicate> Where(const Predicate& pp) {
return WhereType<Predicate>(pp);
}
template<class EnumerableType, class Predicate>
EnumerableWhere<EnumerableType, Predicate>
operator >> (const EnumerableType& en, const WhereType<Predicate>& were)
{
return EnumerableWhere<EnumerableType, Predicate>(en, were.p);
}
//primary
template<class From, class To> struct ConvertType;
template<class ClassType, class DataType>
struct ConvertDataMemberType
{
typedef ClassType From;
typedef DataType To;
DataType ClassType::*m_p;
ConvertDataMemberType(DataType ClassType::*p) : m_p(p) {}
To operator()(const From& from) const {
return from.*m_p;
}
};
template <class AnyConverter>
AnyConverter Select(const AnyConverter& c) { return c; }
template <class ClassType, class DataType>
ConvertDataMemberType<ClassType, DataType> Select(DataType ClassType::*p)
{
return ConvertDataMemberType<ClassType, DataType>(p);
}
template<class EnumerableType, class ConvertType>
EnumerableSelect<EnumerableType, ConvertType>
operator >> (const ConvertType& converter, const EnumerableType& en)
{
return EnumerableSelect<EnumerableType, ConvertType>(en, converter);
}
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 en1 = From(v);
while (en1.Next())
cout << en1.Current().x << ", ";
cout << endl;
auto en = Select(&Point::x) >>
From(v) >>
Where([](int i){ return i < 3; });
while (en.Next())
cout << en.Current() << ", ";
return 0;
}