// Compiled with g++ 4.7
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
#include <list>
#include <functional>
namespace linq
{
template <typename ContType>
class linq_impl {
public:
typedef typename ContType::value_type value_type;
typedef typename ContType::const_reference const_reference;
private:
typedef std::vector<typename ContType::iterator> inner_cont_type;
typedef typename inner_cont_type::const_reference inner_cref;
public:
class iterator: std::iterator<std::random_access_iterator_tag, value_type> {
// TODO
};
public:
linq_impl(ContType& cont): vec() {
this->vec.reserve(cont.size());
for (auto it = cont.begin(); it != cont.end(); ++it)
vec.push_back(it);
}
template <typename Func = std::less<value_type> >
linq_impl& orderby(Func func = Func()) {
std::sort(this->vec.begin(), this->vec.end(), [=] (inner_cref v1, inner_cref v2) {
return func(*v1, *v2);
});
return *this;
}
template <typename Func = std::greater<value_type> >
linq_impl& orderby_descending(Func func = Func()) {
return orderby(func);
}
template <typename Func>
linq_impl& where(Func func) {
vec.erase(std::remove_if(this->vec.begin(), this->vec.end(), [=] (inner_cref val) {
return !func(*val);
}), this->vec.end());
return *this;
}
public:
std::vector<value_type> to_vector() {
// TODO: Use linq_impl::iterator to do this
std::vector<value_type> result;
result.reserve(this->vec.size());
for (auto it = this->vec.begin(); it != this->vec.end(); ++it)
result.push_back(**it);
return result;
}
std::list<value_type> to_list() {
// TODO: Use linq_impl::iterator to do this
std::list<value_type> result;
for (auto it = this->vec.begin(); it != this->vec.end(); ++it)
result.push_back(**it);
return result;
}
private:
inner_cont_type vec;
};
template <typename ContType>
linq_impl<ContType> from(ContType& cont) {
return linq_impl<ContType>(cont);
}
}
int main(int argc, char* argv[])
{
using namespace std;
int arr[] = { 5, 2, 6, 2, 3, 1, 4 };
vector<int> vec(begin(arr), end(arr));
auto query = linq::from(vec)
.where([] (int x) { return x % 2 == 0; })
.orderby();
for (auto&& i : query.to_vector())
cout << i;
}