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
e60b3857
Commit
e60b3857
authored
Nov 03, 2011
by
neverlord
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
some performance tweaks and new pattern matching prototype
parent
a61fb447
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
398 additions
and
5 deletions
+398
-5
.gitignore
.gitignore
+1
-0
cppa/detail/tdata.hpp
cppa/detail/tdata.hpp
+14
-1
cppa/detail/yielding_message_queue.hpp
cppa/detail/yielding_message_queue.hpp
+3
-0
cppa/util/any_tuple_iterator.hpp
cppa/util/any_tuple_iterator.hpp
+7
-0
gen_server/Makefile
gen_server/Makefile
+2
-2
src/uniform_type_info.cpp
src/uniform_type_info.cpp
+1
-1
src/yielding_message_queue.cpp
src/yielding_message_queue.cpp
+34
-0
unit_testing/main.cpp
unit_testing/main.cpp
+335
-0
unit_testing/test__uniform_type.cpp
unit_testing/test__uniform_type.cpp
+1
-1
No files found.
.gitignore
View file @
e60b3857
...
@@ -44,3 +44,4 @@ Makefile
...
@@ -44,3 +44,4 @@ Makefile
unit_testing/Makefile
unit_testing/Makefile
libcppa.so*
libcppa.so*
blob/cppatest
blob/cppatest
callgrind.out.*
cppa/detail/tdata.hpp
View file @
e60b3857
...
@@ -31,6 +31,11 @@ struct tdata<>
...
@@ -31,6 +31,11 @@ struct tdata<>
throw
std
::
out_of_range
(
""
);
throw
std
::
out_of_range
(
""
);
}
}
inline
const
void
*
at
(
size_t
)
const
{
throw
std
::
out_of_range
(
""
);
}
inline
bool
operator
==
(
const
tdata
&
)
const
inline
bool
operator
==
(
const
tdata
&
)
const
{
{
return
true
;
return
true
;
...
@@ -48,7 +53,10 @@ struct tdata<Head, Tail...> : tdata<Tail...>
...
@@ -48,7 +53,10 @@ struct tdata<Head, Tail...> : tdata<Tail...>
inline
tdata
()
:
super
(),
head
()
{
}
inline
tdata
()
:
super
(),
head
()
{
}
tdata
(
const
Head
&
v0
,
const
Tail
&
...
vals
)
:
super
(
vals
...),
head
(
v0
)
{
}
//tdata(const Head& v0, const Tail&... vals) : super(vals...), head(v0) { }
template
<
typename
...
Args
>
tdata
(
const
Head
&
v0
,
const
Args
&
...
vals
)
:
super
(
vals
...),
head
(
v0
)
{
}
inline
tdata
<
Tail
...
>&
tail
()
inline
tdata
<
Tail
...
>&
tail
()
{
{
...
@@ -67,6 +75,11 @@ struct tdata<Head, Tail...> : tdata<Tail...>
...
@@ -67,6 +75,11 @@ struct tdata<Head, Tail...> : tdata<Tail...>
return
head
==
other
.
head
&&
tail
()
==
other
.
tail
();
return
head
==
other
.
head
&&
tail
()
==
other
.
tail
();
}
}
inline
const
void
*
at
(
size_t
pos
)
const
{
return
(
pos
==
0
)
?
&
head
:
super
::
at
(
pos
-
1
);
}
};
};
template
<
size_t
N
,
typename
...
Tn
>
template
<
size_t
N
,
typename
...
Tn
>
...
...
cppa/detail/yielding_message_queue.hpp
View file @
e60b3857
...
@@ -43,6 +43,9 @@ class yielding_message_queue_impl : public message_queue
...
@@ -43,6 +43,9 @@ class yielding_message_queue_impl : public message_queue
std
::
uint32_t
m_active_timeout_id
;
std
::
uint32_t
m_active_timeout_id
;
scheduled_actor
*
m_parent
;
scheduled_actor
*
m_parent
;
std
::
atomic
<
int
>
m_state
;
std
::
atomic
<
int
>
m_state
;
const
uniform_type_info
*
m_atom_value_uti
;
const
uniform_type_info
*
m_ui32_uti
;
const
uniform_type_info
*
m_actor_ptr_uti
;
util
::
single_reader_queue
<
queue_node
>
m_queue
;
util
::
single_reader_queue
<
queue_node
>
m_queue
;
void
yield_until_not_empty
();
void
yield_until_not_empty
();
...
...
cppa/util/any_tuple_iterator.hpp
View file @
e60b3857
...
@@ -20,6 +20,8 @@ class any_tuple_iterator
...
@@ -20,6 +20,8 @@ class any_tuple_iterator
template
<
typename
T
>
template
<
typename
T
>
inline
const
T
&
value
()
const
;
inline
const
T
&
value
()
const
;
inline
const
void
*
value_ptr
()
const
;
inline
const
cppa
::
uniform_type_info
&
type
()
const
;
inline
const
cppa
::
uniform_type_info
&
type
()
const
;
inline
size_t
position
()
const
;
inline
size_t
position
()
const
;
...
@@ -44,6 +46,11 @@ inline const uniform_type_info& any_tuple_iterator::type() const
...
@@ -44,6 +46,11 @@ inline const uniform_type_info& any_tuple_iterator::type() const
return
m_data
.
utype_info_at
(
m_pos
);
return
m_data
.
utype_info_at
(
m_pos
);
}
}
inline
const
void
*
any_tuple_iterator
::
value_ptr
()
const
{
return
m_data
.
at
(
m_pos
);
}
inline
size_t
any_tuple_iterator
::
position
()
const
inline
size_t
any_tuple_iterator
::
position
()
const
{
{
return
m_pos
;
return
m_pos
;
...
...
gen_server/Makefile
View file @
e60b3857
#CXX = /opt/local/bin/g++-mp-4.6
#CXX = /opt/local/bin/g++-mp-4.6
CXX
=
/usr/bin/g++-4.6
CXX
=
/usr/bin/g++-4.6
CXXFLAGS
=
-std
=
c++0x
-pedantic
-Wall
-Wextra
-I
/opt/local/include/
-I
../
-fpermissive
-O2
CXXFLAGS
=
-std
=
c++0x
-pedantic
-Wall
-Wextra
-I
/opt/local/include/
-I
../
-fpermissive
-O2
-g
LIBS
=
-L
../.libs/
-lcppa
-L
/opt/local/lib
-L
/usr/lib
-lboost_thread-mt
LIBS
=
-L
../.libs/
-lcppa
-L
/opt/local/lib
-L
/usr/lib
-lboost_thread-mt
all
:
all
:
$(CXX)
$(CXXFLAGS)
-o
sequential_send sequential_send.cpp
$(LIBS)
$(CXX)
$(CXXFLAGS)
-o
sequential_send sequential_send.cpp
$(LIBS)
$(CXX)
$(CXXFLAGS)
-o
parallel_send parallel_send.cpp
$(LIBS)
#
$(CXX) $(CXXFLAGS) -o parallel_send parallel_send.cpp $(LIBS)
src/uniform_type_info.cpp
View file @
e60b3857
...
@@ -700,7 +700,7 @@ class uniform_type_info_map_helper
...
@@ -700,7 +700,7 @@ class uniform_type_info_map_helper
insert
<
double
>
(
d
);
insert
<
double
>
(
d
);
insert
<
long
double
>
(
d
);
insert
<
long
double
>
(
d
);
}
}
insert
<
any_type
>
(
d
);
//
insert<any_type>(d);
// first: signed
// first: signed
// second: unsigned
// second: unsigned
push
<
char
,
push
<
char
,
...
...
src/yielding_message_queue.cpp
View file @
e60b3857
...
@@ -42,6 +42,9 @@ yielding_message_queue_impl::queue_node::queue_node(const any_tuple& content)
...
@@ -42,6 +42,9 @@ yielding_message_queue_impl::queue_node::queue_node(const any_tuple& content)
yielding_message_queue_impl
::
yielding_message_queue_impl
(
scheduled_actor
*
p
)
yielding_message_queue_impl
::
yielding_message_queue_impl
(
scheduled_actor
*
p
)
:
m_has_pending_timeout_request
(
false
),
m_active_timeout_id
(
0
)
:
m_has_pending_timeout_request
(
false
),
m_active_timeout_id
(
0
)
,
m_parent
(
p
),
m_state
(
ready
)
,
m_parent
(
p
),
m_state
(
ready
)
,
m_atom_value_uti
(
uniform_typeid
<
atom_value
>
())
,
m_ui32_uti
(
uniform_typeid
<
std
::
uint32_t
>
())
,
m_actor_ptr_uti
(
uniform_typeid
<
actor_ptr
>
())
{
{
}
}
...
@@ -60,6 +63,36 @@ enum filter_result
...
@@ -60,6 +63,36 @@ enum filter_result
yielding_message_queue_impl
::
filter_result
yielding_message_queue_impl
::
filter_result
yielding_message_queue_impl
::
filter_msg
(
const
any_tuple
&
msg
)
yielding_message_queue_impl
::
filter_msg
(
const
any_tuple
&
msg
)
{
{
if
(
m_trap_exit
==
false
&&
msg
.
size
()
==
3
&&
m_atom_value_uti
==
&
(
msg
.
utype_info_at
(
0
)))
{
if
(
*
reinterpret_cast
<
const
atom_value
*>
(
msg
.
at
(
0
))
==
atom
(
":Exit"
))
{
if
(
m_actor_ptr_uti
==
&
(
msg
.
utype_info_at
(
1
))
&&
m_ui32_uti
==
&
(
msg
.
utype_info_at
(
2
)))
{
auto
why
=
*
reinterpret_cast
<
const
std
::
uint32_t
*>
(
msg
.
at
(
1
));
if
(
why
!=
exit_reason
::
normal
)
{
self
()
->
quit
(
why
);
}
return
normal_exit_signal
;
}
}
}
if
(
msg
.
size
()
==
2
&&
m_atom_value_uti
==
&
(
msg
.
utype_info_at
(
0
))
&&
atom
(
":Timeout"
)
==
*
reinterpret_cast
<
const
atom_value
*>
(
msg
.
at
(
0
)))
{
if
(
m_ui32_uti
==
&
(
msg
.
utype_info_at
(
1
)))
{
auto
id
=
*
reinterpret_cast
<
const
std
::
uint32_t
*>
(
msg
.
at
(
1
));
return
(
id
==
m_active_timeout_id
)
?
timeout_message
:
expired_timeout_message
;
}
}
/*
if ( m_trap_exit == false
if ( m_trap_exit == false
&& match<atom_value, actor_ptr, std::uint32_t>(msg,
&& match<atom_value, actor_ptr, std::uint32_t>(msg,
nullptr,
nullptr,
...
@@ -81,6 +114,7 @@ yielding_message_queue_impl::filter_msg(const any_tuple& msg)
...
@@ -81,6 +114,7 @@ yielding_message_queue_impl::filter_msg(const any_tuple& msg)
return (id == m_active_timeout_id) ? timeout_message
return (id == m_active_timeout_id) ? timeout_message
: expired_timeout_message;
: expired_timeout_message;
}
}
*/
return
ordinary_message
;
return
ordinary_message
;
}
}
...
...
unit_testing/main.cpp
View file @
e60b3857
...
@@ -24,6 +24,12 @@
...
@@ -24,6 +24,12 @@
#include "cppa/detail/task_scheduler.hpp"
#include "cppa/detail/task_scheduler.hpp"
#include "cppa/detail/thread_pool_scheduler.hpp"
#include "cppa/detail/thread_pool_scheduler.hpp"
// header for experimental stuff
#include "cppa/util/filter_type_list.hpp"
#include "cppa/util/any_tuple_iterator.hpp"
#include "cppa/detail/matcher_arguments.hpp"
#define CPPA_TEST_CATCH_BLOCK() \
#define CPPA_TEST_CATCH_BLOCK() \
catch (std::exception& e) \
catch (std::exception& e) \
{ \
{ \
...
@@ -115,8 +121,337 @@ inline bool found_key(Iterator& i, Container& cont, Key&& key)
...
@@ -115,8 +121,337 @@ inline bool found_key(Iterator& i, Container& cont, Key&& key)
return
(
i
=
cont
.
find
(
std
::
forward
<
Key
>
(
key
)))
!=
cont
.
end
();
return
(
i
=
cont
.
find
(
std
::
forward
<
Key
>
(
key
)))
!=
cont
.
end
();
}
}
namespace
{
using
namespace
cppa
;
struct
wildcard
{
};
typedef
std
::
vector
<
const
uniform_type_info
*>
uti_vec
;
template
<
typename
T
>
struct
is_wildcard
{
static
constexpr
bool
value
=
false
;
};
template
<
>
struct
is_wildcard
<
wildcard
>
{
static
constexpr
bool
value
=
true
;
};
template
<
typename
OutputIterator
,
typename
T0
>
void
fill_vec
(
OutputIterator
&
ii
)
{
*
ii
=
is_wildcard
<
T0
>::
value
?
nullptr
:
cppa
::
uniform_typeid
<
T0
>
();
}
template
<
typename
OutputIterator
,
typename
T0
,
typename
T1
,
typename
...
Tn
>
void
fill_vec
(
OutputIterator
&
ii
);
template
<
typename
OutputIterator
,
typename
T0
>
struct
fill_vec_util
{
template
<
typename
T1
,
typename
...
Tn
>
static
void
_
(
OutputIterator
&
ii
)
{
*
ii
=
cppa
::
uniform_typeid
<
T0
>
();
++
ii
;
fill_vec
<
OutputIterator
,
T1
,
Tn
...
>
(
ii
);
}
};
template
<
typename
OutputIterator
>
struct
fill_vec_util
<
OutputIterator
,
wildcard
>
{
template
<
typename
T1
,
typename
...
Tn
>
static
void
_
(
OutputIterator
&
ii
)
{
*
ii
=
nullptr
;
++
ii
;
fill_vec
<
OutputIterator
,
T1
,
Tn
...
>
(
ii
);
}
};
template
<
typename
OutputIterator
,
typename
T0
,
typename
T1
,
typename
...
Tn
>
void
fill_vec
(
OutputIterator
&
ii
)
{
fill_vec_util
<
OutputIterator
,
T0
>::
template
_
<
T1
,
Tn
...>(
ii
);
}
bool
match_fun
(
const
cppa
::
uniform_type_info
**
utis
,
size_t
utis_size
,
const
cppa
::
any_tuple
&
msg
)
{
if
(
msg
.
size
()
==
utis_size
)
{
for
(
size_t
i
=
0
;
i
<
utis_size
;
++
i
)
{
if
(
utis
[
i
]
!=
&
(
msg
.
utype_info_at
(
i
)))
return
false
;
}
return
true
;
}
return
false
;
}
bool
compare_at
(
size_t
pos
,
const
cppa
::
any_tuple
&
msg
,
const
cppa
::
uniform_type_info
*
uti
,
const
void
*
value
)
{
if
(
uti
==
&
(
msg
.
utype_info_at
(
pos
)))
{
return
(
value
)
?
uti
->
equal
(
msg
.
at
(
pos
),
value
)
:
true
;
}
return
false
;
}
template
<
typename
T
>
struct
tdata_from_type_list
;
template
<
typename
...
T
>
struct
tdata_from_type_list
<
cppa
::
util
::
type_list
<
T
...
>>
{
typedef
cppa
::
detail
::
tdata
<
T
...
>
type
;
};
struct
matcher_types_args
{
size_t
m_pos
;
size_t
m_size
;
void
const
*
const
*
m_data
;
cppa
::
uniform_type_info
const
*
const
*
m_types
;
public:
matcher_types_args
(
size_t
msize
,
void
const
*
const
*
mdata
,
cppa
::
uniform_type_info
const
*
const
*
mtypes
)
:
m_pos
(
0
)
,
m_size
(
msize
)
,
m_data
(
mdata
)
,
m_types
(
mtypes
)
{
}
matcher_types_args
(
const
matcher_types_args
&
)
=
default
;
matcher_types_args
&
operator
=
(
const
matcher_types_args
&
)
=
default
;
inline
bool
at_end
()
const
{
return
m_pos
==
m_size
;
}
inline
matcher_types_args
&
next
()
{
++
m_pos
;
return
*
this
;
}
inline
const
uniform_type_info
*
type
()
const
{
return
m_types
[
m_pos
];
}
inline
bool
has_value
()
const
{
return
value
()
!=
nullptr
;
}
inline
const
void
*
value
()
const
{
return
m_data
[
m_pos
];
}
};
struct
matcher_tuple_args
{
util
::
any_tuple_iterator
iter
;
std
::
vector
<
size_t
>*
mapping
;
matcher_tuple_args
(
const
any_tuple
&
tup
,
std
::
vector
<
size_t
>*
mv
=
0
)
:
iter
(
tup
),
mapping
(
mv
)
{
}
matcher_tuple_args
(
const
util
::
any_tuple_iterator
&
from_iter
,
std
::
vector
<
size_t
>*
mv
=
nullptr
)
:
iter
(
from_iter
),
mapping
(
mv
)
{
}
inline
bool
at_end
()
const
{
return
iter
.
at_end
();
}
inline
matcher_tuple_args
&
next
()
{
iter
.
next
();
return
*
this
;
}
inline
matcher_tuple_args
&
push_mapping
()
{
if
(
mapping
)
mapping
->
push_back
(
iter
.
position
());
return
*
this
;
}
inline
const
uniform_type_info
*
type
()
const
{
return
&
(
iter
.
type
());
}
inline
const
void
*
value
()
const
{
return
iter
.
value_ptr
();
}
};
bool
do_match
(
matcher_types_args
&
ty_args
,
matcher_tuple_args
&
tu_args
)
{
// nullptr == wildcard
if
(
ty_args
.
at_end
()
&&
tu_args
.
at_end
())
{
return
true
;
}
if
(
ty_args
.
type
()
==
nullptr
)
{
// perform submatching
ty_args
.
next
();
if
(
ty_args
.
at_end
())
{
// always true at the end of the pattern
return
true
;
}
auto
ty_cpy
=
ty_args
;
std
::
vector
<
size_t
>
mv
;
auto
mv_ptr
=
(
tu_args
.
mapping
)
?
&
mv
:
nullptr
;
// iterate over tu_iter until we found a match
while
(
tu_args
.
at_end
()
==
false
)
{
matcher_tuple_args
tu_cpy
(
tu_args
.
iter
,
mv_ptr
);
if
(
do_match
(
ty_cpy
,
tu_cpy
))
{
if
(
mv_ptr
)
{
tu_args
.
mapping
->
insert
(
tu_args
.
mapping
->
end
(),
mv
.
begin
(),
mv
.
end
());
}
return
true
;
}
// next iteration
mv
.
clear
();
tu_args
.
next
();
}
}
else
{
if
(
tu_args
.
at_end
()
==
false
&&
ty_args
.
type
()
==
tu_args
.
type
())
{
if
(
ty_args
.
has_value
()
==
false
||
ty_args
.
type
()
->
equal
(
ty_args
.
value
(),
tu_args
.
value
()))
{
tu_args
.
push_mapping
();
return
do_match
(
ty_args
.
next
(),
tu_args
.
next
());
}
}
}
return
false
;
}
template
<
typename
...
Types
>
struct
foobar_test
{
typedef
typename
cppa
::
util
::
filter_type_list
<
wildcard
,
cppa
::
util
::
type_list
<
Types
...
>
>::
type
filtered_types
;
typename
tdata_from_type_list
<
filtered_types
>::
type
m_data
;
const
void
*
m_data_ptr
[
sizeof
...(
Types
)];
const
cppa
::
uniform_type_info
*
m_utis
[
sizeof
...(
Types
)];
foobar_test
()
{
const
cppa
::
uniform_type_info
**
iter
=
m_utis
;
fill_vec
<
decltype
(
iter
),
Types
...
>
(
iter
);
for
(
size_t
i
=
0
;
i
<
sizeof
...(
Types
);
++
i
)
{
m_data_ptr
[
i
]
=
nullptr
;
}
}
template
<
typename
Arg0
,
typename
...
Args
>
foobar_test
(
const
Arg0
&
arg0
,
const
Args
&
...
args
)
:
m_data
(
arg0
,
args
...)
{
const
cppa
::
uniform_type_info
**
iter
=
m_utis
;
fill_vec
<
decltype
(
iter
),
Types
...
>
(
iter
);
size_t
j
=
0
;
for
(
size_t
i
=
0
;
i
<
sizeof
...(
Types
);
++
i
)
{
if
(
m_utis
[
i
]
==
nullptr
)
{
m_data_ptr
[
i
]
=
nullptr
;
}
else
{
if
(
j
<
(
sizeof
...(
Args
)
+
1
))
{
m_data_ptr
[
i
]
=
m_data
.
at
(
j
++
);
}
else
{
m_data_ptr
[
i
]
=
nullptr
;
}
}
}
}
const
cppa
::
uniform_type_info
&
operator
[](
size_t
pos
)
const
{
return
*
(
m_utis
[
pos
]);
}
bool
operator
()(
const
cppa
::
any_tuple
&
msg
)
const
{
matcher_types_args
ty
(
sizeof
...(
Types
),
m_data_ptr
,
m_utis
);
matcher_tuple_args
tu
(
msg
);
return
do_match
(
ty
,
tu
);
}
};
}
// namespace <anonmyous> w/ using cppa
int
main
(
int
argc
,
char
**
argv
)
int
main
(
int
argc
,
char
**
argv
)
{
{
cout
<<
std
::
boolalpha
;
auto
x
=
cppa
::
make_tuple
(
0
,
0.0
f
,
0.0
);
foobar_test
<
wildcard
>
ft0
;
foobar_test
<
int
,
float
,
double
>
ft1
;
/*
cout << "ft1[0] = " << ft1[0].name() << ", "
<< "ft1[1] = " << ft1[1].name() << ", "
<< "ft1[2] = " << ft1[2].name()
<< endl;
*/
cout
<<
"ft0(x) [expected: true] = "
<<
ft0
(
x
)
<<
endl
;
cout
<<
"ft1(x) [expected: true] = "
<<
ft1
(
x
)
<<
endl
;
foobar_test
<
int
,
float
,
double
>
ft2
(
0
);
cout
<<
"ft2(x) [expected: true] = "
<<
std
::
boolalpha
<<
ft2
(
x
)
<<
endl
;
foobar_test
<
int
,
float
,
double
>
ft3
(
0
,
0.
f
);
cout
<<
"ft3(x) [expected: true] = "
<<
std
::
boolalpha
<<
ft3
(
x
)
<<
endl
;
foobar_test
<
int
,
float
,
double
>
ft4
(
0
,
0.
f
,
0.0
);
cout
<<
"ft4(x) [expected: true] = "
<<
std
::
boolalpha
<<
ft4
(
x
)
<<
endl
;
foobar_test
<
int
,
float
,
double
>
ft5
(
0
,
0.1
f
,
0.0
);
cout
<<
"ft5(x) [expected: false] = "
<<
std
::
boolalpha
<<
ft5
(
x
)
<<
endl
;
return
0
;
auto
args
=
get_kv_pairs
(
argc
,
argv
);
auto
args
=
get_kv_pairs
(
argc
,
argv
);
if
(
!
args
.
empty
())
if
(
!
args
.
empty
())
{
{
...
...
unit_testing/test__uniform_type.cpp
View file @
e60b3857
...
@@ -84,7 +84,7 @@ size_t test__uniform_type()
...
@@ -84,7 +84,7 @@ size_t test__uniform_type()
"@0"
,
// cppa::util::void_type
"@0"
,
// cppa::util::void_type
// default announced cppa types
// default announced cppa types
"@atom"
,
// cppa::atom_value
"@atom"
,
// cppa::atom_value
"@*"
,
// cppa::any_type
//
"@*", // cppa::any_type
"@<>"
,
// cppa::any_tuple
"@<>"
,
// cppa::any_tuple
"@msg"
,
// cppa::message
"@msg"
,
// cppa::message
"@actor"
,
// cppa::actor_ptr
"@actor"
,
// cppa::actor_ptr
...
...
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