Added type filtering iterator.
This commit is contained in:
parent
0b8772c952
commit
121e8a84f5
@ -360,6 +360,10 @@ struct MappingRange : RangeAdapter
|
||||
{
|
||||
return MappingIterator(base.end(), functor);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool empty() const noexcept {
|
||||
return base.begin() == base.end();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename TIterable, typename TFunctor>
|
||||
@ -668,6 +672,100 @@ auto chain(TFirstRange&& firstRange, TSecondRange&& secondRange, TMoreRanges&&..
|
||||
return chain(std::forward<TFirstRange>(firstRange), chain(std::forward<TSecondRange>(secondRange), std::forward<TMoreRanges>(moreRanges)...));
|
||||
}
|
||||
|
||||
template<typename TType, typename TIterator>
|
||||
struct TypeFilteringIterator
|
||||
{
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = TType;
|
||||
using pointer = std::remove_pointer_t<value_type>*;
|
||||
using reference = std::remove_reference_t<value_type>&;
|
||||
using iterator_category = std::bidirectional_iterator_tag; // TODO?
|
||||
|
||||
TIterator base;
|
||||
TIterator end;
|
||||
|
||||
TypeFilteringIterator(TIterator base_, TIterator end_) noexcept : base(base_), end(end_) {
|
||||
if (base != end && !isCastable()) {
|
||||
++(*this);
|
||||
}
|
||||
}
|
||||
TypeFilteringIterator(const TypeFilteringIterator&) noexcept = default;
|
||||
TypeFilteringIterator(TypeFilteringIterator&&) noexcept = default;
|
||||
|
||||
TypeFilteringIterator& operator=(const TypeFilteringIterator&) noexcept = default;
|
||||
TypeFilteringIterator& operator=(TypeFilteringIterator&&) noexcept = default;
|
||||
|
||||
reference operator*() const noexcept
|
||||
{
|
||||
return static_cast<reference>(*base);
|
||||
}
|
||||
|
||||
TypeFilteringIterator& operator++() noexcept
|
||||
{
|
||||
do
|
||||
{
|
||||
++base;
|
||||
} while (base != end && !isCastable());
|
||||
return *this;
|
||||
}
|
||||
|
||||
TypeFilteringIterator operator++(int) noexcept
|
||||
{
|
||||
FilteringIterator copy(*this);
|
||||
++(*this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
bool operator==(const TypeFilteringIterator& other) const noexcept
|
||||
{
|
||||
return base == other.base && end == other.end;
|
||||
}
|
||||
|
||||
bool operator!=(const TypeFilteringIterator& other) const noexcept
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
private:
|
||||
bool isCastable() const
|
||||
{
|
||||
if constexpr (std::is_pointer_v<TType>)
|
||||
{
|
||||
return dynamic_cast<TType>(*base);
|
||||
}
|
||||
else
|
||||
{
|
||||
return dynamic_cast<TType*>(&*base);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename TType, typename TIterable>
|
||||
struct TypeFilteringRange : RangeAdapter
|
||||
{
|
||||
using orig_value_type = typename std::iterator_traits<decltype(std::begin(std::declval<TIterable>()))>::value_type;
|
||||
using value_type = TType;
|
||||
|
||||
RangeRef<TIterable> iterable;
|
||||
|
||||
auto begin() const noexcept
|
||||
{
|
||||
return TypeFilteringIterator<TType, decltype(iterable.begin())>(iterable.begin(), iterable.end());
|
||||
}
|
||||
|
||||
auto end() const noexcept
|
||||
{
|
||||
return TypeFilteringIterator<TType, decltype(iterable.begin())>(iterable.end(), iterable.end());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename TType, typename TIterable>
|
||||
auto filterType(TIterable&& iterable)
|
||||
{
|
||||
return TypeFilteringRange<TType, TIterable>{
|
||||
.iterable = {std::forward<TIterable>(iterable)}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename TAs, typename TIterable>
|
||||
TAs collect(TIterable&& iterable)
|
||||
{
|
||||
@ -770,6 +868,17 @@ auto operator|(TIterable&& iterable, Filter<TFilter> filterer)
|
||||
return filter(std::forward<TIterable>(iterable), std::move(filterer.predicate));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct FilterType
|
||||
{
|
||||
};
|
||||
|
||||
template<typename TIterable, typename T>
|
||||
auto operator|(TIterable&& iterable, FilterType<T>)
|
||||
{
|
||||
return filterType<T>(std::forward<TIterable>(iterable));
|
||||
}
|
||||
|
||||
template<std::size_t idx>
|
||||
struct Xth {};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user