Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
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
Operations
Operations
Metrics
Environments
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
cpp-libs
Actor Framework
Commits
95554bc0
Commit
95554bc0
authored
Feb 12, 2018
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix disallow in the testing DSL
parent
4dda7d9a
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
76 additions
and
141 deletions
+76
-141
libcaf_test/caf/test/dsl.hpp
libcaf_test/caf/test/dsl.hpp
+76
-141
No files found.
libcaf_test/caf/test/dsl.hpp
View file @
95554bc0
...
@@ -152,16 +152,21 @@ private:
...
@@ -152,16 +152,21 @@ private:
// -- unified access to all actor handles in CAF -------------------------------
// -- unified access to all actor handles in CAF -------------------------------
/// Reduces any of CAF's handle types to an `abstract_actor` pointer.
/// Reduces any of CAF's handle types to an `abstract_actor` pointer.
class
caf_handle
{
class
caf_handle
:
caf
::
detail
::
comparable
<
caf_handle
>
,
caf
::
detail
::
comparable
<
caf_handle
,
std
::
nullptr_t
>
{
public:
public:
using
pointer
=
caf
::
abstract_actor
*
;
using
pointer
=
caf
::
abstract_actor
*
;
constexpr
caf_handle
()
:
ptr_
(
nullptr
)
{
// nop
}
template
<
class
T
>
template
<
class
T
>
caf_handle
(
const
T
&
x
)
{
caf_handle
(
const
T
&
x
)
{
*
this
=
x
;
*
this
=
x
;
}
}
caf_handle
&
operator
=
(
caf
::
abstract_actor
*
x
)
{
inline
caf_handle
&
operator
=
(
caf
::
abstract_actor
*
x
)
{
ptr_
=
x
;
ptr_
=
x
;
return
*
this
;
return
*
this
;
}
}
...
@@ -175,15 +180,20 @@ public:
...
@@ -175,15 +180,20 @@ public:
caf_handle
&
operator
=
(
const
caf_handle
&
)
=
default
;
caf_handle
&
operator
=
(
const
caf_handle
&
)
=
default
;
pointer
get
()
const
{
inline
pointer
get
()
const
{
return
ptr_
;
return
ptr_
;
}
}
private:
inline
ptrdiff_t
compare
(
const
caf_handle
&
other
)
const
{
caf_handle
()
:
ptr_
(
nullptr
)
{
return
reinterpret_cast
<
ptrdiff_t
>
(
ptr_
)
// nop
-
reinterpret_cast
<
ptrdiff_t
>
(
other
.
ptr_
);
}
inline
ptrdiff_t
compare
(
std
::
nullptr_t
)
const
{
return
reinterpret_cast
<
ptrdiff_t
>
(
ptr_
);
}
}
private:
caf
::
abstract_actor
*
ptr_
;
caf
::
abstract_actor
*
ptr_
;
};
};
...
@@ -192,7 +202,7 @@ private:
...
@@ -192,7 +202,7 @@ private:
/// Returns a pointer to the next element in an actor's mailbox without taking
/// Returns a pointer to the next element in an actor's mailbox without taking
/// it out of the mailbox.
/// it out of the mailbox.
/// @pre `ptr` is alive and either a `scheduled_actor` or `blocking_actor`
/// @pre `ptr` is alive and either a `scheduled_actor` or `blocking_actor`
caf
::
mailbox_element
*
next_mailbox_element
(
caf_handle
x
)
{
inline
caf
::
mailbox_element
*
next_mailbox_element
(
caf_handle
x
)
{
CAF_ASSERT
(
x
.
get
()
!=
nullptr
);
CAF_ASSERT
(
x
.
get
()
!=
nullptr
);
auto
sptr
=
dynamic_cast
<
caf
::
scheduled_actor
*>
(
x
.
get
());
auto
sptr
=
dynamic_cast
<
caf
::
scheduled_actor
*>
(
x
.
get
());
if
(
sptr
!=
nullptr
)
if
(
sptr
!=
nullptr
)
...
@@ -227,26 +237,33 @@ caf::optional<std::tuple<T>> unboxing_extract(caf_handle x) {
...
@@ -227,26 +237,33 @@ caf::optional<std::tuple<T>> unboxing_extract(caf_handle x) {
/// `default_extract`.
/// `default_extract`.
/// @private
/// @private
template
<
class
T
,
bool
HasOuterType
,
class
...
Ts
>
template
<
class
T
,
bool
HasOuterType
,
class
...
Ts
>
struct
extract_impl
{
struct
try_
extract_impl
{
caf
::
optional
<
std
::
tuple
<
T
,
Ts
...
>>
operator
()(
caf_handle
x
)
{
caf
::
optional
<
std
::
tuple
<
T
,
Ts
...
>>
operator
()(
caf_handle
x
)
{
return
default_extract
<
T
,
Ts
...
>
(
x
);
return
default_extract
<
T
,
Ts
...
>
(
x
);
}
}
};
};
template
<
class
T
>
template
<
class
T
>
struct
extract_impl
<
T
,
true
>
{
struct
try_
extract_impl
<
T
,
true
>
{
caf
::
optional
<
std
::
tuple
<
T
>>
operator
()(
caf_handle
x
)
{
caf
::
optional
<
std
::
tuple
<
T
>>
operator
()(
caf_handle
x
)
{
return
unboxing_extract
<
T
>
(
x
);
return
unboxing_extract
<
T
>
(
x
);
}
}
};
};
/// Returns the content of the next mailbox element as `tuple<T, Ts...>` on a
/// match. Returns `none` otherwise.
template
<
class
T
,
class
...
Ts
>
caf
::
optional
<
std
::
tuple
<
T
,
Ts
...
>>
try_extract
(
caf_handle
x
)
{
try_extract_impl
<
T
,
has_outer_type
<
T
>::
value
,
Ts
...
>
f
;
return
f
(
x
);
}
/// Returns the content of the next mailbox element without taking it out of
/// Returns the content of the next mailbox element without taking it out of
/// the mailbox. Fails on an empty mailbox or if the content of the next
/// the mailbox. Fails on an empty mailbox or if the content of the next
/// element does not match `<T, Ts...>`.
/// element does not match `<T, Ts...>`.
template
<
class
T
,
class
...
Ts
>
template
<
class
T
,
class
...
Ts
>
std
::
tuple
<
T
,
Ts
...
>
extract
(
caf_handle
x
)
{
std
::
tuple
<
T
,
Ts
...
>
extract
(
caf_handle
x
)
{
extract_impl
<
T
,
has_outer_type
<
T
>::
value
,
Ts
...
>
f
;
auto
result
=
try_extract
<
T
,
Ts
...
>
(
x
);
auto
result
=
f
(
x
);
if
(
result
==
caf
::
none
)
{
if
(
result
==
caf
::
none
)
{
auto
ptr
=
next_mailbox_element
(
x
);
auto
ptr
=
next_mailbox_element
(
x
);
if
(
ptr
==
nullptr
)
if
(
ptr
==
nullptr
)
...
@@ -259,11 +276,9 @@ std::tuple<T, Ts...> extract(caf_handle x) {
...
@@ -259,11 +276,9 @@ std::tuple<T, Ts...> extract(caf_handle x) {
template
<
class
T
,
class
...
Ts
>
template
<
class
T
,
class
...
Ts
>
bool
received
(
caf_handle
x
)
{
bool
received
(
caf_handle
x
)
{
extract_impl
<
T
,
has_outer_type
<
T
>::
value
,
Ts
...
>
f
;
return
try_extract
<
T
,
Ts
...
>
(
x
)
!=
caf
::
none
;
return
f
(
x
)
!=
caf
::
none
;
}
}
template
<
class
...
Ts
>
template
<
class
...
Ts
>
class
expect_clause
{
class
expect_clause
{
public:
public:
...
@@ -340,149 +355,69 @@ protected:
...
@@ -340,149 +355,69 @@ protected:
std
::
function
<
void
()
>
peek_
;
std
::
function
<
void
()
>
peek_
;
};
};
template
<
class
Derived
>
template
<
class
...
Ts
>
class
disallow_clause
_base
{
class
disallow_clause
{
public:
public:
disallow_clause_base
(
caf
::
scheduler
::
test_coordinator
&
sched
)
disallow_clause
()
{
:
sched_
(
sched
),
check_
=
[
=
]
{
dest_
(
nullptr
)
{
auto
ptr
=
next_mailbox_element
(
dest_
);
// nop
if
(
ptr
==
nullptr
)
}
return
;
if
(
src_
!=
nullptr
&&
ptr
->
sender
!=
src_
)
disallow_clause_base
(
disallow_clause_base
&&
other
)
return
;
:
sched_
(
other
.
sched_
),
auto
res
=
try_extract
<
Ts
...
>
(
dest_
);
src_
(
std
::
move
(
other
.
src_
))
{
if
(
res
!=
caf
::
none
)
// nop
CAF_FAIL
(
"received disallowed message: "
<<
CAF_ARG
(
*
res
));
}
};
Derived
&
from
(
const
wildcard
&
)
{
return
dref
();
}
template
<
class
Handle
>
Derived
&
from
(
const
Handle
&
whom
)
{
src_
=
caf
::
actor_cast
<
caf
::
strong_actor_ptr
>
(
whom
);
return
dref
();
}
}
template
<
class
Handle
>
disallow_clause
(
disallow_clause
&&
other
)
=
default
;
Derived
&
to
(
const
Handle
&
whom
)
{
// not setting dest_ causes the content checking to succeed immediately
if
(
sched_
.
prioritize
(
whom
))
{
dest_
=
&
sched_
.
next_job
<
caf
::
scheduled_actor
>
();
}
return
dref
();
}
Derived
&
to
(
const
wildcard
&
whom
)
{
~
disallow_clause
(
)
{
if
(
sched_
.
prioritize
(
whom
)
)
if
(
check_
!=
nullptr
)
dest_
=
&
sched_
.
next_job
<
caf
::
scheduled_actor
>
();
check_
();
}
}
Derived
&
to
(
const
caf
::
scoped_actor
&
whom
)
{
disallow_clause
&
from
(
const
wildcard
&
)
{
dest_
=
whom
.
ptr
();
return
*
this
;
return
dref
();
}
template
<
class
...
Ts
>
caf
::
optional
<
std
::
tuple
<
const
Ts
&
...
>>
peek
()
{
CAF_REQUIRE
(
dest_
!=
nullptr
);
auto
ptr
=
peek
(
dest_
);
if
(
!
ptr
->
content
().
template
match_elements
<
Ts
...>())
return
caf
::
none
;
return
ptr
->
content
().
template
get_as_tuple
<
Ts
...>();
}
}
protected:
disallow_clause
&
from
(
caf_handle
x
)
{
Derived
&
dref
()
{
src_
=
x
;
return
*
static_cast
<
Derived
*>
(
this
)
;
return
*
this
;
}
}
caf
::
scheduler
::
test_coordinator
&
sched_
;
disallow_clause
&
to
(
caf_handle
x
)
{
caf
::
strong_actor_ptr
src_
;
dest_
=
x
;
caf
::
local_actor
*
dest_
;
return
*
this
;
};
template
<
class
...
Ts
>
class
disallow_clause
:
public
disallow_clause_base
<
disallow_clause
<
Ts
...
>>
{
public:
template
<
class
...
Us
>
disallow_clause
(
Us
&&
...
xs
)
:
disallow_clause_base
<
disallow_clause
<
Ts
...
>>
(
std
::
forward
<
Us
>
(
xs
)...)
{
// nop
}
}
template
<
class
...
Us
>
template
<
class
...
Us
>
void
with
(
Us
&&
...
xs
)
{
void
with
(
Us
&&
...
xs
)
{
// succeed immediately if dest_ is empty
// TODO: move tmp into lambda when switching to C++14
if
(
this
->
dest_
==
nullptr
)
return
;
auto
tmp
=
std
::
make_tuple
(
std
::
forward
<
Us
>
(
xs
)...);
auto
tmp
=
std
::
make_tuple
(
std
::
forward
<
Us
>
(
xs
)...);
elementwise_compare_inspector
<
decltype
(
tmp
)
>
inspector
{
tmp
};
check_
=
[
=
]
{
auto
ys
=
this
->
template
peek
<
Ts
...>();
auto
ptr
=
next_mailbox_element
(
dest_
);
if
(
ys
&&
inspector
(
get
<
0
>
(
*
ys
)))
if
(
ptr
==
nullptr
)
CAF_FAIL
(
"disallowed message found: "
<<
caf
::
deep_to_string
(
ys
));
}
};
/// The single-argument disallow-clause allows to automagically unwrap T
/// if it's a variant-like wrapper.
template
<
class
T
>
class
disallow_clause
<
T
>
:
public
disallow_clause_base
<
disallow_clause
<
T
>>
{
public:
template
<
class
...
Us
>
disallow_clause
(
Us
&&
...
xs
)
:
disallow_clause_base
<
disallow_clause
<
T
>>
(
std
::
forward
<
Us
>
(
xs
)...)
{
// nop
}
template
<
class
...
Us
>
void
with
(
Us
&&
...
xs
)
{
if
(
this
->
dest_
==
nullptr
)
return
;
return
;
std
::
integral_constant
<
bool
,
has_outer_type
<
T
>::
value
>
token
;
if
(
src_
!=
nullptr
&&
ptr
->
sender
!=
src_
)
auto
tmp
=
std
::
make_tuple
(
std
::
forward
<
Us
>
(
xs
)...);
with_content
(
token
,
tmp
);
}
private:
template
<
class
U
>
void
with_content
(
std
::
integral_constant
<
bool
,
false
>
,
const
U
&
x
)
{
elementwise_compare_inspector
<
U
>
inspector
{
x
};
auto
xs
=
this
->
template
peek
<
T
>();
if
(
xs
&&
inspector
(
get
<
0
>
(
*
xs
)))
CAF_FAIL
(
"disallowed message found: "
<<
caf
::
deep_to_string
(
*
xs
));
}
template
<
class
U
>
void
with_content
(
std
::
integral_constant
<
bool
,
true
>
,
const
U
&
x
)
{
elementwise_compare_inspector
<
U
>
inspector
{
x
};
auto
xs
=
this
->
template
peek
<
typename
T
::
outer_type
>();
if
(
!
xs
)
return
;
return
;
auto
&
x0
=
get
<
0
>
(
*
xs
);
auto
res
=
try_extract
<
Ts
...
>
(
dest_
);
if
(
is
<
T
>
(
x0
)
&&
inspect
(
inspector
,
const_cast
<
T
&>
(
get
<
T
>
(
x0
))))
if
(
res
!=
caf
::
none
)
{
CAF_FAIL
(
"disallowed message found: "
<<
caf
::
deep_to_string
(
x0
));
using
namespace
caf
::
detail
;
elementwise_compare_inspector
<
decltype
(
tmp
)
>
inspector
{
tmp
};
auto
&
ys
=
*
res
;
auto
ys_indices
=
get_indices
(
ys
);
if
(
apply_args
(
inspector
,
ys_indices
,
ys
))
CAF_FAIL
(
"received disallowed message: "
<<
CAF_ARG
(
*
res
));
}
}
};
};
template
<
>
class
disallow_clause
<
void
>
:
public
disallow_clause_base
<
disallow_clause
<
void
>>
{
public:
template
<
class
...
Us
>
disallow_clause
(
Us
&&
...
xs
)
:
disallow_clause_base
<
disallow_clause
<
void
>>
(
std
::
forward
<
Us
>
(
xs
)...)
{
// nop
}
}
void
with
()
{
protected:
if
(
dest_
==
nullptr
)
caf_handle
src_
;
return
;
caf_handle
dest_
;
auto
ptr
=
next_mailbox_element
(
dest_
);
std
::
function
<
void
()
>
check_
;
CAF_REQUIRE
(
!
ptr
->
content
().
empty
());
}
};
};
template
<
class
Config
=
caf
::
actor_system_config
>
template
<
class
Config
=
caf
::
actor_system_config
>
...
@@ -547,4 +482,4 @@ struct test_coordinator_fixture {
...
@@ -547,4 +482,4 @@ struct test_coordinator_fixture {
#define disallow(types, fields) \
#define disallow(types, fields) \
CAF_MESSAGE("disallow" << #types << "." << #fields); \
CAF_MESSAGE("disallow" << #types << "." << #fields); \
disallow_clause< CAF_EXPAND(CAF_DSL_LIST types) >{
sched
} . fields
disallow_clause< CAF_EXPAND(CAF_DSL_LIST types) >{} . fields
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