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
a9300af4
Commit
a9300af4
authored
Mar 06, 2012
by
neverlord
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
RIP invoke_rules, long live partial_function
parent
550a4200
Changes
51
Show whitespace changes
Inline
Side-by-side
Showing
51 changed files
with
1146 additions
and
945 deletions
+1146
-945
Makefile.am
Makefile.am
+211
-209
cppa.files
cppa.files
+2
-3
cppa/abstract_actor.hpp
cppa/abstract_actor.hpp
+106
-124
cppa/abstract_event_based_actor.hpp
cppa/abstract_event_based_actor.hpp
+10
-17
cppa/actor.hpp
cppa/actor.hpp
+14
-11
cppa/actor_proxy.hpp
cppa/actor_proxy.hpp
+5
-3
cppa/any_tuple.hpp
cppa/any_tuple.hpp
+13
-6
cppa/behavior.hpp
cppa/behavior.hpp
+99
-3
cppa/channel.hpp
cppa/channel.hpp
+6
-4
cppa/cppa.hpp
cppa/cppa.hpp
+1
-1
cppa/detail/abstract_scheduled_actor.hpp
cppa/detail/abstract_scheduled_actor.hpp
+3
-3
cppa/detail/abstract_tuple.hpp
cppa/detail/abstract_tuple.hpp
+37
-6
cppa/detail/converted_thread_context.hpp
cppa/detail/converted_thread_context.hpp
+3
-3
cppa/detail/decorated_tuple.hpp
cppa/detail/decorated_tuple.hpp
+6
-1
cppa/detail/empty_tuple.hpp
cppa/detail/empty_tuple.hpp
+2
-2
cppa/detail/invokable.hpp
cppa/detail/invokable.hpp
+113
-133
cppa/detail/object_array.hpp
cppa/detail/object_array.hpp
+3
-1
cppa/detail/receive_loop_helper.hpp
cppa/detail/receive_loop_helper.hpp
+24
-65
cppa/detail/tuple_vals.hpp
cppa/detail/tuple_vals.hpp
+6
-1
cppa/detail/yielding_actor.hpp
cppa/detail/yielding_actor.hpp
+2
-2
cppa/event_based_actor.hpp
cppa/event_based_actor.hpp
+1
-3
cppa/event_based_actor_base.hpp
cppa/event_based_actor_base.hpp
+7
-45
cppa/local_actor.hpp
cppa/local_actor.hpp
+7
-6
cppa/match.hpp
cppa/match.hpp
+17
-14
cppa/on.hpp
cppa/on.hpp
+30
-30
cppa/partial_function.hpp
cppa/partial_function.hpp
+72
-21
cppa/pattern.hpp
cppa/pattern.hpp
+41
-3
cppa/receive.hpp
cppa/receive.hpp
+18
-60
cppa/stacked_event_based_actor.hpp
cppa/stacked_event_based_actor.hpp
+1
-2
cppa/util/duration.hpp
cppa/util/duration.hpp
+3
-1
cppa/util/tbind.hpp
cppa/util/tbind.hpp
+1
-1
cppa/util/type_list.hpp
cppa/util/type_list.hpp
+12
-12
cppa/util/upgrade_lock_guard.hpp
cppa/util/upgrade_lock_guard.hpp
+1
-1
src/abstract_event_based_actor.cpp
src/abstract_event_based_actor.cpp
+21
-36
src/abstract_scheduled_actor.cpp
src/abstract_scheduled_actor.cpp
+8
-5
src/abstract_tuple.cpp
src/abstract_tuple.cpp
+1
-1
src/actor.cpp
src/actor.cpp
+2
-2
src/converted_thread_context.cpp
src/converted_thread_context.cpp
+21
-14
src/empty_tuple.cpp
src/empty_tuple.cpp
+6
-1
src/event_based_actor.cpp
src/event_based_actor.cpp
+12
-41
src/invokable.cpp
src/invokable.cpp
+1
-5
src/mock_scheduler.cpp
src/mock_scheduler.cpp
+1
-2
src/object_array.cpp
src/object_array.cpp
+6
-1
src/partial_function.cpp
src/partial_function.cpp
+120
-0
src/receive.cpp
src/receive.cpp
+2
-2
src/stacked_event_based_actor.cpp
src/stacked_event_based_actor.cpp
+5
-13
src/yielding_actor.cpp
src/yielding_actor.cpp
+29
-21
unit_testing/test__atom.cpp
unit_testing/test__atom.cpp
+0
-1
unit_testing/test__pattern.cpp
unit_testing/test__pattern.cpp
+34
-0
unit_testing/test__tuple.cpp
unit_testing/test__tuple.cpp
+0
-2
unit_testing/test__type_list.cpp
unit_testing/test__type_list.cpp
+0
-1
No files found.
Makefile.am
View file @
a9300af4
...
...
@@ -4,12 +4,12 @@ lib_LTLIBRARIES = libcppa.la
libcppa_la_SOURCES
=
\
src/abstract_event_based_actor.cpp
\
src/abstract_scheduled_actor.cpp
\
src/abstract_tuple.cpp
\
src/scheduled_actor.cpp
\
src/actor_count.cpp
\
src/actor.cpp
\
src/actor_proxy_cache
.cpp
\
src/actor_count
.cpp
\
src/actor_proxy.cpp
\
src/actor_proxy_cache.cpp
\
src/actor_registry.cpp
\
src/addressed_message.cpp
\
src/any_tuple.cpp
\
...
...
@@ -18,35 +18,35 @@ libcppa_la_SOURCES = \
src/binary_deserializer.cpp
\
src/binary_serializer.cpp
\
src/channel.cpp
\
src/local_actor.cpp
\
src/converted_thread_context.cpp
\
src/cppa.cpp
\
src/event_based_actor.cpp
\
src/delegate.cpp
\
src/demangle.cpp
\
src/deserializer.cpp
\
src/duration.cpp
\
src/empty_tuple.cpp
\
src/event_based_actor.cpp
\
src/exception.cpp
\
src/fiber.cpp
\
src/group.cpp
\
src/group_manager.cpp
\
src/intermediate.cpp
\
src/invokable.cpp
\
src/invoke_rules
.cpp
\
src/local_actor
.cpp
\
src/mailman.cpp
\
src/mock_scheduler.cpp
\
src/native_socket.cpp
\
src/network_manager.cpp
\
src/object_array.cpp
\
src/object.cpp
\
src/object_array.cpp
\
src/partial_function.cpp
\
src/post_office.cpp
\
src/post_office_msg.cpp
\
src/primitive_variant.cpp
\
src/process_information.cpp
\
src/receive.cpp
\
src/ripemd_160.cpp
\
src/abstract_
scheduled_actor.cpp
\
src/
scheduled_actor.cpp
\
src/scheduler.cpp
\
src/self.cpp
\
src/serializer.cpp
\
...
...
@@ -70,11 +70,12 @@ endif
nobase_library_include_HEADERS
=
\
cppa/abstract_actor.hpp
\
cppa/schedul
ed_actor.hpp
\
cppa/abstract_event_bas
ed_actor.hpp
\
cppa/actor.hpp
\
cppa/actor_proxy.hpp
\
cppa/announce.hpp
\
cppa/any_tuple.hpp
\
cppa/any_tuple_view.hpp
\
cppa/anything.hpp
\
cppa/atom.hpp
\
cppa/attachable.hpp
\
...
...
@@ -83,15 +84,10 @@ nobase_library_include_HEADERS = \
cppa/binary_serializer.hpp
\
cppa/channel.hpp
\
cppa/config.hpp
\
cppa/local_actor.hpp
\
cppa/match.hpp
\
cppa/cow_ptr.hpp
\
cppa/cppa.hpp
\
cppa/deserializer.hpp
\
cppa/either.hpp
\
cppa/event_based_actor.hpp
\
cppa/event_based_actor_base.hpp
\
cppa/abstract_event_based_actor.hpp
\
cppa/detail/abstract_scheduled_actor.hpp
\
cppa/detail/abstract_tuple.hpp
\
cppa/detail/actor_count.hpp
\
cppa/detail/actor_proxy_cache.hpp
\
...
...
@@ -128,7 +124,6 @@ nobase_library_include_HEADERS = \
cppa/detail/ptype_to_type.hpp
\
cppa/detail/receive_loop_helper.hpp
\
cppa/detail/ref_counted_impl.hpp
\
cppa/detail/abstract_scheduled_actor.hpp
\
cppa/detail/serialize_tuple.hpp
\
cppa/detail/singleton_manager.hpp
\
cppa/detail/swap_bytes.hpp
\
...
...
@@ -145,6 +140,9 @@ nobase_library_include_HEADERS = \
cppa/detail/uniform_type_info_map.hpp
\
cppa/detail/yield_interface.hpp
\
cppa/detail/yielding_actor.hpp
\
cppa/either.hpp
\
cppa/event_based_actor.hpp
\
cppa/event_based_actor_base.hpp
\
cppa/exception.hpp
\
cppa/exit_reason.hpp
\
cppa/from_string.hpp
\
...
...
@@ -152,16 +150,19 @@ nobase_library_include_HEADERS = \
cppa/get.hpp
\
cppa/group.hpp
\
cppa/intrusive_ptr.hpp
\
cppa/invoke_rules.hpp
\
cppa/local_actor.hpp
\
cppa/match.hpp
\
cppa/object.hpp
\
cppa/on.hpp
\
cppa/option.hpp
\
cppa/partial_function.hpp
\
cppa/pattern.hpp
\
cppa/primitive_type.hpp
\
cppa/primitive_variant.hpp
\
cppa/process_information.hpp
\
cppa/receive.hpp
\
cppa/ref_counted.hpp
\
cppa/scheduled_actor.hpp
\
cppa/scheduler.hpp
\
cppa/scheduling_hint.hpp
\
cppa/self.hpp
\
...
...
@@ -190,14 +191,14 @@ nobase_library_include_HEADERS = \
cppa/util/fiber.hpp
\
cppa/util/fixed_vector.hpp
\
cppa/util/has_copy_member_fun.hpp
\
cppa/util
.hpp
\
cppa/util/if_else
.hpp
\
cppa/util/is_array_of.hpp
\
cppa/util/is_builtin.hpp
\
cppa/util/if_else.hpp
\
cppa/util/is_comparable.hpp
\
cppa/util/is_copyable.hpp
\
cppa/util/is_forward_iterator.hpp
\
cppa/util/is_iterable.hpp
\
cppa/util/is_iterable.hpp
\
cppa/util/is_legal_tuple_type.hpp
\
cppa/util/is_manipulator.hpp
\
cppa/util/is_mutable_ref.hpp
\
...
...
@@ -210,11 +211,12 @@ nobase_library_include_HEADERS = \
cppa/util/replace_type.hpp
\
cppa/util/ripemd_160.hpp
\
cppa/util/rm_ref.hpp
\
cppa/util/static_foreach.hpp
\
cppa/util/shared_lock_guard.hpp
\
cppa/util/shared_spinlock.hpp
\
cppa/util/single_reader_queue.hpp
\
cppa/util/singly_linked_list.hpp
\
cppa/util/static_foreach.hpp
\
cppa/util/tbind.hpp
\
cppa/util/type_list.hpp
\
cppa/util/type_pair.hpp
\
cppa/util/upgrade_lock_guard.hpp
\
...
...
cppa.files
View file @
a9300af4
...
...
@@ -3,7 +3,6 @@ cppa/tuple.hpp
unit_testing/main.cpp
cppa/util/void_type.hpp
cppa/util/type_list.hpp
cppa/util.hpp
cppa/util/is_one_of.hpp
cppa/util/conjunction.hpp
cppa/util/disjunction.hpp
...
...
@@ -34,7 +33,6 @@ cppa/util/is_copyable.hpp
cppa/util/has_copy_member_fun.hpp
cppa/detail/intermediate.hpp
cppa/detail/invokable.hpp
cppa/invoke_rules.hpp
cppa/on.hpp
unit_testing/test__serialization.cpp
cppa/serializer.hpp
...
...
@@ -176,7 +174,6 @@ cppa/detail/receive_loop_helper.hpp
cppa/util/wrapped.hpp
cppa/detail/boxed.hpp
cppa/detail/unboxed.hpp
src/invoke_rules.cpp
src/abstract_tuple.cpp
cppa/util/duration.hpp
src/duration.cpp
...
...
@@ -262,3 +259,5 @@ cppa/detail/disablable_delete.hpp
unit_testing/test__fixed_vector.cpp
cppa/detail/tuple_cast_impl.hpp
cppa/match.hpp
cppa/partial_function.hpp
src/partial_function.cpp
cppa/abstract_actor.hpp
View file @
a9300af4
...
...
@@ -52,60 +52,125 @@ namespace cppa {
template
<
class
Base
>
class
abstract_actor
:
public
Base
{
typedef
detail
::
lock_guard
<
detail
::
mutex
>
guard_type
;
//typedef std::lock_guard<std::mutex> guard_type;
typedef
std
::
unique_ptr
<
attachable
>
attachable_ptr
;
// true if the associated thread has finished execution
std
::
atomic
<
std
::
uint32_t
>
m_exit_reason
;
// guards access to m_exited, m_subscriptions and m_links
detail
::
mutex
m_mtx
;
// links to other actors
std
::
vector
<
actor_ptr
>
m_links
;
// code that is executed on cleanup
std
::
vector
<
attachable_ptr
>
m_attachables
;
typedef
std
::
unique_ptr
<
attachable
>
attachable_ptr
;
typedef
detail
::
lock_guard
<
detail
::
mutex
>
guard_type
;
public:
struct
queue_node
{
friend
class
abstract_actor
;
friend
class
queue_node_ptr
;
queue_node
*
next
;
actor_ptr
sender
;
any_tuple
msg
;
queue_node
()
:
next
(
nullptr
)
{
}
queue_node
(
actor
*
from
,
any_tuple
&&
content
)
:
next
(
nullptr
),
sender
(
from
),
msg
(
std
::
move
(
content
))
:
next
(
nullptr
),
sender
(
from
),
msg
(
std
::
move
(
content
))
{
}
queue_node
(
actor
*
from
,
any_tuple
const
&
content
)
:
next
(
nullptr
),
sender
(
from
),
msg
(
content
)
{
}
};
typedef
std
::
unique_ptr
<
queue_node
>
queue_node_ptr
;
bool
attach
(
attachable
*
ptr
)
/*override*/
{
if
(
ptr
==
nullptr
)
{
guard_type
guard
(
m_mtx
);
return
m_exit_reason
.
load
()
==
exit_reason
::
not_exited
;
}
queue_node
(
actor
*
from
,
any_tuple
const
&
content
)
:
next
(
nullptr
),
sender
(
from
),
msg
(
content
)
else
{
attachable_ptr
uptr
(
ptr
);
std
::
uint32_t
reason
;
// lifetime scope of guard
{
guard_type
guard
(
m_mtx
);
reason
=
m_exit_reason
.
load
();
if
(
reason
==
exit_reason
::
not_exited
)
{
m_attachables
.
push_back
(
std
::
move
(
uptr
));
return
true
;
}
}
uptr
->
actor_exited
(
reason
);
return
false
;
}
}
};
typedef
std
::
unique_ptr
<
queue_node
>
queue_node_ptr
;
void
detach
(
attachable
::
token
const
&
what
)
/*override*/
{
attachable_ptr
uptr
;
// lifetime scope of guard
{
guard_type
guard
(
m_mtx
);
auto
end
=
m_attachables
.
end
();
auto
i
=
std
::
find_if
(
m_attachables
.
begin
(),
end
,
[
&
](
attachable_ptr
&
p
)
{
return
p
->
matches
(
what
);
});
if
(
i
!=
end
)
{
uptr
=
std
::
move
(
*
i
);
m_attachables
.
erase
(
i
);
}
}
// uptr will be destroyed here, without locked mutex
}
protected:
void
link_to
(
intrusive_ptr
<
actor
>&
other
)
/*override*/
{
(
void
)
link_to_impl
(
other
);
}
util
::
single_reader_queue
<
queue_node
>
m_mailbox
;
void
unlink_from
(
intrusive_ptr
<
actor
>&
other
)
/*override*/
{
(
void
)
unlink_from_impl
(
other
);
}
private:
bool
remove_backlink
(
intrusive_ptr
<
actor
>&
other
)
/*override*/
{
if
(
other
&&
other
!=
this
)
{
guard_type
guard
(
m_mtx
);
auto
i
=
std
::
find
(
m_links
.
begin
(),
m_links
.
end
(),
other
);
if
(
i
!=
m_links
.
end
())
{
m_links
.
erase
(
i
);
return
true
;
}
}
return
false
;
}
// @pre m_mtx.locked()
bool
exited
()
const
bool
establish_backlink
(
intrusive_ptr
<
actor
>&
other
)
/*override*/
{
return
m_exit_reason
.
load
()
!=
exit_reason
::
not_exited
;
std
::
uint32_t
reason
=
exit_reason
::
not_exited
;
if
(
other
&&
other
!=
this
)
{
guard_type
guard
(
m_mtx
);
reason
=
m_exit_reason
.
load
();
if
(
reason
==
exit_reason
::
not_exited
)
{
auto
i
=
std
::
find
(
m_links
.
begin
(),
m_links
.
end
(),
other
);
if
(
i
==
m_links
.
end
())
{
m_links
.
push_back
(
other
);
return
true
;
}
}
}
// send exit message without lock
if
(
reason
!=
exit_reason
::
not_exited
)
{
other
->
enqueue
(
this
,
make_tuple
(
atom
(
":Exit"
),
reason
));
}
return
false
;
}
protected:
util
::
single_reader_queue
<
queue_node
>
m_mailbox
;
template
<
typename
T
>
inline
queue_node
*
fetch_node
(
actor
*
sender
,
T
&&
msg
)
{
...
...
@@ -185,105 +250,22 @@ class abstract_actor : public Base
return
false
;
}
public:
bool
attach
(
attachable
*
ptr
)
/*override*/
{
if
(
ptr
==
nullptr
)
{
guard_type
guard
(
m_mtx
);
return
m_exit_reason
.
load
()
==
exit_reason
::
not_exited
;
}
else
{
attachable_ptr
uptr
(
ptr
);
std
::
uint32_t
reason
;
// lifetime scope of guard
{
guard_type
guard
(
m_mtx
);
reason
=
m_exit_reason
.
load
();
if
(
reason
==
exit_reason
::
not_exited
)
{
m_attachables
.
push_back
(
std
::
move
(
uptr
));
return
true
;
}
}
uptr
->
actor_exited
(
reason
);
return
false
;
}
}
void
detach
(
attachable
::
token
const
&
what
)
/*override*/
{
attachable_ptr
uptr
;
// lifetime scope of guard
{
guard_type
guard
(
m_mtx
);
auto
end
=
m_attachables
.
end
();
auto
i
=
std
::
find_if
(
m_attachables
.
begin
(),
end
,
[
&
](
attachable_ptr
&
ptr
)
{
return
ptr
->
matches
(
what
);
});
if
(
i
!=
end
)
{
uptr
=
std
::
move
(
*
i
);
m_attachables
.
erase
(
i
);
}
}
// uptr will be destroyed here, without locked mutex
}
void
link_to
(
intrusive_ptr
<
actor
>&
other
)
/*override*/
{
(
void
)
link_to_impl
(
other
);
}
void
unlink_from
(
intrusive_ptr
<
actor
>&
other
)
/*override*/
{
(
void
)
unlink_from_impl
(
other
);
}
private:
bool
remove_backlink
(
intrusive_ptr
<
actor
>&
other
)
/*override*/
{
if
(
other
&&
other
!=
this
)
{
guard_type
guard
(
m_mtx
);
auto
i
=
std
::
find
(
m_links
.
begin
(),
m_links
.
end
(),
other
);
if
(
i
!=
m_links
.
end
())
// @pre m_mtx.locked()
bool
exited
()
const
{
m_links
.
erase
(
i
);
return
true
;
}
}
return
false
;
return
m_exit_reason
.
load
()
!=
exit_reason
::
not_exited
;
}
bool
establish_backlink
(
intrusive_ptr
<
actor
>&
other
)
/*override*/
{
std
::
uint32_t
reason
=
exit_reason
::
not_exited
;
if
(
other
&&
other
!=
this
)
{
guard_type
guard
(
m_mtx
);
reason
=
m_exit_reason
.
load
();
if
(
reason
==
exit_reason
::
not_exited
)
{
auto
i
=
std
::
find
(
m_links
.
begin
(),
m_links
.
end
(),
other
);
if
(
i
==
m_links
.
end
())
{
m_links
.
push_back
(
other
);
return
true
;
}
}
}
// send exit message without lock
if
(
reason
!=
exit_reason
::
not_exited
)
{
other
->
enqueue
(
this
,
make_tuple
(
atom
(
":Exit"
),
reason
));
}
return
false
;
}
// true if the associated thread has finished execution
std
::
atomic
<
std
::
uint32_t
>
m_exit_reason
;
// guards access to m_exited, m_subscriptions and m_links
detail
::
mutex
m_mtx
;
// links to other actors
std
::
vector
<
actor_ptr
>
m_links
;
// code that is executed on cleanup
std
::
vector
<
attachable_ptr
>
m_attachables
;
};
...
...
cppa/abstract_event_based_actor.hpp
View file @
a9300af4
...
...
@@ -38,7 +38,7 @@
#include "cppa/config.hpp"
#include "cppa/either.hpp"
#include "cppa/pattern.hpp"
#include "cppa/
invoke_rules
.hpp"
#include "cppa/
behavior
.hpp"
#include "cppa/detail/disablable_delete.hpp"
#include "cppa/detail/abstract_scheduled_actor.hpp"
...
...
@@ -56,9 +56,9 @@ class abstract_event_based_actor : public detail::abstract_scheduled_actor
public:
void
dequeue
(
invoke_rules
&
)
/*override*/
;
void
dequeue
(
behavior
&
)
/*override*/
;
void
dequeue
(
timed_invoke_rules
&
)
/*override*/
;
void
dequeue
(
partial_function
&
)
/*override*/
;
void
resume
(
util
::
fiber
*
,
resume_callback
*
callback
)
/*override*/
;
...
...
@@ -74,31 +74,20 @@ class abstract_event_based_actor : public detail::abstract_scheduled_actor
template
<
typename
Scheduler
>
abstract_event_based_actor
*
attach_to_scheduler
(
void
(
*
enq
ueue
_fun
)(
Scheduler
*
,
abstract_scheduled_actor
*
),
attach_to_scheduler
(
void
(
*
enq_fun
)(
Scheduler
*
,
abstract_scheduled_actor
*
),
Scheduler
*
sched
)
{
m_enqueue_to_scheduler
.
reset
(
enq
ueue
_fun
,
sched
,
this
);
m_enqueue_to_scheduler
.
reset
(
enq_fun
,
sched
,
this
);
this
->
init
();
return
this
;
}
private:
void
handle_message
(
queue_node_ptr
&
node
,
invoke_rules
&
behavior
);
void
handle_message
(
queue_node_ptr
&
node
,
timed_invoke_rules
&
behavior
);
void
handle_message
(
queue_node_ptr
&
node
);
protected:
abstract_event_based_actor
();
// ownership flag + pointer
typedef
either
<
std
::
unique_ptr
<
invoke_rules
,
detail
::
disablable_delete
<
invoke_rules
>>
,
std
::
unique_ptr
<
timed_invoke_rules
,
detail
::
disablable_delete
<
timed_invoke_rules
>>>
typedef
std
::
unique_ptr
<
behavior
,
detail
::
disablable_delete
<
behavior
>>
stack_element
;
queue_node_buffer
m_buffer
;
...
...
@@ -132,6 +121,10 @@ class abstract_event_based_actor : public detail::abstract_scheduled_actor
receive
(
std
::
forward
<
Args
>
(
args
)...);
}
private:
void
handle_message
(
queue_node_ptr
&
node
);
};
}
// namespace cppa
...
...
cppa/actor.hpp
View file @
a9300af4
...
...
@@ -56,17 +56,6 @@ typedef std::uint32_t actor_id;
class
actor
:
public
channel
{
bool
m_is_proxy
;
actor_id
m_id
;
process_information_ptr
m_parent_process
;
protected:
actor
(
process_information_ptr
const
&
parent
=
process_information
::
get
());
actor
(
std
::
uint32_t
aid
,
process_information_ptr
const
&
parent
=
process_information
::
get
());
public:
~
actor
();
...
...
@@ -202,6 +191,20 @@ class actor : public channel
*/
inline
bool
is_proxy
()
const
;
protected:
actor
(
process_information_ptr
const
&
parent
=
process_information
::
get
());
actor
(
std
::
uint32_t
aid
,
process_information_ptr
const
&
parent
=
process_information
::
get
());
private:
actor_id
m_id
;
bool
m_is_proxy
;
process_information_ptr
m_parent_process
;
};
/**
...
...
cppa/actor_proxy.hpp
View file @
a9300af4
...
...
@@ -50,9 +50,6 @@ class actor_proxy : public abstract_actor<actor>
typedef
abstract_actor
<
actor
>
super
;
void
forward_message
(
process_information_ptr
const
&
,
actor
*
,
any_tuple
const
&
);
public:
actor_proxy
(
std
::
uint32_t
mid
,
process_information_ptr
const
&
parent
);
...
...
@@ -77,6 +74,11 @@ class actor_proxy : public abstract_actor<actor>
bool
establish_backlink
(
intrusive_ptr
<
actor
>&
to
);
public:
void
forward_message
(
process_information_ptr
const
&
,
actor
*
,
any_tuple
const
&
);
};
#endif // CPPA_DOCUMENTATION
...
...
cppa/any_tuple.hpp
View file @
a9300af4
...
...
@@ -45,10 +45,6 @@ namespace cppa {
class
any_tuple
{
cow_ptr
<
detail
::
abstract_tuple
>
m_vals
;
explicit
any_tuple
(
cow_ptr
<
detail
::
abstract_tuple
>
const
&
vals
);
public:
/**
...
...
@@ -143,11 +139,22 @@ class any_tuple
cow_ptr
<
detail
::
abstract_tuple
>
const
&
vals
()
const
;
inline
std
::
type_info
const
*
values_type_list
()
const
inline
void
const
*
type_token
()
const
{
return
m_vals
->
type_token
();
}
inline
std
::
type_info
const
*
impl_type
()
const
{
return
m_vals
->
values_type_list
();
return
m_vals
->
impl_type
();
}
private:
cow_ptr
<
detail
::
abstract_tuple
>
m_vals
;
explicit
any_tuple
(
cow_ptr
<
detail
::
abstract_tuple
>
const
&
vals
);
};
inline
bool
operator
==
(
any_tuple
const
&
lhs
,
any_tuple
const
&
rhs
)
...
...
cppa/behavior.hpp
View file @
a9300af4
...
...
@@ -31,15 +31,111 @@
#ifndef BEHAVIOR_HPP
#define BEHAVIOR_HPP
#include "cppa/either.hpp"
#include "cppa/invoke_rules.hpp"
#include <functional>
#include <type_traits>
#include "cppa/util/tbind.hpp"
#include "cppa/util/rm_ref.hpp"
#include "cppa/util/if_else.hpp"
#include "cppa/util/duration.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/partial_function.hpp"
namespace
cppa
{
/**
* @brief
*/
typedef
either
<
invoke_rules
,
timed_invoke_rules
>
behavior
;
class
behavior
{
behavior
(
behavior
const
&
)
=
delete
;
behavior
&
operator
=
(
behavior
const
&
)
=
delete
;
public:
behavior
()
=
default
;
behavior
(
behavior
&&
)
=
default
;
behavior
&
operator
=
(
behavior
&&
)
=
default
;
inline
behavior
(
partial_function
&&
fun
)
:
m_fun
(
std
::
move
(
fun
))
{
}
inline
behavior
(
util
::
duration
tout
,
std
::
function
<
void
()
>&&
handler
)
:
m_timeout
(
tout
),
m_timeout_handler
(
std
::
move
(
handler
))
{
}
inline
void
handle_timeout
()
const
{
m_timeout_handler
();
}
inline
util
::
duration
const
&
timeout
()
const
{
return
m_timeout
;
}
inline
void
operator
()(
any_tuple
const
&
value
)
{
m_fun
(
value
);
}
inline
detail
::
intermediate
*
get_intermediate
(
any_tuple
const
&
value
)
{
return
m_fun
.
get_intermediate
(
value
);
}
inline
partial_function
&
get_partial_function
()
{
return
m_fun
;
}
inline
behavior
&
splice
(
behavior
&&
what
)
{
m_fun
.
splice
(
std
::
move
(
what
.
get_partial_function
()));
m_timeout
=
what
.
m_timeout
;
m_timeout_handler
=
std
::
move
(
what
.
m_timeout_handler
);
return
*
this
;
}
template
<
class
...
Args
>
inline
behavior
&
splice
(
partial_function
&&
arg0
,
Args
&&
...
args
)
{
m_fun
.
splice
(
std
::
move
(
arg0
));
return
splice
(
std
::
forward
<
Args
>
(
args
)...);
}
private:
// terminates recursion
inline
behavior
&
splice
()
{
return
*
this
;
}
partial_function
m_fun
;
util
::
duration
m_timeout
;
std
::
function
<
void
()
>
m_timeout_handler
;
};
namespace
detail
{
template
<
typename
...
Ts
>
struct
select_bhvr
{
static
constexpr
bool
timed
=
util
::
tl_exists
<
util
::
type_list
<
Ts
...
>
,
util
::
tbind
<
std
::
is_same
,
behavior
>::
type
>::
value
;
typedef
typename
util
::
if_else_c
<
timed
,
behavior
,
util
::
wrapped
<
partial_function
>
>::
type
type
;
};
}
// namespace detail
}
// namespace cppa
...
...
cppa/channel.hpp
View file @
a9300af4
...
...
@@ -53,10 +53,6 @@ class channel : public ref_counted
friend
class
actor
;
friend
class
group
;
// channel is a sealed class and the only
// allowed subclasses are actor and group.
channel
()
=
default
;
public:
virtual
~
channel
();
...
...
@@ -68,6 +64,12 @@ class channel : public ref_counted
virtual
void
enqueue
(
actor
*
sender
,
any_tuple
&&
msg
)
=
0
;
private:
// channel is a sealed class and the only
// allowed subclasses are actor and group.
channel
()
=
default
;
};
/**
...
...
cppa/cppa.hpp
View file @
a9300af4
...
...
@@ -42,6 +42,7 @@
#include "cppa/actor.hpp"
#include "cppa/channel.hpp"
#include "cppa/receive.hpp"
#include "cppa/behavior.hpp"
#include "cppa/announce.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/to_string.hpp"
...
...
@@ -49,7 +50,6 @@
#include "cppa/fsm_actor.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/exit_reason.hpp"
#include "cppa/invoke_rules.hpp"
#include "cppa/scheduled_actor.hpp"
#include "cppa/scheduling_hint.hpp"
#include "cppa/event_based_actor.hpp"
...
...
cppa/detail/abstract_scheduled_actor.hpp
View file @
a9300af4
...
...
@@ -84,7 +84,7 @@ class abstract_scheduled_actor : public abstract_actor<local_actor>
filter_result
filter_msg
(
any_tuple
const
&
msg
);
dq_result
dq
(
queue_node_ptr
&
node
,
invoke_rules_base
&
rules
,
partial_function
&
rules
,
queue_node_buffer
&
buffer
);
bool
has_pending_timeout
()
...
...
@@ -157,8 +157,8 @@ struct scheduled_actor_dummy : abstract_scheduled_actor
{
void
resume
(
util
::
fiber
*
,
resume_callback
*
);
void
quit
(
std
::
uint32_t
);
void
dequeue
(
invoke_rules
&
);
void
dequeue
(
timed_invoke_rules
&
);
void
dequeue
(
behavior
&
);
void
dequeue
(
partial_function
&
);
void
link_to
(
intrusive_ptr
<
actor
>&
);
void
unlink_from
(
intrusive_ptr
<
actor
>&
);
bool
establish_backlink
(
intrusive_ptr
<
actor
>&
);
...
...
cppa/detail/abstract_tuple.hpp
View file @
a9300af4
...
...
@@ -56,14 +56,19 @@ 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_list of values or nullptr
virtual
std
::
type_info
const
*
values_type_list
()
const
=
0
;
// identifies the type of the implementation, this is NOT the
// typeid of the implementation class
virtual
std
::
type_info
const
*
impl_type
()
const
=
0
;
// uniquely identifies this category (element types) of messages
virtual
void
const
*
type_token
()
const
=
0
;
bool
equals
(
abstract_tuple
const
&
other
)
const
;
// iterator support
class
const_iterator
:
public
std
::
iterator
<
std
::
bidirectional_iterator_tag
,
type_value_pair
>
class
const_iterator
//
: public std::iterator<std::bidirectional_iterator_tag,
//
type_value_pair>
{
size_t
m_pos
;
...
...
@@ -142,7 +147,7 @@ struct abstract_tuple : ref_counted
inline
const_iterator
&
operator
*
()
{
return
*
this
;
}
inline
operator
type_value_pair
()
const
{
return
{
type
(),
value
()};
}
//
inline operator type_value_pair() const { return {type(), value()}; }
};
...
...
@@ -160,6 +165,20 @@ inline bool full_eq(abstract_tuple::const_iterator const& lhs,
||
lhs
.
type
()
->
equals
(
lhs
.
value
(),
rhs
.
second
));
}
inline
bool
full_eq_v2
(
type_value_pair
const
&
lhs
,
abstract_tuple
::
const_iterator
const
&
rhs
)
{
return
full_eq
(
rhs
,
lhs
);
}
inline
bool
full_eq_v3
(
abstract_tuple
::
const_iterator
const
&
lhs
,
abstract_tuple
::
const_iterator
const
&
rhs
)
{
return
lhs
.
type
()
==
rhs
.
type
()
&&
lhs
.
type
()
->
equals
(
lhs
.
value
(),
rhs
.
value
());
}
inline
bool
values_only_eq
(
abstract_tuple
::
const_iterator
const
&
lhs
,
type_value_pair
const
&
rhs
)
{
...
...
@@ -167,12 +186,24 @@ inline bool values_only_eq(abstract_tuple::const_iterator const& lhs,
||
lhs
.
type
()
->
equals
(
lhs
.
value
(),
rhs
.
second
);
}
inline
bool
values_only_eq_v2
(
type_value_pair
const
&
lhs
,
abstract_tuple
::
const_iterator
const
&
rhs
)
{
return
values_only_eq
(
rhs
,
lhs
);
}
inline
bool
types_only_eq
(
abstract_tuple
::
const_iterator
const
&
lhs
,
type_value_pair
const
&
rhs
)
{
return
lhs
.
type
()
==
rhs
.
first
;
}
inline
bool
types_only_eq_v2
(
type_value_pair
const
&
lhs
,
abstract_tuple
::
const_iterator
const
&
rhs
)
{
return
lhs
.
first
==
rhs
.
type
();
}
}
}
// namespace cppa::detail
#endif // ABSTRACT_TUPLE_HPP
cppa/detail/converted_thread_context.hpp
View file @
a9300af4
...
...
@@ -75,9 +75,9 @@ class converted_thread_context : public abstract_actor<local_actor>
void
enqueue
(
actor
*
sender
,
any_tuple
const
&
msg
)
/*override*/
;
void
dequeue
(
invoke_rules
&
rules
)
/*override*/
;
void
dequeue
(
behavior
&
rules
)
/*override*/
;
void
dequeue
(
timed_invoke_rules
&
rules
)
/*override*/
;
void
dequeue
(
partial_function
&
rules
)
/*override*/
;
inline
decltype
(
m_mailbox
)
&
mailbox
()
{
...
...
@@ -97,7 +97,7 @@ class converted_thread_context : public abstract_actor<local_actor>
// returns true if node->msg was accepted by rules
bool
dq
(
queue_node_ptr
&
node
,
invoke_rules_base
&
rules
,
partial_function
&
rules
,
queue_node_buffer
&
buffer
);
throw_on_exit_result
throw_on_exit
(
any_tuple
const
&
msg
);
...
...
cppa/detail/decorated_tuple.hpp
View file @
a9300af4
...
...
@@ -102,7 +102,12 @@ class decorated_tuple : public abstract_tuple
return
m_decorated
->
type_at
(
m_mapping
[
pos
]);
}
std
::
type_info
const
*
values_type_list
()
const
void
const
*
type_token
()
const
{
return
detail
::
static_type_list
<
ElementTypes
...
>::
list
;
}
std
::
type_info
const
*
impl_type
()
const
{
return
detail
::
static_type_list
<
ElementTypes
...
>::
list
;
}
...
...
cppa/detail/empty_tuple.hpp
View file @
a9300af4
...
...
@@ -46,8 +46,8 @@ struct empty_tuple : 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
;
std
::
type_info
const
*
values_type_list
()
const
;
std
::
type_info
const
*
impl_type
()
const
;
void
const
*
type_token
()
const
;
};
...
...
cppa/detail/invokable.hpp
View file @
a9300af4
...
...
@@ -32,6 +32,7 @@
#define INVOKABLE_HPP
#include <vector>
#include <memory>
#include <cstddef>
#include <cstdint>
...
...
@@ -47,87 +48,81 @@
#include "cppa/detail/intermediate.hpp"
// forward declaration
namespace
cppa
{
class
any_tuple
;
}
namespace
cppa
{
class
any_tuple
;
class
partial_function
;
}
namespace
cppa
{
namespace
detail
{
class
invokable
_base
class
invokable
{
invokable
_base
(
invokable_bas
e
const
&
)
=
delete
;
invokable
_base
&
operator
=
(
invokable_bas
e
const
&
)
=
delete
;
invokable
(
invokabl
e
const
&
)
=
delete
;
invokable
&
operator
=
(
invokabl
e
const
&
)
=
delete
;
public:
invokable_base
()
=
default
;
virtual
~
invokable_base
();
invokable
()
=
default
;
virtual
~
invokable
();
virtual
bool
invoke
(
any_tuple
const
&
)
const
=
0
;
// Suppress type checking.
virtual
bool
unsafe_invoke
(
any_tuple
const
&
value
)
const
=
0
;
// Checks whether the types of @p value match the pattern.
virtual
bool
types_match
(
any_tuple
const
&
value
)
const
=
0
;
// Checks whether this invokable could be invoked with @p value.
virtual
bool
could_invoke
(
any_tuple
const
&
value
)
const
=
0
;
// Prepare this invokable.
virtual
intermediate
*
get_intermediate
(
any_tuple
const
&
value
)
=
0
;
// Prepare this invokable and suppress type checking.
virtual
intermediate
*
get_unsafe_intermediate
(
any_tuple
const
&
value
)
=
0
;
};
class
timed_invokable
:
public
invokable_base
template
<
class
Tuple
,
class
Pattern
>
struct
abstract_invokable
:
public
invokable
{
util
::
duration
m_timeout
;
protected:
timed_invokable
(
util
::
duration
const
&
);
public:
inline
util
::
duration
const
&
timeout
()
const
std
::
unique_ptr
<
Pattern
>
m_pattern
;
abstract_invokable
(
std
::
unique_ptr
<
Pattern
>&&
pptr
)
:
m_pattern
(
std
::
move
(
pptr
))
{
return
m_timeout
;
}
};
template
<
class
TargetFun
>
class
timed_invokable_impl
:
public
timed_invokable
{
typedef
timed_invokable
super
;
TargetFun
m_target
;
public:
template
<
typename
F
>
timed_invokable_impl
(
util
::
duration
const
&
d
,
F
&&
fun
)
:
super
(
d
),
m_target
(
std
::
forward
<
F
>
(
fun
))
bool
types_match
(
any_tuple
const
&
value
)
const
{
return
match_types
(
value
,
*
m_pattern
);
}
bool
invoke
(
any_tuple
const
&
)
const
bool
could_invoke
(
any_tuple
const
&
value
)
const
{
m_target
();
return
true
;
return
match
(
value
,
*
m_pattern
);
}
};
class
invokable
:
public
invokable_base
template
<
bool
CheckValues
,
size_t
NumArgs
,
typename
Fun
,
class
Tuple
,
class
Pattern
>
class
invokable_impl
:
public
abstract_invokable
<
Tuple
,
Pattern
>
{
public:
typedef
abstract_invokable
<
Tuple
,
Pattern
>
super
;
// Checks whether the types of @p value match the pattern.
virtual
bool
types_match
(
any_tuple
const
&
value
)
const
=
0
;
// Checks whether this invokable could be invoked with @p value.
virtual
bool
could_invoke
(
any_tuple
const
&
value
)
const
=
0
;
// Prepare this invokable.
virtual
intermediate
*
get_intermediate
(
any_tuple
const
&
value
)
=
0
;
// Prepare this invokable and suppress type checking.
virtual
intermediate
*
get_unsafe_intermediate
(
any_tuple
const
&
value
)
=
0
;
// Suppress type checking.
virtual
bool
unsafe_invoke
(
any_tuple
const
&
value
)
const
=
0
;
template
<
typename
T
>
inline
bool
invoke_impl
(
option
<
T
>&&
tup
)
const
{
if
(
tup
)
{
util
::
apply_tuple
(
m_iimpl
.
m_fun
,
*
tup
)
;
return
true
;
}
return
false
;
}
};
template
<
typename
T
>
inline
intermediate
*
get_intermediate_impl
(
option
<
T
>&&
tup
)
{
if
(
tup
)
{
m_iimpl
.
m_args
=
std
::
move
(
*
tup
);
return
&
m_iimpl
;
}
return
nullptr
;
}
template
<
size_t
NumArgs
,
typename
Fun
,
class
Tuple
,
class
Pattern
>
class
invokable_impl
:
public
invokable
{
protected:
struct
iimpl
:
intermediate
{
...
...
@@ -137,141 +132,121 @@ class invokable_impl : public invokable
void
invoke
()
{
util
::
apply_tuple
(
m_fun
,
m_args
);
}
}
m_iimpl
;
std
::
unique_ptr
<
Pattern
>
m_pattern
;
public:
template
<
typename
F
>
invokable_impl
(
F
&&
fun
,
std
::
unique_ptr
<
Pattern
>&&
pptr
)
:
m_iimpl
(
std
::
forward
<
F
>
(
fun
)),
m_pattern
(
std
::
move
(
pptr
))
:
super
(
std
::
move
(
pptr
)),
m_iimpl
(
std
::
forward
<
F
>
(
fun
))
{
}
bool
invoke
(
any_tuple
const
&
value
)
const
{
auto
tuple_option
=
tuple_cast
(
value
,
*
m_pattern
);
if
(
tuple_option
)
{
util
::
apply_tuple
(
m_iimpl
.
m_fun
,
*
tuple_option
);
return
true
;
}
return
false
;
return
invoke_impl
(
tuple_cast
(
value
,
*
(
this
->
m_pattern
)));
}
bool
unsafe_invoke
(
any_tuple
const
&
value
)
const
{
auto
tuple_option
=
unsafe_tuple_cast
(
value
,
*
m_pattern
);
if
(
tuple_option
)
{
util
::
apply_tuple
(
m_iimpl
.
m_fun
,
*
tuple_option
);
return
true
;
}
return
false
;
return
invoke_impl
(
unsafe_tuple_cast
(
value
,
*
(
this
->
m_pattern
)));
}
bool
types_match
(
any_tuple
const
&
value
)
const
intermediate
*
get_intermediate
(
any_tuple
const
&
value
)
{
return
match_types
(
value
,
*
m_pattern
);
return
get_intermediate_impl
(
tuple_cast
(
value
,
*
(
this
->
m_pattern
))
);
}
bool
could_invoke
(
any_tuple
const
&
value
)
const
intermediate
*
get_unsafe_intermediate
(
any_tuple
const
&
value
)
{
return
match
(
value
,
*
m_pattern
);
return
get_intermediate_impl
(
unsafe_tuple_cast
(
value
,
*
(
this
->
m_pattern
))
);
}
intermediate
*
get_intermediate
(
any_tuple
const
&
value
)
{
auto
tuple_option
=
tuple_cast
(
value
,
*
m_pattern
);
if
(
tuple_option
)
};
template
<
size_t
NumArgs
,
typename
Fun
,
class
Tuple
,
class
Pattern
>
struct
invokable_impl
<
false
,
NumArgs
,
Fun
,
Tuple
,
Pattern
>
:
public
invokable_impl
<
true
,
NumArgs
,
Fun
,
Tuple
,
Pattern
>
{
typedef
invokable_impl
<
true
,
NumArgs
,
Fun
,
Tuple
,
Pattern
>
super
;
template
<
typename
F
>
invokable_impl
(
F
&&
fun
,
std
::
unique_ptr
<
Pattern
>&&
pptr
)
:
super
(
std
::
forward
<
F
>
(
fun
),
std
::
move
(
pptr
))
{
m_iimpl
.
m_args
=
std
::
move
(
*
tuple_option
);
return
&
m_iimpl
;
}
return
nullptr
;
bool
unsafe_invoke
(
any_tuple
const
&
value
)
const
{
auto
tup
=
forced_tuple_cast
(
value
,
*
(
this
->
m_pattern
));
util
::
apply_tuple
((
this
->
m_iimpl
).
m_fun
,
tup
);
return
true
;
}
intermediate
*
get_unsafe_intermediate
(
any_tuple
const
&
value
)
{
auto
x
=
unsafe_tuple_cast
(
value
,
*
m_pattern
);
if
(
x
)
{
m_iimpl
.
m_args
=
std
::
move
(
*
x
);
return
&
m_iimpl
;
(
this
->
m_iimpl
).
m_args
=
forced_tuple_cast
(
value
,
*
(
this
->
m_pattern
));
return
&
(
this
->
m_iimpl
);
}
return
nullptr
;
}
};
template
<
typename
Fun
,
class
Tuple
,
class
Pattern
>
class
invokable_impl
<
0
,
Fun
,
Tuple
,
Pattern
>
:
public
invokable
class
invokable_impl
<
true
,
0
,
Fun
,
Tuple
,
Pattern
>
:
public
abstract_invokable
<
Tuple
,
Pattern
>
{
typedef
abstract_invokable
<
Tuple
,
Pattern
>
super
;
template
<
typename
...
P
>
inline
bool
unsafe_vmatch
(
any_tuple
const
&
t
,
pattern
<
P
...
>
const
&
p
)
const
{
return
matcher
<
pattern
<
P
...
>::
wildcard_pos
,
P
...
>::
vmatch
(
t
,
p
);
}
protected:
struct
iimpl
:
intermediate
{
Fun
m_fun
;
template
<
typename
F
>
iimpl
(
F
&&
fun
)
:
m_fun
(
std
::
forward
<
F
>
(
fun
))
{
}
void
invoke
()
{
m_fun
();
}
inline
bool
operator
()()
const
{
m_fun
();
return
true
;
}
}
m_iimpl
;
std
::
unique_ptr
<
Pattern
>
m_pattern
;
template
<
typename
...
P
>
inline
bool
unsafe_vmatch
(
any_tuple
const
&
t
,
pattern
<
P
...
>
const
&
p
)
const
{
return
p
.
has_values
()
==
false
||
matcher
<
Pattern
::
wildcard_pos
,
P
...
>::
vmatch
(
t
,
p
);
}
public:
template
<
typename
F
>
invokable_impl
(
F
&&
fun
,
std
::
unique_ptr
<
Pattern
>&&
pptr
)
:
m_iimpl
(
std
::
forward
<
F
>
(
fun
)),
m_pattern
(
std
::
move
(
pptr
))
:
super
(
std
::
move
(
pptr
)),
m_iimpl
(
std
::
forward
<
F
>
(
fun
))
{
}
bool
invoke
(
any_tuple
const
&
data
)
const
{
if
(
match
(
data
,
*
m_pattern
))
{
m_iimpl
.
m_fun
();
return
true
;
}
return
false
;
return
match
(
data
,
*
(
this
->
m_pattern
))
?
m_iimpl
()
:
false
;
}
bool
unsafe_invoke
(
any_tuple
const
&
value
)
const
{
if
(
unsafe_vmatch
(
value
,
*
m_pattern
))
{
m_iimpl
.
m_fun
();
return
true
;
return
unsafe_vmatch
(
value
,
*
(
this
->
m_pattern
))
?
m_iimpl
()
:
false
;
}
return
false
;
}
bool
types_match
(
any_tuple
const
&
value
)
const
intermediate
*
get_intermediate
(
any_tuple
const
&
value
)
{
return
match
_types
(
value
,
*
m_pattern
)
;
return
match
(
value
,
*
(
this
->
m_pattern
))
?
&
m_iimpl
:
nullptr
;
}
bool
could_invoke
(
any_tuple
const
&
value
)
const
intermediate
*
get_unsafe_intermediate
(
any_tuple
const
&
value
)
{
return
match
(
value
,
*
m_pattern
)
;
return
unsafe_vmatch
(
value
,
*
(
this
->
m_pattern
))
?
&
m_iimpl
:
nullptr
;
}
};
intermediate
*
get_intermediate
(
any_tuple
const
&
value
)
template
<
typename
Fun
,
class
Tuple
,
class
Pattern
>
struct
invokable_impl
<
false
,
0
,
Fun
,
Tuple
,
Pattern
>
:
public
invokable_impl
<
true
,
0
,
Fun
,
Tuple
,
Pattern
>
{
typedef
invokable_impl
<
true
,
0
,
Fun
,
Tuple
,
Pattern
>
super
;
template
<
typename
...
Args
>
invokable_impl
(
Args
&&
...
args
)
:
super
(
std
::
forward
<
Args
>
(
args
)...)
{
}
bool
unsafe_invoke
(
any_tuple
const
&
)
const
{
return
match
(
value
,
*
m_pattern
)
?
&
m_iimpl
:
nullptr
;
return
(
this
->
m_iimpl
)()
;
}
intermediate
*
get_unsafe_intermediate
(
any_tuple
const
&
value
)
intermediate
*
get_unsafe_intermediate
(
any_tuple
const
&
)
{
return
unsafe_vmatch
(
value
,
*
m_pattern
)
?
&
m_iimpl
:
nullptr
;
return
&
(
this
->
m_iimpl
)
;
}
};
template
<
typename
Fun
,
class
Pattern
>
...
...
@@ -280,15 +255,20 @@ struct select_invokable_impl
typedef
typename
util
::
get_arg_types
<
Fun
>::
types
arg_types
;
typedef
typename
Pattern
::
filtered_types
filtered_types
;
typedef
typename
tuple_from_type_list
<
filtered_types
>::
type
tuple_type
;
typedef
invokable_impl
<
arg_types
::
size
,
Fun
,
tuple_type
,
Pattern
>
type
;
typedef
invokable_impl
<
true
,
arg_types
::
size
,
Fun
,
tuple_type
,
Pattern
>
type1
;
typedef
invokable_impl
<
false
,
arg_types
::
size
,
Fun
,
tuple_type
,
Pattern
>
type2
;
};
template
<
typename
Fun
,
class
Pattern
>
std
::
unique_ptr
<
invokable
>
get_invokable_impl
(
Fun
&&
fun
,
std
::
unique_ptr
<
Pattern
>&&
pptr
)
{
typedef
typename
select_invokable_impl
<
Fun
,
Pattern
>::
type
result
;
return
std
::
unique_ptr
<
invokable
>
(
new
result
(
std
::
forward
<
Fun
>
(
fun
),
typedef
select_invokable_impl
<
Fun
,
Pattern
>
result
;
bool
check_values
=
pptr
->
has_values
();
return
std
::
unique_ptr
<
invokable
>
(
check_values
?
new
typename
result
::
type1
(
std
::
forward
<
Fun
>
(
fun
),
std
::
move
(
pptr
))
:
new
typename
result
::
type2
(
std
::
forward
<
Fun
>
(
fun
),
std
::
move
(
pptr
)));
}
...
...
cppa/detail/object_array.hpp
View file @
a9300af4
...
...
@@ -68,7 +68,9 @@ class object_array : public abstract_tuple
uniform_type_info
const
*
type_at
(
size_t
pos
)
const
;
std
::
type_info
const
*
values_type_list
()
const
;
void
const
*
type_token
()
const
;
std
::
type_info
const
*
impl_type
()
const
;
};
...
...
cppa/detail/receive_loop_helper.hpp
View file @
a9300af4
...
...
@@ -36,7 +36,12 @@
#include "cppa/self.hpp"
#include "cppa/behavior.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/invoke_rules.hpp"
#include "cppa/partial_function.hpp"
#include "cppa/util/tbind.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/detail/invokable.hpp"
namespace
cppa
{
namespace
detail
{
...
...
@@ -47,54 +52,33 @@ struct receive_while_helper
Statement
m_stmt
;
template
<
typename
S
>
receive_while_helper
(
S
&&
stmt
)
:
m_stmt
(
std
::
forward
<
S
>
(
stmt
))
{
}
receive_while_helper
(
S
&&
stmt
)
:
m_stmt
(
std
::
forward
<
S
>
(
stmt
))
{
}
void
operator
()(
invoke_rules
&
rules
)
void
operator
()(
behavior
&
bhvr
)
{
local_actor
*
sptr
=
self
;
while
(
m_stmt
())
{
sptr
->
dequeue
(
rules
);
}
}
void
operator
()(
invoke_rules
&&
rules
)
{
invoke_rules
tmp
(
std
::
move
(
rules
));
(
*
this
)(
tmp
);
while
(
m_stmt
())
sptr
->
dequeue
(
bhvr
);
}
void
operator
()(
timed_invoke_rules
&
rules
)
void
operator
()(
partial_function
&
fun
)
{
local_actor
*
sptr
=
self
;
while
(
m_stmt
())
{
sptr
->
dequeue
(
rules
);
}
while
(
m_stmt
())
sptr
->
dequeue
(
fun
);
}
void
operator
()(
timed_invoke_rules
&&
rules
)
void
operator
()(
behavior
&&
bhvr
)
{
timed_invoke_rules
tmp
(
std
::
move
(
rules
))
;
behavior
tmp
{
std
::
move
(
bhvr
)}
;
(
*
this
)(
tmp
);
}
template
<
typename
Arg0
,
typename
...
Args
>
void
operator
()(
invoke_rules
&
rules
,
Arg0
&&
arg0
,
Args
&&
...
args
)
template
<
typename
...
Args
>
void
operator
()(
partial_function
&&
arg0
,
Args
&&
...
args
)
{
(
*
this
)(
rules
.
splice
(
std
::
forward
<
Arg0
>
(
arg0
)),
std
::
forward
<
Args
>
(
args
)...
);
typename
select_bhvr
<
Args
...
>::
type
tmp
;
(
*
this
)(
tmp
.
splice
(
std
::
move
(
arg0
),
std
::
forward
<
Args
>
(
args
)...)
);
}
template
<
typename
Arg0
,
typename
...
Args
>
void
operator
()(
invoke_rules
&&
rules
,
Arg0
&&
arg0
,
Args
&&
...
args
)
{
invoke_rules
tmp
(
std
::
move
(
rules
));
(
*
this
)(
tmp
.
splice
(
std
::
forward
<
Arg0
>
(
arg0
)),
std
::
forward
<
Args
>
(
args
)...);
}
};
class
do_receive_helper
...
...
@@ -102,44 +86,19 @@ class do_receive_helper
behavior
m_bhvr
;
inline
void
init
(
timed_invoke_rules
&&
bhvr
)
{
m_bhvr
=
std
::
move
(
bhvr
);
}
inline
void
init
(
invoke_rules
&
bhvr
)
{
m_bhvr
=
std
::
move
(
bhvr
);
}
template
<
typename
Arg0
,
typename
...
Args
>
inline
void
init
(
invoke_rules
&
rules
,
Arg0
&&
arg0
,
Args
&&
...
args
)
{
init
(
rules
.
splice
(
std
::
forward
<
Arg0
>
(
arg0
)),
std
::
forward
<
Args
>
(
args
)...);
}
public:
do_receive_helper
(
invoke_rules
&&
rules
)
:
m_bhvr
(
std
::
move
(
rules
))
{
}
do_receive_helper
(
timed_invoke_rules
&&
rules
)
:
m_bhvr
(
std
::
move
(
rules
))
do_receive_helper
(
behavior
&&
bhvr
)
:
m_bhvr
(
std
::
move
(
bhvr
))
{
}
template
<
typename
Arg0
,
typename
...
Args
>
do_receive_helper
(
invoke_rules
&&
rules
,
Arg0
&&
arg0
,
Args
&&
...
args
)
do_receive_helper
(
Arg0
&&
arg0
,
Args
&&
...
args
)
{
invoke_rules
tmp
(
std
::
move
(
rules
));
init
(
tmp
.
splice
(
std
::
forward
<
Arg0
>
(
arg0
)),
std
::
forward
<
Args
>
(
args
)...);
m_bhvr
.
splice
(
std
::
forward
<
Arg0
>
(
arg0
),
std
::
forward
<
Args
>
(
args
)...);
}
do_receive_helper
(
do_receive_helper
&&
other
)
:
m_bhvr
(
std
::
move
(
other
.
m_bhvr
))
{
}
do_receive_helper
(
do_receive_helper
&&
)
=
default
;
template
<
typename
Statement
>
void
until
(
Statement
&&
stmt
)
...
...
@@ -147,11 +106,11 @@ class do_receive_helper
static_assert
(
std
::
is_same
<
bool
,
decltype
(
stmt
())
>::
value
,
"functor or function does not return a boolean"
);
local_actor
*
sptr
=
self
;
if
(
m_bhvr
.
is_left
())
if
(
m_bhvr
.
timeout
().
valid
())
{
do
{
sptr
->
dequeue
(
m_bhvr
.
left
()
);
sptr
->
dequeue
(
m_bhvr
);
}
while
(
stmt
()
==
false
);
}
...
...
@@ -159,7 +118,7 @@ class do_receive_helper
{
do
{
sptr
->
dequeue
(
m_bhvr
.
right
());
sptr
->
dequeue
(
m_bhvr
.
get_partial_function
());
}
while
(
stmt
()
==
false
);
}
...
...
cppa/detail/tuple_vals.hpp
View file @
a9300af4
...
...
@@ -112,7 +112,12 @@ class tuple_vals : public abstract_tuple
return
abstract_tuple
::
equals
(
other
);
}
std
::
type_info
const
*
values_type_list
()
const
void
const
*
type_token
()
const
{
return
detail
::
static_type_list
<
ElementTypes
...
>::
list
;
}
std
::
type_info
const
*
impl_type
()
const
{
return
detail
::
static_type_list
<
ElementTypes
...
>::
list
;
}
...
...
cppa/detail/yielding_actor.hpp
View file @
a9300af4
...
...
@@ -79,9 +79,9 @@ class yielding_actor : public abstract_scheduled_actor
~
yielding_actor
()
/*override*/
;
void
dequeue
(
invoke_rules
&
rules
)
/*override*/
;
void
dequeue
(
behavior
&
rules
)
/*override*/
;
void
dequeue
(
timed_invoke_rules
&
rules
)
/*override*/
;
void
dequeue
(
partial_function
&
rules
)
/*override*/
;
void
resume
(
util
::
fiber
*
from
,
resume_callback
*
callback
)
/*override*/
;
...
...
cppa/event_based_actor.hpp
View file @
a9300af4
...
...
@@ -44,9 +44,7 @@ class event_based_actor : public event_based_actor_base<event_based_actor>
typedef
abstract_event_based_actor
::
stack_element
stack_element
;
// has_ownership == false
void
do_become
(
behavior
*
bhvr
);
void
do_become
(
invoke_rules
*
bhvr
,
bool
has_ownership
);
void
do_become
(
timed_invoke_rules
*
bhvr
,
bool
has_ownership
);
void
do_become
(
behavior
*
bhvr
,
bool
has_ownership
);
public:
...
...
cppa/event_based_actor_base.hpp
View file @
a9300af4
...
...
@@ -42,64 +42,26 @@ class event_based_actor_base : public abstract_event_based_actor
typedef
abstract_event_based_actor
super
;
inline
void
become_impl
(
invoke_rules
&
rules
)
{
become
(
std
::
move
(
rules
));
}
inline
void
become_impl
(
timed_invoke_rules
&&
rules
)
{
become
(
std
::
move
(
rules
));
}
template
<
typename
Head
,
typename
...
Tail
>
void
become_impl
(
invoke_rules
&
rules
,
Head
&&
head
,
Tail
&&
...
tail
)
{
become_impl
(
rules
.
splice
(
std
::
forward
<
Head
>
(
head
)),
std
::
forward
<
Tail
>
(
tail
)...);
}
inline
Derived
*
d_this
()
{
return
static_cast
<
Derived
*>
(
this
);
}
protected:
inline
void
become
(
behavior
*
bhvr
)
{
d_this
()
->
do_become
(
bhvr
);
}
inline
void
become
(
invoke_rules
*
bhvr
)
{
d_this
()
->
do_become
(
bhvr
,
false
);
}
inline
void
become
(
timed_invoke_rules
*
bhvr
)
{
d_this
()
->
do_become
(
bhvr
,
false
);
}
inline
void
become
(
invoke_rules
&&
bhvr
)
{
d_this
()
->
do_become
(
new
invoke_rules
(
std
::
move
(
bhvr
)),
true
);
}
inline
void
become
(
timed_invoke_rules
&&
bhvr
)
{
d_this
()
->
do_become
(
new
timed_invoke_rules
(
std
::
move
(
bhvr
)),
true
);
}
inline
void
become
(
behavior
&&
bhvr
)
template
<
typename
...
Args
>
void
become
(
partial_function
&&
arg0
,
Args
&&
...
args
)
{
if
(
bhvr
.
is_left
())
become
(
std
::
move
(
bhvr
.
left
()));
else
become
(
std
::
move
(
bhvr
.
right
()));
auto
ptr
=
new
behavior
;
ptr
->
splice
(
std
::
move
(
arg0
),
std
::
forward
<
Args
>
(
args
)...);
d_this
()
->
do_become
(
ptr
,
true
);
}
template
<
typename
Head
,
typename
...
Tail
>
void
become
(
invoke_rules
&&
rules
,
Head
&&
head
,
Tail
&&
...
tail
)
inline
void
become
(
behavior
&&
arg0
)
{
invoke_rules
tmp
(
std
::
move
(
rules
));
become_impl
(
tmp
.
splice
(
std
::
forward
<
Head
>
(
head
)),
std
::
forward
<
Tail
>
(
tail
)...);
d_this
()
->
do_become
(
new
behavior
(
std
::
move
(
arg0
)),
true
);
}
};
...
...
cppa/local_actor.hpp
View file @
a9300af4
...
...
@@ -32,8 +32,9 @@
#define CONTEXT_HPP
#include "cppa/actor.hpp"
#include "cppa/behavior.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/
invoke_rules
.hpp"
#include "cppa/
partial_function
.hpp"
#include "cppa/util/single_reader_queue.hpp"
namespace
cppa
{
...
...
@@ -70,19 +71,19 @@ class local_actor : public actor
virtual
void
quit
(
std
::
uint32_t
reason
)
=
0
;
/**
* @brief Removes the first element from the queue that is matched
* by @p rules and invokes the corresponding callback.
* @brief
* @param rules
* @warning Call only from the owner of the queue.
*/
virtual
void
dequeue
(
invoke_rules
&
rules
)
=
0
;
virtual
void
dequeue
(
behavior
&
rules
)
=
0
;
/**
* @brief
* @brief Removes the first element from the queue that is matched
* by @p rules and invokes the corresponding callback.
* @param rules
* @warning Call only from the owner of the queue.
*/
virtual
void
dequeue
(
timed_invoke_rules
&
rules
)
=
0
;
virtual
void
dequeue
(
partial_function
&
rules
)
=
0
;
inline
bool
trap_exit
()
const
;
...
...
cppa/match.hpp
View file @
a9300af4
...
...
@@ -210,14 +210,16 @@ struct matcher<wildcard_position::nil, T...>
static
inline
bool
tmatch
(
any_tuple
const
&
tup
)
{
// match implementation type if possible
auto
vals
=
tup
.
values_type_list
();
auto
prns
=
detail
::
static_type_list
<
T
...
>::
list
;
if
(
vals
==
prns
||
*
vals
==
*
prns
)
auto
impl
=
tup
.
impl_type
();
// the impl_type of both decorated_tuple and tuple_vals
// is &typeid(type_list<T...>)
auto
tinf
=
detail
::
static_type_list
<
T
...
>::
list
;
if
(
impl
==
tinf
||
*
impl
==
*
tinf
)
{
return
true
;
}
// always use a full dynamic match for object arrays
else
if
(
*
vals
==
typeid
(
detail
::
object_array
)
else
if
(
*
impl
==
typeid
(
detail
::
object_array
)
&&
tup
.
size
()
==
sizeof
...(
T
))
{
auto
&
tarr
=
detail
::
static_types_array
<
T
...
>::
arr
;
...
...
@@ -241,8 +243,9 @@ struct matcher<wildcard_position::nil, T...>
static
inline
bool
vmatch
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
ptrn
)
{
return
std
::
equal
(
tup
.
begin
(),
tup
.
end
(),
ptrn
.
begin
(),
detail
::
values_only_eq
);
CPPA_REQUIRE
(
tup
.
size
()
==
sizeof
...(
T
));
return
std
::
equal
(
ptrn
.
begin
(),
ptrn
.
vend
(),
tup
.
begin
(),
detail
::
values_only_eq_v2
);
}
};
...
...
@@ -277,9 +280,8 @@ struct matcher<wildcard_position::trailing, T...>
static
inline
bool
vmatch
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
ptrn
)
{
auto
begin
=
tup
.
begin
();
return
std
::
equal
(
begin
,
begin
+
size
,
ptrn
.
begin
(),
detail
::
values_only_eq
);
return
std
::
equal
(
ptrn
.
begin
(),
ptrn
.
vend
(),
tup
.
begin
(),
detail
::
values_only_eq_v2
);
}
};
...
...
@@ -334,11 +336,12 @@ struct matcher<wildcard_position::leading, T...>
static
inline
bool
vmatch
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
ptrn
)
{
auto
begin
=
tup
.
begin
();
begin
+=
(
tup
.
size
()
-
size
);
return
std
::
equal
(
begin
,
tup
.
end
(),
ptrn
.
begin
()
+
1
,
// skip 'anything'
detail
::
values_only_eq
);
auto
tbegin
=
tup
.
begin
();
// skip unmatched elements
tbegin
+=
(
tup
.
size
()
-
size
);
// skip leading wildcard ++(ptr.begin())
return
std
::
equal
(
++
(
ptrn
.
begin
()),
ptrn
.
vend
(),
tbegin
,
detail
::
values_only_eq_v2
);
}
};
...
...
cppa/on.hpp
View file @
a9300af4
...
...
@@ -37,8 +37,9 @@
#include "cppa/atom.hpp"
#include "cppa/pattern.hpp"
#include "cppa/anything.hpp"
#include "cppa/behavior.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/
invoke_rules
.hpp"
#include "cppa/
partial_function
.hpp"
#include "cppa/util/duration.hpp"
#include "cppa/util/type_list.hpp"
...
...
@@ -54,28 +55,27 @@
namespace
cppa
{
namespace
detail
{
class
timed_invoke_rul
e_builder
class
behavior_rvalu
e_builder
{
util
::
duration
m_timeout
;
public:
constexpr
timed_invoke_rul
e_builder
(
util
::
duration
const
&
d
)
:
m_timeout
(
d
)
constexpr
behavior_rvalu
e_builder
(
util
::
duration
const
&
d
)
:
m_timeout
(
d
)
{
}
template
<
typename
F
>
timed_invoke_rules
operator
>>
(
F
&&
f
)
behavior
operator
>>
(
F
&&
f
)
{
typedef
timed_invokable_impl
<
F
>
impl
;
return
timed_invokable_ptr
(
new
impl
(
m_timeout
,
std
::
forward
<
F
>
(
f
)));
return
{
m_timeout
,
std
::
function
<
void
()
>
{
std
::
forward
<
F
>
(
f
)}};
}
};
template
<
typename
...
TypeList
>
class
invoke_rul
e_builder
class
rvalu
e_builder
{
typedef
util
::
arg_match_t
arg_match_t
;
...
...
@@ -85,7 +85,8 @@ class invoke_rule_builder
static
constexpr
bool
is_complete
=
!
std
::
is_same
<
arg_match_t
,
typename
raw_types
::
back
>::
value
;
typedef
typename
util
::
if_else_c
<
is_complete
==
false
,
typedef
typename
util
::
if_else_c
<
is_complete
==
false
,
typename
util
::
tl_pop_back
<
raw_types
>::
type
,
util
::
wrapped
<
raw_types
>
>::
type
types
;
...
...
@@ -103,13 +104,13 @@ class invoke_rule_builder
std
::
unique_ptr
<
pattern_type
>
m_ptr
;
template
<
typename
F
>
invoke_rules
cr_rules
(
F
&&
f
,
std
::
integral_constant
<
bool
,
true
>
)
partial_function
cr_rvalue
(
F
&&
f
,
std
::
integral_constant
<
bool
,
true
>
)
{
return
get_invokable_impl
(
std
::
forward
<
F
>
(
f
),
std
::
move
(
m_ptr
));
}
template
<
typename
F
>
invoke_rules
cr_rules
(
F
&&
f
,
std
::
integral_constant
<
bool
,
false
>
)
partial_function
cr_rvalue
(
F
&&
f
,
std
::
integral_constant
<
bool
,
false
>
)
{
using
namespace
::
cppa
::
util
;
typedef
typename
get_callable_trait
<
F
>::
type
ctrait
;
...
...
@@ -125,32 +126,31 @@ class invoke_rule_builder
public:
template
<
typename
...
Args
>
invoke_rule_builder
(
Args
const
&
...
args
)
:
m_ptr
(
new
pattern_type
(
args
...))
rvalue_builder
(
Args
const
&
...
args
)
:
m_ptr
(
new
pattern_type
(
args
...))
{
}
template
<
typename
F
>
invoke_rules
operator
>>
(
F
&&
f
)
partial_function
operator
>>
(
F
&&
f
)
{
std
::
integral_constant
<
bool
,
is_complete
>
token
;
return
cr_r
ules
(
std
::
forward
<
F
>
(
f
),
token
);
std
::
integral_constant
<
bool
,
is_complete
>
token
;
return
cr_r
value
(
std
::
forward
<
F
>
(
f
),
token
);
}
};
class
on_the_fly_
invoke_rul
e_builder
class
on_the_fly_
rvalu
e_builder
{
public:
constexpr
on_the_fly_
invoke_rul
e_builder
()
constexpr
on_the_fly_
rvalu
e_builder
()
{
}
template
<
typename
F
>
invoke_rules
operator
>>
(
F
&&
f
)
const
partial_function
operator
>>
(
F
&&
f
)
const
{
using
namespace
::
cppa
::
util
;
typedef
typename
get_callable_trait
<
F
>::
type
ctrait
;
...
...
@@ -180,10 +180,10 @@ typedef typename detail::boxed<util::arg_match_t>::type boxed_arg_match_t;
constexpr
boxed_arg_match_t
arg_match
=
boxed_arg_match_t
();
constexpr
detail
::
on_the_fly_
invoke_rul
e_builder
on_arg_match
;
constexpr
detail
::
on_the_fly_
rvalu
e_builder
on_arg_match
;
template
<
typename
Arg0
,
typename
...
Args
>
detail
::
invoke_rul
e_builder
<
typename
detail
::
unboxed
<
Arg0
>::
type
,
detail
::
rvalu
e_builder
<
typename
detail
::
unboxed
<
Arg0
>::
type
,
typename
detail
::
unboxed
<
Args
>::
type
...
>
on
(
Arg0
const
&
arg0
,
Args
const
&
...
args
)
{
...
...
@@ -191,25 +191,25 @@ on(Arg0 const& arg0, Args const&... args)
}
template
<
typename
...
TypeList
>
detail
::
invoke_rul
e_builder
<
TypeList
...
>
on
()
detail
::
rvalu
e_builder
<
TypeList
...
>
on
()
{
return
{
};
}
template
<
atom_value
A0
,
typename
...
TypeList
>
detail
::
invoke_rul
e_builder
<
atom_value
,
TypeList
...
>
on
()
detail
::
rvalu
e_builder
<
atom_value
,
TypeList
...
>
on
()
{
return
{
A0
};
}
template
<
atom_value
A0
,
atom_value
A1
,
typename
...
TypeList
>
detail
::
invoke_rul
e_builder
<
atom_value
,
atom_value
,
TypeList
...
>
on
()
detail
::
rvalu
e_builder
<
atom_value
,
atom_value
,
TypeList
...
>
on
()
{
return
{
A0
,
A1
};
}
template
<
atom_value
A0
,
atom_value
A1
,
atom_value
A2
,
typename
...
TypeList
>
detail
::
invoke_rul
e_builder
<
atom_value
,
atom_value
,
detail
::
rvalu
e_builder
<
atom_value
,
atom_value
,
atom_value
,
TypeList
...
>
on
()
{
return
{
A0
,
A1
,
A2
};
...
...
@@ -218,20 +218,20 @@ detail::invoke_rule_builder<atom_value, atom_value,
template
<
atom_value
A0
,
atom_value
A1
,
atom_value
A2
,
atom_value
A3
,
typename
...
TypeList
>
detail
::
invoke_rul
e_builder
<
atom_value
,
atom_value
,
atom_value
,
detail
::
rvalu
e_builder
<
atom_value
,
atom_value
,
atom_value
,
atom_value
,
TypeList
...
>
on
()
{
return
{
A0
,
A1
,
A2
,
A3
};
}
template
<
class
Rep
,
class
Period
>
constexpr
detail
::
timed_invoke_rul
e_builder
after
(
const
std
::
chrono
::
duration
<
Rep
,
Period
>
&
d
)
constexpr
detail
::
behavior_rvalu
e_builder
after
(
std
::
chrono
::
duration
<
Rep
,
Period
>
const
&
d
)
{
return
{
util
::
duration
(
d
)
};
}
inline
detail
::
invoke_rul
e_builder
<
anything
>
others
()
inline
detail
::
rvalu
e_builder
<
anything
>
others
()
{
return
{
};
}
...
...
cppa/
util
.hpp
→
cppa/
partial_function
.hpp
View file @
a9300af4
...
...
@@ -28,24 +28,75 @@
\******************************************************************************/
#ifndef UTIL_HPP
#define UTIL_HPP
#include "cppa/util/callable_trait.hpp"
#include "cppa/util/compare_tuples.hpp"
#include "cppa/util/conjunction.hpp"
#include "cppa/util/disjunction.hpp"
#include "cppa/util/enable_if.hpp"
#include "cppa/util/has_copy_member_fun.hpp"
#include "cppa/util/is_comparable.hpp"
#include "cppa/util/is_copyable.hpp"
#include "cppa/util/is_legal_tuple_type.hpp"
#include "cppa/util/is_one_of.hpp"
#include "cppa/util/remove_const_reference.hpp"
#include "cppa/util/replace_type.hpp"
#include "cppa/util/single_reader_queue.hpp"
#include "cppa/util/singly_linked_list.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/void_type.hpp"
#endif // UTIL_HPP
#ifndef PARTIAL_FUNCTION_HPP
#define PARTIAL_FUNCTION_HPP
#include <vector>
#include <memory>
#include <utility>
#include "cppa/detail/invokable.hpp"
namespace
cppa
{
class
behavior
;
class
partial_function
{
public:
typedef
std
::
unique_ptr
<
detail
::
invokable
>
invokable_ptr
;
partial_function
()
=
default
;
partial_function
(
partial_function
&&
other
);
partial_function
(
invokable_ptr
&&
ptr
);
bool
defined_at
(
any_tuple
const
&
value
);
void
operator
()(
any_tuple
const
&
value
);
detail
::
invokable
const
*
definition_at
(
any_tuple
const
&
value
);
detail
::
intermediate
*
get_intermediate
(
any_tuple
const
&
value
);
template
<
class
...
Args
>
partial_function
&
splice
(
partial_function
&&
arg0
,
Args
&&
...
args
)
{
auto
&
vec
=
arg0
.
m_funs
;
std
::
move
(
vec
.
begin
(),
vec
.
end
(),
std
::
back_inserter
(
m_funs
));
return
splice
(
std
::
forward
<
Args
>
(
args
)...);
}
inline
partial_function
operator
,(
partial_function
&&
arg
)
{
return
std
::
move
(
splice
(
std
::
move
(
arg
)));
}
behavior
operator
,(
behavior
&&
arg
);
private:
// terminates recursion
inline
partial_function
&
splice
()
{
m_cache
.
clear
();
return
*
this
;
}
typedef
std
::
vector
<
detail
::
invokable
*>
cache_entry
;
typedef
std
::
pair
<
void
const
*
,
cache_entry
>
cache_element
;
std
::
vector
<
invokable_ptr
>
m_funs
;
std
::
vector
<
cache_element
>
m_cache
;
cache_element
m_dummy
;
// binary search dummy
cache_entry
&
get_cache_entry
(
any_tuple
const
&
value
);
};
}
// namespace cppa
#endif // PARTIAL_FUNCTION_HPP
cppa/pattern.hpp
View file @
a9300af4
...
...
@@ -111,10 +111,25 @@ class pattern
typedef
type_value_pair_const_iterator
const_iterator
;
typedef
std
::
reverse_iterator
<
const_iterator
>
reverse_const_iterator
;
const_iterator
begin
()
const
{
return
m_ptrs
;
}
inline
const_iterator
begin
()
const
{
return
m_ptrs
;
}
const_iterator
end
()
const
{
return
m_ptrs
+
size
;
}
inline
const_iterator
end
()
const
{
return
m_ptrs
+
size
;
}
inline
reverse_const_iterator
rbegin
()
const
{
return
reverse_const_iterator
{
end
()};
}
inline
reverse_const_iterator
rend
()
const
{
return
reverse_const_iterator
{
begin
()};
}
inline
const_iterator
vbegin
()
const
{
return
m_vbegin
;
}
inline
const_iterator
vend
()
const
{
return
m_vend
;
}
pattern
()
:
m_has_values
(
false
)
{
...
...
@@ -124,6 +139,7 @@ class pattern
m_ptrs
[
i
].
first
=
arr
[
i
];
m_ptrs
[
i
].
second
=
nullptr
;
}
m_vbegin
=
m_vend
=
begin
();
}
template
<
typename
Arg0
,
typename
...
Args
>
...
...
@@ -152,6 +168,7 @@ class pattern
m_ptrs
[
i
].
first
=
arr
[
i
];
m_ptrs
[
i
].
second
=
nullptr
;
}
init_value_iterators
();
}
inline
bool
has_values
()
const
{
return
m_has_values
;
}
...
...
@@ -174,10 +191,28 @@ class pattern
}
};
void
init_value_iterators
()
{
auto
pred
=
[](
type_value_pair
const
&
tvp
)
{
return
tvp
.
second
!=
0
;
};
auto
last
=
end
();
m_vbegin
=
std
::
find_if
(
begin
(),
last
,
pred
);
if
(
m_vbegin
==
last
)
{
m_vbegin
=
m_vend
=
begin
();
}
else
{
m_vend
=
std
::
find_if
(
rbegin
(),
rend
(),
pred
).
base
();
}
}
detail
::
tdata
<
option
<
Types
>
...
>
m_data
;
bool
m_has_values
;
type_value_pair
m_ptrs
[
size
];
const_iterator
m_vbegin
;
const_iterator
m_vend
;
};
template
<
class
ExtendedType
,
class
BasicType
>
...
...
@@ -189,10 +224,13 @@ ExtendedType* extend_pattern(BasicType const* p)
detail
::
tdata_set
(
et
->
m_data
,
p
->
m_data
);
et
->
m_has_values
=
true
;
typedef
typename
ExtendedType
::
types
extended_types
;
typedef
typename
detail
::
static_types_array_from_type_list
<
extended_types
>::
type
tarr
;
typedef
typename
detail
::
static_types_array_from_type_list
<
extended_types
>::
type
tarr
;
auto
&
arr
=
tarr
::
arr
;
typename
ExtendedType
::
init_helper
f
(
et
->
m_ptrs
,
arr
);
util
::
static_foreach
<
0
,
BasicType
::
size
>::
_
(
et
->
m_data
,
f
);
et
->
init_value_iterators
();
}
return
et
;
}
...
...
cppa/receive.hpp
View file @
a9300af4
...
...
@@ -97,84 +97,42 @@ auto do_receive(behavior& bhvr);
#else // CPPA_DOCUMENTATION
inline
void
receive
(
invoke_rules
&
bhvr
)
{
self
->
dequeue
(
bhvr
);
}
inline
void
receive
(
behavior
&
bhvr
)
{
self
->
dequeue
(
bhvr
);
}
inline
void
receive
(
timed_invoke_rules
&
bhvr
)
{
self
->
dequeue
(
bhvr
);
}
inline
void
receive
(
partial_function
&
fun
)
{
self
->
dequeue
(
fun
);
}
inline
void
receive
(
behavior
&
bhvr
)
inline
void
receive
(
behavior
&
&
arg0
)
{
if
(
bhvr
.
is_left
())
self
->
dequeue
(
bhvr
.
left
())
;
else
self
->
dequeue
(
bhvr
.
right
()
);
behavior
tmp
{
std
::
move
(
arg0
)}
;
receive
(
tmp
);
}
inline
void
receive
(
timed_invoke_rules
&&
bhvr
)
{
timed_invoke_rules
tmp
(
std
::
move
(
bhvr
));
self
->
dequeue
(
tmp
);
}
inline
void
receive
(
invoke_rules
&&
bhvr
)
{
invoke_rules
tmp
(
std
::
move
(
bhvr
));
self
->
dequeue
(
tmp
);
}
template
<
typename
Head
,
typename
...
Tail
>
void
receive
(
invoke_rules
&&
bhvr
,
Head
&&
head
,
Tail
&&
...
tail
)
{
invoke_rules
tmp
(
std
::
move
(
bhvr
));
receive
(
tmp
.
splice
(
std
::
forward
<
Head
>
(
head
)),
std
::
forward
<
Tail
>
(
tail
)...);
}
template
<
typename
Head
,
typename
...
Tail
>
void
receive
(
invoke_rules
&
bhvr
,
Head
&&
head
,
Tail
&&
...
tail
)
template
<
typename
...
Args
>
void
receive
(
partial_function
&&
arg0
,
Args
&&
...
args
)
{
receive
(
bhvr
.
splice
(
std
::
forward
<
Head
>
(
head
)),
std
::
forward
<
Tail
>
(
tail
)...
);
typename
detail
::
select_bhvr
<
Args
...
>::
type
tmp
;
receive
(
tmp
.
splice
(
std
::
move
(
arg0
),
std
::
forward
<
Args
>
(
args
)...)
);
}
void
receive_loop
(
behavior
&
rules
);
void
receive_loop
(
invoke_rules
&
rules
);
void
receive_loop
(
timed_invoke_rules
&
rules
);
void
receive_loop
(
partial_function
&
rules
);
inline
void
receive_loop
(
behavior
&
bhvr
)
inline
void
receive_loop
(
behavior
&
&
arg0
)
{
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
));
behavior
tmp
{
std
::
move
(
arg0
)};
receive_loop
(
tmp
);
}
inline
void
receive_loop
(
timed_invoke_rules
&&
rules
)
{
timed_invoke_rules
tmp
(
std
::
move
(
rules
));
receive_loop
(
tmp
);
}
template
<
typename
Head
,
typename
...
Tail
>
void
receive_loop
(
invoke_rules
&
rules
,
Head
&&
head
,
Tail
&&
...
tail
)
{
receive_loop
(
rules
.
splice
(
std
::
forward
<
Head
>
(
head
)),
std
::
forward
<
Tail
>
(
tail
)...);
}
template
<
typename
Head
,
typename
...
Tail
>
void
receive_loop
(
invoke_rules
&&
rules
,
Head
&&
head
,
Tail
&&
...
tail
)
template
<
typename
...
Args
>
void
receive_loop
(
partial_function
&&
arg0
,
Args
&&
...
args
)
{
invoke_rules
tmp
(
std
::
move
(
rules
));
receive_loop
(
tmp
.
splice
(
std
::
forward
<
Head
>
(
head
)),
std
::
forward
<
Tail
>
(
tail
)...);
typename
detail
::
select_bhvr
<
Args
...
>::
type
tmp
;
receive_loop
(
tmp
.
splice
(
std
::
move
(
arg0
),
std
::
forward
<
Args
>
(
args
)...));
}
template
<
typename
Statement
>
detail
::
receive_while_helper
<
Statement
>
receive_while
(
Statement
&&
stmt
)
detail
::
receive_while_helper
<
Statement
>
receive_while
(
Statement
&&
stmt
)
{
static_assert
(
std
::
is_same
<
bool
,
decltype
(
stmt
())
>::
value
,
"functor or function does not return a boolean"
);
...
...
cppa/stacked_event_based_actor.hpp
View file @
a9300af4
...
...
@@ -42,8 +42,7 @@ class stacked_event_based_actor : public event_based_actor_base<stacked_event_ba
typedef
abstract_event_based_actor
::
stack_element
stack_element
;
void
do_become
(
invoke_rules
*
behavior
,
bool
has_ownership
);
void
do_become
(
timed_invoke_rules
*
behavior
,
bool
has_ownership
);
void
do_become
(
behavior
*
behavior
,
bool
has_ownership
);
protected:
...
...
cppa/util/duration.hpp
View file @
a9300af4
...
...
@@ -71,7 +71,7 @@ class duration
{
}
template
<
class
Rep
,
class
Period
>
template
<
class
Rep
,
class
Period
>
constexpr
duration
(
std
::
chrono
::
duration
<
Rep
,
Period
>
d
)
:
unit
(
get_time_unit_from_period
<
Period
>
()),
count
(
d
.
count
())
{
...
...
@@ -79,6 +79,8 @@ class duration
"only seconds, milliseconds or microseconds allowed"
);
}
inline
bool
valid
()
const
{
return
unit
!=
time_unit
::
none
;
}
time_unit
unit
;
std
::
uint32_t
count
;
...
...
cppa/util/tbind.hpp
View file @
a9300af4
...
...
@@ -33,7 +33,7 @@
namespace
cppa
{
namespace
util
{
template
<
template
<
typename
,
typename
>
class
Tpl
,
typename
Arg1
>
template
<
template
<
typename
,
typename
>
class
Tpl
,
typename
Arg1
>
struct
tbind
{
template
<
typename
Arg2
>
...
...
cppa/util/type_list.hpp
View file @
a9300af4
...
...
@@ -185,7 +185,7 @@ struct tl_first_n
/**
* @brief Tests whether a predicate holds for all elements of a list.
*/
template
<
class
List
,
template
<
typename
>
class
Predicate
>
template
<
class
List
,
template
<
typename
>
class
Predicate
>
struct
tl_forall
{
static
constexpr
bool
value
=
...
...
@@ -193,7 +193,7 @@ struct tl_forall
&&
tl_forall
<
typename
List
::
tail
,
Predicate
>::
value
;
};
template
<
template
<
typename
>
class
Predicate
>
template
<
template
<
typename
>
class
Predicate
>
struct
tl_forall
<
type_list
<>
,
Predicate
>
{
static
constexpr
bool
value
=
true
;
...
...
@@ -202,7 +202,7 @@ struct tl_forall<type_list<>, Predicate>
/**
* @brief Tests whether a predicate holds for some of the elements of a list.
*/
template
<
class
List
,
template
<
typename
>
class
Predicate
>
template
<
class
List
,
template
<
typename
>
class
Predicate
>
struct
tl_exists
{
static
constexpr
bool
value
=
...
...
@@ -210,7 +210,7 @@ struct tl_exists
||
tl_exists
<
typename
List
::
tail
,
Predicate
>::
value
;
};
template
<
template
<
typename
>
class
Predicate
>
template
<
template
<
typename
>
class
Predicate
>
struct
tl_exists
<
type_list
<>
,
Predicate
>
{
static
constexpr
bool
value
=
false
;
...
...
@@ -222,7 +222,7 @@ struct tl_exists<type_list<>, Predicate>
/**
* @brief Counts the number of elements in the list which satisfy a predicate.
*/
template
<
class
List
,
template
<
typename
>
class
Predicate
>
template
<
class
List
,
template
<
typename
>
class
Predicate
>
struct
tl_count
{
static
constexpr
size_t
value
=
...
...
@@ -230,7 +230,7 @@ struct tl_count
+
tl_count
<
typename
List
::
tail
,
Predicate
>::
value
;
};
template
<
template
<
typename
>
class
Predicate
>
template
<
template
<
typename
>
class
Predicate
>
struct
tl_count
<
type_list
<>
,
Predicate
>
{
static
constexpr
size_t
value
=
0
;
...
...
@@ -241,7 +241,7 @@ struct tl_count<type_list<>, Predicate>
/**
* @brief Counts the number of elements in the list which satisfy a predicate.
*/
template
<
class
List
,
template
<
typename
>
class
Predicate
>
template
<
class
List
,
template
<
typename
>
class
Predicate
>
struct
tl_count_not
{
static
constexpr
size_t
value
=
...
...
@@ -249,7 +249,7 @@ struct tl_count_not
+
tl_count_not
<
typename
List
::
tail
,
Predicate
>::
value
;
};
template
<
template
<
typename
>
class
Predicate
>
template
<
template
<
typename
>
class
Predicate
>
struct
tl_count_not
<
type_list
<>
,
Predicate
>
{
static
constexpr
size_t
value
=
0
;
...
...
@@ -260,7 +260,7 @@ struct tl_count_not<type_list<>, Predicate>
/**
* @brief Tests whether a predicate holds for all elements of a zipped list.
*/
template
<
class
ZippedList
,
template
<
typename
,
typename
>
class
Predicate
>
template
<
class
ZippedList
,
template
<
typename
,
typename
>
class
Predicate
>
struct
tl_zipped_forall
{
typedef
typename
ZippedList
::
head
head
;
...
...
@@ -269,7 +269,7 @@ struct tl_zipped_forall
&&
tl_zipped_forall
<
typename
ZippedList
::
tail
,
Predicate
>::
value
;
};
template
<
template
<
typename
,
typename
>
class
Predicate
>
template
<
template
<
typename
,
typename
>
class
Predicate
>
struct
tl_zipped_forall
<
type_list
<>
,
Predicate
>
{
static
constexpr
bool
value
=
true
;
...
...
@@ -294,10 +294,10 @@ struct tl_concat<type_list<ListATypes...>, type_list<ListBTypes...> >
/**
* @brief Applies a "template function" to each element in the list.
*/
template
<
typename
List
,
template
<
typename
>
class
Trait
>
template
<
typename
List
,
template
<
typename
>
class
Trait
>
struct
tl_apply
;
template
<
template
<
typename
>
class
Trait
,
typename
...
Elements
>
template
<
template
<
typename
>
class
Trait
,
typename
...
Elements
>
struct
tl_apply
<
type_list
<
Elements
...
>
,
Trait
>
{
typedef
type_list
<
typename
Trait
<
Elements
>::
type
...
>
type
;
...
...
cppa/util/upgrade_lock_guard.hpp
View file @
a9300af4
...
...
@@ -44,7 +44,7 @@ class upgrade_lock_guard
public:
template
<
template
<
typename
>
class
LockType
>
template
<
template
<
typename
>
class
LockType
>
upgrade_lock_guard
(
LockType
<
UpgradeLockable
>&
other
)
{
m_lockable
=
other
.
release
();
...
...
src/abstract_event_based_actor.cpp
View file @
a9300af4
...
...
@@ -39,31 +39,26 @@ abstract_event_based_actor::abstract_event_based_actor()
{
}
void
abstract_event_based_actor
::
dequeue
(
invoke_rules
&
)
void
abstract_event_based_actor
::
dequeue
(
behavior
&
)
{
quit
(
exit_reason
::
unallowed_function_call
);
}
void
abstract_event_based_actor
::
dequeue
(
timed_invoke_rules
&
)
void
abstract_event_based_actor
::
dequeue
(
partial_function
&
)
{
quit
(
exit_reason
::
unallowed_function_call
);
}
void
abstract_event_based_actor
::
handle_message
(
queue_node_ptr
&
node
,
invoke_rules
&
behavior
)
{
// no need to handle result
(
void
)
dq
(
node
,
behavior
,
m_buffer
);
}
void
abstract_event_based_actor
::
handle_message
(
queue_node_ptr
&
node
,
timed_invoke_rules
&
behavior
)
void
abstract_event_based_actor
::
handle_message
(
queue_node_ptr
&
node
)
{
switch
(
dq
(
node
,
behavior
,
m_buffer
))
auto
&
bhvr
=
*
(
m_loop_stack
.
back
());
if
(
bhvr
.
timeout
().
valid
())
{
switch
(
dq
(
node
,
bhvr
.
get_partial_function
(),
m_buffer
))
{
case
dq_timeout_occured
:
{
behavio
r
.
handle_timeout
();
bhv
r
.
handle_timeout
();
// fall through
}
case
dq_done
:
...
...
@@ -72,28 +67,18 @@ void abstract_event_based_actor::handle_message(queue_node_ptr& node,
// request next timeout if needed
if
(
!
m_loop_stack
.
empty
())
{
auto
&
back
=
m_loop_stack
.
back
();
if
(
back
.
is_right
())
{
request_timeout
(
back
.
right
()
->
timeout
());
}
auto
&
next_bhvr
=
*
(
m_loop_stack
.
back
());
request_timeout
(
next_bhvr
.
timeout
());
}
break
;
}
default:
break
;
}
}
void
abstract_event_based_actor
::
handle_message
(
queue_node_ptr
&
node
)
{
auto
&
bhvr
=
m_loop_stack
.
back
();
if
(
bhvr
.
is_left
())
{
handle_message
(
node
,
*
(
bhvr
.
left
()));
}
else
{
handle_message
(
node
,
*
(
bhvr
.
right
()));
// no need to handle result
(
void
)
dq
(
node
,
bhvr
.
get_partial_function
(),
m_buffer
);
}
}
...
...
src/abstract_scheduled_actor.cpp
View file @
a9300af4
...
...
@@ -129,8 +129,11 @@ int abstract_scheduled_actor::compare_exchange_state(int expected,
void
abstract_scheduled_actor
::
request_timeout
(
util
::
duration
const
&
d
)
{
if
(
d
.
valid
())
{
future_send
(
this
,
d
,
atom
(
":Timeout"
),
++
m_active_timeout_id
);
m_has_pending_timeout_request
=
true
;
}
}
auto
abstract_scheduled_actor
::
filter_msg
(
const
any_tuple
&
msg
)
->
filter_result
...
...
@@ -162,7 +165,7 @@ auto abstract_scheduled_actor::filter_msg(const any_tuple& msg) -> filter_result
}
auto
abstract_scheduled_actor
::
dq
(
queue_node_ptr
&
node
,
invoke_rules_base
&
rules
,
partial_function
&
rules
,
queue_node_buffer
&
buffer
)
->
dq_result
{
switch
(
filter_msg
(
node
->
msg
))
...
...
@@ -232,11 +235,11 @@ void scheduled_actor_dummy::quit(std::uint32_t)
{
}
void
scheduled_actor_dummy
::
dequeue
(
invoke_rules
&
)
void
scheduled_actor_dummy
::
dequeue
(
behavior
&
)
{
}
void
scheduled_actor_dummy
::
dequeue
(
timed_invoke_rules
&
)
void
scheduled_actor_dummy
::
dequeue
(
partial_function
&
)
{
}
...
...
src/abstract_tuple.cpp
View file @
a9300af4
...
...
@@ -36,7 +36,7 @@ bool abstract_tuple::equals(const abstract_tuple &other) const
{
return
this
==
&
other
||
(
size
()
==
other
.
size
()
&&
std
::
equal
(
begin
(),
end
(),
other
.
begin
(),
detail
::
full_eq
));
&&
std
::
equal
(
begin
(),
end
(),
other
.
begin
(),
detail
::
full_eq
_v3
));
}
abstract_tuple
::
abstract_tuple
(
abstract_tuple
const
&
)
:
ref_counted
()
{
}
...
...
src/actor.cpp
View file @
a9300af4
...
...
@@ -55,7 +55,7 @@ inline cppa::detail::actor_registry& registry()
namespace
cppa
{
actor
::
actor
(
std
::
uint32_t
aid
,
const
process_information_ptr
&
pptr
)
:
m_i
s_proxy
(
true
),
m_id
(
aid
),
m_parent_process
(
pptr
)
:
m_i
d
(
aid
),
m_is_proxy
(
true
),
m_parent_process
(
pptr
)
{
if
(
!
pptr
)
{
...
...
@@ -64,7 +64,7 @@ actor::actor(std::uint32_t aid, const process_information_ptr& pptr)
}
actor
::
actor
(
const
process_information_ptr
&
pptr
)
:
m_i
s_proxy
(
false
),
m_id
(
registry
().
next_id
()
),
m_parent_process
(
pptr
)
:
m_i
d
(
registry
().
next_id
()),
m_is_proxy
(
false
),
m_parent_process
(
pptr
)
{
if
(
!
pptr
)
{
...
...
src/converted_thread_context.cpp
View file @
a9300af4
...
...
@@ -69,7 +69,7 @@ void converted_thread_context::enqueue(actor* sender, const any_tuple& msg)
m_mailbox
.
push_back
(
fetch_node
(
sender
,
msg
));
}
void
converted_thread_context
::
dequeue
(
invoke_rules
&
rules
)
/*override*/
void
converted_thread_context
::
dequeue
(
partial_function
&
rules
)
/*override*/
{
queue_node_buffer
buffer
;
queue_node_ptr
node
(
m_mailbox
.
pop
());
...
...
@@ -79,8 +79,10 @@ void converted_thread_context::dequeue(invoke_rules& rules) /*override*/
}
}
void
converted_thread_context
::
dequeue
(
timed_invoke_rules
&
rules
)
/*override*/
void
converted_thread_context
::
dequeue
(
behavior
&
rules
)
/*override*/
{
if
(
rules
.
timeout
().
valid
())
{
auto
timeout
=
now
();
timeout
+=
rules
.
timeout
();
queue_node_buffer
buffer
;
...
...
@@ -98,7 +100,12 @@ void converted_thread_context::dequeue(timed_invoke_rules& rules) /*override*/
}
}
}
while
(
dq
(
node
,
rules
,
buffer
)
==
false
);
while
(
dq
(
node
,
rules
.
get_partial_function
(),
buffer
)
==
false
);
}
else
{
converted_thread_context
::
dequeue
(
rules
.
get_partial_function
());
}
}
converted_thread_context
::
throw_on_exit_result
...
...
@@ -121,7 +128,7 @@ converted_thread_context::throw_on_exit(any_tuple const& msg)
}
bool
converted_thread_context
::
dq
(
queue_node_ptr
&
node
,
invoke_rules_base
&
rules
,
partial_function
&
rules
,
queue_node_buffer
&
buffer
)
{
if
(
m_trap_exit
==
false
&&
throw_on_exit
(
node
->
msg
)
==
normal_exit_signal
)
...
...
src/empty_tuple.cpp
View file @
a9300af4
...
...
@@ -63,7 +63,12 @@ bool empty_tuple::equals(const abstract_tuple& other) const
return
other
.
size
()
==
0
;
}
std
::
type_info
const
*
empty_tuple
::
values_type_list
()
const
void
const
*
empty_tuple
::
type_token
()
const
{
return
&
typeid
(
empty_tuple
);
}
std
::
type_info
const
*
empty_tuple
::
impl_type
()
const
{
return
&
typeid
(
empty_tuple
);
}
...
...
src/event_based_actor.cpp
View file @
a9300af4
...
...
@@ -30,27 +30,6 @@
#include "cppa/event_based_actor.hpp"
namespace
{
template
<
class
StackElement
,
class
Vec
,
class
What
>
void
push_to
(
Vec
&
vec
,
What
&&
bhvr
)
{
// keep always the latest element in the stack to prevent subtle errors,
// e.g., the addresses of all variables in a lambda expression calling
// become() suddenly are invalid if we would pop the behavior!
if
(
vec
.
size
()
<
2
)
{
vec
.
push_back
(
std
::
move
(
bhvr
));
}
else
{
vec
[
0
]
=
std
::
move
(
vec
[
1
]);
vec
[
1
]
=
std
::
move
(
bhvr
);
}
}
}
// namespace <anonymous>
namespace
cppa
{
void
event_based_actor
::
become_void
()
...
...
@@ -58,32 +37,24 @@ void event_based_actor::become_void()
m_loop_stack
.
clear
();
}
void
event_based_actor
::
do_become
(
behavior
*
bhvr
)
void
event_based_actor
::
do_become
(
behavior
*
bhvr
,
bool
has_ownership
)
{
if
(
bhvr
->
is_left
())
reset_timeout
();
request_timeout
(
bhvr
->
timeout
());
stack_element
se
{
bhvr
};
if
(
!
has_ownership
)
se
.
get_deleter
().
disable
();
// keep always the latest element in the stack to prevent subtle errors,
// e.g., the addresses of all variables in a lambda expression calling
// become() suddenly are invalid if we would pop the behavior!
if
(
m_loop_stack
.
size
()
<
2
)
{
do_become
(
&
(
bhvr
->
left
()),
false
);
m_loop_stack
.
push_back
(
std
::
move
(
se
)
);
}
else
{
do_become
(
&
(
bhvr
->
right
()),
false
);
m_loop_stack
[
0
]
=
std
::
move
(
m_loop_stack
[
1
]);
m_loop_stack
[
1
]
=
std
::
move
(
se
);
}
}
void
event_based_actor
::
do_become
(
invoke_rules
*
bhvr
,
bool
has_ownership
)
{
reset_timeout
();
stack_element
::
left_type
ptr
(
bhvr
);
if
(
!
has_ownership
)
ptr
.
get_deleter
().
disable
();
push_to
<
stack_element
>
(
m_loop_stack
,
std
::
move
(
ptr
));
}
void
event_based_actor
::
do_become
(
timed_invoke_rules
*
bhvr
,
bool
has_ownership
)
{
request_timeout
(
bhvr
->
timeout
());
stack_element
::
right_type
ptr
(
bhvr
);
if
(
!
has_ownership
)
ptr
.
get_deleter
().
disable
();
push_to
<
stack_element
>
(
m_loop_stack
,
std
::
move
(
ptr
));
}
}
// namespace cppa
src/invokable.cpp
View file @
a9300af4
...
...
@@ -32,11 +32,7 @@
namespace
cppa
{
namespace
detail
{
invokable_base
::~
invokable_base
()
{
}
timed_invokable
::
timed_invokable
(
const
util
::
duration
&
d
)
:
m_timeout
(
d
)
invokable
::~
invokable
()
{
}
...
...
src/mock_scheduler.cpp
View file @
a9300af4
...
...
@@ -35,10 +35,9 @@
#include "cppa/self.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/attachable.hpp"
#include "cppa/
invoke_rules
.hpp"
#include "cppa/
local_actor
.hpp"
#include "cppa/scheduled_actor.hpp"
#include "cppa/detail/thread.hpp"
...
...
src/object_array.cpp
View file @
a9300af4
...
...
@@ -67,7 +67,12 @@ uniform_type_info const* object_array::type_at(size_t pos) const
return
m_elements
[
pos
].
type
();
}
std
::
type_info
const
*
object_array
::
values_type_list
()
const
void
const
*
object_array
::
type_token
()
const
{
return
&
typeid
(
object_array
);
}
std
::
type_info
const
*
object_array
::
impl_type
()
const
{
return
&
typeid
(
object_array
);
}
...
...
src/partial_function.cpp
0 → 100644
View file @
a9300af4
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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/>. *
\******************************************************************************/
#include "cppa/config.hpp"
#include "cppa/behavior.hpp"
#include "cppa/partial_function.hpp"
#include "cppa/detail/invokable.hpp"
namespace
cppa
{
partial_function
::
partial_function
(
partial_function
&&
other
)
:
m_funs
(
std
::
move
(
other
.
m_funs
))
{
}
partial_function
::
partial_function
(
invokable_ptr
&&
ptr
)
{
m_funs
.
push_back
(
std
::
move
(
ptr
));
}
auto
partial_function
::
get_cache_entry
(
any_tuple
const
&
value
)
->
cache_entry
&
{
m_dummy
.
first
=
value
.
type_token
();
auto
end
=
m_cache
.
end
();
// note: uses >= for comparison (not a "real" upper bound)
auto
i
=
std
::
upper_bound
(
m_cache
.
begin
(),
end
,
m_dummy
,
[](
cache_element
const
&
lhs
,
cache_element
const
&
rhs
)
{
return
lhs
.
first
>=
rhs
.
first
;
});
// if we didn't found a cache entry ...
if
(
i
==
end
||
i
->
first
!=
m_dummy
.
first
)
{
// ... create one (store all invokables with matching types)
cache_entry
tmp
;
for
(
auto
&
fun
:
m_funs
)
{
if
(
fun
->
types_match
(
value
))
{
tmp
.
push_back
(
fun
.
get
());
}
}
// m_cache is always sorted,
// due to emplace(upper_bound, ...) insertions
i
=
m_cache
.
emplace
(
i
,
std
::
move
(
m_dummy
.
first
),
std
::
move
(
tmp
));
}
return
i
->
second
;
}
void
partial_function
::
operator
()(
any_tuple
const
&
value
)
{
auto
&
v
=
get_cache_entry
(
value
);
(
void
)
std
::
any_of
(
v
.
begin
(),
v
.
end
(),
[
&
](
detail
::
invokable
*
i
)
{
return
i
->
unsafe_invoke
(
value
);
});
}
detail
::
invokable
const
*
partial_function
::
definition_at
(
any_tuple
const
&
value
)
{
auto
&
v
=
get_cache_entry
(
value
);
auto
i
=
std
::
find_if
(
v
.
begin
(),
v
.
end
(),
[
&
](
detail
::
invokable
*
i
)
{
return
i
->
could_invoke
(
value
);
});
return
(
i
!=
v
.
end
())
?
*
i
:
nullptr
;
}
bool
partial_function
::
defined_at
(
any_tuple
const
&
value
)
{
return
definition_at
(
value
)
!=
nullptr
;
}
detail
::
intermediate
*
partial_function
::
get_intermediate
(
any_tuple
const
&
value
)
{
detail
::
intermediate
*
result
=
nullptr
;
for
(
auto
&
i
:
get_cache_entry
(
value
))
{
if
((
result
=
i
->
get_unsafe_intermediate
(
value
))
!=
nullptr
)
{
return
result
;
}
}
return
nullptr
;
}
behavior
partial_function
::
operator
,(
behavior
&&
arg
)
{
behavior
bhvr
{
std
::
move
(
arg
)};
bhvr
.
get_partial_function
().
m_funs
=
std
::
move
(
m_funs
);
return
bhvr
;
}
}
// namespace cppa
src/receive.cpp
View file @
a9300af4
...
...
@@ -32,7 +32,7 @@
namespace
cppa
{
void
receive_loop
(
invoke_rules
&
rules
)
void
receive_loop
(
behavior
&
rules
)
{
local_actor
*
sptr
=
self
;
for
(;;)
...
...
@@ -41,7 +41,7 @@ void receive_loop(invoke_rules& rules)
}
}
void
receive_loop
(
timed_invoke_rules
&
rules
)
void
receive_loop
(
partial_function
&
rules
)
{
local_actor
*
sptr
=
self
;
for
(;;)
...
...
src/stacked_event_based_actor.cpp
View file @
a9300af4
...
...
@@ -45,22 +45,14 @@ void stacked_event_based_actor::unbecome()
}
}
void
stacked_event_based_actor
::
do_become
(
invoke_rules
*
behavio
r
,
void
stacked_event_based_actor
::
do_become
(
behavior
*
bhv
r
,
bool
has_ownership
)
{
reset_timeout
();
stack_element
::
left_type
ptr
(
behavior
);
if
(
!
has_ownership
)
ptr
.
get_deleter
().
disable
();
m_loop_stack
.
push_back
(
std
::
move
(
ptr
));
}
void
stacked_event_based_actor
::
do_become
(
timed_invoke_rules
*
behavior
,
bool
has_ownership
)
{
request_timeout
(
behavior
->
timeout
());
stack_element
::
right_type
ptr
(
behavior
);
if
(
!
has_ownership
)
ptr
.
get_deleter
().
disable
();
m_loop_stack
.
push_back
(
std
::
move
(
ptr
));
request_timeout
(
bhvr
->
timeout
());
stack_element
se
{
bhvr
};
if
(
!
has_ownership
)
se
.
get_deleter
().
disable
();
m_loop_stack
.
push_back
(
std
::
move
(
se
));
}
}
// namespace cppa
src/yielding_actor.cpp
View file @
a9300af4
...
...
@@ -93,7 +93,7 @@ void yielding_actor::yield_until_not_empty()
}
}
void
yielding_actor
::
dequeue
(
invoke_rules
&
rules
)
void
yielding_actor
::
dequeue
(
partial_function
&
rules
)
{
queue_node_buffer
buffer
;
yield_until_not_empty
();
...
...
@@ -105,8 +105,10 @@ void yielding_actor::dequeue(invoke_rules& rules)
}
}
void
yielding_actor
::
dequeue
(
timed_invoke_rules
&
rules
)
void
yielding_actor
::
dequeue
(
behavior
&
rules
)
{
if
(
rules
.
timeout
().
valid
())
{
queue_node_buffer
buffer
;
// try until a message was successfully dequeued
request_timeout
(
rules
.
timeout
());
...
...
@@ -118,7 +120,7 @@ void yielding_actor::dequeue(timed_invoke_rules& rules)
//}
yield_until_not_empty
();
queue_node_ptr
node
(
m_mailbox
.
pop
());
switch
(
dq
(
node
,
rules
,
buffer
))
switch
(
dq
(
node
,
rules
.
get_partial_function
()
,
buffer
))
{
case
dq_done
:
{
...
...
@@ -132,6 +134,12 @@ void yielding_actor::dequeue(timed_invoke_rules& rules)
default:
break
;
}
}
}
else
{
// suppress virtual function call
yielding_actor
::
dequeue
(
rules
.
get_partial_function
());
}
}
void
yielding_actor
::
resume
(
util
::
fiber
*
from
,
resume_callback
*
callback
)
...
...
unit_testing/test__atom.cpp
View file @
a9300af4
...
...
@@ -3,7 +3,6 @@
#include <iostream>
#include "test.hpp"
#include "cppa/util.hpp"
#include "cppa/cppa.hpp"
...
...
unit_testing/test__pattern.cpp
View file @
a9300af4
#include <string>
#include <sstream>
#include <functional>
#include "test.hpp"
...
...
@@ -11,6 +12,7 @@
#include "cppa/pattern.hpp"
#include "cppa/announce.hpp"
#include "cppa/tuple_cast.hpp"
#include "cppa/partial_function.hpp"
#include "cppa/util/enable_if.hpp"
#include "cppa/util/disable_if.hpp"
...
...
@@ -19,9 +21,12 @@
#include "cppa/util/is_primitive.hpp"
#include "cppa/util/is_mutable_ref.hpp"
#include "cppa/detail/invokable.hpp"
#include "cppa/detail/types_array.hpp"
#include "cppa/detail/decorated_tuple.hpp"
#include <boost/progress.hpp>
using
namespace
cppa
;
template
<
typename
Arr
>
...
...
@@ -59,6 +64,35 @@ void match_test(T const& value)
);
}
template
<
class
Testee
>
void
invoke_test
(
std
::
vector
<
any_tuple
>&
test_tuples
,
Testee
&
x
)
{
boost
::
progress_timer
t
;
for
(
int
i
=
0
;
i
<
1000000
;
++
i
)
{
for
(
auto
&
t
:
test_tuples
)
x
(
t
);
}
}
inline
detail
::
intermediate
*
get_i
(
partial_function
&
pf
,
any_tuple
const
&
value
)
{
return
pf
.
get_intermediate
(
value
);
}
template
<
class
Testee
>
void
intermediate_test
(
std
::
vector
<
any_tuple
>&
test_tuples
,
Testee
&
x
)
{
boost
::
progress_timer
t
;
for
(
int
i
=
0
;
i
<
1000000
;
++
i
)
{
for
(
auto
&
t
:
test_tuples
)
{
auto
i
=
get_i
(
x
,
t
);
if
(
i
)
i
->
invoke
();
}
}
}
size_t
test__pattern
()
{
CPPA_TEST
(
test__pattern
);
...
...
unit_testing/test__tuple.cpp
View file @
a9300af4
...
...
@@ -9,13 +9,11 @@
#include "test.hpp"
#include "cppa/on.hpp"
#include "cppa/util.hpp"
#include "cppa/tuple.hpp"
#include "cppa/pattern.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/to_string.hpp"
#include "cppa/tuple_cast.hpp"
#include "cppa/invoke_rules.hpp"
#include "cppa/intrusive_ptr.hpp"
#include "cppa/uniform_type_info.hpp"
...
...
unit_testing/test__type_list.cpp
View file @
a9300af4
...
...
@@ -5,7 +5,6 @@
#include "test.hpp"
#include "cppa/util.hpp"
#include "cppa/util/at.hpp"
#include "cppa/util/element_at.hpp"
#include "cppa/uniform_type_info.hpp"
...
...
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