diff --git a/CMakeLists.txt b/CMakeLists.txt index 44a26ae..ecfc9ba 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.21.3) +set(BLT_VERSION 0.21.4) set(BLT_TEST_VERSION 0.0.1) set(BLT_TARGET BLT) diff --git a/include/blt/meta/iterator.h b/include/blt/meta/iterator.h index e5873f6..58ec2e8 100644 --- a/include/blt/meta/iterator.h +++ b/include/blt/meta/iterator.h @@ -24,27 +24,71 @@ namespace blt::meta { + template + struct is_input_iterator_category + { + constexpr static bool value = std::is_same_v; + }; + + template + struct is_forward_iterator_category + { + constexpr static bool value = std::is_same_v; + }; + + template + struct is_bidirectional_iterator_category + { + constexpr static bool value = std::is_same_v; + }; + + template + struct is_random_access_iterator_category + { + constexpr static bool value = std::is_same_v; + }; + + template + inline constexpr bool is_input_iterator_category_v = is_input_iterator_category::value; + + template + inline constexpr bool is_forward_iterator_category_v = is_forward_iterator_category::value; + + template + inline constexpr bool is_bidirectional_iterator_category_v = is_bidirectional_iterator_category::value; + + template + inline constexpr bool is_random_access_iterator_category_v = is_random_access_iterator_category::value; + + template + inline constexpr bool is_bidirectional_or_better_category_v = + is_bidirectional_iterator_category_v || is_random_access_iterator_category_v; + // this is required! :/ template - struct is_input_iterator { - constexpr static bool value = std::is_same_v::iterator_category, std::input_iterator_tag>; + struct is_input_iterator + { + constexpr static bool value = is_input_iterator_category_v::iterator_category>; }; template - struct is_forward_iterator { - constexpr static bool value = std::is_same_v::iterator_category, std::forward_iterator_tag>; + struct is_forward_iterator + { + constexpr static bool value = is_forward_iterator_category_v::iterator_category>; }; template - struct is_bidirectional_iterator { - constexpr static bool value = std::is_same_v::iterator_category, std::bidirectional_iterator_tag>; + struct is_bidirectional_iterator + { + constexpr static bool value = is_bidirectional_iterator_category_v::iterator_category>; }; template - struct is_random_access_iterator { - constexpr static bool value = std::is_same_v::iterator_category, std::random_access_iterator_tag>; + struct is_random_access_iterator + { + constexpr static bool value = is_random_access_iterator_category_v::iterator_category>; }; template @@ -61,6 +105,12 @@ namespace blt::meta template inline constexpr bool is_bidirectional_or_better_v = is_bidirectional_iterator_v || is_random_access_iterator_v; + + template + struct lowest_iterator_category + { + using type = std::common_type_t::iterator_category...>; + }; } #endif //BLT_META_ITERATOR_H diff --git a/include/blt/std/iterator.h b/include/blt/std/iterator.h index 7fa9ec2..5096fa9 100644 --- a/include/blt/std/iterator.h +++ b/include/blt/std/iterator.h @@ -41,6 +41,9 @@ namespace blt template> class enumerate_wrapper; + template> + class pair_wrapper; + /** * struct which is returned by the enumerator. * @tparam T type to store. @@ -105,36 +108,38 @@ namespace blt { return {this->m_iter2, *this->m_iter1}; } + }; + + template + class pair_iterator_base : public dual_iterator_base + { + public: + using dual_iterator_base::dual_iterator_base; - auto base() const + std::pair, blt::meta::deref_return_t> operator*() const { - return this->iter1(); - } - - auto get_index() const - { - return this->iter2(); + return {*this->m_iter1, *this->m_iter2}; } }; /** - * Forward iterator base class for the enumerator. Contains the ++ operator. - * @tparam Iter iterator type. + * Forward iterator base class. Contains the ++ operator. + * @tparam Base iterator base type. */ - template - class enumerate_forward_iterator : public enumerate_iterator_base + template + class forward_iterator_base : public Base { public: - using enumerate_iterator_base::enumerate_iterator_base; + using Base::Base; - enumerate_forward_iterator& operator++() + forward_iterator_base& operator++() { ++this->m_iter1; ++this->m_iter2; return *this; } - enumerate_forward_iterator operator++(int) + forward_iterator_base operator++(int) { auto tmp = *this; ++*this; @@ -143,23 +148,23 @@ namespace blt }; /** - * Bidirectional iterator base class for the enumerator. Contains the -- operator. - * @tparam Iter iterator type. + * Bidirectional iterator base class. Contains the -- operator. + * @tparam Base iterator base type. */ - template - class enumerate_bidirectional_iterator : public enumerate_forward_iterator + template + class bidirectional_iterator_base : public Base { public: - using enumerate_forward_iterator::enumerate_forward_iterator; + using Base::Base; - enumerate_bidirectional_iterator& operator--() + bidirectional_iterator_base& operator--() { --this->m_iter1; --this->m_iter2; return *this; } - enumerate_bidirectional_iterator operator--(int) + bidirectional_iterator_base operator--(int) { auto tmp = *this; --*this; @@ -167,8 +172,20 @@ namespace blt } }; + template + using enumerate_forward_iterator = forward_iterator_base>; + + template + using enumerate_bidirectional_iterator = bidirectional_iterator_base>; + + template + using pair_forward_iterator = forward_iterator_base>; + + template + using pair_bidirectional_iterator = bidirectional_iterator_base>; + /** - * Wrapper class specialization for forward iterators. + * Enumerator wrapper class specialization for forward iterators. * @tparam Iter iterator type */ template @@ -181,13 +198,32 @@ namespace blt using difference_type = typename std::iterator_traits::difference_type; using pointer = value_type; using reference = value_type; - using iterator_type = Iter; using enumerate_forward_iterator::enumerate_forward_iterator; }; /** - * Wrapper class for bidirectional iterators or random access iterators. + * Pair wrapper class specialization for forward iterators. + * @tparam Iter iterator type + */ + template + class pair_wrapper>, + std::void_t + >> : public pair_forward_iterator + { + public: + using iterator_category = std::forward_iterator_tag; + using value_type = std::pair, blt::meta::deref_return_t>; + using difference_type = std::common_type_t::difference_type, typename std::iterator_traits::difference_type>; + using pointer = value_type; + using reference = value_type; + + using pair_forward_iterator::pair_forward_iterator; + }; + + /** + * Enumerator wrapper class for bidirectional iterators or random access iterators. * @tparam Iter iterator type. */ template @@ -200,24 +236,44 @@ namespace blt using difference_type = typename std::iterator_traits::difference_type; using pointer = value_type; using reference = value_type; - using iterator_type = Iter; using enumerate_bidirectional_iterator::enumerate_bidirectional_iterator; }; /** - * Base class for the enumerator. Holds the begin and end iterators. + * Pair wrapper class for bidirectional iterators or random access iterators. * @tparam Iter iterator type. - * @tparam IterWrapper wrapper used to iterate (enumerate_wrapper) */ - template - class enumerator_base + template + class pair_wrapper>, + std::void_t + >> : public pair_bidirectional_iterator { public: - explicit enumerator_base(Iter begin, Iter end): begin_(std::move(begin)), end_(std::move(end)) + using iterator_category = typename blt::meta::lowest_iterator_category::type; + using value_type = std::pair, blt::meta::deref_return_t>; + using difference_type = std::common_type_t::difference_type, typename std::iterator_traits::difference_type>; + using pointer = value_type; + using reference = value_type; + + using pair_bidirectional_iterator::pair_bidirectional_iterator; + }; + + /** + * Base class for storing begin/end iterators. + * @tparam Iter iterator type. + * @tparam IterWrapper wrapper used to iterate + * @tparam CompleteClass completed class returned from skip/take methods + */ + template + class iterator_storage_base + { + public: + explicit iterator_storage_base(Iter begin, Iter end): begin_(std::move(begin)), end_(std::move(end)) {} - explicit enumerator_base(IterWrapper begin, IterWrapper end): begin_(std::move(begin)), end_(std::move(end)) + explicit iterator_storage_base(IterWrapper begin, IterWrapper end): begin_(std::move(begin)), end_(std::move(end)) {} auto begin() @@ -239,10 +295,10 @@ namespace blt auto begin = this->begin_; for (blt::size_t i = 0; i < amount; i++) ++begin; - return enumerator{begin.base(), - this->end_.base(), - begin.get_index(), - this->end_.get_index()}; + return CompleteClass{begin.iter1(), + this->end_.iter1(), + begin.iter2(), + this->end_.iter2()}; } /** @@ -254,33 +310,36 @@ namespace blt auto end = this->begin(); for (blt::size_t i = 0; i < amount; i++) ++end; - return enumerator{this->begin_.base(), - end.base(), - this->begin_.get_index(), - end.get_index()}; + return CompleteClass{this->begin_.iter1(), + end.iter1(), + this->begin_.iter2(), + end.iter2()}; } + protected: IterWrapper begin_; IterWrapper end_; }; /** - * Reversible (bidirectional) base class for the enumerator. + * Reversible (bidirectional) base class storing the begin / end iterators. * @tparam Iter iterator type. - * @tparam IterWrapper wrapper used to iterate (enumerate_wrapper). + * @tparam IterWrapper wrapper used to iterate. + * @tparam CompleteClass completed class returned from skip/take methods + * @tparam CompleteClassRev reverse version of CompleteClass, returned from rev */ - template - class enumerator_reversible : public enumerator_base + template + class iterator_storage_reversible : public iterator_storage_base { public: - explicit enumerator_reversible(Iter begin, Iter end, blt::size_t container_size): - enumerator_base{IterWrapper{enumerate_wrapper{std::move(begin), 0}}, - IterWrapper{enumerate_wrapper{std::move(end), container_size}}} + explicit iterator_storage_reversible(Iter begin, Iter end, blt::size_t container_size): + iterator_storage_base{IterWrapper{enumerate_wrapper{std::move(begin), 0}}, + IterWrapper{enumerate_wrapper{std::move(end), container_size}}} {} - explicit enumerator_reversible(Iter begin, Iter end, blt::size_t begin_index, blt::size_t end_index): - enumerator_base(IterWrapper{enumerate_wrapper{std::move(begin), begin_index}}, - IterWrapper{enumerate_wrapper{std::move(end), end_index}}) + explicit iterator_storage_reversible(Iter begin, Iter end, blt::size_t begin_index, blt::size_t end_index): + iterator_storage_base(IterWrapper{enumerate_wrapper{std::move(begin), begin_index}}, + IterWrapper{enumerate_wrapper{std::move(end), end_index}}) {} /** @@ -288,58 +347,63 @@ namespace blt */ auto rev() const { - return enumerator_rev{this->end_.base(), - this->begin_.base(), - this->end_.get_index(), - this->begin_.get_index()}; + return CompleteClassRev{this->end_.iter1(), + this->begin_.iter1(), + this->end_.iter2(), + this->begin_.iter2()}; } }; /** - * Random access base class for the enumerator. Has updated skip and take methods which make use of the random access nature of the iterator. + * Random access base class storage for begin/end iterators. + * Has updated skip and take methods which make use of the random access nature of the iterator. * @tparam Iter iterator type. - * @tparam IterWrapper wrapper used to iterate (enumerate_wrapper). + * @tparam IterWrapper wrapper used to iterate. + * @tparam CompleteClass completed class returned from skip/take methods + * @tparam CompleteClassRev reverse version of CompleteClass, returned from rev */ - template - class enumerator_random_access : public enumerator_reversible + template + class iterator_storage_random_access : public iterator_storage_reversible { public: - using enumerator_reversible::enumerator_reversible; + using iterator_storage_reversible::iterator_storage_reversible; auto skip(blt::size_t amount) { - return enumerator{this->begin_.base() + amount, - this->end_.base(), - this->begin_.get_index() + amount, - this->end_.get_index()}; + return CompleteClass{this->begin_.iter1() + amount, + this->end_.iter1(), + this->begin_.iter2() + amount, + this->end_.iter2()}; } auto take(blt::size_t amount) { - return enumerator{this->begin_.base(), - this->begin_.base() + amount, - this->begin_.get_index(), - this->begin_.get_index() + amount}; + return CompleteClass{this->begin_.iter1(), + this->begin_.iter1() + amount, + this->begin_.iter2(), + this->begin_.iter2() + amount}; } }; /** - * Reversible (bidirectional) base class for the enumerator, operates in reverse for reverse enumeration. + * Reversible (bidirectional) base class for storing the begin/end iterators, operates in reverse for reverse iteration. * @tparam Iter iterator type. * @tparam IterWrapper wrapper used to iterate (std::reverse_iterator). + * @tparam CompleteClass completed class returned from skip/take methods + * @tparam CompleteClassRev reverse version of CompleteClass, returned from rev */ - template - class enumerator_reversible_rev : public enumerator_reversible + template + class iterator_storage_reversible_rev : public iterator_storage_reversible { public: - using enumerator_reversible::enumerator_reversible; + using iterator_storage_reversible::iterator_storage_reversible; auto rev() const { - return enumerator{this->end_.base().base(), - this->begin_.base().base(), - this->end_.base().get_index(), - this->begin_.base().get_index()}; + return CompleteClass{this->end_.base().iter1(), + this->begin_.base().iter1(), + this->end_.base().iter2(), + this->begin_.base().iter2()}; } auto skip(blt::size_t amount) @@ -347,10 +411,10 @@ namespace blt auto begin = this->begin_.base(); for (blt::size_t i = 0; i < amount; i++) --begin; - return enumerator_rev{begin.base(), - this->end_.base().base(), - begin.get_index(), - this->end_.base().get_index()}; + return CompleteClassRev{begin.iter1(), + this->end_.base().iter1(), + begin.iter2(), + this->end_.base().iter2()}; } auto take(blt::size_t amount) @@ -358,40 +422,43 @@ namespace blt auto end = this->begin_.base(); for (blt::size_t i = 0; i < amount; i++) --end; - return enumerator_rev{ - this->begin_.base().base(), - end.base(), - this->begin_.base().get_index(), - end.get_index()}; + return CompleteClassRev{ + this->begin_.base().iter1(), + end.iter1(), + this->begin_.base().iter2(), + end.iter2()}; } }; /** - * Random access base class for the enumerator. Has updated skip and take methods which make use of the random access nature of the iterator. - * Operates in reverse for reverse enumeration. + * Random access base class for storing the begin/end iterator. + * Has updated skip and take methods which make use of the random access nature of the iterator. + * Operates in reverse for reverse iteration. * @tparam Iter iterator type. * @tparam IterWrapper wrapper used to iterate (std::reverse_iterator). + * @tparam CompleteClass completed class returned from skip/take methods + * @tparam CompleteClassRev reverse version of CompleteClass, returned from rev */ - template - class enumerator_random_access_rev : public enumerator_reversible_rev + template + class iterator_storage_random_access_rev : public iterator_storage_reversible_rev { public: - using enumerator_reversible_rev::enumerator_reversible_rev; + using iterator_storage_reversible_rev::iterator_storage_reversible_rev; auto skip(blt::size_t amount) { - return enumerator_rev{this->begin_.base().base() - amount, - this->end_.base().base(), - this->begin_.base().get_index() - amount, - this->end_.base().get_index()}; + return CompleteClassRev{this->begin_.base().iter1() - amount, + this->end_.base().iter1(), + this->begin_.base().iter2() - amount, + this->end_.base().iter2()}; } auto take(blt::size_t amount) { - return enumerator_rev{this->begin_.base().base(), - this->begin_.base().base() - amount, - this->begin_.base().get_index(), - this->begin_.base().get_index() - amount}; + return CompleteClassRev{this->begin_.base().iter1(), + this->begin_.base().iter1() - amount, + this->begin_.base().iter2(), + this->begin_.base().iter2() - amount}; } }; @@ -403,10 +470,10 @@ namespace blt */ template class enumerator, std::void_t>> - : public iterator::enumerator_base> + : public iterator::iterator_storage_base, enumerator> { public: - using iterator::enumerator_base>::enumerator_base; + using iterator::iterator_storage_base, enumerator>::iterator_storage_base; }; /** @@ -414,10 +481,10 @@ namespace blt */ template class enumerator, std::void_t>> - : public iterator::enumerator_reversible> + : public iterator::iterator_storage_reversible, enumerator, enumerator_rev> { public: - using iterator::enumerator_reversible>::enumerator_reversible; + using iterator::iterator_storage_reversible, enumerator, enumerator_rev>::iterator_storage_reversible; }; /** @@ -425,10 +492,10 @@ namespace blt */ template class enumerator, std::void_t>> - : public iterator::enumerator_random_access> + : public iterator::iterator_storage_random_access, enumerator, enumerator_rev> { public: - using iterator::enumerator_random_access>::enumerator_random_access; + using iterator::iterator_storage_random_access, enumerator, enumerator_rev>::iterator_storage_random_access; }; /** @@ -436,10 +503,10 @@ namespace blt */ template class enumerator_rev, std::void_t>> - : public iterator::enumerator_reversible_rev>> + : public iterator::iterator_storage_reversible_rev>, enumerator, enumerator_rev> { public: - using iterator::enumerator_reversible_rev>>::enumerator_reversible_rev; + using iterator::iterator_storage_reversible_rev>, enumerator, enumerator_rev>::iterator_storage_reversible_rev; }; /** @@ -447,10 +514,10 @@ namespace blt */ template class enumerator_rev, std::void_t>> - : public iterator::enumerator_random_access_rev>> + : public iterator::iterator_storage_random_access_rev>, enumerator, enumerator_rev> { public: - using iterator::enumerator_random_access_rev>>::enumerator_random_access_rev; + using iterator::iterator_storage_random_access_rev>, enumerator, enumerator_rev>::iterator_storage_random_access_rev; }; // CTAD for enumerators