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<>>
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>
struct enumerate_item
{
@ -49,6 +52,11 @@ namespace blt
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>
class dual_iterator_base
{
@ -81,6 +89,10 @@ namespace blt
Iter2 m_iter2;
};
/**
* Base class for all enumerator iterators. Handles the deference (*) operator.
* @tparam Iter iterator type
*/
template<typename Iter>
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>
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>
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>
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>
@ -162,6 +186,10 @@ namespace blt
using enumerate_forward_iterator<Iter>::enumerate_forward_iterator;
};
/**
* Wrapper class for bidirectional iterators or random access iterators.
* @tparam Iter iterator type.
*/
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>>>
: public enumerate_bidirectional_iterator<Iter>
@ -177,6 +205,11 @@ namespace blt
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>
class enumerator_base
{
@ -196,12 +229,46 @@ namespace blt
{
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:
IterWrapper begin_;
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>
class enumerator_reversible : public enumerator_base<Iter, IterWrapper>
{
@ -216,6 +283,9 @@ namespace blt
IterWrapper{enumerate_wrapper<Iter>{std::move(end), end_index}})
{}
/**
* Reverses the enumerators direction.
*/
auto rev() const
{
return enumerator_rev<Iter>{this->end_.base(),
@ -223,30 +293,41 @@ namespace blt
this->end_.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 begin = this->begin_;
for (blt::size_t i = 0; i < amount; i++)
++begin;
return enumerator<Iter>{begin.base(),
return enumerator<Iter>{this->begin_.base() + amount,
this->end_.base(),
begin.get_index(),
this->begin_.get_index() + amount,
this->end_.get_index()};
}
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_.base() + amount,
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>
class enumerator_reversible_rev : public enumerator_reversible<Iter, IterWrapper>
{
@ -284,8 +365,42 @@ namespace blt
end.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.
* 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:
using enumerator_reversible_rev<Iter, IterWrapper>::enumerator_reversible_rev;
auto skip(blt::size_t amount)
{
return enumerator_rev<Iter>{this->begin_.base().base() - amount,
this->end_.base().base(),
this->begin_.base().get_index() - amount,
this->end_.base().get_index()};
}
auto take(blt::size_t amount)
{
return enumerator_rev<Iter>{this->begin_.base().base(),
this->begin_.base().base() - amount,
this->begin_.base().get_index(),
this->begin_.base().get_index() - amount};
}
};
}
/**
* 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>>
@ -294,6 +409,9 @@ namespace blt
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>>
@ -302,30 +420,20 @@ namespace blt
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_reversible<Iter, iterator::enumerate_wrapper<Iter>>
: public iterator::enumerator_random_access<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};
}
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>>>
@ -334,30 +442,19 @@ namespace blt
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_reversible_rev<Iter, std::reverse_iterator<iterator::enumerate_wrapper<Iter>>>
: public iterator::enumerator_random_access_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)
{
return enumerator_rev<Iter>{this->begin_.base().base() - amount,
this->end_.base().base(),
this->begin_.base().get_index() - amount,
this->end_.base().get_index()};
}
auto take(blt::size_t amount)
{
return enumerator_rev<Iter>{this->begin_.base().base(),
this->begin_.base().base() - amount,
this->begin_.base().get_index(),
this->begin_.base().get_index() - amount};
}
using iterator::enumerator_random_access_rev<Iter, std::reverse_iterator<iterator::enumerate_wrapper<Iter>>>::enumerator_random_access_rev;
};
// CTAD for enumerators
template<typename Iter>
enumerator(Iter, Iter) -> enumerator<Iter>;
@ -367,12 +464,6 @@ namespace blt
template<typename 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>
static inline auto enumerate(const T(& container)[size])
{
@ -397,6 +488,12 @@ namespace blt
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