xtd 1.0.0
Loading...
Searching...
No Matches
enumerable.hpp
Go to the documentation of this file.
1
4#pragma once
5#include "enumerable_.hpp" // contains xtd::linq::enumerable <type_t> class definition
8#include "../nullopt.hpp"
9#include "from.hpp"
10
12template<typename type_t>
13xtd::linq::enumerable::enumerable_holder<type_t>::enumerable_holder(const type_t& value) : ptr_(std::addressof(value)) {
14}
15
16//template<typename type_t>
17//xtd::linq::enumerable::enumerable_holder<type_t>::enumerable_holder(type_t& value) : ptr_(std::addressof(value)) {
18//}
19
20template<typename type_t>
21xtd::linq::enumerable::enumerable_holder<type_t>::enumerable_holder(type_t&& value) requires std::movable<type_t> : value_(std::move(value)), ptr_(std::addressof(*value_)) {
22}
23
24template<typename type_t>
25auto xtd::linq::enumerable::enumerable_holder<type_t>::get() const -> const xtd::raw_type<type_t>& {return *ptr_;}
26
27template<xtd::iterable source_t, xtd::func_callable<xtd::iterable_value_type<source_t>, xtd::iterable_value_type<source_t>, xtd::iterable_value_type<source_t>> func_t>
28auto xtd::linq::enumerable::aggregate(source_t&& source, func_t&& func) -> xtd::iterable_value_type<source_t> {
29 auto nb = 0;
30 auto aggregated = xtd::iterable_value_type<source_t> {};
31 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
32 //for (const auto& item : source_holder.get())
33 for (const auto& item : source)
34 aggregated = nb++ == 0 ? item : func(aggregated, item);
35 return aggregated;
36}
37
38template<typename accumulate_t, xtd::iterable source_t, xtd::func_callable<accumulate_t, accumulate_t, xtd::iterable_value_type<source_t>> func_t>
39auto xtd::linq::enumerable::aggregate(source_t&& source, accumulate_t&& seed, func_t&& func) -> accumulate_t {
40 auto aggregated = std::move(seed);
41 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
42 //for (const auto& item : source_holder.get())
43 for (const auto& item : source)
44 aggregated = func(aggregated, item);
45 return aggregated;
46}
47
48template<typename result_t, typename accumulate_t, xtd::iterable source_t, xtd::func_callable<accumulate_t, accumulate_t, xtd::iterable_value_type<source_t>> func_t, xtd::func_callable<result_t, accumulate_t> result_selector_t>
49auto xtd::linq::enumerable::aggregate(source_t&& source, accumulate_t&& seed, func_t&& func, result_selector_t&& result_selector) -> result_t {
50 auto aggregated = std::move(seed);
51 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
52 //for (const auto& item : source_holder.get())
53 for (const auto& item : source)
54 aggregated = func(aggregated, item);
55 return result_selector(aggregated);
56}
57
58template<xtd::iterable source_t, xtd::predicate_callable<xtd::iterable_value_type<source_t>> predicate_t>
59auto xtd::linq::enumerable::all(source_t&& source, predicate_t&& predicate) -> bool {
60 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
61 //for (const auto& item : source_holder.get())
62 for (const auto& item : source)
63 if (!predicate(item)) return false;
64 return true;
65}
66
67template<xtd::iterable source_t>
68auto xtd::linq::enumerable::any(source_t&& source) noexcept -> bool {
69 return source.begin() != source.end();
70}
71
72template<xtd::iterable source_t, xtd::predicate_callable<xtd::iterable_value_type<source_t>> predicate_t>
73auto xtd::linq::enumerable::any(source_t&& source, predicate_t&& predicate) -> bool {
74 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
75 //for (const auto& item : source_holder.get())
76 for (const auto& item : source)
77 if (predicate(item)) return true;
78 return false;
79}
80
81template<xtd::iterable source_t>
83 //auto source_holder = enumerable_holder<source_t> {std::forward<xtd::raw_type<source_t>>(source)};
84 //for (const auto& item : source_holder.get())
85 for (const auto& item : source)
86 co_yield item;
87 co_yield std::move(element);
88}
89
90template<xtd::iterable source_t>
92 for (const auto& item : source)
93 co_yield item;
94}
95
96template<xtd::iterable source_t>
98 for (const auto& item : source)
99 co_yield item;
100}
101
102template<typename value_t>
103auto xtd::linq::enumerable::as_enumerable(std::initializer_list<value_t> source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
104 for (const auto& item : source)
105 co_yield item;
106}
107
108template<std::forward_iterator iterator_t>
109auto xtd::linq::enumerable::as_enumerable(iterator_t first, iterator_t last) noexcept -> xtd::collections::generic::enumerable_generator<typename std::decay<decltype(*first)>::type> {
110 for (auto iterator = first; iterator != last; ++iterator)
111 co_yield *iterator;
112}
113
114template<std::forward_iterator iterator_t>
115auto xtd::linq::enumerable::as_enumerable(iterator_t iterator, xtd::usize length) noexcept -> xtd::collections::generic::enumerable_generator<typename std::decay<decltype(*iterator)>::type> {
116 return as_enumerable(iterator, iterator + length);
117}
118
119template<typename value_t, xtd::usize length>
121 return as_enumerable(array, array + length);
122}
123
124template<typename value_t, xtd::usize length>
126 return as_enumerable(array, array + length);
127}
128
129template<typename value_t, typename container_t>
130auto xtd::linq::enumerable::as_enumerable(const std::queue<value_t, container_t>& source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
131 struct accessor : public std::queue<value_t> {static auto get() {return &accessor::c;}};
132 const auto& underlying_items = source.*accessor::get();
133 return as_enumerable(underlying_items.begin(), underlying_items.end());
134}
135template<typename value_t, typename container_t>
136auto xtd::linq::enumerable::as_enumerable(std::queue<value_t, container_t>& source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
137 struct accessor : public std::queue<value_t> {static auto get() {return &accessor::c;}};
138 const auto& underlying_items = source.*accessor::get();
139 return as_enumerable(underlying_items.begin(), underlying_items.end());
140}
141template<typename value_t, typename container_t>
142auto xtd::linq::enumerable::as_enumerable(const std::priority_queue<value_t, container_t>& source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
143 struct accessor : public std::priority_queue<value_t> {static auto get() {return &accessor::c;}};
144 const auto& underlying_items = source.*accessor::get();
145 return as_enumerable(underlying_items.begin(), underlying_items.end());
146}
147template<typename value_t, typename container_t>
148auto xtd::linq::enumerable::as_enumerable(std::priority_queue<value_t, container_t>& source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
149 struct accessor : public std::priority_queue<value_t> {static auto get() {return &accessor::c;}};
150 const auto& underlying_items = source.*accessor::get();
151 return as_enumerable(underlying_items.begin(), underlying_items.end());
152}
153template<typename value_t, typename container_t>
154auto xtd::linq::enumerable::as_enumerable(const std::stack<value_t, container_t>& source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
155 struct accessor : public std::stack<value_t> {static auto get() {return &accessor::c;}};
156 const auto& underlying_items = source.*accessor::get();
157 return as_enumerable(underlying_items.begin(), underlying_items.end());
158}
159template<typename value_t, typename container_t>
160auto xtd::linq::enumerable::as_enumerable(std::stack<value_t, container_t>& source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
161 struct accessor : public std::stack<value_t> {static auto get() {return &accessor::c;}};
162 const auto& underlying_items = source.*accessor::get();
163 return as_enumerable(underlying_items.begin(), underlying_items.end());
164}
165
166template<xtd::iterable source_t>
168auto xtd::linq::enumerable::average(source_t&& source) -> xtd::decimal {
169 auto average = .0l;
170 auto count = 0;
171 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
172 //for (const auto& item : source_holder.get())
173 for (const auto& item : source) {
174 average += item;
175 ++count;
176 }
178 return average / count;
179}
180
181template<xtd::iterable source_t>
183auto xtd::linq::enumerable::average(source_t&& source) -> double {
184 auto average = .0;
185 auto count = 0;
186 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
187 //for (const auto& item : source_holder.get())
188 for (const auto& item : source) {
189 average += item;
190 ++count;
191 }
193 return average / count;
194}
195
196template<xtd::iterable source_t>
198auto xtd::linq::enumerable::average(source_t&& source) -> xtd::single {
199 auto average = .0f;
200 auto count = 0;
201 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
202 //for (const auto& item : source_holder.get())
203 for (const auto& item : source) {
204 average += item;
205 ++count;
206 }
208 return average / count;
209}
210
211template<xtd::iterable source_t>
213auto xtd::linq::enumerable::average(source_t&& source) -> double {
214 auto average = .0;
215 auto count = 0;
216 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
217 //for (const auto& item : source_holder.get())
218 for (const auto& item : source) {
219 average += item;
220 ++count;
221 }
223 return average / count;
224}
225
226template<xtd::iterable source_t>
228auto xtd::linq::enumerable::average(source_t&& source) -> double {
229 auto average = .0;
230 auto count = 0;
231 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
232 //for (const auto& item : source_holder.get())
233 for (const auto& item : source) {
234 average += item;
235 ++count;
236 }
238 return average / count;
239}
240
241template<xtd::iterable source_t>
242requires std::same_as<xtd::iterable_value_type<source_t>, xtd::optional<xtd::decimal>>
244 auto average = .0l;
245 auto count = 0;
246 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
247 //for (const auto& item : source_holder.get())
248 for (const auto& item : source) {
249 if (!item) continue;
250 average += *item;
251 ++count;
252 }
253 return count == 0 ? xtd::nullopt : std::make_optional(average / count);
254}
255
256template<xtd::iterable source_t>
257requires std::same_as<xtd::iterable_value_type<source_t>, xtd::optional<double>>
258auto xtd::linq::enumerable::average(source_t&& source) -> xtd::optional<double> {
259 auto average = .0;
260 auto count = 0;
261 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
262 //for (const auto& item : source_holder.get())
263 for (const auto& item : source) {
264 if (!item) continue;
265 average += *item;
266 ++count;
267 }
268 return count == 0 ? xtd::nullopt : std::make_optional(average / count);
269}
270
271template<xtd::iterable source_t>
272requires std::same_as<xtd::iterable_value_type<source_t>, xtd::optional<xtd::single>>
274 auto average = .0f;
275 auto count = 0;
276 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
277 //for (const auto& item : source_holder.get())
278 for (const auto& item : source) {
279 if (!item) continue;
280 average += *item;
281 ++count;
282 }
283 return count == 0 ? xtd::nullopt : std::make_optional(average / count);
284}
285
286template<xtd::iterable source_t>
287requires std::same_as<xtd::iterable_value_type<source_t>, xtd::optional<xtd::int32>>
288auto xtd::linq::enumerable::average(source_t&& source) -> xtd::optional<double> {
289 auto average = .0;
290 auto count = 0;
291 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
292 //for (const auto& item : source_holder.get())
293 for (const auto& item : source) {
294 if (!item) continue;
295 average += *item;
296 ++count;
297 }
298 return count == 0 ? xtd::nullopt : std::make_optional(average / count);
299}
300
301template<xtd::iterable source_t>
302requires std::same_as<xtd::iterable_value_type<source_t>, xtd::optional<xtd::int64>>
303auto xtd::linq::enumerable::average(source_t&& source) -> xtd::optional<double> {
304 auto average = .0;
305 auto count = 0;
306 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
307 //for (const auto& item : source_holder.get())
308 for (const auto& item : source) {
309 if (!item) continue;
310 average += *item;
311 ++count;
312 }
313 return count == 0 ? xtd::nullopt : std::make_optional(average / count);
314}
315
316template<xtd::iterable first_t,xtd::iterable second_t>
318 //auto first_holder = enumerable_holder<xtd::raw_type<first_t>> {std::forward<first_t>(first)};
319 //auto second_holder = enumerable_holder<xtd::raw_type<second_t>> {std::forward<second_t>(second)};
320 //for (const auto& item : first_holder.get())
321 // co_yield item;
322 //for (const auto& item : second_holder.get())
323 // co_yield item;
324 for (const auto& item : first)
325 co_yield item;
326 for (const auto& item : second)
327 co_yield item;
328}
329
330template<xtd::iterable source_t>
331auto xtd::linq::enumerable::contains(source_t&& source, const xtd::iterable_value_type<source_t>& value) noexcept -> bool {
332 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
333 //for (const auto& item : source_holder.get())
334 for (const auto& item : source)
335 if (item == value) return true;
336 return false;
337}
338
339template<xtd::iterable source_t>
340auto xtd::linq::enumerable::contains(source_t&& source, const xtd::iterable_value_type<source_t>& value, const iequality_comparer<xtd::iterable_value_type<source_t>>& comparer) noexcept -> bool {
341 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
342 //for (const auto& item : source_holder.get())
343 for (const auto& item : source)
344 if (comparer.equals(item, value)) return true;
345 return false;
346}
347
348template<xtd::iterable source_t, xtd::func_callable<bool, xtd::iterable_value_type<source_t>, xtd::iterable_value_type<source_t>> equater_t>
349auto xtd::linq::enumerable::contains(source_t&& source, const xtd::iterable_value_type<source_t>& value, equater_t&& equater) noexcept -> bool {
350 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
351 //for (const auto& item : source_holder.get())
352 for (const auto& item : source)
353 if (equater(item, value)) return true;
354 return false;
355}
356
357template<xtd::iterable source_t>
358auto xtd::linq::enumerable::count(source_t&& source) noexcept -> xtd::usize {
359 auto count = xtd::usize {0};
360 auto enumerator = source.get_enumerator();
361 while (enumerator.move_next()) ++count;
362 return count;
363}
364
365template<xtd::iterable source_t, xtd::predicate_callable<xtd::iterable_value_type<source_t>> predicate_t>
366auto xtd::linq::enumerable::count(source_t&& source, predicate_t&& predicate) noexcept -> xtd::usize {
367 return where(std::forward<source_t>(source), predicate).count();
368}
369
370template<xtd::iterable source_t>
371auto xtd::linq::enumerable::count(source_t&& source, xtd::iterable_value_type<source_t>&& value) noexcept -> xtd::usize {
372 return count(std::forward<source_t>(source), [value](const xtd::iterable_value_type<source_t>& item) -> bool {return item == value;});
373}
374
375template<typename key_t, xtd::iterable source_t, xtd::callable<key_t, xtd::iterable_value_type<source_t>> key_selector_t>
377 return count_by<key_t>(std::forward<source_t>(source), key_selector, [](auto&& a, auto&& b) {return xtd::collections::generic::equality_comparer<key_t>::default_equality_comparer().equals(a, b);});
378 //return count_by<key_t>(std::forward<source_t>(source), key_selector, xtd::collections::generic::equality_comparer<key_t>::default_equality_comparer());
379}
380
381template<typename key_t, xtd::iterable source_t, xtd::callable<key_t, xtd::iterable_value_type<source_t>> key_selector_t>
382auto xtd::linq::enumerable::count_by(source_t&& source, key_selector_t&& key_selector, const iequality_comparer<key_t>& key_comparer) noexcept -> xtd::collections::generic::enumerable_generator<xtd::collections::generic::key_value_pair<key_t, xtd::usize>> {
383 return count_by<key_t>(std::forward<source_t>(source), key_selector, [&key_comparer](auto&& a, auto&& b) {return key_comparer.equals(a, b);});
384}
385
386template<xtd::iterable source_t>
389 //return default_if_empty(std::forward<source_t>(source), std::forward<xtd::iterable_value_type<source_t>>(default_value));
390 if (!any(source)) co_yield default_value;
391 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
392 //else for (const auto& item : source_holder.get())
393 else for (const auto& item : source)
394 co_yield item;
395}
396
397template<xtd::iterable source_t>
399 if (!any(source)) co_yield default_value;
400 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
401 //else for (const auto& item : source_holder.get())
402 else for (const auto& item : source)
403 co_yield item;
404}
405
406template<xtd::iterable source_t, xtd::predicate_callable<xtd::iterable_value_type<source_t>> prediacte_t>
407auto xtd::linq::enumerable::first_or_default(source_t&& source, prediacte_t&& predicate, xtd::iterable_value_type<source_t>&& default_value) noexcept -> xtd::iterable_value_type<source_t> {
408 auto result = where(std::forward<source_t>(source), std::forward<prediacte_t>(predicate));
409 return any(result) ? *result.begin() : std::move(default_value);
410}
411
412template<xtd::iterable source_t, xtd::predicate_callable<xtd::iterable_value_type<source_t>> prediacte_t>
413auto xtd::linq::enumerable::first_or_default(source_t&& source, prediacte_t&& predicate) noexcept -> xtd::iterable_value_type<source_t> {
414 return first_or_default(std::forward<source_t>(source), std::forward<prediacte_t>(predicate), xtd::iterable_value_type<source_t> {});
415}
416
417template<xtd::iterable source_t>
419 return any(std::forward<source_t>(source)) ? *source.begin() : std::move(default_value);
420}
421
422template<xtd::iterable source_t>
424 return first_or_default(std::forward<source_t>(source), xtd::iterable_value_type<source_t> {});
425}
426
427template<xtd::iterable source_t>
429 return as_enumerable(source);
430}
431
432template<xtd::iterable source_t>
434 return as_enumerable(source);
435}
436
437template<typename value_t>
438auto xtd::linq::enumerable::from(std::initializer_list<value_t> source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
439 return as_enumerable(source);
440}
441
442template<std::forward_iterator iterator_t>
443auto xtd::linq::enumerable::from(iterator_t first, iterator_t last) noexcept -> xtd::collections::generic::enumerable_generator<typename std::decay<decltype(*first)>::type> {
444 return as_enumerable(first, last);
445}
446
447template<std::forward_iterator iterator_t>
448auto xtd::linq::enumerable::from(iterator_t iterator, xtd::usize length) noexcept -> xtd::collections::generic::enumerable_generator<typename std::decay<decltype(*iterator)>::type> {
449 return as_enumerable(iterator, length);
450}
451
452template<typename value_t, xtd::usize length>
453auto xtd::linq::enumerable::from(const value_t (&array)[length]) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
454 return as_enumerable(array);
455}
456
457template<typename value_t, xtd::usize length>
459 return as_enumerable(array);
460}
461
462template<typename value_t, typename container_t>
463auto xtd::linq::enumerable::from(const std::queue<value_t, container_t>& source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
464 return as_enumerable(source);
465}
466
467template<typename value_t, typename container_t>
468auto xtd::linq::enumerable::from(std::queue<value_t, container_t>& source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
469 return as_enumerable(source);
470}
471
472template<typename value_t, typename container_t>
473auto xtd::linq::enumerable::from(const std::priority_queue<value_t, container_t>& source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
474 return as_enumerable(source);
475}
476
477template<typename value_t, typename container_t>
478auto xtd::linq::enumerable::from(std::priority_queue<value_t, container_t>& source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
479 return as_enumerable(source);
480}
481
482template<typename value_t, typename container_t>
483auto xtd::linq::enumerable::from(const std::stack<value_t, container_t>& source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
484 return as_enumerable(source);
485}
486
487template<typename value_t, typename container_t>
488auto xtd::linq::enumerable::from(std::stack<value_t, container_t>& source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
489 return as_enumerable(source);
490}
491
492template<xtd::iterable source_t>
496 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
497 //for (const auto& item : source_holder.get())
498 for (const auto& item : source)
499 if (!result || item > result) result = item;
500 return result.value_or(xtd::iterable_value_type<source_t> {});
501}
502
503template<xtd::iterable source_t, xtd::callable<xtd::iterable_value_type<source_t>, xtd::iterable_value_type<source_t>> selector_t>
505auto xtd::linq::enumerable::max(source_t&& source, selector_t&& selector) -> xtd::iterable_value_type<source_t> {
507 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
508 //for (const auto& item : source_holder.get())
509 for (const auto& item : source) {
510 auto val = selector(item);
511 if (!result || val > result) result = val;
512 }
513 return result.value_or(xtd::iterable_value_type<source_t> {});
514}
515
516template<typename result_t, xtd::iterable source_t, xtd::callable<result_t, xtd::iterable_value_type<source_t>> selector_t>
518auto xtd::linq::enumerable::max(source_t&& source, selector_t&& selector) -> result_t {
519 auto result = xtd::optional<result_t> {};
520 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
521 //for (const auto& item : source_holder.get())
522 for (const auto& item : source) {
523 auto val = selector(item);
524 if (!result || val > result) result = val;
525 }
526 return result.value_or(result_t {});
527}
528
529template<xtd::iterable source_t>
532 auto result = xtd::optional<source_t> {};
533 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
534 //for (const auto& item : source_holder.get())
535 for (const auto& item : source)
536 if (!result || item < result) result = item;
537 return result.value_or(source_t {});
538}
539
540template<xtd::iterable source_t, xtd::callable<xtd::iterable_value_type<source_t>, xtd::iterable_value_type<source_t>> selector_t>
542auto xtd::linq::enumerable::min(source_t&& source, selector_t&& selector) -> xtd::iterable_value_type<source_t> {
543 auto result = xtd::optional<source_t> {};
544 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
545 //for (const auto& item : source_holder.get())
546 for (const auto& item : source) {
547 auto val = selector(item);
548 if (!result || val < result) result = val;
549 }
550 return result.value_or(source_t {});
551}
552
553template<typename result_t, xtd::iterable source_t, xtd::callable<result_t, xtd::iterable_value_type<source_t>> selector_t>
555auto xtd::linq::enumerable::min(source_t&& source, selector_t&& selector) -> result_t {
556 auto result = xtd::optional<result_t> {};
557 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
558 //for (const auto& item : source_holder.get())
559 for (const auto& item : source) {
560 auto val = selector(item);
561 if (!result || val < result) result = val;
562 }
563 return result.value_or(result_t {});
564}
565
566template<xtd::iterable source_t>
568 //return order(source, xtd::collections::generic::comparer<xtd::iterable_value_type<source_t>>::default_comparer);
570}
571
572template<xtd::iterable source_t>
575}
576
577template<xtd::integer integer_t>
579 auto step = integer_t {};
580 return range(integer_t {}, count, ++step);
581}
582
583template<xtd::integer integer_t>
585 auto step = integer_t {};
586 return range(start, count, ++step);
587}
588
589template<xtd::integer integer_t>
590auto xtd::linq::enumerable::range(integer_t start, integer_t count, integer_t step) -> xtd::collections::generic::enumerable_generator<integer_t> {
593
594 for (auto index = integer_t {}; index < count; ++index)
595 co_yield start + (index * step);
596}
597
598template<typename result_t, xtd::iterable source_t>
600 auto index = xtd::usize {0};
601 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
602 //for (const auto& item : source_holder.get())
603 for (const auto& item : source)
604 co_yield invoke_selector_with_optional_index<result_t>(selector, item, index++);
605}
606
607template<xtd::iterable source_t>
609 auto index = xtd::usize {0};
610 //auto source_holder = enumerable_holder<xtd::raw_type<source_t>> {std::forward<source_t>(source)};
611 //for (const auto& item : source_holder.get())
612 for (const auto& item : source)
613 co_yield invoke_selector_with_optional_index<xtd::iterable_value_type<source_t>>(selector, item, index++);
614}
615
616template<xtd::iterable source_t>
618 auto index = xtd::usize {0};
619 //auto source_holder = enumerable_holder<xtd::raw_type<source_t>> {std::forward<source_t>(source)};
620 //for (const auto& item : source_holder.get())
621 for (const auto& item : source) {
622 if (index++ < count) continue;
623 co_yield item;
624 }
625}
626
627template<xtd::iterable source_t>
629 bool skip = true;
630 auto index = xtd::usize {0};
631 //auto source_holder = enumerable_holder<xtd::raw_type<source_t>> {std::forward<source_t>(source)};
632 //for (const auto& item : source_holder.get())
633 for (const auto& item : source) {
634 if (skip && !invoke_predicate_with_optional_index(predicate, item, index++)) skip = false;
635 if (!skip) co_yield item;
636 }
637}
638
639template<xtd::iterable source_t>
641 auto index = xtd::usize {0};
642 //auto source_holder = enumerable_holder<xtd::raw_type<source_t>> {std::forward<source_t>(source)};
643 //for (const auto& item : source_holder.get())
644 for (const auto& item : source) {
645 if (index++ == count) break;
646 co_yield item;
647 }
648}
649
650template<xtd::iterable source_t>
652 auto index = xtd::usize {0};
653 //auto source_holder = enumerable_holder<xtd::raw_type<source_t>> {std::forward<source_t>(source)};
654 //for (const auto& item : source_holder.get())
655 for (const auto& item : source) {
656 if (!invoke_predicate_with_optional_index(predicate, item, index++)) break;
657 co_yield item;
658 }
659}
660
661template<xtd::iterable source_t>
663 auto index = xtd::usize {0};
664 //auto source_holder = enumerable_holder<xtd::raw_type<source_t>> {std::forward<source_t>(source)};
665 //for (const auto& item : source_holder.get())
666 for (const auto& item : source)
667 if (invoke_predicate_with_optional_index(predicate, item, index++)) co_yield item;
668}
669
670
671template<typename predicate_t, typename value_t>
672constexpr auto xtd::linq::enumerable::invoke_predicate_with_optional_index(predicate_t&& predicate, value_t&& value, xtd::usize index) -> bool {
673 if constexpr (xtd::func_callable<predicate_t, bool, xtd::raw_type<value_t>, xtd::usize>) return predicate(std::forward<value_t>(value), index);
674 else if constexpr (xtd::predicate_callable<predicate_t, xtd::raw_type<value_t>>) return predicate(std::forward<value_t>(value));
675 else static_assert(always_false_v<predicate_t>, "Predicate must accept either (value) or (value, index).");
676}
677
678template<typename result_t, typename selector_t, typename value_t>
679auto xtd::linq::enumerable::invoke_selector_with_optional_index(selector_t&& selector, value_t&& value, xtd::usize index) -> result_t {
680 if constexpr (xtd::callable<selector_t, xtd::raw_type<result_t>, xtd::raw_type<value_t>, xtd::usize>) return selector(std::forward<value_t>(value), index);
681 if constexpr (xtd::callable<selector_t, xtd::raw_type<result_t>, xtd::raw_type<value_t>>) return selector(std::forward<value_t>(value));
682 else static_assert(always_false_v<selector_t>, "Selector must accept either (value) or (value, index).");
683}
Provides a base class for implementations of the xtd::collections::generic::icomparer <type_t> generi...
Definition comparer.hpp:33
Represents an enumerable generator that supports deferred, lazy iteration over a collection of a spec...
Definition enumerable_generator.hpp:44
static auto default_equality_comparer() -> const equality_comparer &
Gets the default equality comparer for the type specified by the generic argument.
Definition equality_comparer.hpp:42
Exposes a method that compares two objects.
Definition icomparer.hpp:30
static auto throws(xtd::helpers::exception_case exception_case, const source_location &location=source_location::current()) -> void
Throws an exption with specified exception case.
static auto skip_while(source_t &&source, auto &&predicate) -> xtd::collections::generic::enumerable_generator< xtd::iterable_value_type< source_t > >
Bypasses elements in a sequence as long as a specified condition is true and then returns the remaini...
static auto concat(first_t &&first, second_t &&second) noexcept -> xtd::collections::generic::enumerable_generator< xtd::iterable_value_type< first_t > >
Concatenates two sequences.
static auto first_or_default(source_t &&source, prediacte_t &&predicate, xtd::iterable_value_type< source_t > &&default_value) noexcept -> xtd::iterable_value_type< source_t >
Returns the first element of the sequence that satisfies a condition, or a specified default value if...
static auto min(source_t &&source) -> xtd::iterable_value_type< source_t >
Returns the minimum value in a sequence of xtd::numeric values.
static auto select(source_t &&source, auto &&selector) -> xtd::collections::generic::enumerable_generator< result_t >
Projects each element of a sequence into a new form.
static auto default_if_empty(source_t &&source) noexcept -> xtd::collections::generic::enumerable_generator< xtd::iterable_value_type< source_t > >
Returns the elements of the specified sequence or the type parameter's default value in a singleton c...
static auto contains(source_t &&source, const xtd::iterable_value_type< source_t > &value) noexcept -> bool
Determines whether a sequence contains a specified element by using the default equality comparer.
static auto take(source_t &&source, xtd::usize count) -> xtd::collections::generic::enumerable_generator< xtd::iterable_value_type< source_t > >
Returns a specified number of contiguous elements from the start of a sequence.
static auto count_by(source_t &&source, key_selector_t &&key_selector) noexcept -> xtd::collections::generic::enumerable_generator< xtd::collections::generic::key_value_pair< key_t, xtd::usize > >
Returns the count of elements in the source sequence grouped by key.
static auto all(source_t &&source, predicate_t &&predicate) -> bool
Determines whether all elements of a sequence satisfy a condition.
static auto from(source_t &&source) noexcept
Returns the input typed as xtd::collections::generic::ienumerable <type_t>.
static auto order(source_t &&source) -> xtd::collections::generic::enumerable_generator< xtd::iterable_value_type< source_t > >
Sorts the elements of a sequence in ascending order.
static auto where(source_t &&source, auto &&predicate) -> xtd::collections::generic::enumerable_generator< xtd::iterable_value_type< source_t > >
Filters a sequence of values based on a predicate.
static auto aggregate(source_t &&source, func_t &&func) -> xtd::iterable_value_type< source_t >
Applies an accumulator function over a sequence.
static auto as_enumerable(source_t &&source) noexcept
Returns the input typed as xtd::collections::generic::ienumerable <type_t>.
static auto average(source_t &&source) -> xtd::decimal
Computes the average of a sequence of xtd::decimal values.
static auto append(source_t &&source, xtd::iterable_value_type< source_t > &&element) noexcept -> xtd::collections::generic::enumerable_generator< xtd::iterable_value_type< source_t > >
Appends a value to the end of the sequence.
static auto count(source_t &&source) noexcept -> xtd::usize
Returns the number of elements in a sequence.
static auto range(integer_t count) -> xtd::collections::generic::enumerable_generator< integer_t >
Generates a sequence of integral numbers within a specified range.
static auto skip(source_t &&source, xtd::usize count) -> xtd::collections::generic::enumerable_generator< xtd::iterable_value_type< source_t > >
Bypasses a specified number of elements in a sequence and then returns the remaining elements.
static auto max(source_t &&source) -> xtd::iterable_value_type< source_t >
Returns the maximum value in a sequence of xtd::numeric values.
static auto take_while(source_t &&source, auto &&predicate) -> xtd::collections::generic::enumerable_generator< xtd::iterable_value_type< source_t > >
Returns elements from a sequence as long as a specified condition is true, and then skips the remaini...
static auto any(source_t &&source) noexcept -> bool
Determines whether a sequence contains any elements.
virtual auto equals(const object &obj) const noexcept -> bool
Determines whether the specified object is equal to the current object.
Contains xtd::collections::generic::extensions::enumerable <type_t> class.
Definition callable.hpp:11
Definition func_callable.hpp:11
Definition numeric.hpp:12
Definition predicate_callable.hpp:11
Definition real_decimal.hpp:13
Definition real_double.hpp:13
Definition real_single.hpp:13
Definition signed_integer_32.hpp:13
Definition signed_integer_64.hpp:14
Contains xtd::collections::generic::enumerable_generator <> class.
Contains xtd::linq::from methods.
generic::enumerator< xtd::any_object > enumerator
Supports a simple iteration over a non-generic collection.
Definition enumerator.hpp:28
xtd::collections::generic::comparer< xtd::any_object > comparer
Exposes a method that compares two objects.
Definition comparer.hpp:25
xtd::raw_type< decltype(*std::begin(std::declval< iterable_t & >()))> iterable_value_type
Represents the orward iterable value type.
Definition iterable_value_type.hpp:29
xtd::delegate< result_t(arguments_t... arguments)> func
Represents a delegate that has variables parameters and returns a value of the type specified by the ...
Definition func.hpp:27
@ value
Represnets the constant operator precedence (42).
Definition operator_precedence.hpp:30
@ argument
The argument is not valid.
Definition exception_case.hpp:31
@ argument_out_of_range
The argument is out of range.
Definition exception_case.hpp:35
@ invalid_operation
The operation is not valid.
Definition exception_case.hpp:65
constexpr auto where
The xtd::ranges::views::where instance.
Definition where.hpp:40
auto range(type_t count)
Generates a sequence of integral numbers within a specified range.
Definition range.hpp:39
long double decimal
Represents a decimal-precision floating-point number.
Definition decimal.hpp:23
std::optional< type_t > optional
Represents the optional alias on std::optional.
Definition optional.hpp:26
std::size_t usize
Represents an unsigned size of any object in bytes.
Definition usize.hpp:22
constexpr null_opt nullopt
Represents a nullopt value. Used to indicate that an std::optional does not contain a value.
Definition nullopt.hpp:26
float single
Represents a single-precision floating-point number.
Definition single.hpp:23
std::any any
Represents the any alias on std::any.
Definition any.hpp:24
std::remove_cvref_t< value_t > raw_type
Represents a raw type alias equivalent to std::remove_cvref_t<value_t>.
Definition raw_type.hpp:25
xtd::func< bool, type_t > predicate
Represents a delegate that defines a set of criteria and determines whether the specified object meet...
Definition predicate.hpp:16
@ default_value
Default quality.
Definition compositing_quality.hpp:24
Contains xtd::linq::enumerable <type_t> class.
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition abstract_object.hpp:8
const xtd::collections::generic::helpers::wrap_pointer_iterator< pointer > iterator
Represents the iterator of read_only_span value type.
Definition read_only_span.hpp:75
auto last() const -> read_only_span< type_t, count >
Obtains a subspan consisting of the last N elements of the sequence.
Definition read_only_span.hpp:288
Contains xtd::nullopt valiue.
bool move_next() override
Advances the enumerator to the next element of the collection.
Definition enumerator.hpp:72
Implements a function object for compare data.
Definition lesser.hpp:39