Merge remote-tracking branch 'origin'
commit
a0a2052479
|
@ -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 enumerator’s 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,8 +365,42 @@ namespace blt
|
||||||
end.get_index()};
|
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>
|
template<typename Iter>
|
||||||
class enumerator<Iter, std::enable_if_t<blt::meta::is_forward_iterator_v<Iter>, std::void_t<std::forward_iterator_tag>>>
|
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 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;
|
using iterator::enumerator_base<Iter, iterator::enumerate_wrapper<Iter>>::enumerator_base;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumerator specialization for bidirectional iterators
|
||||||
|
*/
|
||||||
template<typename Iter>
|
template<typename Iter>
|
||||||
class enumerator<Iter, std::enable_if_t<blt::meta::is_bidirectional_iterator_v<Iter>, std::void_t<std::bidirectional_iterator_tag>>>
|
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 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;
|
using iterator::enumerator_reversible<Iter, iterator::enumerate_wrapper<Iter>>::enumerator_reversible;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumerator specialization for random access iterators
|
||||||
|
*/
|
||||||
template<typename Iter>
|
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>>>
|
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:
|
public:
|
||||||
using iterator::enumerator_reversible<Iter, iterator::enumerate_wrapper<Iter>>::enumerator_reversible;
|
using iterator::enumerator_random_access<Iter, iterator::enumerate_wrapper<Iter>>::enumerator_random_access;
|
||||||
|
|
||||||
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};
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse enumerator specialization for bidirectional iterators
|
||||||
|
*/
|
||||||
template<typename Iter>
|
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>>>
|
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 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;
|
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>
|
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>>>
|
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:
|
public:
|
||||||
using iterator::enumerator_reversible_rev<Iter, std::reverse_iterator<iterator::enumerate_wrapper<Iter>>>::enumerator_reversible_rev;
|
using iterator::enumerator_random_access_rev<Iter, std::reverse_iterator<iterator::enumerate_wrapper<Iter>>>::enumerator_random_access_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};
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
Loading…
Reference in New Issue