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
b045c90e
Commit
b045c90e
authored
Nov 11, 2011
by
neverlord
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
documentation and unit testing
parent
e4a39512
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
285 additions
and
406 deletions
+285
-406
cppa.files
cppa.files
+0
-1
cppa/actor.hpp
cppa/actor.hpp
+6
-5
cppa/cow_ptr.hpp
cppa/cow_ptr.hpp
+4
-0
cppa/cppa.hpp
cppa/cppa.hpp
+62
-4
cppa/tuple.hpp
cppa/tuple.hpp
+101
-51
unit_testing/Makefile.am
unit_testing/Makefile.am
+0
-1
unit_testing/main.cpp
unit_testing/main.cpp
+0
-1
unit_testing/test.hpp
unit_testing/test.hpp
+1
-1
unit_testing/test__a_matches_b.cpp
unit_testing/test__a_matches_b.cpp
+0
-50
unit_testing/test__pattern.cpp
unit_testing/test__pattern.cpp
+85
-4
unit_testing/test__tuple.cpp
unit_testing/test__tuple.cpp
+26
-288
No files found.
cppa.files
View file @
b045c90e
...
...
@@ -9,7 +9,6 @@ cppa/util/is_one_of.hpp
cppa/util/conjunction.hpp
cppa/util/disjunction.hpp
unit_testing/test.hpp
unit_testing/test__a_matches_b.cpp
cppa/uniform_type_info.hpp
src/uniform_type_info.cpp
cppa/config.hpp
...
...
cppa/actor.hpp
View file @
b045c90e
...
...
@@ -172,7 +172,7 @@ class actor : public channel
*/
static
intrusive_ptr
<
actor
>
by_id
(
std
::
uint32_t
actor_id
);
inline
bool
is_proxy
()
const
{
return
m_is_proxy
;
}
inline
bool
is_proxy
()
const
;
};
...
...
@@ -181,10 +181,6 @@ class actor : public channel
*/
typedef
intrusive_ptr
<
actor
>
actor_ptr
;
serializer
&
operator
<<
(
serializer
&
,
const
actor_ptr
&
);
deserializer
&
operator
>>
(
deserializer
&
,
actor_ptr
&
);
/******************************************************************************
* inline and template member function implementations *
******************************************************************************/
...
...
@@ -204,6 +200,11 @@ inline std::uint32_t actor::id() const
return
m_id
;
}
inline
bool
actor
::
is_proxy
()
const
{
return
m_is_proxy
;
}
template
<
typename
T
>
bool
actor
::
attach
(
std
::
unique_ptr
<
T
>&&
ptr
,
typename
util
::
enable_if
<
std
::
is_base_of
<
attachable
,
T
>>::
type
*
)
...
...
cppa/cow_ptr.hpp
View file @
b045c90e
...
...
@@ -37,6 +37,10 @@ T* copy_of(const T* what, std::integral_constant<int, 2>)
namespace
cppa
{
/**
* @ingroup CopyOnWrite
* @brief A copy-on-write smart pointer implementation.
*/
template
<
typename
T
>
class
cow_ptr
{
...
...
cppa/cppa.hpp
View file @
b045c90e
...
...
@@ -57,7 +57,7 @@
#include "cppa/detail/receive_loop_helper.hpp"
/**
* @author Dominik Charousset <dominik.charousset
\@
haw-hamburg.de>
* @author Dominik Charousset <dominik.charousset
(at)
haw-hamburg.de>
*
* @mainpage libcppa
*
...
...
@@ -82,12 +82,70 @@
* functions of this namespace could change even in minor
* updates of the library and should not be used by outside of libcppa.
*
* @defgroup ReceiveMessages Receive messages
* @brief
* @defgroup CopyOnWrite Copy-on-write optimization.
* @p libcppa uses a copy-on-write optimization for its message
* passing implementation.
*
* {@link tuple Tuples} should @b always be used used with by-value semantic,
* since tuples use a copy-on-write smart pointer internally. Let's assume two
* tuple @p x and @p y, whereas @p y is a copy of @p x:
*
* @code
* auto x = make_tuple(1, 2, 3);
* auto y = x;
* @endcode
*
* Those two tuples initially point to the same data (the addresses of the
* first element of @p x is equal to the address of the first element
* of @p y):
*
* @code
* assert(&(get<0>(x)) == &(get<0>(y)));
* @endcode
*
* <tt>get<0>(x)</tt> returns a const-reference to the first element of @p x.
* The function @p get does not have a const-overload to avoid
* unintended copies. The function @p get_ref could be used to
* modify tuple elements. A call to this function detaches
* the tuple by copying the data before modifying it if there are two or more
* references to the data:
*
* @code
* // detaches x from y
* get_ref<0>(x) = 42;
* // x and y no longer point to the same data
* assert(&(get<0>(x)) != &(get<0>(y)));
* @endcode
*
* @defgroup MessageHandling Send and receive messages
*
* @section UsingOwnTypes Using own types in messages
* @brief
*
* @defgroup ImplicitConversion Implicit type conversions.
*
* The message passing of @p libcppa prohibits pointers in messages because
* it enforces network transparent messaging.
* Unfortunately, string literals in @p C++ have the type <tt>const char*</tt>,
* resp. <tt>const char[]</tt>. Since @p libcppa is a user-friendly library,
* it silently converts string literals and C-strings to @p std::string objects.
* It also converts unicode literals to the corresponding STL container.
*
* A few examples:
* @code
* // sends an std::string containing "hello actor!" to itself
* send(self(), "hello actor!");
*
* const char* cstring = "cstring";
* // sends an std::string containing "cstring" to itself
* send(self(), cstring);
*
* // sends an std::u16string containing the UTF16 string "hello unicode world!"
* send(self(), u"hello unicode world!");
*
* // x has the type tuple<std::string, std::string>
* auto x = make_tuple("hello", "tuple");
*
* @endcode
*/
...
...
cppa/tuple.hpp
View file @
b045c90e
...
...
@@ -29,18 +29,16 @@ class any_tuple;
class
local_actor
;
/**
* @brief Describes a fixed-length tuple.
* @ingroup CopyOnWrite
* @brief A fixed-length copy-on-write tuple.
*/
template
<
typename
...
ElementTypes
>
class
tuple
{
//friend class any_tuple;
template
<
size_t
N
,
typename
...
Types
>
friend
typename
util
::
at
<
N
,
Types
...
>::
type
&
get_ref
(
tuple
<
Types
...
>&
);
public:
typedef
util
::
type_list
<
ElementTypes
...
>
element_types
;
...
...
@@ -58,80 +56,67 @@ class tuple
cow_ptr
<
vals_t
>
m_vals
;
static
bool
compare_vals
(
const
detail
::
tdata
<>&
v0
,
const
detail
::
tdata
<>&
v1
)
{
return
true
;
}
template
<
typename
Vals0
,
typename
Vals1
>
static
bool
compare_vals
(
const
Vals0
&
v0
,
const
Vals1
&
v1
)
{
typedef
typename
Vals0
::
head_type
lhs_type
;
typedef
typename
Vals1
::
head_type
rhs_type
;
static_assert
(
util
::
is_comparable
<
lhs_type
,
rhs_type
>::
value
,
"Types are not comparable"
);
return
v0
.
head
==
v1
.
head
&&
compare_vals
(
v0
.
tail
(),
v1
.
tail
());
}
public:
// enable use of tuple as type_list
typedef
typename
element_types
::
head_type
head_type
;
typedef
typename
element_types
::
tail_type
tail_type
;
/**
* @brief Initializes each element with its default constructor.
*/
tuple
()
:
m_vals
(
new
vals_t
)
{
}
/**
* @brief Initializes the tuple with @p args.
* @param args Initialization values.
*/
tuple
(
const
ElementTypes
&
...
args
)
:
m_vals
(
new
vals_t
(
args
...))
{
}
size_t
size
()
const
/**
* @brief Gets the size of this tuple.
* @returns <tt>sizeof...(ElementTypes)</tt>.
*/
inline
size_t
size
()
const
{
return
m_vals
->
size
();
return
sizeof
...(
ElementTypes
);
//return m_vals->size();
}
const
void
*
at
(
size_t
p
)
const
/**
* @brief Gets a pointer to the internal data.
* @returns A const void pointer to the <tt>N</tt>th element.
*/
inline
const
void
*
at
(
size_t
p
)
const
{
return
m_vals
->
at
(
p
);
}
const
uniform_type_info
*
utype_at
(
size_t
p
)
const
/**
* @brief Gets {@link uniform_type_info uniform type information}
* of an element.
* @returns The uniform type of the <tt>N</tt>th element.
*/
inline
const
uniform_type_info
*
utype_at
(
size_t
p
)
const
{
return
m_vals
->
utype_info_at
(
p
);
}
const
cow_ptr
<
vals_t
>&
vals
()
const
# ifdef CPPA_DOCUMENTATION
/**
* @brief Gets the internal data.
* @returns A pointer to the internal data representation.
*/
cow_ptr
<
InternalData
>
vals
()
const
;
# else
inline
const
cow_ptr
<
vals_t
>&
vals
()
const
{
return
m_vals
;
}
template
<
typename
...
Args
>
bool
equal_to
(
const
tuple
<
Args
...
>&
other
)
const
{
static_assert
(
sizeof
...(
ElementTypes
)
==
sizeof
...(
Args
),
"Can't compare tuples of different size"
);
return
compare_vals
(
vals
()
->
data
(),
other
.
vals
()
->
data
());
}
# endif
};
template
<
size_t
N
,
typename
...
Types
>
const
typename
util
::
at
<
N
,
Types
...
>::
type
&
get
(
const
tuple
<
Types
...
>&
t
)
{
return
get
<
N
>
(
t
.
vals
()
->
data
());
}
template
<
size_t
N
,
typename
...
Types
>
typename
util
::
at
<
N
,
Types
...
>::
type
&
get_ref
(
tuple
<
Types
...
>&
t
)
{
return
get_ref
<
N
>
(
t
.
m_vals
->
data_ref
());
}
template
<
typename
TypeList
>
struct
tuple_type_from_type_list
;
...
...
@@ -141,6 +126,55 @@ struct tuple_type_from_type_list<util::type_list<Types...>>
typedef
tuple
<
Types
...
>
type
;
};
#ifdef CPPA_DOCUMENTATION
/**
* @ingroup CopyOnWrite
* @brief Gets a const-reference to the <tt>N</tt>th element of @p tup.
* @param tup The tuple object.
* @returns A const-reference of type T, whereas T is the type of the
* <tt>N</tt>th element of @p tup.
* @relates tuple
*/
template
<
size_t
N
,
typename
T
>
const
T
&
get
(
const
tuple
<
...
>&
tup
);
/**
* @ingroup CopyOnWrite
* @brief Gets a reference to the <tt>N</tt>th element of @p tup.
* @param tup The tuple object.
* @returns A reference of type T, whereas T is the type of the
* <tt>N</tt>th element of @p tup.
* @note Detaches @p tup if there are two or more references to the tuple data.
* @relates tuple
*/
template
<
size_t
N
,
typename
T
>
T
&
get_ref
(
tuple
<
...
>&
tup
);
/**
* @ingroup ImplicitConversion
* @brief Creates a new tuple from @p args.
* @param args Values for the tuple elements.
* @returns A tuple object containing the values @p args.
* @relates tuple
*/
template
<
typename
...
Types
>
tuple
<
Types
...
>
make_tuple
(
const
Types
&
...
args
);
#else
template
<
size_t
N
,
typename
...
Types
>
const
typename
util
::
at
<
N
,
Types
...
>::
type
&
get
(
const
tuple
<
Types
...
>&
tup
)
{
return
get
<
N
>
(
tup
.
vals
()
->
data
());
}
template
<
size_t
N
,
typename
...
Types
>
typename
util
::
at
<
N
,
Types
...
>::
type
&
get_ref
(
tuple
<
Types
...
>&
tup
)
{
return
get_ref
<
N
>
(
tup
.
m_vals
->
data_ref
());
}
template
<
typename
...
Types
>
typename
tuple_type_from_type_list
<
typename
util
::
type_list_apply
<
util
::
type_list
<
Types
...
>
,
...
...
@@ -150,6 +184,15 @@ make_tuple(const Types&... args)
return
{
args
...
};
}
#endif
/**
* @brief Compares two tuples.
* @param lhs First tuple object.
* @param rhs Second tuple object.
* @returns @p true if @p lhs and @p rhs are equal; otherwise @p false.
* @relates tuple
*/
template
<
typename
...
LhsTypes
,
typename
...
RhsTypes
>
inline
bool
operator
==
(
const
tuple
<
LhsTypes
...
>&
lhs
,
const
tuple
<
RhsTypes
...
>&
rhs
)
...
...
@@ -157,6 +200,13 @@ inline bool operator==(const tuple<LhsTypes...>& lhs,
return
util
::
compare_tuples
(
lhs
,
rhs
);
}
/**
* @brief Compares two tuples.
* @param lhs First tuple object.
* @param rhs Second tuple object.
* @returns @p true if @p lhs and @p rhs are not equal; otherwise @p false.
* @relates tuple
*/
template
<
typename
...
LhsTypes
,
typename
...
RhsTypes
>
inline
bool
operator
!=
(
const
tuple
<
LhsTypes
...
>&
lhs
,
const
tuple
<
RhsTypes
...
>&
rhs
)
...
...
unit_testing/Makefile.am
View file @
b045c90e
...
...
@@ -6,7 +6,6 @@ noinst_PROGRAMS = unit_tests
unit_tests_SOURCES
=
hash_of.cpp
\
main.cpp
\
ping_pong.cpp
\
test__a_matches_b.cpp
\
test__atom.cpp
\
test__intrusive_ptr.cpp
\
test__local_group.cpp
\
...
...
unit_testing/main.cpp
View file @
b045c90e
...
...
@@ -177,7 +177,6 @@ int main(int argc, char** argv)
RUN_TEST
(
test__primitive_variant
);
RUN_TEST
(
test__uniform_type
);
RUN_TEST
(
test__intrusive_ptr
);
RUN_TEST
(
test__a_matches_b
);
RUN_TEST
(
test__type_list
);
RUN_TEST
(
test__tuple
);
RUN_TEST
(
test__serialization
);
...
...
unit_testing/test.hpp
View file @
b045c90e
...
...
@@ -47,6 +47,7 @@ std::cerr << err_msg << std::endl; \
++cppa_ts.error_count
#define CPPA_CHECK_EQUAL(lhs_loc, rhs_loc) CPPA_CHECK(((lhs_loc) == (rhs_loc)))
#define CPPA_CHECK_NOT_EQUAL(lhs_loc, rhs_loc) CPPA_CHECK(((lhs_loc) != (rhs_loc)))
size_t
test__yield_interface
();
size_t
test__remote_actor
(
const
char
*
app_path
,
bool
is_client
,
...
...
@@ -54,7 +55,6 @@ size_t test__remote_actor(const char* app_path, bool is_client,
size_t
test__ripemd_160
();
size_t
test__uniform_type
();
size_t
test__type_list
();
size_t
test__a_matches_b
();
size_t
test__atom
();
size_t
test__tuple
();
size_t
test__spawn
();
...
...
unit_testing/test__a_matches_b.cpp
deleted
100644 → 0
View file @
e4a39512
#include <string>
#include <typeinfo>
#include "test.hpp"
#include "cppa/util.hpp"
#include "cppa/anything.hpp"
using
namespace
cppa
;
using
namespace
cppa
::
util
;
size_t
test__a_matches_b
()
{
CPPA_TEST
(
test__a_matches_b
);
/*
typedef type_list<int, anything> int_star;
typedef type_list<int, float, int> int_float_int;
typedef type_list<int, int, std::string> int_int_string;
typedef type_list<int, int, const std::string&> int_int_const_string_ref;
typedef typename first_n<2, int_float_int>::type int_float;
typedef type_list_apply<int_int_const_string_ref,
remove_const_reference>::type
int_int_string2;
CPPA_CHECK((std::is_same<int, remove_const_reference<const int&>::type>::value));
CPPA_CHECK((a_matches_b<int_star, int_float_int>::value));
CPPA_CHECK((a_matches_b<int_float_int, int_float_int>::value));
CPPA_CHECK((a_matches_b<int_int_string, int_int_string>::value));
CPPA_CHECK((a_matches_b<int_int_string, int_int_string2>::value));
CPPA_CHECK(!(a_matches_b<int_int_string, int_int_const_string_ref>::value));
CPPA_CHECK(!(a_matches_b<type_list<float>,
type_list<int, float, int>>::value));
CPPA_CHECK((std::is_same<util::type_list<int, float>, int_float>::value));
CPPA_CHECK((a_matches_b<type_list<anything, float>,
type_list<int, float, int>>::value) == false);
CPPA_CHECK((a_matches_b<type_list<anything, float>,
type_list<int, int, float>>::value));
*/
return
CPPA_TEST_RESULT
;
}
unit_testing/test__pattern.cpp
View file @
b045c90e
...
...
@@ -2,6 +2,7 @@
#include "test.hpp"
#include "cppa/on.hpp"
#include "cppa/atom.hpp"
#include "cppa/tuple.hpp"
#include "cppa/pattern.hpp"
...
...
@@ -11,9 +12,7 @@ using namespace cppa;
size_t
test__pattern
()
{
CPPA_TEST
(
test__pattern
);
auto
x
=
make_tuple
(
atom
(
"FooBar"
),
42
,
"hello world"
);
// some pattern objects to play with
pattern
<
atom_value
,
int
,
std
::
string
>
p0
{
util
::
wrapped
<
atom_value
>
()};
pattern
<
atom_value
,
int
,
std
::
string
>
p1
(
atom
(
"FooBar"
));
pattern
<
atom_value
,
int
,
std
::
string
>
p2
(
atom
(
"FooBar"
),
42
);
...
...
@@ -23,7 +22,8 @@ size_t test__pattern()
pattern
<
anything
>
p6
;
pattern
<
atom_value
,
anything
>
p7
;
pattern
<
atom_value
,
anything
,
std
::
string
>
p8
;
// each one should accept x ...
auto
x
=
make_tuple
(
atom
(
"FooBar"
),
42
,
"hello world"
);
CPPA_CHECK
(
p0
(
x
));
CPPA_CHECK
(
p1
(
x
));
CPPA_CHECK
(
p2
(
x
));
...
...
@@ -33,6 +33,87 @@ size_t test__pattern()
CPPA_CHECK
(
p6
(
x
));
CPPA_CHECK
(
p7
(
x
));
CPPA_CHECK
(
p8
(
x
));
// ... but p2 and p3 should reject y
auto
y
=
make_tuple
(
atom
(
"FooBar"
),
24
,
"hello world"
);
CPPA_CHECK_EQUAL
(
p0
(
y
),
true
);
CPPA_CHECK_EQUAL
(
p1
(
y
),
true
);
CPPA_CHECK_EQUAL
(
p2
(
y
),
false
);
CPPA_CHECK_EQUAL
(
p3
(
y
),
false
);
CPPA_CHECK_EQUAL
(
p4
(
y
),
true
);
CPPA_CHECK_EQUAL
(
p5
(
y
),
true
);
CPPA_CHECK_EQUAL
(
p6
(
y
),
true
);
CPPA_CHECK_EQUAL
(
p7
(
y
),
true
);
CPPA_CHECK_EQUAL
(
p8
(
y
),
true
);
// let's check some invoke rules
constexpr
size_t
num_lambdas
=
6
;
bool
lambda_invoked
[
num_lambdas
];
auto
reset_invoke_states
=
[
&
]()
{
for
(
size_t
i
=
0
;
i
<
num_lambdas
;
++
i
)
{
lambda_invoked
[
i
]
=
false
;
}
};
reset_invoke_states
();
auto
patterns
=
(
on
<
int
,
anything
,
int
>
()
>>
[
&
](
int
v1
,
int
v2
)
{
CPPA_CHECK_EQUAL
(
v1
,
1
);
CPPA_CHECK_EQUAL
(
v2
,
3
);
lambda_invoked
[
0
]
=
true
;
},
on
<
std
::
string
>
()
>>
[
&
](
const
std
::
string
&
str
)
{
CPPA_CHECK_EQUAL
(
str
,
"hello foo"
);
lambda_invoked
[
1
]
=
true
;
},
on
(
"1"
,
val
<
int
>
(),
any_vals
)
>>
[
&
](
int
value
)
{
CPPA_CHECK_EQUAL
(
value
,
2
);
lambda_invoked
[
2
]
=
true
;
},
on
(
1
,
val
<
std
::
string
>
(),
any_vals
)
>>
[
&
](
const
std
::
string
&
str
)
{
CPPA_CHECK_EQUAL
(
str
,
"2"
);
lambda_invoked
[
3
]
=
true
;
},
on
<
atom
(
"Foo"
),
int
>
()
>>
[
&
](
int
value
)
{
CPPA_CHECK_EQUAL
(
value
,
1
);
lambda_invoked
[
4
]
=
true
;
},
on_param_match
()
>>
[
&
](
double
v1
,
const
float
&
v2
)
{
CPPA_CHECK_EQUAL
(
v1
,
1.0
);
CPPA_CHECK_EQUAL
(
v2
,
2.0
f
);
lambda_invoked
[
5
]
=
true
;
}
);
// invokes lambda 0
patterns
(
make_tuple
(
1
,
"2"
,
3
));
CPPA_CHECK
(
lambda_invoked
[
0
]);
reset_invoke_states
();
// invokes lambda 1
patterns
(
make_tuple
(
"hello foo"
));
CPPA_CHECK
(
lambda_invoked
[
1
]);
reset_invoke_states
();
// invokes lambda 2
patterns
(
make_tuple
(
"1"
,
2
,
3
));
CPPA_CHECK
(
lambda_invoked
[
2
]);
reset_invoke_states
();
// invokes lambda 3
patterns
(
make_tuple
(
1
,
"2"
,
"3"
));
CPPA_CHECK
(
lambda_invoked
[
3
]);
reset_invoke_states
();
// invokes lambda 4
patterns
(
make_tuple
(
atom
(
"Foo"
),
1
));
CPPA_CHECK
(
lambda_invoked
[
4
]);
reset_invoke_states
();
// invokes lambda 5
patterns
(
make_tuple
(
1.0
,
2.0
f
));
CPPA_CHECK
(
lambda_invoked
[
5
]);
reset_invoke_states
();
return
CPPA_TEST_RESULT
;
}
unit_testing/test__tuple.cpp
View file @
b045c90e
This diff is collapsed.
Click to expand it.
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