#ifndef ITER_SLICE_HPP_ #define ITER_SLICE_HPP_ #include "internal/iterbase.hpp" #include #include #include namespace iter { namespace impl { template class Sliced; } template impl::Sliced slice(Container&& container, DifferenceType start, DifferenceType stop, DifferenceType step = 1); template impl::Sliced slice( Container&& container, DifferenceType stop); template impl::Sliced, DifferenceType> slice( std::initializer_list il, DifferenceType start, DifferenceType stop, DifferenceType step = 1); template impl::Sliced, DifferenceType> slice( std::initializer_list il, DifferenceType stop); } template class iter::impl::Sliced { private: Container container; DifferenceType start; DifferenceType stop; DifferenceType step; friend Sliced iter::slice( Container&&, DifferenceType, DifferenceType, DifferenceType); friend Sliced iter::slice( Container&&, DifferenceType); Sliced(Container&& in_container, DifferenceType in_start, DifferenceType in_stop, DifferenceType in_step) : container(std::forward(in_container)), start{in_start < in_stop && in_step > 0 ? in_start : in_stop}, stop{in_stop}, step{in_step} {} public: Sliced(Sliced&&) = default; class Iterator : public std::iterator> { private: iterator_type sub_iter; iterator_type sub_end; DifferenceType current; DifferenceType stop; DifferenceType step; public: Iterator(iterator_type&& si, iterator_type&& se, DifferenceType in_start, DifferenceType in_stop, DifferenceType in_step) : sub_iter{std::move(si)}, sub_end{std::move(se)}, current{in_start}, stop{in_stop}, step{in_step} {} iterator_deref operator*() { return *this->sub_iter; } iterator_arrow operator->() { return apply_arrow(this->sub_iter); } Iterator& operator++() { dumb_advance(this->sub_iter, this->sub_end, this->step); this->current += this->step; if (this->stop < this->current) { this->current = this->stop; } return *this; } Iterator operator++(int) { auto ret = *this; ++*this; return ret; } bool operator!=(const Iterator& other) const { return this->sub_iter != other.sub_iter && this->current != other.current; } bool operator==(const Iterator& other) const { return !(*this != other); } }; Iterator begin() { auto it = std::begin(this->container); dumb_advance(it, std::end(this->container), this->start); return {std::move(it), std::end(this->container), this->start, this->stop, this->step}; } Iterator end() { return {std::end(this->container), std::end(this->container), this->stop, this->stop, this->step}; } }; // Helper function to instantiate a Sliced template iter::impl::Sliced iter::slice(Container&& container, DifferenceType start, DifferenceType stop, DifferenceType step) { return {std::forward(container), start, stop, step}; } // only give the end as an arg and assume step is 1 and begin is 0 template iter::impl::Sliced iter::slice( Container&& container, DifferenceType stop) { return {std::forward(container), 0, stop, 1}; } template iter::impl::Sliced, DifferenceType> iter::slice( std::initializer_list il, DifferenceType start, DifferenceType stop, DifferenceType step) { return {std::move(il), start, stop, step}; } template iter::impl::Sliced, DifferenceType> iter::slice( std::initializer_list il, DifferenceType stop) { return {std::move(il), 0, stop, 1}; } #endif