Merge remote-tracking branch 'origin'

v1
Brett 2024-09-26 13:51:20 -04:00
commit a0a2052479
1 changed files with 151 additions and 54 deletions

View File

@ -41,7 +41,10 @@ namespace blt
template<typename Iter, typename = std::void_t<>> template<typename Iter, typename = std::void_t<>>
class enumerate_wrapper; class enumerate_wrapper;
// struct which is returned by the enumerator /**
* struct which is returned by the enumerator.
* @tparam T type to store.
*/
template<typename T> template<typename T>
struct enumerate_item struct enumerate_item
{ {
@ -49,6 +52,11 @@ namespace blt
T value; T value;
}; };
/**
* base class for iterators which operate on pairs of values. Handles comparison.
* @tparam Iter1 first iterator type. this will be used for comparison.
* @tparam Iter2 second iterator type. this value is not modified by this class.
*/
template<typename Iter1, typename Iter2> template<typename Iter1, typename Iter2>
class dual_iterator_base class dual_iterator_base
{ {
@ -81,6 +89,10 @@ namespace blt
Iter2 m_iter2; Iter2 m_iter2;
}; };
/**
* Base class for all enumerator iterators. Handles the deference (*) operator.
* @tparam Iter iterator type
*/
template<typename Iter> template<typename Iter>
class enumerate_iterator_base : public dual_iterator_base<Iter, blt::size_t> class enumerate_iterator_base : public dual_iterator_base<Iter, blt::size_t>
{ {
@ -105,6 +117,10 @@ namespace blt
} }
}; };
/**
* Forward iterator base class for the enumerator. Contains the ++ operator.
* @tparam Iter iterator type.
*/
template<typename Iter> template<typename Iter>
class enumerate_forward_iterator : public enumerate_iterator_base<Iter> class enumerate_forward_iterator : public enumerate_iterator_base<Iter>
{ {
@ -126,6 +142,10 @@ namespace blt
} }
}; };
/**
* Bidirectional iterator base class for the enumerator. Contains the -- operator.
* @tparam Iter iterator type.
*/
template<typename Iter> template<typename Iter>
class enumerate_bidirectional_iterator : public enumerate_forward_iterator<Iter> class enumerate_bidirectional_iterator : public enumerate_forward_iterator<Iter>
{ {
@ -147,6 +167,10 @@ namespace blt
} }
}; };
/**
* Wrapper class specialization for forward iterators.
* @tparam Iter iterator type
*/
template<typename Iter> template<typename Iter>
class enumerate_wrapper<Iter, std::enable_if_t<blt::meta::is_forward_iterator_v<Iter>, std::void_t<std::forward_iterator_tag>>> class enumerate_wrapper<Iter, std::enable_if_t<blt::meta::is_forward_iterator_v<Iter>, std::void_t<std::forward_iterator_tag>>>
: public enumerate_forward_iterator<Iter> : public enumerate_forward_iterator<Iter>
@ -162,6 +186,10 @@ namespace blt
using enumerate_forward_iterator<Iter>::enumerate_forward_iterator; using enumerate_forward_iterator<Iter>::enumerate_forward_iterator;
}; };
/**
* Wrapper class for bidirectional iterators or random access iterators.
* @tparam Iter iterator type.
*/
template<typename Iter> template<typename Iter>
class enumerate_wrapper<Iter, std::enable_if_t<blt::meta::is_bidirectional_or_better_v<Iter>, std::void_t<std::bidirectional_iterator_tag>>> class enumerate_wrapper<Iter, std::enable_if_t<blt::meta::is_bidirectional_or_better_v<Iter>, std::void_t<std::bidirectional_iterator_tag>>>
: public enumerate_bidirectional_iterator<Iter> : public enumerate_bidirectional_iterator<Iter>
@ -177,6 +205,11 @@ namespace blt
using enumerate_bidirectional_iterator<Iter>::enumerate_bidirectional_iterator; using enumerate_bidirectional_iterator<Iter>::enumerate_bidirectional_iterator;
}; };
/**
* Base class for the enumerator. Holds the begin and end iterators.
* @tparam Iter iterator type.
* @tparam IterWrapper wrapper used to iterate (enumerate_wrapper)
*/
template<typename Iter, typename IterWrapper> template<typename Iter, typename IterWrapper>
class enumerator_base class enumerator_base
{ {
@ -197,11 +230,45 @@ namespace blt
return end_; return end_;
} }
/**
* Creates an enumerator that skips the first n elements.
* @param amount amount of values to skip.
*/
auto skip(blt::size_t amount)
{
auto begin = this->begin_;
for (blt::size_t i = 0; i < amount; i++)
++begin;
return enumerator<Iter>{begin.base(),
this->end_.base(),
begin.get_index(),
this->end_.get_index()};
}
/**
* Creates an enumerator that yields the first n elements, or UB if the underlying iterator ends sooner.
* @param amount amount to take.
*/
auto take(blt::size_t amount)
{
auto end = this->begin();
for (blt::size_t i = 0; i < amount; i++)
++end;
return enumerator<Iter>{this->begin_.base(),
end.base(),
this->begin_.get_index(),
end.get_index()};
}
protected: protected:
IterWrapper begin_; IterWrapper begin_;
IterWrapper end_; IterWrapper end_;
}; };
/**
* Reversible (bidirectional) base class for the enumerator.
* @tparam Iter iterator type.
* @tparam IterWrapper wrapper used to iterate (enumerate_wrapper).
*/
template<typename Iter, typename IterWrapper> template<typename Iter, typename IterWrapper>
class enumerator_reversible : public enumerator_base<Iter, IterWrapper> class enumerator_reversible : public enumerator_base<Iter, IterWrapper>
{ {
@ -216,6 +283,9 @@ namespace blt
IterWrapper{enumerate_wrapper<Iter>{std::move(end), end_index}}) IterWrapper{enumerate_wrapper<Iter>{std::move(end), end_index}})
{} {}
/**
* Reverses the enumerators direction.
*/
auto rev() const auto rev() const
{ {
return enumerator_rev<Iter>{this->end_.base(), return enumerator_rev<Iter>{this->end_.base(),
@ -223,30 +293,41 @@ namespace blt
this->end_.get_index(), this->end_.get_index(),
this->begin_.get_index()}; this->begin_.get_index()};
} }
};
/**
* Random access base class for the enumerator. 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).
*/
template<typename Iter, typename IterWrapper>
class enumerator_random_access : public enumerator_reversible<Iter, IterWrapper>
{
public:
using enumerator_reversible<Iter, IterWrapper>::enumerator_reversible;
auto skip(blt::size_t amount) auto skip(blt::size_t amount)
{ {
auto begin = this->begin_; return enumerator<Iter>{this->begin_.base() + amount,
for (blt::size_t i = 0; i < amount; i++)
++begin;
return enumerator<Iter>{begin.base(),
this->end_.base(), this->end_.base(),
begin.get_index(), this->begin_.get_index() + amount,
this->end_.get_index()}; this->end_.get_index()};
} }
auto take(blt::size_t amount) auto take(blt::size_t amount)
{ {
auto end = this->begin();
for (blt::size_t i = 0; i < amount; i++)
++end;
return enumerator<Iter>{this->begin_.base(), return enumerator<Iter>{this->begin_.base(),
end.base(), this->begin_.base() + amount,
this->begin_.get_index(), this->begin_.get_index(),
end.get_index()}; this->begin_.get_index() + amount};
} }
}; };
/**
* Reversible (bidirectional) base class for the enumerator, operates in reverse for reverse enumeration.
* @tparam Iter iterator type.
* @tparam IterWrapper wrapper used to iterate (std::reverse_iterator<enumerate_wrapper>).
*/
template<typename Iter, typename IterWrapper> template<typename Iter, typename IterWrapper>
class enumerator_reversible_rev : public enumerator_reversible<Iter, IterWrapper> class enumerator_reversible_rev : public enumerator_reversible<Iter, IterWrapper>
{ {
@ -284,62 +365,18 @@ namespace blt
end.get_index()}; end.get_index()};
} }
}; };
}
template<typename Iter> /**
class enumerator<Iter, std::enable_if_t<blt::meta::is_forward_iterator_v<Iter>, std::void_t<std::forward_iterator_tag>>> * Random access base class for the enumerator. Has updated skip and take methods which make use of the random access nature of the iterator.
: public iterator::enumerator_base<Iter, iterator::enumerate_wrapper<Iter>> * Operates in reverse for reverse enumeration.
* @tparam Iter iterator type.
* @tparam IterWrapper wrapper used to iterate (std::reverse_iterator<enumerate_wrapper>).
*/
template<typename Iter, typename IterWrapper>
class enumerator_random_access_rev : public enumerator_reversible_rev<Iter, IterWrapper>
{ {
public: public:
using iterator::enumerator_base<Iter, iterator::enumerate_wrapper<Iter>>::enumerator_base; using enumerator_reversible_rev<Iter, IterWrapper>::enumerator_reversible_rev;
};
template<typename Iter>
class enumerator<Iter, std::enable_if_t<blt::meta::is_bidirectional_iterator_v<Iter>, std::void_t<std::bidirectional_iterator_tag>>>
: public iterator::enumerator_reversible<Iter, iterator::enumerate_wrapper<Iter>>
{
public:
using iterator::enumerator_reversible<Iter, iterator::enumerate_wrapper<Iter>>::enumerator_reversible;
};
template<typename Iter>
class enumerator<Iter, std::enable_if_t<blt::meta::is_random_access_iterator_v<Iter>, std::void_t<std::random_access_iterator_tag>>>
: public iterator::enumerator_reversible<Iter, iterator::enumerate_wrapper<Iter>>
{
public:
using iterator::enumerator_reversible<Iter, iterator::enumerate_wrapper<Iter>>::enumerator_reversible;
auto skip(blt::size_t amount)
{
return enumerator<Iter>{this->begin_.base() + amount,
this->end_.base(),
this->begin_.get_index() + amount,
this->end_.get_index()};
}
auto take(blt::size_t amount)
{
return enumerator<Iter>{this->begin_.base(),
this->begin_.base() + amount,
this->begin_.get_index(),
this->begin_.get_index() + amount};
}
};
template<typename Iter>
class enumerator_rev<Iter, std::enable_if_t<blt::meta::is_bidirectional_iterator_v<Iter>, std::void_t<std::bidirectional_iterator_tag>>>
: public iterator::enumerator_reversible_rev<Iter, std::reverse_iterator<iterator::enumerate_wrapper<Iter>>>
{
public:
using iterator::enumerator_reversible_rev<Iter, std::reverse_iterator<iterator::enumerate_wrapper<Iter>>>::enumerator_reversible_rev;
};
template<typename Iter>
class enumerator_rev<Iter, std::enable_if_t<blt::meta::is_random_access_iterator_v<Iter>, std::void_t<std::random_access_iterator_tag>>>
: public iterator::enumerator_reversible_rev<Iter, std::reverse_iterator<iterator::enumerate_wrapper<Iter>>>
{
public:
using iterator::enumerator_reversible_rev<Iter, std::reverse_iterator<iterator::enumerate_wrapper<Iter>>>::enumerator_reversible_rev;
auto skip(blt::size_t amount) auto skip(blt::size_t amount)
{ {
@ -358,6 +395,66 @@ namespace blt
} }
}; };
}
/**
* Enumerator specialization for forward iterators
*/
template<typename Iter>
class enumerator<Iter, std::enable_if_t<blt::meta::is_forward_iterator_v<Iter>, std::void_t<std::forward_iterator_tag>>>
: public iterator::enumerator_base<Iter, iterator::enumerate_wrapper<Iter>>
{
public:
using iterator::enumerator_base<Iter, iterator::enumerate_wrapper<Iter>>::enumerator_base;
};
/**
* Enumerator specialization for bidirectional iterators
*/
template<typename Iter>
class enumerator<Iter, std::enable_if_t<blt::meta::is_bidirectional_iterator_v<Iter>, std::void_t<std::bidirectional_iterator_tag>>>
: public iterator::enumerator_reversible<Iter, iterator::enumerate_wrapper<Iter>>
{
public:
using iterator::enumerator_reversible<Iter, iterator::enumerate_wrapper<Iter>>::enumerator_reversible;
};
/**
* Enumerator specialization for random access iterators
*/
template<typename Iter>
class enumerator<Iter, std::enable_if_t<blt::meta::is_random_access_iterator_v<Iter>, std::void_t<std::random_access_iterator_tag>>>
: public iterator::enumerator_random_access<Iter, iterator::enumerate_wrapper<Iter>>
{
public:
using iterator::enumerator_random_access<Iter, iterator::enumerate_wrapper<Iter>>::enumerator_random_access;
};
/**
* Reverse enumerator specialization for bidirectional iterators
*/
template<typename Iter>
class enumerator_rev<Iter, std::enable_if_t<blt::meta::is_bidirectional_iterator_v<Iter>, std::void_t<std::bidirectional_iterator_tag>>>
: public iterator::enumerator_reversible_rev<Iter, std::reverse_iterator<iterator::enumerate_wrapper<Iter>>>
{
public:
using iterator::enumerator_reversible_rev<Iter, std::reverse_iterator<iterator::enumerate_wrapper<Iter>>>::enumerator_reversible_rev;
};
/**
* Reverse enumerator specialization for random access iterators
*/
template<typename Iter>
class enumerator_rev<Iter, std::enable_if_t<blt::meta::is_random_access_iterator_v<Iter>, std::void_t<std::random_access_iterator_tag>>>
: public iterator::enumerator_random_access_rev<Iter, std::reverse_iterator<iterator::enumerate_wrapper<Iter>>>
{
public:
using iterator::enumerator_random_access_rev<Iter, std::reverse_iterator<iterator::enumerate_wrapper<Iter>>>::enumerator_random_access_rev;
};
// CTAD for enumerators
template<typename Iter> template<typename Iter>
enumerator(Iter, Iter) -> enumerator<Iter>; enumerator(Iter, Iter) -> enumerator<Iter>;
@ -367,12 +464,6 @@ namespace blt
template<typename Iter> template<typename Iter>
enumerator(Iter, Iter, blt::size_t, blt::size_t) -> enumerator<Iter>; enumerator(Iter, Iter, blt::size_t, blt::size_t) -> enumerator<Iter>;
template<typename T>
static inline auto enumerate(const T& container)
{
return enumerator{container.begin(), container.end(), container.size()};
}
template<typename T, blt::size_t size> template<typename T, blt::size_t size>
static inline auto enumerate(const T(& container)[size]) static inline auto enumerate(const T(& container)[size])
{ {
@ -397,6 +488,12 @@ namespace blt
return enumerator{container.begin(), container.end(), container.size()}; return enumerator{container.begin(), container.end(), container.size()};
} }
template<typename T>
static inline auto enumerate(const T& container)
{
return enumerator{container.begin(), container.end(), container.size()};
}
} }
#endif //BLT_ITERATOR_H #endif //BLT_ITERATOR_H