zip storage. i am in hell

v1
Brett 2024-09-27 18:18:02 -04:00
parent 0ecee088f6
commit 88e8e8fc5b
3 changed files with 187 additions and 25 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
include(cmake/color.cmake) 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_TEST_VERSION 0.0.1)
set(BLT_TARGET BLT) set(BLT_TARGET BLT)

View File

@ -111,6 +111,9 @@ namespace blt::meta
{ {
using type = std::common_type_t<typename std::iterator_traits<Iter>::iterator_category...>; using type = std::common_type_t<typename std::iterator_traits<Iter>::iterator_category...>;
}; };
template<typename... Iter>
using lowest_iterator_category_t = typename lowest_iterator_category<Iter...>::type;
} }
#endif //BLT_META_ITERATOR_H #endif //BLT_META_ITERATOR_H

View File

@ -25,6 +25,7 @@
#include <blt/meta/iterator.h> #include <blt/meta/iterator.h>
#include <type_traits> #include <type_traits>
#include <iterator> #include <iterator>
#include <tuple>
namespace blt namespace blt
{ {
@ -42,6 +43,12 @@ namespace blt
template<typename Iter, typename Iter2, typename = std::void_t<>> template<typename Iter, typename Iter2, typename = std::void_t<>>
class pair_iterator_rev; class pair_iterator_rev;
template<typename... Iter>
class zip_iterator;
template<typename... Iter>
class zip_iterator_rev;
namespace iterator namespace iterator
{ {
template<typename Iter, typename = std::void_t<>> template<typename Iter, typename = std::void_t<>>
@ -50,6 +57,118 @@ namespace blt
template<typename Iter1, typename Iter2, typename = std::void_t<>> template<typename Iter1, typename Iter2, typename = std::void_t<>>
class pair_wrapper; class pair_wrapper;
template<typename Tag, typename... Iter>
class zip_wrapper;
template<typename Tag, typename... Iter>
class zip_iterator_storage;
template<typename Tag, typename... Iter>
class zip_iterator_storage_rev;
template<typename... Iter>
class zip_forward_iterator
{
public:
explicit zip_forward_iterator(Iter... iter): iter(std::make_tuple(iter...))
{}
std::tuple<blt::meta::deref_return_t<Iter>...> 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...> iter;
};
template<typename... Iter>
class zip_bidirectional_iterator : public zip_forward_iterator<Iter...>
{
public:
using zip_forward_iterator<Iter...>::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<typename... Iter>
class zip_wrapper<std::forward_iterator_tag, Iter...> : public zip_forward_iterator<Iter...>
{
public:
using zip_forward_iterator<Iter...>::zip_forward_iterator;
using iterator_category = std::forward_iterator_tag;
using value_type = std::tuple<blt::meta::deref_return_t<Iter>...>;
using difference_type = blt::ptrdiff_t;
using pointer = value_type;
using reference = value_type;
};
template<typename... Iter>
class zip_wrapper<std::bidirectional_iterator_tag, Iter...> : public zip_bidirectional_iterator<Iter...>
{
public:
using zip_bidirectional_iterator<Iter...>::zip_bidirectional_iterator;
using iterator_category = std::bidirectional_iterator_tag;
using value_type = std::tuple<blt::meta::deref_return_t<Iter>...>;
using difference_type = blt::ptrdiff_t;
using pointer = value_type;
using reference = value_type;
};
template<typename... Iter>
class zip_wrapper<std::random_access_iterator_tag, Iter...> : public zip_bidirectional_iterator<Iter...>
{
public:
using zip_bidirectional_iterator<Iter...>::zip_bidirectional_iterator;
using iterator_category = std::bidirectional_iterator_tag;
using value_type = std::tuple<blt::meta::deref_return_t<Iter>...>;
using difference_type = blt::ptrdiff_t;
using pointer = value_type;
using reference = value_type;
};
/** /**
* struct which is returned by the enumerator. * struct which is returned by the enumerator.
* @tparam T type to store. * @tparam T type to store.
@ -188,7 +307,7 @@ namespace blt
using pair_forward_iterator = forward_iterator_base<pair_iterator_base<Iter1, Iter2>>; using pair_forward_iterator = forward_iterator_base<pair_iterator_base<Iter1, Iter2>>;
template<typename Iter1, typename Iter2> template<typename Iter1, typename Iter2>
using pair_bidirectional_iterator = bidirectional_iterator_base<pair_iterator_base<Iter1, Iter2>>; using pair_bidirectional_iterator = bidirectional_iterator_base<pair_forward_iterator<Iter1, Iter2>>;
/** /**
* Enumerator wrapper class specialization for forward iterators. * Enumerator wrapper class specialization for forward iterators.
@ -214,7 +333,7 @@ namespace blt
*/ */
template<typename Iter1, typename Iter2> template<typename Iter1, typename Iter2>
class pair_wrapper<Iter1, Iter2, std::enable_if_t< class pair_wrapper<Iter1, Iter2, std::enable_if_t<
blt::meta::is_forward_iterator_category_v<blt::meta::lowest_iterator_category<Iter1, Iter2>>, blt::meta::is_forward_iterator_category_v<blt::meta::lowest_iterator_category_t<Iter1, Iter2>>,
std::void_t<std::forward_iterator_tag>>> : public pair_forward_iterator<Iter1, Iter2> std::void_t<std::forward_iterator_tag>>> : public pair_forward_iterator<Iter1, Iter2>
{ {
public: public:
@ -236,7 +355,7 @@ namespace blt
: public enumerate_bidirectional_iterator<Iter> : public enumerate_bidirectional_iterator<Iter>
{ {
public: public:
using iterator_category = typename std::iterator_traits<Iter>::iterator_category; using iterator_category = std::bidirectional_iterator_tag;
using value_type = enumerate_item<blt::meta::deref_return_t<Iter>>; using value_type = enumerate_item<blt::meta::deref_return_t<Iter>>;
using difference_type = typename std::iterator_traits<Iter>::difference_type; using difference_type = typename std::iterator_traits<Iter>::difference_type;
using pointer = value_type; using pointer = value_type;
@ -251,11 +370,11 @@ namespace blt
*/ */
template<typename Iter1, typename Iter2> template<typename Iter1, typename Iter2>
class pair_wrapper<Iter1, Iter2, std::enable_if_t< class pair_wrapper<Iter1, Iter2, std::enable_if_t<
blt::meta::is_bidirectional_or_better_category_v<blt::meta::lowest_iterator_category<Iter1, Iter2>>, blt::meta::is_bidirectional_or_better_category_v<blt::meta::lowest_iterator_category_t<Iter1, Iter2>>,
std::void_t<std::bidirectional_iterator_tag>>> : public pair_bidirectional_iterator<Iter1, Iter2> std::void_t<std::bidirectional_iterator_tag>>> : public pair_bidirectional_iterator<Iter1, Iter2>
{ {
public: public:
using iterator_category = typename blt::meta::lowest_iterator_category<Iter1, Iter2>::type; using iterator_category = std::bidirectional_iterator_tag;
using value_type = std::pair<blt::meta::deref_return_t<Iter1>, blt::meta::deref_return_t<Iter2>>; using value_type = std::pair<blt::meta::deref_return_t<Iter1>, blt::meta::deref_return_t<Iter2>>;
using difference_type = std::common_type_t<typename std::iterator_traits<Iter1>::difference_type, typename std::iterator_traits<Iter2>::difference_type>; using difference_type = std::common_type_t<typename std::iterator_traits<Iter1>::difference_type, typename std::iterator_traits<Iter2>::difference_type>;
using pointer = value_type; using pointer = value_type;
@ -456,6 +575,37 @@ namespace blt
} }
}; };
/**
* Base class for types which can be converted to an enumerator
*/
template<typename Derived, typename CompleteEnumerator>
class enumerator_convertible
{
public:
auto enumerate()
{
auto* b = static_cast<Derived*>(this);
return CompleteEnumerator{b->begin(), b->end(), static_cast<blt::size_t>(std::distance(b->begin(), b->end()))};
}
};
template<typename... Iter>
class zip_iterator_storage<std::forward_iterator_tag, Iter...>
{
};
template<typename... Iter>
class zip_iterator_storage<std::bidirectional_iterator_tag, Iter...>
{
};
template<typename... Iter>
class zip_iterator_storage<std::random_access_iterator_tag, Iter...>
{
};
} }
@ -582,9 +732,10 @@ namespace blt
template<typename Iter1, typename Iter2> template<typename Iter1, typename Iter2>
class pair_iterator<Iter1, Iter2, class pair_iterator<Iter1, Iter2,
std::enable_if_t< std::enable_if_t<
blt::meta::is_forward_iterator_category_v<blt::meta::lowest_iterator_category<Iter1, Iter2>>, blt::meta::is_forward_iterator_category_v<blt::meta::lowest_iterator_category_t<Iter1, Iter2>>,
std::void_t<std::forward_iterator_tag>>> std::void_t<std::forward_iterator_tag>>>
: public iterator::iterator_storage_base<iterator::pair_wrapper<Iter1, Iter2>, pair_iterator<Iter1, Iter2>> : public iterator::iterator_storage_base<iterator::pair_wrapper<Iter1, Iter2>, pair_iterator<Iter1, Iter2>>,
public iterator::enumerator_convertible<pair_iterator<Iter1, Iter2>, enumerator<iterator::pair_wrapper<Iter1, Iter2>>>
{ {
public: public:
explicit pair_iterator(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2): explicit pair_iterator(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2):
@ -597,9 +748,10 @@ namespace blt
template<typename Iter1, typename Iter2> template<typename Iter1, typename Iter2>
class pair_iterator<Iter1, Iter2, class pair_iterator<Iter1, Iter2,
std::enable_if_t< std::enable_if_t<
blt::meta::is_bidirectional_iterator_category_v<blt::meta::lowest_iterator_category<Iter1, Iter2>>, blt::meta::is_bidirectional_iterator_category_v<blt::meta::lowest_iterator_category_t<Iter1, Iter2>>,
std::void_t<std::bidirectional_iterator_tag>>> std::void_t<std::bidirectional_iterator_tag>>>
: public iterator::iterator_storage_reversible<iterator::pair_wrapper<Iter1, Iter2>, pair_iterator<Iter1, Iter2>, pair_iterator_rev<Iter1, Iter2>> : public iterator::iterator_storage_reversible<iterator::pair_wrapper<Iter1, Iter2>, pair_iterator<Iter1, Iter2>, pair_iterator_rev<Iter1, Iter2>>,
public iterator::enumerator_convertible<pair_iterator<Iter1, Iter2>, enumerator<iterator::pair_wrapper<Iter1, Iter2>>>
{ {
public: public:
explicit pair_iterator(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2): explicit pair_iterator(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2):
@ -612,9 +764,10 @@ namespace blt
template<typename Iter1, typename Iter2> template<typename Iter1, typename Iter2>
class pair_iterator<Iter1, Iter2, class pair_iterator<Iter1, Iter2,
std::enable_if_t< std::enable_if_t<
blt::meta::is_random_access_iterator_category_v<blt::meta::lowest_iterator_category<Iter1, Iter2>>, blt::meta::is_random_access_iterator_category_v<blt::meta::lowest_iterator_category_t<Iter1, Iter2>>,
std::void_t<std::random_access_iterator_tag>>> std::void_t<std::random_access_iterator_tag>>>
: public iterator::iterator_storage_random_access<iterator::pair_wrapper<Iter1, Iter2>, pair_iterator<Iter1, Iter2>, pair_iterator_rev<Iter1, Iter2>> : public iterator::iterator_storage_random_access<iterator::pair_wrapper<Iter1, Iter2>, pair_iterator<Iter1, Iter2>, pair_iterator_rev<Iter1, Iter2>>,
public iterator::enumerator_convertible<pair_iterator<Iter1, Iter2>, enumerator<iterator::pair_wrapper<Iter1, Iter2>>>
{ {
public: public:
explicit pair_iterator(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2): explicit pair_iterator(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2):
@ -627,30 +780,36 @@ namespace blt
template<typename Iter1, typename Iter2> template<typename Iter1, typename Iter2>
class pair_iterator_rev<Iter1, Iter2, class pair_iterator_rev<Iter1, Iter2,
std::enable_if_t< std::enable_if_t<
blt::meta::is_bidirectional_iterator_category_v<blt::meta::lowest_iterator_category<Iter1, Iter2>>, blt::meta::is_bidirectional_iterator_category_v<blt::meta::lowest_iterator_category_t<Iter1, Iter2>>,
std::void_t<std::bidirectional_iterator_tag>>> std::void_t<std::bidirectional_iterator_tag>>>
: public iterator::iterator_storage_reversible_rev<std::reverse_iterator<iterator::pair_wrapper<Iter1, Iter2>>, pair_iterator<Iter1, Iter2>, pair_iterator_rev<Iter1, Iter2>> : public iterator::iterator_storage_reversible_rev<std::reverse_iterator<iterator::pair_wrapper<Iter1, Iter2>>, pair_iterator<Iter1, Iter2>, pair_iterator_rev<Iter1, Iter2>>,
public iterator::enumerator_convertible<pair_iterator<Iter1, Iter2>, enumerator<iterator::pair_wrapper<Iter1, Iter2>>>
{ {
public: public:
explicit pair_iterator_rev(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2): explicit pair_iterator_rev(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2):
iterator::iterator_storage_reversible_rev<std::reverse_iterator<iterator::pair_wrapper<Iter1, Iter2>>, pair_iterator<Iter1, Iter2>, pair_iterator_rev<Iter1, Iter2>> iterator::iterator_storage_reversible_rev<std::reverse_iterator<iterator::pair_wrapper<Iter1, Iter2>>, pair_iterator<Iter1, Iter2>, pair_iterator_rev<Iter1, Iter2>>
{std::reverse_iterator<iterator::pair_wrapper<Iter1, Iter2>>{iterator::pair_wrapper<Iter1, Iter2>{std::move(begin1), std::move(begin2)}}, {std::reverse_iterator<iterator::pair_wrapper<Iter1, Iter2>>{
std::reverse_iterator<iterator::pair_wrapper<Iter1, Iter2>>{iterator::pair_wrapper<Iter1, Iter2>{std::move(end1), std::move(end2)}}} iterator::pair_wrapper<Iter1, Iter2>{std::move(begin1), std::move(begin2)}},
std::reverse_iterator<iterator::pair_wrapper<Iter1, Iter2>>{
iterator::pair_wrapper<Iter1, Iter2>{std::move(end1), std::move(end2)}}}
{} {}
}; };
template<typename Iter1, typename Iter2> template<typename Iter1, typename Iter2>
class pair_iterator_rev<Iter1, Iter2, class pair_iterator_rev<Iter1, Iter2,
std::enable_if_t< std::enable_if_t<
blt::meta::is_random_access_iterator_category_v<blt::meta::lowest_iterator_category<Iter1, Iter2>>, blt::meta::is_random_access_iterator_category_v<blt::meta::lowest_iterator_category_t<Iter1, Iter2>>,
std::void_t<std::random_access_iterator_tag>>> std::void_t<std::random_access_iterator_tag>>>
: public iterator::iterator_storage_random_access_rev<std::reverse_iterator<iterator::pair_wrapper<Iter1, Iter2>>, pair_iterator<Iter1, Iter2>, pair_iterator_rev<Iter1, Iter2>> : public iterator::iterator_storage_random_access_rev<std::reverse_iterator<iterator::pair_wrapper<Iter1, Iter2>>, pair_iterator<Iter1, Iter2>, pair_iterator_rev<Iter1, Iter2>>,
public iterator::enumerator_convertible<pair_iterator<Iter1, Iter2>, enumerator<iterator::pair_wrapper<Iter1, Iter2>>>
{ {
public: public:
explicit pair_iterator_rev(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2): explicit pair_iterator_rev(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2):
iterator::iterator_storage_random_access_rev<std::reverse_iterator<iterator::pair_wrapper<Iter1, Iter2>>, pair_iterator<Iter1, Iter2>, pair_iterator_rev<Iter1, Iter2>> iterator::iterator_storage_random_access_rev<std::reverse_iterator<iterator::pair_wrapper<Iter1, Iter2>>, pair_iterator<Iter1, Iter2>, pair_iterator_rev<Iter1, Iter2>>
{std::reverse_iterator<iterator::pair_wrapper<Iter1, Iter2>>{iterator::pair_wrapper<Iter1, Iter2>{std::move(begin1), std::move(begin2)}}, {std::reverse_iterator<iterator::pair_wrapper<Iter1, Iter2>>{
std::reverse_iterator<iterator::pair_wrapper<Iter1, Iter2>>{iterator::pair_wrapper<Iter1, Iter2>{std::move(end1), std::move(end2)}}} iterator::pair_wrapper<Iter1, Iter2>{std::move(begin1), std::move(begin2)}},
std::reverse_iterator<iterator::pair_wrapper<Iter1, Iter2>>{
iterator::pair_wrapper<Iter1, Iter2>{std::move(end1), std::move(end2)}}}
{} {}
}; };