#ifndef MORE_ADAPTORS_FIRST_N_HPP_ #define MORE_ADAPTORS_FIRST_N_HPP_ #include #include namespace more { namespace range_detail { template class first_n_iterator : public boost::iterator_adaptor, Iterator> { public: explicit first_n_iterator(const Iterator& it) : first_n_iterator::iterator_adaptor_(it), initial(it), count(0) {} first_n_iterator(const Iterator& it, std::size_t n) : first_n_iterator::iterator_adaptor_(it), initial(it), count(n) {} // using compiler provided copy constructor and copy assignment private: friend class boost::iterator_core_access; void increment() { ++(this->base_reference()); ++count; } bool equal(first_n_iterator const& other) const { return this->initial == other.initial && this->count == other.count; } Iterator initial; // used to be able to differentiate ranges std::size_t count; }; struct first_nd { first_nd(std::size_t n) : n(n) {} std::size_t n; }; template class first_nd_range : public boost::iterator_range< first_n_iterator < typename boost::range_iterator::type> > { typedef boost::iterator_range< first_n_iterator < typename boost::range_iterator::type> > base_t; public: first_nd_range(SinglePassRange& r, std::size_t n) : base_t(boost::make_iterator_range( first_n_iterator< typename boost::range_iterator::type > (r.begin()), first_n_iterator< typename boost::range_iterator::type > (r.begin(),n) )) { } }; template< class SinglePassRange > inline first_nd_range operator|(SinglePassRange& r, const first_nd& f) { return first_nd_range(r, f.n); } template< class SinglePassRange > inline first_nd_range operator|(const SinglePassRange& r, const first_nd& f) { return first_nd_range(r, f.n); } } // namespace range_detail using range_detail::first_nd_range; namespace adaptors { using range_detail::first_nd; template inline first_nd_range first_n(SinglePassRange& r, std::size_t n) { return first_nd_range(r,n); } template inline first_nd_range first_n(const SinglePassRange& r, std::size_t n) { return first_nd_range(r,n); } } // namespace adaptors } // namespace more #endif /* MORE_ADAPTORS_FIRST_N_HPP_ */