#include <utility>
template <typename Iterator, typename Runnable>
struct ConditionalIterator
{
private:
Iterator iterator;
Iterator end;
const Runnable& condition;
public:
ConditionalIterator(Iterator b, Iterator e, const Runnable& r)
:
iterator(b),
end(e),
condition(r)
{
}
auto operator*() -> decltype(*iterator)
{
return *iterator;
}
ConditionalIterator& operator++()
{
do
{
++iterator;
}
while ( iterator != end && !condition(*iterator) );
return *this;
}
bool operator==(const ConditionalIterator& second)
{
return iterator == second.iterator;
}
bool operator!=(const ConditionalIterator& second)
{
return !(*this == second);
}
};
template <typename Range, typename Runnable>
struct ConditionalRange;
template <typename Range, typename Runnable>
ConditionalRange<Range, Runnable> makeConditionalRange(Range& range, Runnable&& condition)
{
static_assert(std::is_same<decltype(condition(*std::declval<Range>().begin())), bool>::value, "Condition must return a boolean value.");
return ConditionalRange<Range, Runnable>(range, std::forward<Runnable>(condition));
}
template <typename Range, typename Runnable>
struct ConditionalRange
{
public:
friend ConditionalRange makeConditionalRange<>(Range&, Runnable&&);
public:
using iterator_type = ConditionalIterator<decltype(std::declval<Range>().begin()), Runnable>;
iterator_type begin() const
{
auto b = range.begin();
while ( b != range.end() && !condition(*b) )
{
++b;
}
return ConditionalIterator<decltype(std::declval<Range>().begin()), Runnable>(b, range.end(), condition);
}
iterator_type end() const
{
return ConditionalIterator<decltype(std::declval<Range>().begin()), Runnable>(range.end(), range.end(), condition);
}
private:
ConditionalRange(Range& range_, Runnable&& condition_)
:
range(range_),
condition(std::forward<Runnable>(condition_))
{
}
private:
Range& range;
Runnable condition;
};
// user code begins here!
#include <iostream>
#include <vector>
int main()
{
std::vector<int> ns{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for ( const auto& n : makeConditionalRange(ns, [](int a) { return a % 2 == 0; }) )
{
std::cout << n << " ";
}
std::cout << "\n";
for ( const auto& n : makeConditionalRange(ns, [](int a) { return a % 2 != 0; }) )
{
std::cout << n << " ";
}
std::cout << "\n";
}
CiNpbmNsdWRlIDx1dGlsaXR5PgoKdGVtcGxhdGUgPHR5cGVuYW1lIEl0ZXJhdG9yLCB0eXBlbmFtZSBSdW5uYWJsZT4Kc3RydWN0IENvbmRpdGlvbmFsSXRlcmF0b3IKewogICBwcml2YXRlOgogICAgICBJdGVyYXRvciBpdGVyYXRvcjsKICAgICAgSXRlcmF0b3IgZW5kOwogICAgICBjb25zdCBSdW5uYWJsZSYgY29uZGl0aW9uOwogICBwdWJsaWM6CiAgICAgIENvbmRpdGlvbmFsSXRlcmF0b3IoSXRlcmF0b3IgYiwgSXRlcmF0b3IgZSwgY29uc3QgUnVubmFibGUmIHIpCiAgICAgIDoKICAgICAgICAgaXRlcmF0b3IoYiksCiAgICAgICAgIGVuZChlKSwKICAgICAgICAgY29uZGl0aW9uKHIpCiAgICAgIHsKICAgICAgfQogICAgICBhdXRvIG9wZXJhdG9yKigpIC0+IGRlY2x0eXBlKCppdGVyYXRvcikKICAgICAgewogICAgICAgICByZXR1cm4gKml0ZXJhdG9yOwogICAgICB9CiAgICAgIENvbmRpdGlvbmFsSXRlcmF0b3ImIG9wZXJhdG9yKysoKQogICAgICB7CiAgICAgICAgIGRvCiAgICAgICAgIHsKICAgICAgICAgICAgKytpdGVyYXRvcjsKICAgICAgICAgfQogICAgICAgICB3aGlsZSAoIGl0ZXJhdG9yICE9IGVuZCAmJiAhY29uZGl0aW9uKCppdGVyYXRvcikgKTsKICAgICAgICAgcmV0dXJuICp0aGlzOwogICAgICB9CiAgICAgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBDb25kaXRpb25hbEl0ZXJhdG9yJiBzZWNvbmQpCiAgICAgIHsKICAgICAgICAgcmV0dXJuIGl0ZXJhdG9yID09IHNlY29uZC5pdGVyYXRvcjsKICAgICAgfQogICAgICBib29sIG9wZXJhdG9yIT0oY29uc3QgQ29uZGl0aW9uYWxJdGVyYXRvciYgc2Vjb25kKQogICAgICB7CiAgICAgICAgIHJldHVybiAhKCp0aGlzID09IHNlY29uZCk7CiAgICAgIH0KfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBSYW5nZSwgdHlwZW5hbWUgUnVubmFibGU+CnN0cnVjdCBDb25kaXRpb25hbFJhbmdlOwoKdGVtcGxhdGUgPHR5cGVuYW1lIFJhbmdlLCB0eXBlbmFtZSBSdW5uYWJsZT4KQ29uZGl0aW9uYWxSYW5nZTxSYW5nZSwgUnVubmFibGU+IG1ha2VDb25kaXRpb25hbFJhbmdlKFJhbmdlJiByYW5nZSwgUnVubmFibGUmJiBjb25kaXRpb24pCnsKICAgc3RhdGljX2Fzc2VydChzdGQ6OmlzX3NhbWU8ZGVjbHR5cGUoY29uZGl0aW9uKCpzdGQ6OmRlY2x2YWw8UmFuZ2U+KCkuYmVnaW4oKSkpLCBib29sPjo6dmFsdWUsICJDb25kaXRpb24gbXVzdCByZXR1cm4gYSBib29sZWFuIHZhbHVlLiIpOwogICByZXR1cm4gQ29uZGl0aW9uYWxSYW5nZTxSYW5nZSwgUnVubmFibGU+KHJhbmdlLCBzdGQ6OmZvcndhcmQ8UnVubmFibGU+KGNvbmRpdGlvbikpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgUmFuZ2UsIHR5cGVuYW1lIFJ1bm5hYmxlPgpzdHJ1Y3QgQ29uZGl0aW9uYWxSYW5nZQp7CiAgIHB1YmxpYzoKICAgICAgZnJpZW5kIENvbmRpdGlvbmFsUmFuZ2UgbWFrZUNvbmRpdGlvbmFsUmFuZ2U8PihSYW5nZSYsIFJ1bm5hYmxlJiYpOwogICBwdWJsaWM6CiAgICAgIHVzaW5nIGl0ZXJhdG9yX3R5cGUgPSBDb25kaXRpb25hbEl0ZXJhdG9yPGRlY2x0eXBlKHN0ZDo6ZGVjbHZhbDxSYW5nZT4oKS5iZWdpbigpKSwgUnVubmFibGU+OwogICAgICBpdGVyYXRvcl90eXBlIGJlZ2luKCkgY29uc3QKICAgICAgewoJICAgICBhdXRvIGIgPSByYW5nZS5iZWdpbigpOwoJICAgICB3aGlsZSAoIGIgIT0gcmFuZ2UuZW5kKCkgJiYgIWNvbmRpdGlvbigqYikgKQoJICAgICB7CgkgICAgICAgICsrYjsKCSAgICAgfQoJICAgICByZXR1cm4gQ29uZGl0aW9uYWxJdGVyYXRvcjxkZWNsdHlwZShzdGQ6OmRlY2x2YWw8UmFuZ2U+KCkuYmVnaW4oKSksIFJ1bm5hYmxlPihiLCByYW5nZS5lbmQoKSwgY29uZGl0aW9uKTsKCSAgfQogICAgICBpdGVyYXRvcl90eXBlIGVuZCgpIGNvbnN0CiAgICAgIHsKICAgICAgCSByZXR1cm4gQ29uZGl0aW9uYWxJdGVyYXRvcjxkZWNsdHlwZShzdGQ6OmRlY2x2YWw8UmFuZ2U+KCkuYmVnaW4oKSksIFJ1bm5hYmxlPihyYW5nZS5lbmQoKSwgcmFuZ2UuZW5kKCksIGNvbmRpdGlvbik7CiAgICAgIH0KICAgcHJpdmF0ZToKICAgICAgQ29uZGl0aW9uYWxSYW5nZShSYW5nZSYgcmFuZ2VfLCBSdW5uYWJsZSYmIGNvbmRpdGlvbl8pCgkgIDoKICAgCQkgcmFuZ2UocmFuZ2VfKSwKICAgCQkgY29uZGl0aW9uKHN0ZDo6Zm9yd2FyZDxSdW5uYWJsZT4oY29uZGl0aW9uXykpCiAgICAgIHsKCSAgfQogICBwcml2YXRlOgogICAgICBSYW5nZSYgcmFuZ2U7CiAgICAgIFJ1bm5hYmxlIGNvbmRpdGlvbjsKfTsKCi8vIHVzZXIgY29kZSBiZWdpbnMgaGVyZSEKCiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHZlY3Rvcj4KCmludCBtYWluKCkKewoJc3RkOjp2ZWN0b3I8aW50PiBuc3swLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5fTsKICAgZm9yICggY29uc3QgYXV0byYgbiA6IG1ha2VDb25kaXRpb25hbFJhbmdlKG5zLCBbXShpbnQgYSkgeyByZXR1cm4gYSAlIDIgPT0gMDsgfSkgKQogICB7CiAgICAgIHN0ZDo6Y291dCA8PCBuIDw8ICIgIjsKICAgfQogICBzdGQ6OmNvdXQgPDwgIlxuIjsKICAgZm9yICggY29uc3QgYXV0byYgbiA6IG1ha2VDb25kaXRpb25hbFJhbmdlKG5zLCBbXShpbnQgYSkgeyByZXR1cm4gYSAlIDIgIT0gMDsgfSkgKQogICB7CiAgICAgIHN0ZDo6Y291dCA8PCBuIDw8ICIgIjsKICAgfQogICBzdGQ6OmNvdXQgPDwgIlxuIjsKfQ==