Skip to content

Commit 34eb9a4

Browse files
committed
Add xtd::collections::generic::enumerable_generator (coroutines)
1 parent f8792c4 commit 34eb9a4

File tree

4 files changed

+85
-0
lines changed

4 files changed

+85
-0
lines changed

src/xtd.core/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,8 @@ add_sources(
669669
"include/xtd/collections/generic/dictionary"
670670
"include/xtd/collections/generic/empty_comparer.hpp"
671671
"include/xtd/collections/generic/empty_comparer"
672+
"include/xtd/collections/generic/enumerable_generator.hpp"
673+
"include/xtd/collections/generic/enumerable_generator"
672674
"include/xtd/collections/generic/enumerator.hpp"
673675
"include/xtd/collections/generic/enumerator"
674676
"include/xtd/collections/generic/equality_comparer.hpp"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#pragma once
2+
#include <xtd/collections/generic/generator.hpp>
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/// @file
2+
/// @brief Contains xtd::collections::generic::enumerable_generator <> class.
3+
/// @copyright Copyright (c) 2026 Gammasoft. All rights reserved.
4+
#pragma once
5+
#include "ienumerable.hpp"
6+
#include "ienumerator.hpp"
7+
#include "../../helpers/throw_helper.hpp"
8+
#include <coroutine>
9+
#include <exception>
10+
11+
/// @brief The xtd namespace contains all fundamental classes to access Hardware, Os, System, and more.
12+
namespace xtd {
13+
/// @brief The xtd::collections namespace contains interfaces and classes that define various collections of objects, such as lists, queues, bit arrays, hash tables and dictionaries.
14+
namespace collections {
15+
/// @brief The xtd::collections::generic namespace contains interfaces and classes that define generic collections, which allow users to create strongly typed collections that provide better type safety and performance than non-generic strongly typed collections.
16+
namespace generic {
17+
/// @brief Represents an enumerable enumerable_generator.
18+
/// @par Namespace
19+
/// xtd::collections::generic
20+
/// @par Library
21+
/// xtd.core
22+
/// @ingroup xtd_core generic_collections
23+
template<typename type_t>
24+
class enumerable_generator : public xtd::collections::generic::ienumerable<type_t> {
25+
public:
26+
struct promise_type {
27+
type_t current_value;
28+
29+
enumerable_generator get_return_object() {return enumerable_generator {std::coroutine_handle<promise_type>::from_promise(*this)};}
30+
31+
std::suspend_always initial_suspend() noexcept {return {};}
32+
std::suspend_always final_suspend() noexcept {return {};}
33+
void return_void() noexcept {}
34+
void unhandled_exception() {std::terminate();}
35+
36+
std::suspend_always yield_value(type_t value) noexcept {
37+
current_value = std::move(value);
38+
return {};
39+
}
40+
std::suspend_always yield_value(type_t&& value) noexcept {
41+
current_value = std::move(std::forward<type_t>(value));
42+
return {};
43+
}
44+
};
45+
46+
enumerable_generator(const enumerable_generator& other) = delete;
47+
enumerable_generator& operator =(const enumerable_generator& other) = delete;
48+
enumerable_generator(enumerable_generator&& other) noexcept : handle_(std::exchange(other.handle_, {})) {}
49+
enumerable_generator& operator =(enumerable_generator&& other) noexcept {
50+
handle_ = std::exchange(other.handle_, {});
51+
return *this;
52+
}
53+
~enumerable_generator() override {if (handle_) handle_.destroy();}
54+
55+
xtd::collections::generic::enumerator<type_t> get_enumerator() const override {
56+
struct generator_enumerator final : xtd::collections::generic::ienumerator<type_t> {
57+
explicit generator_enumerator(std::coroutine_handle<promise_type> handle) : handle_(handle) {}
58+
const type_t& current() const override {return handle_.promise().current_value;}
59+
bool move_next() override {
60+
if (!handle_ || handle_.done()) return false;
61+
handle_.resume();
62+
return !handle_.done();
63+
}
64+
void reset() override {xtd::helpers::throw_helper::throws(xtd::helpers::exception_case::not_supported);}
65+
66+
private:
67+
std::coroutine_handle<promise_type> handle_;
68+
};
69+
70+
return {new_ptr<generator_enumerator>(handle_)};
71+
}
72+
73+
private:
74+
explicit enumerable_generator(std::coroutine_handle<promise_type> handle) : handle_(handle) {}
75+
76+
mutable std::coroutine_handle<promise_type> handle_;
77+
};
78+
}
79+
}
80+
}

src/xtd.core/include/xtd/xtd.core.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "collections/generic/comparer.hpp"
3535
#include "collections/generic/dictionary.hpp"
3636
#include "collections/generic/empty_comparer.hpp"
37+
#include "collections/generic/enumerable_generator.hpp"
3738
#include "collections/generic/enumerator.hpp"
3839
#include "collections/generic/equality_comparer.hpp"
3940
#include "collections/generic/hash_set.hpp"

0 commit comments

Comments
 (0)