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
704aa400
Commit
704aa400
authored
Apr 03, 2012
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
maintenance
parent
7ae2965f
Changes
27
Show whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
629 additions
and
345 deletions
+629
-345
.gitignore
.gitignore
+1
-0
cppa/any_tuple.hpp
cppa/any_tuple.hpp
+9
-5
cppa/detail/abstract_tuple.hpp
cppa/detail/abstract_tuple.hpp
+24
-7
cppa/detail/container_tuple_view.hpp
cppa/detail/container_tuple_view.hpp
+7
-13
cppa/detail/decorated_tuple.hpp
cppa/detail/decorated_tuple.hpp
+7
-9
cppa/detail/empty_tuple.hpp
cppa/detail/empty_tuple.hpp
+2
-2
cppa/detail/invokable.hpp
cppa/detail/invokable.hpp
+216
-120
cppa/detail/matches.hpp
cppa/detail/matches.hpp
+30
-10
cppa/detail/object_array.hpp
cppa/detail/object_array.hpp
+4
-4
cppa/detail/tuple_cast_impl.hpp
cppa/detail/tuple_cast_impl.hpp
+33
-27
cppa/detail/tuple_vals.hpp
cppa/detail/tuple_vals.hpp
+7
-9
cppa/detail/tuple_view.hpp
cppa/detail/tuple_view.hpp
+7
-7
cppa/match.hpp
cppa/match.hpp
+20
-3
cppa/partial_function.hpp
cppa/partial_function.hpp
+3
-3
cppa/to_string.hpp
cppa/to_string.hpp
+1
-1
cppa/tuple.hpp
cppa/tuple.hpp
+3
-3
cppa/tuple_cast.hpp
cppa/tuple_cast.hpp
+58
-8
examples/announce_example_4.cpp
examples/announce_example_4.cpp
+4
-5
src/abstract_tuple.cpp
src/abstract_tuple.cpp
+10
-1
src/any_tuple.cpp
src/any_tuple.cpp
+0
-50
src/empty_tuple.cpp
src/empty_tuple.cpp
+6
-7
src/invokable.cpp
src/invokable.cpp
+4
-4
src/object_array.cpp
src/object_array.cpp
+4
-10
src/partial_function.cpp
src/partial_function.cpp
+47
-17
unit_testing/main.cpp
unit_testing/main.cpp
+14
-20
unit_testing/test.hpp
unit_testing/test.hpp
+3
-0
unit_testing/test__match.cpp
unit_testing/test__match.cpp
+105
-0
No files found.
.gitignore
View file @
704aa400
...
...
@@ -61,3 +61,4 @@ examples/announce_example_5
examples/hello_world_example
examples/math_actor_example
examples/dining_philosophers
examples/dancing_kirby
cppa/any_tuple.hpp
View file @
704aa400
...
...
@@ -31,6 +31,8 @@
#ifndef ANY_TUPLE_HPP
#define ANY_TUPLE_HPP
#include <iostream>
#include "cppa/tuple.hpp"
#include "cppa/config.hpp"
#include "cppa/cow_ptr.hpp"
...
...
@@ -136,7 +138,7 @@ class any_tuple
}
template
<
typename
T
>
inline
T
&
get_
mutable_as
(
size_t
p
)
inline
T
&
get_
as_mutable
(
size_t
p
)
{
CPPA_REQUIRE
(
*
(
type_at
(
p
))
==
typeid
(
T
));
return
*
reinterpret_cast
<
T
*>
(
mutable_at
(
p
));
...
...
@@ -146,14 +148,16 @@ class any_tuple
inline
const_iterator
end
()
const
{
return
m_vals
->
end
();
}
cow_ptr
<
detail
::
abstract_tuple
>
const
&
vals
()
const
;
inline
cow_ptr
<
detail
::
abstract_tuple
>&
vals
()
{
return
m_vals
;
}
inline
cow_ptr
<
detail
::
abstract_tuple
>
const
&
vals
()
const
{
return
m_vals
;
}
inline
cow_ptr
<
detail
::
abstract_tuple
>
const
&
cvals
()
const
{
return
m_vals
;
}
inline
void
const
*
type_token
()
const
inline
std
::
type_info
const
*
type_token
()
const
{
return
m_vals
->
type_token
();
}
inline
std
::
type_info
const
*
impl_type
()
const
inline
detail
::
tuple_impl_info
impl_type
()
const
{
return
m_vals
->
impl_type
();
}
...
...
@@ -235,7 +239,7 @@ class any_tuple
std
::
integral_constant
<
bool
,
false
>
)
{
typedef
typename
util
::
rm_ref
<
T
>::
type
ctype
;
return
new
detail
::
container_tuple_view
<
T
>
(
new
ctype
(
std
::
forward
<
T
>
(
value
)));
return
new
detail
::
container_tuple_view
<
T
>
(
new
ctype
(
std
::
forward
<
T
>
(
value
))
,
true
);
}
};
...
...
cppa/detail/abstract_tuple.hpp
View file @
704aa400
...
...
@@ -32,6 +32,7 @@
#define ABSTRACT_TUPLE_HPP
#include <iterator>
#include <typeinfo>
#include "cppa/config.hpp"
#include "cppa/ref_counted.hpp"
...
...
@@ -42,11 +43,21 @@
namespace
cppa
{
namespace
detail
{
struct
abstract_tuple
:
ref_counted
enum
tuple_impl_info
{
statically_typed
,
dynamically_typed
};
class
abstract_tuple
:
public
ref_counted
{
tuple_impl_info
m_impl_type
;
public:
abstract_tuple
()
=
default
;
abstract_tuple
(
abstract_tuple
const
&
);
inline
abstract_tuple
(
tuple_impl_info
tii
)
:
m_impl_type
(
tii
)
{
}
abstract_tuple
(
abstract_tuple
const
&
other
);
// mutators
virtual
void
*
mutable_at
(
size_t
pos
)
=
0
;
...
...
@@ -57,12 +68,16 @@ struct abstract_tuple : ref_counted
virtual
void
const
*
at
(
size_t
pos
)
const
=
0
;
virtual
uniform_type_info
const
*
type_at
(
size_t
pos
)
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
;
// Identifies the type of the implementation.
// A statically typed tuple implementation can use some optimizations,
// e.g., "impl_type() == statically_typed" implies that type_token()
// identifies all possible instances of a given tuple implementation
inline
tuple_impl_info
impl_type
()
const
{
return
m_impl_type
;
}
// uniquely identifies this category (element types) of messages
virtual
void
const
*
type_token
()
const
=
0
;
// override this member function only if impl_type() == statically_typed
// (default returns &typeid(void))
virtual
std
::
type_info
const
*
type_token
()
const
;
bool
equals
(
abstract_tuple
const
&
other
)
const
;
...
...
@@ -151,8 +166,10 @@ struct abstract_tuple : ref_counted
};
inline
const_iterator
begin
()
const
{
return
{
this
};
}
inline
const_iterator
cbegin
()
const
{
return
{
this
};
}
inline
const_iterator
end
()
const
{
return
{
this
,
size
()};
}
inline
const_iterator
cend
()
const
{
return
{
this
,
size
()};
}
};
...
...
cppa/detail/container_tuple_view.hpp
View file @
704aa400
...
...
@@ -31,6 +31,8 @@
#ifndef CONTAINER_TUPLE_VIEW_HPP
#define CONTAINER_TUPLE_VIEW_HPP
#include <iostream>
#include "cppa/detail/tuple_vals.hpp"
#include "cppa/detail/object_array.hpp"
#include "cppa/detail/abstract_tuple.hpp"
...
...
@@ -42,11 +44,14 @@ template<class Container>
class
container_tuple_view
:
public
abstract_tuple
{
typedef
abstract_tuple
super
;
public:
typedef
typename
Container
::
value_type
value_type
;
container_tuple_view
(
Container
*
c
,
bool
take_ownership
=
false
)
:
m_ptr
(
c
)
container_tuple_view
(
Container
*
c
,
bool
take_ownership
=
false
)
:
super
(
tuple_impl_info
::
dynamically_typed
),
m_ptr
(
c
)
{
CPPA_REQUIRE
(
c
!=
nullptr
);
if
(
!
take_ownership
)
m_ptr
.
get_deleter
().
disable
();
...
...
@@ -78,22 +83,11 @@ class container_tuple_view : public abstract_tuple
return
&
(
*
i
);
}
uniform_type_info
const
*
type_at
(
size_t
pos
)
const
uniform_type_info
const
*
type_at
(
size_t
)
const
{
CPPA_REQUIRE
(
pos
<
size
());
return
static_types_array
<
value_type
>::
arr
[
0
];
}
void
const
*
type_token
()
const
{
return
&
(
typeid
(
Container
));
}
std
::
type_info
const
*
impl_type
()
const
{
return
&
(
typeid
(
detail
::
object_array
));
}
private:
std
::
unique_ptr
<
Container
,
disablable_delete
<
Container
>
>
m_ptr
;
...
...
cppa/detail/decorated_tuple.hpp
View file @
704aa400
...
...
@@ -53,6 +53,8 @@ template<typename... ElementTypes>
class
decorated_tuple
:
public
abstract_tuple
{
typedef
abstract_tuple
super
;
static_assert
(
sizeof
...(
ElementTypes
)
>
0
,
"decorated_tuple is not allowed to be empty"
);
...
...
@@ -102,14 +104,9 @@ class decorated_tuple : public abstract_tuple
return
m_decorated
->
type_at
(
m_mapping
[
pos
]);
}
void
const
*
type_token
()
const
{
return
detail
::
static_type_list
<
ElementTypes
...
>::
list
;
}
std
::
type_info
const
*
impl_type
()
const
std
::
type_info
const
*
type_token
()
const
{
return
detail
::
static_type_list
<
ElementTypes
...
>::
list
;
return
static_type_list
<
ElementTypes
...
>::
list
;
}
private:
...
...
@@ -118,7 +115,8 @@ class decorated_tuple : public abstract_tuple
vector_type
m_mapping
;
decorated_tuple
(
cow_pointer_type
d
,
vector_type
const
&
v
)
:
m_decorated
(
std
::
move
(
d
)),
m_mapping
(
v
)
:
super
(
tuple_impl_info
::
statically_typed
)
,
m_decorated
(
std
::
move
(
d
)),
m_mapping
(
v
)
{
# ifdef CPPA_DEBUG
cow_pointer_type
const
&
ptr
=
m_decorated
;
// prevent detaching
...
...
@@ -129,7 +127,7 @@ class decorated_tuple : public abstract_tuple
}
decorated_tuple
(
cow_pointer_type
d
,
size_t
offset
)
:
m_decorated
(
std
::
move
(
d
))
:
super
(
tuple_impl_info
::
statically_typed
),
m_decorated
(
std
::
move
(
d
))
{
# ifdef CPPA_DEBUG
cow_pointer_type
const
&
ptr
=
m_decorated
;
// prevent detaching
...
...
cppa/detail/empty_tuple.hpp
View file @
704aa400
...
...
@@ -40,14 +40,14 @@ struct empty_tuple : abstract_tuple
using
abstract_tuple
::
const_iterator
;
empty_tuple
();
size_t
size
()
const
;
void
*
mutable_at
(
size_t
);
abstract_tuple
*
copy
()
const
;
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
;
void
const
*
type_token
()
const
;
std
::
type_info
const
*
type_token
()
const
;
};
...
...
cppa/detail/invokable.hpp
View file @
704aa400
...
...
@@ -47,9 +47,6 @@
#include "cppa/detail/matches.hpp"
#include "cppa/detail/intermediate.hpp"
// forward declaration
namespace
cppa
{
class
any_tuple
;
class
partial_function
;
}
namespace
cppa
{
namespace
detail
{
class
invokable
...
...
@@ -65,207 +62,306 @@ class invokable
inline
invokable
()
:
next
(
nullptr
)
{
}
virtual
~
invokable
();
virtual
bool
invoke
(
any_tuple
const
&
)
const
;
// Suppress type checking.
virtual
bool
unsafe_invoke
(
any_tuple
const
&
value
)
const
;
// Checks whether the types of @p value match the pattern.
virtual
bool
types_match
(
any_tuple
const
&
value
)
const
;
// Checks whether this invokable could be invoked with @p value.
virtual
bool
could_invoke
(
any_tuple
const
&
value
)
const
;
// Type checking.
virtual
bool
invoke
(
any_tuple
&
value
)
const
;
// Suppress type checking.
virtual
bool
unsafe_invoke
(
any_tuple
&
value
)
const
;
// Prepare this invokable.
virtual
intermediate
*
get_intermediate
(
any_tuple
const
&
value
);
virtual
intermediate
*
get_intermediate
(
any_tuple
&
value
);
// Prepare this invokable and suppress type checking.
virtual
intermediate
*
get_unsafe_intermediate
(
any_tuple
const
&
value
);
virtual
intermediate
*
get_unsafe_intermediate
(
any_tuple
&
value
);
};
template
<
class
Tuple
,
class
Pattern
>
struct
abstract_invokable
:
public
invokable
/*
* @tparam Fun Function or functor
* @tparam FunArgs Type list of functor parameters *without* any qualifiers
*/
template
<
typename
Fun
,
class
FunArgs
,
class
TupleTypes
>
struct
iimpl
:
intermediate
{
Pattern
m_pattern
;
abstract_invokable
()
{
}
template
<
typename
...
Args
>
abstract_invokable
(
Args
&&
...
args
)
:
m_pattern
(
std
::
forward
<
Args
>
(
args
)...)
typedef
Fun
functor_type
;
typedef
typename
tuple_from_type_list
<
TupleTypes
>::
type
tuple_type
;
functor_type
m_fun
;
tuple_type
m_default_args
;
tuple_type
m_args
;
template
<
typename
F
>
iimpl
(
F
&&
fun
)
:
m_fun
(
std
::
forward
<
F
>
(
fun
))
{
}
void
invoke
()
{
util
::
apply_tuple
(
m_fun
,
m_args
);
// "forget" arguments after invocation
m_args
=
m_default_args
;
}
bool
types_match
(
any_tuple
const
&
value
)
const
inline
intermediate
*
prepare
(
option
<
tuple_type
>&&
tup
)
{
return
matches_types
(
value
,
m_pattern
);
}
bool
could_invoke
(
any_tuple
const
&
value
)
const
if
(
tup
)
{
return
matches
(
value
,
m_pattern
);
m_args
=
std
::
move
(
*
tup
);
return
this
;
}
};
template
<
bool
CheckValues
,
size_t
NumArgs
,
typename
Fun
,
class
Tuple
,
class
Pattern
>
class
invokable_impl
:
public
abstract_invokable
<
Tuple
,
Pattern
>
{
typedef
abstract_invokable
<
Tuple
,
Pattern
>
super
;
template
<
typename
T
>
inline
bool
invoke_impl
(
option
<
T
>&&
tup
)
const
return
nullptr
;
}
inline
bool
operator
()(
option
<
tuple_type
>&&
tup
)
const
{
if
(
tup
)
{
util
::
apply_tuple
(
m_
iimpl
.
m_
fun
,
*
tup
);
util
::
apply_tuple
(
m_fun
,
*
tup
);
return
true
;
}
return
false
;
}
};
template
<
typename
T
>
inline
intermediate
*
get_intermediate_impl
(
option
<
T
>&&
tup
)
{
if
(
tup
)
template
<
typename
Fun
,
class
TupleTypes
>
struct
iimpl
<
Fun
,
util
::
type_list
<>
,
TupleTypes
>
:
intermediate
{
typedef
Fun
functor_type
;
functor_type
m_fun
;
template
<
typename
F
>
iimpl
(
F
&&
fun
)
:
m_fun
(
std
::
forward
<
F
>
(
fun
))
{
}
void
invoke
()
{
m_fun
();
}
inline
intermediate
*
prepare
(
bool
result
)
// result passed by policy
{
m_iimpl
.
m_args
=
std
::
move
(
*
tup
);
return
&
m_iimpl
;
return
result
?
this
:
nullptr
;
}
return
nullptr
;
inline
bool
operator
()(
bool
result
)
const
// result passed by policy
{
if
(
result
)
m_fun
();
return
result
;
}
};
protected:
struct
iimpl
:
intermediate
{
Fun
m_fun
;
Tuple
m_args
;
template
<
typename
Fun
,
class
TupleTypes
>
struct
iimpl
<
Fun
,
util
::
type_list
<
any_tuple
>
,
TupleTypes
>
:
intermediate
{
typedef
Fun
functor_type
;
functor_type
m_fun
;
any_tuple
m_arg
;
template
<
typename
F
>
iimpl
(
F
&&
fun
)
:
m_fun
(
std
::
forward
<
F
>
(
fun
))
{
}
void
invoke
()
{
util
::
apply_tuple
(
m_fun
,
m_args
);
}
void
invoke
()
{
m_fun
(
m_arg
);
m_arg
=
any_tuple
{};
}
inline
intermediate
*
prepare
(
any_tuple
arg
)
{
m_arg
=
std
::
move
(
arg
);
return
this
;
}
inline
bool
operator
()(
any_tuple
arg
)
const
{
m_fun
(
arg
);
return
true
;
}
m_iimpl
;
}
;
public:
enum
mapping_policy
{
do_not_map
,
map_to_bool
,
map_to_option
};
template
<
typename
F
,
typename
...
Args
>
invokable_impl
(
F
&&
fun
,
Args
&&
...
args
)
:
super
(
std
::
forward
<
Args
>
(
args
)...),
m_iimpl
(
std
::
forward
<
F
>
(
fun
))
template
<
mapping_policy
,
class
Pattern
>
struct
pattern_policy
{
Pattern
m_pattern
;
template
<
typename
...
Args
>
pattern_policy
(
Args
&&
...
args
)
:
m_pattern
(
std
::
forward
<
Args
>
(
args
)...)
{
}
bool
types_match
(
any_tuple
const
&
value
)
const
{
return
matches_types
(
value
,
m_pattern
);
}
bool
invoke
(
any_tuple
const
&
value
)
const
bool
could_invoke
(
any_tuple
const
&
value
)
const
{
return
invoke_impl
(
tuple_cast
(
value
,
this
->
m_pattern
)
);
return
matches
(
value
,
m_pattern
);
}
bool
unsafe_invoke
(
any_tuple
const
&
value
)
const
any_tuple
map
(
any_tuple
&
value
)
const
{
return
invoke_impl
(
unsafe_tuple_cast
(
value
,
this
->
m_pattern
)
);
return
std
::
move
(
value
);
}
intermediate
*
get_intermediate
(
any_tuple
const
&
value
)
any_tuple
map_unsafe
(
any_tuple
&
value
)
const
{
return
get_intermediate_impl
(
tuple_cast
(
value
,
this
->
m_pattern
)
);
return
std
::
move
(
value
);
}
};
intermediate
*
get_unsafe_intermediate
(
any_tuple
const
&
value
)
template
<
class
Pattern
>
struct
pattern_policy
<
map_to_option
,
Pattern
>
{
Pattern
m_pattern
;
template
<
typename
...
Args
>
pattern_policy
(
Args
&&
...
args
)
:
m_pattern
(
std
::
forward
<
Args
>
(
args
)...)
{
}
bool
types_match
(
any_tuple
const
&
value
)
const
{
return
get_intermediate_impl
(
unsafe_tuple_cast
(
value
,
this
->
m_pattern
));
return
matches_types
(
value
,
m_pattern
);
}
bool
could_invoke
(
any_tuple
const
&
value
)
const
{
return
matches
(
value
,
m_pattern
);
}
auto
map
(
any_tuple
&
value
)
const
->
decltype
(
moving_tuple_cast
(
value
,
m_pattern
))
{
auto
result
=
moving_tuple_cast
(
value
,
m_pattern
);
return
result
;
}
auto
map_unsafe
(
any_tuple
&
value
)
const
->
decltype
(
unsafe_tuple_cast
(
value
,
m_pattern
))
{
return
unsafe_tuple_cast
(
value
,
m_pattern
);
}
};
template
<
class
Pattern
>
struct
pattern_policy
<
map_to_bool
,
Pattern
>
{
Pattern
m_pattern
;
template
<
typename
...
Args
>
pattern_policy
(
Args
&&
...
args
)
:
m_pattern
(
std
::
forward
<
Args
>
(
args
)...)
{
}
bool
types_match
(
any_tuple
const
&
value
)
const
{
return
matches_types
(
value
,
m_pattern
);
}
bool
could_invoke
(
any_tuple
const
&
value
)
const
{
return
matches
(
value
,
m_pattern
);
}
bool
map
(
any_tuple
&
value
)
const
{
return
could_invoke
(
value
);
}
bool
map_unsafe
(
any_tuple
&
value
)
const
{
return
could_invoke
(
value
);
}
};
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
>
struct
dummy_policy
{
typedef
invokable_impl
<
true
,
NumArgs
,
Fun
,
Tuple
,
Pattern
>
super
;
template
<
typename
F
>
invokable_impl
(
F
&&
fun
)
:
super
(
std
::
forward
<
F
>
(
fun
))
inline
bool
types_match
(
any_tuple
const
&
)
const
{
return
true
;
}
bool
unsafe_invoke
(
any_tuple
const
&
value
)
const
inline
bool
could_invoke
(
any_tuple
const
&
)
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
)
inline
any_tuple
map
(
any_tuple
&
value
)
const
{
return
std
::
move
(
value
);
}
inline
any_tuple
map_unsafe
(
any_tuple
&
value
)
const
{
(
this
->
m_iimpl
).
m_args
=
forced_tuple_cast
(
value
,
this
->
m_pattern
);
return
&
(
this
->
m_iimpl
);
return
std
::
move
(
value
);
}
};
template
<
typename
Fun
,
class
Tuple
,
class
Pattern
>
class
invokable_impl
<
true
,
0
,
Fun
,
Tuple
,
Pattern
>
:
public
abstract_invokable
<
Tuple
,
Pattern
>
template
<
class
IntermediateImpl
,
class
Policy
>
struct
invokable_impl
:
public
invokable
{
typedef
abstract_invokable
<
Tuple
,
Pattern
>
super
;
IntermediateImpl
m_ii
;
Policy
m_policy
;
template
<
typename
...
P
>
inline
bool
unsafe_vmatch
(
any_tuple
const
&
t
,
pattern
<
P
...
>
const
&
p
)
const
template
<
typename
Arg0
,
typename
...
Args
>
invokable_impl
(
Arg0
&&
arg0
,
Args
&&
...
args
)
:
m_ii
(
std
::
forward
<
Arg0
>
(
arg0
))
,
m_policy
(
std
::
forward
<
Args
>
(
args
)...)
{
return
matcher
<
pattern
<
P
...
>::
wildcard_pos
,
P
...
>::
vmatch
(
t
,
p
);
}
protected:
struct
iimpl
:
intermediate
bool
invoke
(
any_tuple
&
value
)
const
{
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
;
}
return
m_ii
(
m_policy
.
map
(
value
));
}
m_iimpl
;
public:
template
<
typename
F
,
typename
...
Args
>
invokable_impl
(
F
&&
fun
,
Args
&&
...
args
)
:
super
(
std
::
forward
<
Args
>
(
args
)...),
m_iimpl
(
std
::
forward
<
F
>
(
fun
))
bool
unsafe_invoke
(
any_tuple
&
value
)
const
{
return
m_ii
(
m_policy
.
map_unsafe
(
value
));
}
bool
invoke
(
any_tuple
const
&
value
)
const
bool
types_match
(
any_tuple
const
&
value
)
const
{
return
m
atches
(
value
,
this
->
m_pattern
)
?
m_iimpl
()
:
false
;
return
m
_policy
.
types_match
(
value
)
;
}
bool
unsafe_invoke
(
any_tuple
const
&
value
)
const
bool
could_invoke
(
any_tuple
const
&
value
)
const
{
return
unsafe_vmatch
(
value
,
this
->
m_pattern
)
?
m_iimpl
()
:
false
;
return
m_policy
.
could_invoke
(
value
)
;
}
intermediate
*
get_intermediate
(
any_tuple
const
&
value
)
intermediate
*
get_intermediate
(
any_tuple
&
value
)
{
return
m
atches
(
value
,
this
->
m_pattern
)
?
&
m_iimpl
:
nullptr
;
return
m
_ii
.
prepare
(
m_policy
.
map
(
value
))
;
}
intermediate
*
get_unsafe_intermediate
(
any_tuple
const
&
value
)
intermediate
*
get_unsafe_intermediate
(
any_tuple
&
value
)
{
return
unsafe_vmatch
(
value
,
this
->
m_pattern
)
?
&
m_iimpl
:
nullptr
;
return
m_ii
.
prepare
(
m_policy
.
map_unsafe
(
value
))
;
}
};
template
<
typename
Fun
,
class
Tuple
,
class
Pattern
>
struct
invokable_impl
<
false
,
0
,
Fun
,
Tuple
,
Pattern
>
:
public
invokable_impl
<
true
,
0
,
Fun
,
Tuple
,
Pattern
>
template
<
class
ArgTypes
>
constexpr
mapping_policy
get_mapping_policy
()
{
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
(
this
->
m_iimpl
)();
}
intermediate
*
get_unsafe_intermediate
(
any_tuple
const
&
)
{
return
&
(
this
->
m_iimpl
);
}
return
(
ArgTypes
::
size
==
0
)
?
map_to_bool
:
((
std
::
is_same
<
typename
ArgTypes
::
head
,
any_tuple
>::
value
&&
ArgTypes
::
size
==
1
)
?
do_not_map
:
map_to_option
);
}
template
<
class
Container
>
struct
filtered
;
template
<
typename
...
Ts
>
struct
filtered
<
util
::
type_list
<
Ts
...
>
>
{
typedef
typename
util
::
tl_filter_not
<
util
::
type_list
<
Ts
...
>
,
is_anything
>::
type
types
;
};
template
<
typename
...
Ts
>
struct
filtered
<
pattern
<
Ts
...
>
>
{
typedef
typename
filtered
<
util
::
type_list
<
Ts
...
>>::
types
types
;
};
template
<
typename
Fun
,
class
Pattern
>
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
<
true
,
arg_types
::
size
,
Fun
,
tuple_type
,
Pattern
>
type1
;
typedef
invokable_impl
<
false
,
arg_types
::
size
,
Fun
,
tuple_type
,
Pattern
>
type2
;
typedef
typename
util
::
get_arg_types
<
Fun
>::
types
qualified_arg_types
;
typedef
typename
util
::
tl_apply
<
qualified_arg_types
,
util
::
rm_ref
>::
type
arg_types
;
static
constexpr
mapping_policy
mp
=
get_mapping_policy
<
arg_types
>
();
typedef
invokable_impl
<
iimpl
<
Fun
,
arg_types
,
typename
filtered
<
Pattern
>::
types
>
,
pattern_policy
<
mp
,
Pattern
>
>
type
;
};
template
<
typename
Fun
>
struct
select_invokable_impl
<
Fun
,
pattern
<
anything
>
>
{
typedef
typename
util
::
get_arg_types
<
Fun
>::
types
qualified_arg_types
;
typedef
typename
util
::
tl_apply
<
qualified_arg_types
,
util
::
rm_ref
>::
type
arg_types
;
typedef
typename
util
::
rm_ref
<
typename
arg_types
::
head
>::
type
arg0
;
static_assert
(
arg_types
::
size
<
2
,
"functor has too many arguments"
);
static_assert
(
arg_types
::
size
==
0
||
std
::
is_same
<
any_tuple
,
arg0
>::
value
,
"bad signature"
);
typedef
invokable_impl
<
iimpl
<
Fun
,
arg_types
,
util
::
type_list
<>
>
,
dummy_policy
>
type
;
};
template
<
class
Pattern
,
typename
Fun
,
typename
Data
>
std
::
unique_ptr
<
invokable
>
get_invokable_impl
(
Fun
&&
fun
,
Data
&&
dt
)
{
typedef
typename
select_invokable_impl
<
Fun
,
Pattern
>::
type
1
result
;
typedef
typename
select_invokable_impl
<
Fun
,
Pattern
>::
type
result
;
return
std
::
unique_ptr
<
invokable
>
(
new
result
(
std
::
forward
<
Fun
>
(
fun
),
std
::
forward
<
Data
>
(
dt
)));
}
...
...
@@ -273,7 +369,7 @@ std::unique_ptr<invokable> get_invokable_impl(Fun&& fun, Data&& dt)
template
<
class
Pattern
,
typename
Fun
>
std
::
unique_ptr
<
invokable
>
get_invokable_impl
(
Fun
&&
fun
)
{
typedef
typename
select_invokable_impl
<
Fun
,
Pattern
>::
type2
result
;
typedef
typename
select_invokable_impl
<
Fun
,
typename
Pattern
::
types
>::
type
result
;
return
std
::
unique_ptr
<
invokable
>
(
new
result
(
std
::
forward
<
Fun
>
(
fun
)));
}
...
...
cppa/detail/matches.hpp
View file @
704aa400
...
...
@@ -46,18 +46,14 @@ struct matcher<wildcard_position::nil, T...>
{
static
inline
bool
tmatch
(
any_tuple
const
&
tup
)
{
// match implementation type if possible
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
)
if
(
tup
.
impl_type
()
==
tuple_impl_info
::
statically_typed
)
{
return
true
;
// statically typed tuples return &typeid(type_list<T...>)
// as type token
return
typeid
(
util
::
type_list
<
T
...
>
)
==
*
(
tup
.
type_token
());
}
// always use a full dynamic match for object arrays
else
if
(
*
impl
==
typeid
(
detail
::
object_array
)
&&
tup
.
size
()
==
sizeof
...(
T
))
// always use a full dynamic match for dynamic typed tuples
else
if
(
tup
.
size
()
==
sizeof
...(
T
))
{
auto
&
tarr
=
detail
::
static_types_array
<
T
...
>::
arr
;
return
std
::
equal
(
tup
.
begin
(),
tup
.
end
(),
tarr
.
begin
(),
...
...
@@ -479,6 +475,24 @@ bool matches(any_tuple const& tup, pattern<Ts...> const& pn,
mv
);
}
// support for type_list based matching
template
<
typename
...
Ts
>
inline
bool
matches
(
any_tuple
const
&
tup
,
util
::
type_list
<
Ts
...
>
const
&
)
{
return
matches
<
Ts
...
>
(
tup
);
}
template
<
typename
...
Ts
>
inline
bool
matches
(
any_tuple
const
&
tup
,
util
::
type_list
<
Ts
...
>
const
&
,
util
::
fixed_vector
<
size_t
,
util
::
tl_count_not
<
util
::
type_list
<
Ts
...
>
,
is_anything
>::
value
>&
mv
)
{
return
matches
<
Ts
...
>
(
mv
);
}
/*
* @brief Returns true if this tuple matches the pattern <tt>{Ts...}</tt>
* (does not match for values).
...
...
@@ -489,6 +503,12 @@ inline bool matches_types(any_tuple const& tup, pattern<Ts...> const&)
return
matches
<
Ts
...
>
(
tup
);
}
template
<
typename
...
Ts
>
inline
bool
matches_types
(
any_tuple
const
&
tup
,
util
::
type_list
<
Ts
...
>
const
&
)
{
return
matches
<
Ts
...
>
(
tup
);
}
}
}
// namespace cppa::detail
#endif // MATCHES_HPP
cppa/detail/object_array.hpp
View file @
704aa400
...
...
@@ -42,13 +42,13 @@ namespace cppa { namespace detail {
class
object_array
:
public
abstract_tuple
{
std
::
vector
<
object
>
m_elements
;
typedef
abstract_tuple
super
;
public:
using
abstract_tuple
::
const_iterator
;
object_array
()
=
default
;
object_array
();
object_array
(
object_array
&&
)
=
default
;
object_array
(
object_array
const
&
)
=
default
;
...
...
@@ -68,9 +68,9 @@ class object_array : public abstract_tuple
uniform_type_info
const
*
type_at
(
size_t
pos
)
const
;
void
const
*
type_token
()
const
;
private:
std
::
type_info
const
*
impl_type
()
const
;
std
::
vector
<
object
>
m_elements
;
};
...
...
cppa/detail/tuple_cast_impl.hpp
View file @
704aa400
...
...
@@ -61,19 +61,21 @@ struct tuple_cast_impl
static
constexpr
size_t
first_wc
=
static_cast
<
size_t
>
(
util
::
tl_find
<
util
::
type_list
<
T
...
>
,
anything
>::
value
);
typedef
util
::
fixed_vector
<
size_t
,
size
>
mapping_vector
;
static
inline
option
<
Result
>
safe
(
any_tuple
const
&
tup
)
static
inline
option
<
Result
>
safe
(
any_tuple
&
tup
)
{
mapping_vector
mv
;
if
(
matches
<
T
...
>
(
tup
,
mv
))
return
{
Result
::
from
(
tup
.
vals
(),
mv
)};
if
(
matches
<
T
...
>
(
tup
,
mv
))
return
{
Result
::
from
(
std
::
move
(
tup
.
vals
()),
mv
)};
return
{};
}
static
inline
option
<
Result
>
safe
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
static
inline
option
<
Result
>
safe
(
any_tuple
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
mapping_vector
mv
;
if
(
matches
(
tup
,
p
,
mv
))
return
{
Result
::
from
(
tup
.
vals
(),
mv
)};
if
(
matches
(
tup
,
p
,
mv
))
return
{
Result
::
from
(
std
::
move
(
tup
.
vals
()),
mv
)};
return
{};
}
static
inline
option
<
Result
>
unsafe
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
static
inline
option
<
Result
>
unsafe
(
any_tuple
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
mapping_vector
mv
;
if
(
WP
==
wildcard_position
::
in_between
)
...
...
@@ -87,16 +89,17 @@ struct tuple_cast_impl
// second range
begin
=
mv
.
begin
()
+
first_wc
;
std
::
iota
(
begin
,
mv
.
end
(),
tup
.
size
()
-
(
size
-
first_wc
));
return
{
Result
::
from
(
tup
.
vals
(
),
mv
)};
return
{
Result
::
from
(
std
::
move
(
tup
.
vals
()
),
mv
)};
}
}
else
{
if
(
matches
(
tup
,
p
,
mv
))
return
{
Result
::
from
(
tup
.
vals
(),
mv
)};
if
(
matches
(
tup
,
p
,
mv
))
return
{
Result
::
from
(
std
::
move
(
tup
.
vals
()),
mv
)};
}
return
{};
}
static
inline
Result
force
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
static
inline
Result
force
(
any_tuple
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
mapping_vector
mv
;
if
(
WP
==
wildcard_position
::
in_between
)
...
...
@@ -108,12 +111,12 @@ struct tuple_cast_impl
// second range
begin
=
mv
.
begin
()
+
first_wc
;
std
::
iota
(
begin
,
mv
.
end
(),
tup
.
size
()
-
(
size
-
first_wc
));
return
{
Result
::
from
(
tup
.
vals
(
),
mv
)};
return
{
Result
::
from
(
std
::
move
(
tup
.
vals
()
),
mv
)};
}
else
{
matches
(
tup
,
p
,
mv
);
return
{
Result
::
from
(
tup
.
vals
(
),
mv
)};
return
{
Result
::
from
(
std
::
move
(
tup
.
vals
()
),
mv
)};
}
}
};
...
...
@@ -121,28 +124,31 @@ struct tuple_cast_impl
template
<
class
Result
,
typename
...
T
>
struct
tuple_cast_impl
<
wildcard_position
::
nil
,
Result
,
T
...
>
{
static
inline
option
<
Result
>
safe
(
any_tuple
const
&
tup
)
static
inline
option
<
Result
>
safe
(
any_tuple
&
tup
)
{
if
(
matches
<
T
...
>
(
tup
))
return
{
Result
::
from
(
tup
.
vals
(
))};
if
(
matches
<
T
...
>
(
tup
))
return
{
Result
::
from
(
std
::
move
(
tup
.
vals
()
))};
return
{};
}
static
inline
option
<
Result
>
safe
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
static
inline
option
<
Result
>
safe
(
any_tuple
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
if
(
matches
(
tup
,
p
))
return
{
Result
::
from
(
tup
.
vals
())};
if
(
matches
(
tup
,
p
))
{
return
{
Result
::
from
(
std
::
move
(
tup
.
vals
()))};
}
return
{};
}
static
inline
option
<
Result
>
unsafe
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
static
inline
option
<
Result
>
unsafe
(
any_tuple
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
if
(
p
.
has_values
()
==
false
||
matcher
<
wildcard_position
::
nil
,
T
...
>::
vmatch
(
tup
,
p
))
{
return
{
Result
::
from
(
tup
.
vals
(
))};
return
{
Result
::
from
(
std
::
move
(
tup
.
vals
()
))};
}
return
{};
}
static
inline
Result
force
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
)
static
inline
Result
force
(
any_tuple
&
tup
,
pattern
<
T
...
>
const
&
)
{
return
{
Result
::
from
(
tup
.
vals
(
))};
return
{
Result
::
from
(
std
::
move
(
tup
.
vals
()
))};
}
};
...
...
@@ -150,37 +156,37 @@ template<class Result, typename... T>
struct
tuple_cast_impl
<
wildcard_position
::
trailing
,
Result
,
T
...
>
:
tuple_cast_impl
<
wildcard_position
::
nil
,
Result
,
T
...
>
{
static
inline
option
<
Result
>
unsafe
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
static
inline
option
<
Result
>
unsafe
(
any_tuple
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
if
(
p
.
has_values
()
==
false
||
matcher
<
wildcard_position
::
trailing
,
T
...
>::
vmatch
(
tup
,
p
))
{
return
{
Result
::
from
(
tup
.
vals
(
))};
return
{
Result
::
from
(
std
::
move
(
tup
.
vals
()
))};
}
return
{};
}
static
inline
Result
force
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
)
static
inline
Result
force
(
any_tuple
&
tup
,
pattern
<
T
...
>
const
&
)
{
return
{
Result
::
from
(
tup
.
vals
(
))};
return
{
Result
::
from
(
std
::
move
(
tup
.
vals
()
))};
}
};
template
<
class
Result
,
typename
...
T
>
struct
tuple_cast_impl
<
wildcard_position
::
leading
,
Result
,
T
...
>
{
static
inline
option
<
Result
>
safe
(
any_tuple
const
&
tup
)
static
inline
option
<
Result
>
safe
(
any_tuple
&
tup
)
{
size_t
o
=
tup
.
size
()
-
(
sizeof
...(
T
)
-
1
);
if
(
matches
<
T
...
>
(
tup
))
return
{
Result
::
offset_subtuple
(
tup
.
vals
(),
o
)};
return
{};
}
static
inline
option
<
Result
>
safe
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
static
inline
option
<
Result
>
safe
(
any_tuple
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
size_t
o
=
tup
.
size
()
-
(
sizeof
...(
T
)
-
1
);
if
(
matches
(
tup
,
p
))
return
{
Result
::
offset_subtuple
(
tup
.
vals
(),
o
)};
return
{};
}
static
inline
option
<
Result
>
unsafe
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
static
inline
option
<
Result
>
unsafe
(
any_tuple
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
if
(
p
.
has_values
()
==
false
||
matcher
<
wildcard_position
::
leading
,
T
...
>::
vmatch
(
tup
,
p
))
...
...
@@ -190,7 +196,7 @@ struct tuple_cast_impl<wildcard_position::leading, Result, T...>
}
return
{};
}
static
inline
Result
force
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
)
static
inline
Result
force
(
any_tuple
&
tup
,
pattern
<
T
...
>
const
&
)
{
size_t
o
=
tup
.
size
()
-
(
sizeof
...(
T
)
-
1
);
return
Result
::
offset_subtuple
(
tup
.
vals
(),
o
);
...
...
cppa/detail/tuple_vals.hpp
View file @
704aa400
...
...
@@ -59,11 +59,14 @@ class tuple_vals : public abstract_tuple
typedef
types_array
<
ElementTypes
...
>
element_types
;
tuple_vals
()
:
m_data
()
{
}
tuple_vals
()
:
super
(
tuple_impl_info
::
statically_typed
),
m_data
()
{
}
tuple_vals
(
tuple_vals
const
&
other
)
:
super
(),
m_data
(
other
.
m_data
)
{
}
tuple_vals
(
tuple_vals
const
&
)
=
default
;
tuple_vals
(
ElementTypes
const
&
...
args
)
:
m_data
(
args
...)
{
}
tuple_vals
(
ElementTypes
const
&
...
args
)
:
super
(
tuple_impl_info
::
statically_typed
),
m_data
(
args
...)
{
}
inline
data_type
&
data
()
{
...
...
@@ -114,12 +117,7 @@ class tuple_vals : public abstract_tuple
return
abstract_tuple
::
equals
(
other
);
}
void
const
*
type_token
()
const
{
return
detail
::
static_type_list
<
ElementTypes
...
>::
list
;
}
std
::
type_info
const
*
impl_type
()
const
std
::
type_info
const
*
type_token
()
const
{
return
detail
::
static_type_list
<
ElementTypes
...
>::
list
;
}
...
...
cppa/detail/tuple_view.hpp
View file @
704aa400
...
...
@@ -57,6 +57,8 @@ class tuple_view : public abstract_tuple
static_assert
(
sizeof
...(
ElementTypes
)
>
0
,
"tuple_vals is not allowed to be empty"
);
typedef
abstract_tuple
super
;
public:
typedef
tdata
<
ElementTypes
*
...
>
data_type
;
...
...
@@ -69,7 +71,10 @@ class tuple_view : public abstract_tuple
/**
* @warning @p tuple_view does @b NOT takes ownership for given pointers
*/
tuple_view
(
ElementTypes
*
...
args
)
:
m_data
(
args
...)
{
}
tuple_view
(
ElementTypes
*
...
args
)
:
super
(
tuple_impl_info
::
statically_typed
),
m_data
(
args
...)
{
}
inline
data_type
&
data
()
{
...
...
@@ -112,12 +117,7 @@ class tuple_view : public abstract_tuple
return
m_types
[
pos
];
}
void
const
*
type_token
()
const
{
return
detail
::
static_type_list
<
ElementTypes
...
>::
list
;
}
std
::
type_info
const
*
impl_type
()
const
std
::
type_info
const
*
type_token
()
const
{
return
detail
::
static_type_list
<
ElementTypes
...
>::
list
;
}
...
...
cppa/match.hpp
View file @
704aa400
...
...
@@ -38,23 +38,29 @@ namespace cppa { namespace detail {
struct
match_helper
{
match_helper
(
match_helper
const
&
)
=
delete
;
match_helper
&
operator
=
(
match_helper
const
&
)
=
delete
;
any_tuple
tup
;
match_helper
(
any_tuple
t
)
:
tup
(
std
::
move
(
t
))
{
}
match_helper
(
any_tuple
&&
t
)
:
tup
(
std
::
move
(
t
))
{
}
match_helper
(
match_helper
&&
)
=
default
;
template
<
class
...
Args
>
void
operator
()(
partial_function
&&
pf
,
Args
&&
...
args
)
{
partial_function
tmp
;
tmp
.
splice
(
std
::
move
(
pf
),
std
::
forward
<
Args
>
(
args
)...);
tmp
(
tup
);
tmp
(
std
::
move
(
tup
)
);
}
};
template
<
typename
Iterator
>
struct
match_each_helper
{
match_each_helper
(
match_each_helper
const
&
)
=
delete
;
match_each_helper
&
operator
=
(
match_each_helper
const
&
)
=
delete
;
Iterator
i
;
Iterator
e
;
match_each_helper
(
Iterator
first
,
Iterator
last
)
:
i
(
first
),
e
(
last
)
{
}
match_each_helper
(
match_each_helper
&&
)
=
default
;
template
<
typename
...
Args
>
void
operator
()(
partial_function
&&
arg0
,
Args
&&
...
args
)
{
...
...
@@ -70,11 +76,17 @@ struct match_each_helper
template
<
typename
Iterator
,
typename
Projection
>
struct
pmatch_each_helper
{
pmatch_each_helper
(
pmatch_each_helper
const
&
)
=
delete
;
pmatch_each_helper
&
operator
=
(
pmatch_each_helper
const
&
)
=
delete
;
Iterator
i
;
Iterator
e
;
Projection
p
;
pmatch_each_helper
(
pmatch_each_helper
&&
)
=
default
;
template
<
typename
PJ
>
pmatch_each_helper
(
Iterator
first
,
Iterator
last
,
PJ
&&
proj
)
:
i
(
first
),
e
(
last
),
p
(
std
::
forward
<
PJ
>
(
proj
))
{
}
pmatch_each_helper
(
Iterator
first
,
Iterator
last
,
PJ
&&
proj
)
:
i
(
first
),
e
(
last
),
p
(
std
::
forward
<
PJ
>
(
proj
))
{
}
template
<
typename
...
Args
>
void
operator
()(
partial_function
&&
arg0
,
Args
&&
...
args
)
{
...
...
@@ -91,6 +103,11 @@ struct pmatch_each_helper
namespace
cppa
{
//inline detail::match_helper match(any_tuple t)
//{
// return std::move(t);
//}
/**
* @brief Match expression.
*/
...
...
cppa/partial_function.hpp
View file @
704aa400
...
...
@@ -65,11 +65,11 @@ class partial_function
bool
defined_at
(
any_tuple
const
&
value
);
void
operator
()(
any_tuple
const
&
value
);
void
operator
()(
any_tuple
value
);
detail
::
invokable
const
*
definition_at
(
any_tuple
const
&
value
);
detail
::
invokable
const
*
definition_at
(
any_tuple
value
);
detail
::
intermediate
*
get_intermediate
(
any_tuple
const
&
value
);
detail
::
intermediate
*
get_intermediate
(
any_tuple
value
);
template
<
class
...
Args
>
partial_function
&
splice
(
partial_function
&&
arg0
,
Args
&&
...
args
)
...
...
cppa/to_string.hpp
View file @
704aa400
...
...
@@ -43,7 +43,7 @@ std::string to_string_impl(void const* what, uniform_type_info const* utype);
}
// namespace detail
/**
* @brief Serializes a value to a string.
* @brief Serializes a value to a string
representation
.
* @param what A value of an announced type.
* @returns A string representation of @p what.
*/
...
...
cppa/tuple.hpp
View file @
704aa400
...
...
@@ -121,19 +121,19 @@ class tuple
inline
static
tuple
from
(
cow_ptr_type
ptr
)
{
return
{
priv_ctor
()
,
std
::
move
(
ptr
)};
return
{
priv_ctor
{}
,
std
::
move
(
ptr
)};
}
inline
static
tuple
from
(
cow_ptr_type
ptr
,
util
::
fixed_vector
<
size_t
,
num_elements
>
const
&
mv
)
{
return
{
priv_ctor
()
,
decorated_type
::
create
(
std
::
move
(
ptr
),
mv
)};
return
{
priv_ctor
{}
,
decorated_type
::
create
(
std
::
move
(
ptr
),
mv
)};
}
inline
static
tuple
offset_subtuple
(
cow_ptr_type
ptr
,
size_t
offset
)
{
CPPA_REQUIRE
(
offset
>
0
);
return
{
priv_ctor
()
,
decorated_type
::
create
(
std
::
move
(
ptr
),
offset
)};
return
{
priv_ctor
{}
,
decorated_type
::
create
(
std
::
move
(
ptr
),
offset
)};
}
/**
...
...
cppa/tuple_cast.hpp
View file @
704aa400
...
...
@@ -42,10 +42,11 @@
namespace
cppa
{
/**
* @brief Tries to cast @p tup to {@link tuple tuple<T...>}.
* @brief Tries to cast @p tup to {@link tuple tuple<T...>}; moves content
* of @p tup on success.
*/
template
<
typename
...
T
>
auto
tuple_cast
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
auto
moving_tuple_cast
(
any_tuple
&
tup
,
pattern
<
T
...
>
const
&
p
)
->
option
<
typename
tuple_from_type_list
<
typename
pattern
<
T
...
>::
filtered_types
...
...
@@ -59,28 +60,70 @@ auto tuple_cast(any_tuple const& tup, pattern<T...> const& p)
}
/**
* @brief Tries to cast @p tup to {@link tuple tuple<T...>}.
* @brief Tries to cast @p tup to {@link tuple tuple<T...>}; moves content
* of @p tup on success.
*/
template
<
typename
...
T
>
auto
tuple_cast
(
any_tuple
const
&
tup
)
auto
moving_tuple_cast
(
any_tuple
&
tup
)
->
option
<
typename
tuple_from_type_list
<
typename
util
::
tl_filter_not
<
util
::
type_list
<
T
...
>
,
is_anything
>::
type
>::
type
>
{
typedef
decltype
(
tuple_cast
<
T
...
>
(
tup
))
result_type
;
typedef
decltype
(
moving_
tuple_cast
<
T
...
>
(
tup
))
result_type
;
typedef
typename
result_type
::
value_type
tuple_type
;
static
constexpr
auto
impl
=
get_wildcard_position
<
util
::
type_list
<
T
...
>>
();
return
detail
::
tuple_cast_impl
<
impl
,
tuple_type
,
T
...
>::
safe
(
tup
);
}
template
<
typename
...
T
>
auto
moving_tuple_cast
(
any_tuple
&
tup
,
util
::
type_list
<
T
...
>
const
&
)
->
decltype
(
moving_tuple_cast
<
T
...
>
(
tup
))
{
return
moving_tuple_cast
<
T
...
>
(
tup
);
}
/**
* @brief Tries to cast @p tup to {@link tuple tuple<T...>}.
*/
template
<
typename
...
T
>
auto
tuple_cast
(
any_tuple
tup
,
pattern
<
T
...
>
const
&
p
)
->
option
<
typename
tuple_from_type_list
<
typename
pattern
<
T
...
>::
filtered_types
>::
type
>
{
return
moving_tuple_cast
(
tup
,
p
);
}
/**
* @brief Tries to cast @p tup to {@link tuple tuple<T...>}.
*/
template
<
typename
...
T
>
auto
tuple_cast
(
any_tuple
tup
)
->
option
<
typename
tuple_from_type_list
<
typename
util
::
tl_filter_not
<
util
::
type_list
<
T
...
>
,
is_anything
>::
type
>::
type
>
{
return
moving_tuple_cast
<
T
...
>
(
tup
);
}
template
<
typename
...
T
>
auto
tuple_cast
(
any_tuple
tup
,
util
::
type_list
<
T
...
>
const
&
)
->
decltype
(
tuple_cast
<
T
...
>
(
tup
))
{
return
moving_tuple_cast
<
T
...
>
(
tup
);
}
/////////////////////////// for in-library use only! ///////////////////////////
// cast using a pattern; does not perform type checking
//
(moving)
cast using a pattern; does not perform type checking
template
<
typename
...
T
>
auto
unsafe_tuple_cast
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
auto
unsafe_tuple_cast
(
any_tuple
&
tup
,
pattern
<
T
...
>
const
&
p
)
->
option
<
typename
tuple_from_type_list
<
typename
pattern
<
T
...
>::
filtered_types
...
...
@@ -93,9 +136,16 @@ auto unsafe_tuple_cast(any_tuple const& tup, pattern<T...> const& p)
return
detail
::
tuple_cast_impl
<
impl
,
tuple_type
,
T
...
>::
unsafe
(
tup
,
p
);
}
template
<
typename
...
T
>
auto
unsafe_tuple_cast
(
any_tuple
&
tup
,
util
::
type_list
<
T
...
>
const
&
)
->
decltype
(
tuple_cast
<
T
...
>
(
tup
))
{
return
tuple_cast
<
T
...
>
(
tup
);
}
// cast using a pattern; does neither perform type checking nor checks values
template
<
typename
...
T
>
auto
forced_tuple_cast
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
auto
forced_tuple_cast
(
any_tuple
&
tup
,
pattern
<
T
...
>
const
&
p
)
->
typename
tuple_from_type_list
<
typename
pattern
<
T
...
>::
filtered_types
>::
type
...
...
examples/announce_example_4.cpp
View file @
704aa400
...
...
@@ -118,7 +118,7 @@ int main(int, char**)
int
i
=
0
;
receive_while
([
&
]()
{
return
++
i
<=
2
;
})
(
on
<
bar
>
()
>>
[](
const
bar
&
val
)
on
<
bar
>
()
>>
[](
bar
const
&
val
)
{
cout
<<
"bar(foo("
<<
val
.
f
.
a
()
<<
","
...
...
@@ -126,12 +126,11 @@ int main(int, char**)
<<
val
.
i
<<
")"
<<
endl
;
},
on
<
baz
>
()
>>
[]()
on
<
baz
>
()
>>
[](
baz
const
&
val
)
{
// prints:
@<> ( { baz ( foo ( 1, 2 ), bar ( foo ( 3, 4 ), 5 ) ) }
)
cout
<<
to_string
(
self
->
last_dequeued
()
)
<<
endl
;
// prints:
baz ( foo ( 1, 2 ), bar ( foo ( 3, 4 ), 5 )
)
cout
<<
to_string
(
val
)
<<
endl
;
}
);
return
0
;
}
...
...
src/abstract_tuple.cpp
View file @
704aa400
...
...
@@ -39,6 +39,15 @@ bool abstract_tuple::equals(const abstract_tuple &other) const
&&
std
::
equal
(
begin
(),
end
(),
other
.
begin
(),
detail
::
full_eq_v3
));
}
abstract_tuple
::
abstract_tuple
(
abstract_tuple
const
&
)
:
ref_counted
()
{
}
abstract_tuple
::
abstract_tuple
(
abstract_tuple
const
&
other
)
:
ref_counted
()
,
m_impl_type
(
other
.
m_impl_type
)
{
}
std
::
type_info
const
*
abstract_tuple
::
type_token
()
const
{
return
&
typeid
(
void
);
}
}
}
// namespace cppa::detail
src/any_tuple.cpp
View file @
704aa400
...
...
@@ -34,51 +34,6 @@
namespace
{
/*
struct offset_decorator : cppa::detail::abstract_tuple
{
typedef cppa::cow_ptr<cppa::detail::abstract_tuple> ptr_type;
offset_decorator(ptr_type const& decorated, size_t offset)
: m_offset(offset)
, m_decorated(decorated)
{
}
void* mutable_at(size_t pos)
{
return m_decorated->mutable_at(pos + m_offset);
}
size_t size() const
{
return m_decorated->size() - m_offset;
}
abstract_tuple* copy() const
{
return new offset_decorator(m_decorated, m_offset);
}
const void* at(size_t pos) const
{
return m_decorated->at(pos + m_offset);
}
const cppa::uniform_type_info* type_at(size_t pos) const
{
return m_decorated->type_at(pos + m_offset);
}
private:
size_t m_offset;
ptr_type m_decorated;
};
*/
inline
cppa
::
detail
::
empty_tuple
*
s_empty_tuple
()
{
return
cppa
::
detail
::
singleton_manager
::
get_empty_tuple
();
...
...
@@ -131,11 +86,6 @@ const uniform_type_info* any_tuple::type_at(size_t p) const
return
m_vals
->
type_at
(
p
);
}
const
cow_ptr
<
detail
::
abstract_tuple
>&
any_tuple
::
vals
()
const
{
return
m_vals
;
}
bool
any_tuple
::
equals
(
any_tuple
const
&
other
)
const
{
return
m_vals
->
equals
(
*
other
.
vals
());
...
...
src/empty_tuple.cpp
View file @
704aa400
...
...
@@ -33,6 +33,10 @@
namespace
cppa
{
namespace
detail
{
empty_tuple
::
empty_tuple
()
:
abstract_tuple
(
tuple_impl_info
::
statically_typed
)
{
}
size_t
empty_tuple
::
size
()
const
{
return
0
;
...
...
@@ -63,14 +67,9 @@ bool empty_tuple::equals(const abstract_tuple& other) const
return
other
.
size
()
==
0
;
}
void
const
*
empty_tuple
::
type_token
()
const
{
return
&
typeid
(
empty_tuple
);
}
std
::
type_info
const
*
empty_tuple
::
impl_type
()
const
std
::
type_info
const
*
empty_tuple
::
type_token
()
const
{
return
&
typeid
(
empty_tuple
);
return
&
typeid
(
util
::
type_list
<>
);
}
}
}
// namespace cppa::detail
src/invokable.cpp
View file @
704aa400
...
...
@@ -36,16 +36,16 @@ invokable::~invokable()
{
}
bool
invokable
::
invoke
(
any_tuple
const
&
)
const
{
return
false
;
}
bool
invokable
::
invoke
(
any_tuple
&
)
const
{
return
false
;
}
bool
invokable
::
unsafe_invoke
(
any_tuple
const
&
)
const
{
return
false
;
}
bool
invokable
::
unsafe_invoke
(
any_tuple
&
)
const
{
return
false
;
}
bool
invokable
::
types_match
(
any_tuple
const
&
)
const
{
return
false
;
}
bool
invokable
::
could_invoke
(
any_tuple
const
&
)
const
{
return
false
;
}
intermediate
*
invokable
::
get_intermediate
(
any_tuple
const
&
)
{
return
0
;
}
intermediate
*
invokable
::
get_intermediate
(
any_tuple
&
)
{
return
0
;
}
intermediate
*
invokable
::
get_unsafe_intermediate
(
any_tuple
const
&
)
{
return
0
;
}
intermediate
*
invokable
::
get_unsafe_intermediate
(
any_tuple
&
)
{
return
0
;
}
}
}
// namespace cppa::detail
src/object_array.cpp
View file @
704aa400
...
...
@@ -32,6 +32,10 @@
namespace
cppa
{
namespace
detail
{
object_array
::
object_array
()
:
super
(
tuple_impl_info
::
dynamically_typed
)
{
}
void
object_array
::
push_back
(
object
const
&
what
)
{
m_elements
.
push_back
(
what
);
...
...
@@ -67,14 +71,4 @@ uniform_type_info const* object_array::type_at(size_t pos) const
return
m_elements
[
pos
].
type
();
}
void
const
*
object_array
::
type_token
()
const
{
return
&
typeid
(
object_array
);
}
std
::
type_info
const
*
object_array
::
impl_type
()
const
{
return
&
typeid
(
object_array
);
}
}
}
// namespace cppa::detail
src/partial_function.cpp
View file @
704aa400
...
...
@@ -28,6 +28,8 @@
\******************************************************************************/
#include "cppa/to_string.hpp"
#include "cppa/config.hpp"
#include "cppa/behavior.hpp"
#include "cppa/partial_function.hpp"
...
...
@@ -66,12 +68,24 @@ auto partial_function::get_cache_entry(any_tuple const& value) -> cache_entry&
// if we didn't found a cache entry ...
if
(
i
==
end
||
i
->
first
!=
m_dummy
.
first
)
{
// ... create one
(store all invokables with matching types)
// ... create one
cache_entry
tmp
;
if
(
value
.
impl_type
()
==
detail
::
tuple_impl_info
::
statically_typed
)
{
// use static type information for optimal caching
for
(
auto
f
=
m_funs
.
begin
();
f
!=
m_funs
.
end
();
++
f
)
{
if
(
f
->
types_match
(
value
))
tmp
.
push_back
(
f
.
ptr
());
}
}
else
{
// "dummy" cache entry with all functions (dynamically typed tuple)
for
(
auto
f
=
m_funs
.
begin
();
f
!=
m_funs
.
end
();
++
f
)
{
tmp
.
push_back
(
f
.
ptr
());
}
}
// m_cache is always sorted,
// due to emplace(upper_bound, ...) insertions
i
=
m_cache
.
emplace
(
i
,
std
::
move
(
m_dummy
.
first
),
std
::
move
(
tmp
));
...
...
@@ -79,20 +93,31 @@ auto partial_function::get_cache_entry(any_tuple const& value) -> cache_entry&
return
i
->
second
;
}
void
partial_function
::
operator
()(
any_tuple
const
&
value
)
void
partial_function
::
operator
()(
any_tuple
value
)
{
using
detail
::
invokable
;
auto
&
v
=
get_cache_entry
(
value
);
(
void
)
std
::
any_of
(
v
.
begin
(),
v
.
end
(),
[
&
](
detail
::
invokable
*
i
)
{
return
i
->
unsafe_invoke
(
value
);
});
if
(
value
.
impl_type
()
==
detail
::
tuple_impl_info
::
statically_typed
)
{
std
::
any_of
(
v
.
begin
(),
v
.
end
(),
[
&
](
invokable
*
i
)
{
return
i
->
unsafe_invoke
(
value
);
});
}
else
{
std
::
any_of
(
v
.
begin
(),
v
.
end
(),
[
&
](
invokable
*
i
)
{
return
i
->
invoke
(
value
);
});
}
}
detail
::
invokable
const
*
partial_function
::
definition_at
(
any_tuple
const
&
value
)
detail
::
invokable
const
*
partial_function
::
definition_at
(
any_tuple
value
)
{
using
detail
::
invokable
;
auto
&
v
=
get_cache_entry
(
value
);
auto
i
=
std
::
find_if
(
v
.
begin
(),
v
.
end
(),
[
&
](
detail
::
invokable
*
i
)
{
return
i
->
could_invoke
(
value
);
});
auto
i
=
(
value
.
impl_type
()
==
detail
::
tuple_impl_info
::
statically_typed
)
?
std
::
find_if
(
v
.
begin
(),
v
.
end
(),
[
&
](
invokable
*
i
)
{
return
i
->
could_invoke
(
value
);})
:
std
::
find_if
(
v
.
begin
(),
v
.
end
(),
[
&
](
invokable
*
i
)
{
return
i
->
invoke
(
value
);
});
return
(
i
!=
v
.
end
())
?
*
i
:
nullptr
;
}
...
...
@@ -101,15 +126,20 @@ 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
*
partial_function
::
get_intermediate
(
any_tuple
value
)
{
detail
::
intermediate
*
result
=
nullptr
;
for
(
auto
&
i
:
get_cache_entry
(
value
)
)
if
(
value
.
impl_type
()
==
detail
::
tuple_impl_info
::
statically_typed
)
{
for
(
auto
&
i
:
get_cache_entry
(
value
))
if
((
result
=
i
->
get_unsafe_intermediate
(
value
))
!=
nullptr
)
{
return
result
;
}
else
{
for
(
auto
&
i
:
get_cache_entry
(
value
))
if
((
result
=
i
->
get_intermediate
(
value
))
!=
nullptr
)
return
result
;
}
return
nullptr
;
}
...
...
unit_testing/main.cpp
View file @
704aa400
...
...
@@ -65,6 +65,15 @@ using std::endl;
using
namespace
cppa
;
std
::
vector
<
std
::
string
>
split
(
std
::
string
const
&
str
,
char
delim
)
{
std
::
vector
<
std
::
string
>
result
;
std
::
stringstream
strs
{
str
};
std
::
string
tmp
;
while
(
std
::
getline
(
strs
,
tmp
,
delim
))
result
.
push_back
(
tmp
);
return
result
;
}
void
print_node_id
()
{
auto
pinfo
=
cppa
::
process_information
::
get
();
...
...
@@ -78,15 +87,6 @@ void print_node_id()
<<
endl
;
}
std
::
vector
<
std
::
string
>
split
(
std
::
string
const
&
str
,
char
delim
)
{
std
::
vector
<
std
::
string
>
result
;
std
::
stringstream
strs
{
str
};
std
::
string
tmp
;
while
(
std
::
getline
(
strs
,
tmp
,
delim
))
result
.
push_back
(
tmp
);
return
result
;
}
std
::
vector
<
string_pair
>
get_kv_pairs
(
int
argc
,
char
**
argv
,
int
begin
=
1
)
{
std
::
vector
<
string_pair
>
result
;
...
...
@@ -121,16 +121,6 @@ void usage(char const* argv0)
int
main
(
int
argc
,
char
**
argv
)
{
/*
std::string abc = "abc";
cout << "is_iterable<string> = " << cppa::util::is_iterable<std::string>::value << endl;
match(abc)
(
on("abc") >> []()
{
cout << "ABC" << endl;
}
);
match_each(argv + 1, argv + argc)
(
on_arg_match >> [](std::string const& str)
...
...
@@ -145,11 +135,15 @@ int main(int argc, char** argv)
{
cout << "key = \"" << key << "\", value = \"" << value << "\""
<< endl;
},
others() >> [](any_tuple const& oops)
{
cout << "not a key value pair: " << to_string(oops) << endl;
}
);
return 0;
*/
//
*/
auto
args
=
get_kv_pairs
(
argc
,
argv
);
match_each
(
args
)
...
...
unit_testing/test.hpp
View file @
704aa400
...
...
@@ -4,6 +4,7 @@
#include <vector>
#include <string>
#include <cstddef>
#include <sstream>
#include <iostream>
#include <type_traits>
...
...
@@ -110,6 +111,8 @@ size_t test__intrusive_containers();
void
test__queue_performance
();
std
::
vector
<
std
::
string
>
split
(
std
::
string
const
&
str
,
char
delim
);
using
std
::
cout
;
using
std
::
endl
;
using
std
::
cerr
;
...
...
unit_testing/test__match.cpp
View file @
704aa400
#include <functional>
#include "test.hpp"
#include "cppa/on.hpp"
#include "cppa/match.hpp"
#include "cppa/announce.hpp"
#include "cppa/to_string.hpp"
using
namespace
cppa
;
using
std
::
vector
;
using
std
::
string
;
size_t
test__match
()
{
CPPA_TEST
(
test__match
);
bool
invoked
=
false
;
match
(
"abc"
)
(
on
(
"abc"
)
>>
[
&
]()
{
invoked
=
true
;
}
);
if
(
!
invoked
)
{
CPPA_ERROR
(
"match(
\"
abc
\"
) failed"
);
}
invoked
=
false
;
vector
<
string
>
vec
{
"a"
,
"b"
,
"c"
};
match
(
vec
)
(
on
(
"a"
,
"b"
,
arg_match
)
>>
[
&
](
string
&
str
)
{
invoked
=
true
;
str
=
"C"
;
}
);
if
(
!
invoked
)
{
CPPA_ERROR
(
"match({
\"
a
\"
,
\"
b
\"
,
\"
c
\"
}) failed"
);
}
CPPA_CHECK_EQUAL
(
"C"
,
vec
.
back
());
invoked
=
false
;
match_each
(
vec
)
(
on
(
"a"
)
>>
[
&
](
string
&
str
)
{
invoked
=
true
;
str
=
"A"
;
}
);
if
(
!
invoked
)
{
CPPA_ERROR
(
"match_each({
\"
a
\"
,
\"
b
\"
,
\"
C
\"
}) failed"
);
}
CPPA_CHECK_EQUAL
(
"A"
,
vec
.
front
());
invoked
=
false
;
match
(
vec
)
(
others
()
>>
[
&
](
any_tuple
&
tup
)
{
if
(
detail
::
matches
<
string
,
string
,
string
>
(
tup
))
{
tup
.
get_as_mutable
<
string
>
(
1
)
=
"B"
;
}
else
{
CPPA_ERROR
(
"matches<string, string, string>(tup) == false"
);
}
invoked
=
true
;
}
);
if
(
!
invoked
)
{
CPPA_ERROR
(
"match({
\"
a
\"
,
\"
b
\"
,
\"
c
\"
}) failed"
);
}
CPPA_CHECK_EQUAL
(
vec
[
1
],
"B"
);
invoked
=
false
;
vector
<
string
>
vec2
{
"a=0"
,
"b=1"
,
"c=2"
};
auto
c2
=
split
(
vec2
.
back
(),
'='
);
match
(
c2
)
(
on
(
"c"
,
"2"
)
>>
[
&
]()
{
invoked
=
true
;
}
);
CPPA_CHECK_EQUAL
(
true
,
invoked
);
invoked
=
false
;
int
pmatches
=
0
;
using
std
::
placeholders
::
_1
;
pmatch_each
(
vec2
.
begin
(),
vec2
.
end
(),
std
::
bind
(
split
,
_1
,
'='
))
(
on
(
"a"
,
arg_match
)
>>
[
&
](
string
const
&
value
)
{
CPPA_CHECK_EQUAL
(
"0"
,
value
);
CPPA_CHECK_EQUAL
(
0
,
pmatches
);
++
pmatches
;
},
on
(
"b"
,
arg_match
)
>>
[
&
](
string
const
&
value
)
{
CPPA_CHECK_EQUAL
(
"1"
,
value
);
CPPA_CHECK_EQUAL
(
1
,
pmatches
);
++
pmatches
;
},
on
(
"c"
,
arg_match
)
>>
[
&
](
string
const
&
value
)
{
CPPA_CHECK_EQUAL
(
"2"
,
value
);
CPPA_CHECK_EQUAL
(
2
,
pmatches
);
++
pmatches
;
},
others
()
>>
[](
any_tuple
const
&
value
)
{
cout
<<
to_string
(
value
)
<<
endl
;
}
);
CPPA_CHECK_EQUAL
(
3
,
pmatches
);
return
CPPA_TEST_RESULT
;
}
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