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
c330ac55
Commit
c330ac55
authored
May 05, 2022
by
Xavier Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor future.hpp
parent
153bf460
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
66 additions
and
108 deletions
+66
-108
rt/include/typon/future.hpp
rt/include/typon/future.hpp
+66
-108
No files found.
rt/include/typon/future.hpp
View file @
c330ac55
...
@@ -6,115 +6,17 @@
...
@@ -6,115 +6,17 @@
#include <type_traits>
#include <type_traits>
#include <utility>
#include <utility>
#include <typon/fundamental/meta.hpp>
#include <typon/fundamental/scope.hpp>
#include <typon/result.hpp>
#include <typon/result.hpp>
namespace
typon
::
rt
namespace
typon
::
rt
{
{
template
<
typename
Promise
>
using
value_type
=
typename
Promise
::
value_type
;
template
<
typename
P
>
concept
Void
=
std
::
is_void_v
<
value_type
<
P
>>
;
template
<
typename
P
>
concept
Reference
=
std
::
is_reference_v
<
value_type
<
P
>>
;
template
<
typename
P
>
concept
Complete
=
!
Void
<
P
>
&&
!
Reference
<
P
>
;
template
<
typename
P
>
concept
Small
=
sizeof
(
value_type
<
P
>
)
<=
2
*
sizeof
(
void
*
);
template
<
typename
P
>
concept
TriviallyCopyable
=
std
::
is_trivially_copyable_v
<
value_type
<
P
>>
;
struct
CoroutineGuard
{
std
::
coroutine_handle
<>
_coroutine
;
~
CoroutineGuard
()
{
_coroutine
.
destroy
();
}
};
template
<
typename
Promise
>
template
<
typename
Promise
>
struct
Future
struct
Future
{
template
<
typename
T
>
struct
always_false
{
static
constexpr
bool
value
{
false
};
};
static_assert
(
always_false
<
Promise
>::
value
,
"Unexpected Promise type for Future"
);
};
template
<
typename
Promise
>
requires
Complete
<
Promise
>
&&
(
!
Small
<
Promise
>
)
struct
Future
<
Promise
>
{
std
::
coroutine_handle
<
Promise
>
_coroutine
;
bool
_owning
;
Future
(
std
::
coroutine_handle
<
Promise
>
coroutine
,
bool
ready
)
{
_coroutine
=
coroutine
;
_owning
=
ready
;
if
(
ready
)
{
if
(
coroutine
.
promise
().
_exception
)
{
std
::
rethrow_exception
(
coroutine
.
promise
().
_exception
);
}
}
}
Future
(
const
Future
&
)
=
delete
;
Future
&
operator
=
(
const
Future
&
)
=
delete
;
Future
(
Future
&&
other
)
noexcept
:
_coroutine
(
other
.
_coroutine
)
,
_owning
(
std
::
exchange
(
other
.
_owning
,
false
))
{}
Future
&
operator
=
(
Future
&&
other
)
noexcept
{
std
::
swap
(
_owning
,
other
.
_owning
);
std
::
swap
(
_coroutine
,
other
.
_coroutine
);
return
*
this
;
}
~
Future
()
{
if
(
_owning
)
{
_coroutine
.
destroy
();
}
}
auto
get
()
{
return
_coroutine
.
promise
().
get
();
}
};
template
<
typename
Promise
>
requires
Complete
<
Promise
>
&&
Small
<
Promise
>
&&
(
!
TriviallyCopyable
<
Promise
>
)
struct
Future
<
Promise
>
{
{
using
value_type
=
typename
Promise
::
value_type
;
using
value_type
=
typename
Promise
::
value_type
;
...
@@ -128,7 +30,7 @@ namespace typon::rt
...
@@ -128,7 +30,7 @@ namespace typon::rt
{
{
if
(
ready
)
if
(
ready
)
{
{
CoroutineGuard
guard
{
coroutine
};
fdt
::
defer
defer
{
[
&
coroutine
]()
{
coroutine
.
destroy
();
}
};
std
::
construct_at
(
&
(
_result
),
coroutine
.
promise
().
get
());
std
::
construct_at
(
&
(
_result
),
coroutine
.
promise
().
get
());
}
}
else
else
...
@@ -182,7 +84,58 @@ namespace typon::rt
...
@@ -182,7 +84,58 @@ namespace typon::rt
template
<
typename
Promise
>
template
<
typename
Promise
>
requires
Complete
<
Promise
>
&&
Small
<
Promise
>
&&
TriviallyCopyable
<
Promise
>
requires
requires
{
sizeof
(
typename
Promise
::
value_type
);
}
&&
(
sizeof
(
typename
Promise
::
value_type
)
>
2
*
sizeof
(
void
*
))
struct
Future
<
Promise
>
{
std
::
coroutine_handle
<
Promise
>
_coroutine
;
bool
_owning
;
Future
(
std
::
coroutine_handle
<
Promise
>
coroutine
,
bool
ready
)
{
_coroutine
=
coroutine
;
_owning
=
ready
;
if
(
ready
)
{
if
(
coroutine
.
promise
().
_exception
)
{
std
::
rethrow_exception
(
coroutine
.
promise
().
_exception
);
}
}
}
Future
(
const
Future
&
)
=
delete
;
Future
&
operator
=
(
const
Future
&
)
=
delete
;
Future
(
Future
&&
other
)
noexcept
:
_coroutine
(
other
.
_coroutine
)
,
_owning
(
std
::
exchange
(
other
.
_owning
,
false
))
{}
Future
&
operator
=
(
Future
&&
other
)
noexcept
{
std
::
swap
(
_owning
,
other
.
_owning
);
std
::
swap
(
_coroutine
,
other
.
_coroutine
);
return
*
this
;
}
~
Future
()
{
if
(
_owning
)
{
_coroutine
.
destroy
();
}
}
auto
get
()
{
return
_coroutine
.
promise
().
get
();
}
};
template
<
typename
Promise
>
requires
std
::
is_trivially_copyable_v
<
typename
Promise
::
value_type
>
struct
Future
<
Promise
>
struct
Future
<
Promise
>
{
{
using
value_type
=
typename
Promise
::
value_type
;
using
value_type
=
typename
Promise
::
value_type
;
...
@@ -197,7 +150,7 @@ namespace typon::rt
...
@@ -197,7 +150,7 @@ namespace typon::rt
{
{
if
(
ready
)
if
(
ready
)
{
{
CoroutineGuard
guard
{
coroutine
};
fdt
::
defer
defer
{
[
&
coroutine
]()
{
coroutine
.
destroy
();
}
};
std
::
construct_at
(
&
(
_result
),
coroutine
.
promise
().
get
());
std
::
construct_at
(
&
(
_result
),
coroutine
.
promise
().
get
());
}
}
else
else
...
@@ -206,6 +159,9 @@ namespace typon::rt
...
@@ -206,6 +159,9 @@ namespace typon::rt
}
}
}
}
Future
(
Future
&&
other
)
=
default
;
Future
&
operator
=
(
Future
&&
other
)
=
default
;
~
Future
()
~
Future
()
{
{
if
(
!
_coroutine
)
if
(
!
_coroutine
)
...
@@ -225,7 +181,8 @@ namespace typon::rt
...
@@ -225,7 +181,8 @@ namespace typon::rt
};
};
template
<
Reference
Promise
>
template
<
typename
Promise
>
requires
std
::
is_reference_v
<
typename
Promise
::
value_type
>
struct
Future
<
Promise
>
struct
Future
<
Promise
>
{
{
using
value_type
=
typename
Promise
::
value_type
;
using
value_type
=
typename
Promise
::
value_type
;
...
@@ -237,7 +194,7 @@ namespace typon::rt
...
@@ -237,7 +194,7 @@ namespace typon::rt
{
{
if
(
ready
)
if
(
ready
)
{
{
CoroutineGuard
guard
{
coroutine
};
fdt
::
defer
defer
{
[
&
coroutine
]()
{
coroutine
.
destroy
();
}
};
_result
=
std
::
addressof
(
coroutine
.
promise
().
get
());
_result
=
std
::
addressof
(
coroutine
.
promise
().
get
());
}
}
else
else
...
@@ -257,7 +214,8 @@ namespace typon::rt
...
@@ -257,7 +214,8 @@ namespace typon::rt
};
};
template
<
Void
Promise
>
template
<
typename
Promise
>
requires
std
::
is_void_v
<
typename
Promise
::
value_type
>
struct
Future
<
Promise
>
struct
Future
<
Promise
>
{
{
using
value_type
=
typename
Promise
::
value_type
;
using
value_type
=
typename
Promise
::
value_type
;
...
@@ -268,7 +226,7 @@ namespace typon::rt
...
@@ -268,7 +226,7 @@ namespace typon::rt
{
{
if
(
ready
)
if
(
ready
)
{
{
CoroutineGuard
guard
{
coroutine
};
fdt
::
defer
defer
{
[
&
coroutine
]()
{
coroutine
.
destroy
();
}
};
coroutine
.
promise
().
get
();
coroutine
.
promise
().
get
();
}
}
else
else
...
...
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