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
Hide 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,236 +294,419 @@ namespace Async {
...
@@ -295,236 +294,419 @@ 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
>
{
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
)
{
static_assert
(
sizeof
...(
Args
)
==
1
,
doResolveImpl
(
core
,
std
::
is_void
<
T
>
());
"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
doReject
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
void
doResolve
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
rejectFunc_
(
core
->
exc
);
finishResolve
(
resolve_
(
detail
::
tryMove
<
Resolve
>
(
core
->
value
())));
for
(
const
auto
&
req
:
this
->
chain_
->
requests
)
{
req
->
reject
(
this
->
chain_
);
}
}
}
void
doResolveImpl
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
,
std
::
true_type
/* is_void */
)
{
void
doReject
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
finishResolve
(
resolveFunc_
());
reject_
(
core
->
exc
);
}
for
(
const
auto
&
req
:
this
->
chain_
->
requests
)
{
req
->
reject
(
this
->
chain_
);
}
}
void
doResolveImpl
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
,
std
::
false_type
/* is_void */
)
{
template
<
typename
Ret
>
finishResolve
(
resolveFunc_
(
detail
::
tryMove
<
ResolveFunc
>
(
core
->
value
())));
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_
);
}
}
Resolve
resolve_
;
Reject
reject_
;
};
template
<
typename
Ret
>
// Specialization for a void-Promise
void
finishResolve
(
Ret
&&
ret
)
const
{
template
<
typename
Resolve
,
typename
Reject
,
typename
Res
,
typename
...
Args
>
typedef
typename
std
::
remove_reference
<
Ret
>::
type
CleanRet
;
struct
Continuation
<
void
,
Resolve
,
Reject
,
Res
(
Args
...)
>
:
public
Continuable
<
void
>
{
this
->
chain_
->
template
construct
<
CleanRet
>(
std
::
forward
<
Ret
>
(
ret
));
for
(
const
auto
&
req
:
this
->
chain_
->
requests
)
{
Continuation
(
req
->
resolve
(
this
->
chain_
);
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_
());
}
}
}
ResolveFunc
resolveFunc_
;
void
doReject
(
const
std
::
shared_ptr
<
CoreT
<
void
>>&
core
)
{
RejectFunc
rejectFunc_
;
reject_
(
core
->
exc
);
};
for
(
const
auto
&
req
:
this
->
chain_
->
requests
)
{
req
->
reject
(
this
->
chain_
);
}
}
template
<
typename
T
,
typename
ResolveFunc
,
typename
RejectFunc
>
template
<
typename
Ret
>
struct
ThenChainContinuation
:
public
Continuable
<
T
>
{
void
finishResolve
(
Ret
&&
ret
)
const
{
ThenChainContinuation
(
typedef
typename
std
::
remove_reference
<
Ret
>::
type
CleanRet
;
const
std
::
shared_ptr
<
Core
>&
chain
,
this
->
chain_
->
template
construct
<
CleanRet
>(
std
::
forward
<
Ret
>
(
ret
));
ResolveFunc
&&
resolveFunc
,
RejectFunc
&&
rejectFunc
)
for
(
const
auto
&
req
:
this
->
chain_
->
requests
)
{
:
Continuable
<
T
>
(
chain
)
req
->
resolve
(
this
->
chain_
);
,
resolveFunc_
(
std
::
forward
<
ResolveFunc
>
(
resolveFunc
))
}
,
rejectFunc_
(
std
::
forward
<
RejectFunc
>
(
rejectFunc
))
}
{
}
Resolve
resolve_
;
Reject
reject_
;
};
// Specialization for a callback returning void
template
<
typename
T
,
typename
Resolve
,
typename
Reject
,
typename
...
Args
>
struct
Continuation
<
T
,
Resolve
,
Reject
,
void
(
Args
...)
>
:
public
Continuable
<
T
>
{
Continuation
(
const
std
::
shared_ptr
<
Core
>&
chain
,
Resolve
resolve
,
Reject
reject
)
:
Continuable
<
T
>
(
chain
)
,
resolve_
(
resolve
)
,
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
)
{
doResolveImpl
(
core
,
std
::
is_void
<
T
>
());
}
void
doReject
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
void
doResolve
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
rejectFunc_
(
core
->
exc
);
resolve_
(
core
->
value
());
for
(
const
auto
&
req
:
core
->
requests
)
{
req
->
reject
(
core
);
}
}
}
void
doResolveImpl
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
,
std
::
true_type
/* is_void */
)
{
void
doReject
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
auto
promise
=
resolveFunc_
();
reject_
(
core
->
exc
);
finishResolve
(
promise
);
}
}
void
doResolveImpl
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
,
std
::
false_type
/* is_void */
)
{
Resolve
resolve_
;
auto
promise
=
resolveFunc_
(
detail
::
tryMove
<
ResolveFunc
>
(
core
->
value
()));
Reject
reject_
;
finishResolve
(
promise
);
};
}
// 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"
);
template
<
typename
P
>
Continuation
(
void
finishResolve
(
P
&
promise
)
{
const
std
::
shared_ptr
<
Core
>&
chain
,
auto
chainer
=
makeChainer
(
promise
);
Resolve
resolve
,
promise
.
then
(
std
::
move
(
chainer
),
[
=
](
std
::
exception_ptr
exc
)
{
Reject
reject
)
auto
core
=
this
->
chain_
;
:
Continuable
<
T
>
(
chain
)
core
->
exc
=
std
::
move
(
exc
);
,
resolve_
(
resolve
)
core
->
state
=
State
::
Rejected
;
,
reject_
(
reject
)
{
}
void
doResolve
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
auto
promise
=
resolve_
(
detail
::
tryMove
<
Resolve
>
(
core
->
value
()));
finishResolve
(
promise
);
}
void
doReject
(
const
std
::
shared_ptr
<
CoreT
<
T
>>&
core
)
{
reject_
(
core
->
exc
);
for
(
const
auto
&
req
:
core
->
requests
)
{
for
(
const
auto
&
req
:
core
->
requests
)
{
req
->
reject
(
core
);
req
->
reject
(
core
);
}
}
});
}
}
template
<
typename
PromiseType
>
struct
Chainer
{
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
);
}
}
std
::
shared_ptr
<
Core
>
chainCore
;
};
template
<
typename
Promise
,
typename
Type
=
typename
detail
::
RemovePromise
<
Promise
>
::
Type
>
Chainer
<
Type
>
makeChainer
(
const
Promise
&
)
{
return
Chainer
<
Type
>
(
this
->
chain_
);
}
template
<
typename
P
>
void
finishResolve
(
P
&
promise
)
{
auto
chainer
=
makeChainer
(
promise
);
promise
.
then
(
std
::
move
(
chainer
),
[
=
](
std
::
exception_ptr
exc
)
{
auto
core
=
this
->
chain_
;
core
->
exc
=
std
::
move
(
exc
);
core
->
state
=
State
::
Rejected
;
for
(
const
auto
&
req
:
core
->
requests
)
{
req
->
reject
(
core
);
}
});
}
Resolve
resolve_
;
Reject
reject_
;
ResolveFunc
resolveFunc_
;
};
RejectFunc
rejectFunc_
;
// 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"
);
template
<
typename
PromiseType
>
Continuation
(
struct
Chainer
{
const
std
::
shared_ptr
<
Core
>&
chain
,
Chainer
(
const
std
::
shared_ptr
<
Private
::
Core
>&
core
)
Resolve
resolve
,
:
chainCore
(
core
)
Reject
reject
)
:
Continuable
<
void
>
(
chain
)
,
resolve_
(
resolve
)
,
reject_
(
reject
)
{
}
{
}
void
operator
()(
const
PromiseType
&
val
)
{
void
doResolve
(
const
std
::
shared_ptr
<
CoreT
<
void
>>&
core
)
{
chainCore
->
construct
<
PromiseType
>
(
val
);
auto
promise
=
resolve_
();
for
(
const
auto
&
req
:
chainCore
->
requests
)
{
finishResolve
(
promise
);
req
->
resolve
(
chainCore
);
}
void
doReject
(
const
std
::
shared_ptr
<
CoreT
<
void
>>&
core
)
{
reject_
(
core
->
exc
);
for
(
const
auto
&
req
:
core
->
requests
)
{
req
->
reject
(
core
);
}
}
}
}
std
::
shared_ptr
<
Core
>
chainCore
;
template
<
typename
PromiseType
,
typename
Dummy
=
void
>
struct
Chainer
{
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
);
}
}
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
<
typename
Promise
,
typename
Type
=
typename
detail
::
RemovePromise
<
Promise
>
::
Type
>
Chainer
<
Type
>
makeChainer
(
const
Promise
&
)
{
return
Chainer
<
Type
>
(
this
->
chain_
);
}
template
<
typename
P
>
void
finishResolve
(
P
&
promise
)
{
auto
chainer
=
makeChainer
(
promise
);
promise
.
then
(
std
::
move
(
chainer
),
[
=
](
std
::
exception_ptr
exc
)
{
auto
core
=
this
->
chain_
;
core
->
exc
=
std
::
move
(
exc
);
core
->
state
=
State
::
Rejected
;
for
(
const
auto
&
req
:
core
->
requests
)
{
req
->
reject
(
core
);
}
});
}
Resolve
resolve_
;
Reject
reject_
;
};
};
template
<
}
// namespace impl
typename
Promise
,
typename
Type
=
typename
detail
::
RemovePromise
<
Promise
>
::
Type
>
Chainer
<
Type
>
makeChainer
(
const
Promise
&
)
{
return
Chainer
<
Type
>
(
this
->
chain_
);
}
};
template
<
typename
T
,
typename
Resolve
,
typename
Reject
,
typename
Sig
>
struct
Continuation
:
public
impl
::
Continuation
<
T
,
Resolve
,
Reject
,
decltype
(
&
Sig
::
operator
())
>
{
template
<
typename
T
,
typename
ResolveFunc
>
typedef
impl
::
Continuation
<
T
,
Resolve
,
Reject
,
decltype
(
&
Sig
::
operator
())
>
Base
;
struct
ContinuationFactory
:
public
ContinuationFactory
<
T
,
decltype
(
&
ResolveFunc
::
operator
())
>
{
};
/* Const */
template
<
typename
T
,
typename
R
,
typename
Class
,
typename
...
Args
>
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
));
}
};
template
<
typename
T
,
typename
Class
,
typename
...
Args
>
Continuation
(
struct
ContinuationFactory
<
T
,
void
(
Class
::*
)(
Args
...)
const
>
{
const
std
::
shared_ptr
<
Core
>&
core
,
template
<
typename
ResolveFunc
,
typename
RejectFunc
>
Resolve
resolve
,
static
Continuable
<
T
>*
create
(
Reject
reject
)
const
std
::
shared_ptr
<
Private
::
Core
>&
chain
,
:
Base
(
core
,
std
::
move
(
resolve
),
std
::
move
(
reject
))
ResolveFunc
&&
resolveFunc
,
RejectFunc
&&
rejectFunc
)
{
{
}
return
new
ThenContinuation
<
T
,
ResolveFunc
,
RejectFunc
>
(
chain
,
std
::
forward
<
ResolveFunc
>
(
resolveFunc
),
std
::
forward
<
RejectFunc
>
(
rejectFunc
));
}
};
};
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