diff --git a/CMakeLists.txt b/CMakeLists.txt index fb9f575..039d660 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.5) +set(BLT_VERSION 0.21.6) 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 58ec2e8..77084d0 100644 --- a/include/blt/meta/iterator.h +++ b/include/blt/meta/iterator.h @@ -111,6 +111,9 @@ namespace blt::meta { using type = std::common_type_t::iterator_category...>; }; + + template + using lowest_iterator_category_t = typename lowest_iterator_category::type; } #endif //BLT_META_ITERATOR_H diff --git a/include/blt/std/iterator.h b/include/blt/std/iterator.h index ec5e682..cb95c4c 100644 --- a/include/blt/std/iterator.h +++ b/include/blt/std/iterator.h @@ -25,6 +25,7 @@ #include #include #include +#include namespace blt { @@ -42,6 +43,12 @@ namespace blt template> class pair_iterator_rev; + template + class zip_iterator; + + template + class zip_iterator_rev; + namespace iterator { template> @@ -50,6 +57,118 @@ namespace blt template> class pair_wrapper; + template + class zip_wrapper; + + template + class zip_iterator_storage; + + template + class zip_iterator_storage_rev; + + template + class zip_forward_iterator + { + public: + explicit zip_forward_iterator(Iter... iter): iter(std::make_tuple(iter...)) + {} + + std::tuple...> operator*() const + { + return std::apply([](auto& ... i) { return std::make_tuple(*i...); }, iter); + } + + friend bool operator==(const zip_forward_iterator& a, const zip_forward_iterator& b) + { + return a.iter == b.iter; + } + + friend bool operator!=(const zip_forward_iterator& a, const zip_forward_iterator& b) + { + return !(a.iter == b.iter); + } + + zip_forward_iterator& operator++() + { + std::apply([](auto& ... i) { ((++i), ...); }, iter); + return *this; + } + + zip_forward_iterator operator++(int) + { + auto tmp = *this; + ++*this; + return tmp; + } + + auto base() + { + return iter; + } + + protected: + std::tuple iter; + }; + + template + class zip_bidirectional_iterator : public zip_forward_iterator + { + public: + using zip_forward_iterator::zip_forward_iterator; + + zip_bidirectional_iterator& operator--() + { + std::apply([](auto& ... i) { ((--i), ...); }, this->iter); + return *this; + } + + zip_bidirectional_iterator operator--(int) + { + auto tmp = *this; + --*this; + return tmp; + } + }; + + template + class zip_wrapper : public zip_forward_iterator + { + public: + using zip_forward_iterator::zip_forward_iterator; + + using iterator_category = std::forward_iterator_tag; + using value_type = std::tuple...>; + using difference_type = blt::ptrdiff_t; + using pointer = value_type; + using reference = value_type; + }; + + template + class zip_wrapper : public zip_bidirectional_iterator + { + public: + using zip_bidirectional_iterator::zip_bidirectional_iterator; + + using iterator_category = std::bidirectional_iterator_tag; + using value_type = std::tuple...>; + using difference_type = blt::ptrdiff_t; + using pointer = value_type; + using reference = value_type; + }; + + template + class zip_wrapper : public zip_bidirectional_iterator + { + public: + using zip_bidirectional_iterator::zip_bidirectional_iterator; + + using iterator_category = std::bidirectional_iterator_tag; + using value_type = std::tuple...>; + using difference_type = blt::ptrdiff_t; + using pointer = value_type; + using reference = value_type; + }; + /** * struct which is returned by the enumerator. * @tparam T type to store. @@ -188,7 +307,7 @@ namespace blt using pair_forward_iterator = forward_iterator_base>; template - using pair_bidirectional_iterator = bidirectional_iterator_base>; + using pair_bidirectional_iterator = bidirectional_iterator_base>; /** * Enumerator wrapper class specialization for forward iterators. @@ -214,7 +333,7 @@ namespace blt */ template class pair_wrapper>, + blt::meta::is_forward_iterator_category_v>, std::void_t>> : public pair_forward_iterator { public: @@ -236,7 +355,7 @@ namespace blt : public enumerate_bidirectional_iterator { public: - using iterator_category = typename std::iterator_traits::iterator_category; + using iterator_category = std::bidirectional_iterator_tag; using value_type = enumerate_item>; using difference_type = typename std::iterator_traits::difference_type; using pointer = value_type; @@ -251,11 +370,11 @@ namespace blt */ template class pair_wrapper>, + blt::meta::is_bidirectional_or_better_category_v>, std::void_t>> : public pair_bidirectional_iterator { public: - using iterator_category = typename blt::meta::lowest_iterator_category::type; + using iterator_category = std::bidirectional_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; @@ -456,6 +575,37 @@ namespace blt } }; + /** + * Base class for types which can be converted to an enumerator + */ + template + class enumerator_convertible + { + public: + auto enumerate() + { + auto* b = static_cast(this); + return CompleteEnumerator{b->begin(), b->end(), static_cast(std::distance(b->begin(), b->end()))}; + } + }; + + template + class zip_iterator_storage + { + + }; + + template + class zip_iterator_storage + { + + }; + + template + class zip_iterator_storage + { + + }; } @@ -582,9 +732,10 @@ namespace blt template class pair_iterator>, + blt::meta::is_forward_iterator_category_v>, std::void_t>> - : public iterator::iterator_storage_base, pair_iterator> + : public iterator::iterator_storage_base, pair_iterator>, + public iterator::enumerator_convertible, enumerator>> { public: explicit pair_iterator(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2): @@ -597,9 +748,10 @@ namespace blt template class pair_iterator>, + blt::meta::is_bidirectional_iterator_category_v>, std::void_t>> - : public iterator::iterator_storage_reversible, pair_iterator, pair_iterator_rev> + : public iterator::iterator_storage_reversible, pair_iterator, pair_iterator_rev>, + public iterator::enumerator_convertible, enumerator>> { public: explicit pair_iterator(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2): @@ -612,9 +764,10 @@ namespace blt template class pair_iterator>, + blt::meta::is_random_access_iterator_category_v>, std::void_t>> - : public iterator::iterator_storage_random_access, pair_iterator, pair_iterator_rev> + : public iterator::iterator_storage_random_access, pair_iterator, pair_iterator_rev>, + public iterator::enumerator_convertible, enumerator>> { public: explicit pair_iterator(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2): @@ -627,30 +780,36 @@ namespace blt template class pair_iterator_rev>, + blt::meta::is_bidirectional_iterator_category_v>, std::void_t>> - : public iterator::iterator_storage_reversible_rev>, pair_iterator, pair_iterator_rev> + : public iterator::iterator_storage_reversible_rev>, pair_iterator, pair_iterator_rev>, + public iterator::enumerator_convertible, enumerator>> { public: explicit pair_iterator_rev(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2): iterator::iterator_storage_reversible_rev>, pair_iterator, pair_iterator_rev> - {std::reverse_iterator>{iterator::pair_wrapper{std::move(begin1), std::move(begin2)}}, - std::reverse_iterator>{iterator::pair_wrapper{std::move(end1), std::move(end2)}}} + {std::reverse_iterator>{ + iterator::pair_wrapper{std::move(begin1), std::move(begin2)}}, + std::reverse_iterator>{ + iterator::pair_wrapper{std::move(end1), std::move(end2)}}} {} }; template class pair_iterator_rev>, + blt::meta::is_random_access_iterator_category_v>, std::void_t>> - : public iterator::iterator_storage_random_access_rev>, pair_iterator, pair_iterator_rev> + : public iterator::iterator_storage_random_access_rev>, pair_iterator, pair_iterator_rev>, + public iterator::enumerator_convertible, enumerator>> { public: explicit pair_iterator_rev(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2): iterator::iterator_storage_random_access_rev>, pair_iterator, pair_iterator_rev> - {std::reverse_iterator>{iterator::pair_wrapper{std::move(begin1), std::move(begin2)}}, - std::reverse_iterator>{iterator::pair_wrapper{std::move(end1), std::move(end2)}}} + {std::reverse_iterator>{ + iterator::pair_wrapper{std::move(begin1), std::move(begin2)}}, + std::reverse_iterator>{ + iterator::pair_wrapper{std::move(end1), std::move(end2)}}} {} }; @@ -688,31 +847,31 @@ namespace blt { return enumerator{container.begin(), container.end(), container.size()}; } - + template static inline auto in_pairs(const T& container1, const G& container2) { return pair_iterator{container1.begin(), container1.end(), container2.begin(), container2.end()}; } - + template static inline auto in_pairs(T& container1, G& container2) { return pair_iterator{container1.begin(), container1.end(), container2.begin(), container2.end()}; } - + template static inline auto in_pairs(const T(& container1)[size], const G(& container2)[size]) { return pair_iterator{&container1[0], &container1[size], &container2[0], &container2[size]}; } - + template static inline auto in_pairs(T(& container1)[size], G(& container2)[size]) { return pair_iterator{&container1[0], &container1[size], &container2[0], &container2[size]}; } - + template static inline auto in_pairs(T&& container1, G&& container2) {