#include <functional>
#include <vector>
template<class Container>
class ForRangedLoopFilter
{
using value_type = typename Container::value_type;
using iterator = typename Container::iterator;
public:
friend class Iterator;
class Iterator
{
public:
Iterator(ForRangedLoopFilter& owner)
: mOwner(owner)
{
mIterator = first();
}
Iterator(ForRangedLoopFilter& owner, bool)
: mOwner(owner)
{
mIterator = last();
}
value_type& operator*() { return *mIterator; }
value_type& operator->() { return *mIterator; }
Iterator& operator++() { mIterator = next(); return *this; }
bool operator !=(const Iterator& other) const { return mIterator != other.mIterator; }
private:
iterator first()
{
mIterator = mOwner.mContainer.begin();
if (!isValid(mIterator))
mIterator = next();
return mIterator;
}
iterator next()
{
do {
mIterator++;
} while (mIterator != last() && !isValid(mIterator));
return mIterator;
}
iterator last() { return mOwner.mContainer.end(); }
bool isValid(const iterator& it) const
{
for (auto&& func : mOwner.mFilterFunctions)
{
if (!func(*it))
return false;
}
return true;
}
private:
ForRangedLoopFilter & mOwner;
iterator mIterator;
};
public:
template<class FilterFunc>
ForRangedLoopFilter(Container& container, FilterFunc func)
: mContainer(container)
{
mFilterFunctions.push_back(func);
}
template<class FilterFunc>
ForRangedLoopFilter(const Container& container, FilterFunc func)
: mContainer(const_cast<Container&>(container))
{
mFilterFunctions.push_back(func);
}
Iterator begin() { return Iterator(*this); }
Iterator end() { return Iterator(*this, true); }
ForRangedLoopFilter<Container> operator|(std::function<bool(const value_type& entry)> filter)
{
mFilterFunctions.push_back(filter);
return *this;
}
private:
Container & mContainer;
std::vector<std::function<bool(const value_type& entry)>> mFilterFunctions;
};
template<class Container>
ForRangedLoopFilter<Container> operator|(Container& container, std::function<bool(const typename Container::value_type& entry)> filter)
{
return ForRangedLoopFilter<Container>(container, filter);
}
template<class Container>
ForRangedLoopFilter<Container> operator|(const Container& container, std::function<bool(const typename Container::value_type& entry)> filter)
{
return ForRangedLoopFilter<Container>(const_cast<Container&>(container), filter);
}
#include <iostream>
#include <vector>
#include <string>
int main()
{
std::vector<int> vec{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (int v : vec | [](int v) { return v % 2 == 0; } | [](int v) { return v % 3 == 0; })
{
std::cout << v << std::endl;
}
struct Toto {
int value;
std::string nom;
};
const std::vector<Toto> vec2{ { 0, "toto" },{ 1, "tata" },{ 2, "titi" } };
for (const Toto& v : vec2 | [](const Toto& v) { return v.value % 2 == 0; } | [](const Toto& v) { return v.nom.find('i') != std::string::npos; })
{
std::cout << v.value << ":" << v.nom << std::endl;
}
return 0;
}