Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
T
typon-concurrency
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
typon
typon-concurrency
Commits
f7900b6b
Commit
f7900b6b
authored
Apr 02, 2023
by
Tom Niget
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Generator core update
parent
5f506528
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
53 additions
and
34 deletions
+53
-34
rt/include/typon/generator.hpp
rt/include/typon/generator.hpp
+53
-34
No files found.
rt/include/typon/generator.hpp
View file @
f7900b6b
...
...
@@ -13,11 +13,44 @@ namespace typon {
* https://github.com/feabhas/coroutines-blog
*/
template
<
typename
T
>
class
Generator
{
class
Promise
{
public:
using
value_type
=
T
;
class
promise_type
;
explicit
Generator
(
std
::
coroutine_handle
<
promise_type
>
coroutine
)
noexcept
:
_coroutine
(
coroutine
)
{}
Generator
(
const
Generator
&
)
=
delete
;
Generator
&
operator
=
(
const
Generator
&
)
=
delete
;
Generator
(
Generator
&&
other
)
noexcept
:
_coroutine
(
std
::
exchange
(
other
.
_coroutine
,
nullptr
))
{}
Generator
&
operator
=
(
Generator
other
)
{
std
::
swap
(
_coroutine
,
other
.
_coroutine
);
return
*
this
;
}
~
Generator
()
{
if
(
_coroutine
)
{
_coroutine
.
destroy
();
}
}
Task
<
Generator
>
async_self
()
{
co_return
std
::
move
(
*
this
);
}
auto
operator
co_await
()
&&
noexcept
{
return
std
::
move
(
async_self
().
operator
co_await
());
}
class
promise_type
{
public:
using
value_type
=
std
::
optional
<
T
>
;
Promis
e
()
=
default
;
promise_typ
e
()
=
default
;
std
::
suspend_always
initial_suspend
()
{
return
{};
}
std
::
suspend_always
final_suspend
()
noexcept
{
final
=
true
;
...
...
@@ -38,7 +71,10 @@ template <typename T> class Generator {
void
return_void
()
{
this
->
value
=
std
::
nullopt
;
}
inline
Generator
get_return_object
();
inline
Generator
<
T
>
get_return_object
()
noexcept
{
return
Generator
{
std
::
coroutine_handle
<
promise_type
>::
from_promise
(
*
this
)};
}
value_type
get_value
()
{
return
std
::
move
(
value
);
}
...
...
@@ -52,24 +88,12 @@ template <typename T> class Generator {
bool
final
=
false
;
};
public:
using
value_type
=
T
;
using
promise_type
=
Promise
;
explicit
Generator
(
std
::
coroutine_handle
<
Promise
>
handle
)
:
handle
(
handle
)
{}
~
Generator
()
{
if
(
handle
)
{
handle
.
destroy
();
}
promise_type
::
value_type
next
()
{
if
(
_coroutine
)
{
if
(
!
_coroutine
.
promise
().
finished
())
{
_coroutine
.
resume
();
}
Promise
::
value_type
next
()
{
if
(
handle
)
{
if
(
!
handle
.
promise
().
finished
())
{
handle
.
resume
();
}
return
handle
.
promise
().
get_value
();
return
_coroutine
.
promise
().
get_value
();
}
else
{
return
{};
}
...
...
@@ -79,7 +103,7 @@ public:
class
iterator
{
public:
using
value_type
=
Promis
e
::
value_type
;
using
value_type
=
promise_typ
e
::
value_type
;
using
difference_type
=
std
::
ptrdiff_t
;
using
iterator_category
=
std
::
input_iterator_tag
;
...
...
@@ -88,34 +112,34 @@ public:
value_type
operator
*
()
const
{
if
(
generator
)
{
return
generator
->
handl
e
.
promise
().
get_value
();
return
generator
->
_coroutin
e
.
promise
().
get_value
();
}
return
{};
}
value_type
operator
->
()
const
{
if
(
generator
)
{
return
generator
->
handl
e
.
promise
().
get_value
();
return
generator
->
_coroutin
e
.
promise
().
get_value
();
}
return
{};
}
iterator
&
operator
++
()
{
if
(
generator
&&
generator
->
handl
e
)
{
generator
->
handl
e
.
resume
();
if
(
generator
&&
generator
->
_coroutin
e
)
{
generator
->
_coroutin
e
.
resume
();
}
return
*
this
;
}
iterator
&
operator
++
(
int
)
{
if
(
generator
&&
generator
->
handl
e
)
{
generator
->
handl
e
.
resume
();
if
(
generator
&&
generator
->
_coroutin
e
)
{
generator
->
_coroutin
e
.
resume
();
}
return
*
this
;
}
bool
operator
==
(
const
end_iterator
&
)
const
{
return
generator
?
generator
->
handle
.
promise
().
finished
()
:
true
;
return
!
generator
||
generator
->
_coroutine
.
promise
().
finished
()
;
}
private:
...
...
@@ -133,14 +157,9 @@ public:
private:
end_iterator
end_sentinel
{};
std
::
coroutine_handle
<
Promise
>
handl
e
;
std
::
coroutine_handle
<
promise_type
>
_coroutin
e
;
};
template
<
typename
T
>
inline
Generator
<
T
>
Generator
<
T
>::
Promise
::
get_return_object
()
{
return
Generator
{
std
::
coroutine_handle
<
Promise
>::
from_promise
(
*
this
)};
}
}
// namespace typon
#endif // TYPON_GENERATOR_HPP
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment