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
754dbbe1
Commit
754dbbe1
authored
Nov 23, 2011
by
neverlord
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
announcing of list and map typedefs
parent
4a354707
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
209 additions
and
69 deletions
+209
-69
cppa/cppa.hpp
cppa/cppa.hpp
+7
-1
cppa/detail/default_uniform_type_info_impl.hpp
cppa/detail/default_uniform_type_info_impl.hpp
+21
-23
cppa/detail/list_member.hpp
cppa/detail/list_member.hpp
+64
-19
cppa/detail/map_member.hpp
cppa/detail/map_member.hpp
+65
-15
cppa/detail/pair_member.hpp
cppa/detail/pair_member.hpp
+5
-0
examples/announce_example_1.cpp
examples/announce_example_1.cpp
+23
-9
examples/announce_example_5.cpp
examples/announce_example_5.cpp
+24
-1
src/uniform_type_info.cpp
src/uniform_type_info.cpp
+0
-1
No files found.
cppa/cppa.hpp
View file @
754dbbe1
...
...
@@ -151,7 +151,13 @@
* assert(&(get<0>(x)) != &(get<0>(y)));
* @endcode
*
* @defgroup MessageHandling Send and receive messages
* @defgroup MessageHandling Message handling.
*
* This is the beating heart of @p libcppa. Actor programming is all about
* message handling.
*
* A message in @p libcppa is a n-tuple of values (with size >= 1). You can use
* almost every type in messages.
*
* @section UsingOwnTypes Using own types in messages
*
...
...
cppa/detail/default_uniform_type_info_impl.hpp
View file @
754dbbe1
...
...
@@ -14,6 +14,7 @@
#include "cppa/detail/map_member.hpp"
#include "cppa/detail/list_member.hpp"
#include "cppa/detail/type_to_ptype.hpp"
#include "cppa/detail/primitive_member.hpp"
namespace
cppa
{
namespace
detail
{
...
...
@@ -73,14 +74,6 @@ class is_stl_compliant_map
};
template
<
typename
T
>
struct
has_default_uniform_type_info_impl
{
static
const
bool
value
=
util
::
is_primitive
<
T
>::
value
||
is_stl_compliant_map
<
T
>::
value
||
is_stl_compliant_list
<
T
>::
value
;
};
template
<
typename
T
>
class
default_uniform_type_info_impl
:
public
util
::
abstract_uniform_type_info
<
T
>
{
...
...
@@ -175,7 +168,7 @@ class default_uniform_type_info_impl : public util::abstract_uniform_type_info<T
}
// a member that's not a member at all, but "forwards"
// the 'self' pointer to make use *_member implementations
// the 'self' pointer to make use
of
*_member implementations
static
member
fake_member
(
uniform_type_info
*
mtptr
)
{
return
{
...
...
@@ -284,28 +277,29 @@ class default_uniform_type_info_impl : public util::abstract_uniform_type_info<T
"stl-compliant list/map"
);
}
template
<
class
C
>
void
init_
(
typename
util
::
enable_if
<
util
::
disjunction
<
std
::
is_same
<
C
,
util
::
void_type
>
,
std
::
is_same
<
C
,
anything
>>>::
type
*
=
0
)
{
// anything doesn't have any fields (no serialization required)
}
template
<
typename
P
>
void
init_
(
typename
util
::
enable_if
<
util
::
is_primitive
<
P
>>::
type
*
=
0
)
{
m_members
.
push_back
(
member
::
fake_member
(
new
primitive_member
<
P
>
()));
}
template
<
typename
Map
>
void
init_
(
typename
util
::
enable_if
<
is_stl_compliant_map
<
Map
>>::
type
*
=
0
)
{
m_members
.
push_back
(
member
::
fake_member
(
new
map_member
<
Map
>
));
}
template
<
typename
List
>
void
init_
(
typename
util
::
enable_if
<
is_stl_compliant_list
<
List
>>::
type
*
=
0
)
{
m_members
.
push_back
(
member
::
fake_member
(
new
list_member
<
List
>
));
}
template
<
typename
X
>
void
init_
(
typename
util
::
disable_if
<
util
::
disjunction
<
util
::
is_primitive
<
X
>
,
std
::
is_same
<
X
,
util
::
void_type
>
,
std
::
is_same
<
X
,
anything
>>>::
type
*
=
0
)
void
init_
(
typename
util
::
enable_if
<
is_invalid
<
X
>>::
type
*
=
0
)
{
// T is neither primitive nor a STL compliant list/map,
// so it has to be an announced type
static_assert
(
util
::
is_primitive
<
X
>::
value
,
"T is neither a primitive type nor a "
"stl-compliant list/map"
);
...
...
@@ -322,6 +316,10 @@ class default_uniform_type_info_impl : public util::abstract_uniform_type_info<T
default_uniform_type_info_impl
()
{
init_
<
T
>
();
if
(
m_members
.
size
()
!=
1
)
{
throw
std
::
logic_error
(
"no fake member added"
);
}
}
void
serialize
(
const
void
*
obj
,
serializer
*
s
)
const
...
...
cppa/detail/list_member.hpp
View file @
754dbbe1
#ifndef LIST_MEMBER_HPP
#define LIST_MEMBER_HPP
#include "cppa/util/is_primitive.hpp"
#include "cppa/util/abstract_uniform_type_info.hpp"
namespace
cppa
{
namespace
detail
{
template
<
typename
List
>
class
list_member
:
public
util
::
abstract_uniform_type_info
<
List
>
template
<
typename
List
,
bool
HasPrimitiveValues
>
struct
list_member_util
{
typedef
typename
List
::
value_type
value_type
;
static
constexpr
primitive_type
vptype
=
type_to_ptype
<
value_type
>::
ptype
;
void
operator
()(
const
List
&
list
,
serializer
*
s
)
const
{
s
->
begin_sequence
(
list
.
size
());
for
(
auto
i
=
list
.
begin
();
i
!=
list
.
end
();
++
i
)
{
s
->
write_value
(
*
i
);
}
s
->
end_sequence
();
}
void
operator
()(
List
&
list
,
deserializer
*
d
)
const
{
list
.
clear
();
auto
size
=
d
->
begin_sequence
();
for
(
decltype
(
size
)
i
=
0
;
i
<
size
;
++
i
)
{
list
.
push_back
(
get
<
value_type
>
(
d
->
read_value
(
vptype
)));
}
}
};
static_assert
(
vptype
!=
pt_null
,
"List::value_type is not a primitive data type"
);
template
<
typename
List
>
struct
list_member_util
<
List
,
false
>
{
typedef
typename
List
::
value_type
value_type
;
public:
const
uniform_type_info
*
m_value_type
;
void
serialize
(
const
void
*
obj
,
serializer
*
s
)
const
list_member_util
()
:
m_value_type
(
uniform_typeid
<
value_type
>
())
{
}
void
operator
()(
const
List
&
list
,
serializer
*
s
)
const
{
auto
&
ls
=
*
reinterpret_cast
<
const
List
*>
(
obj
);
s
->
begin_sequence
(
ls
.
size
());
for
(
const
auto
&
val
:
ls
)
s
->
begin_sequence
(
list
.
size
());
for
(
auto
i
=
list
.
begin
();
i
!=
list
.
end
();
++
i
)
{
s
->
write_value
(
val
);
m_value_type
->
serialize
(
&
(
*
i
),
s
);
}
s
->
end_sequence
();
}
void
deserialize
(
void
*
obj
,
deserializer
*
d
)
const
void
operator
()(
List
&
list
,
deserializer
*
d
)
const
{
auto
&
ls
=
*
reinterpret_cast
<
List
*>
(
obj
);
size_t
ls_size
=
d
->
begin_sequence
();
for
(
size_t
i
=
0
;
i
<
ls_size
;
++
i
)
list
.
clear
();
value_type
tmp
;
auto
size
=
d
->
begin_sequence
();
for
(
decltype
(
size
)
i
=
0
;
i
<
size
;
++
i
)
{
primitive_variant
val
=
d
->
read_value
(
vptype
);
l
s
.
push_back
(
std
::
move
(
get_ref
<
value_type
>
(
val
))
);
m_value_type
->
deserialize
(
&
tmp
,
d
);
l
ist
.
push_back
(
tmp
);
}
d
->
end_sequence
();
}
};
template
<
typename
List
>
class
list_member
:
public
util
::
abstract_uniform_type_info
<
List
>
{
typedef
typename
List
::
value_type
value_type
;
list_member_util
<
List
,
util
::
is_primitive
<
value_type
>::
value
>
m_helper
;
public:
void
serialize
(
const
void
*
obj
,
serializer
*
s
)
const
{
auto
&
list
=
*
reinterpret_cast
<
const
List
*>
(
obj
);
m_helper
(
list
,
s
);
}
void
deserialize
(
void
*
obj
,
deserializer
*
d
)
const
{
auto
&
list
=
*
reinterpret_cast
<
List
*>
(
obj
);
m_helper
(
list
,
d
);
}
};
...
...
cppa/detail/map_member.hpp
View file @
754dbbe1
#ifndef MAP_MEMBER_HPP
#define MAP_MEMBER_HPP
#include "cppa/util/abstract_uniform_type_info.hpp"
#include "cppa/detail/primitive_member.hpp"
#include <type_traits>
#include "cppa/detail/pair_member.hpp"
#include "cppa/detail/primitive_member.hpp"
#include "cppa/util/abstract_uniform_type_info.hpp"
namespace
cppa
{
namespace
detail
{
// matches value_type of std::set
template
<
typename
T
>
struct
meta_value_type
struct
is_pair
{
static
const
bool
value
=
false
;
};
template
<
typename
First
,
typename
Second
>
struct
is_pair
<
std
::
pair
<
First
,
Second
>
>
{
static
const
bool
value
=
true
;
};
template
<
typename
T
,
bool
IsPair
,
bool
IsPrimitive
>
struct
map_member_util
;
// std::set with primitive value
template
<
typename
T
>
struct
map_member_util
<
T
,
false
,
true
>
{
primitive_member
<
T
>
impl
;
void
serialize_value
(
const
T
&
what
,
serializer
*
s
)
const
{
impl
.
serialize
(
&
what
,
s
);
}
template
<
typename
M
>
void
deserialize_and_insert
(
M
&
map
,
deserializer
*
d
)
const
{
...
...
@@ -25,24 +37,59 @@ struct meta_value_type
}
};
// matches value_type of std::map
template
<
typename
T1
,
typename
T2
>
struct
meta_value_type
<
std
::
pair
<
const
T1
,
T2
>>
// std::set with non-primitive value
template
<
typename
T
>
struct
map_member_util
<
T
,
false
,
false
>
{
const
uniform_type_info
*
m_type
;
map_member_util
()
:
m_type
(
uniform_typeid
<
T
>
())
{
}
void
serialize_value
(
const
T
&
what
,
serializer
*
s
)
const
{
m_type
->
serialize
(
&
what
,
s
);
}
template
<
typename
M
>
void
deserialize_and_insert
(
M
&
map
,
deserializer
*
d
)
const
{
T
value
;
m_type
->
deserialize
(
&
value
,
d
);
map
.
insert
(
std
::
move
(
value
));
}
};
// std::map
template
<
typename
T
>
struct
map_member_util
<
T
,
true
,
false
>
{
pair_member
<
T1
,
T2
>
impl
;
void
serialize_value
(
const
std
::
pair
<
const
T1
,
T2
>&
what
,
serializer
*
s
)
const
// std::map defines its first half of value_type as const
typedef
typename
std
::
remove_const
<
typename
T
::
first_type
>::
type
first_type
;
typedef
typename
T
::
second_type
second_type
;
pair_member
<
first_type
,
second_type
>
impl
;
void
serialize_value
(
const
T
&
what
,
serializer
*
s
)
const
{
std
::
pair
<
T1
,
T2
>
p
(
what
.
first
,
what
.
second
);
// impl needs a pair without const modifier
std
::
pair
<
first_type
,
second_type
>
p
(
what
.
first
,
what
.
second
);
impl
.
serialize
(
&
p
,
s
);
}
template
<
typename
M
>
void
deserialize_and_insert
(
M
&
map
,
deserializer
*
d
)
const
{
std
::
pair
<
T1
,
T2
>
p
;
std
::
pair
<
first_type
,
second_type
>
p
;
impl
.
deserialize
(
&
p
,
d
);
std
::
pair
<
const
T1
,
T2
>
v
(
std
::
move
(
p
.
first
),
std
::
move
(
p
.
second
));
std
::
pair
<
const
first_type
,
second_type
>
v
(
std
::
move
(
p
.
first
),
std
::
move
(
p
.
second
));
map
.
insert
(
std
::
move
(
v
));
}
};
template
<
typename
Map
>
...
...
@@ -52,7 +99,9 @@ class map_member : public util::abstract_uniform_type_info<Map>
typedef
typename
Map
::
key_type
key_type
;
typedef
typename
Map
::
value_type
value_type
;
meta_value_type
<
value_type
>
m_value_type_meta
;
map_member_util
<
value_type
,
is_pair
<
value_type
>::
value
,
util
::
is_primitive
<
value_type
>::
value
>
m_helper
;
public:
...
...
@@ -62,7 +111,7 @@ class map_member : public util::abstract_uniform_type_info<Map>
s
->
begin_sequence
(
mp
.
size
());
for
(
const
auto
&
val
:
mp
)
{
m_
value_type_meta
.
serialize_value
(
val
,
s
);
m_
helper
.
serialize_value
(
val
,
s
);
}
s
->
end_sequence
();
}
...
...
@@ -70,10 +119,11 @@ class map_member : public util::abstract_uniform_type_info<Map>
void
deserialize
(
void
*
obj
,
deserializer
*
d
)
const
{
auto
&
mp
=
*
reinterpret_cast
<
Map
*>
(
obj
);
mp
.
clear
();
size_t
mp_size
=
d
->
begin_sequence
();
for
(
size_t
i
=
0
;
i
<
mp_size
;
++
i
)
{
m_
value_type_meta
.
deserialize_and_insert
(
mp
,
d
);
m_
helper
.
deserialize_and_insert
(
mp
,
d
);
}
d
->
end_sequence
();
}
...
...
cppa/detail/pair_member.hpp
View file @
754dbbe1
...
...
@@ -2,6 +2,11 @@
#define PAIR_MEMBER_HPP
#include <utility>
#include "cppa/serializer.hpp"
#include "cppa/deserializer.hpp"
#include "cppa/primitive_variant.hpp"
#include "cppa/detail/type_to_ptype.hpp"
#include "cppa/util/abstract_uniform_type_info.hpp"
namespace
cppa
{
namespace
detail
{
...
...
examples/announce_example_1.cpp
View file @
754dbbe1
#include <vector>
#include <cassert>
#include <utility>
#include <iostream>
...
...
@@ -9,10 +10,10 @@ using std::endl;
using
namespace
cppa
;
// POD struct
- pair of two ints
// POD struct
struct
foo
{
int
a
;
std
::
vector
<
int
>
a
;
int
b
;
};
...
...
@@ -23,9 +24,10 @@ bool operator==(const foo& lhs, const foo& rhs)
&&
lhs
.
b
==
rhs
.
b
;
}
// a
nother
pair of two ints
// a pair of two ints
typedef
std
::
pair
<
int
,
int
>
foo_pair
;
// another pair of two ints
typedef
std
::
pair
<
int
,
int
>
foo_pair2
;
int
main
(
int
,
char
**
)
...
...
@@ -44,12 +46,16 @@ int main(int, char**)
assert
(
announce
<
foo_pair2
>
(
&
foo_pair2
::
first
,
&
foo_pair2
::
second
)
==
false
);
// send a foo to ourselves
send
(
self
(),
foo
{
1
,
2
});
send
(
self
(),
foo
{
{
1
,
2
,
3
,
4
},
5
});
// send a foo_pair2 to ourselves
send
(
self
(),
foo_pair2
{
3
,
4
});
send
(
self
(),
foo_pair2
{
3
,
4
});
// quits the program
send
(
self
(),
atom
(
"done"
));
// libcppa returns the same uniform_type_info
// instance for foo_pair and foo_pair2
assert
(
uniform_typeid
<
foo_pair
>
()
==
uniform_typeid
<
foo_pair2
>
());
// receive two messages
int
i
=
0
;
receive_while
([
&
]()
{
return
++
i
<=
2
;
})
...
...
@@ -65,10 +71,18 @@ int main(int, char**)
},
on
<
foo
>
()
>>
[](
const
foo
&
val
)
{
cout
<<
"foo("
<<
val
.
a
<<
","
<<
val
.
b
<<
")"
<<
endl
;
cout
<<
"foo({"
;
auto
i
=
val
.
a
.
begin
();
auto
end
=
val
.
a
.
end
();
if
(
i
!=
end
)
{
cout
<<
*
i
;
while
(
++
i
!=
end
)
{
cout
<<
","
<<
*
i
;
}
}
cout
<<
"},"
<<
val
.
b
<<
")"
<<
endl
;
}
);
return
0
;
...
...
examples/announce_example_5.cpp
View file @
754dbbe1
...
...
@@ -190,7 +190,17 @@ int main()
// send a tree to ourselves ...
send
(
self
(),
t
);
receive
// send a vector of trees to ourselves
typedef
std
::
vector
<
tree
>
tree_vector
;
announce
<
tree_vector
>
();
tree_vector
tvec
;
tvec
.
push_back
(
t
);
tvec
.
push_back
(
t
);
send
(
self
(),
tvec
);
// receive both messages
int
i
=
0
;
receive_while
([
&
]()
{
return
++
i
<=
2
;
})
(
// ... and receive it
on
<
tree
>
()
>>
[](
const
tree
&
tmsg
)
...
...
@@ -203,6 +213,19 @@ int main()
// prints the tree using the print member function:
// 0 { 10 { 11, 12, 13 } , 20 { 21, 22 } }
tmsg
.
print
();
},
on
<
tree_vector
>
()
>>
[](
const
tree_vector
&
trees
)
{
// prints "received 2 trees"
cout
<<
"received "
<<
trees
.
size
()
<<
" trees"
<<
endl
;
// prints:
// @<> ( {
// std::vector<tree,std::allocator<tree>> ( {
// tree ( 0, { 10, { 11, { }, 12, { }, 13, { } }, 20, { 21, { }, 22, { } } } ),
// tree ( 0, { 10, { 11, { }, 12, { }, 13, { } }, 20, { 21, { }, 22, { } } } )
// )
// } )
cout
<<
"to_string: "
<<
to_string
(
last_received
())
<<
endl
;
}
);
...
...
src/uniform_type_info.cpp
View file @
754dbbe1
...
...
@@ -647,7 +647,6 @@ class uniform_type_info_map_helper
insert
(
d
,
new
atom_value_tinfo
,
{
raw_name
<
atom_value
>
()
});
insert
(
d
,
new
addr_msg_tinfo
,
{
raw_name
<
detail
::
addressed_message
>
()});
insert
<
float
>
(
d
);
insert
<
cppa
::
util
::
void_type
>
(
d
);
if
(
sizeof
(
double
)
==
sizeof
(
long
double
))
{
std
::
string
dbl
=
raw_name
<
double
>
();
...
...
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