diff --git a/CMakeLists.txt b/CMakeLists.txt index 662bdf8..b10102d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.20) include(cmake/color.cmake) -set(BLT_VERSION 0.20.22) +set(BLT_VERSION 0.20.23) set(BLT_TEST_VERSION 0.0.1) set(BLT_TARGET BLT) diff --git a/include/blt/std/ranges.h b/include/blt/std/ranges.h index 9ff8bb6..ae3a4fb 100644 --- a/include/blt/std/ranges.h +++ b/include/blt/std/ranges.h @@ -18,6 +18,13 @@ namespace blt { + template::iterator_cateogry> + constexpr bool is_input_or_forward_only = + std::is_same_v || std::is_same_v; + + template::iterator_category> + constexpr bool is_bidirectional_or_better = + std::is_same_v || std::is_same_v; template struct enumerate_item @@ -30,23 +37,7 @@ namespace blt class enumerate_base { public: - explicit enumerate_base(Iter iter): iter(std::move(iter)) - {} - - auto get_iterator() const - { - return iter; - } - - protected: - Iter iter; - }; - - template - class enumerate_base_fwd : public enumerate_base - { - public: - explicit enumerate_base_fwd(Iter iter, blt::size_t place = 0): enumerate_base(std::move(iter)), index(place) + explicit enumerate_base(Iter iter, blt::size_t place = 0): iter(std::move(iter)), index(place) {} enumerate_item>* operator->() const @@ -59,48 +50,66 @@ namespace blt return {index, *this->iter}; } - enumerate_base_fwd& operator++() + friend bool operator==(const enumerate_base& a, const enumerate_base& b) + { + return a.iter == b.iter; + } + + friend bool operator!=(const enumerate_base& a, const enumerate_base& b) + { + return a.iter != b.iter; + } + + auto get_iterator() const + { + return iter; + } + + auto get_index() const + { + return index; + } + + protected: + Iter iter; + blt::size_t index; + }; + + template + class enumerate_fwd : public enumerate_base + { + public: + using enumerate_base::enumerate_base; + + enumerate_fwd& operator++() { ++this->iter; - ++index; + ++this->index; return *this; } - enumerate_base_fwd operator++(int) + enumerate_fwd operator++(int) { auto tmp = *this; ++*this; return tmp; } - - friend bool operator==(const enumerate_base_fwd& a, const enumerate_base_fwd& b) - { - return a.iter == b.iter; - } - - friend bool operator!=(const enumerate_base_fwd& a, const enumerate_base_fwd& b) - { - return a.iter != b.iter; - } - - protected: - blt::size_t index; }; template - class enumerate_base_bidirectional : public enumerate_base_fwd + class enumerate_bidirectional : public enumerate_fwd { public: - using enumerate_base_fwd::enumerate_base_fwd; + using enumerate_fwd::enumerate_fwd; - enumerate_base_bidirectional& operator--() + enumerate_bidirectional& operator--() { --this->iter; --this->index; return *this; } - enumerate_base_bidirectional operator--(int) + enumerate_bidirectional operator--(int) { auto tmp = *this; --*this; @@ -108,19 +117,54 @@ namespace blt } }; - template::iterator_cateogry> - constexpr bool is_input_or_forward_only = - std::is_same_v || std::is_same_v; + template + class enumerate_rev_fwd : public enumerate_base + { + public: + explicit enumerate_rev_fwd(Iter iter, blt::size_t place = 0): enumerate_base(std::move(iter), place) + {} + + enumerate_rev_fwd& operator++() + { + --this->iter; + --this->index; + return *this; + } + + enumerate_rev_fwd operator++(int) + { + auto tmp = *this; + ++*this; + return tmp; + } + }; - template::iterator_category> - constexpr bool is_bidirectional_or_better = - std::is_same_v || std::is_same_v; + template + class enumerate_rev_bidirectional : public enumerate_rev_fwd + { + public: + using enumerate_rev_fwd::enumerate_rev_fwd; + + enumerate_rev_bidirectional& operator--() + { + ++this->iter; + ++this->index; + return *this; + } + + enumerate_rev_bidirectional operator--(int) + { + auto tmp = *this; + --*this; + return tmp; + } + }; template> class enumerate_wrapper; template - class enumerate_wrapper, std::void_t>> : public enumerate_base_fwd + class enumerate_wrapper, std::void_t>> : public enumerate_fwd { public: using iterator_category = std::forward_iterator_tag; @@ -130,12 +174,12 @@ namespace blt using reference = typename std::iterator_traits::reference; using iterator_type = Iter; - using enumerate_base_fwd::enumerate_base_fwd; + using enumerate_fwd::enumerate_fwd; }; template class enumerate_wrapper, std::void_t>> - : public enumerate_base_bidirectional + : public enumerate_bidirectional { public: using iterator_category = std::forward_iterator_tag; @@ -145,7 +189,39 @@ namespace blt using reference = typename std::iterator_traits::reference; using iterator_type = Iter; - using enumerate_base_bidirectional::enumerate_base_bidirectional; + using enumerate_bidirectional::enumerate_bidirectional; + }; + + template> + class enumerate_wrapper_rev; + + template + class enumerate_wrapper_rev, std::void_t>> : public enumerate_rev_fwd + { + public: + using iterator_category = std::forward_iterator_tag; + 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; + using iterator_type = Iter; + + using enumerate_rev_fwd::enumerate_rev_fwd; + }; + + template + class enumerate_wrapper_rev, std::void_t>> + : public enumerate_rev_bidirectional + { + public: + using iterator_category = std::forward_iterator_tag; + 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; + using iterator_type = Iter; + + using enumerate_rev_bidirectional::enumerate_rev_bidirectional; }; namespace itr @@ -236,7 +312,7 @@ namespace blt return itr::itr_container{std::reverse_iterator(std::forward(end)), std::reverse_iterator(std::forward(begin))}; } - template + template typename Iter_type> class enumerator_base { public: @@ -258,44 +334,71 @@ namespace blt } protected: - enumerate_wrapper begin_; - enumerate_wrapper end_; + Iter_type begin_; + Iter_type end_; }; template> class enumerator; template - class enumerator, std::void_t>> : public enumerator_base + class enumerator_rev; + + template + class enumerator, std::void_t>> + : public enumerator_base { public: - using enumerator_base::enumerator_base; + using enumerator_base::enumerator_base; }; template class enumerator, std::void_t>> - : public enumerator_base + : public enumerator_base { public: - using iter = Iter; - using type = decltype(std::reverse_iterator{enumerator::end_}); - //using enumerator_base::enumerator_base; - explicit enumerator(Iter begin, Iter end, blt::size_t container_size): - enumerator_base(std::move(begin), std::move(end)), container_size(container_size) + enumerator_base(std::move(begin), std::move(end)), container_size(container_size) {} explicit enumerator(Iter begin, Iter end, blt::size_t begin_index, blt::size_t end_index): - enumerator_base(std::move(begin), std::move(end), begin_index, end_index), + enumerator_base(std::move(begin), std::move(end), begin_index, end_index), container_size(std::abs(static_cast(end_index) - static_cast(begin_index))) {} auto rev() { - return enumerator>{ - std::reverse_iterator{this->end_.get_iterator()}, - std::reverse_iterator{this->begin_.get_iterator()}, - this->container_size - 1, 0ul}; + auto end = this->end_.get_iterator(); + auto begin = this->begin_.get_iterator(); + --end; + --begin; + return enumerator_rev{end, begin, this->container_size - 1, 0ul}; + } + + protected: + blt::size_t container_size; + }; + + template + class enumerator_rev : public enumerator_base + { + public: + explicit enumerator_rev(Iter begin, Iter end, blt::size_t container_size): + enumerator_base(std::move(begin), std::move(end)), container_size(container_size) + {} + + explicit enumerator_rev(Iter begin, Iter end, blt::size_t begin_index, blt::size_t end_index): + enumerator_base(std::move(begin), std::move(end), begin_index, end_index), + container_size(std::abs(static_cast(end_index) - static_cast(begin_index))) + {} + + auto rev() + { + auto end = this->end_.get_iterator(); + auto begin = this->begin_.get_iterator(); + ++end; + ++begin; + return enumerator{end, begin, container_size + 1}; } protected: