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>
408 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
409 //for (const auto& item : source_holder.get())
410 for (const auto& item : source)
411 return item;
413}
414
415template<xtd::iterable source_t, xtd::func_callable<bool, xtd::iterable_value_type<source_t>> predicate_t>
416auto xtd::linq::enumerable::first(source_t&& source, predicate_t&& predicate) -> xtd::iterable_value_type<source_t> {
417 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
418 //for (const auto& item : source_holder.get())
419 for (const auto& item : source)
420 if (predicate(item)) return item;
422}
423
424template<xtd::iterable source_t, xtd::predicate_callable<xtd::iterable_value_type<source_t>> prediacte_t>
425auto 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> {
426 auto result = where(std::forward<source_t>(source), std::forward<prediacte_t>(predicate));
427 return any(result) ? *result.begin() : std::move(default_value);
428}
429
430template<xtd::iterable source_t, xtd::predicate_callable<xtd::iterable_value_type<source_t>> prediacte_t>
431auto xtd::linq::enumerable::first_or_default(source_t&& source, prediacte_t&& predicate) noexcept -> xtd::iterable_value_type<source_t> {
432 return first_or_default(std::forward<source_t>(source), std::forward<prediacte_t>(predicate), xtd::iterable_value_type<source_t> {});
433}
434
435template<xtd::iterable source_t>
437 return any(std::forward<source_t>(source)) ? *source.begin() : std::move(default_value);
438}
439
440template<xtd::iterable source_t>
442 return first_or_default(std::forward<source_t>(source), xtd::iterable_value_type<source_t> {});
443}
444
445template<xtd::iterable source_t>
447 return as_enumerable(source);
448}
449
450template<xtd::iterable source_t>
452 return as_enumerable(source);
453}
454
455template<typename value_t>
456auto xtd::linq::enumerable::from(std::initializer_list<value_t> source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
457 return as_enumerable(source);
458}
459
460template<std::forward_iterator iterator_t>
461auto xtd::linq::enumerable::from(iterator_t first, iterator_t last) noexcept -> xtd::collections::generic::enumerable_generator<typename std::decay<decltype(*first)>::type> {
462 return as_enumerable(first, last);
463}
464
465template<std::forward_iterator iterator_t>
466auto xtd::linq::enumerable::from(iterator_t iterator, xtd::usize length) noexcept -> xtd::collections::generic::enumerable_generator<typename std::decay<decltype(*iterator)>::type> {
467 return as_enumerable(iterator, length);
468}
469
470template<typename value_t, xtd::usize length>
471auto xtd::linq::enumerable::from(const value_t (&array)[length]) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
472 return as_enumerable(array);
473}
474
475template<typename value_t, xtd::usize length>
477 return as_enumerable(array);
478}
479
480template<typename value_t, typename container_t>
481auto xtd::linq::enumerable::from(const std::queue<value_t, container_t>& source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
482 return as_enumerable(source);
483}
484
485template<typename value_t, typename container_t>
486auto xtd::linq::enumerable::from(std::queue<value_t, container_t>& source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
487 return as_enumerable(source);
488}
489
490template<typename value_t, typename container_t>
491auto xtd::linq::enumerable::from(const std::priority_queue<value_t, container_t>& source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
492 return as_enumerable(source);
493}
494
495template<typename value_t, typename container_t>
496auto xtd::linq::enumerable::from(std::priority_queue<value_t, container_t>& source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
497 return as_enumerable(source);
498}
499
500template<typename value_t, typename container_t>
501auto xtd::linq::enumerable::from(const std::stack<value_t, container_t>& source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
502 return as_enumerable(source);
503}
504
505template<typename value_t, typename container_t>
506auto xtd::linq::enumerable::from(std::stack<value_t, container_t>& source) noexcept -> xtd::collections::generic::enumerable_generator<value_t> {
507 return as_enumerable(source);
508}
509
510template<xtd::iterable source_t>
512 auto reversed = std::vector<xtd::iterable_value_type<source_t>>(source.begin(), source.end());
513 std::reverse(reversed.begin(), reversed.end());
514 for (const auto& item : reversed)
515 return item;
517}
518
519template<xtd::iterable source_t, xtd::func_callable<bool, xtd::iterable_value_type<source_t>> predicate_t>
520auto xtd::linq::enumerable::last(source_t&& source, predicate_t&& predicate) -> xtd::iterable_value_type<source_t> {
521 auto reversed = std::vector(source.begin(), source.end());
522 std::reverse(reversed.begin(), reversed.end());
523 for (const auto& item : reversed)
524 if (predicate(item)) return item;
526}
527
528template<xtd::iterable source_t>
532 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
533 //for (const auto& item : source_holder.get())
534 for (const auto& item : source)
535 if (!result || item > result) result = item;
536 return result.value_or(xtd::iterable_value_type<source_t> {});
537}
538
539template<xtd::iterable source_t, xtd::callable<xtd::iterable_value_type<source_t>, xtd::iterable_value_type<source_t>> selector_t>
541auto xtd::linq::enumerable::max(source_t&& source, selector_t&& selector) -> xtd::iterable_value_type<source_t> {
543 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
544 //for (const auto& item : source_holder.get())
545 for (const auto& item : source) {
546 auto val = selector(item);
547 if (!result || val > result) result = val;
548 }
549 return result.value_or(xtd::iterable_value_type<source_t> {});
550}
551
552template<typename result_t, xtd::iterable source_t, xtd::callable<result_t, xtd::iterable_value_type<source_t>> selector_t>
554auto xtd::linq::enumerable::max(source_t&& source, selector_t&& selector) -> result_t {
555 auto result = xtd::optional<result_t> {};
556 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
557 //for (const auto& item : source_holder.get())
558 for (const auto& item : source) {
559 auto val = selector(item);
560 if (!result || val > result) result = val;
561 }
562 return result.value_or(result_t {});
563}
564
565template<xtd::iterable source_t>
569 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
570 //for (const auto& item : source_holder.get())
571 for (const auto& item : source)
572 if (!result || item < result) result = item;
573 return result.value_or(xtd::iterable_value_type<source_t> {});
574}
575
576template<xtd::iterable source_t, xtd::callable<xtd::iterable_value_type<source_t>, xtd::iterable_value_type<source_t>> selector_t>
578auto xtd::linq::enumerable::min(source_t&& source, selector_t&& selector) -> xtd::iterable_value_type<source_t> {
580 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
581 //for (const auto& item : source_holder.get())
582 for (const auto& item : source) {
583 auto val = selector(item);
584 if (!result || val < result) result = val;
585 }
586 return result.value_or(xtd::iterable_value_type<source_t> {});
587}
588
589template<typename result_t, xtd::iterable source_t, xtd::callable<result_t, xtd::iterable_value_type<source_t>> selector_t>
591auto xtd::linq::enumerable::min(source_t&& source, selector_t&& selector) -> result_t {
592 auto result = xtd::optional<result_t> {};
593 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
594 //for (const auto& item : source_holder.get())
595 for (const auto& item : source) {
596 auto val = selector(item);
597 if (!result || val < result) result = val;
598 }
599 return result.value_or(result_t {});
600}
601
602template<xtd::iterable source_t>
604 //return order(source, xtd::collections::generic::comparer<xtd::iterable_value_type<source_t>>::default_comparer);
606}
607
608template<xtd::iterable source_t>
611}
612
613template<xtd::integer integer_t>
615 auto step = integer_t {};
616 return range(integer_t {}, count, ++step);
617}
618
619template<xtd::integer integer_t>
621 auto step = integer_t {};
622 return range(start, count, ++step);
623}
624
625template<xtd::integer integer_t>
626auto xtd::linq::enumerable::range(integer_t start, integer_t count, integer_t step) -> xtd::collections::generic::enumerable_generator<integer_t> {
629
630 for (auto index = integer_t {}; index < count; ++index)
631 co_yield start + (index * step);
632}
633
634template<typename element_t>
636 for (auto index = xtd::usize {}; index < count; ++index)
637 co_yield element;
638}
639
640template<xtd::iterable source_t>
642 auto reversed = std::vector<xtd::iterable_value_type<source_t>>(source.begin(), source.end());
643 std::reverse(reversed.begin(), reversed.end());
644 for (const auto& item : reversed)
645 co_yield item;
646}
647
648template<xtd::iterable source_t>
650//auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
651 //for (const auto& item : source_holder.get())
652 for (const auto& item : source)
653 co_yield selector(item);
654}
655
656/*
657// WARNING : Comment select with index because is ambigus with xtd::expression.
658template<xtd::iterable source_t>
659auto xtd::linq::enumerable::select(source_t&& source, auto&& selector) -> xtd::collections::generic::enumerable_generator<xtd::raw_type<decltype(selector(xtd::iterable_value_type<source_t> {}, xtd::usize {}))>> {
660 auto index = xtd::usize {};
661 //auto source_holder = enumerable_holder<source_t> {std::forward<source_t>(source)};
662 //for (const auto& item : source_holder.get())
663 for (const auto& item : source)
664 co_yield selector(item, index++);
665}*/
666
667template<xtd::iterable first_t, xtd::iterable second_t>
668auto xtd::linq::enumerable::sequence_equal(first_t&& first, second_t&& second) -> bool {
669 return sequence_equal(first, second, [](auto&& f, auto&& s) {return f == s;});
670}
671
672template<xtd::iterable first_t, xtd::iterable second_t>
673auto xtd::linq::enumerable::sequence_equal(first_t&& first, second_t&& second, const iequality_comparer<xtd::iterable_value_type<first_t>>& comparer) -> bool {
674 return sequence_equal(first, second, comparer.equals);
675}
676
677template<xtd::iterable first_t, xtd::iterable second_t, xtd::func_callable<bool, xtd::iterable_value_type<first_t>, xtd::iterable_value_type<second_t>> equality_comparer_t>
678auto xtd::linq::enumerable::sequence_equal(first_t&& first, second_t&& second, equality_comparer_t&& comparer) -> bool {
679 // if second is an xtd collection and second is shortest than first an exception will be thrown.
680 // if second is not a xtd collection, we need to check the size of second. By checling first if `auto size() const -> xtd::usize` is a member of second.
681 try {
682 for (auto index = xtd::usize {}; const auto& item : second) {
683 if (!comparer(item, *(first.begin() + index))) return false;
684 ++index;
685 }
686 return true;
687 } catch(...) {
688 return false;
689 }
690}
691
692template<xtd::iterable source_t>
694 auto index = xtd::usize {0};
695 //auto source_holder = enumerable_holder<xtd::raw_type<source_t>> {std::forward<source_t>(source)};
696 //for (const auto& item : source_holder.get())
697 for (const auto& item : source) {
698 if (index++ < count) continue;
699 co_yield item;
700 }
701}
702
703template<xtd::iterable source_t>
705 bool skip = true;
706 auto index = xtd::usize {0};
707 //auto source_holder = enumerable_holder<xtd::raw_type<source_t>> {std::forward<source_t>(source)};
708 //for (const auto& item : source_holder.get())
709 for (const auto& item : source) {
710 if (skip && !invoke_predicate_with_optional_index(predicate, item, index++)) skip = false;
711 if (!skip) co_yield item;
712 }
713}
714
715template<xtd::iterable source_t>
717 auto index = xtd::usize {0};
718 //auto source_holder = enumerable_holder<xtd::raw_type<source_t>> {std::forward<source_t>(source)};
719 //for (const auto& item : source_holder.get())
720 for (const auto& item : source) {
721 if (index++ == count) break;
722 co_yield item;
723 }
724}
725
726template<xtd::iterable source_t>
728 auto index = xtd::usize {0};
729 //auto source_holder = enumerable_holder<xtd::raw_type<source_t>> {std::forward<source_t>(source)};
730 //for (const auto& item : source_holder.get())
731 for (const auto& item : source) {
732 if (!invoke_predicate_with_optional_index(predicate, item, index++)) break;
733 co_yield item;
734 }
735}
736
737template<xtd::iterable source_t>
739 auto index = xtd::usize {0};
740 //auto source_holder = enumerable_holder<xtd::raw_type<source_t>> {std::forward<source_t>(source)};
741 //for (const auto& item : source_holder.get())
742 for (const auto& item : source)
743 if (invoke_predicate_with_optional_index(predicate, item, index++)) co_yield item;
744}
745
746template<xtd::iterable first_t, xtd::iterable second_t>
748 return zip(std::forward<first_t>(first), std::forward<second_t>(second), [](const auto& first, const auto& second) {return std::make_tuple(first, second);});
749}
750template<xtd::iterable first_t, xtd::iterable second_t>
752 auto index = xtd::usize {};
753 //auto source_holder = enumerable_holder<xtd::raw_type<source_t>> {std::forward<source_t>(source)};
754 //for (const auto& item : source_holder.get())
755 for (const auto& item : first) {
756 co_yield selector(item, *(second.begin() + index));
757 ++index;
758 }
759}
760template<xtd::iterable first_t, xtd::iterable second_t, xtd::iterable third_t>
762 return zip(std::forward<first_t>(first), std::forward<second_t>(second), std::forward<third_t>(third), [](const auto& first, const auto& second, const auto& third) {return std::make_tuple(first, second, third);});
763}
764template<xtd::iterable first_t, xtd::iterable second_t, xtd::iterable third_t>
766 auto index = xtd::usize {};
767 //auto source_holder = enumerable_holder<xtd::raw_type<source_t>> {std::forward<source_t>(source)};
768 //for (const auto& item : source_holder.get())
769 for (const auto& item : first) {
770 co_yield selector(item, *(second.begin() + index), *(third.begin() + index));
771 ++index;
772 }
773}
774
775template<typename predicate_t, typename value_t>
776constexpr auto xtd::linq::enumerable::invoke_predicate_with_optional_index(predicate_t&& predicate, value_t&& value, xtd::usize index) -> bool {
777 if constexpr (xtd::func_callable<predicate_t, bool, xtd::raw_type<value_t>, xtd::usize>) return predicate(std::forward<value_t>(value), index);
778 else if constexpr (xtd::predicate_callable<predicate_t, xtd::raw_type<value_t>>) return predicate(std::forward<value_t>(value));
779 else static_assert(always_false_v<predicate_t>, "Predicate must accept either (value) or (value, index).");
780}
781
782template<typename result_t, typename selector_t, typename value_t>
783auto xtd::linq::enumerable::invoke_selector_with_optional_index(selector_t&& selector, value_t&& value, xtd::usize index) -> result_t {
784 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);
785 if constexpr (xtd::callable<selector_t, xtd::raw_type<result_t>, xtd::raw_type<value_t>>) return selector(std::forward<value_t>(value));
786 else static_assert(always_false_v<selector_t>, "Selector must accept either (value) or (value, index).");
787}
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:45
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 last(source_t &&source) -> xtd::iterable_value_type< source_t >
Returns the last element of a sequence.
static auto sequence_equal(first_t &&first, second_t &&second) -> bool
Determines whether two sequences are equal by comparing the elements by using the default equality co...
static auto zip(first_t &&first, second_t &&second) -> xtd::collections::generic::enumerable_generator< std::tuple< xtd::iterable_value_type< first_t >, xtd::iterable_value_type< second_t > > >
Produces a sequence of tuples with elements from the two specified sequences.
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 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 repeat(const element_t &element, xtd::usize count) -> xtd::collections::generic::enumerable_generator< element_t >
Generates a sequence that contains one repeated value.
static auto first(source_t &&source) -> xtd::iterable_value_type< source_t >
Returns the first element of a 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 reverse(source_t &&source) -> xtd::collections::generic::enumerable_generator< xtd::iterable_value_type< source_t > >
Inverts the order of the elements in a sequence.
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 select(source_t &&source, auto &&selector) -> xtd::collections::generic::enumerable_generator< xtd::raw_type< decltype(selector(xtd::iterable_value_type< source_t > {}))> >
Projects each element of a sequence into a new form.
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
@ s
The S key.
Definition console_key.hpp:124
@ f
The F key.
Definition console_key.hpp:98
@ 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
auto first() const -> read_only_span< type_t, count >
Obtains a subspan consisting of the first count elements of the sequence.
Definition read_only_span.hpp:245
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:286
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