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
Xavier Thompson
typon-concurrency
Commits
960389fb
Commit
960389fb
authored
Mar 14, 2023
by
Tom Niget
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add basic support for generators (co_yield)
parent
c230e37d
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
155 additions
and
0 deletions
+155
-0
rt/include/typon/generator.hpp
rt/include/typon/generator.hpp
+155
-0
No files found.
rt/include/typon/generator.hpp
0 → 100644
View file @
960389fb
//
// Created by Tom on 13/03/2023.
//
#ifndef TYPON_GENERATOR_HPP
#define TYPON_GENERATOR_HPP
#include <coroutine>
namespace
typon
{
/**
* https://github.com/feabhas/coroutines-blog
*/
template
<
typename
T
>
class
Generator
{
class
Promise
{
public:
using
value_type
=
std
::
optional
<
T
>
;
Promise
()
=
default
;
std
::
suspend_always
initial_suspend
()
{
return
{};
}
std
::
suspend_always
final_suspend
()
noexcept
{
return
{};
}
void
unhandled_exception
()
{
std
::
rethrow_exception
(
std
::
move
(
std
::
current_exception
()));
}
std
::
suspend_always
yield_value
(
T
value
)
{
this
->
value
=
std
::
move
(
value
);
return
{};
}
// void return_value(T value) {
// this->value = std::move(value);
// }
void
return_void
()
{
this
->
value
=
std
::
nullopt
;
}
inline
Generator
get_return_object
();
value_type
get_value
()
{
return
std
::
move
(
value
);
}
bool
finished
()
{
return
!
value
.
has_value
();
}
private:
value_type
value
{};
};
public:
using
value_type
=
T
;
using
promise_type
=
Promise
;
explicit
Generator
(
std
::
coroutine_handle
<
Promise
>
handle
)
:
handle
(
handle
)
{}
~
Generator
()
{
if
(
handle
)
{
handle
.
destroy
();
}
}
Promise
::
value_type
next
()
{
if
(
handle
)
{
handle
.
resume
();
return
handle
.
promise
().
get_value
();
}
else
{
return
{};
}
}
struct
end_iterator
{};
class
iterator
{
public:
using
value_type
=
Promise
::
value_type
;
using
difference_type
=
std
::
ptrdiff_t
;
using
iterator_category
=
std
::
input_iterator_tag
;
iterator
()
=
default
;
iterator
(
Generator
&
generator
)
:
generator
{
&
generator
}
{}
value_type
operator
*
()
const
{
if
(
generator
)
{
return
generator
->
handle
.
promise
().
get_value
();
}
return
{};
}
value_type
operator
->
()
const
{
if
(
generator
)
{
return
generator
->
handle
.
promise
().
get_value
();
}
return
{};
}
iterator
&
operator
++
()
{
if
(
generator
&&
generator
->
handle
)
{
generator
->
handle
.
resume
();
}
return
*
this
;
}
iterator
&
operator
++
(
int
)
{
if
(
generator
&&
generator
->
handle
)
{
generator
->
handle
.
resume
();
}
return
*
this
;
}
bool
operator
==
(
const
end_iterator
&
)
const
{
return
generator
?
generator
->
handle
.
promise
().
finished
()
:
true
;
}
private:
Generator
*
generator
{};
};
iterator
begin
()
{
iterator
it
{
*
this
};
return
++
it
;
}
end_iterator
end
()
{
return
end_sentinel
;
}
std
::
optional
<
value_type
>
py_next
()
{
return
*
begin
();
}
private:
end_iterator
end_sentinel
{};
std
::
coroutine_handle
<
Promise
>
handle
;
};
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