CXXIter 0.2
Loading...
Searching...
No Matches
CXXIter.h
1#pragma once
2
3#include <utility>
4#include <optional>
5#include <concepts>
6#include <functional>
7#include <string>
8#include <limits>
9
10#include <unordered_map>
11#include <vector>
12#include <cmath>
13
14#include "src/Common.h"
15#include "src/Generator.h"
16#include "src/sources/Concepts.h"
17#include "src/sources/ContainerSources.h"
18#include "src/sources/GeneratorSources.h"
19#include "src/Collector.h"
20#include "src/op/Alternater.h"
21#include "src/op/Caster.h"
22#include "src/op/Chainer.h"
23#include "src/op/Chunked.h"
24#include "src/op/ChunkedExact.h"
25#include "src/op/Filter.h"
26#include "src/op/FilterMap.h"
27#include "src/op/FlagLast.h"
28#include "src/op/FlatMap.h"
29#include "src/op/GenerateFrom.h"
30#include "src/op/GroupBy.h"
31#include "src/op/InplaceModifier.h"
32#include "src/op/Intersperser.h"
33#include "src/op/Map.h"
34#include "src/op/Reverse.h"
35#include "src/op/SkipN.h"
36#include "src/op/SkipWhile.h"
37#include "src/op/Sorter.h"
38#include "src/op/TakeN.h"
39#include "src/op/TakeWhile.h"
40#include "src/op/Unique.h"
41#include "src/op/Zipper.h"
42#include "src/Helpers.h"
43
44
48namespace CXXIter {
49
50// ################################################################################################
51// SURFACE-API
52// ################################################################################################
53
57template<CXXIterIterator TSelf>
58class IterApi {
59public: // Associated types
67 using Item = typename Iterator::Item;
71 using ItemOwned = std::remove_cvref_t<Item>;
72
73private:
74 constexpr TSelf* self() { return static_cast<TSelf*>(this); }
75 constexpr const TSelf* self() const { return static_cast<const TSelf*>(this); }
76 static constexpr bool IS_REFERENCE = std::is_lvalue_reference_v<Item>;
77
78public: // C++ Iterator API-Surface
79
83 class iterator {
84 friend class IterApi;
85 TSelf& self;
86 IterValue<Item> element;
87
89 iterator(TSelf& self) : self(self) {}
91 iterator(TSelf& self, IterValue<Item>&& element) : self(self), element(std::move(element)) {}
92
93
94 public:
95 iterator& operator++() {
96 if(element.has_value()) {
97 element = self.next();
98 }
99 return *this;
100 }
101
102 Item& operator*() { return element.value(); }
103
104 bool operator!=(const iterator& o) {
105 return (element.has_value() != o.element.has_value());
106 }
107 };
108
113 iterator begin() { return {*self(), next()}; }
114
119 iterator end() { return {*self()}; }
120
121public: // CXXIter API-Surface
122
128 constexpr SizeHint sizeHint() const {
129 return Iterator::sizeHint(*self());
130 }
131
158 constexpr size_t size() const requires CXXIterExactSizeIterator<TSelf> {
160 }
161
175 constexpr IterValue<Item> next() {
176 return Iterator::next(*self());
177 }
178
195 constexpr void advanceBy(size_t n) {
196 Iterator::advanceBy(*self(), n);
197 }
198
213 constexpr IterValue<Item> nextBack() requires CXXIterDoubleEndedIterator<TSelf> {
215 }
216
217 // ###################
218 // CONSUMERS
219 // ###################
224
240 template<typename TUseFn>
241 constexpr void forEach(TUseFn useFn) {
242 while(true) {
243 auto item = Iterator::next(*self());
244 if(!item.has_value()) [[unlikely]] { return; }
245 useFn(std::forward<Item>( item.value() ));
246 }
247 }
248
272 template<template <typename...> typename TTargetContainer, typename... TTargetContainerArgs>
273 constexpr auto collect() {
274 return Collector<TSelf, TTargetContainer, TTargetContainerArgs...>::template collect<Item, ItemOwned>(*self());
275 }
276
305 template<typename TTargetContainer>
306 constexpr TTargetContainer collect() {
307 TTargetContainer container;
308 collectInto(container);
309 return container;
310 }
311
328 template<typename TTargetContainer>
329 constexpr void collectInto(TTargetContainer& container) {
330 IntoCollector<TSelf, TTargetContainer>::collectInto(*self(), container);
331 }
332
352 template<typename TResult, std::invocable<TResult&, Item&&> FoldFn>
353 constexpr TResult fold(TResult startValue, FoldFn foldFn) {
354 TResult result = startValue;
355 forEach([&result, &foldFn](Item&& item) { foldFn(result, std::forward<Item>(item)); });
356 return result;
357 }
358
394 template<std::invocable<const ItemOwned&> TPredicateFn>
395 requires std::same_as<std::invoke_result_t<TPredicateFn, const ItemOwned&>, bool>
396 constexpr bool all(TPredicateFn predicateFn) {
397 return !skipWhile(predicateFn).next().has_value();
398 }
399
431 constexpr bool all() requires requires(const ItemOwned& item) {
432 {static_cast<bool>(item)};
433 } {
434 return all([](const auto& item) -> bool { return item; });
435 }
436
471 template<std::invocable<const ItemOwned&> TPredicateFn>
472 constexpr bool any(TPredicateFn predicateFn) {
473 return filter(predicateFn).next().has_value();
474 }
475
507 constexpr bool any() requires requires(const ItemOwned& item) {
508 {static_cast<bool>(item)};
509 } {
510 return any([](const auto& item) -> bool { return item; });
511 }
512
533 constexpr std::optional<size_t> findIdx(const ItemOwned& searchItem) requires requires(const ItemOwned& searchItem, const Item& item) {
534 {searchItem == item} -> std::same_as<bool>;
535 } {
536 return findIdx([&searchItem](const ItemOwned& item) {
537 return (searchItem == item);
538 });
539 }
540
541
564 template<std::invocable<const ItemOwned&> TFindFn>
565 constexpr std::optional<size_t> findIdx(TFindFn findFn) {
566 size_t idx = 0;
567 while(true) {
568 auto item = Iterator::next(*self());
569 if(!item.has_value()) [[unlikely]] { return {}; }
570 if(findFn(item.value())) [[unlikely]] { return idx; }
571 idx += 1;
572 }
573 }
574
601 template<std::invocable<const ItemOwned&> TFindFn>
602 constexpr IterValue<Item> find(TFindFn findFn) {
603 return filter(findFn).next();
604 }
605
621 constexpr size_t count() {
622 return fold((size_t)0, [](size_t& cnt, auto&&) { cnt += 1; });
623 }
624
641 template<std::invocable<const ItemOwned&> TPredicateFn>
642 constexpr size_t count(TPredicateFn predicateFn) {
643 return fold((size_t)0, [&predicateFn](size_t& cnt, auto&& item) {
644 if(predicateFn(item)) { cnt += 1; }
645 });
646 }
647
663 constexpr size_t count(const ItemOwned& countItem)
664 requires requires(const ItemOwned& countItem, Item&& item) {
665 {countItem == item};
666 } {
667 return fold((size_t)0, [&countItem](size_t& cnt, auto&& item) {
668 if(item == countItem) { cnt += 1; }
669 });
670 }
671
672
706 template<typename TResult = ItemOwned>
707 requires requires(TResult res, Item item) { { res += item }; }
708 constexpr TResult sum(TResult startValue = TResult()) {
709 return fold(startValue, [](TResult& res, Item&& item) { res += item; });
710 }
711
746 std::string stringJoin(const std::string& separator) requires std::is_same_v<ItemOwned, std::string> {
747 std::string result;
748 forEach([&result, &separator](const std::string& item) {
749 if(result.size() > 0) [[likely]] { result += separator + item; }
750 else [[unlikely]] { result = item; }
751 });
752 return result;
753 }
754
784 template<StatisticNormalization NORM = StatisticNormalization::N, typename TResult = ItemOwned, typename TCount = ItemOwned>
785 constexpr std::optional<TResult> mean(TResult sumStart = TResult()) {
786 size_t cnt = 0;
787 TResult result = fold(sumStart, [&cnt](TResult& res, Item&& item) {
788 cnt += 1;
789 res += item;
790 });
791 if(cnt > 0) {
792 if constexpr(NORM == StatisticNormalization::N) {
793 return result / static_cast<TCount>(cnt);
794 } else {
795 return result / static_cast<TCount>(cnt - 1);
796 }
797 }
798 return {};
799 }
800
838 template<StatisticNormalization NORM = StatisticNormalization::N, typename TResult = ItemOwned, typename TCount = ItemOwned>
839 constexpr std::optional<TResult> variance() {
840 TResult sumSquare = TResult();
841 TResult sum = TResult();
842 size_t cnt = 0;
843 forEach([&sumSquare, &sum, &cnt](Item&& item) {
844 sum += item;
845 sumSquare += (item * item);
846 cnt += 1;
847 });
848 if(cnt >= 2) {
849 if constexpr(NORM == StatisticNormalization::N) {
850 TResult E1 = (sumSquare / static_cast<TCount>(cnt));
851 TResult E2 = (sum / static_cast<TCount>(cnt));
852 return E1 - (E2 * E2);
853 } else {
854 TResult E1 = (sum * sum / static_cast<TCount>(cnt));
855 return (sumSquare - E1) / static_cast<TCount>(cnt - 1);
856 }
857 }
858 return {};
859 }
860
895 template<StatisticNormalization NORM = StatisticNormalization::N, typename TResult = ItemOwned, typename TCount = ItemOwned>
896 constexpr std::optional<TResult> stddev() {
897 std::optional<TResult> result = variance<NORM, TResult, TCount>();
898 if(result.has_value()) { return std::sqrt(result.value()); }
899 return {};
900 }
901
924 constexpr IterValue<Item> min() {
925 return minBy([](auto&& item) { return item; });
926 }
927
947 constexpr std::optional<size_t> minIdx() {
948 return minIdxBy([](auto&& item) { return item; });
949 }
950
973 constexpr IterValue<Item> max() {
974 return maxBy([](auto&& item) { return item; });
975 }
976
996 constexpr std::optional<size_t> maxIdx() {
997 return maxIdxBy([](auto&& item) { return item; });
998 }
999
1027 template<typename TCompValueExtractFn>
1028 requires requires(const std::invoke_result_t<TCompValueExtractFn, Item&&>& a, std::remove_cvref_t<decltype(a)> ownedA) {
1029 { a < a };
1030 { ownedA = ownedA };
1031 }
1032 constexpr IterValue<Item> minBy(TCompValueExtractFn compValueExtractFn) {
1033 IterValue<Item> result = Iterator::next(*self());
1034 if(!result.has_value()) { return {}; }
1035 auto resultValue = compValueExtractFn(std::forward<Item>(result.value()));
1036 forEach([&result, &resultValue, &compValueExtractFn](Item&& item) {
1037 auto itemValue = compValueExtractFn(std::forward<Item>(item));
1038 if(itemValue < resultValue) {
1039 result = item;
1040 resultValue = itemValue;
1041 }
1042 });
1043 return result;
1044 }
1045
1070 template<typename TCompValueExtractFn>
1071 requires requires(const std::invoke_result_t<TCompValueExtractFn, Item&&>& a) {
1072 { a < a };
1073 }
1074 constexpr std::optional<size_t> minIdxBy(TCompValueExtractFn compValueExtractFn) {
1075 IterValue<Item> tmp = Iterator::next(*self());
1076 if(!tmp.has_value()) { return {}; }
1077 size_t iterationIdx = 1, minIdx = 0;
1078 auto minValue = compValueExtractFn(std::forward<Item>(tmp.value()));
1079 forEach([iterationIdx, &minIdx, &minValue, &compValueExtractFn](Item&& item) mutable {
1080 auto itemValue = compValueExtractFn(std::forward<Item>(item));
1081 if(itemValue < minValue) {
1082 minValue = itemValue;
1083 minIdx = iterationIdx;
1084 }
1085 iterationIdx += 1;
1086 });
1087 return minIdx;
1088 }
1089
1117 template<typename TMaxValueExtractFn>
1118 requires requires(const std::invoke_result_t<TMaxValueExtractFn, Item&&>& a, std::remove_cvref_t<decltype(a)> ownedA) {
1119 { a > a };
1120 { ownedA = ownedA };
1121 }
1122 constexpr IterValue<Item> maxBy(TMaxValueExtractFn compValueExtractFn) {
1123 IterValue<Item> result = Iterator::next(*self());
1124 if(!result.has_value()) { return {}; }
1125 auto resultValue = compValueExtractFn(std::forward<Item>(result.value()));
1126 forEach([&result, &resultValue, &compValueExtractFn](Item&& item) {
1127 auto itemValue = compValueExtractFn(std::forward<Item>(item));
1128 if(itemValue > resultValue) {
1129 result = item;
1130 resultValue = itemValue;
1131 }
1132 });
1133 return result;
1134 }
1135
1160 template<typename TMaxValueExtractFn>
1161 requires requires(const std::invoke_result_t<TMaxValueExtractFn, Item&&>& a, std::remove_cvref_t<decltype(a)> ownedA) {
1162 { a > a };
1163 { ownedA = ownedA };
1164 }
1165 constexpr std::optional<size_t> maxIdxBy(TMaxValueExtractFn compValueExtractFn) {
1166 IterValue<Item> tmp = Iterator::next(*self());
1167 if(!tmp.has_value()) { return {}; }
1168 size_t iterationIdx = 1, maxIdx = 0;
1169 auto maxValue = compValueExtractFn(std::forward<Item>(tmp.value()));
1170 forEach([iterationIdx, &maxIdx, &maxValue, &compValueExtractFn](Item&& item) mutable {
1171 auto itemValue = compValueExtractFn(std::forward<Item>(item));
1172 if(itemValue > maxValue) {
1173 maxValue = itemValue;
1174 maxIdx = iterationIdx;
1175 }
1176 iterationIdx += 1;
1177 });
1178 return maxIdx;
1179 }
1180
1204 constexpr IterValue<Item> last() {
1205 IterValue<Item> tmp;
1206 forEach([&tmp](Item&& item) { tmp = item; });
1207 return tmp;
1208 }
1209
1229 constexpr IterValue<Item> nth(size_t n) {
1230 return skip(n).next();
1231 }
1233
1234
1235 // ###################
1236 // CHAINERS
1237 // ###################
1242
1257 template<typename TItemOutput>
1258 constexpr op::Caster<TSelf, TItemOutput> cast() {
1259 return op::Caster<TSelf, TItemOutput>(std::move(*self()));
1260 }
1261
1277 constexpr auto copied() {
1278 return map([](const ItemOwned& item) -> ItemOwned {
1279 ItemOwned copy = item;
1280 return copy;
1281 });
1282
1283 }
1284
1300 constexpr auto indexed() {
1301 size_t idx = 0;
1302 return map([idx](Item&& item) mutable -> std::pair<size_t, Item> {
1303 return std::pair<size_t, Item>(idx++, std::forward<Item>(item));
1304 });
1305 }
1306
1333 constexpr op::FlagLast<TSelf> flagLast() {
1334 return op::FlagLast<TSelf>(std::move(*self()));
1335 }
1336
1352 template<std::invocable<const ItemOwned&> TFilterFn>
1353 constexpr op::Filter<TSelf, TFilterFn> filter(TFilterFn filterFn) {
1354 return op::Filter<TSelf, TFilterFn>(std::move(*self()), filterFn);
1355 }
1356
1376 template<std::invocable<const ItemOwned&> TMapFn>
1377 requires util::is_hashable<std::invoke_result_t<TMapFn, const ItemOwned&>>
1378 constexpr op::Unique<TSelf, TMapFn> unique(TMapFn mapFn) {
1379 return op::Unique<TSelf, TMapFn>(std::move(*self()), mapFn);
1380 }
1381
1400 constexpr auto unique() {
1401 return unique([](const auto& item) { return item; });
1402 }
1403
1421 constexpr op::Reverse<TSelf> reverse() {
1422 return op::Reverse<TSelf>(std::move(*self()));
1423 }
1424
1453 template<const size_t CHUNK_SIZE>
1454 constexpr op::Chunked<TSelf, CHUNK_SIZE> chunked() {
1455 return op::Chunked<TSelf, CHUNK_SIZE>(std::move(*self()));
1456 }
1457
1561 template<const size_t CHUNK_SIZE, const size_t STEP_SIZE = CHUNK_SIZE>
1562 constexpr op::ChunkedExact<TSelf, CHUNK_SIZE, STEP_SIZE> chunkedExact() {
1563 return op::ChunkedExact<TSelf, CHUNK_SIZE, STEP_SIZE>(std::move(*self()));
1564 }
1565
1584 template<std::invocable<Item&&> TMapFn>
1585 constexpr auto map(TMapFn mapFn) {
1586 using TMapFnResult = std::invoke_result_t<TMapFn, Item&&>;
1587 return op::Map<TSelf, TMapFn, TMapFnResult>(std::move(*self()), mapFn);
1588 }
1589
1610 template<std::invocable<Item&&> TFlatMapFn>
1611 constexpr auto flatMap(TFlatMapFn mapFn) {
1612 using TFlatMapFnResult = std::invoke_result_t<TFlatMapFn, Item&&>;
1613 return op::FlatMap<TSelf, TFlatMapFn, TFlatMapFnResult>(std::move(*self()), mapFn);
1614 }
1615
1616#ifdef CXXITER_HAS_COROUTINE
1688 template<GeneratorFromFunction<Item> TGeneratorFn>
1689 constexpr auto generateFrom(TGeneratorFn generatorFn) {
1690 using TGeneratorFnResult = std::invoke_result_t<TGeneratorFn, Item>;
1691 return op::GenerateFrom<TSelf, TGeneratorFn, TGeneratorFnResult>(std::move(*self()), generatorFn);
1692 }
1693#endif
1694
1712 constexpr auto flatMap() {
1713 return flatMap([](Item&& item) { return item; });
1714 }
1715
1731 template<std::invocable<Item&> TModifierFn>
1732 constexpr op::InplaceModifier<TSelf, TModifierFn> modify(TModifierFn modifierFn) {
1733 return op::InplaceModifier<TSelf, TModifierFn>(std::move(*self()), modifierFn);
1734 }
1735
1755 template<std::invocable<ItemOwned&&> TFilterMapFn>
1756 requires util::is_optional<std::invoke_result_t<TFilterMapFn, ItemOwned&&>>
1757 constexpr auto filterMap(TFilterMapFn filterMapFn) {
1758 using TFilterMapFnResult = typename std::invoke_result_t<TFilterMapFn, ItemOwned&&>::value_type;
1759 return op::FilterMap<TSelf, TFilterMapFn, TFilterMapFnResult>(std::move(*self()), filterMapFn);
1760 }
1761
1776 constexpr op::SkipN<TSelf> skip(size_t cnt) {
1777 return op::SkipN<TSelf>(std::move(*self()), cnt);
1778 }
1779
1800 template<std::invocable<const Item&> TSkipPredicate>
1801 constexpr op::SkipWhile<TSelf, TSkipPredicate> skipWhile(TSkipPredicate skipPredicate) {
1802 return op::SkipWhile<TSelf, TSkipPredicate>(std::move(*self()), skipPredicate);
1803 }
1804
1818 constexpr op::TakeN<TSelf> take(size_t cnt) {
1819 return op::TakeN<TSelf>(std::move(*self()), cnt);
1820 }
1821
1840 template<std::invocable<const Item&> TTakePredicate>
1841 requires std::is_same_v<std::invoke_result_t<TTakePredicate, const Item&>, bool>
1842 constexpr auto takeWhile(TTakePredicate takePredicate) {
1843 return op::TakeWhile<TSelf, TTakePredicate>(std::move(*self()), takePredicate);
1844 }
1845
1871 constexpr auto stepBy(size_t stepWidth) {
1872 //TODO: better SizeHints?
1873 size_t idx = 0;
1874 return filter([idx, stepWidth](const ItemOwned&) mutable {
1875 return (idx++ % stepWidth) == 0;
1876 });
1877 }
1878
1897 template<typename TOtherIterator>
1898 constexpr op::Zipper<TSelf, std::pair, TOtherIterator> zip(TOtherIterator&& otherIterator) {
1899 return op::Zipper<TSelf, std::pair, TOtherIterator>(std::move(*self()), std::forward<TOtherIterator>(otherIterator));
1900 }
1901
1922 template<typename... TOtherIterators>
1923 requires (CXXIterIterator<TOtherIterators> && ...)
1924 && (!std::disjunction_v< std::is_reference<typename trait::Iterator<TOtherIterators>::Item>... > && !IS_REFERENCE)
1925 constexpr op::Zipper<TSelf, std::tuple, TOtherIterators...> zipTuple(TOtherIterators&&... otherIterators) {
1926 return op::Zipper<TSelf, std::tuple, TOtherIterators...>(std::move(*self()), std::forward<TOtherIterators>(otherIterators)...);
1927 }
1928
1946 template<typename TOtherIterator>
1947 requires std::is_same_v<Item, typename TOtherIterator::Item>
1948 constexpr op::Chainer<TSelf, TOtherIterator> chain(TOtherIterator&& otherIterator) {
1949 return op::Chainer<TSelf, TOtherIterator>(std::move(*self()), std::forward<TOtherIterator>(otherIterator));
1950 }
1951
1971 template<typename... TOtherIterators>
1972 requires (CXXIterIterator<TOtherIterators> && ...)
1973 && (util::are_same_v<Item, typename TOtherIterators::Item...>)
1974 constexpr op::Alternater<TSelf, TOtherIterators...> alternate(TOtherIterators&&... otherIterators) {
1975 return op::Alternater<TSelf, TOtherIterators...>(std::move(*self()), std::forward<TOtherIterators>(otherIterators)...);
1976 }
1977
2016 template<typename TOtherIterator>
2017 requires (std::is_same_v<Item, typename TOtherIterator::Item>)
2018 constexpr op::Intersperser<TSelf, TOtherIterator> intersperse(TOtherIterator&& otherIterator) {
2019 return op::Intersperser<TSelf, TOtherIterator>(std::move(*self()), std::forward<TOtherIterator>(otherIterator));
2020 }
2021
2048 template<std::invocable<const Item&> TGroupIdentifierFn>
2049 requires util::is_hashable<std::invoke_result_t<TGroupIdentifierFn, const Item&>>
2050 constexpr auto groupBy(TGroupIdentifierFn groupIdentFn) {
2051 using TGroupIdent = std::remove_cvref_t<std::invoke_result_t<TGroupIdentifierFn, const ItemOwned&>>;
2052 return op::GroupBy<TSelf, TGroupIdentifierFn, TGroupIdent>(std::move(*self()), groupIdentFn);
2053 }
2054
2084 template<bool STABLE, std::invocable<const ItemOwned&, const ItemOwned&> TCompareFn>
2085 constexpr auto sort(TCompareFn compareFn) {
2086 return op::Sorter<TSelf, TCompareFn, STABLE>(std::move(*self()), compareFn);
2087 }
2088
2114 template<SortOrder ORDER = SortOrder::ASCENDING, bool STABLE = false>
2115 requires requires(const ItemOwned& a) { { a < a }; { a > a }; }
2116 constexpr auto sort() {
2117 return sort<STABLE>([](const ItemOwned& a, const ItemOwned& b) {
2118 if constexpr(ORDER == SortOrder::ASCENDING) {
2119 return (a < b);
2120 } else {
2121 return (a > b);
2122 }
2123 });
2124 }
2125
2153 template<SortOrder ORDER = SortOrder::ASCENDING, bool STABLE = false, std::invocable<const ItemOwned&> TSortValueExtractFn>
2154 requires requires(const std::invoke_result_t<TSortValueExtractFn, const ItemOwned&>& a) {
2155 { a < a }; { a > a };
2156 }
2157 constexpr auto sortBy(TSortValueExtractFn sortValueExtractFn) {
2158 return sort<STABLE>([sortValueExtractFn](const ItemOwned& a, const ItemOwned& b) {
2159 if constexpr(ORDER == SortOrder::ASCENDING) {
2160 return (sortValueExtractFn(a) < sortValueExtractFn(b));
2161 } else {
2162 return (sortValueExtractFn(a) > sortValueExtractFn(b));
2163 }
2164 });
2165 }
2167};
2168
2169
2170
2171// ################################################################################################
2172// ENTRY POINTS
2173// ################################################################################################
2174
2186 template<typename TContainer>
2187 requires (!std::is_reference_v<TContainer> && !util::is_const_reference_v<TContainer> && concepts::SourceContainer<TContainer>)
2188 constexpr SrcMov<std::remove_cvref_t<TContainer>> from(TContainer&& container) {
2189 return SrcMov<std::remove_cvref_t<TContainer>>(std::forward<TContainer>(container));
2190 }
2191
2199 template<typename TContainer>
2200 requires (!std::is_reference_v<TContainer> && !util::is_const_reference_v<TContainer> && concepts::SourceContainer<TContainer>)
2201 constexpr SrcRef<std::remove_cvref_t<TContainer>> from(TContainer& container) {
2202 return SrcRef<std::remove_cvref_t<TContainer>>(container);
2203 }
2204
2212 template<typename TContainer>
2213 requires (!std::is_reference_v<TContainer> && !util::is_const_reference_v<TContainer> && concepts::SourceContainer<TContainer>)
2214 constexpr SrcCRef<std::remove_cvref_t<TContainer>> from(const TContainer& container) {
2215 return SrcCRef<std::remove_cvref_t<TContainer>>(container);
2216 }
2218
2219
2235 template<typename TItem>
2236 constexpr Empty<TItem> empty() { return Empty<TItem>(); }
2237
2259 template<std::invocable<> TGeneratorFn>
2260 requires util::is_optional<std::invoke_result_t<TGeneratorFn>>
2261 constexpr auto fromFn(TGeneratorFn generatorFn) {
2262 using TGeneratorFnResult = typename std::invoke_result_t<TGeneratorFn>::value_type;
2263 return FunctionGenerator<TGeneratorFnResult, TGeneratorFn>(generatorFn);
2264 }
2265
2266 #ifdef CXXITER_HAS_COROUTINE
2288 template<GeneratorFunction TGeneratorFn>
2289 auto generate(TGeneratorFn generatorFn) {
2290 using TGenerator = typename std::invoke_result_t<TGeneratorFn>;
2291 TGenerator generator = generatorFn();
2292 return CoroutineGenerator<TGenerator>(std::forward<TGenerator>(generator));
2293 }
2294 #endif
2295
2312 template<typename TItem>
2313 constexpr Repeater<TItem> repeat(const TItem& item, std::optional<size_t> cnt = {}) {
2314 return Repeater<TItem>(item, cnt);
2315 }
2316
2340 template<typename TValue>
2341 constexpr Range<TValue> range(TValue from, TValue to, TValue step = 1) {
2342 return Range<TValue>(from, to, step);
2343 }
2345}
C++ iterator implementation for a CXXIter chain.
Definition: CXXIter.h:83
Public Iterator API surface.
Definition: CXXIter.h:58
typename Iterator::Item Item
Type of the elements of this iterator. (Can be references)
Definition: CXXIter.h:67
constexpr auto collect()
Consumer that collects all elements from this iterator in a new container of type TTargetContainer.
Definition: CXXIter.h:273
constexpr void collectInto(TTargetContainer &container)
Consumer that collects all elements from this iterator into the given container.
Definition: CXXIter.h:329
constexpr op::Alternater< TSelf, TOtherIterators... > alternate(TOtherIterators &&... otherIterators)
Alternating the elements of this iterator with the ones from the other given iterator(s).
Definition: CXXIter.h:1974
constexpr auto generateFrom(TGeneratorFn generatorFn)
Creates a new iterator containing the items that the given generator produces for each element in thi...
Definition: CXXIter.h:1689
constexpr std::optional< size_t > maxIdx()
Consumer that yields the index of the largest element within this iterator.
Definition: CXXIter.h:996
constexpr IterValue< Item > minBy(TCompValueExtractFn compValueExtractFn)
Consumer that yields the smallest element from this iterator. Comparison of items is done using the c...
Definition: CXXIter.h:1032
constexpr void advanceBy(size_t n)
Advance the iterator by n elements.
Definition: CXXIter.h:195
constexpr auto takeWhile(TTakePredicate takePredicate)
Creates an iterator that yields the first elements of this iterator, for which the given takePredicat...
Definition: CXXIter.h:1842
constexpr op::ChunkedExact< TSelf, CHUNK_SIZE, STEP_SIZE > chunkedExact()
Create new iterator that collects elements from this iterator in exact-sized chunks of CHUNK_SIZE,...
Definition: CXXIter.h:1562
constexpr auto indexed()
Constructs a new iterator that tags each element of this iterator with the corresponding index,...
Definition: CXXIter.h:1300
constexpr op::Unique< TSelf, TMapFn > unique(TMapFn mapFn)
Constructs a new iterator that only contains every element of the input iterator only once.
Definition: CXXIter.h:1378
constexpr op::Reverse< TSelf > reverse()
Constructs a new iterator that provides the elements of this iterator in reverse order.
Definition: CXXIter.h:1421
constexpr auto stepBy(size_t stepWidth)
Creates an iterator with the requested stepWidth from this iterator.
Definition: CXXIter.h:1871
constexpr IterValue< Item > nth(size_t n)
Return the {n}-th element from this iterator (if available).
Definition: CXXIter.h:1229
constexpr op::Caster< TSelf, TItemOutput > cast()
Constructs a new iterator that casts the elements of this iterator to the type requested by TItemOutp...
Definition: CXXIter.h:1258
constexpr IterValue< Item > max()
Consumer that yields the largest element from this iterator.
Definition: CXXIter.h:973
constexpr IterValue< Item > nextBack()
Get the next element from the back of this iterator (if any), wrapped in a CXXIter::IterValue<>.
Definition: CXXIter.h:213
constexpr auto unique()
Constructs a new iterator that only contains every element of the input iterator only once.
Definition: CXXIter.h:1400
constexpr size_t size() const
Get this iterator's exact size.
Definition: CXXIter.h:158
constexpr auto map(TMapFn mapFn)
Creates an iterator that uses the given mapFn to map each element from this iterator to elements of t...
Definition: CXXIter.h:1585
constexpr IterValue< Item > last()
Consumer that yields the last element of this iterator.
Definition: CXXIter.h:1204
constexpr auto filterMap(TFilterMapFn filterMapFn)
Creates a new iterator that filters and maps items from this iterator.
Definition: CXXIter.h:1757
constexpr op::FlagLast< TSelf > flagLast()
Constructs a new iterator that tags each element with a boolean value specifying whether the element ...
Definition: CXXIter.h:1333
constexpr std::optional< size_t > findIdx(TFindFn findFn)
Search for the iterator with the given findFn, and return the index of the element from this iterator...
Definition: CXXIter.h:565
constexpr IterValue< Item > maxBy(TMaxValueExtractFn compValueExtractFn)
Consumer that yields the largest element from this iterator. Comparison of items is done using the co...
Definition: CXXIter.h:1122
constexpr op::Zipper< TSelf, std::tuple, TOtherIterators... > zipTuple(TOtherIterators &&... otherIterators)
"Zips up" an arbitrary amount of CXXIter iterators into a single iterator over std::tuple<> from both...
Definition: CXXIter.h:1925
std::remove_cvref_t< Item > ItemOwned
Owned Type of the elements of this iterator. (References removed).
Definition: CXXIter.h:71
constexpr TResult sum(TResult startValue=TResult())
Consumer that calculates the sum of all elements from this iterator.
Definition: CXXIter.h:708
constexpr op::TakeN< TSelf > take(size_t cnt)
Creates an iterator that yields at most the first cnt elements from this iterator.
Definition: CXXIter.h:1818
constexpr auto groupBy(TGroupIdentifierFn groupIdentFn)
Groups the elements of this iterator according to the values returned by the given groupidentFn.
Definition: CXXIter.h:2050
constexpr op::InplaceModifier< TSelf, TModifierFn > modify(TModifierFn modifierFn)
Allows to inspect and modify each item in-place, that passes through this iterator.
Definition: CXXIter.h:1732
constexpr size_t count(TPredicateFn predicateFn)
Consumer that counts the elements in this iterator, for which the given predicateFn returns true.
Definition: CXXIter.h:642
constexpr void forEach(TUseFn useFn)
Consumer that calls the given function useFn for each of the elements in this iterator.
Definition: CXXIter.h:241
constexpr TResult fold(TResult startValue, FoldFn foldFn)
Consumer that executes the given foldFn for each item in this iterator, to apply to a working value,...
Definition: CXXIter.h:353
constexpr op::Intersperser< TSelf, TOtherIterator > intersperse(TOtherIterator &&otherIterator)
Draw elements from the given otherIterator and use the returned elements as separators between the el...
Definition: CXXIter.h:2018
constexpr std::optional< size_t > minIdxBy(TCompValueExtractFn compValueExtractFn)
Consumer that yields the index of the smallest element from this iterator. Comparison of items is don...
Definition: CXXIter.h:1074
constexpr std::optional< TResult > mean(TResult sumStart=TResult())
Consumer that calculates the mean of all elements of this iterator.
Definition: CXXIter.h:785
constexpr std::optional< size_t > minIdx()
Consumer that yields the index of the smallest element within this iterator.
Definition: CXXIter.h:947
constexpr SizeHint sizeHint() const
Get the bounds on the remaining length of this iterator, estimated from the source and all of the cha...
Definition: CXXIter.h:128
constexpr std::optional< TResult > variance()
Consumer that calculates the variance of all elements of this iterator.
Definition: CXXIter.h:839
constexpr bool any()
Tests if any of the elements of this iterator yield the value true when casted to bool.
Definition: CXXIter.h:507
constexpr auto copied()
Constructs a new iterator that copies the elements of this iterator.
Definition: CXXIter.h:1277
constexpr op::Chunked< TSelf, CHUNK_SIZE > chunked()
Create new iterator that collects elements from this iterator in chunks of size up to CHUNK_SIZE,...
Definition: CXXIter.h:1454
constexpr size_t count(const ItemOwned &countItem)
Consumer that counts the occurences of countItem within this iterator.
Definition: CXXIter.h:663
constexpr IterValue< Item > find(TFindFn findFn)
Searches for an element of this iterator, that satisfies the given findFn predicate.
Definition: CXXIter.h:602
constexpr auto flatMap()
Creates an iterator that flattens the iterable elements of this iterator.
Definition: CXXIter.h:1712
constexpr auto sortBy(TSortValueExtractFn sortValueExtractFn)
Creates a new iterator that takes the items from this iterator, and passes them on sorted.
Definition: CXXIter.h:2157
iterator begin()
begin() method, part of C++'s iterator interface
Definition: CXXIter.h:113
constexpr op::SkipWhile< TSelf, TSkipPredicate > skipWhile(TSkipPredicate skipPredicate)
Creates an iterator that skips the first elements of this iterator, for which the given skipPredicate...
Definition: CXXIter.h:1801
constexpr bool any(TPredicateFn predicateFn)
Tests if any of the elements of this iterator match the given predicateFn.
Definition: CXXIter.h:472
constexpr op::SkipN< TSelf > skip(size_t cnt)
Creates an iterator that skips the first cnt elements from this iterator, before it yields the remain...
Definition: CXXIter.h:1776
std::string stringJoin(const std::string &separator)
Consumer that concatenates the elements of this iterator to a large std::string , where each element ...
Definition: CXXIter.h:746
iterator end()
end() method, part of C++'s iterator interface
Definition: CXXIter.h:119
constexpr bool all(TPredicateFn predicateFn)
Tests if all elements of this iterator match the given predicateFn.
Definition: CXXIter.h:396
constexpr TTargetContainer collect()
Consumer that collects all elements from this iterator in a new container of type TTargetContainer.
Definition: CXXIter.h:306
constexpr size_t count()
Consumer that counts the elements in this iterator.
Definition: CXXIter.h:621
constexpr op::Zipper< TSelf, std::pair, TOtherIterator > zip(TOtherIterator &&otherIterator)
"Zips up" two CXXIter iterators into a single iterator over pairs from both iterators.
Definition: CXXIter.h:1898
constexpr bool all()
Tests if all elements of this iterator yield the value true when casted to bool.
Definition: CXXIter.h:431
constexpr IterValue< Item > min()
Consumer that yields the smallest element from this iterator.
Definition: CXXIter.h:924
constexpr auto flatMap(TFlatMapFn mapFn)
Creates an iterator that works like map(), but flattens nested containers.
Definition: CXXIter.h:1611
constexpr auto sort()
Creates a new iterator that takes the items from this iterator, and passes them on sorted.
Definition: CXXIter.h:2116
constexpr op::Chainer< TSelf, TOtherIterator > chain(TOtherIterator &&otherIterator)
Chains this iterator with the given otherIterator, resulting in a new iterator that first yields the ...
Definition: CXXIter.h:1948
constexpr std::optional< TResult > stddev()
Consumer that calculates the standard deviation of all elements of this iterator.
Definition: CXXIter.h:896
constexpr IterValue< Item > next()
Get the next element from this iterator (if any), wrapped in a CXXIter::IterValue<>.
Definition: CXXIter.h:175
constexpr auto sort(TCompareFn compareFn)
Creates a new iterator that takes the items from this iterator, and passes them on sorted,...
Definition: CXXIter.h:2085
constexpr std::optional< size_t > findIdx(const ItemOwned &searchItem)
Search for the given searchItem within the items of this iterator, and return the index of the first ...
Definition: CXXIter.h:533
constexpr op::Filter< TSelf, TFilterFn > filter(TFilterFn filterFn)
Constructs a new iterator that only contains the elements from this iterator, for which the given fil...
Definition: CXXIter.h:1353
constexpr std::optional< size_t > maxIdxBy(TMaxValueExtractFn compValueExtractFn)
Consumer that yields the index of the largest element from this iterator. Comparison of items is done...
Definition: CXXIter.h:1165
Container that is used to pass elements through CXXIter's iterator pipelines.
Definition: IterValue.h:19
constexpr bool has_value() const noexcept
Get whether this optional IteratorValue contains a value.
Definition: IterValue.h:86
constexpr const TValueDeref & value() const
Get the contained value (if any).
Definition: IterValue.h:62
CXXIter iterator source that immutably borrows the input item source, and passes immutable references...
CXXIter iterator source that takes over the input item source, and moves its items through the elemen...
CXXIter iterator source that mutably borrows the input item source, and passes mutable references to ...
CXXIter.
Definition: CXXIter.h:48
constexpr Range< TValue > range(TValue from, TValue to, TValue step=1)
Construct a CXXIter iterator that yields all elements in the range between [from, to] (inclusive both...
Definition: CXXIter.h:2341
auto generate(TGeneratorFn generatorFn)
Generator source that produces a new iterator over the elements produced by the given generatorFn - w...
Definition: CXXIter.h:2289
constexpr Repeater< TItem > repeat(const TItem &item, std::optional< size_t > cnt={})
Construct a CXXIter iterator, by repeating the given item cnt times.
Definition: CXXIter.h:2313
@ N
Use when the mean, variance, stddev is calculated with the COMPLETE population.
constexpr Empty< TItem > empty()
Constructs an empty iterator yielding no items.
Definition: CXXIter.h:2236
constexpr SrcMov< std::remove_cvref_t< TContainer > > from(TContainer &&container)
Construct a CXXIter move source from the given container.
Definition: CXXIter.h:2188
constexpr auto fromFn(TGeneratorFn generatorFn)
Generator source that takes a generatorFn, each invocation of which produces one element for the resu...
Definition: CXXIter.h:2261
Structure holding the bounds of a CXXIter iterator's estimated length.
Definition: SizeHint.h:15
static constexpr IterValue< typename Iterator< T >::Item > nextBack(Self &self)=delete
Pull the next last element from the iterator pipeline previous to this pipeline-element.
static constexpr size_t size(const typename trait::Iterator< T >::Self &self)=delete
Get the iterator's exact number of elements.
Trait, that is used for the chaining and the operation of iterator pipelines.
Definition: Traits.h:24
static constexpr IterValue< Item > next(Self &self)=delete
Pull one element from the iterator pipeline previous to this pipeline-element.
void Item
Item-Type. This is the type of elements that can be pulled from this pipeline-element.
Definition: Traits.h:32
static constexpr SizeHint sizeHint(const Self &self)=delete
Get the bounds on the remaining length of the iterator pipeline until this pipeline-element,...
static constexpr size_t advanceBy(Self &self, size_t n)=delete
Advance the iterator by n elements.