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
Hide 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:
// -- unified access to all actor handles in CAF -------------------------------
/// 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:
using
pointer
=
caf
::
abstract_actor
*
;
constexpr
caf_handle
()
:
ptr_
(
nullptr
)
{
// nop
}
template
<
class
T
>
caf_handle
(
const
T
&
x
)
{
*
this
=
x
;
}
caf_handle
&
operator
=
(
caf
::
abstract_actor
*
x
)
{
inline
caf_handle
&
operator
=
(
caf
::
abstract_actor
*
x
)
{
ptr_
=
x
;
return
*
this
;
}
...
...
@@ -175,15 +180,20 @@ public:
caf_handle
&
operator
=
(
const
caf_handle
&
)
=
default
;
pointer
get
()
const
{
inline
pointer
get
()
const
{
return
ptr_
;
}
private:
caf_handle
()
:
ptr_
(
nullptr
)
{
// nop
inline
ptrdiff_t
compare
(
const
caf_handle
&
other
)
const
{
return
reinterpret_cast
<
ptrdiff_t
>
(
ptr_
)
-
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_
;
};
...
...
@@ -192,7 +202,7 @@ private:
/// Returns a pointer to the next element in an actor's mailbox without taking
/// it out of the mailbox.
/// @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
);
auto
sptr
=
dynamic_cast
<
caf
::
scheduled_actor
*>
(
x
.
get
());
if
(
sptr
!=
nullptr
)
...
...
@@ -227,26 +237,33 @@ caf::optional<std::tuple<T>> unboxing_extract(caf_handle x) {
/// `default_extract`.
/// @private
template
<
class
T
,
bool
HasOuterType
,
class
...
Ts
>
struct
extract_impl
{
struct
try_
extract_impl
{
caf
::
optional
<
std
::
tuple
<
T
,
Ts
...
>>
operator
()(
caf_handle
x
)
{
return
default_extract
<
T
,
Ts
...
>
(
x
);
}
};
template
<
class
T
>
struct
extract_impl
<
T
,
true
>
{
struct
try_
extract_impl
<
T
,
true
>
{
caf
::
optional
<
std
::
tuple
<
T
>>
operator
()(
caf_handle
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
/// the mailbox. Fails on an empty mailbox or if the content of the next
/// element does not match `<T, Ts...>`.
template
<
class
T
,
class
...
Ts
>
std
::
tuple
<
T
,
Ts
...
>
extract
(
caf_handle
x
)
{
extract_impl
<
T
,
has_outer_type
<
T
>::
value
,
Ts
...
>
f
;
auto
result
=
f
(
x
);
auto
result
=
try_extract
<
T
,
Ts
...
>
(
x
);
if
(
result
==
caf
::
none
)
{
auto
ptr
=
next_mailbox_element
(
x
);
if
(
ptr
==
nullptr
)
...
...
@@ -259,11 +276,9 @@ std::tuple<T, Ts...> extract(caf_handle x) {
template
<
class
T
,
class
...
Ts
>
bool
received
(
caf_handle
x
)
{
extract_impl
<
T
,
has_outer_type
<
T
>::
value
,
Ts
...
>
f
;
return
f
(
x
)
!=
caf
::
none
;
return
try_extract
<
T
,
Ts
...
>
(
x
)
!=
caf
::
none
;
}
template
<
class
...
Ts
>
class
expect_clause
{
public:
...
...
@@ -340,149 +355,69 @@ protected:
std
::
function
<
void
()
>
peek_
;
};
template
<
class
Derived
>
class
disallow_clause
_base
{
template
<
class
...
Ts
>
class
disallow_clause
{
public:
disallow_clause_base
(
caf
::
scheduler
::
test_coordinator
&
sched
)
:
sched_
(
sched
),
dest_
(
nullptr
)
{
// nop
}
disallow_clause_base
(
disallow_clause_base
&&
other
)
:
sched_
(
other
.
sched_
),
src_
(
std
::
move
(
other
.
src_
))
{
// nop
}
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
>
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
)
{
if
(
sched_
.
prioritize
(
whom
))
dest_
=
&
sched_
.
next_job
<
caf
::
scheduled_actor
>
();
disallow_clause
()
{
check_
=
[
=
]
{
auto
ptr
=
next_mailbox_element
(
dest_
);
if
(
ptr
==
nullptr
)
return
;
if
(
src_
!=
nullptr
&&
ptr
->
sender
!=
src_
)
return
;
auto
res
=
try_extract
<
Ts
...
>
(
dest_
);
if
(
res
!=
caf
::
none
)
CAF_FAIL
(
"received disallowed message: "
<<
CAF_ARG
(
*
res
));
};
}
Derived
&
to
(
const
caf
::
scoped_actor
&
whom
)
{
dest_
=
whom
.
ptr
();
return
dref
();
}
disallow_clause
(
disallow_clause
&&
other
)
=
default
;
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
...>();
~
disallow_clause
()
{
if
(
check_
!=
nullptr
)
check_
();
}
protected:
Derived
&
dref
()
{
return
*
static_cast
<
Derived
*>
(
this
);
}
caf
::
scheduler
::
test_coordinator
&
sched_
;
caf
::
strong_actor_ptr
src_
;
caf
::
local_actor
*
dest_
;
};
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
disallow_clause
&
from
(
const
wildcard
&
)
{
return
*
this
;
}
template
<
class
...
Us
>
void
with
(
Us
&&
...
xs
)
{
// succeed immediately if dest_ is empty
if
(
this
->
dest_
==
nullptr
)
return
;
auto
tmp
=
std
::
make_tuple
(
std
::
forward
<
Us
>
(
xs
)...);
elementwise_compare_inspector
<
decltype
(
tmp
)
>
inspector
{
tmp
};
auto
ys
=
this
->
template
peek
<
Ts
...>();
if
(
ys
&&
inspector
(
get
<
0
>
(
*
ys
)))
CAF_FAIL
(
"disallowed message found: "
<<
caf
::
deep_to_string
(
ys
));
disallow_clause
&
from
(
caf_handle
x
)
{
src_
=
x
;
return
*
this
;
}
};
/// 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
disallow_clause
&
to
(
caf_handle
x
)
{
dest_
=
x
;
return
*
this
;
}
template
<
class
...
Us
>
void
with
(
Us
&&
...
xs
)
{
if
(
this
->
dest_
==
nullptr
)
return
;
std
::
integral_constant
<
bool
,
has_outer_type
<
T
>::
value
>
token
;
// TODO: move tmp into lambda when switching to C++14
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
;
auto
&
x0
=
get
<
0
>
(
*
xs
);
if
(
is
<
T
>
(
x0
)
&&
inspect
(
inspector
,
const_cast
<
T
&>
(
get
<
T
>
(
x0
))))
CAF_FAIL
(
"disallowed message found: "
<<
caf
::
deep_to_string
(
x0
));
}
};
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
check_
=
[
=
]
{
auto
ptr
=
next_mailbox_element
(
dest_
);
if
(
ptr
==
nullptr
)
return
;
if
(
src_
!=
nullptr
&&
ptr
->
sender
!=
src_
)
return
;
auto
res
=
try_extract
<
Ts
...
>
(
dest_
);
if
(
res
!=
caf
::
none
)
{
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
));
}
};
}
void
with
()
{
if
(
dest_
==
nullptr
)
return
;
auto
ptr
=
next_mailbox_element
(
dest_
);
CAF_REQUIRE
(
!
ptr
->
content
().
empty
());
}
protected:
caf_handle
src_
;
caf_handle
dest_
;
std
::
function
<
void
()
>
check_
;
};
template
<
class
Config
=
caf
::
actor_system_config
>
...
...
@@ -547,4 +482,4 @@ struct test_coordinator_fixture {
#define 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