26template<
typename RangeLike, AkTraits::Container OutContainer>
27OutContainer copyContainer(
const RangeLike &range)
29 return OutContainer(range.begin(), range.end());
32template<
typename RangeList,
typename OutContainer>
33OutContainer copyAssocContainer(
const RangeList &range)
36 if constexpr (AkTraits::ReservableContainer<OutContainer>) {
37 rv.reserve(range.size());
39 for (
const auto &v : range) {
40 rv.insert(v.first, v.second);
45template<
typename Iterator>
47 using iterator_category =
typename Iterator::iterator_category;
48 using value_type =
typename Iterator::value_type;
49 using difference_type =
typename Iterator::difference_type;
50 using pointer =
typename Iterator::pointer;
51 using reference =
typename Iterator::reference;
57template<
typename Iterator>
58struct IteratorTrait<Iterator *> {
60 using iterator_category = std::random_access_iterator_tag;
61 using value_type = Iterator;
62 using difference_type = qsizetype;
63 using pointer = Iterator *;
64 using reference = Iterator &;
67template<
typename Iterator>
68struct IteratorTrait<const Iterator *> {
69 using iterator_category = std::random_access_iterator_tag;
70 using value_type = Iterator;
71 using difference_type = qsizetype;
72 using pointer =
const Iterator *;
73 using reference =
const Iterator &;
76template<
typename IterImpl,
typename RangeLike,
typename Iterator =
typename RangeLike::const_iterator>
77struct BidiIteratorBase {
79 using iterator_category = std::bidirectional_iterator_tag;
80 using value_type =
typename IteratorTrait<Iterator>::value_type;
81 using difference_type =
typename IteratorTrait<Iterator>::difference_type;
82 using pointer =
typename IteratorTrait<Iterator>::pointer;
83 using reference =
typename IteratorTrait<Iterator>::reference;
85 BidiIteratorBase(
const BidiIteratorBase<IterImpl, RangeLike> &other)
87 , mRange(other.mRange)
91 IterImpl &operator++()
93 ++
static_cast<IterImpl *
>(
this)->mIter;
94 return *
static_cast<IterImpl *
>(
this);
97 IterImpl operator++(
int)
99 auto ret = *
static_cast<IterImpl *
>(
this);
100 ++
static_cast<IterImpl *
>(
this)->mIter;
104 bool operator==(
const IterImpl &other)
const
106 return mIter == other.mIter;
109 bool operator!=(
const IterImpl &other)
const
111 return !(*
static_cast<const IterImpl *
>(
this) == other);
114 auto operator*()
const
120 BidiIteratorBase(
const Iterator &iter,
const RangeLike &range)
125 BidiIteratorBase(
const Iterator &iter, RangeLike &&range)
127 , mRange(std::
move(range))
135template<
typename IterImpl,
typename RangeLike,
typename Iterator =
typename RangeLike::const_iterator>
136struct RandomAccessIteratorBase :
public BidiIteratorBase<IterImpl, RangeLike, Iterator> {
138 using iterator_category = std::random_access_iterator_tag;
140 using BidiIteratorBase<IterImpl, RangeLike, Iterator>::BidiIteratorBase;
142 auto operator-(
const IterImpl &other)
const
144 return this->mIter - other.mIter;
148template<
typename IterImpl,
typename RangeLike,
typename Iterator =
typename RangeLike::const_iterator>
149using IteratorBase = std::conditional_t<std::random_access_iterator<Iterator>,
150 RandomAccessIteratorBase<IterImpl, RangeLike, Iterator>,
151 BidiIteratorBase<IterImpl, RangeLike, Iterator>>;
153template<
typename RangeLike,
typename TransformFn,
typename Iterator =
typename RangeLike::const_iterator>
154struct TransformIterator :
public IteratorBase<TransformIterator<RangeLike, TransformFn>, RangeLike> {
156 template<
typename... T>
159 template<
typename R,
typename... Args>
160 struct ResultOf<R(Args...)> {
164 using IteratorValueType = std::invoke_result_t<TransformFn, typename IteratorTrait<Iterator>::value_type>;
167 using value_type = IteratorValueType;
168 using pointer = IteratorValueType *;
169 using reference =
const IteratorValueType &;
171 TransformIterator(
const Iterator &iter,
const TransformFn &fn,
const RangeLike &range)
172 : IteratorBase<TransformIterator<RangeLike, TransformFn>, RangeLike>(iter, range)
177 auto operator*()
const
179 return std::invoke(mFn, *(this->mIter));
186template<
typename RangeLike,
typename Predicate,
typename Iterator =
typename RangeLike::const_iterator>
187class FilterIterator :
public IteratorBase<FilterIterator<RangeLike, Predicate>, RangeLike>
192 using iterator_category = std::input_iterator_tag;
194 FilterIterator(
const Iterator &iter,
const Iterator &end,
const Predicate &predicate,
const RangeLike &range)
195 : IteratorBase<FilterIterator, RangeLike>(iter, range)
196 , mPredicate(predicate)
199 while (this->mIter != mEnd && !std::invoke(mPredicate, *this->mIter)) {
206 if (this->mIter != mEnd) {
209 }
while (this->mIter != mEnd && !std::invoke(mPredicate, *this->mIter));
222 Predicate mPredicate;
226template<
typename RangeLike,
typename Iterator =
typename RangeLike::const_iterator>
227class EnumerateIterator :
public IteratorBase<EnumerateIterator<RangeLike>, RangeLike>
230 using value_type = std::pair<qsizetype, typename Iterator::value_type>;
231 using pointer = value_type *;
232 using reference =
const value_type &;
234 EnumerateIterator(
const Iterator &iter, qsizetype
start,
const RangeLike &range)
235 : IteratorBase<EnumerateIterator, RangeLike>(iter, range)
247 auto &operator++(
int)
254 QPair<qsizetype, typename Iterator::value_type> operator*()
const
256 return qMakePair(mCount, *this->mIter);
260 qsizetype mCount = 0;
263template<
typename Container,
int Pos,
typename Iterator =
typename Container::const_key_value_iterator>
264class AssociativeContainerIterator :
public IteratorBase<AssociativeContainerIterator<Container, Pos>, Container, Iterator>
267 using value_type = std::remove_const_t<std::remove_reference_t<typename std::tuple_element<Pos, typename Iterator::value_type>::type>>;
268 using pointer = std::add_pointer_t<value_type>;
269 using reference = std::add_lvalue_reference_t<value_type>;
271 AssociativeContainerIterator(
const Iterator &iter,
const Container &container)
272 : IteratorBase<AssociativeContainerIterator<Container, Pos>, Container, Iterator>(iter, container)
276 auto operator*()
const
278 return std::get<Pos>(*this->mIter);
282template<
typename Container>
283using AssociativeContainerKeyIterator = AssociativeContainerIterator<Container, 0>;
284template<
typename Container>
285using AssociativeContainerValueIterator = AssociativeContainerIterator<Container, 1>;
287template<
typename Iterator>
290 using iterator = Iterator;
291 using const_iterator = Iterator;
292 using value_type =
typename detail::IteratorTrait<Iterator>::value_type;
294 Range(Iterator &&begin, Iterator &&end)
295 : mBegin(std::
move(begin))
300 Iterator begin()
const
305 Iterator cbegin()
const
315 Iterator cend()
const
322 return std::distance(mBegin, mEnd);
331using IsRange =
typename std::is_same<T, Range<typename T::iterator>>;
335template<
template<
typename>
class Cont>
338 using OutputContainer = Cont<T>;
341template<
template<
typename,
typename>
class Cont>
343 template<
typename Key,
typename Value>
344 using OuputContainer = Cont<Key, Value>;
352template<
typename UnaryOperation>
353struct TransformTag_ {
357template<
typename UnaryPredicate>
362template<
typename UnaryOperation>
367template<
typename UnaryPredicate>
372template<
typename UnaryPredicate>
377template<
typename UnaryPredicate>
382struct EnumerateTag_ {
383 qsizetype mStart = 0;
390template<
typename RangeLike,
template<
typename>
class OutContainer,
typename T =
typename RangeLike::value_type>
391auto operator|(
const RangeLike &range, AkRanges::detail::ToTag_<OutContainer>) -> OutContainer<T>
393 using namespace AkRanges::detail;
394 return copyContainer<RangeLike, OutContainer<T>>(range);
399template<
template<
typename>
class InContainer,
typename T>
400auto operator|(
const InContainer<T> &in, AkRanges::detail::ToTag_<InContainer>) -> InContainer<T>
406template<
typename RangeLike,
template<
typename,
typename>
class OutContainer,
typename T =
typename RangeLike::value_type>
407auto operator|(
const RangeLike &range, AkRanges::detail::ToAssocTag_<OutContainer>) -> OutContainer<typename T::first_type, typename T::second_type>
409 using namespace AkRanges::detail;
410 return copyAssocContainer<RangeLike, OutContainer<typename T::first_type, typename T::second_type>>(range);
414template<
typename RangeLike,
typename UnaryOperation>
415auto operator|(
const RangeLike &range, AkRanges::detail::TransformTag_<UnaryOperation> t)
417 using namespace AkRanges::detail;
418 using OutIt = TransformIterator<RangeLike, UnaryOperation>;
419 return Range<OutIt>(OutIt(std::cbegin(range), t.mFn, range), OutIt(std::cend(range), t.mFn, range));
423template<
typename RangeLike,
typename UnaryPredicate>
424auto operator|(
const RangeLike &range, AkRanges::detail::FilterTag_<UnaryPredicate> p)
426 using namespace AkRanges::detail;
427 using OutIt = FilterIterator<RangeLike, UnaryPredicate>;
428 return Range<OutIt>(OutIt(std::cbegin(range), std::cend(range), p.mFn, range), OutIt(std::cend(range), std::cend(range), p.mFn, range));
432template<
typename RangeLike>
433auto operator|(
const RangeLike &range, AkRanges::detail::EnumerateTag_ tag)
435 using namespace AkRanges::detail;
436 using OutIt = EnumerateIterator<RangeLike>;
437 return Range<OutIt>(OutIt(std::cbegin(range), tag.mStart, range), OutIt(std::cend(range), tag.mStart, range));
441template<
typename RangeLike,
typename UnaryOperation>
442auto operator|(
const RangeLike &range, AkRanges::detail::ForEachTag_<UnaryOperation> op)
444 std::for_each(std::cbegin(range), std::cend(range), [op = std::move(op)](
const auto &val)
mutable {
445 std::invoke(op.mFn, val);
451template<
typename RangeLike,
typename UnaryPredicate>
452auto operator|(
const RangeLike &range, AkRanges::detail::AllTag_<UnaryPredicate> p)
454 return std::all_of(std::cbegin(range), std::cend(range), p.mFn);
458template<
typename RangeLike,
typename PredicateFn>
459auto operator|(
const RangeLike &range, AkRanges::detail::AnyTag_<PredicateFn> p)
461 return std::any_of(std::cbegin(range), std::cend(range), p.mFn);
465template<
typename RangeLike,
typename UnaryPredicate>
466auto operator|(
const RangeLike &range, AkRanges::detail::NoneTag_<UnaryPredicate> p)
468 return std::none_of(std::cbegin(range), std::cend(range), p.mFn);
472template<
typename AssocContainer>
473auto operator|(
const AssocContainer &in, AkRanges::detail::KeysTag_)
475 using namespace AkRanges::detail;
476 using OutIt = AssociativeContainerKeyIterator<AssocContainer>;
477 return Range<OutIt>(OutIt(in.constKeyValueBegin(), in), OutIt(in.constKeyValueEnd(), in));
481template<
typename AssocContainer>
482auto operator|(
const AssocContainer &in, AkRanges::detail::ValuesTag_)
484 using namespace AkRanges::detail;
485 using OutIt = AssociativeContainerValueIterator<AssocContainer>;
486 return Range<OutIt>(OutIt(in.constKeyValueBegin(), in), OutIt(in.constKeyValueEnd(), in));
494static constexpr auto toQVector = detail::ToTag_<QList>{};
496static constexpr auto toQSet = detail::ToTag_<QSet>{};
498static constexpr auto toQList = detail::ToTag_<QList>{};
500static constexpr auto toQMap = detail::ToAssocTag_<QMap>{};
502static constexpr auto toQHash = detail::ToAssocTag_<QHash>{};
505template<
typename UnaryOperation>
506detail::ForEachTag_<UnaryOperation> forEach(UnaryOperation &&op)
508 return detail::ForEachTag_<UnaryOperation>{std::forward<UnaryOperation>(op)};
512template<
typename UnaryPredicate>
513detail::AllTag_<UnaryPredicate> all(UnaryPredicate &&pred)
515 return detail::AllTag_<UnaryPredicate>{std::forward<UnaryPredicate>(pred)};
519template<
typename UnaryPredicate>
520detail::AnyTag_<UnaryPredicate> any(UnaryPredicate &&pred)
522 return detail::AnyTag_<UnaryPredicate>{std::forward<UnaryPredicate>(pred)};
526template<
typename UnaryPredicate>
527detail::NoneTag_<UnaryPredicate> none(UnaryPredicate &&pred)
529 return detail::NoneTag_<UnaryPredicate>{std::forward<UnaryPredicate>(pred)};
537static constexpr auto values = detail::ValuesTag_{};
539static constexpr auto keys = detail::KeysTag_{};
542template<
typename UnaryOperation>
543detail::TransformTag_<UnaryOperation>
transform(UnaryOperation &&op)
545 return detail::TransformTag_<UnaryOperation>{std::forward<UnaryOperation>(op)};
549template<
typename UnaryPredicate>
550detail::FilterTag_<UnaryPredicate>
filter(UnaryPredicate &&pred)
552 return detail::FilterTag_<UnaryPredicate>{std::forward<UnaryPredicate>(pred)};
556inline detail::EnumerateTag_ enumerate(qsizetype
start = 0)
558 return detail::EnumerateTag_{
start};
562template<
typename Iterator1,
typename Iterator2,
typename It = std::remove_reference_t<Iterator1>>
563detail::Range<It> range(Iterator1 begin, Iterator2 end)
565 return detail::Range<It>(std::move(begin), std::move(end));
Q_SCRIPTABLE Q_NOREPLY void start()
QAction * end(const QObject *recvr, const char *slot, QObject *parent)
KIOCORE_EXPORT CopyJob * move(const QList< QUrl > &src, const QUrl &dest, JobFlags flags=DefaultFlags)
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
QFuture< void > filter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&filterFunction)