diff --git a/CMakeLists.txt b/CMakeLists.txt index d0ebaf1..014dc94 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.20) include(cmake/color.cmake) -set(BLT_VERSION 1.1.3) +set(BLT_VERSION 1.1.4) set(BLT_TARGET BLT) diff --git a/include/blt/iterator/common.h b/include/blt/iterator/common.h index 12389dc..a415a78 100644 --- a/include/blt/iterator/common.h +++ b/include/blt/iterator/common.h @@ -131,77 +131,49 @@ namespace blt::iterator namespace impls { - template - struct skip_wrapper : public passthrough_wrapper> + template + class skip_t { - public: - using iterator_category = typename std::iterator_traits::iterator_category; - using value_type = typename std::iterator_traits::value_type; - using difference_type = typename std::iterator_traits::difference_type; - using pointer = typename std::iterator_traits::pointer; - using reference = typename std::iterator_traits::reference; - - explicit skip_wrapper(Iter iter, blt::size_t n): passthrough_wrapper>(std::move(iter)), skip(n) - {} - - meta::deref_return_t operator*() const - { - BLT_TRACE("Dereference Skip"); - forward_skip(); - return *this->iter; - } - - skip_wrapper& operator++() - { - BLT_TRACE("Forward Skip"); - forward_skip(); - ++this->iter; - return *this; - } - - skip_wrapper& operator--() - { - BLT_TRACE("Backward Skip"); - forward_skip(); - --this->iter; - return *this; - } - - friend skip_wrapper operator+(const skip_wrapper& a, blt::ptrdiff_t n) - { - static_assert(std::is_same_v, - "Iterator must allow random access"); - return {a.base() + static_cast(a.skip) + n, 0}; - } - - friend skip_wrapper operator-(const skip_wrapper& a, blt::ptrdiff_t n) - { - static_assert(std::is_same_v, - "Iterator must allow random access"); - return {a.base() - static_cast(a.skip) - n, 0}; - } - private: - void forward_skip() const + template + auto skip_base(blt::size_t n) { - if constexpr (std::is_same_v) + auto* d = static_cast(this); + auto begin = d->begin(); + auto end = d->end(); + + if constexpr (std::is_same_v || + std::is_same_v) { - if (skip > 0) + for (blt::size_t i = 0; i < n; i++) { - this->iter = this->iter + skip; - skip = 0; + if constexpr (check) + { + if (begin == end) + break; + } + ++begin; } - } else + return Derived{std::move(begin), std::move(end)}; + } else if constexpr (std::is_same_v) { - while (skip > 0) + // random access iterators can have math directly applied to them. + if constexpr (check) { - ++this->iter; - --skip; + return Derived{begin + std::min(static_cast(n), std::distance(begin, end)), end}; + } else + { + return Derived{begin + n, end}; } } } + + public: + auto skip(blt::size_t n) + { return skip_base(n); } - mutable blt::size_t skip; + auto skip_or(blt::size_t n) + { return skip_base(n); } }; template @@ -256,7 +228,7 @@ namespace blt::iterator } template - class iterator_container : public impls::take_t> + class iterator_container : public impls::take_t>, public impls::skip_t> { public: using iterator_category = typename IterBase::iterator_category; @@ -277,12 +249,6 @@ namespace blt::iterator std::reverse_iterator{begin()}}; } - auto skip(blt::size_t n) - { - return iterator_container>{impls::skip_wrapper{begin(), n}, - impls::skip_wrapper{end(), n}}; - } - auto begin() const { return m_begin;