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
03b3b68b
Commit
03b3b68b
authored
Jan 22, 2012
by
neverlord
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
documentation and minor API changes
parent
1bfe10c2
Changes
46
Show whitespace changes
Inline
Side-by-side
Showing
46 changed files
with
745 additions
and
366 deletions
+745
-366
benchmarks/Matching.scala
benchmarks/Matching.scala
+6
-6
benchmarks/mixed_case.cpp
benchmarks/mixed_case.cpp
+2
-2
benchmarks/scala_test.sh
benchmarks/scala_test.sh
+1
-1
cppa.files
cppa.files
+2
-0
cppa/abstract_event_based_actor.hpp
cppa/abstract_event_based_actor.hpp
+5
-2
cppa/actor.hpp
cppa/actor.hpp
+20
-15
cppa/actor_proxy.hpp
cppa/actor_proxy.hpp
+8
-0
cppa/any_tuple.hpp
cppa/any_tuple.hpp
+24
-1
cppa/any_tuple_view.hpp
cppa/any_tuple_view.hpp
+8
-0
cppa/anything.hpp
cppa/anything.hpp
+1
-1
cppa/attachable.hpp
cppa/attachable.hpp
+17
-3
cppa/cppa.hpp
cppa/cppa.hpp
+9
-74
cppa/detail/abstract_tuple.hpp
cppa/detail/abstract_tuple.hpp
+6
-1
cppa/detail/decorated_tuple.hpp
cppa/detail/decorated_tuple.hpp
+17
-2
cppa/detail/empty_tuple.hpp
cppa/detail/empty_tuple.hpp
+1
-0
cppa/detail/invokable.hpp
cppa/detail/invokable.hpp
+2
-3
cppa/detail/matches.hpp
cppa/detail/matches.hpp
+152
-26
cppa/detail/object_array.hpp
cppa/detail/object_array.hpp
+2
-0
cppa/detail/tdata.hpp
cppa/detail/tdata.hpp
+55
-8
cppa/detail/tuple_vals.hpp
cppa/detail/tuple_vals.hpp
+14
-0
cppa/detail/types_array.hpp
cppa/detail/types_array.hpp
+60
-30
cppa/pattern.hpp
cppa/pattern.hpp
+55
-52
cppa/process_information.hpp
cppa/process_information.hpp
+29
-9
cppa/receive.hpp
cppa/receive.hpp
+69
-90
cppa/scheduled_actor.hpp
cppa/scheduled_actor.hpp
+22
-0
cppa/scheduler.hpp
cppa/scheduler.hpp
+2
-1
cppa/scheduling_hint.hpp
cppa/scheduling_hint.hpp
+13
-0
cppa/self.hpp
cppa/self.hpp
+0
-6
cppa/tuple.hpp
cppa/tuple.hpp
+3
-1
cppa/tuple_cast.hpp
cppa/tuple_cast.hpp
+3
-5
cppa/tuple_view.hpp
cppa/tuple_view.hpp
+2
-0
cppa/type_value_pair.hpp
cppa/type_value_pair.hpp
+42
-0
cppa/uniform_type_info.hpp
cppa/uniform_type_info.hpp
+1
-1
cppa/util/static_foreach.hpp
cppa/util/static_foreach.hpp
+56
-0
examples/announce_example_4.cpp
examples/announce_example_4.cpp
+1
-1
examples/announce_example_5.cpp
examples/announce_example_5.cpp
+3
-3
src/abstract_tuple.cpp
src/abstract_tuple.cpp
+1
-1
src/any_tuple.cpp
src/any_tuple.cpp
+4
-4
src/converted_thread_context.cpp
src/converted_thread_context.cpp
+1
-1
src/empty_tuple.cpp
src/empty_tuple.cpp
+5
-0
src/object_array.cpp
src/object_array.cpp
+5
-0
src/scheduler.cpp
src/scheduler.cpp
+2
-1
unit_testing/ping_pong.cpp
unit_testing/ping_pong.cpp
+2
-2
unit_testing/test__local_group.cpp
unit_testing/test__local_group.cpp
+1
-0
unit_testing/test__pattern.cpp
unit_testing/test__pattern.cpp
+4
-4
unit_testing/test__spawn.cpp
unit_testing/test__spawn.cpp
+7
-9
No files found.
benchmarks/Matching.scala
View file @
03b3b68b
...
...
@@ -30,12 +30,12 @@ object Matching {
case
Msg5
(
0
,
0
,
0
)
=>
msg5Matched
+=
1
case
Msg6
(
0
,
0.0
,
"0"
)
=>
msg6Matched
+=
1
}
val
m1
=
Msg1
(
0
)
val
m2
=
Msg2
(
0.0
)
val
m3
=
Msg3
(
List
(
0
))
val
m4
=
Msg4
(
0
,
"0"
)
val
m5
=
Msg5
(
0
,
0
,
0
)
val
m6
=
Msg6
(
0
,
0.0
,
"0"
)
val
m1
:
Any
=
Msg1
(
0
)
val
m2
:
Any
=
Msg2
(
0.0
)
val
m3
:
Any
=
Msg3
(
List
(
0
))
val
m4
:
Any
=
Msg4
(
0
,
"0"
)
val
m5
:
Any
=
Msg5
(
0
,
0
,
0
)
val
m6
:
Any
=
Msg6
(
0
,
0.0
,
"0"
)
for
(
_
<-
zero
until
numLoops
)
{
partFun
(
m1
)
partFun
(
m2
)
...
...
benchmarks/mixed_case.cpp
View file @
03b3b68b
...
...
@@ -88,7 +88,7 @@ struct fsm_chain_link : fsm_actor<fsm_chain_link>
(
on
<
atom
(
"token"
),
int
>
()
>>
[
=
](
int
v
)
{
next
->
enqueue
(
nullptr
,
std
::
move
(
last_receiv
ed
()));
next
->
enqueue
(
nullptr
,
std
::
move
(
self
->
last_dequeu
ed
()));
if
(
v
==
0
)
become_void
();
}
);
...
...
@@ -174,7 +174,7 @@ void chain_link(actor_ptr next)
(
on
<
atom
(
"token"
),
int
>
()
>>
[
&
](
int
v
)
{
next
<<
last_receiv
ed
();
next
<<
self
->
last_dequeu
ed
();
if
(
v
==
0
)
{
done
=
true
;
...
...
benchmarks/scala_test.sh
View file @
03b3b68b
#!/bin/bash
#export JAVA_OPTS="-Xmx1024"
#echo "scala -cp /home/neverlord/akka-microkernel-1.2/lib/akka/akka-actor-1.2.jar $@" | ./exec.sh
echo
"
/home/neverlord/scala/bin/
scala -cp /home/neverlord/akka-microkernel-1.2/lib/akka/akka-actor-1.2.jar
$@
"
| ./exec.sh
echo
"scala -cp /home/neverlord/akka-microkernel-1.2/lib/akka/akka-actor-1.2.jar
$@
"
| ./exec.sh
cppa.files
View file @
03b3b68b
...
...
@@ -259,3 +259,5 @@ benchmarks/theron_mailbox_performance.cpp
benchmarks/utility.hpp
benchmarks/theron_actor_creation.cpp
benchmarks/theron_mixed_case.cpp
cppa/util/static_foreach.hpp
cppa/type_value_pair.hpp
cppa/abstract_event_based_actor.hpp
View file @
03b3b68b
...
...
@@ -42,6 +42,9 @@
namespace
cppa
{
/**
* @brief Base class for all event-based actor implementations.
*/
class
abstract_event_based_actor
:
public
detail
::
abstract_scheduled_actor
{
...
...
@@ -58,12 +61,12 @@ class abstract_event_based_actor : public detail::abstract_scheduled_actor
void
resume
(
util
::
fiber
*
,
resume_callback
*
callback
)
/*override*/
;
/**
*
*
@brief Initializes the actor by defining an initial behavior.
*/
virtual
void
init
()
=
0
;
/**
*
*
@copydoc cppa::scheduled_actor::on_exit()
*/
virtual
void
on_exit
();
...
...
cppa/actor.hpp
View file @
03b3b68b
...
...
@@ -72,22 +72,26 @@ class actor : public channel
~
actor
();
/**
* @brief Attaches @p ptr to this actor
* (the actor takes ownership of @p ptr).
*
* The actor will call <tt>ptr->detach(...)</tt> on exit or immediately
* if he already exited.
* @brief Attaches @p ptr to this actor.
*
* The actor will call <tt>ptr->detach(...)</tt> on exit, or immediately
* if it already finished execution.
* @param ptr A callback object that's executed if the actor finishes
* execution.
* @returns @c true if @p ptr was successfully attached to the actor;
* otherwise (actor already exited) @p false.
* @warning The actor takes ownership of @p ptr.
*/
virtual
bool
attach
(
attachable
*
ptr
)
=
0
;
/**
* @brief Attaches the functor or function @p ftor to this actor.
* @brief Convenience function that attaches the functor
* or function @p ftor to this actor.
*
* The actor executes <tt>ftor()</tt> on exit or immediatley if he
* already exited.
* The actor executes <tt>ftor()</tt> on exit, or immediatley
* if it already finished execution.
* @param ftor A functor, function or lambda expression that's executed
* if the actor finishes execution.
* @returns @c true if @p ftor was successfully attached to the actor;
* otherwise (actor already exited) @p false.
*/
...
...
@@ -128,7 +132,7 @@ class actor : public channel
/**
* @brief Unlinks this actor from @p other.
* @param oter Linked Actor.
* @param ot
h
er Linked Actor.
* @note Links are automatically removed if the Actor finishes execution.
*/
virtual
void
unlink_from
(
intrusive_ptr
<
actor
>&
other
)
=
0
;
...
...
@@ -152,27 +156,23 @@ class actor : public channel
// rvalue support
/**
* @copydoc link_to(intrusive_ptr<actor>&)
* Support for rvalue references.
*/
void
link_to
(
intrusive_ptr
<
actor
>&&
other
);
/**
* @copydoc unlink_from(intrusive_ptr<actor>&)
* Support for rvalue references.
*/
void
unlink_from
(
intrusive_ptr
<
actor
>&&
other
);
/**
* @copydoc remove_backlink(intrusive_ptr<actor>&)
* Support for rvalue references.
*/
bool
remove_backlink
(
intrusive_ptr
<
actor
>&&
to
);
bool
remove_backlink
(
intrusive_ptr
<
actor
>&&
other
);
/**
* @copydoc establish_backlink(intrusive_ptr<actor>&)
* Support for rvalue references.
*/
bool
establish_backlink
(
intrusive_ptr
<
actor
>&&
to
);
bool
establish_backlink
(
intrusive_ptr
<
actor
>&&
other
);
/**
* @brief Gets the {@link process_information} of the parent process.
...
...
@@ -195,6 +195,11 @@ class actor : public channel
*/
inline
actor_id
id
()
const
;
/**
* @brief Checks if this actor is running on a remote node.
* @returns @c true if this actor represents a remote actor;
* otherwise @c false.
*/
inline
bool
is_proxy
()
const
;
};
...
...
cppa/actor_proxy.hpp
View file @
03b3b68b
...
...
@@ -36,9 +36,15 @@
namespace
cppa
{
#ifdef CPPA_DOCUMENTATION
/**
* @brief Represents a remote Actor.
*/
class
actor_proxy
:
public
actor
{
};
#else // CPPA_DOCUMENTATION
class
actor_proxy
:
public
abstract_actor
<
actor
>
{
...
...
@@ -65,6 +71,8 @@ class actor_proxy : public abstract_actor<actor>
};
#endif // CPPA_DOCUMENTATION
typedef
intrusive_ptr
<
actor_proxy
>
actor_proxy_ptr
;
}
// namespace cppa
...
...
cppa/any_tuple.hpp
View file @
03b3b68b
...
...
@@ -50,19 +50,42 @@ class any_tuple
public:
/**
* @brief Creates an empty tuple.
* @post <tt>empty() == true</tt>
*/
any_tuple
();
/**
* @brief Creates a tuple from @p t.
* @param t A typed tuple representation.
* @post <tt>empty() == false</tt>
*/
template
<
typename
...
Args
>
any_tuple
(
tuple
<
Args
...
>
const
&
t
)
:
m_vals
(
t
.
vals
())
{
}
explicit
any_tuple
(
detail
::
abstract_tuple
*
);
/**
* @brief Move constructor.
*/
any_tuple
(
any_tuple
&&
);
/**
* @brief Copy constructor.
*/
any_tuple
(
any_tuple
const
&
)
=
default
;
/**
* @brief Move assignment.
* @returns <tt>*this</tt>.
*/
any_tuple
&
operator
=
(
any_tuple
&&
);
/**
* @brief Copy assignment.
* @returns <tt>*this</tt>.
*/
any_tuple
&
operator
=
(
any_tuple
const
&
)
=
default
;
size_t
size
()
const
;
...
...
@@ -77,7 +100,7 @@ class any_tuple
bool
equals
(
any_tuple
const
&
other
)
const
;
any_tuple
tail
(
size_t
offset
=
1
)
const
;
std
::
type_info
const
&
impl_type
(
)
const
;
inline
bool
empty
()
const
{
...
...
cppa/any_tuple_view.hpp
View file @
03b3b68b
...
...
@@ -45,6 +45,7 @@
#include "cppa/util/is_primitive.hpp"
#include "cppa/detail/types_array.hpp"
#include "cppa/detail/object_array.hpp"
namespace
cppa
{
...
...
@@ -147,6 +148,13 @@ class any_tuple_view
return
*
reinterpret_cast
<
T
const
*>
(
at
(
p
));
}
inline
std
::
type_info
const
&
impl_type
()
const
{
// this is a lie, but the pattern matching implementation
// needs to do a full runtime check of each element
return
typeid
(
detail
::
object_array
);
}
class
const_iterator
{
typedef
typename
vector_type
::
const_iterator
vec_iterator
;
...
...
cppa/anything.hpp
View file @
03b3b68b
...
...
@@ -34,7 +34,7 @@
namespace
cppa
{
/**
* @brief Acts as wildcard
pattern
.
* @brief Acts as wildcard
expression in patterns
.
*/
struct
anything
{
};
...
...
cppa/attachable.hpp
View file @
03b3b68b
...
...
@@ -51,9 +51,18 @@ class attachable
public:
/**
* @brief Represents a pointer to a value with its RTTI.
*/
struct
token
{
/**
* @brief Denotes the type of @c ptr.
*/
std
::
type_info
const
&
subtype
;
/**
* @brief Any value, used to identify @c attachable instances.
*/
void
const
*
ptr
;
inline
token
(
std
::
type_info
const
&
msubtype
,
void
const
*
mptr
)
:
subtype
(
msubtype
),
ptr
(
mptr
)
...
...
@@ -64,14 +73,19 @@ class attachable
virtual
~
attachable
();
/**
* @brief Executed if the actor finished execution
* with given @p reason.
* @brief Executed if the actor finished execution with given @p reason.
*
* The default implementation does nothing.
* @param reason The exit rason of the observed actor.
*/
virtual
void
actor_exited
(
std
::
uint32_t
reason
)
=
0
;
virtual
bool
matches
(
token
const
&
)
=
0
;
/**
* @brief Selects a group of @c attachable instances by @p what.
* @param what A value that selects zero or more @c attachable instances.
* @returns @c true if @p what selects this instance; otherwise @c false.
*/
virtual
bool
matches
(
token
const
&
what
)
=
0
;
};
...
...
cppa/cppa.hpp
View file @
03b3b68b
...
...
@@ -205,7 +205,7 @@
*
* @section Receive Receive messages
*
* The function @p receive takes a @
i
behavior as argument. The behavior
* The function @p receive takes a @
p
behavior as argument. The behavior
* is a list of { pattern >> callback } rules.
*
* @code
...
...
@@ -377,46 +377,34 @@
namespace
cppa
{
/**
* @brief Links the calling actor to @p other.
* @param other An Actor that is related with the calling Actor.
*/
void
link
(
actor_ptr
&
other
);
/**
* @copydoc link(actor_ptr&)
* Support for rvalue references.
*/
void
link
(
actor_ptr
&&
other
);
/**
* @brief Links @p lhs and @p rhs;
* @param lhs
First Actor instance
.
* @param rhs
Second Actor instance
.
* @param lhs
Left-hand operand
.
* @param rhs
Right-hand operand
.
* @pre <tt>lhs != rhs</tt>
*/
void
link
(
actor_ptr
&
lhs
,
actor_ptr
&
rhs
);
/**
* @copydoc link(actor_ptr&,actor_ptr&)
* Support for rvalue references.
*/
void
link
(
actor_ptr
&&
lhs
,
actor_ptr
&
rhs
);
/**
* @copydoc link(actor_ptr&,actor_ptr&)
* Support for rvalue references.
*/
void
link
(
actor_ptr
&&
lhs
,
actor_ptr
&&
rhs
);
/**
* @copydoc link(actor_ptr&,actor_ptr&)
* Support for rvalue references.
*/
void
link
(
actor_ptr
&
lhs
,
actor_ptr
&&
rhs
);
/**
* @brief Unlinks @p lhs and @p rhs;
* @brief Unlinks @p lhs from @p rhs;
* @param lhs Left-hand operand.
* @param rhs Right-hand operand.
* @pre <tt>lhs != rhs</tt>
*/
void
unlink
(
actor_ptr
&
lhs
,
actor_ptr
&
rhs
);
...
...
@@ -430,7 +418,6 @@ void monitor(actor_ptr& whom);
/**
* @copydoc monitor(actor_ptr&)
* Support for rvalue references.
*/
void
monitor
(
actor_ptr
&&
whom
);
...
...
@@ -440,29 +427,6 @@ void monitor(actor_ptr&& whom);
*/
void
demonitor
(
actor_ptr
&
whom
);
/**
* @brief Gets the @c trap_exit state of the calling Actor.
* @returns @c true if the Actor explicitly handles Exit messages;
* @c false if the Actor uses the default behavior (finish execution
* if an Exit message with non-normal exit reason was received).
*/
inline
bool
trap_exit
()
{
return
self
->
trap_exit
();
}
/**
* @brief Sets the @c trap_exit state of the calling Actor.
* @param new_value Set this to @c true if you want to explicitly handle Exit
* messages. The default is @c false, causing an Actor to
* finish execution if an Exit message with non-normal
* exit reason was received.
*/
inline
void
trap_exit
(
bool
new_value
)
{
self
->
trap_exit
(
new_value
);
}
inline
actor_ptr
spawn
(
scheduled_actor
*
what
)
{
return
get_scheduler
()
->
spawn
(
what
,
scheduled
);
...
...
@@ -481,7 +445,7 @@ inline actor_ptr spawn(abstract_event_based_actor* what)
/**
* @brief Spawns a new actor that executes @p what with given arguments.
* @param Hint Hint to the scheduler for the best scheduling strategy.
* @
t
param Hint Hint to the scheduler for the best scheduling strategy.
* @param what Function or functor that the spawned Actor should execute.
* @param args Arguments needed to invoke @p what.
* @returns A pointer to the newly created {@link actor Actor}.
...
...
@@ -515,34 +479,6 @@ spawn(F&& what, Args const&... args)
return
spawn
<
scheduled
>
(
std
::
forward
<
F
>
(
what
),
args
...);
}
/**
* @copydoc local_actor::quit()
*
* Alias for <tt>self->quit(reason);</tt>
*/
inline
void
quit
(
std
::
uint32_t
reason
)
{
self
->
quit
(
reason
);
}
/**
* @brief Gets the last dequeued message from the mailbox.
* @returns The last dequeued message from the mailbox.
*/
inline
any_tuple
&
last_received
()
{
return
self
->
last_dequeued
();
}
/**
* @brief Gets the sender of the last received message.
* @returns An {@link actor_ptr} to the sender of the last received message.
*/
inline
actor_ptr
&
last_sender
()
{
return
self
->
last_sender
();
}
#ifdef CPPA_DOCUMENTATION
/**
...
...
@@ -634,7 +570,7 @@ self_type const& operator<<(self_type const& s, any_tuple const& what);
self_type
const
&
operator
<<
(
self_type
const
&
s
,
any_tuple
&&
what
);
#endif
#endif
// CPPA_DOCUMENTATION
template
<
typename
Arg0
,
typename
...
Args
>
void
reply
(
Arg0
const
&
arg0
,
Args
const
&
...
args
)
...
...
@@ -677,7 +613,6 @@ void publish(actor_ptr& whom, std::uint16_t port);
/**
* @copydoc publish(actor_ptr&,std::uint16_t)
* Support for rvalue references.
*/
void
publish
(
actor_ptr
&&
whom
,
std
::
uint16_t
port
);
...
...
cppa/detail/abstract_tuple.hpp
View file @
03b3b68b
...
...
@@ -32,6 +32,7 @@
#define ABSTRACT_TUPLE_HPP
#include "cppa/ref_counted.hpp"
#include "cppa/type_value_pair.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/util/type_list.hpp"
...
...
@@ -41,6 +42,8 @@ namespace cppa { namespace detail {
struct
abstract_tuple
:
ref_counted
{
typedef
type_value_pair
const
*
const_iterator
;
// mutators
virtual
void
*
mutable_at
(
size_t
pos
)
=
0
;
...
...
@@ -49,8 +52,10 @@ struct abstract_tuple : ref_counted
virtual
abstract_tuple
*
copy
()
const
=
0
;
virtual
void
const
*
at
(
size_t
pos
)
const
=
0
;
virtual
uniform_type_info
const
*
type_at
(
size_t
pos
)
const
=
0
;
// type of the implementation class
virtual
std
::
type_info
const
&
impl_type
()
const
=
0
;
virtual
bool
equals
(
abstract_tuple
const
&
other
)
const
;
bool
equals
(
abstract_tuple
const
&
other
)
const
;
};
...
...
cppa/detail/decorated_tuple.hpp
View file @
03b3b68b
...
...
@@ -45,13 +45,13 @@
namespace
cppa
{
namespace
detail
{
template
<
size_t
VectorSize
>
template
<
typename
...
ElementTypes
>
class
decorated_tuple
:
public
abstract_tuple
{
public:
typedef
util
::
fixed_vector
<
size_t
,
VectorSize
>
vector_type
;
typedef
util
::
fixed_vector
<
size_t
,
sizeof
...(
ElementTypes
)
>
vector_type
;
typedef
cow_ptr
<
abstract_tuple
>
ptr_type
;
...
...
@@ -95,6 +95,12 @@ class decorated_tuple : public abstract_tuple
return
false
;
}
virtual
std
::
type_info
const
&
impl_type
()
const
{
return
typeid
(
decorated_tuple
);
}
private:
ptr_type
m_decorated
;
...
...
@@ -111,6 +117,15 @@ class decorated_tuple : public abstract_tuple
};
template
<
typename
TypeList
>
struct
decorated_tuple_from_type_list
;
template
<
typename
...
Types
>
struct
decorated_tuple_from_type_list
<
util
::
type_list
<
Types
...
>
>
{
typedef
decorated_tuple
<
Types
...
>
type
;
};
}
}
// namespace cppa::detail
#endif // DECORATED_TUPLE_HPP
cppa/detail/empty_tuple.hpp
View file @
03b3b68b
...
...
@@ -44,6 +44,7 @@ struct empty_tuple : cppa::detail::abstract_tuple
void
const
*
at
(
size_t
)
const
;
bool
equals
(
abstract_tuple
const
&
other
)
const
;
uniform_type_info
const
*
type_at
(
size_t
)
const
;
std
::
type_info
const
&
impl_type
()
const
;
};
...
...
cppa/detail/invokable.hpp
View file @
03b3b68b
...
...
@@ -197,7 +197,7 @@ class invokable_impl<0, Fun, Tuple, Pattern> : public invokable
template
<
typename
T
>
bool
invoke_impl
(
T
const
&
data
)
const
{
if
(
detail
::
matches
(
data
.
begin
(),
m_pattern
->
begin
()
))
if
(
matches
(
data
,
*
m_pattern
))
{
m_iimpl
.
m_fun
();
return
true
;
...
...
@@ -225,8 +225,7 @@ class invokable_impl<0, Fun, Tuple, Pattern> : public invokable
intermediate
*
get_intermediate
(
any_tuple
const
&
data
)
{
return
detail
::
matches
(
data
.
begin
(),
m_pattern
->
begin
())
?
&
m_iimpl
:
nullptr
;
return
matches
(
data
,
*
m_pattern
)
?
&
m_iimpl
:
nullptr
;
}
};
...
...
cppa/detail/matches.hpp
View file @
03b3b68b
...
...
@@ -31,9 +31,15 @@
#ifndef DO_MATCH_HPP
#define DO_MATCH_HPP
#include <type_traits>
#include "cppa/pattern.hpp"
#include "cppa/util/enable_if.hpp"
#include "cppa/util/fixed_vector.hpp"
#include "cppa/detail/tuple_vals.hpp"
#include "cppa/detail/types_array.hpp"
#include "cppa/detail/object_array.hpp"
#include "cppa/detail/decorated_tuple.hpp"
namespace
cppa
{
namespace
detail
{
...
...
@@ -153,20 +159,20 @@ class is_pm_decorated
};
template
<
class
TupleIterator
,
class
PatternIterator
>
auto
matches
(
TupleIterator
targ
,
PatternIterator
iter
)
auto
matches
(
TupleIterator
targ
,
PatternIterator
pbegin
,
PatternIterator
pend
)
->
typename
util
::
enable_if_c
<
is_pm_decorated
<
TupleIterator
>::
value
,
bool
>::
type
{
for
(
;
!
(
iter
.
at_end
()
&&
targ
.
at_end
());
iter
.
next
()
,
targ
.
next
())
for
(
;
!
(
pbegin
==
pend
&&
targ
.
at_end
());
++
pbegin
,
targ
.
next
())
{
if
(
iter
.
at_end
()
)
if
(
pbegin
==
pend
)
{
return
false
;
}
else
if
(
iter
.
type
()
==
nullptr
)
// nullptr == wildcard (anything)
else
if
(
pbegin
->
first
==
nullptr
)
// nullptr == wildcard (anything)
{
// perform submatching
iter
.
next
()
;
if
(
iter
.
at_end
()
)
++
pbegin
;
if
(
pbegin
==
pend
)
{
// always true at the end of the pattern
return
true
;
...
...
@@ -176,7 +182,7 @@ auto matches(TupleIterator targ, PatternIterator iter)
// iterate over tu_args until we found a match
for
(
;
targ
.
at_end
()
==
false
;
mv
.
clear
(),
targ
.
next
())
{
if
(
matches
(
TupleIterator
(
targ
,
mv_ptr
),
iter
))
if
(
matches
(
TupleIterator
(
targ
,
mv_ptr
),
pbegin
,
pend
))
{
targ
.
push_mapping
(
mv
);
return
true
;
...
...
@@ -185,11 +191,11 @@ auto matches(TupleIterator targ, PatternIterator iter)
return
false
;
// no submatch found
}
// compare types
else
if
(
targ
.
at_end
()
==
false
&&
iter
.
type
()
==
targ
.
type
())
else
if
(
targ
.
at_end
()
==
false
&&
pbegin
->
first
==
targ
.
type
())
{
// compare values if needed
if
(
iter
.
has_value
()
==
false
||
iter
.
type
()
->
equals
(
iter
.
value
()
,
targ
.
value
()))
if
(
pbegin
->
second
==
nullptr
||
pbegin
->
first
->
equals
(
pbegin
->
second
,
targ
.
value
()))
{
targ
.
push_mapping
();
}
...
...
@@ -203,24 +209,24 @@ auto matches(TupleIterator targ, PatternIterator iter)
return
false
;
// no match
}
}
return
true
;
//
iter.at_end()
&& targ.at_end()
return
true
;
//
pbegin == pend
&& targ.at_end()
}
template
<
class
TupleIterator
,
class
PatternIterator
>
auto
matches
(
TupleIterator
targ
,
PatternIterator
iter
)
auto
matches
(
TupleIterator
targ
,
PatternIterator
pbegin
,
PatternIterator
pend
)
->
typename
util
::
enable_if_c
<!
is_pm_decorated
<
TupleIterator
>::
value
,
bool
>::
type
{
for
(
;
!
(
iter
.
at_end
()
&&
targ
.
at_end
());
iter
.
next
()
,
targ
.
next
())
for
(
;
!
(
pbegin
==
pend
&&
targ
.
at_end
());
++
pbegin
,
targ
.
next
())
{
if
(
iter
.
at_end
()
)
if
(
pbegin
==
pend
)
{
return
false
;
}
else
if
(
iter
.
type
()
==
nullptr
)
// nullptr == wildcard (anything)
else
if
(
pbegin
->
first
==
nullptr
)
// nullptr == wildcard (anything)
{
// perform submatching
iter
.
next
()
;
if
(
iter
.
at_end
()
)
++
pbegin
;
if
(
pbegin
==
pend
)
{
// always true at the end of the pattern
return
true
;
...
...
@@ -228,7 +234,7 @@ auto matches(TupleIterator targ, PatternIterator iter)
// iterate over tu_args until we found a match
for
(
;
targ
.
at_end
()
==
false
;
targ
.
next
())
{
if
(
matches
(
targ
,
iter
))
if
(
matches
(
targ
,
pbegin
,
pend
))
{
return
true
;
}
...
...
@@ -236,25 +242,145 @@ auto matches(TupleIterator targ, PatternIterator iter)
return
false
;
// no submatch found
}
// compare types
else
if
(
targ
.
at_end
()
==
false
&&
iter
.
type
()
==
targ
.
type
())
else
if
(
targ
.
at_end
()
==
false
&&
pbegin
->
first
==
targ
.
type
())
{
// compare values if needed
if
(
iter
.
has_value
()
==
false
||
iter
.
type
()
->
equals
(
iter
.
value
()
,
targ
.
value
()))
if
(
pbegin
->
second
!=
nullptr
&&
!
pbegin
->
first
->
equals
(
pbegin
->
second
,
targ
.
value
()))
{
// ok, match next
return
false
;
// values didn't match
}
}
else
{
return
false
;
// values didn't match
return
false
;
// no match
}
}
return
true
;
// pbegin == pend && targ.at_end()
}
// pattern does not contain "anything"
template
<
class
Tuple
,
class
Pattern
>
bool
matches
(
std
::
integral_constant
<
int
,
0
>
,
Tuple
const
&
tpl
,
Pattern
const
&
pttrn
,
util
::
fixed_vector
<
size_t
,
Pattern
::
filtered_size
>*
mv
)
{
typedef
typename
Pattern
::
types
ptypes
;
typedef
typename
decorated_tuple_from_type_list
<
ptypes
>::
type
dec_t
;
typedef
typename
tuple_vals_from_type_list
<
ptypes
>::
type
tv_t
;
std
::
type_info
const
&
tinfo
=
tpl
.
impl_type
();
if
(
tinfo
==
typeid
(
dec_t
)
||
tinfo
==
typeid
(
tv_t
))
{
if
(
pttrn
.
has_values
())
{
size_t
i
=
0
;
auto
end
=
pttrn
.
end
();
for
(
auto
iter
=
pttrn
.
begin
();
iter
!=
end
;
++
iter
)
{
if
(
iter
->
second
)
{
if
(
iter
->
first
->
equals
(
iter
->
second
,
tpl
.
at
(
i
))
==
false
)
{
return
false
;
}
}
++
i
;
}
}
}
else
if
(
tinfo
==
typeid
(
object_array
))
{
if
(
pttrn
.
has_values
())
{
size_t
i
=
0
;
auto
end
=
pttrn
.
end
();
for
(
auto
iter
=
pttrn
.
begin
();
iter
!=
end
;
++
iter
,
++
i
)
{
if
(
iter
->
first
!=
tpl
.
type_at
(
i
))
return
false
;
if
(
iter
->
second
)
{
if
(
iter
->
first
->
equals
(
iter
->
second
,
tpl
.
at
(
i
))
==
false
)
return
false
;
}
}
}
else
{
return
false
;
// no match
size_t
i
=
0
;
auto
end
=
pttrn
.
end
();
for
(
auto
iter
=
pttrn
.
begin
();
iter
!=
end
;
++
iter
,
++
i
)
{
if
(
iter
->
first
!=
tpl
.
type_at
(
i
))
return
false
;
}
}
return
true
;
// iter.at_end() && targ.at_end()
}
else
{
return
false
;
}
// ok => match
if
(
mv
)
for
(
size_t
i
=
0
;
i
<
Pattern
::
size
;
++
i
)
mv
->
push_back
(
i
);
return
true
;
}
// "anything" at end of pattern
template
<
class
Tuple
,
class
Pattern
>
bool
matches
(
std
::
integral_constant
<
int
,
1
>
,
Tuple
const
&
tpl
,
Pattern
const
&
pttrn
,
util
::
fixed_vector
<
size_t
,
Pattern
::
filtered_size
>*
mv
)
{
auto
end
=
pttrn
.
end
();
--
end
;
// iterate until we reach "anything"
size_t
i
=
0
;
if
(
pttrn
.
has_values
())
{
for
(
auto
iter
=
pttrn
.
begin
();
iter
!=
end
;
++
iter
,
++
i
)
{
if
(
iter
->
first
!=
tpl
.
type_at
(
i
))
return
false
;
if
(
iter
->
second
)
{
if
(
iter
->
first
->
equals
(
iter
->
second
,
tpl
.
at
(
i
))
==
false
)
return
false
;
}
}
}
else
{
for
(
auto
iter
=
pttrn
.
begin
();
iter
!=
end
;
++
iter
,
++
i
)
{
if
(
iter
->
first
!=
tpl
.
type_at
(
i
))
return
false
;
}
}
// ok => match
if
(
mv
)
for
(
size_t
i
=
0
;
i
<
Pattern
::
size
;
++
i
)
mv
->
push_back
(
i
);
return
true
;
}
// "anything" somewhere in between (ugh!)
template
<
class
Tuple
,
class
Pattern
>
bool
matches
(
std
::
integral_constant
<
int
,
2
>
,
Tuple
const
&
tpl
,
Pattern
const
&
ptrn
,
util
::
fixed_vector
<
size_t
,
Pattern
::
filtered_size
>*
mv
=
0
)
{
if
(
mv
)
return
matches
(
pm_decorated
(
tpl
.
begin
(),
mv
),
ptrn
.
begin
(),
ptrn
.
end
());
return
matches
(
tpl
.
begin
(),
ptrn
.
begin
(),
ptrn
.
end
());
}
template
<
class
Tuple
,
class
Pattern
>
inline
bool
matches
(
Tuple
const
&
tpl
,
Pattern
const
&
pttrn
,
util
::
fixed_vector
<
size_t
,
Pattern
::
filtered_size
>*
mv
=
0
)
{
typedef
typename
Pattern
::
types
ptypes
;
static
constexpr
int
first_anything
=
util
::
tl_find
<
ptypes
,
anything
>::
value
;
// impl1 = no anything
// impl2 = anything at end
// impl3 = anything somewhere in between
static
constexpr
int
impl
=
(
first_anything
==
-
1
)
?
0
:
((
first_anything
==
((
int
)
Pattern
::
size
)
-
1
)
?
1
:
2
);
static
constexpr
std
::
integral_constant
<
int
,
impl
>
token
;
return
matches
(
token
,
tpl
,
pttrn
,
mv
);
}
}
}
// namespace cppa::detail
...
...
cppa/detail/object_array.hpp
View file @
03b3b68b
...
...
@@ -70,6 +70,8 @@ class object_array : public detail::abstract_tuple
uniform_type_info
const
*
type_at
(
size_t
pos
)
const
;
std
::
type_info
const
&
impl_type
()
const
;
};
}
}
// namespace cppa::detail
...
...
cppa/detail/tdata.hpp
View file @
03b3b68b
...
...
@@ -34,6 +34,7 @@
#include <typeinfo>
#include "cppa/get.hpp"
#include "cppa/option.hpp"
#include "cppa/util/at.hpp"
#include "cppa/util/wrapped.hpp"
...
...
@@ -145,23 +146,69 @@ struct tdata<Head, Tail...> : tdata<Tail...>
return
*
this
;
}
inline
tdata
<
Tail
...
>&
tail
()
{
// upcast
return
*
this
;
inline
tdata
<
Tail
...
>&
tail
()
{
return
*
this
;
}
inline
tdata
<
Tail
...
>
const
&
tail
()
const
{
return
*
this
;
}
inline
void
const
*
at
(
size_t
p
)
const
{
return
(
p
==
0
)
?
&
head
:
super
::
at
(
p
-
1
);
}
inline
tdata
<
Tail
...
>
const
&
tail
()
const
inline
uniform_type_info
const
*
type_at
(
size_t
p
)
const
{
return
(
p
==
0
)
?
uniform_typeid
(
typeid
(
Head
))
:
super
::
type_at
(
p
-
1
);
}
};
template
<
typename
Head
,
typename
...
Tail
>
struct
tdata
<
option
<
Head
>
,
Tail
...
>
:
tdata
<
Tail
...
>
{
typedef
tdata
<
Tail
...
>
super
;
option
<
Head
>
head
;
typedef
option
<
Head
>
opt_type
;
inline
tdata
()
:
super
(),
head
()
{
}
template
<
typename
...
Args
>
tdata
(
Head
const
&
v0
,
Args
const
&
...
vals
)
:
super
(
vals
...),
head
(
v0
)
{
}
template
<
typename
...
Args
>
tdata
(
Head
&&
v0
,
Args
const
&
...
vals
)
:
super
(
vals
...),
head
(
std
::
move
(
v0
))
{
}
template
<
typename
...
Args
>
tdata
(
util
::
wrapped
<
Head
>
const
&
,
Args
const
&
...
vals
)
:
super
(
vals
...)
{
}
// allow (partial) initialization from a different tdata
template
<
typename
...
Y
>
tdata
(
tdata
<
Y
...
>
const
&
other
)
:
super
(
other
.
tail
()),
head
(
other
.
head
)
{
}
template
<
typename
...
Y
>
tdata
(
tdata
<
Y
...
>&&
other
)
:
super
(
std
::
move
(
other
.
tail
())),
head
(
std
::
move
(
other
.
head
))
{
}
// allow initialization with a function pointer or reference
// returning a wrapped<Head>
template
<
typename
...
Args
>
tdata
(
util
::
wrapped
<
Head
>
(
*
)(),
Args
const
&
...
vals
)
:
super
(
vals
...),
head
()
{
// upcast
return
*
this
;
}
inline
bool
operator
==
(
tdata
const
&
other
)
const
template
<
typename
...
Y
>
tdata
&
operator
=
(
tdata
<
Y
...
>
const
&
other
)
{
return
head
==
other
.
head
&&
tail
()
==
other
.
tail
();
tdata_set
(
*
this
,
other
);
return
*
this
;
}
// upcast
inline
tdata
<
Tail
...
>&
tail
()
{
return
*
this
;
}
inline
tdata
<
Tail
...
>
const
&
tail
()
const
{
return
*
this
;
}
inline
void
const
*
at
(
size_t
p
)
const
{
return
(
p
==
0
)
?
&
head
:
super
::
at
(
p
-
1
);
...
...
cppa/detail/tuple_vals.hpp
View file @
03b3b68b
...
...
@@ -116,11 +116,25 @@ class tuple_vals : public abstract_tuple
return
abstract_tuple
::
equals
(
other
);
}
std
::
type_info
const
&
impl_type
()
const
{
return
typeid
(
tuple_vals
);
}
};
template
<
typename
...
ElementTypes
>
types_array
<
ElementTypes
...
>
tuple_vals
<
ElementTypes
...
>::
m_types
;
template
<
typename
TypeList
>
struct
tuple_vals_from_type_list
;
template
<
typename
...
Types
>
struct
tuple_vals_from_type_list
<
util
::
type_list
<
Types
...
>
>
{
typedef
tuple_vals
<
Types
...
>
type
;
};
}
}
// namespace cppa::detail
#endif // TUPLE_VALS_HPP
cppa/detail/types_array.hpp
View file @
03b3b68b
...
...
@@ -3,6 +3,9 @@
#include <typeinfo>
#include "cppa/type_value_pair.hpp"
#include "cppa/util/tbind.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/is_builtin.hpp"
...
...
@@ -57,27 +60,39 @@ struct ta_util<cppa_tinf, false, T>
template
<
bool
BuiltinOnlyTypes
,
typename
...
T
>
struct
types_array_impl
{
static
constexpr
bool
builtin_only
=
true
;
// all types are builtin, perform lookup on constuction
uniform_type_info
const
*
data
[
sizeof
...(
T
)];
type_value_pair
pairs
[
sizeof
...(
T
)];
types_array_impl
()
:
data
{
ta_util
<
cppa_tinf
,
util
::
is_builtin
<
T
>::
value
,
T
>::
get
()...}
{
for
(
size_t
i
=
0
;
i
<
sizeof
...(
T
);
++
i
)
{
pairs
[
i
].
first
=
data
[
i
];
pairs
[
i
].
second
=
nullptr
;
}
}
inline
size_t
size
()
const
{
return
sizeof
...(
T
);
}
inline
uniform_type_info
const
*
operator
[](
size_t
p
)
const
{
return
data
[
p
];
}
typedef
type_value_pair
const
*
const_iterator
;
inline
const_iterator
begin
()
const
{
return
pairs
;
}
inline
const_iterator
end
()
const
{
return
pairs
+
sizeof
...(
T
);
}
};
template
<
typename
...
T
>
struct
types_array_impl
<
false
,
T
...
>
{
static
constexpr
bool
builtin_only
=
false
;
// contains std::type_info for all non-builtin types
std
::
type_info
const
*
tinfo_data
[
sizeof
...(
T
)];
// contains uniform_type_infos for builtin types and lazy initializes
// non-builtin types at runtime
mutable
std
::
atomic
<
uniform_type_info
const
*>
data
[
sizeof
...(
T
)];
mutable
std
::
atomic
<
type_value_pair
const
*>
pairs
;
// pairs[sizeof...(T)];
types_array_impl
()
:
tinfo_data
{
ta_util
<
std_tinf
,
util
::
is_builtin
<
T
>::
value
,
T
>::
get
()...}
{
...
...
@@ -92,7 +107,6 @@ struct types_array_impl<false, T...>
}
}
}
inline
size_t
size
()
const
{
return
sizeof
...(
T
);
}
inline
uniform_type_info
const
*
operator
[](
size_t
p
)
const
{
auto
result
=
data
[
p
].
load
();
...
...
@@ -107,41 +121,48 @@ struct types_array_impl<false, T...>
}
return
result
;
}
typedef
type_value_pair
const
*
const_iterator
;
inline
const_iterator
begin
()
const
{
auto
result
=
pairs
.
load
();
if
(
result
==
nullptr
)
{
auto
parr
=
new
type_value_pair
[
sizeof
...(
T
)];
for
(
size_t
i
=
0
;
i
<
sizeof
...(
T
);
++
i
)
{
parr
[
i
].
first
=
(
*
this
)[
i
];
parr
[
i
].
second
=
nullptr
;
}
if
(
!
pairs
.
compare_exchange_weak
(
result
,
parr
,
std
::
memory_order_relaxed
))
{
delete
[]
parr
;
}
else
{
result
=
parr
;
}
}
return
result
;
}
inline
const_iterator
end
()
const
{
return
begin
()
+
sizeof
...(
T
);
}
};
// a container for uniform_type_information singletons with optimization
// for builtin types; can act as pattern
template
<
typename
...
T
>
struct
types_array
:
types_array_impl
<
util
::
tl_forall
<
util
::
type_list
<
T
...
>
,
util
::
is_builtin
>::
value
,
T
...
>
{
class
const_iterator
{
types_array
const
&
m_ref
;
size_t
m_pos
;
public:
const_iterator
(
const_iterator
const
&
)
=
default
;
const_iterator
&
operator
=
(
const_iterator
const
&
)
=
default
;
const_iterator
(
types_array
const
&
ptr
)
:
m_ref
(
ptr
),
m_pos
(
0
)
{
}
inline
void
next
()
{
++
m_pos
;
}
inline
bool
at_end
()
const
{
return
m_pos
==
sizeof
...(
T
);
}
inline
uniform_type_info
const
*
type
()
const
{
return
m_ref
[
m_pos
];
}
inline
bool
has_value
()
const
{
return
false
;
}
inline
void
const
*
value
()
const
{
return
nullptr
;
}
};
const_iterator
begin
()
const
{
return
{
*
this
};
}
static
constexpr
size_t
size
=
sizeof
...(
T
);
typedef
util
::
type_list
<
T
...
>
types
;
typedef
typename
util
::
tl_filter_not
<
types
,
util
::
tbind
<
std
::
is_same
,
anything
>::
type
>::
type
filtered_types
;
static
constexpr
size_t
filtered_size
=
filtered_types
::
size
;
inline
bool
has_values
()
const
{
return
false
;
}
};
template
<
typename
...
T
>
...
...
@@ -153,6 +174,15 @@ struct static_types_array
template
<
typename
...
T
>
types_array
<
T
...
>
static_types_array
<
T
...
>::
arr
;
template
<
typename
TypeList
>
struct
static_types_array_from_type_list
;
template
<
typename
...
T
>
struct
static_types_array_from_type_list
<
util
::
type_list
<
T
...
>>
{
typedef
static_types_array
<
T
...
>
type
;
};
}
}
// namespace cppa::detail
#endif // TYPES_ARRAY_HPP
cppa/pattern.hpp
View file @
03b3b68b
...
...
@@ -40,6 +40,7 @@
#include "cppa/anything.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/tuple_view.hpp"
#include "cppa/type_value_pair.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/util/tbind.hpp"
...
...
@@ -47,6 +48,7 @@
#include "cppa/util/arg_match_t.hpp"
#include "cppa/util/fixed_vector.hpp"
#include "cppa/util/is_primitive.hpp"
#include "cppa/util/static_foreach.hpp"
#include "cppa/detail/boxed.hpp"
#include "cppa/detail/tdata.hpp"
...
...
@@ -78,51 +80,23 @@ class pattern
typedef
typename
util
::
tl_filter_not
<
types
,
util
::
tbind
<
std
::
is_same
,
anything
>::
type
>::
type
filtered_types
;
typedef
util
::
fixed_vector
<
size_t
,
filtered_types
::
size
>
mapping_vector
;
class
const_iterator
{
pattern
const
*
m_ptr
;
size_t
m_pos
;
public:
const_iterator
(
const_iterator
const
&
)
=
default
;
const_iterator
&
operator
=
(
const_iterator
const
&
)
=
default
;
const_iterator
(
pattern
const
*
ptr
)
:
m_ptr
(
ptr
),
m_pos
(
0
)
{
}
inline
void
next
()
{
++
m_pos
;
}
inline
bool
at_end
()
{
return
m_pos
==
sizeof
...(
Types
);
}
static
constexpr
size_t
filtered_size
=
filtered_types
::
size
;
inline
uniform_type_info
const
*
type
()
const
{
return
m_ptr
->
m_utis
[
m_pos
];
}
inline
bool
has_value
()
const
{
return
m_ptr
->
m_data_ptr
[
m_pos
]
!=
nullptr
;
}
typedef
util
::
fixed_vector
<
size_t
,
filtered_types
::
size
>
mapping_vector
;
inline
void
const
*
value
()
const
{
return
m_ptr
->
m_data_ptr
[
m_pos
];
}
typedef
type_value_pair
const
*
const_iterator
;
};
const_iterator
begin
()
const
{
return
m_ptrs
;
}
const_iterator
begin
()
const
{
return
{
this
};
}
const_iterator
end
()
const
{
return
m_ptrs
+
size
;
}
pattern
()
pattern
()
:
m_has_values
(
false
)
{
auto
&
arr
=
detail
::
static_types_array
<
Types
...
>::
arr
;
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
{
m_data_ptr
[
i
]
=
nullptr
;
m_ptrs
[
i
].
first
=
arr
[
i
];
m_ptrs
[
i
].
second
=
nullptr
;
}
}
...
...
@@ -131,34 +105,55 @@ class pattern
{
using
std
::
is_same
;
using
namespace
util
;
static
constexpr
bool
all_boxed
=
util
::
tl_forall
<
type_list
<
Arg0
,
Args
...
>
,
detail
::
is_boxed
>::
value
;
m_has_values
=
!
all_boxed
;
typedef
typename
type_list
<
Arg0
,
Args
...
>::
back
arg_n
;
static
constexpr
bool
ignore_arg_n
=
is_same
<
arg_n
,
arg_match_t
>::
value
;
bool
invalid_args
[]
=
{
detail
::
is_boxed
<
Arg0
>::
value
,
detail
::
is_boxed
<
Args
>::
value
...
};
// ignore extra arg_match_t argument
static
constexpr
size_t
args_size
=
sizeof
...(
Args
)
+
(
ignore_arg_n
?
0
:
1
);
static_assert
(
args_size
<=
size
,
"too many arguments"
);
for
(
size_t
i
=
0
;
i
<
args_size
;
++
i
)
{
m_data_ptr
[
i
]
=
invalid_args
[
i
]
?
nullptr
:
m_data
.
at
(
i
);
}
auto
&
arr
=
detail
::
static_types_array
<
Types
...
>::
arr
;
functor
f
(
*
this
,
arr
);
util
::
static_foreach
<
0
,
args_size
>::
_
(
m_data
,
f
);
for
(
size_t
i
=
args_size
;
i
<
size
;
++
i
)
{
m_data_ptr
[
i
]
=
nullptr
;
m_ptrs
[
i
].
first
=
arr
[
i
];
m_ptrs
[
i
].
second
=
nullptr
;
}
}
inline
bool
has_values
()
const
{
return
m_has_values
;
}
private:
detail
::
tdata
<
Types
...
>
m_data
;
static
detail
::
types_array
<
Types
...
>
m_utis
;
void
const
*
m_data_ptr
[
size
];
struct
functor
;
}
;
friend
class
functor
;
template
<
typename
...
Types
>
detail
::
types_array
<
Types
...
>
pattern
<
Types
...
>::
m_utis
;
struct
functor
{
pattern
&
p
;
detail
::
types_array
<
Types
...
>&
arr
;
size_t
i
;
functor
(
pattern
&
pp
,
detail
::
types_array
<
Types
...
>&
tarr
)
:
p
(
pp
),
arr
(
tarr
),
i
(
0
)
{
}
template
<
typename
T
>
void
operator
()(
option
<
T
>
const
&
what
)
{
p
.
m_ptrs
[
i
].
first
=
arr
[
i
];
p
.
m_ptrs
[
i
].
second
=
(
what
)
?
&
(
*
what
)
:
nullptr
;
++
i
;
}
};
detail
::
tdata
<
option
<
Types
>
...
>
m_data
;
bool
m_has_values
;
type_value_pair
m_ptrs
[
size
];
};
template
<
class
ExtendedType
,
class
BasicType
>
ExtendedType
*
extend_pattern
(
BasicType
const
*
p
)
...
...
@@ -167,11 +162,19 @@ ExtendedType* extend_pattern(BasicType const* p)
detail
::
tdata_set
(
et
->
m_data
,
p
->
m_data
);
for
(
size_t
i
=
0
;
i
<
BasicType
::
size
;
++
i
)
{
if
(
p
->
m_data_ptr
[
i
]
!=
nullptr
)
et
->
m_ptrs
[
i
].
first
=
p
->
m_ptrs
[
i
].
first
;
if
(
p
->
m_ptrs
[
i
].
second
!=
nullptr
)
{
et
->
m_
data_ptr
[
i
]
=
et
->
m_data
.
at
(
i
);
et
->
m_
ptrs
[
i
].
second
=
et
->
m_data
.
at
(
i
);
}
}
typedef
typename
ExtendedType
::
types
extended_types
;
typedef
typename
detail
::
static_types_array_from_type_list
<
extended_types
>::
type
tarr
;
auto
&
arr
=
tarr
::
arr
;
for
(
auto
i
=
BasicType
::
size
;
i
<
ExtendedType
::
size
;
++
i
)
{
et
->
m_ptrs
[
i
].
first
=
arr
[
i
];
}
return
et
;
}
...
...
cppa/process_information.hpp
View file @
03b3b68b
...
...
@@ -52,34 +52,51 @@ class process_information : public ref_counted,
public:
/**
* @brief @c libcppa uses 160 bit hashes (20 bytes).
*/
static
constexpr
size_t
node_id_size
=
20
;
/**
* @brief Represents a 160 bit hash.
*/
typedef
std
::
array
<
std
::
uint8_t
,
node_id_size
>
node_id_type
;
//process_information();
process_information
(
std
::
uint32_t
process_id
,
node_id_type
const
&
node_id
);
/**
* @brief Copy constructor.
*/
process_information
(
process_information
const
&
);
/**
* @brief Creates @c this from @p process_id and @p hash.
* @param process_id System-wide unique process identifier.
* @param hash Unique node id as hexadecimal string representation.
*/
process_information
(
std
::
uint32_t
process_id
,
std
::
string
const
&
hash
);
process_information
(
process_information
const
&
other
);
/**
* @brief Creates @c this from @p process_id and @p hash.
* @param process_id System-wide unique process identifier.
* @param hash Unique node id.
*/
process_information
(
std
::
uint32_t
process_id
,
node_id_type
const
&
node_id
);
/**
* @brief Identifies the running process.
* @returns A system-wide unique process identifier.
*/
inline
std
::
uint32_t
process_id
()
const
{
return
m_process_id
;
}
/**
* @brief Identifies the host system.
*
* A hash build from the MAC address of the first network device
* and the serial number from the root HD (mounted in "/" or "C:").
* @returns A hash build from the MAC address of the first network device
* and the UUID of the root partition (mounted in "/" or "C:").
*/
inline
node_id_type
const
&
node_id
()
const
{
return
m_node_id
;
}
/**
* @brief Returns the proccess_information for the running process.
* @returns
* @returns
A pointer to the singleton of this process.
*/
static
intrusive_ptr
<
process_information
>
const
&
get
();
...
...
@@ -108,7 +125,10 @@ inline bool equal(process_information::node_id_type const& node_id,
std
::
string
to_string
(
process_information
const
&
what
);
/**
* @brief Converts {@link node_id} to an hexadecimal string.
* @brief Converts a {@link process_information::node_id_type node_id}
* to a hexadecimal string.
* @param node_id A unique node identifier.
* @returns A hexadecimal representation of @p node_id.
*/
std
::
string
to_string
(
process_information
::
node_id_type
const
&
node_id
);
...
...
cppa/receive.hpp
View file @
03b3b68b
...
...
@@ -38,18 +38,73 @@
namespace
cppa
{
#ifdef CPPA_DOCUMENTATION
/**
* @brief Dequeues the next message from the mailbox that's matched
* by @p bhvr and executes the corresponding callback.
* @param bhvr Denotes the actor's response the next incoming message.
*/
inline
void
receive
(
invoke_rules
&
bhvr
)
{
self
->
dequeue
(
bhvr
);
}
void
receive
(
behavior
&
bhvr
);
/**
* @brief Receives messages in an endless loop.
*
* Semantically equal to: <tt>for (;;) { receive(bhvr); }</tt>
* @param bhvr Denotes the actor's response the next incoming message.
*/
void
receive_loop
(
behavior
&
bhvr
);
/**
* @brief Receives messages as long as @p stmt returns true.
*
* Semantically equal to: <tt>while (stmt()) { receive(...); }</tt>.
*
* <b>Usage example:</b>
* @code
* int i = 0;
* receive_while([&]() { return (++i <= 10); })
* (
* on<int>() >> int_fun,
* on<float>() >> float_fun
* );
* @endcode
* @param stmt Lambda expression, functor or function returning a @c bool.
* @returns A functor implementing the loop.
*/
template
<
typename
Statement
>
auto
receive_while
(
Statement
&&
stmt
);
/**
* @brief Receives messages until @p stmt returns true.
*
* Semantically equal to: <tt>do { receive(...); } while (stmt() == false);</tt>
*
* <b>Usage example:</b>
* @code
* int i = 0;
* do_receive
* (
* on<int>() >> int_fun,
* on<float>() >> float_fun
* )
* .until([&]() { return (++i >= 10); };
* @endcode
* @param bhvr Denotes the actor's response the next incoming message.
* @returns A functor providing the @c until member function.
*/
auto
do_receive
(
behavior
&
bhvr
);
#else // CPPA_DOCUMENTATION
inline
void
receive
(
invoke_rules
&
bhvr
)
{
self
->
dequeue
(
bhvr
);
}
inline
void
receive
(
timed_invoke_rules
&
bhvr
)
{
self
->
dequeue
(
bhvr
);
}
inline
void
receive
(
timed_invoke_rules
&
bhvr
)
inline
void
receive
(
behavior
&
bhvr
)
{
self
->
dequeue
(
bhvr
);
if
(
bhvr
.
is_left
())
self
->
dequeue
(
bhvr
.
left
());
else
self
->
dequeue
(
bhvr
.
right
());
}
inline
void
receive
(
timed_invoke_rules
&&
bhvr
)
...
...
@@ -79,58 +134,29 @@ void receive(invoke_rules& bhvr, Head&& head, Tail&&... tail)
std
::
forward
<
Tail
>
(
tail
)...);
}
inline
void
receive
(
behavior
&
bhvr
)
{
if
(
bhvr
.
is_left
())
receive
(
bhvr
.
left
());
else
receive
(
bhvr
.
right
());
}
/**
* @brief Receives messages in an endless loop.
*
* Semantically equal to: <tt>for (;;) { receive(rules); }</tt>
* @param rules Invoke rules to receive and handle messages.
*/
void
receive_loop
(
invoke_rules
&
rules
);
/**
* @copydoc receive_loop(invoke_rules&)
* Support for invoke rules with timeout.
*/
void
receive_loop
(
timed_invoke_rules
&
rules
);
/**
* @copydoc receive_loop(invoke_rules&)
* Support for rvalue references.
*/
inline
void
receive_loop
(
behavior
&
bhvr
)
{
if
(
bhvr
.
is_left
())
receive_loop
(
bhvr
.
left
());
else
receive_loop
(
bhvr
.
right
());
}
inline
void
receive_loop
(
invoke_rules
&&
rules
)
{
invoke_rules
tmp
(
std
::
move
(
rules
));
receive_loop
(
tmp
);
}
/**
* @copydoc receive_loop(invoke_rules&)
* Support for rvalue references and timeout.
*/
inline
void
receive_loop
(
timed_invoke_rules
&&
rules
)
{
timed_invoke_rules
tmp
(
std
::
move
(
rules
));
receive_loop
(
tmp
);
}
/**
* @brief Receives messages in an endless loop.
*
* This function overload provides a simple way to define a receive loop
* with on-the-fly {@link invoke_rules}.
*
* @b Example:
* @code
* receive_loop(on<int>() >> int_fun, on<float>() >> float_fun);
* @endcode
* @see receive_loop(invoke_rules&)
*/
template
<
typename
Head
,
typename
...
Tail
>
void
receive_loop
(
invoke_rules
&
rules
,
Head
&&
head
,
Tail
&&
...
tail
)
{
...
...
@@ -138,20 +164,6 @@ void receive_loop(invoke_rules& rules, Head&& head, Tail&&... tail)
std
::
forward
<
Tail
>
(
tail
)...);
}
/**
* @brief Receives messages in an endless loop.
*
* This function overload provides a simple way to define a receive loop
* with on-the-fly {@link invoke_rules}.
*
* @b Example:
* @code
* receive_loop(on<int>() >> int_fun, on<float>() >> float_fun);
* @endcode
* @see receive_loop(invoke_rules&)
*
* Support for rvalue references.
*/
template
<
typename
Head
,
typename
...
Tail
>
void
receive_loop
(
invoke_rules
&&
rules
,
Head
&&
head
,
Tail
&&
...
tail
)
{
...
...
@@ -160,23 +172,6 @@ void receive_loop(invoke_rules&& rules, Head&& head, Tail&&... tail)
std
::
forward
<
Tail
>
(
tail
)...);
}
/**
* @brief Receives messages as long as @p stmt returns true.
*
* Semantically equal to: <tt>while (stmt()) { receive(...); }</tt>.
*
* <b>Usage example:</b>
* @code
* int i = 0;
* receive_while([&]() { return (++i <= 10); })
* (
* on<int>() >> int_fun,
* on<float>() >> float_fun
* );
* @endcode
* @param stmt Lambda expression, functor or function returning a @c bool.
* @returns A functor implementing the loop.
*/
template
<
typename
Statement
>
detail
::
receive_while_helper
<
Statement
>
receive_while
(
Statement
&&
stmt
)
...
...
@@ -186,30 +181,14 @@ receive_while(Statement&& stmt)
return
std
::
move
(
stmt
);
}
/**
* @brief Receives messages until @p stmt returns true.
*
* Semantically equal to: <tt>do { receive(...); } while (stmt() == false);</tt>
*
* <b>Usage example:</b>
* @code
* int i = 0;
* do_receive
* (
* on<int>() >> int_fun,
* on<float>() >> float_fun
* )
* .until([&]() { return (++i >= 10); };
* @endcode
* @param args Invoke rules to handle received messages.
* @returns A functor providing the @c until member function.
*/
template
<
typename
...
Args
>
detail
::
do_receive_helper
do_receive
(
Args
&&
...
args
)
{
return
detail
::
do_receive_helper
(
std
::
forward
<
Args
>
(
args
)...);
}
#endif // CPPA_DOCUMENTATION
}
// namespace cppa
#endif // RECEIVE_HPP
cppa/scheduled_actor.hpp
View file @
03b3b68b
...
...
@@ -33,13 +33,35 @@
namespace
cppa
{
/**
* @brief A base class for context-switching or thread-mapped actor
* implementations.
*
* This abstract class provides a class-based way to define context-switching
* or thread-mapped actors. In general,
* you always should use event-based actors. However, if you need to call
* blocking functions, or need to have your own thread for other reasons,
* this class can be used to define a class-based actor.
*/
class
scheduled_actor
{
public:
virtual
~
scheduled_actor
();
/**
* @brief Can be overridden to perform cleanup code after an actor
* finished execution.
* @warning Must not call any function manipulating the actor's state such
* as join, leave, link, or monitor.
*/
virtual
void
on_exit
();
/**
* @brief Implements the behavior of a context-switching or thread-mapped
* actor.
*/
virtual
void
act
()
=
0
;
};
...
...
cppa/scheduler.hpp
View file @
03b3b68b
...
...
@@ -112,7 +112,8 @@ class scheduler
Duration
const
&
rel_time
,
Data
const
&
...
data
)
{
static_assert
(
sizeof
...(
Data
)
>
0
,
"no message to send"
);
any_tuple
tup
=
make_tuple
(
util
::
duration
(
rel_time
),
to
,
data
...);
any_tuple
data_tup
=
make_tuple
(
data
...);
any_tuple
tup
=
make_tuple
(
util
::
duration
(
rel_time
),
to
,
data_tup
);
future_send_helper
()
->
enqueue
(
self
,
std
::
move
(
tup
));
}
...
...
cppa/scheduling_hint.hpp
View file @
03b3b68b
...
...
@@ -33,10 +33,23 @@
namespace
cppa
{
/**
* @brief Denotes whether a user wants an actor to take part in
* cooperative scheduling or not.
*/
enum
scheduling_hint
{
/**
* @brief Indicates that an actor takes part in cooperative scheduling.
*/
scheduled
,
/**
* @brief Indicates that an actor should run in its own thread.
*/
detached
};
}
// namespace cppa
...
...
cppa/self.hpp
View file @
03b3b68b
...
...
@@ -84,12 +84,6 @@ class self_type : public convertible<self_type, actor*>
return
get_impl
();
}
// backward compatibility
inline
local_actor
*
operator
()()
const
{
return
get_impl
();
}
// @pre get_unchecked() == nullptr
inline
void
set
(
local_actor
*
ptr
)
const
{
...
...
cppa/tuple.hpp
View file @
03b3b68b
...
...
@@ -86,6 +86,8 @@ class tuple
public:
typedef
util
::
type_list
<
ElementTypes
...
>
types
;
static
constexpr
size_t
num_elements
=
sizeof
...(
ElementTypes
);
/**
...
...
@@ -130,7 +132,7 @@ class tuple
util
::
fixed_vector
<
size_t
,
num_elements
>
const
&
mv
)
{
return
tuple
(
ptr_ctor
(),
new
detail
::
decorated_tuple
<
num_elements
>
(
ptr
,
mv
));
new
detail
::
decorated_tuple
<
ElementTypes
...
>
(
ptr
,
mv
));
}
/**
...
...
cppa/tuple_cast.hpp
View file @
03b3b68b
...
...
@@ -51,7 +51,7 @@ option<ResultTuple> tuple_cast_impl(Tuple const& tup, pattern<P...> const& p)
{
typedef
typename
pattern
<
P
...
>::
filtered_types
filtered_types
;
typename
pattern
<
P
...
>::
mapping_vector
mv
;
if
(
detail
::
matches
(
detail
::
pm_decorated
(
tup
.
begin
(),
&
mv
),
p
.
begin
()
))
if
(
detail
::
matches
(
tup
,
p
,
&
mv
))
{
if
(
mv
.
size
()
==
tup
.
size
())
// perfect match
{
...
...
@@ -59,7 +59,7 @@ option<ResultTuple> tuple_cast_impl(Tuple const& tup, pattern<P...> const& p)
}
else
{
typedef
detail
::
decorated_tuple
<
filtered_types
::
size
>
decorated
;
typedef
typename
detail
::
decorated_tuple_from_type_list
<
filtered_types
>::
type
decorated
;
return
{
ResultTuple
::
from
(
tup
.
vals
(),
mv
)};
}
}
...
...
@@ -87,11 +87,9 @@ option<ResultTuple> tuple_cast_impl(Tuple const& tup)
else
{
util
::
fixed_vector
<
size_t
,
ResultTuple
::
num_elements
>
mv
;
if
(
detail
::
matches
(
detail
::
pm_decorated
(
tup
.
begin
(),
&
mv
),
detail
::
static_types_array
<
T
...
>::
arr
.
begin
()))
if
(
detail
::
matches
(
tup
,
detail
::
static_types_array
<
T
...
>::
arr
,
&
mv
))
{
// never a perfect match
typedef
detail
::
decorated_tuple
<
ResultTuple
::
num_elements
>
decorated
;
return
{
ResultTuple
::
from
(
tup
.
vals
(),
mv
)};
}
}
...
...
cppa/tuple_view.hpp
View file @
03b3b68b
...
...
@@ -68,6 +68,8 @@ class tuple_view
static
constexpr
size_t
num_elements
=
sizeof
...(
ElementTypes
);
typedef
util
::
type_list
<
ElementTypes
...
>
types
;
static
tuple_view
from
(
std
::
vector
<
std
::
pair
<
uniform_type_info
const
*
,
void
const
*>
>
const
&
vec
)
{
tuple_view
result
;
...
...
cppa/type_value_pair.hpp
0 → 100644
View file @
03b3b68b
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef TYPE_VALUE_PAIR_HPP
#define TYPE_VALUE_PAIR_HPP
#include "cppa/uniform_type_info.hpp"
namespace
cppa
{
typedef
std
::
pair
<
uniform_type_info
const
*
,
void
const
*>
type_value_pair
;
}
// namespace cppa
#endif // TYPE_VALUE_PAIR_HPP
cppa/uniform_type_info.hpp
View file @
03b3b68b
...
...
@@ -100,7 +100,7 @@ uniform_type_info const* uniform_typeid(std::type_info const&);
* Depending on your platform, the error message looks somewhat like this:
*
* <tt>
* terminate called after throwing an instance of
'std::runtime_error'
* terminate called after throwing an instance of
std::runtime_error
* <br>
* what(): uniform_type_info::by_type_info(): foo is an unknown typeid name
* </tt>
...
...
cppa/util/static_foreach.hpp
0 → 100644
View file @
03b3b68b
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef STATIC_FOREACH_HPP
#define STATIC_FOREACH_HPP
namespace
cppa
{
namespace
util
{
template
<
size_t
Begin
,
size_t
End
>
struct
static_foreach
{
template
<
typename
Container
,
typename
Fun
>
static
inline
void
_
(
Container
const
&
c
,
Fun
&
f
)
{
f
(
get
<
Begin
>
(
c
));
static_foreach
<
Begin
+
1
,
End
>::
_
(
c
,
f
);
}
};
template
<
size_t
X
>
struct
static_foreach
<
X
,
X
>
{
template
<
typename
Container
,
typename
Fun
>
static
inline
void
_
(
Container
const
&
,
Fun
&
)
{
}
};
}
}
// namespace cppa::util
#endif // STATIC_FOREACH_HPP
examples/announce_example_4.cpp
View file @
03b3b68b
...
...
@@ -129,7 +129,7 @@ int main(int, char**)
on
<
baz
>
()
>>
[]()
{
// prints: @<> ( { baz ( foo ( 1, 2 ), bar ( foo ( 3, 4 ), 5 ) ) } )
cout
<<
to_string
(
last_receiv
ed
())
<<
endl
;
cout
<<
to_string
(
self
->
last_dequeu
ed
())
<<
endl
;
}
);
...
...
examples/announce_example_5.cpp
View file @
03b3b68b
...
...
@@ -207,8 +207,8 @@ int main()
{
// prints the tree in its serialized format:
// @<> ( { tree ( 0, { 10, { 11, { }, 12, { }, 13, { } }, 20, { 21, { }, 22, { } } } ) } )
cout
<<
"to_string(
last_receiv
ed()): "
<<
to_string
(
last_receiv
ed
())
cout
<<
"to_string(
self->last_dequeu
ed()): "
<<
to_string
(
self
->
last_dequeu
ed
())
<<
endl
;
// prints the tree using the print member function:
// 0 { 10 { 11, 12, 13 } , 20 { 21, 22 } }
...
...
@@ -225,7 +225,7 @@ int main()
// tree ( 0, { 10, { 11, { }, 12, { }, 13, { } }, 20, { 21, { }, 22, { } } } )
// )
// } )
cout
<<
"to_string: "
<<
to_string
(
last_receiv
ed
())
<<
endl
;
cout
<<
"to_string: "
<<
to_string
(
self
->
last_dequeu
ed
())
<<
endl
;
}
);
...
...
src/abstract_tuple.cpp
View file @
03b3b68b
...
...
@@ -42,7 +42,7 @@ bool abstract_tuple::equals(const abstract_tuple &other) const
if
(
uti
!=
other
.
type_at
(
i
))
return
false
;
auto
lhs
=
at
(
i
);
auto
rhs
=
other
.
at
(
i
);
// compare
first addresses
, then values
// compare
addresses first
, then values
if
(
lhs
!=
rhs
&&
!
(
uti
->
equals
(
lhs
,
rhs
)))
return
false
;
}
return
true
;
...
...
src/any_tuple.cpp
View file @
03b3b68b
...
...
@@ -34,6 +34,7 @@
namespace
{
/*
struct offset_decorator : cppa::detail::abstract_tuple
{
...
...
@@ -76,6 +77,7 @@ struct offset_decorator : cppa::detail::abstract_tuple
ptr_type m_decorated;
};
*/
inline
cppa
::
detail
::
empty_tuple
*
s_empty_tuple
()
{
...
...
@@ -109,11 +111,9 @@ any_tuple& any_tuple::operator=(any_tuple&& other)
return
*
this
;
}
any_tuple
any_tuple
::
tail
(
size_t
offset
)
const
std
::
type_info
const
&
any_tuple
::
impl_type
(
)
const
{
if
(
offset
==
0
)
return
*
this
;
if
(
size
()
<=
offset
)
return
any_tuple
(
s_empty_tuple
());
return
any_tuple
(
new
offset_decorator
(
m_vals
,
offset
));
return
m_vals
->
impl_type
();
}
size_t
any_tuple
::
size
()
const
...
...
src/converted_thread_context.cpp
View file @
03b3b68b
...
...
@@ -103,7 +103,7 @@ void converted_thread_context::dequeue(timed_invoke_rules& rules) /*override*/
converted_thread_context
::
throw_on_exit_result
converted_thread_context
::
throw_on_exit
(
any_tuple
const
&
msg
)
{
if
(
matches
(
msg
.
begin
(),
m_exit_msg_pattern
.
begin
()
))
if
(
matches
(
msg
,
m_exit_msg_pattern
))
{
auto
reason
=
msg
.
get_as
<
std
::
uint32_t
>
(
1
);
if
(
reason
!=
exit_reason
::
normal
)
...
...
src/empty_tuple.cpp
View file @
03b3b68b
...
...
@@ -63,4 +63,9 @@ bool empty_tuple::equals(const abstract_tuple& other) const
return
other
.
size
()
==
0
;
}
std
::
type_info
const
&
empty_tuple
::
impl_type
()
const
{
return
typeid
(
empty_tuple
);
}
}
}
// namespace cppa::detail
src/object_array.cpp
View file @
03b3b68b
...
...
@@ -102,4 +102,9 @@ uniform_type_info const* object_array::type_at(size_t pos) const
return
m_elements
[
pos
].
type
();
}
std
::
type_info
const
&
object_array
::
impl_type
()
const
{
return
typeid
(
object_array
);
}
}
}
// namespace cppa::detail
src/scheduler.cpp
View file @
03b3b68b
...
...
@@ -148,7 +148,8 @@ void scheduler_helper::time_emitter(scheduler_helper::ptr_type m_self)
ptr
->
msg
.
at
(
1
)));
if
(
*
whom
)
{
auto
msg
=
ptr
->
msg
.
tail
(
2
);
any_tuple
msg
=
*
(
reinterpret_cast
<
any_tuple
const
*>
(
ptr
->
msg
.
at
(
2
)));
(
*
whom
)
->
enqueue
(
ptr
->
sender
.
get
(),
std
::
move
(
msg
));
}
messages
.
erase
(
it
);
...
...
unit_testing/ping_pong.cpp
View file @
03b3b68b
...
...
@@ -31,7 +31,7 @@ void ping()
void
pong
(
actor_ptr
ping_actor
)
{
link
(
ping_actor
);
self
->
link_to
(
ping_actor
);
// kickoff
send
(
ping_actor
,
atom
(
"pong"
),
0
);
receive_loop
...
...
@@ -40,7 +40,7 @@ void pong(actor_ptr ping_actor)
{
// terminate with non-normal exit reason
// to force ping actor to quit
quit
(
exit_reason
::
user_defined
);
self
->
quit
(
exit_reason
::
user_defined
);
},
on
<
atom
(
"ping"
),
int
>
()
>>
[](
int
value
)
{
...
...
unit_testing/test__local_group.cpp
View file @
03b3b68b
...
...
@@ -53,6 +53,7 @@ size_t test__local_group()
after
(
std
::
chrono
::
seconds
(
2
))
>>
[
&
]()
{
CPPA_CHECK
(
false
);
result
=
10
;
}
)
.
until
([
&
result
]()
{
return
result
==
10
;
});
...
...
unit_testing/test__pattern.cpp
View file @
03b3b68b
...
...
@@ -29,7 +29,7 @@ std::string plot(Arr const& arr)
{
std
::
ostringstream
oss
;
oss
<<
"{ "
;
for
(
size_t
i
=
0
;
i
<
arr
.
size
()
;
++
i
)
for
(
size_t
i
=
0
;
i
<
Arr
::
size
;
++
i
)
{
if
(
i
>
0
)
oss
<<
", "
;
oss
<<
"arr["
<<
i
<<
"] = "
<<
((
arr
[
i
])
?
arr
[
i
]
->
name
()
:
"anything"
);
...
...
@@ -63,9 +63,9 @@ size_t test__pattern()
{
CPPA_TEST
(
test__pattern
);
match_test
(
make_tuple
(
1
,
2
,
3
));
match_test
(
std
::
list
<
int
>
{
1
,
2
,
3
});
match_test
(
"abc"
);
//
match_test(make_tuple(1,2,3));
//
match_test(std::list<int>{1, 2, 3});
//
match_test("abc");
pattern
<
int
,
anything
,
int
>
i3
;
any_tuple
i3_any_tup
=
make_tuple
(
1
,
2
,
3
);
...
...
unit_testing/test__spawn.cpp
View file @
03b3b68b
...
...
@@ -255,18 +255,15 @@ class testee_actor : public scheduled_actor
// receives one timeout and quits
void
testee1
()
{
receive
_loop
receive
(
after
(
std
::
chrono
::
milliseconds
(
10
))
>>
[]()
{
quit
(
exit_reason
::
user_defined
);
}
after
(
std
::
chrono
::
milliseconds
(
10
))
>>
[]()
{
}
);
}
void
testee2
(
actor_ptr
other
)
{
link
(
other
);
self
->
link_to
(
other
);
send
(
other
,
std
::
uint32_t
(
1
));
receive_loop
(
...
...
@@ -370,13 +367,14 @@ size_t test__spawn()
auto
report_unexpected
=
[
&
]()
{
cerr
<<
"unexpected message: "
<<
to_string
(
last_received
())
<<
endl
;
cerr
<<
"unexpected message: "
<<
to_string
(
self
->
last_dequeued
())
<<
endl
;
CPPA_CHECK
(
false
);
};
trap_exit
(
true
);
self
->
trap_exit
(
true
);
auto
pong_actor
=
spawn
(
pong
,
spawn
(
ping
));
monitor
(
pong_actor
);
link
(
pong_actor
);
self
->
link_to
(
pong_actor
);
// monitor(spawn(testee2, spawn(testee1)));
int
i
=
0
;
int
flags
=
0
;
...
...
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