
#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";
}