Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
pistache
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
Libraries
pistache
Commits
fc806ccc
Commit
fc806ccc
authored
May 26, 2016
by
octal
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'promise-refactor'
parents
93a1c2fc
254e46f5
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
383 additions
and
222 deletions
+383
-222
include/async.h
include/async.h
+383
-222
No files found.
include/async.h
View file @
fc806ccc
...
@@ -47,19 +47,6 @@ namespace Async {
...
@@ -47,19 +47,6 @@ namespace Async {
virtual
const
char
*
what
()
const
noexcept
{
return
"Bad any cast"
;
}
virtual
const
char
*
what
()
const
noexcept
{
return
"Bad any cast"
;
}
};
};
/*
- Direct: The continuation will be directly called in the context
of the same thread
- Deferred: The continuation will be called in an asynchronous way
Note that Deferred requires the Promise to be bound to an event
loop
*/
enum
class
Continuation
{
Direct
,
Deferred
};
enum
class
State
{
enum
class
State
{
Pending
,
Fulfilled
,
Rejected
Pending
,
Fulfilled
,
Rejected
};
};
...
@@ -131,6 +118,18 @@ namespace Async {
...
@@ -131,6 +118,18 @@ namespace Async {
typedef
T
Type
;
typedef
T
Type
;
};
};
template
<
size_t
N
,
typename
...
T
>
struct
nth_element
;
template
<
typename
Head
,
typename
...
Tail
>
struct
nth_element
<
0
,
Head
,
Tail
...
>
{
typedef
Head
type
;
};
template
<
size_t
N
,
typename
Head
,
typename
...
Tail
>
struct
nth_element
<
N
,
Head
,
Tail
...
>
{
typedef
typename
nth_element
<
N
-
1
,
Tail
...
>::
type
type
;
};
}
}
namespace
Private
{
namespace
Private
{
...
@@ -295,65 +294,106 @@ namespace Async {
...
@@ -295,65 +294,106 @@ namespace Async {
std
::
shared_ptr
<
Core
>
chain_
;
std
::
shared_ptr
<
Core
>
chain_
;
};
};
template
<
typename
T
,
typename
ResolveFunc
,
typename
RejectFunc
>
namespace
impl
{
struct
ThenContinuation
:
public
Continuable
<
T
>
{
ThenContinuation
(
const
std
::
shared_ptr
<
Core
>&
chain
,
ResolveFunc
&&
resolveFunc
,
RejectFunc
&&
rejectFunc
)
:
Continuable
<
T
>
(
chain
)
,
resolveFunc_
(
std
::
forward
<
ResolveFunc
>
(
resolveFunc
))
,
rejectFunc_
(
std
::
forward
<
RejectFunc
>
(
rejectFunc
))
{
}
void
doResolve
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
template
<
typename
T
,
typename
Resolve
,
typename
Reject
,
typename
U
>
struct
Continuation
;
doResolveImpl
(
core
,
std
::
is_void
<
T
>
());
}
void
doReject
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
template
<
typename
T
,
typename
Resolve
,
typename
Reject
,
typename
Res
,
typename
Cls
,
typename
...
Args
>
rejectFunc_
(
core
->
exc
);
struct
Continuation
<
T
,
Resolve
,
Reject
,
Res
(
Cls
::*
)(
Args
...)
const
>
:
public
Continuation
<
T
,
Resolve
,
Reject
,
Res
(
Args
...)
>
{
}
typedef
Continuation
<
T
,
Resolve
,
Reject
,
Res
(
Args
...)
>
Base
;
void
doResolveImpl
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
,
std
::
true_type
/* is_void */
)
{
Continuation
(
resolveFunc_
();
const
std
::
shared_ptr
<
Core
>&
chain
,
}
Resolve
resolve
,
Reject
reject
)
:
Base
(
chain
,
std
::
move
(
resolve
),
std
::
move
(
reject
))
{
}
};
void
doResolveImpl
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
,
std
::
false_type
/* is_void */
)
{
template
<
typename
T
,
typename
Resolve
,
typename
Reject
,
typename
Res
,
typename
Cls
,
typename
...
Args
>
resolveFunc_
(
core
->
value
());
struct
Continuation
<
T
,
Resolve
,
Reject
,
Res
(
Cls
::*
)(
Args
...)
>
:
public
Continuation
<
T
,
Resolve
,
Reject
,
Res
(
Args
...)
>
{
}
typedef
Continuation
<
T
,
Resolve
,
Reject
,
Res
(
Args
...)
>
Base
;
ResolveFunc
resolveFunc_
;
Continuation
(
RejectFunc
rejectFunc_
;
const
std
::
shared_ptr
<
Core
>&
chain
,
Resolve
resolve
,
Reject
reject
)
:
Base
(
chain
,
std
::
move
(
resolve
),
std
::
move
(
reject
))
{
}
};
};
template
<
typename
T
,
typename
ResolveFunc
,
typename
RejectFunc
,
typename
Return
>
// General specialization
struct
ThenReturnContinuation
:
public
Continuable
<
T
>
{
template
<
typename
T
,
typename
Resolve
,
typename
Reject
,
typename
Res
,
typename
...
Args
>
ThenReturnContinuation
(
struct
Continuation
<
T
,
Resolve
,
Reject
,
Res
(
Args
...)
>
:
public
Continuable
<
T
>
{
static_assert
(
sizeof
...(
Args
)
==
1
,
"A continuation should only take one single argument"
);
typedef
typename
detail
::
nth_element
<
0
,
Args
...
>::
type
Arg
;
static_assert
(
std
::
is_same
<
T
,
Arg
>::
value
||
std
::
is_convertible
<
T
,
Arg
>::
value
,
"Incompatible types detected"
);
Continuation
(
const
std
::
shared_ptr
<
Core
>&
chain
,
const
std
::
shared_ptr
<
Core
>&
chain
,
ResolveFunc
&&
resolveFunc
,
RejectFunc
&&
rejectFunc
)
Resolve
resolve
,
Reject
reject
)
:
Continuable
<
T
>
(
chain
)
:
Continuable
<
T
>
(
chain
)
,
resolveFunc_
(
std
::
forward
<
ResolveFunc
>
(
resolveFunc
))
,
resolve_
(
resolve
)
,
rejectFunc_
(
std
::
forward
<
RejectFunc
>
(
rejectFunc
))
,
reject_
(
reject
)
{
{
}
}
void
doResolve
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
void
doResolve
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
doResolveImpl
(
core
,
std
::
is_void
<
T
>
(
));
finishResolve
(
resolve_
(
detail
::
tryMove
<
Resolve
>
(
core
->
value
())
));
}
}
void
doReject
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
void
doReject
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
rejectFunc
_
(
core
->
exc
);
reject
_
(
core
->
exc
);
for
(
const
auto
&
req
:
this
->
chain_
->
requests
)
{
for
(
const
auto
&
req
:
this
->
chain_
->
requests
)
{
req
->
reject
(
this
->
chain_
);
req
->
reject
(
this
->
chain_
);
}
}
}
}
void
doResolveImpl
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
,
std
::
true_type
/* is_void */
)
{
template
<
typename
Ret
>
finishResolve
(
resolveFunc_
());
void
finishResolve
(
Ret
&&
ret
)
const
{
typedef
typename
std
::
decay
<
Ret
>::
type
CleanRet
;
this
->
chain_
->
template
construct
<
CleanRet
>(
std
::
forward
<
Ret
>
(
ret
));
for
(
const
auto
&
req
:
this
->
chain_
->
requests
)
{
req
->
resolve
(
this
->
chain_
);
}
}
}
void
doResolveImpl
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
,
std
::
false_type
/* is_void */
)
{
Resolve
resolve_
;
finishResolve
(
resolveFunc_
(
detail
::
tryMove
<
ResolveFunc
>
(
core
->
value
())));
Reject
reject_
;
};
// Specialization for a void-Promise
template
<
typename
Resolve
,
typename
Reject
,
typename
Res
,
typename
...
Args
>
struct
Continuation
<
void
,
Resolve
,
Reject
,
Res
(
Args
...)
>
:
public
Continuable
<
void
>
{
Continuation
(
const
std
::
shared_ptr
<
Core
>&
chain
,
Resolve
resolve
,
Reject
reject
)
:
Continuable
<
void
>
(
chain
)
,
resolve_
(
resolve
)
,
reject_
(
reject
)
{
}
static_assert
(
sizeof
...(
Args
)
==
0
,
"Can not attach a non-void continuation to a void-Promise"
);
void
doResolve
(
const
std
::
shared_ptr
<
CoreT
<
void
>>&
core
)
{
finishResolve
(
resolve_
());
}
void
doReject
(
const
std
::
shared_ptr
<
CoreT
<
void
>>&
core
)
{
reject_
(
core
->
exc
);
for
(
const
auto
&
req
:
this
->
chain_
->
requests
)
{
req
->
reject
(
this
->
chain_
);
}
}
}
template
<
typename
Ret
>
template
<
typename
Ret
>
...
@@ -365,40 +405,133 @@ namespace Async {
...
@@ -365,40 +405,133 @@ namespace Async {
}
}
}
}
ResolveFunc
resolveFunc
_
;
Resolve
resolve
_
;
RejectFunc
rejectFunc
_
;
Reject
reject
_
;
};
};
template
<
typename
T
,
typename
ResolveFunc
,
typename
RejectFunc
>
// Specialization for a callback returning void
struct
ThenChainContinuation
:
public
Continuable
<
T
>
{
template
<
typename
T
,
typename
Resolve
,
typename
Reject
,
typename
...
Args
>
ThenChainContinuation
(
struct
Continuation
<
T
,
Resolve
,
Reject
,
void
(
Args
...)
>
:
public
Continuable
<
T
>
{
Continuation
(
const
std
::
shared_ptr
<
Core
>&
chain
,
const
std
::
shared_ptr
<
Core
>&
chain
,
ResolveFunc
&&
resolveFunc
,
RejectFunc
&&
rejectFunc
)
Resolve
resolve
,
Reject
reject
)
:
Continuable
<
T
>
(
chain
)
:
Continuable
<
T
>
(
chain
)
,
resolveFunc_
(
std
::
forward
<
ResolveFunc
>
(
resolveFunc
))
,
resolve_
(
resolve
)
,
rejectFunc_
(
std
::
forward
<
RejectFunc
>
(
rejectFunc
))
,
reject_
(
reject
)
{
{
}
static_assert
(
sizeof
...(
Args
)
==
1
,
"A continuation should only take one single argument"
);
typedef
typename
detail
::
nth_element
<
0
,
Args
...
>::
type
Arg
;
static_assert
(
std
::
is_same
<
T
,
Arg
>::
value
||
std
::
is_convertible
<
T
,
Arg
>::
value
,
"Incompatible types detected"
);
void
doResolve
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
resolve_
(
core
->
value
());
}
void
doReject
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
reject_
(
core
->
exc
);
}
Resolve
resolve_
;
Reject
reject_
;
};
// Specialization for a void-Promise on a callback returning void
template
<
typename
Resolve
,
typename
Reject
,
typename
...
Args
>
struct
Continuation
<
void
,
Resolve
,
Reject
,
void
(
Args
...)
>
:
public
Continuable
<
void
>
{
Continuation
(
const
std
::
shared_ptr
<
Core
>&
chain
,
Resolve
resolve
,
Reject
reject
)
:
Continuable
<
void
>
(
chain
)
,
resolve_
(
resolve
)
,
reject_
(
reject
)
{
}
static_assert
(
sizeof
...(
Args
)
==
0
,
"Can not attach a non-void continuation to a void-Promise"
);
void
doResolve
(
const
std
::
shared_ptr
<
CoreT
<
void
>>&
core
)
{
resolve_
();
}
}
void
doReject
(
const
std
::
shared_ptr
<
CoreT
<
void
>>&
core
)
{
reject_
(
core
->
exc
);
}
Resolve
resolve_
;
Reject
reject_
;
};
// Specialization for a callback returning a Promise
template
<
typename
T
,
typename
Resolve
,
typename
Reject
,
typename
U
,
typename
...
Args
>
struct
Continuation
<
T
,
Resolve
,
Reject
,
Promise
<
U
>
(
Args
...)
>
:
public
Continuable
<
T
>
{
static_assert
(
sizeof
...(
Args
)
==
1
,
"A continuation should only take one single argument"
);
typedef
typename
detail
::
nth_element
<
0
,
Args
...
>::
type
Arg
;
static_assert
(
std
::
is_same
<
T
,
Arg
>::
value
||
std
::
is_convertible
<
T
,
Arg
>::
value
,
"Incompatible types detected"
);
Continuation
(
const
std
::
shared_ptr
<
Core
>&
chain
,
Resolve
resolve
,
Reject
reject
)
:
Continuable
<
T
>
(
chain
)
,
resolve_
(
resolve
)
,
reject_
(
reject
)
{
}
void
doResolve
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
void
doResolve
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
doResolveImpl
(
core
,
std
::
is_void
<
T
>
());
auto
promise
=
resolve_
(
detail
::
tryMove
<
Resolve
>
(
core
->
value
()));
finishResolve
(
promise
);
}
}
void
doReject
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
void
doReject
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
rejectFunc
_
(
core
->
exc
);
reject
_
(
core
->
exc
);
for
(
const
auto
&
req
:
core
->
requests
)
{
for
(
const
auto
&
req
:
core
->
requests
)
{
req
->
reject
(
core
);
req
->
reject
(
core
);
}
}
}
}
void
doResolveImpl
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
,
std
::
true_type
/* is_void */
)
{
template
<
typename
PromiseType
>
auto
promise
=
resolveFunc_
();
struct
Chainer
{
finishResolve
(
promise
);
Chainer
(
const
std
::
shared_ptr
<
Private
::
Core
>&
core
)
:
chainCore
(
core
)
{
}
void
operator
()(
const
PromiseType
&
val
)
{
chainCore
->
construct
<
PromiseType
>
(
val
);
for
(
const
auto
&
req
:
chainCore
->
requests
)
{
req
->
resolve
(
chainCore
);
}
}
}
void
doResolveImpl
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
,
std
::
false_type
/* is_void */
)
{
std
::
shared_ptr
<
Core
>
chainCore
;
auto
promise
=
resolveFunc_
(
detail
::
tryMove
<
ResolveFunc
>
(
core
->
value
()));
};
finishResolve
(
promise
);
template
<
typename
Promise
,
typename
Type
=
typename
detail
::
RemovePromise
<
Promise
>
::
Type
>
Chainer
<
Type
>
makeChainer
(
const
Promise
&
)
{
return
Chainer
<
Type
>
(
this
->
chain_
);
}
}
template
<
typename
P
>
template
<
typename
P
>
...
@@ -415,10 +548,40 @@ namespace Async {
...
@@ -415,10 +548,40 @@ namespace Async {
});
});
}
}
ResolveFunc
resolveFunc
_
;
Resolve
resolve
_
;
RejectFunc
rejectFunc
_
;
Reject
reject
_
;
template
<
typename
PromiseType
>
};
// Specialization for a void callback returning a Promise
template
<
typename
Resolve
,
typename
Reject
,
typename
U
,
typename
...
Args
>
struct
Continuation
<
void
,
Resolve
,
Reject
,
Promise
<
U
>
(
Args
...)
>
:
public
Continuable
<
void
>
{
static_assert
(
sizeof
...(
Args
)
==
0
,
"Can not attach a non-void continuation to a void-Promise"
);
Continuation
(
const
std
::
shared_ptr
<
Core
>&
chain
,
Resolve
resolve
,
Reject
reject
)
:
Continuable
<
void
>
(
chain
)
,
resolve_
(
resolve
)
,
reject_
(
reject
)
{
}
void
doResolve
(
const
std
::
shared_ptr
<
CoreT
<
void
>>&
core
)
{
auto
promise
=
resolve_
();
finishResolve
(
promise
);
}
void
doReject
(
const
std
::
shared_ptr
<
CoreT
<
void
>>&
core
)
{
reject_
(
core
->
exc
);
for
(
const
auto
&
req
:
core
->
requests
)
{
req
->
reject
(
core
);
}
}
template
<
typename
PromiseType
,
typename
Dummy
=
void
>
struct
Chainer
{
struct
Chainer
{
Chainer
(
const
std
::
shared_ptr
<
Private
::
Core
>&
core
)
Chainer
(
const
std
::
shared_ptr
<
Private
::
Core
>&
core
)
:
chainCore
(
core
)
:
chainCore
(
core
)
...
@@ -434,6 +597,24 @@ namespace Async {
...
@@ -434,6 +597,24 @@ namespace Async {
std
::
shared_ptr
<
Core
>
chainCore
;
std
::
shared_ptr
<
Core
>
chainCore
;
};
};
template
<
typename
Dummy
>
struct
Chainer
<
void
,
Dummy
>
{
Chainer
(
const
std
::
shared_ptr
<
Private
::
Core
>&
core
)
:
chainCore
(
core
)
{
}
void
operator
()()
{
auto
core
=
this
->
chain_
;
core
->
state
=
State
::
Fulfilled
;
for
(
const
auto
&
req
:
chainCore
->
requests
)
{
req
->
resolve
(
chainCore
);
}
}
std
::
shared_ptr
<
Core
>
chainCore
;
};
template
<
template
<
typename
Promise
,
typename
Promise
,
typename
Type
=
typename
detail
::
RemovePromise
<
Promise
>
::
Type
>
typename
Type
=
typename
detail
::
RemovePromise
<
Promise
>
::
Type
>
...
@@ -442,89 +623,90 @@ namespace Async {
...
@@ -442,89 +623,90 @@ namespace Async {
return
Chainer
<
Type
>
(
this
->
chain_
);
return
Chainer
<
Type
>
(
this
->
chain_
);
}
}
};
template
<
typename
P
>
void
finishResolve
(
P
&
promise
)
{
template
<
typename
T
,
typename
ResolveFunc
>
auto
chainer
=
makeChainer
(
promise
);
struct
ContinuationFactory
:
public
ContinuationFactory
<
T
,
decltype
(
&
ResolveFunc
::
operator
())
>
{
};
promise
.
then
(
std
::
move
(
chainer
),
[
=
](
std
::
exception_ptr
exc
)
{
auto
core
=
this
->
chain_
;
core
->
exc
=
std
::
move
(
exc
);
core
->
state
=
State
::
Rejected
;
/* Const */
for
(
const
auto
&
req
:
core
->
requests
)
{
template
<
typename
T
,
typename
R
,
typename
Class
,
typename
...
Args
>
req
->
reject
(
core
);
struct
ContinuationFactory
<
T
,
R
(
Class
::*
)(
Args
...)
const
>
{
}
template
<
typename
ResolveFunc
,
typename
RejectFunc
>
});
static
Continuable
<
T
>*
create
(
const
std
::
shared_ptr
<
Core
>&
chain
,
ResolveFunc
&&
resolveFunc
,
RejectFunc
&&
rejectFunc
)
{
return
new
ThenReturnContinuation
<
T
,
ResolveFunc
,
RejectFunc
,
R
>
(
chain
,
std
::
forward
<
ResolveFunc
>
(
resolveFunc
),
std
::
forward
<
RejectFunc
>
(
rejectFunc
));
}
}
Resolve
resolve_
;
Reject
reject_
;
};
};
template
<
typename
T
,
typename
Class
,
typename
...
Args
>
}
// namespace impl
struct
ContinuationFactory
<
T
,
void
(
Class
::*
)(
Args
...)
const
>
{
template
<
typename
ResolveFunc
,
typename
RejectFunc
>
template
<
typename
T
,
typename
Resolve
,
typename
Reject
,
typename
Sig
>
static
Continuable
<
T
>*
create
(
struct
Continuation
:
public
impl
::
Continuation
<
T
,
Resolve
,
Reject
,
decltype
(
&
Sig
::
operator
())
>
const
std
::
shared_ptr
<
Private
::
Core
>&
chain
,
{
ResolveFunc
&&
resolveFunc
,
RejectFunc
&&
rejectFunc
)
{
return
new
ThenContinuation
<
T
,
ResolveFunc
,
RejectFunc
>
(
typedef
impl
::
Continuation
<
T
,
Resolve
,
Reject
,
decltype
(
&
Sig
::
operator
())
>
Base
;
chain
,
std
::
forward
<
ResolveFunc
>
(
resolveFunc
),
Continuation
(
std
::
forward
<
RejectFunc
>
(
rejectFunc
));
const
std
::
shared_ptr
<
Core
>&
core
,
}
Resolve
resolve
,
Reject
reject
)
:
Base
(
core
,
std
::
move
(
resolve
),
std
::
move
(
reject
))
{
}
};
};
template
<
typename
T
,
typename
U
,
typename
Clas
s
,
typename
...
Args
>
template
<
typename
T
,
typename
Resolve
,
typename
Reject
,
typename
Re
s
,
typename
...
Args
>
struct
Continuation
Factory
<
T
,
Promise
<
U
>
(
Class
::*
)(
Args
...)
const
>
{
struct
Continuation
<
T
,
Resolve
,
Reject
,
Res
(
*
)(
Args
...)
>
:
public
impl
::
Continuation
<
T
,
Resolve
,
Reject
,
Res
(
Args
...)
>
template
<
typename
ResolveFunc
,
typename
RejectFunc
>
{
static
Continuable
<
T
>*
create
(
typedef
impl
::
Continuation
<
T
,
Resolve
,
Reject
,
Res
(
Args
...)
>
Base
;
const
std
::
shared_ptr
<
Private
::
Core
>&
chain
,
ResolveFunc
&&
resolveFunc
,
RejectFunc
&&
rejectFunc
)
{
Continuation
(
return
new
ThenChainContinuation
<
T
,
ResolveFunc
,
RejectFunc
>
(
const
std
::
shared_ptr
<
Core
>&
core
,
chain
,
Resolve
resolve
,
std
::
forward
<
ResolveFunc
>
(
resolveFunc
),
Reject
reject
)
std
::
forward
<
RejectFunc
>
(
rejectFunc
));
:
Base
(
core
,
std
::
move
(
resolve
),
std
::
move
(
reject
))
}
{
}
};
};
/* Non-const */
template
<
typename
T
,
typename
Resolve
,
typename
Reject
,
typename
Res
,
typename
Cls
,
typename
...
Args
>
template
<
typename
T
,
typename
R
,
typename
Class
,
typename
...
Args
>
struct
Continuation
<
T
,
Resolve
,
Reject
,
Res
(
Cls
::*
)(
Args
...)
>
:
public
impl
::
Continuation
<
T
,
Resolve
,
Reject
,
Res
(
Args
...)
>
struct
ContinuationFactory
<
T
,
R
(
Class
::*
)(
Args
...)
>
{
{
template
<
typename
ResolveFunc
,
typename
RejectFunc
>
typedef
impl
::
Continuation
<
T
,
Resolve
,
Reject
,
Res
(
Args
...)
>
Base
;
static
Continuable
<
T
>*
create
(
const
std
::
shared_ptr
<
Core
>&
chain
,
Continuation
(
ResolveFunc
&&
resolveFunc
,
RejectFunc
&&
rejectFunc
)
{
const
std
::
shared_ptr
<
Core
>&
core
,
return
new
ThenReturnContinuation
<
T
,
ResolveFunc
,
RejectFunc
,
R
>
(
Resolve
resolve
,
chain
,
Reject
reject
)
std
::
forward
<
ResolveFunc
>
(
resolveFunc
),
:
Base
(
core
,
std
::
move
(
resolve
),
std
::
move
(
reject
))
std
::
forward
<
RejectFunc
>
(
rejectFunc
));
{
}
}
};
};
template
<
typename
T
,
typename
Clas
s
,
typename
...
Args
>
template
<
typename
T
,
typename
Resolve
,
typename
Reject
,
typename
Res
,
typename
Cl
s
,
typename
...
Args
>
struct
Continuation
Factory
<
T
,
void
(
Class
::*
)(
Args
...)
>
{
struct
Continuation
<
T
,
Resolve
,
Reject
,
Res
(
Cls
::*
)(
Args
...)
const
>
:
public
impl
::
Continuation
<
T
,
Resolve
,
Reject
,
Res
(
Args
...)
>
template
<
typename
ResolveFunc
,
typename
RejectFunc
>
{
static
Continuable
<
T
>*
create
(
typedef
impl
::
Continuation
<
T
,
Resolve
,
Reject
,
Res
(
Args
...)
>
Base
;
const
std
::
shared_ptr
<
Private
::
Core
>&
chain
,
ResolveFunc
&&
resolveFunc
,
RejectFunc
&&
rejectFunc
)
{
Continuation
(
return
new
ThenContinuation
<
T
,
ResolveFunc
,
RejectFunc
>
(
const
std
::
shared_ptr
<
Core
>&
core
,
chain
,
Resolve
resolve
,
std
::
forward
<
ResolveFunc
>
(
resolveFunc
),
Reject
reject
)
std
::
forward
<
RejectFunc
>
(
rejectFunc
));
:
Base
(
core
,
std
::
move
(
resolve
),
std
::
move
(
reject
))
}
{
}
};
};
template
<
typename
T
,
typename
U
,
typename
Class
,
typename
...
Args
>
template
<
typename
T
,
typename
Resolve
,
typename
Reject
,
typename
Res
,
typename
...
Args
>
struct
ContinuationFactory
<
T
,
Promise
<
U
>
(
Class
::*
)(
Args
...)
>
{
struct
Continuation
<
T
,
Resolve
,
Reject
,
std
::
function
<
Res
(
Args
...)
>>
:
public
impl
::
Continuation
<
T
,
Resolve
,
Reject
,
Res
(
Args
...)
>
{
template
<
typename
ResolveFunc
,
typename
RejectFunc
>
typedef
impl
::
Continuation
<
T
,
Resolve
,
Reject
,
Res
(
Args
...)
>
Base
;
static
Continuable
<
T
>*
create
(
const
std
::
shared_ptr
<
Private
::
Core
>&
chain
,
Continuation
(
ResolveFunc
&&
resolveFunc
,
RejectFunc
&&
rejectFunc
)
{
const
std
::
shared_ptr
<
Core
>&
core
,
return
new
ThenChainContinuation
<
T
,
ResolveFunc
,
RejectFunc
>
(
Resolve
resolve
,
chain
,
Reject
reject
)
std
::
forward
<
ResolveFunc
>
(
resolveFunc
),
:
Base
(
core
,
std
::
move
(
resolve
),
std
::
move
(
reject
))
std
::
forward
<
RejectFunc
>
(
rejectFunc
));
{
}
}
};
};
}
}
...
@@ -818,7 +1000,7 @@ namespace Async {
...
@@ -818,7 +1000,7 @@ namespace Async {
template
<
typename
ResolveFunc
,
typename
RejectFunc
>
template
<
typename
ResolveFunc
,
typename
RejectFunc
>
auto
auto
then
(
ResolveFunc
&&
resolveFunc
,
RejectFunc
&&
rejectFunc
,
Continuation
type
=
Continuation
::
Direct
)
then
(
ResolveFunc
resolveFunc
,
RejectFunc
rejectFunc
)
->
Promise
<
->
Promise
<
typename
detail
::
RemovePromise
<
typename
detail
::
RemovePromise
<
typename
detail
::
FunctionTrait
<
ResolveFunc
>::
ReturnType
typename
detail
::
FunctionTrait
<
ResolveFunc
>::
ReturnType
...
@@ -826,23 +1008,14 @@ namespace Async {
...
@@ -826,23 +1008,14 @@ namespace Async {
>
>
{
{
thenStaticChecks
<
ResolveFunc
>
(
std
::
is_void
<
T
>
());
typedef
typename
detail
::
RemovePromise
<
typedef
typename
detail
::
RemovePromise
<
typename
detail
::
FunctionTrait
<
ResolveFunc
>::
ReturnType
typename
detail
::
FunctionTrait
<
ResolveFunc
>::
ReturnType
>::
Type
RetType
;
>::
Type
RetType
;
Promise
<
RetType
>
promise
;
Promise
<
RetType
>
promise
;
// Due to how template argument deduction works on universal references, we need to remove any reference from
typedef
Private
::
Continuation
<
T
,
ResolveFunc
,
RejectFunc
,
ResolveFunc
>
Continuation
;
// the deduced function type, fun fun fun
std
::
shared_ptr
<
Private
::
Request
>
req
=
std
::
make_shared
<
Continuation
>
(
promise
.
core_
,
resolveFunc
,
rejectFunc
);
typedef
typename
std
::
remove_reference
<
ResolveFunc
>::
type
ResolveFuncType
;
typedef
typename
std
::
remove_reference
<
RejectFunc
>::
type
RejectFuncType
;
std
::
shared_ptr
<
Private
::
Request
>
req
;
req
.
reset
(
Private
::
ContinuationFactory
<
T
,
ResolveFuncType
>::
create
(
promise
.
core_
,
std
::
forward
<
ResolveFunc
>
(
resolveFunc
),
std
::
forward
<
RejectFunc
>
(
rejectFunc
)));
std
::
unique_lock
<
std
::
mutex
>
guard
(
core_
->
mtx
);
std
::
unique_lock
<
std
::
mutex
>
guard
(
core_
->
mtx
);
if
(
isFulfilled
())
{
if
(
isFulfilled
())
{
...
@@ -871,18 +1044,6 @@ namespace Async {
...
@@ -871,18 +1044,6 @@ namespace Async {
,
rejection_
(
core_
)
,
rejection_
(
core_
)
{
}
{
}
template
<
typename
ResolveFunc
>
void
thenStaticChecks
(
std
::
true_type
/* is_void */
)
{
static_assert
(
detail
::
FunctionTrait
<
ResolveFunc
>::
ArgsCount
==
0
,
"Continuation function of a void promise should not take any argument"
);
}
template
<
typename
ResolveFunc
>
void
thenStaticChecks
(
std
::
false_type
/* is_void */
)
{
static_assert
(
detail
::
IsCallable
<
ResolveFunc
,
T
>::
value
,
"Function is not compatible with underlying promise type"
);
}
std
::
shared_ptr
<
Core
>
core_
;
std
::
shared_ptr
<
Core
>
core_
;
Resolver
resolver_
;
Resolver
resolver_
;
Rejection
rejection_
;
Rejection
rejection_
;
...
...
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