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
58318857
Commit
58318857
authored
Apr 03, 2012
by
neverlord
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
match() and match_each()
parent
a7c57cea
Changes
24
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
1080 additions
and
620 deletions
+1080
-620
Makefile.am
Makefile.am
+3
-2
cppa.files
cppa.files
+4
-2
cppa/any_tuple.hpp
cppa/any_tuple.hpp
+89
-0
cppa/detail/container_tuple_view.hpp
cppa/detail/container_tuple_view.hpp
+105
-0
cppa/detail/invokable.hpp
cppa/detail/invokable.hpp
+6
-6
cppa/detail/matches.hpp
cppa/detail/matches.hpp
+494
-0
cppa/detail/tdata.hpp
cppa/detail/tdata.hpp
+14
-2
cppa/detail/tuple_cast_impl.hpp
cppa/detail/tuple_cast_impl.hpp
+24
-37
cppa/detail/tuple_vals.hpp
cppa/detail/tuple_vals.hpp
+14
-6
cppa/detail/tuple_view.hpp
cppa/detail/tuple_view.hpp
+138
-0
cppa/get.hpp
cppa/get.hpp
+0
-11
cppa/match.hpp
cppa/match.hpp
+64
-460
cppa/pattern.hpp
cppa/pattern.hpp
+0
-2
cppa/tuple_cast.hpp
cppa/tuple_cast.hpp
+7
-3
cppa/type_value_pair.hpp
cppa/type_value_pair.hpp
+6
-0
cppa/uniform_type_info.hpp
cppa/uniform_type_info.hpp
+21
-0
cppa/util/is_iterable.hpp
cppa/util/is_iterable.hpp
+1
-1
cppa/util/static_foreach.hpp
cppa/util/static_foreach.hpp
+2
-0
src/converted_thread_context.cpp
src/converted_thread_context.cpp
+2
-2
unit_testing/Makefile.am
unit_testing/Makefile.am
+1
-0
unit_testing/main.cpp
unit_testing/main.cpp
+67
-80
unit_testing/test.hpp
unit_testing/test.hpp
+6
-3
unit_testing/test__match.cpp
unit_testing/test__match.cpp
+8
-0
unit_testing/test__remote_actor.cpp
unit_testing/test__remote_actor.cpp
+4
-3
No files found.
Makefile.am
View file @
58318857
...
@@ -74,7 +74,6 @@ nobase_library_include_HEADERS = \
...
@@ -74,7 +74,6 @@ nobase_library_include_HEADERS = \
cppa/actor_proxy.hpp
\
cppa/actor_proxy.hpp
\
cppa/announce.hpp
\
cppa/announce.hpp
\
cppa/any_tuple.hpp
\
cppa/any_tuple.hpp
\
cppa/any_tuple_view.hpp
\
cppa/anything.hpp
\
cppa/anything.hpp
\
cppa/atom.hpp
\
cppa/atom.hpp
\
cppa/attachable.hpp
\
cppa/attachable.hpp
\
...
@@ -96,6 +95,7 @@ nobase_library_include_HEADERS = \
...
@@ -96,6 +95,7 @@ nobase_library_include_HEADERS = \
cppa/detail/boxed.hpp
\
cppa/detail/boxed.hpp
\
cppa/detail/buffer.hpp
\
cppa/detail/buffer.hpp
\
cppa/detail/channel.hpp
\
cppa/detail/channel.hpp
\
cppa/detail/container_tuple_view.hpp
\
cppa/detail/converted_thread_context.hpp
\
cppa/detail/converted_thread_context.hpp
\
cppa/detail/decorated_tuple.hpp
\
cppa/detail/decorated_tuple.hpp
\
cppa/detail/default_uniform_type_info_impl.hpp
\
cppa/detail/default_uniform_type_info_impl.hpp
\
...
@@ -111,6 +111,7 @@ nobase_library_include_HEADERS = \
...
@@ -111,6 +111,7 @@ nobase_library_include_HEADERS = \
cppa/detail/list_member.hpp
\
cppa/detail/list_member.hpp
\
cppa/detail/mailman.hpp
\
cppa/detail/mailman.hpp
\
cppa/detail/map_member.hpp
\
cppa/detail/map_member.hpp
\
cppa/detail/matches.hpp
\
cppa/detail/mock_scheduler.hpp
\
cppa/detail/mock_scheduler.hpp
\
cppa/detail/native_socket.hpp
\
cppa/detail/native_socket.hpp
\
cppa/detail/network_manager.hpp
\
cppa/detail/network_manager.hpp
\
...
@@ -132,6 +133,7 @@ nobase_library_include_HEADERS = \
...
@@ -132,6 +133,7 @@ nobase_library_include_HEADERS = \
cppa/detail/to_uniform_name.hpp
\
cppa/detail/to_uniform_name.hpp
\
cppa/detail/tuple_cast_impl.hpp
\
cppa/detail/tuple_cast_impl.hpp
\
cppa/detail/tuple_vals.hpp
\
cppa/detail/tuple_vals.hpp
\
cppa/detail/tuple_view.hpp
\
cppa/detail/type_to_ptype.hpp
\
cppa/detail/type_to_ptype.hpp
\
cppa/detail/types_array.hpp
\
cppa/detail/types_array.hpp
\
cppa/detail/unboxed.hpp
\
cppa/detail/unboxed.hpp
\
...
@@ -172,7 +174,6 @@ nobase_library_include_HEADERS = \
...
@@ -172,7 +174,6 @@ nobase_library_include_HEADERS = \
cppa/to_string.hpp
\
cppa/to_string.hpp
\
cppa/tuple.hpp
\
cppa/tuple.hpp
\
cppa/tuple_cast.hpp
\
cppa/tuple_cast.hpp
\
cppa/tuple_view.hpp
\
cppa/type_value_pair.hpp
\
cppa/type_value_pair.hpp
\
cppa/uniform_type_info.hpp
\
cppa/uniform_type_info.hpp
\
cppa/util/abstract_uniform_type_info.hpp
\
cppa/util/abstract_uniform_type_info.hpp
\
...
...
cppa.files
View file @
58318857
...
@@ -11,7 +11,6 @@ src/uniform_type_info.cpp
...
@@ -11,7 +11,6 @@ src/uniform_type_info.cpp
cppa/config.hpp
cppa/config.hpp
unit_testing/test__tuple.cpp
unit_testing/test__tuple.cpp
cppa/detail/abstract_tuple.hpp
cppa/detail/abstract_tuple.hpp
cppa/tuple_view.hpp
cppa/detail/tuple_vals.hpp
cppa/detail/tuple_vals.hpp
cppa/detail/decorated_tuple.hpp
cppa/detail/decorated_tuple.hpp
cppa/cow_ptr.hpp
cppa/cow_ptr.hpp
...
@@ -234,7 +233,6 @@ cppa/tuple_cast.hpp
...
@@ -234,7 +233,6 @@ cppa/tuple_cast.hpp
cppa/util/is_mutable_ref.hpp
cppa/util/is_mutable_ref.hpp
cppa/util/is_manipulator.hpp
cppa/util/is_manipulator.hpp
cppa/util/apply_tuple.hpp
cppa/util/apply_tuple.hpp
cppa/any_tuple_view.hpp
benchmarks/Matching.scala
benchmarks/Matching.scala
benchmarks/matching.cpp
benchmarks/matching.cpp
benchmarks/matching.erl
benchmarks/matching.erl
...
@@ -256,3 +254,7 @@ cppa/intrusive/forward_iterator.hpp
...
@@ -256,3 +254,7 @@ cppa/intrusive/forward_iterator.hpp
unit_testing/test__intrusive_containers.cpp
unit_testing/test__intrusive_containers.cpp
examples/dancing_kirby.cpp
examples/dancing_kirby.cpp
cppa/util/is_comparable.hpp
cppa/util/is_comparable.hpp
cppa/detail/tuple_view.hpp
cppa/detail/container_tuple_view.hpp
cppa/detail/matches.hpp
unit_testing/test__match.cpp
cppa/any_tuple.hpp
View file @
58318857
...
@@ -34,7 +34,16 @@
...
@@ -34,7 +34,16 @@
#include "cppa/tuple.hpp"
#include "cppa/tuple.hpp"
#include "cppa/config.hpp"
#include "cppa/config.hpp"
#include "cppa/cow_ptr.hpp"
#include "cppa/cow_ptr.hpp"
#include "cppa/util/rm_ref.hpp"
#include "cppa/util/enable_if.hpp"
#include "cppa/util/disable_if.hpp"
#include "cppa/util/is_iterable.hpp"
#include "cppa/detail/tuple_view.hpp"
#include "cppa/detail/abstract_tuple.hpp"
#include "cppa/detail/abstract_tuple.hpp"
#include "cppa/detail/container_tuple_view.hpp"
#include "cppa/detail/implicit_conversions.hpp"
namespace
cppa
{
namespace
cppa
{
...
@@ -149,19 +158,99 @@ class any_tuple
...
@@ -149,19 +158,99 @@ class any_tuple
return
m_vals
->
impl_type
();
return
m_vals
->
impl_type
();
}
}
template
<
typename
T
>
static
inline
any_tuple
view
(
T
&&
value
,
typename
util
::
enable_if
<
util
::
is_iterable
<
typename
util
::
rm_ref
<
T
>::
type
>
>::
type
*
=
0
)
{
static
constexpr
bool
can_optimize
=
std
::
is_reference
<
T
>::
value
&&
!
std
::
is_const
<
T
>::
value
;
std
::
integral_constant
<
bool
,
can_optimize
>
token
;
return
any_tuple
{
container_view
(
std
::
forward
<
T
>
(
value
),
token
)};
}
template
<
typename
T
>
static
inline
any_tuple
view
(
T
&&
value
,
typename
util
::
disable_if
<
util
::
is_iterable
<
typename
util
::
rm_ref
<
T
>::
type
>
>::
type
*
=
0
)
{
typedef
typename
util
::
rm_ref
<
T
>::
type
vtype
;
typedef
typename
detail
::
implicit_conversions
<
vtype
>::
type
converted
;
static_assert
(
util
::
is_legal_tuple_type
<
converted
>::
value
,
"T is not a valid tuple type"
);
static
constexpr
bool
can_optimize
=
std
::
is_same
<
converted
,
vtype
>::
value
&&
std
::
is_reference
<
T
>::
value
&&
!
std
::
is_const
<
T
>::
value
;
std
::
integral_constant
<
bool
,
can_optimize
>
token
;
return
any_tuple
{
simple_view
(
std
::
forward
<
T
>
(
value
),
token
)};
}
private:
private:
cow_ptr
<
detail
::
abstract_tuple
>
m_vals
;
cow_ptr
<
detail
::
abstract_tuple
>
m_vals
;
explicit
any_tuple
(
cow_ptr
<
detail
::
abstract_tuple
>
const
&
vals
);
explicit
any_tuple
(
cow_ptr
<
detail
::
abstract_tuple
>
const
&
vals
);
typedef
detail
::
abstract_tuple
*
tup_ptr
;
template
<
typename
T
>
static
inline
tup_ptr
simple_view
(
T
&
value
,
std
::
integral_constant
<
bool
,
true
>
)
{
return
new
detail
::
tuple_view
<
T
>
(
&
value
);
}
template
<
typename
First
,
typename
Second
>
static
inline
tup_ptr
simple_view
(
std
::
pair
<
First
,
Second
>&
p
,
std
::
integral_constant
<
bool
,
true
>
)
{
return
new
detail
::
tuple_view
<
First
,
Second
>
(
&
p
.
first
,
&
p
.
second
);
}
template
<
typename
T
>
static
inline
tup_ptr
simple_view
(
T
&&
value
,
std
::
integral_constant
<
bool
,
false
>
)
{
typedef
typename
util
::
rm_ref
<
T
>::
type
vtype
;
typedef
typename
detail
::
implicit_conversions
<
vtype
>::
type
converted
;
return
new
detail
::
tuple_vals
<
converted
>
(
std
::
forward
<
T
>
(
value
));
}
template
<
typename
First
,
typename
Second
>
static
inline
any_tuple
view
(
std
::
pair
<
First
,
Second
>
p
,
std
::
integral_constant
<
bool
,
false
>
)
{
return
new
detail
::
tuple_vals
<
First
,
Second
>
(
std
::
move
(
p
.
first
),
std
::
move
(
p
.
second
));
}
template
<
typename
T
>
static
inline
detail
::
abstract_tuple
*
container_view
(
T
&
value
,
std
::
integral_constant
<
bool
,
true
>
)
{
return
new
detail
::
container_tuple_view
<
T
>
(
&
value
);
}
template
<
typename
T
>
static
inline
detail
::
abstract_tuple
*
container_view
(
T
&&
value
,
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
)));
}
};
};
/**
* @relates any_tuple
*/
inline
bool
operator
==
(
any_tuple
const
&
lhs
,
any_tuple
const
&
rhs
)
inline
bool
operator
==
(
any_tuple
const
&
lhs
,
any_tuple
const
&
rhs
)
{
{
return
lhs
.
equals
(
rhs
);
return
lhs
.
equals
(
rhs
);
}
}
/**
* @relates any_tuple
*/
inline
bool
operator
!=
(
any_tuple
const
&
lhs
,
any_tuple
const
&
rhs
)
inline
bool
operator
!=
(
any_tuple
const
&
lhs
,
any_tuple
const
&
rhs
)
{
{
return
!
(
lhs
==
rhs
);
return
!
(
lhs
==
rhs
);
...
...
cppa/
any
_tuple_view.hpp
→
cppa/
detail/container
_tuple_view.hpp
View file @
58318857
...
@@ -28,132 +28,78 @@
...
@@ -28,132 +28,78 @@
\******************************************************************************/
\******************************************************************************/
#ifndef
ANY
_TUPLE_VIEW_HPP
#ifndef
CONTAINER
_TUPLE_VIEW_HPP
#define
ANY
_TUPLE_VIEW_HPP
#define
CONTAINER
_TUPLE_VIEW_HPP
#include <set>
#include "cppa/detail/tuple_vals.hpp"
#include <list>
#include <vector>
#include <utility>
#include <iterator>
#include <algorithm>
#include "cppa/tuple.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/tuple_view.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/util/enable_if.hpp"
#include "cppa/util/is_primitive.hpp"
#include "cppa/detail/types_array.hpp"
#include "cppa/detail/object_array.hpp"
#include "cppa/detail/object_array.hpp"
#include "cppa/detail/abstract_tuple.hpp"
#include "cppa/detail/disablable_delete.hpp"
namespace
cppa
{
namespace
cppa
{
namespace
detail
{
class
any_tuple_view
template
<
class
Container
>
class
container_tuple_view
:
public
abstract_tuple
{
{
typedef
std
::
vector
<
type_value_pair
>
vector_type
;
public:
vector_type
m_values
;
typedef
typename
Container
::
value_type
value_type
;
template
<
typename
T
>
container_tuple_view
(
Container
*
c
,
bool
take_ownership
=
false
)
:
m_ptr
(
c
)
void
from_list
(
T
const
&
list
)
{
{
auto
&
arr
=
detail
::
static_types_array
<
typename
T
::
value_type
>::
arr
;
CPPA_REQUIRE
(
c
!=
nullptr
);
for
(
auto
i
=
list
.
begin
();
i
!=
list
.
end
();
++
i
)
if
(
!
take_ownership
)
m_ptr
.
get_deleter
().
disable
();
{
m_values
.
push_back
(
std
::
make_pair
(
arr
[
0
],
&
(
*
i
)));
}
}
}
public:
size_t
size
()
const
class
const_iterator
;
friend
class
const_iterator
;
any_tuple_view
(
any_tuple_view
&&
)
=
default
;
any_tuple_view
(
any_tuple_view
const
&
)
=
default
;
any_tuple_view
&
operator
=
(
any_tuple_view
&&
)
=
default
;
any_tuple_view
&
operator
=
(
any_tuple_view
const
&
)
=
default
;
any_tuple_view
(
any_tuple
&
tup
)
{
{
if
(
tup
.
size
()
>
0
)
return
m_ptr
->
size
();
{
// force tuple to detach
tup
.
mutable_at
(
0
);
std
::
back_insert_iterator
<
vector_type
>
back_iter
{
m_values
};
std
::
copy
(
tup
.
begin
(),
tup
.
end
(),
back_iter
);
}
}
}
template
<
typename
...
T
>
abstract_tuple
*
copy
()
const
any_tuple_view
(
tuple_view
<
T
...
>
const
&
tup
)
{
{
for
(
size_t
i
=
0
;
i
<
tup
.
size
();
++
i
)
return
new
container_tuple_view
{
new
Container
(
*
m_ptr
),
true
};
{
m_values
.
push_back
(
std
::
make_pair
(
tup
.
type_at
(
i
),
tup
.
at
(
i
)));
}
}
}
template
<
typename
F
,
typename
S
>
void
const
*
at
(
size_t
pos
)
const
any_tuple_view
(
std
::
pair
<
F
,
S
>
const
&
pair
)
{
{
auto
&
arr
=
detail
::
static_types_array
<
F
,
S
>::
arr
;
CPPA_REQUIRE
(
pos
<
size
());
m_values
.
push_back
(
std
::
make_pair
(
arr
[
0
],
&
pair
.
first
));
auto
i
=
m_ptr
->
begin
();
m_values
.
push_back
(
std
::
make_pair
(
arr
[
1
],
&
pair
.
second
));
std
::
advance
(
i
,
pos
);
return
&
(
*
i
);
}
}
template
<
typename
T
>
void
*
mutable_at
(
size_t
pos
)
any_tuple_view
(
std
::
set
<
T
>&
vec
)
{
from_list
(
vec
);
}
template
<
typename
T
>
any_tuple_view
(
std
::
list
<
T
>&
vec
)
{
from_list
(
vec
);
}
template
<
typename
T
>
any_tuple_view
(
std
::
vector
<
T
>&
vec
)
{
from_list
(
vec
);
}
template
<
typename
T
>
any_tuple_view
(
T
&
val
,
typename
util
::
enable_if
<
util
::
is_primitive
<
T
>
>::
type
*
=
0
)
{
{
auto
&
arr
=
detail
::
static_types_array
<
T
>::
arr
;
CPPA_REQUIRE
(
pos
<
size
());
m_values
.
push_back
(
std
::
make_pair
(
arr
[
0
],
&
val
));
auto
i
=
m_ptr
->
begin
();
std
::
advance
(
i
,
pos
);
return
&
(
*
i
);
}
}
inline
vector_type
const
&
vals
()
const
{
return
m_values
;
}
uniform_type_info
const
*
type_at
(
size_t
pos
)
const
inline
size_t
size
()
const
{
return
m_values
.
size
();
}
inline
void
const
*
at
(
size_t
p
)
const
{
return
m_values
[
p
].
second
;
}
void
*
mutable_at
(
size_t
p
)
{
return
const_cast
<
void
*>
(
m_values
[
p
].
second
);
}
inline
uniform_type_info
const
*
type_at
(
size_t
p
)
const
{
{
return
m_values
[
p
].
first
;
CPPA_REQUIRE
(
pos
<
size
());
return
static_types_array
<
value_type
>::
arr
[
0
];
}
}
inline
bool
empty
()
const
{
return
m_values
.
empty
();
}
void
const
*
type_token
()
const
template
<
typename
T
>
inline
T
const
&
get_as
(
size_t
p
)
const
{
{
return
*
reinterpret_cast
<
T
const
*>
(
at
(
p
));
return
&
(
typeid
(
Container
));
}
}
inline
std
::
type_info
const
&
impl_type
()
const
std
::
type_info
const
*
impl_type
()
const
{
{
// this is a lie, but the pattern matching implementation
return
&
(
typeid
(
detail
::
object_array
));
// needs to do a full runtime check of each element
return
typeid
(
detail
::
object_array
);
}
}
private:
std
::
unique_ptr
<
Container
,
disablable_delete
<
Container
>
>
m_ptr
;
};
};
}
// namespace cppa
}
}
// namespace cppa::detail
#endif //
ANY
_TUPLE_VIEW_HPP
#endif //
CONTAINER
_TUPLE_VIEW_HPP
cppa/detail/invokable.hpp
View file @
58318857
...
@@ -36,7 +36,6 @@
...
@@ -36,7 +36,6 @@
#include <cstddef>
#include <cstddef>
#include <cstdint>
#include <cstdint>
#include "cppa/match.hpp"
#include "cppa/pattern.hpp"
#include "cppa/pattern.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/tuple_cast.hpp"
#include "cppa/tuple_cast.hpp"
...
@@ -45,6 +44,7 @@
...
@@ -45,6 +44,7 @@
#include "cppa/util/fixed_vector.hpp"
#include "cppa/util/fixed_vector.hpp"
#include "cppa/util/callable_trait.hpp"
#include "cppa/util/callable_trait.hpp"
#include "cppa/detail/matches.hpp"
#include "cppa/detail/intermediate.hpp"
#include "cppa/detail/intermediate.hpp"
// forward declaration
// forward declaration
...
@@ -90,11 +90,11 @@ struct abstract_invokable : public invokable
...
@@ -90,11 +90,11 @@ struct abstract_invokable : public invokable
}
}
bool
types_match
(
any_tuple
const
&
value
)
const
bool
types_match
(
any_tuple
const
&
value
)
const
{
{
return
match_types
(
value
,
m_pattern
);
return
match
es
_types
(
value
,
m_pattern
);
}
}
bool
could_invoke
(
any_tuple
const
&
value
)
const
bool
could_invoke
(
any_tuple
const
&
value
)
const
{
{
return
match
(
value
,
m_pattern
);
return
match
es
(
value
,
m_pattern
);
}
}
};
};
...
@@ -218,9 +218,9 @@ class invokable_impl<true, 0, Fun, Tuple, Pattern> : public abstract_invokable<T
...
@@ -218,9 +218,9 @@ class invokable_impl<true, 0, Fun, Tuple, Pattern> : public abstract_invokable<T
:
super
(
std
::
forward
<
Args
>
(
args
)...),
m_iimpl
(
std
::
forward
<
F
>
(
fun
))
:
super
(
std
::
forward
<
Args
>
(
args
)...),
m_iimpl
(
std
::
forward
<
F
>
(
fun
))
{
{
}
}
bool
invoke
(
any_tuple
const
&
data
)
const
bool
invoke
(
any_tuple
const
&
value
)
const
{
{
return
match
(
data
,
this
->
m_pattern
)
?
m_iimpl
()
:
false
;
return
match
es
(
value
,
this
->
m_pattern
)
?
m_iimpl
()
:
false
;
}
}
bool
unsafe_invoke
(
any_tuple
const
&
value
)
const
bool
unsafe_invoke
(
any_tuple
const
&
value
)
const
{
{
...
@@ -228,7 +228,7 @@ class invokable_impl<true, 0, Fun, Tuple, Pattern> : public abstract_invokable<T
...
@@ -228,7 +228,7 @@ class invokable_impl<true, 0, Fun, Tuple, Pattern> : public abstract_invokable<T
}
}
intermediate
*
get_intermediate
(
any_tuple
const
&
value
)
intermediate
*
get_intermediate
(
any_tuple
const
&
value
)
{
{
return
match
(
value
,
this
->
m_pattern
)
?
&
m_iimpl
:
nullptr
;
return
match
es
(
value
,
this
->
m_pattern
)
?
&
m_iimpl
:
nullptr
;
}
}
intermediate
*
get_unsafe_intermediate
(
any_tuple
const
&
value
)
intermediate
*
get_unsafe_intermediate
(
any_tuple
const
&
value
)
{
{
...
...
cppa/detail/matches.hpp
0 → 100644
View file @
58318857
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef MATCHES_HPP
#define MATCHES_HPP
#include "cppa/pattern.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/util/type_list.hpp"
namespace
cppa
{
namespace
detail
{
template
<
wildcard_position
,
typename
...
>
struct
matcher
;
template
<
typename
...
T
>
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
)
{
return
true
;
}
// always use a full dynamic match for object arrays
else
if
(
*
impl
==
typeid
(
detail
::
object_array
)
&&
tup
.
size
()
==
sizeof
...(
T
))
{
auto
&
tarr
=
detail
::
static_types_array
<
T
...
>::
arr
;
return
std
::
equal
(
tup
.
begin
(),
tup
.
end
(),
tarr
.
begin
(),
detail
::
types_only_eq
);
}
return
false
;
}
static
inline
bool
tmatch
(
any_tuple
const
&
tup
,
util
::
fixed_vector
<
size_t
,
sizeof
...(
T
)
>&
mv
)
{
if
(
tmatch
(
tup
))
{
mv
.
resize
(
sizeof
...(
T
));
std
::
iota
(
mv
.
begin
(),
mv
.
end
(),
0
);
return
true
;
}
return
false
;
}
static
inline
bool
vmatch
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
ptrn
)
{
CPPA_REQUIRE
(
tup
.
size
()
==
sizeof
...(
T
));
return
std
::
equal
(
ptrn
.
begin
(),
ptrn
.
vend
(),
tup
.
begin
(),
detail
::
values_only_eq_v2
);
}
};
template
<
typename
...
T
>
struct
matcher
<
wildcard_position
::
trailing
,
T
...
>
{
static
constexpr
size_t
size
=
sizeof
...(
T
)
-
1
;
static
inline
bool
tmatch
(
any_tuple
const
&
tup
)
{
if
(
tup
.
size
()
>=
size
)
{
auto
&
tarr
=
static_types_array
<
T
...
>::
arr
;
auto
begin
=
tup
.
begin
();
return
std
::
equal
(
begin
,
begin
+
size
,
tarr
.
begin
(),
detail
::
types_only_eq
);
}
return
false
;
}
static
inline
bool
tmatch
(
any_tuple
const
&
tup
,
util
::
fixed_vector
<
size_t
,
size
>&
mv
)
{
if
(
tmatch
(
tup
))
{
mv
.
resize
(
size
);
std
::
iota
(
mv
.
begin
(),
mv
.
end
(),
0
);
return
true
;
}
return
false
;
}
static
inline
bool
vmatch
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
ptrn
)
{
return
std
::
equal
(
ptrn
.
begin
(),
ptrn
.
vend
(),
tup
.
begin
(),
detail
::
values_only_eq_v2
);
}
};
template
<
>
struct
matcher
<
wildcard_position
::
leading
,
anything
>
{
static
inline
bool
tmatch
(
any_tuple
const
&
)
{
return
true
;
}
static
inline
bool
tmatch
(
any_tuple
const
&
,
util
::
fixed_vector
<
size_t
,
0
>&
)
{
return
true
;
}
static
inline
bool
vmatch
(
any_tuple
const
&
,
pattern
<
anything
>
const
&
)
{
return
true
;
}
};
template
<
typename
...
T
>
struct
matcher
<
wildcard_position
::
leading
,
T
...
>
{
static
constexpr
size_t
size
=
sizeof
...(
T
)
-
1
;
static
inline
bool
tmatch
(
any_tuple
const
&
tup
)
{
auto
tup_size
=
tup
.
size
();
if
(
tup_size
>=
size
)
{
auto
&
tarr
=
static_types_array
<
T
...
>::
arr
;
auto
begin
=
tup
.
begin
();
begin
+=
(
tup_size
-
size
);
return
std
::
equal
(
begin
,
tup
.
end
(),
(
tarr
.
begin
()
+
1
),
// skip 'anything'
detail
::
types_only_eq
);
}
return
false
;
}
static
inline
bool
tmatch
(
any_tuple
const
&
tup
,
util
::
fixed_vector
<
size_t
,
size
>&
mv
)
{
if
(
tmatch
(
tup
))
{
mv
.
resize
(
size
);
std
::
iota
(
mv
.
begin
(),
mv
.
end
(),
tup
.
size
()
-
size
);
return
true
;
}
return
false
;
}
static
inline
bool
vmatch
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
ptrn
)
{
auto
tbegin
=
tup
.
begin
();
// skip unmatched elements
tbegin
+=
(
tup
.
size
()
-
size
);
// skip leading wildcard ++(ptr.begin())
return
std
::
equal
(
++
(
ptrn
.
begin
()),
ptrn
.
vend
(),
tbegin
,
detail
::
values_only_eq_v2
);
}
};
template
<
typename
...
T
>
struct
matcher
<
wildcard_position
::
in_between
,
T
...
>
{
static
constexpr
int
signed_wc_pos
=
util
::
tl_find
<
util
::
type_list
<
T
...
>
,
anything
>::
value
;
static
constexpr
size_t
size
=
sizeof
...(
T
);
static
constexpr
size_t
wc_pos
=
static_cast
<
size_t
>
(
signed_wc_pos
);
static_assert
(
signed_wc_pos
!=
-
1
&&
signed_wc_pos
!=
0
&&
signed_wc_pos
!=
(
sizeof
...(
T
)
-
1
),
"illegal wildcard position"
);
static
inline
bool
tmatch
(
any_tuple
const
&
tup
)
{
auto
tup_size
=
tup
.
size
();
if
(
tup_size
>=
size
)
{
auto
&
tarr
=
static_types_array
<
T
...
>::
arr
;
// first range [0, X1)
auto
begin
=
tup
.
begin
();
auto
end
=
begin
+
wc_pos
;
if
(
std
::
equal
(
begin
,
end
,
tarr
.
begin
(),
detail
::
types_only_eq
))
{
// second range [X2, N)
begin
=
end
=
tup
.
end
();
begin
-=
(
size
-
(
wc_pos
+
1
));
auto
arr_begin
=
tarr
.
begin
()
+
(
wc_pos
+
1
);
return
std
::
equal
(
begin
,
end
,
arr_begin
,
detail
::
types_only_eq
);
}
}
return
false
;
}
static
inline
bool
tmatch
(
any_tuple
const
&
tup
,
util
::
fixed_vector
<
size_t
,
size
-
1
>&
mv
)
{
if
(
tmatch
(
tup
))
{
// first range
mv
.
resize
(
size
-
1
);
auto
begin
=
mv
.
begin
();
std
::
iota
(
begin
,
begin
+
wc_pos
,
0
);
// second range
begin
=
mv
.
begin
()
+
wc_pos
;
std
::
iota
(
begin
,
mv
.
end
(),
tup
.
size
()
-
(
size
-
(
wc_pos
+
1
)));
return
true
;
}
return
false
;
}
static
inline
bool
vmatch
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
ptrn
)
{
// first range
auto
tbegin
=
tup
.
begin
();
auto
tend
=
tbegin
+
wc_pos
;
if
(
std
::
equal
(
tbegin
,
tend
,
ptrn
.
begin
(),
detail
::
values_only_eq
))
{
// second range
tbegin
=
tend
=
tup
.
end
();
tbegin
-=
(
size
-
(
wc_pos
+
1
));
auto
pbegin
=
ptrn
.
begin
();
pbegin
+=
(
wc_pos
+
1
);
return
std
::
equal
(
tbegin
,
tend
,
pbegin
,
detail
::
values_only_eq
);
}
return
false
;
}
};
template
<
typename
...
T
>
struct
matcher
<
wildcard_position
::
multiple
,
T
...
>
{
static
constexpr
size_t
wc_count
=
util
::
tl_count
<
util
::
type_list
<
T
...
>
,
is_anything
>::
value
;
static_assert
(
sizeof
...(
T
)
>
wc_count
,
"only wildcards given"
);
template
<
class
TupleIter
,
class
PatternIter
,
class
Push
,
class
Commit
,
class
Rollback
>
static
bool
match
(
TupleIter
tbegin
,
TupleIter
tend
,
PatternIter
pbegin
,
PatternIter
pend
,
Push
&&
push
,
Commit
&&
commit
,
Rollback
&&
rollback
)
{
while
(
!
(
pbegin
==
pend
&&
tbegin
==
tend
))
{
if
(
pbegin
==
pend
)
{
// reached end of pattern while some values remain unmatched
return
false
;
}
else
if
(
pbegin
.
type
()
==
nullptr
)
// nullptr == wildcard (anything)
{
// perform submatching
++
pbegin
;
// always true at the end of the pattern
if
(
pbegin
==
pend
)
return
true
;
// safe current mapping as fallback
commit
();
// iterate over tuple values until we found a match
for
(;
tbegin
!=
tend
;
++
tbegin
)
{
if
(
match
(
tbegin
,
tend
,
pbegin
,
pend
,
push
,
commit
,
rollback
))
{
return
true
;
}
// restore mapping to fallback (delete invalid mappings)
rollback
();
}
return
false
;
// no submatch found
}
// compare types
else
if
(
tbegin
.
type
()
==
pbegin
.
type
())
push
(
tbegin
);
// no match
else
return
false
;
// next iteration
++
tbegin
;
++
pbegin
;
}
return
true
;
// pbegin == pend && tbegin == tend
}
static
inline
bool
tmatch
(
any_tuple
const
&
tup
)
{
auto
&
tarr
=
static_types_array
<
T
...
>::
arr
;
if
(
tup
.
size
()
>=
(
sizeof
...(
T
)
-
wc_count
))
{
return
match
(
tup
.
begin
(),
tup
.
end
(),
tarr
.
begin
(),
tarr
.
end
(),
[](
any_tuple
::
const_iterator
const
&
)
{
},
[]()
{
},
[]()
{
});
}
return
false
;
}
template
<
class
MappingVector
>
static
inline
bool
tmatch
(
any_tuple
const
&
tup
,
MappingVector
&
mv
)
{
auto
&
tarr
=
static_types_array
<
T
...
>::
arr
;
if
(
tup
.
size
()
>=
(
sizeof
...(
T
)
-
wc_count
))
{
size_t
commited_size
=
0
;
return
match
(
tup
.
begin
(),
tup
.
end
(),
tarr
.
begin
(),
tarr
.
end
(),
[
&
](
any_tuple
::
const_iterator
const
&
iter
)
{
mv
.
push_back
(
iter
.
position
());
},
[
&
]()
{
commited_size
=
mv
.
size
();
},
[
&
]()
{
mv
.
resize
(
commited_size
);
});
}
return
false
;
}
static
inline
bool
vmatch
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
ptrn
,
typename
pattern
<
T
...
>::
mapping_vector
const
&
mv
)
{
auto
i
=
mv
.
begin
();
for
(
auto
j
=
ptrn
.
begin
();
j
!=
ptrn
.
end
();
++
j
)
{
if
(
j
.
type
()
!=
nullptr
)
{
if
(
j
.
value
()
!=
nullptr
&&
j
.
type
()
->
equals
(
tup
.
at
(
*
i
),
j
.
value
())
==
false
)
{
return
false
;
}
++
i
;
}
}
}
};
// implementation for zero or one wildcards
template
<
wildcard_position
PC
,
typename
...
Ts
>
struct
match_impl
{
static
inline
bool
_
(
any_tuple
const
&
tup
)
{
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
);
}
template
<
size_t
Size
>
static
inline
bool
_
(
any_tuple
const
&
tup
,
util
::
fixed_vector
<
size_t
,
Size
>&
mv
)
{
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
,
mv
);
}
static
inline
bool
_
(
any_tuple
const
&
tup
,
pattern
<
Ts
...
>
const
&
p
)
{
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
)
&&
(
p
.
has_values
()
==
false
||
detail
::
matcher
<
PC
,
Ts
...
>::
vmatch
(
tup
,
p
));
}
static
inline
bool
_
(
any_tuple
const
&
tup
,
pattern
<
Ts
...
>
const
&
p
,
typename
pattern
<
Ts
...
>::
mapping_vector
&
mv
)
{
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
,
mv
)
&&
(
p
.
has_values
()
==
false
||
detail
::
matcher
<
PC
,
Ts
...
>::
vmatch
(
tup
,
p
));
}
};
// implementation for multiple wildcards
template
<
typename
...
Ts
>
struct
match_impl
<
wildcard_position
::
multiple
,
Ts
...
>
{
static
constexpr
auto
PC
=
wildcard_position
::
multiple
;
static
inline
bool
_
(
any_tuple
const
&
tup
)
{
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
);
}
template
<
size_t
Size
>
static
inline
bool
_
(
any_tuple
const
&
tup
,
util
::
fixed_vector
<
size_t
,
Size
>&
mv
)
{
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
,
mv
);
}
static
inline
bool
_
(
any_tuple
const
&
tup
,
pattern
<
Ts
...
>
const
&
p
)
{
if
(
p
.
has_values
())
{
typename
pattern
<
Ts
...
>::
mapping_vector
mv
;
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
,
mv
)
&&
detail
::
matcher
<
PC
,
Ts
...
>::
vmatch
(
tup
,
p
,
mv
);
}
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
);
}
static
inline
bool
_
(
any_tuple
const
&
tup
,
pattern
<
Ts
...
>
const
&
p
,
typename
pattern
<
Ts
...
>::
mapping_vector
&
mv
)
{
if
(
p
.
has_values
())
{
typename
pattern
<
Ts
...
>::
mapping_vector
mv
;
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
,
mv
)
&&
detail
::
matcher
<
PC
,
Ts
...
>::
vmatch
(
tup
,
p
,
mv
);
}
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
,
mv
);
}
};
/*
* @brief Returns true if this tuple matches the pattern <tt>{Ts...}</tt>.
*/
template
<
typename
...
Ts
>
bool
matches
(
any_tuple
const
&
tup
)
{
typedef
util
::
type_list
<
Ts
...
>
tl
;
return
detail
::
match_impl
<
get_wildcard_position
<
tl
>
(),
Ts
...
>::
_
(
tup
);
}
/*
* @brief Returns true if this tuple matches the pattern <tt>{Ts...}</tt>.
*/
template
<
typename
...
Ts
>
bool
matches
(
any_tuple
const
&
tup
,
util
::
fixed_vector
<
size_t
,
util
::
tl_count_not
<
util
::
type_list
<
Ts
...
>
,
is_anything
>::
value
>&
mv
)
{
typedef
util
::
type_list
<
Ts
...
>
tl
;
return
detail
::
match_impl
<
get_wildcard_position
<
tl
>
(),
Ts
...
>::
_
(
tup
,
mv
);
}
/*
* @brief Returns true if this tuple matches @p pn.
*/
template
<
typename
...
Ts
>
bool
matches
(
any_tuple
const
&
tup
,
pattern
<
Ts
...
>
const
&
pn
)
{
typedef
util
::
type_list
<
Ts
...
>
tl
;
return
detail
::
match_impl
<
get_wildcard_position
<
tl
>
(),
Ts
...
>::
_
(
tup
,
pn
);
}
/*
* @brief Returns true if this tuple matches @p pn.
*/
template
<
typename
...
Ts
>
bool
matches
(
any_tuple
const
&
tup
,
pattern
<
Ts
...
>
const
&
pn
,
typename
pattern
<
Ts
...
>::
mapping_vector
&
mv
)
{
typedef
util
::
type_list
<
Ts
...
>
tl
;
return
detail
::
match_impl
<
get_wildcard_position
<
tl
>
(),
Ts
...
>::
_
(
tup
,
pn
,
mv
);
}
/*
* @brief Returns true if this tuple matches the pattern <tt>{Ts...}</tt>
* (does not match for values).
*/
template
<
typename
...
Ts
>
inline
bool
matches_types
(
any_tuple
const
&
tup
,
pattern
<
Ts
...
>
const
&
)
{
return
matches
<
Ts
...
>
(
tup
);
}
}
}
// namespace cppa::detail
#endif // MATCHES_HPP
cppa/detail/tdata.hpp
View file @
58318857
...
@@ -50,6 +50,18 @@ uniform_type_info const* uniform_typeid(std::type_info const&);
...
@@ -50,6 +50,18 @@ uniform_type_info const* uniform_typeid(std::type_info const&);
namespace
cppa
{
namespace
detail
{
namespace
cppa
{
namespace
detail
{
template
<
typename
T
>
inline
void
*
ptr_to
(
T
&
what
)
{
return
&
what
;
}
template
<
typename
T
>
inline
void
const
*
ptr_to
(
T
const
&
what
)
{
return
&
what
;
}
template
<
typename
T
>
inline
void
*
ptr_to
(
T
*
what
)
{
return
what
;
}
template
<
typename
T
>
inline
void
const
*
ptr_to
(
T
const
*
what
)
{
return
what
;
}
/*
/*
* "enhanced std::tuple"
* "enhanced std::tuple"
*/
*/
...
@@ -153,7 +165,7 @@ struct tdata<Head, Tail...> : tdata<Tail...>
...
@@ -153,7 +165,7 @@ struct tdata<Head, Tail...> : tdata<Tail...>
inline
void
const
*
at
(
size_t
p
)
const
inline
void
const
*
at
(
size_t
p
)
const
{
{
return
(
p
==
0
)
?
&
head
:
super
::
at
(
p
-
1
);
return
(
p
==
0
)
?
ptr_to
(
head
)
:
super
::
at
(
p
-
1
);
}
}
inline
uniform_type_info
const
*
type_at
(
size_t
p
)
const
inline
uniform_type_info
const
*
type_at
(
size_t
p
)
const
...
@@ -215,7 +227,7 @@ struct tdata<option<Head>, Tail...> : tdata<Tail...>
...
@@ -215,7 +227,7 @@ struct tdata<option<Head>, Tail...> : tdata<Tail...>
inline
void
const
*
at
(
size_t
p
)
const
inline
void
const
*
at
(
size_t
p
)
const
{
{
return
(
p
==
0
)
?
&
head
:
super
::
at
(
p
-
1
);
return
(
p
==
0
)
?
ptr_to
(
head
)
:
super
::
at
(
p
-
1
);
}
}
inline
uniform_type_info
const
*
type_at
(
size_t
p
)
const
inline
uniform_type_info
const
*
type_at
(
size_t
p
)
const
...
...
cppa/detail/tuple_cast_impl.hpp
View file @
58318857
...
@@ -31,10 +31,11 @@
...
@@ -31,10 +31,11 @@
#ifndef TUPLE_CAST_IMPL_HPP
#ifndef TUPLE_CAST_IMPL_HPP
#define TUPLE_CAST_IMPL_HPP
#define TUPLE_CAST_IMPL_HPP
#include "cppa/match.hpp"
#include "cppa/pattern.hpp"
#include "cppa/pattern.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/type_value_pair.hpp"
#include "cppa/type_value_pair.hpp"
#include "cppa/detail/matches.hpp"
#include "cppa/detail/tuple_vals.hpp"
#include "cppa/detail/tuple_vals.hpp"
#include "cppa/detail/types_array.hpp"
#include "cppa/detail/types_array.hpp"
#include "cppa/detail/object_array.hpp"
#include "cppa/detail/object_array.hpp"
...
@@ -60,22 +61,19 @@ struct tuple_cast_impl
...
@@ -60,22 +61,19 @@ struct tuple_cast_impl
static
constexpr
size_t
first_wc
=
static
constexpr
size_t
first_wc
=
static_cast
<
size_t
>
(
util
::
tl_find
<
util
::
type_list
<
T
...
>
,
anything
>::
value
);
static_cast
<
size_t
>
(
util
::
tl_find
<
util
::
type_list
<
T
...
>
,
anything
>::
value
);
typedef
util
::
fixed_vector
<
size_t
,
size
>
mapping_vector
;
typedef
util
::
fixed_vector
<
size_t
,
size
>
mapping_vector
;
template
<
class
Tuple
>
static
inline
option
<
Result
>
safe
(
any_tuple
const
&
tup
)
static
inline
option
<
Result
>
safe
(
Tuple
const
&
tup
)
{
{
mapping_vector
mv
;
mapping_vector
mv
;
if
(
match
<
T
...
>
(
tup
,
mv
))
return
{
Result
::
from
(
tup
.
vals
(),
mv
)};
if
(
match
es
<
T
...
>
(
tup
,
mv
))
return
{
Result
::
from
(
tup
.
vals
(),
mv
)};
return
{};
return
{};
}
}
template
<
class
Tuple
>
static
inline
option
<
Result
>
safe
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
static
inline
option
<
Result
>
safe
(
Tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
{
mapping_vector
mv
;
mapping_vector
mv
;
if
(
match
(
tup
,
p
,
mv
))
return
{
Result
::
from
(
tup
.
vals
(),
mv
)};
if
(
match
es
(
tup
,
p
,
mv
))
return
{
Result
::
from
(
tup
.
vals
(),
mv
)};
return
{};
return
{};
}
}
template
<
class
Tuple
>
static
inline
option
<
Result
>
unsafe
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
static
inline
option
<
Result
>
unsafe
(
Tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
{
mapping_vector
mv
;
mapping_vector
mv
;
if
(
WP
==
wildcard_position
::
in_between
)
if
(
WP
==
wildcard_position
::
in_between
)
...
@@ -94,12 +92,11 @@ struct tuple_cast_impl
...
@@ -94,12 +92,11 @@ struct tuple_cast_impl
}
}
else
else
{
{
if
(
match
(
tup
,
p
,
mv
))
return
{
Result
::
from
(
tup
.
vals
(),
mv
)};
if
(
match
es
(
tup
,
p
,
mv
))
return
{
Result
::
from
(
tup
.
vals
(),
mv
)};
}
}
return
{};
return
{};
}
}
template
<
class
Tuple
>
static
inline
Result
force
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
static
inline
Result
force
(
Tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
{
mapping_vector
mv
;
mapping_vector
mv
;
if
(
WP
==
wildcard_position
::
in_between
)
if
(
WP
==
wildcard_position
::
in_between
)
...
@@ -115,7 +112,7 @@ struct tuple_cast_impl
...
@@ -115,7 +112,7 @@ struct tuple_cast_impl
}
}
else
else
{
{
match
(
tup
,
p
,
mv
);
matches
(
tup
,
p
,
mv
);
return
{
Result
::
from
(
tup
.
vals
(),
mv
)};
return
{
Result
::
from
(
tup
.
vals
(),
mv
)};
}
}
}
}
...
@@ -124,20 +121,17 @@ struct tuple_cast_impl
...
@@ -124,20 +121,17 @@ struct tuple_cast_impl
template
<
class
Result
,
typename
...
T
>
template
<
class
Result
,
typename
...
T
>
struct
tuple_cast_impl
<
wildcard_position
::
nil
,
Result
,
T
...
>
struct
tuple_cast_impl
<
wildcard_position
::
nil
,
Result
,
T
...
>
{
{
template
<
class
Tuple
>
static
inline
option
<
Result
>
safe
(
any_tuple
const
&
tup
)
static
inline
option
<
Result
>
safe
(
Tuple
const
&
tup
)
{
{
if
(
match
<
T
...
>
(
tup
))
return
{
Result
::
from
(
tup
.
vals
())};
if
(
match
es
<
T
...
>
(
tup
))
return
{
Result
::
from
(
tup
.
vals
())};
return
{};
return
{};
}
}
template
<
class
Tuple
>
static
inline
option
<
Result
>
safe
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
static
inline
option
<
Result
>
safe
(
Tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
{
if
(
match
(
tup
,
p
))
return
{
Result
::
from
(
tup
.
vals
())};
if
(
match
es
(
tup
,
p
))
return
{
Result
::
from
(
tup
.
vals
())};
return
{};
return
{};
}
}
template
<
class
Tuple
>
static
inline
option
<
Result
>
unsafe
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
static
inline
option
<
Result
>
unsafe
(
Tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
{
if
(
p
.
has_values
()
==
false
if
(
p
.
has_values
()
==
false
||
matcher
<
wildcard_position
::
nil
,
T
...
>::
vmatch
(
tup
,
p
))
||
matcher
<
wildcard_position
::
nil
,
T
...
>::
vmatch
(
tup
,
p
))
...
@@ -146,8 +140,7 @@ struct tuple_cast_impl<wildcard_position::nil, Result, T...>
...
@@ -146,8 +140,7 @@ struct tuple_cast_impl<wildcard_position::nil, Result, T...>
}
}
return
{};
return
{};
}
}
template
<
class
Tuple
>
static
inline
Result
force
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
)
static
inline
Result
force
(
Tuple
const
&
tup
,
pattern
<
T
...
>
const
&
)
{
{
return
{
Result
::
from
(
tup
.
vals
())};
return
{
Result
::
from
(
tup
.
vals
())};
}
}
...
@@ -157,8 +150,7 @@ template<class Result, typename... T>
...
@@ -157,8 +150,7 @@ template<class Result, typename... T>
struct
tuple_cast_impl
<
wildcard_position
::
trailing
,
Result
,
T
...
>
struct
tuple_cast_impl
<
wildcard_position
::
trailing
,
Result
,
T
...
>
:
tuple_cast_impl
<
wildcard_position
::
nil
,
Result
,
T
...
>
:
tuple_cast_impl
<
wildcard_position
::
nil
,
Result
,
T
...
>
{
{
template
<
class
Tuple
>
static
inline
option
<
Result
>
unsafe
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
static
inline
option
<
Result
>
unsafe
(
Tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
{
if
(
p
.
has_values
()
==
false
if
(
p
.
has_values
()
==
false
||
matcher
<
wildcard_position
::
trailing
,
T
...
>::
vmatch
(
tup
,
p
))
||
matcher
<
wildcard_position
::
trailing
,
T
...
>::
vmatch
(
tup
,
p
))
...
@@ -167,8 +159,7 @@ struct tuple_cast_impl<wildcard_position::trailing, Result, T...>
...
@@ -167,8 +159,7 @@ struct tuple_cast_impl<wildcard_position::trailing, Result, T...>
}
}
return
{};
return
{};
}
}
template
<
class
Tuple
>
static
inline
Result
force
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
)
static
inline
Result
force
(
Tuple
const
&
tup
,
pattern
<
T
...
>
const
&
)
{
{
return
{
Result
::
from
(
tup
.
vals
())};
return
{
Result
::
from
(
tup
.
vals
())};
}
}
...
@@ -177,22 +168,19 @@ struct tuple_cast_impl<wildcard_position::trailing, Result, T...>
...
@@ -177,22 +168,19 @@ struct tuple_cast_impl<wildcard_position::trailing, Result, T...>
template
<
class
Result
,
typename
...
T
>
template
<
class
Result
,
typename
...
T
>
struct
tuple_cast_impl
<
wildcard_position
::
leading
,
Result
,
T
...
>
struct
tuple_cast_impl
<
wildcard_position
::
leading
,
Result
,
T
...
>
{
{
template
<
class
Tuple
>
static
inline
option
<
Result
>
safe
(
any_tuple
const
&
tup
)
static
inline
option
<
Result
>
safe
(
Tuple
const
&
tup
)
{
{
size_t
o
=
tup
.
size
()
-
(
sizeof
...(
T
)
-
1
);
size_t
o
=
tup
.
size
()
-
(
sizeof
...(
T
)
-
1
);
if
(
match
<
T
...
>
(
tup
))
return
{
Result
::
offset_subtuple
(
tup
.
vals
(),
o
)};
if
(
match
es
<
T
...
>
(
tup
))
return
{
Result
::
offset_subtuple
(
tup
.
vals
(),
o
)};
return
{};
return
{};
}
}
template
<
class
Tuple
>
static
inline
option
<
Result
>
safe
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
static
inline
option
<
Result
>
safe
(
Tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
{
size_t
o
=
tup
.
size
()
-
(
sizeof
...(
T
)
-
1
);
size_t
o
=
tup
.
size
()
-
(
sizeof
...(
T
)
-
1
);
if
(
match
(
tup
,
p
))
return
{
Result
::
offset_subtuple
(
tup
.
vals
(),
o
)};
if
(
match
es
(
tup
,
p
))
return
{
Result
::
offset_subtuple
(
tup
.
vals
(),
o
)};
return
{};
return
{};
}
}
template
<
class
Tuple
>
static
inline
option
<
Result
>
unsafe
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
static
inline
option
<
Result
>
unsafe
(
Tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
{
if
(
p
.
has_values
()
==
false
if
(
p
.
has_values
()
==
false
||
matcher
<
wildcard_position
::
leading
,
T
...
>::
vmatch
(
tup
,
p
))
||
matcher
<
wildcard_position
::
leading
,
T
...
>::
vmatch
(
tup
,
p
))
...
@@ -202,8 +190,7 @@ struct tuple_cast_impl<wildcard_position::leading, Result, T...>
...
@@ -202,8 +190,7 @@ struct tuple_cast_impl<wildcard_position::leading, Result, T...>
}
}
return
{};
return
{};
}
}
template
<
class
Tuple
>
static
inline
Result
force
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
)
static
inline
Result
force
(
Tuple
const
&
tup
,
pattern
<
T
...
>
const
&
)
{
{
size_t
o
=
tup
.
size
()
-
(
sizeof
...(
T
)
-
1
);
size_t
o
=
tup
.
size
()
-
(
sizeof
...(
T
)
-
1
);
return
Result
::
offset_subtuple
(
tup
.
vals
(),
o
);
return
Result
::
offset_subtuple
(
tup
.
vals
(),
o
);
...
...
cppa/detail/tuple_vals.hpp
View file @
58318857
...
@@ -53,22 +53,23 @@ class tuple_vals : public abstract_tuple
...
@@ -53,22 +53,23 @@ class tuple_vals : public abstract_tuple
typedef
abstract_tuple
super
;
typedef
abstract_tuple
super
;
public:
typedef
tdata
<
ElementTypes
...
>
data_type
;
typedef
tdata
<
ElementTypes
...
>
data_type
;
typedef
types_array
<
ElementTypes
...
>
element_types
;
typedef
types_array
<
ElementTypes
...
>
element_types
;
data_type
m_data
;
static
types_array
<
ElementTypes
...
>
m_types
;
public:
tuple_vals
()
:
m_data
()
{
}
tuple_vals
()
:
m_data
()
{
}
tuple_vals
(
tuple_vals
const
&
other
)
:
super
(),
m_data
(
other
.
m_data
)
{
}
tuple_vals
(
tuple_vals
const
&
other
)
:
super
(),
m_data
(
other
.
m_data
)
{
}
tuple_vals
(
ElementTypes
const
&
...
args
)
:
m_data
(
args
...)
{
}
tuple_vals
(
ElementTypes
const
&
...
args
)
:
m_data
(
args
...)
{
}
inline
data_type
&
data
()
{
return
m_data
;
}
inline
data_type
const
&
data
()
const
inline
data_type
const
&
data
()
const
{
{
return
m_data
;
return
m_data
;
...
@@ -92,6 +93,7 @@ class tuple_vals : public abstract_tuple
...
@@ -92,6 +93,7 @@ class tuple_vals : public abstract_tuple
void
*
mutable_at
(
size_t
pos
)
void
*
mutable_at
(
size_t
pos
)
{
{
CPPA_REQUIRE
(
pos
<
size
());
return
const_cast
<
void
*>
(
at
(
pos
));
return
const_cast
<
void
*>
(
at
(
pos
));
}
}
...
@@ -122,6 +124,12 @@ class tuple_vals : public abstract_tuple
...
@@ -122,6 +124,12 @@ class tuple_vals : public abstract_tuple
return
detail
::
static_type_list
<
ElementTypes
...
>::
list
;
return
detail
::
static_type_list
<
ElementTypes
...
>::
list
;
}
}
private:
data_type
m_data
;
static
types_array
<
ElementTypes
...
>
m_types
;
};
};
template
<
typename
...
ElementTypes
>
template
<
typename
...
ElementTypes
>
...
...
cppa/tuple_view.hpp
→
cppa/
detail/
tuple_view.hpp
View file @
58318857
...
@@ -31,156 +31,108 @@
...
@@ -31,156 +31,108 @@
#ifndef TUPLE_VIEW_HPP
#ifndef TUPLE_VIEW_HPP
#define TUPLE_VIEW_HPP
#define TUPLE_VIEW_HPP
#include <vector>
#include "cppa/util/static_foreach.hpp"
#include <cstring>
#include "cppa/get.hpp"
#include "cppa/detail/tuple_vals.hpp"
#include "cppa/tuple.hpp"
#include "cppa/detail/abstract_tuple.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/util/at.hpp"
namespace
cppa
{
namespace
detail
{
#include "cppa/util/type_list.hpp"
#include "cppa/util/fixed_vector.hpp"
#include "cppa/util/compare_tuples.hpp"
#include "cppa/detail/decorated_tuple.hpp"
struct
tuple_view_copy_helper
{
namespace
cppa
{
size_t
pos
;
abstract_tuple
*
target
;
template
<
size_t
N
,
typename
...
Types
>
tuple_view_copy_helper
(
abstract_tuple
*
trgt
)
:
pos
(
0
),
target
(
trgt
)
{
}
typename
util
::
at
<
N
,
Types
...
>::
type
&
get_ref
(
tuple_view
<
Types
...
>&
t
);
template
<
typename
T
>
void
operator
()(
T
const
*
value
)
{
*
(
reinterpret_cast
<
T
*>
(
target
->
mutable_at
(
pos
++
)))
=
*
value
;
}
};
/**
* @brief Describes a view of an fixed-length tuple.
*/
template
<
typename
...
ElementTypes
>
template
<
typename
...
ElementTypes
>
class
tuple_view
class
tuple_view
:
public
abstract_tuple
{
{
template
<
size_t
N
,
typename
...
Types
>
static_assert
(
sizeof
...(
ElementTypes
)
>
0
,
friend
typename
util
::
at
<
N
,
Types
...
>::
type
&
get_ref
(
tuple_view
<
Types
...
>&
);
"tuple_vals is not allowed to be empty"
);
void
*
m_data
[
sizeof
...(
ElementTypes
)];
public:
t
uple_view
()
{
}
t
ypedef
tdata
<
ElementTypes
*
...
>
data_type
;
public:
typedef
types_array
<
ElementTypes
...
>
element_types
;
static
constexpr
size_t
num_elements
=
sizeof
...(
ElementTypes
);
tuple_view
()
=
delete
;
tuple_view
(
tuple_view
const
&
)
=
delete
;
typedef
util
::
type_list
<
ElementTypes
...
>
types
;
/**
* @warning @p tuple_view does @b NOT takes ownership for given pointers
*/
tuple_view
(
ElementTypes
*
...
args
)
:
m_data
(
args
...)
{
}
static
tuple_view
from
(
std
::
vector
<
type_value_pair
>
const
&
vec
)
inline
data_type
&
data
(
)
{
{
tuple_view
result
;
return
m_data
;
size_t
j
=
0
;
for
(
type_value_pair
const
&
tvp
:
vec
)
{
result
.
m_data
[
j
++
]
=
const_cast
<
void
*>
(
tvp
.
second
);
}
return
std
::
move
(
result
);
}
}
static
tuple_view
from
(
std
::
vector
<
type_value_pair
>
const
&
vec
,
inline
data_type
const
&
data
()
const
util
::
fixed_vector
<
size_t
,
sizeof
...(
ElementTypes
)
>
const
&
mv
)
{
{
tuple_view
result
;
return
m_data
;
for
(
size_t
i
=
0
;
i
<
sizeof
...(
ElementTypes
);
++
i
)
{
result
.
m_data
[
i
]
=
const_cast
<
void
*>
(
vec
[
mv
[
i
]].
second
);
}
return
std
::
move
(
result
);
}
}
tuple_view
&
operator
=
(
tuple_view
const
&
other
)
size_t
size
()
const
{
{
memcpy
(
m_data
,
other
.
m_data
,
num_elements
*
sizeof
(
void
*
));
return
sizeof
...(
ElementTypes
);
return
*
this
;
}
}
tuple_view
(
tuple_view
const
&
other
)
abstract_tuple
*
copy
()
const
{
{
memcpy
(
m_data
,
other
.
m_data
,
num_elements
*
sizeof
(
void
*
));
auto
result
=
new
tuple_vals
<
ElementTypes
...
>
;
tuple_view_copy_helper
f
{
result
};
util
::
static_foreach
<
0
,
sizeof
...(
ElementTypes
)
>::
_
(
m_data
,
f
);
return
result
;
}
}
inline
size_t
size
(
)
const
void
const
*
at
(
size_t
pos
)
const
{
{
return
sizeof
...(
ElementTypes
);
CPPA_REQUIRE
(
pos
<
size
());
return
m_data
.
at
(
pos
);
}
}
inline
void
const
*
at
(
size_t
p
)
const
{
return
m_data
[
p
];
}
void
*
mutable_at
(
size_t
pos
)
{
inline
void
*
mutable_at
(
size_t
p
)
{
return
m_data
[
p
];
}
CPPA_REQUIRE
(
pos
<
size
());
return
const_cast
<
void
*>
(
at
(
pos
));
};
}
template
<
size_t
N
,
typename
...
Types
>
const
typename
util
::
at
<
N
,
Types
...
>::
type
&
get
(
tuple_view
<
Types
...
>
const
&
t
)
{
static_assert
(
N
<
sizeof
...(
Types
),
"N >= t.size()"
);
typedef
typename
util
::
at
<
N
,
Types
...
>::
type
result_t
;
return
*
reinterpret_cast
<
result_t
const
*>
(
t
.
at
(
N
));
}
template
<
size_t
N
,
typename
...
Types
>
typename
util
::
at
<
N
,
Types
...
>::
type
&
get_ref
(
tuple_view
<
Types
...
>&
t
)
{
static_assert
(
N
<
sizeof
...(
Types
),
"N >= t.size()"
);
typedef
typename
util
::
at
<
N
,
Types
...
>::
type
result_t
;
return
*
reinterpret_cast
<
result_t
*>
(
t
.
mutable_at
(
N
));
}
template
<
typename
TypeList
>
uniform_type_info
const
*
type_at
(
size_t
pos
)
const
struct
tuple_view_from_type_list
;
{
CPPA_REQUIRE
(
pos
<
size
());
return
m_types
[
pos
];
}
template
<
typename
...
Types
>
void
const
*
type_token
()
const
struct
tuple_view_from_type_list
<
util
::
type_list
<
Types
...
>>
{
{
return
detail
::
static_type_list
<
ElementTypes
...
>::
list
;
typedef
tuple_view
<
Types
...
>
type
;
}
};
template
<
typename
...
LhsTypes
,
typename
...
RhsTypes
>
std
::
type_info
const
*
impl_type
()
const
inline
bool
operator
==
(
tuple_view
<
LhsTypes
...
>
const
&
lhs
,
{
tuple_view
<
RhsTypes
...
>
const
&
rhs
)
return
detail
::
static_type_list
<
ElementTypes
...
>::
list
;
{
}
return
util
::
compare_tuples
(
lhs
,
rhs
);
}
template
<
typename
...
LhsTypes
,
typename
...
RhsTypes
>
private:
inline
bool
operator
==
(
tuple
<
LhsTypes
...
>
const
&
lhs
,
tuple_view
<
RhsTypes
...
>
const
&
rhs
)
{
return
util
::
compare_tuples
(
lhs
,
rhs
);
}
template
<
typename
...
LhsTypes
,
typename
...
RhsTypes
>
data_type
m_data
;
inline
bool
operator
==
(
tuple_view
<
LhsTypes
...
>
const
&
lhs
,
tuple
<
RhsTypes
...
>
const
&
rhs
)
{
return
util
::
compare_tuples
(
lhs
,
rhs
);
}
template
<
typename
...
LhsTypes
,
typename
...
RhsTypes
>
static
types_array
<
ElementTypes
...
>
m_types
;
inline
bool
operator
!=
(
tuple_view
<
LhsTypes
...
>
const
&
lhs
,
tuple_view
<
RhsTypes
...
>
const
&
rhs
)
{
return
!
(
lhs
==
rhs
);
}
template
<
typename
...
LhsTypes
,
typename
...
RhsTypes
>
};
inline
bool
operator
!=
(
tuple
<
LhsTypes
...
>
const
&
lhs
,
tuple_view
<
RhsTypes
...
>
const
&
rhs
)
{
return
!
(
lhs
==
rhs
);
}
template
<
typename
...
LhsTypes
,
typename
...
RhsTypes
>
template
<
typename
...
ElementTypes
>
inline
bool
operator
!=
(
tuple_view
<
LhsTypes
...
>
const
&
lhs
,
types_array
<
ElementTypes
...
>
tuple_view
<
ElementTypes
...
>::
m_types
;
tuple
<
RhsTypes
...
>
const
&
rhs
)
{
return
!
(
lhs
==
rhs
);
}
}
// namespace cppa
}
}
// namespace cppa::detail
#endif // TUPLE_VIEW_HPP
#endif // TUPLE_VIEW_HPP
cppa/get.hpp
View file @
58318857
...
@@ -44,9 +44,6 @@ namespace detail { template<typename...> class tdata; }
...
@@ -44,9 +44,6 @@ namespace detail { template<typename...> class tdata; }
// forward declaration of tuple
// forward declaration of tuple
template
<
typename
...
>
class
tuple
;
template
<
typename
...
>
class
tuple
;
// forward declaration of tuple_view
template
<
typename
...
>
class
tuple_view
;
// forward declaration of get(detail::tdata<...> const&)
// forward declaration of get(detail::tdata<...> const&)
template
<
size_t
N
,
typename
...
Tn
>
template
<
size_t
N
,
typename
...
Tn
>
const
typename
util
::
at
<
N
,
Tn
...
>::
type
&
get
(
detail
::
tdata
<
Tn
...
>
const
&
);
const
typename
util
::
at
<
N
,
Tn
...
>::
type
&
get
(
detail
::
tdata
<
Tn
...
>
const
&
);
...
@@ -55,10 +52,6 @@ const typename util::at<N, Tn...>::type& get(detail::tdata<Tn...> const&);
...
@@ -55,10 +52,6 @@ const typename util::at<N, Tn...>::type& get(detail::tdata<Tn...> const&);
template
<
size_t
N
,
typename
...
Tn
>
template
<
size_t
N
,
typename
...
Tn
>
const
typename
util
::
at
<
N
,
Tn
...
>::
type
&
get
(
tuple
<
Tn
...
>
const
&
);
const
typename
util
::
at
<
N
,
Tn
...
>::
type
&
get
(
tuple
<
Tn
...
>
const
&
);
// forward declarations of get(tuple_view<...> const&)
template
<
size_t
N
,
typename
...
Tn
>
const
typename
util
::
at
<
N
,
Tn
...
>::
type
&
get
(
tuple_view
<
Tn
...
>
const
&
);
// forward declarations of get_ref(detail::tdata<...>&)
// forward declarations of get_ref(detail::tdata<...>&)
template
<
size_t
N
,
typename
...
Tn
>
template
<
size_t
N
,
typename
...
Tn
>
typename
util
::
at
<
N
,
Tn
...
>::
type
&
get_ref
(
detail
::
tdata
<
Tn
...
>&
);
typename
util
::
at
<
N
,
Tn
...
>::
type
&
get_ref
(
detail
::
tdata
<
Tn
...
>&
);
...
@@ -67,10 +60,6 @@ typename util::at<N, Tn...>::type& get_ref(detail::tdata<Tn...>&);
...
@@ -67,10 +60,6 @@ typename util::at<N, Tn...>::type& get_ref(detail::tdata<Tn...>&);
template
<
size_t
N
,
typename
...
Tn
>
template
<
size_t
N
,
typename
...
Tn
>
typename
util
::
at
<
N
,
Tn
...
>::
type
&
get_ref
(
tuple
<
Tn
...
>&
);
typename
util
::
at
<
N
,
Tn
...
>::
type
&
get_ref
(
tuple
<
Tn
...
>&
);
// forward declarations of get_ref(tuple_view<...>&)
template
<
size_t
N
,
typename
...
Tn
>
typename
util
::
at
<
N
,
Tn
...
>::
type
&
get_ref
(
tuple_view
<
Tn
...
>&
);
}
// namespace cppa
}
// namespace cppa
#endif // GET_HPP
#endif // GET_HPP
cppa/match.hpp
View file @
58318857
...
@@ -28,498 +28,102 @@
...
@@ -28,498 +28,102 @@
\******************************************************************************/
\******************************************************************************/
#ifndef MATCH
ES
_HPP
#ifndef MATCH_HPP
#define MATCH
ES
_HPP
#define MATCH_HPP
#include <type_traits>
#include "cppa/pattern.hpp"
#include "cppa/anything.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/partial_function.hpp"
#include "cppa/util/type_list.hpp"
namespace
cppa
{
namespace
detail
{
#include "cppa/detail/tuple_vals.hpp"
#include "cppa/detail/types_array.hpp"
#include "cppa/detail/object_array.hpp"
#include "cppa/detail/decorated_tuple.hpp"
namespace
cppa
{
namespace
detail
{
typedef
std
::
integral_constant
<
wildcard_position
,
wildcard_position
::
nil
>
no_wildcard
;
}
// namespace detail
namespace
detail
{
template
<
wildcard_position
,
typename
...
>
struct
matcher
;
}
// namespace detail
template
<
wildcard_position
PC
,
typename
...
Ts
>
struct
match_impl
;
/**
*
*/
template
<
typename
...
Ts
>
inline
bool
match
(
any_tuple
const
&
tup
)
{
typedef
util
::
type_list
<
Ts
...
>
tl
;
return
match_impl
<
get_wildcard_position
<
tl
>
(),
Ts
...
>::
_
(
tup
);
}
/**
struct
match_helper
*
*/
template
<
typename
...
Ts
>
inline
bool
match
(
any_tuple
const
&
tup
,
util
::
fixed_vector
<
size_t
,
util
::
tl_count_not
<
util
::
type_list
<
Ts
...
>
,
is_anything
>::
value
>&
mv
)
{
{
typedef
util
::
type_list
<
Ts
...
>
tl
;
any_tuple
tup
;
return
match_impl
<
get_wildcard_position
<
tl
>
(),
Ts
...
>::
_
(
tup
,
mv
);
match_helper
(
any_tuple
t
)
:
tup
(
std
::
move
(
t
))
{
}
}
template
<
class
...
Args
>
void
operator
()(
partial_function
&&
pf
,
Args
&&
...
args
)
/**
*
*/
template
<
typename
...
Ts
>
inline
bool
match
(
any_tuple
const
&
tup
,
pattern
<
Ts
...
>
const
&
ptrn
)
{
typedef
util
::
type_list
<
Ts
...
>
tl
;
return
match_impl
<
get_wildcard_position
<
tl
>
(),
Ts
...
>::
_
(
tup
,
ptrn
);
}
/**
*
*/
template
<
typename
...
Ts
>
inline
bool
match
(
any_tuple
const
&
tup
,
pattern
<
Ts
...
>
const
&
ptrn
,
typename
pattern
<
Ts
...
>::
mapping_vector
&
mv
)
{
typedef
util
::
type_list
<
Ts
...
>
tl
;
return
match_impl
<
get_wildcard_position
<
tl
>
(),
Ts
...
>::
_
(
tup
,
ptrn
,
mv
);
}
/**
* @brief Matches types only (ignores all values of given pattern).
*/
template
<
typename
...
Ts
>
inline
bool
match_types
(
any_tuple
const
&
tup
,
pattern
<
Ts
...
>
const
&
)
{
typedef
util
::
type_list
<
Ts
...
>
tl
;
return
match_impl
<
get_wildcard_position
<
tl
>
(),
Ts
...
>::
_
(
tup
);
}
// implementation for zero or one wildcards
template
<
wildcard_position
PC
,
typename
...
Ts
>
struct
match_impl
{
static
inline
bool
_
(
any_tuple
const
&
tup
)
{
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
);
}
template
<
size_t
Size
>
static
inline
bool
_
(
any_tuple
const
&
tup
,
util
::
fixed_vector
<
size_t
,
Size
>&
mv
)
{
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
,
mv
);
}
static
inline
bool
_
(
any_tuple
const
&
tup
,
pattern
<
Ts
...
>
const
&
p
)
{
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
)
&&
(
p
.
has_values
()
==
false
||
detail
::
matcher
<
PC
,
Ts
...
>::
vmatch
(
tup
,
p
));
}
static
inline
bool
_
(
any_tuple
const
&
tup
,
pattern
<
Ts
...
>
const
&
p
,
typename
pattern
<
Ts
...
>::
mapping_vector
&
mv
)
{
{
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
,
mv
)
partial_function
tmp
;
&&
(
p
.
has_values
()
==
false
tmp
.
splice
(
std
::
move
(
pf
),
std
::
forward
<
Args
>
(
args
)...);
||
detail
::
matcher
<
PC
,
Ts
...
>::
vmatch
(
tup
,
p
)
);
tmp
(
tup
);
}
}
};
};
// implementation for multiple wildcards
template
<
typename
Iterator
>
template
<
typename
...
Ts
>
struct
match_each_helper
struct
match_impl
<
wildcard_position
::
multiple
,
Ts
...
>
{
{
static
constexpr
auto
PC
=
wildcard_position
::
multiple
;
Iterator
i
;
Iterator
e
;
static
inline
bool
_
(
any_tuple
const
&
tup
)
match_each_helper
(
Iterator
first
,
Iterator
last
)
:
i
(
first
),
e
(
last
)
{
}
{
template
<
typename
...
Args
>
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
);
void
operator
()(
partial_function
&&
arg0
,
Args
&&
...
args
)
}
template
<
size_t
Size
>
static
inline
bool
_
(
any_tuple
const
&
tup
,
util
::
fixed_vector
<
size_t
,
Size
>&
mv
)
{
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
,
mv
);
}
static
inline
bool
_
(
any_tuple
const
&
tup
,
pattern
<
Ts
...
>
const
&
p
)
{
if
(
p
.
has_values
())
{
typename
pattern
<
Ts
...
>::
mapping_vector
mv
;
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
,
mv
)
&&
detail
::
matcher
<
PC
,
Ts
...
>::
vmatch
(
tup
,
p
,
mv
);
}
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
);
}
static
inline
bool
_
(
any_tuple
const
&
tup
,
pattern
<
Ts
...
>
const
&
p
,
typename
pattern
<
Ts
...
>::
mapping_vector
&
mv
)
{
{
if
(
p
.
has_values
())
partial_function
tmp
;
tmp
.
splice
(
std
::
move
(
arg0
),
std
::
forward
<
Args
>
(
args
)...);
for
(;
i
!=
e
;
++
i
)
{
{
typename
pattern
<
Ts
...
>::
mapping_vector
mv
;
tmp
(
any_tuple
::
view
(
*
i
));
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
,
mv
)
&&
detail
::
matcher
<
PC
,
Ts
...
>::
vmatch
(
tup
,
p
,
mv
);
}
}
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
,
mv
);
}
}
};
};
/******************************************************************************\
template
<
typename
Iterator
,
typename
Projection
>
** implementation details **
struct
pmatch_each_helper
\******************************************************************************/
namespace
detail
{
template
<
typename
...
T
>
struct
matcher
<
wildcard_position
::
nil
,
T
...
>
{
{
static
inline
bool
tmatch
(
any_tuple
const
&
tup
)
Iterator
i
;
{
Iterator
e
;
// match implementation type if possible
Projection
p
;
auto
impl
=
tup
.
impl_type
();
template
<
typename
PJ
>
// the impl_type of both decorated_tuple and tuple_vals
pmatch_each_helper
(
Iterator
first
,
Iterator
last
,
PJ
&&
proj
)
:
i
(
first
),
e
(
last
),
p
(
std
::
forward
<
PJ
>
(
proj
))
{
}
// is &typeid(type_list<T...>)
template
<
typename
...
Args
>
auto
tinf
=
detail
::
static_type_list
<
T
...
>::
list
;
void
operator
()(
partial_function
&&
arg0
,
Args
&&
...
args
)
if
(
impl
==
tinf
||
*
impl
==
*
tinf
)
{
return
true
;
}
// always use a full dynamic match for object arrays
else
if
(
*
impl
==
typeid
(
detail
::
object_array
)
&&
tup
.
size
()
==
sizeof
...(
T
))
{
auto
&
tarr
=
detail
::
static_types_array
<
T
...
>::
arr
;
return
std
::
equal
(
tup
.
begin
(),
tup
.
end
(),
tarr
.
begin
(),
detail
::
types_only_eq
);
}
return
false
;
}
static
inline
bool
tmatch
(
any_tuple
const
&
tup
,
util
::
fixed_vector
<
size_t
,
sizeof
...(
T
)
>&
mv
)
{
{
if
(
tmatch
(
tup
))
partial_function
tmp
;
tmp
.
splice
(
std
::
move
(
arg0
),
std
::
forward
<
Args
>
(
args
)...);
for
(;
i
!=
e
;
++
i
)
{
{
mv
.
resize
(
sizeof
...(
T
));
tmp
(
any_tuple
::
view
(
p
(
*
i
)));
std
::
iota
(
mv
.
begin
(),
mv
.
end
(),
0
);
return
true
;
}
}
return
false
;
}
static
inline
bool
vmatch
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
ptrn
)
{
CPPA_REQUIRE
(
tup
.
size
()
==
sizeof
...(
T
));
return
std
::
equal
(
ptrn
.
begin
(),
ptrn
.
vend
(),
tup
.
begin
(),
detail
::
values_only_eq_v2
);
}
}
};
};
template
<
typename
...
T
>
}
}
// namespace cppa::detail
struct
matcher
<
wildcard_position
::
trailing
,
T
...
>
{
static
constexpr
size_t
size
=
sizeof
...(
T
)
-
1
;
static
inline
bool
tmatch
(
any_tuple
const
&
tup
)
namespace
cppa
{
{
if
(
tup
.
size
()
>=
size
)
{
auto
&
tarr
=
static_types_array
<
T
...
>::
arr
;
auto
begin
=
tup
.
begin
();
return
std
::
equal
(
begin
,
begin
+
size
,
tarr
.
begin
(),
detail
::
types_only_eq
);
}
return
false
;
}
static
inline
bool
tmatch
(
any_tuple
const
&
tup
,
util
::
fixed_vector
<
size_t
,
size
>&
mv
)
{
if
(
tmatch
(
tup
))
{
mv
.
resize
(
size
);
std
::
iota
(
mv
.
begin
(),
mv
.
end
(),
0
);
return
true
;
}
return
false
;
}
static
inline
bool
vmatch
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
ptrn
)
{
return
std
::
equal
(
ptrn
.
begin
(),
ptrn
.
vend
(),
tup
.
begin
(),
detail
::
values_only_eq_v2
);
}
};
template
<
>
/**
struct
matcher
<
wildcard_position
::
leading
,
anything
>
* @brief Match expression.
*/
template
<
typename
T
>
detail
::
match_helper
match
(
T
&
what
)
{
{
static
inline
bool
tmatch
(
any_tuple
const
&
)
return
any_tuple
::
view
(
what
);
{
}
return
true
;
}
static
inline
bool
tmatch
(
any_tuple
const
&
,
util
::
fixed_vector
<
size_t
,
0
>&
)
{
return
true
;
}
static
inline
bool
vmatch
(
any_tuple
const
&
,
pattern
<
anything
>
const
&
)
{
return
true
;
}
};
template
<
typename
...
T
>
/**
struct
matcher
<
wildcard_position
::
leading
,
T
...
>
* @brief Match expression that matches against all elements of @p what.
*/
template
<
class
Container
>
auto
match_each
(
Container
&
what
)
->
detail
::
match_each_helper
<
decltype
(
std
::
begin
(
what
))
>
{
{
static
constexpr
size_t
size
=
sizeof
...(
T
)
-
1
;
return
{
std
::
begin
(
what
),
std
::
end
(
what
)};
}
static
inline
bool
tmatch
(
any_tuple
const
&
tup
)
{
auto
tup_size
=
tup
.
size
();
if
(
tup_size
>=
size
)
{
auto
&
tarr
=
static_types_array
<
T
...
>::
arr
;
auto
begin
=
tup
.
begin
();
begin
+=
(
tup_size
-
size
);
return
std
::
equal
(
begin
,
tup
.
end
(),
(
tarr
.
begin
()
+
1
),
// skip 'anything'
detail
::
types_only_eq
);
}
return
false
;
}
static
inline
bool
tmatch
(
any_tuple
const
&
tup
,
util
::
fixed_vector
<
size_t
,
size
>&
mv
)
{
if
(
tmatch
(
tup
))
{
mv
.
resize
(
size
);
std
::
iota
(
mv
.
begin
(),
mv
.
end
(),
tup
.
size
()
-
size
);
return
true
;
}
return
false
;
}
static
inline
bool
vmatch
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
ptrn
)
{
auto
tbegin
=
tup
.
begin
();
// skip unmatched elements
tbegin
+=
(
tup
.
size
()
-
size
);
// skip leading wildcard ++(ptr.begin())
return
std
::
equal
(
++
(
ptrn
.
begin
()),
ptrn
.
vend
(),
tbegin
,
detail
::
values_only_eq_v2
);
}
};
template
<
typename
...
T
>
template
<
typename
InputIterator
>
struct
matcher
<
wildcard_position
::
in_between
,
T
...
>
auto
match_each
(
InputIterator
first
,
InputIterator
last
)
->
detail
::
match_each_helper
<
InputIterator
>
{
{
static
constexpr
int
signed_wc_pos
=
return
{
first
,
last
};
util
::
tl_find
<
util
::
type_list
<
T
...
>
,
anything
>::
value
;
}
static
constexpr
size_t
size
=
sizeof
...(
T
);
static
constexpr
size_t
wc_pos
=
static_cast
<
size_t
>
(
signed_wc_pos
);
static_assert
(
signed_wc_pos
!=
-
1
&&
signed_wc_pos
!=
0
&&
signed_wc_pos
!=
(
sizeof
...(
T
)
-
1
),
"illegal wildcard position"
);
static
inline
bool
tmatch
(
any_tuple
const
&
tup
)
{
auto
tup_size
=
tup
.
size
();
if
(
tup_size
>=
size
)
{
auto
&
tarr
=
static_types_array
<
T
...
>::
arr
;
// first range [0, X1)
auto
begin
=
tup
.
begin
();
auto
end
=
begin
+
wc_pos
;
if
(
std
::
equal
(
begin
,
end
,
tarr
.
begin
(),
detail
::
types_only_eq
))
{
// second range [X2, N)
begin
=
end
=
tup
.
end
();
begin
-=
(
size
-
(
wc_pos
+
1
));
auto
arr_begin
=
tarr
.
begin
()
+
(
wc_pos
+
1
);
return
std
::
equal
(
begin
,
end
,
arr_begin
,
detail
::
types_only_eq
);
}
}
return
false
;
}
static
inline
bool
tmatch
(
any_tuple
const
&
tup
,
util
::
fixed_vector
<
size_t
,
size
-
1
>&
mv
)
{
if
(
tmatch
(
tup
))
{
// first range
mv
.
resize
(
size
-
1
);
auto
begin
=
mv
.
begin
();
std
::
iota
(
begin
,
begin
+
wc_pos
,
0
);
// second range
begin
=
mv
.
begin
()
+
wc_pos
;
std
::
iota
(
begin
,
mv
.
end
(),
tup
.
size
()
-
(
size
-
(
wc_pos
+
1
)));
return
true
;
}
return
false
;
}
static
inline
bool
vmatch
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
ptrn
)
{
// first range
auto
tbegin
=
tup
.
begin
();
auto
tend
=
tbegin
+
wc_pos
;
if
(
std
::
equal
(
tbegin
,
tend
,
ptrn
.
begin
(),
detail
::
values_only_eq
))
{
// second range
tbegin
=
tend
=
tup
.
end
();
tbegin
-=
(
size
-
(
wc_pos
+
1
));
auto
pbegin
=
ptrn
.
begin
();
pbegin
+=
(
wc_pos
+
1
);
return
std
::
equal
(
tbegin
,
tend
,
pbegin
,
detail
::
values_only_eq
);
}
return
false
;
}
};
template
<
typename
...
T
>
template
<
typename
InputIterator
,
typename
Projection
>
struct
matcher
<
wildcard_position
::
multiple
,
T
...
>
auto
pmatch_each
(
InputIterator
first
,
InputIterator
last
,
Projection
&&
proj
)
->
detail
::
pmatch_each_helper
<
InputIterator
,
typename
util
::
rm_ref
<
Projection
>::
type
>
{
{
static
constexpr
size_t
wc_count
=
return
{
first
,
last
,
std
::
forward
<
Projection
>
(
proj
)};
util
::
tl_count
<
util
::
type_list
<
T
...
>
,
is_anything
>::
value
;
}
static_assert
(
sizeof
...(
T
)
>
wc_count
,
"only wildcards given"
);
template
<
class
TupleIter
,
class
PatternIter
,
class
Push
,
class
Commit
,
class
Rollback
>
static
bool
match
(
TupleIter
tbegin
,
TupleIter
tend
,
PatternIter
pbegin
,
PatternIter
pend
,
Push
&&
push
,
Commit
&&
commit
,
Rollback
&&
rollback
)
{
while
(
!
(
pbegin
==
pend
&&
tbegin
==
tend
))
{
if
(
pbegin
==
pend
)
{
// reached end of pattern while some values remain unmatched
return
false
;
}
else
if
(
pbegin
.
type
()
==
nullptr
)
// nullptr == wildcard (anything)
{
// perform submatching
++
pbegin
;
// always true at the end of the pattern
if
(
pbegin
==
pend
)
return
true
;
// safe current mapping as fallback
commit
();
// iterate over tuple values until we found a match
for
(;
tbegin
!=
tend
;
++
tbegin
)
{
if
(
match
(
tbegin
,
tend
,
pbegin
,
pend
,
push
,
commit
,
rollback
))
{
return
true
;
}
// restore mapping to fallback (delete invalid mappings)
rollback
();
}
return
false
;
// no submatch found
}
// compare types
else
if
(
tbegin
.
type
()
==
pbegin
.
type
())
push
(
tbegin
);
// no match
else
return
false
;
// next iteration
++
tbegin
;
++
pbegin
;
}
return
true
;
// pbegin == pend && tbegin == tend
}
static
inline
bool
tmatch
(
any_tuple
const
&
tup
)
{
auto
&
tarr
=
static_types_array
<
T
...
>::
arr
;
if
(
tup
.
size
()
>=
(
sizeof
...(
T
)
-
wc_count
))
{
return
match
(
tup
.
begin
(),
tup
.
end
(),
tarr
.
begin
(),
tarr
.
end
(),
[](
any_tuple
::
const_iterator
const
&
)
{
},
[]()
{
},
[]()
{
});
}
return
false
;
}
template
<
class
MappingVector
>
static
inline
bool
tmatch
(
any_tuple
const
&
tup
,
MappingVector
&
mv
)
{
auto
&
tarr
=
static_types_array
<
T
...
>::
arr
;
if
(
tup
.
size
()
>=
(
sizeof
...(
T
)
-
wc_count
))
{
size_t
commited_size
=
0
;
return
match
(
tup
.
begin
(),
tup
.
end
(),
tarr
.
begin
(),
tarr
.
end
(),
[
&
](
any_tuple
::
const_iterator
const
&
iter
)
{
mv
.
push_back
(
iter
.
position
());
},
[
&
]()
{
commited_size
=
mv
.
size
();
},
[
&
]()
{
mv
.
resize
(
commited_size
);
});
}
return
false
;
}
static
inline
bool
vmatch
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
ptrn
,
typename
pattern
<
T
...
>::
mapping_vector
const
&
mv
)
{
auto
i
=
mv
.
begin
();
for
(
auto
j
=
ptrn
.
begin
();
j
!=
ptrn
.
end
();
++
j
)
{
if
(
j
.
type
()
!=
nullptr
)
{
if
(
j
.
value
()
!=
nullptr
&&
j
.
type
()
->
equals
(
tup
.
at
(
*
i
),
j
.
value
())
==
false
)
{
return
false
;
}
++
i
;
}
}
}
};
}
// namespace detail
}
// namespace cppa
}
// namespace cppa
#endif // MATCH
ES
_HPP
#endif // MATCH_HPP
cppa/pattern.hpp
View file @
58318857
...
@@ -38,8 +38,6 @@
...
@@ -38,8 +38,6 @@
#include "cppa/option.hpp"
#include "cppa/option.hpp"
#include "cppa/anything.hpp"
#include "cppa/anything.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/tuple_view.hpp"
#include "cppa/type_value_pair.hpp"
#include "cppa/type_value_pair.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/uniform_type_info.hpp"
...
...
cppa/tuple_cast.hpp
View file @
58318857
...
@@ -33,15 +33,17 @@
...
@@ -33,15 +33,17 @@
#include <type_traits>
#include <type_traits>
#include "cppa/match.hpp"
#include "cppa/option.hpp"
#include "cppa/option.hpp"
#include "cppa/pattern.hpp"
#include "cppa/pattern.hpp"
#include "cppa/detail/matches.hpp"
#include "cppa/detail/tuple_cast_impl.hpp"
#include "cppa/detail/tuple_cast_impl.hpp"
namespace
cppa
{
namespace
cppa
{
// cast using a pattern
/**
* @brief Tries to cast @p tup to {@link tuple tuple<T...>}.
*/
template
<
typename
...
T
>
template
<
typename
...
T
>
auto
tuple_cast
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
auto
tuple_cast
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
->
option
<
->
option
<
...
@@ -56,7 +58,9 @@ auto tuple_cast(any_tuple const& tup, pattern<T...> const& p)
...
@@ -56,7 +58,9 @@ auto tuple_cast(any_tuple const& tup, pattern<T...> const& p)
return
detail
::
tuple_cast_impl
<
impl
,
tuple_type
,
T
...
>::
safe
(
tup
,
p
);
return
detail
::
tuple_cast_impl
<
impl
,
tuple_type
,
T
...
>::
safe
(
tup
,
p
);
}
}
// cast using types
/**
* @brief Tries to cast @p tup to {@link tuple tuple<T...>}.
*/
template
<
typename
...
T
>
template
<
typename
...
T
>
auto
tuple_cast
(
any_tuple
const
&
tup
)
auto
tuple_cast
(
any_tuple
const
&
tup
)
->
option
<
->
option
<
...
...
cppa/type_value_pair.hpp
View file @
58318857
...
@@ -105,12 +105,18 @@ class type_value_pair_const_iterator
...
@@ -105,12 +105,18 @@ class type_value_pair_const_iterator
};
};
/**
* @relates type_value_pair_const_iterator
*/
inline
bool
operator
==
(
type_value_pair_const_iterator
const
&
lhs
,
inline
bool
operator
==
(
type_value_pair_const_iterator
const
&
lhs
,
type_value_pair_const_iterator
const
&
rhs
)
type_value_pair_const_iterator
const
&
rhs
)
{
{
return
lhs
.
base
()
==
rhs
.
base
();
return
lhs
.
base
()
==
rhs
.
base
();
}
}
/**
* @relates type_value_pair_const_iterator
*/
inline
bool
operator
!=
(
type_value_pair_const_iterator
const
&
lhs
,
inline
bool
operator
!=
(
type_value_pair_const_iterator
const
&
lhs
,
type_value_pair_const_iterator
const
&
rhs
)
type_value_pair_const_iterator
const
&
rhs
)
{
{
...
...
cppa/uniform_type_info.hpp
View file @
58318857
...
@@ -263,12 +263,18 @@ class uniform_type_info
...
@@ -263,12 +263,18 @@ class uniform_type_info
};
};
/**
* @relates uniform_type_info
*/
template
<
typename
T
>
template
<
typename
T
>
inline
uniform_type_info
const
*
uniform_typeid
()
inline
uniform_type_info
const
*
uniform_typeid
()
{
{
return
uniform_typeid
(
typeid
(
T
));
return
uniform_typeid
(
typeid
(
T
));
}
}
/**
* @relates uniform_type_info
*/
inline
bool
operator
==
(
uniform_type_info
const
&
lhs
,
inline
bool
operator
==
(
uniform_type_info
const
&
lhs
,
uniform_type_info
const
&
rhs
)
uniform_type_info
const
&
rhs
)
{
{
...
@@ -277,27 +283,42 @@ inline bool operator==(uniform_type_info const& lhs,
...
@@ -277,27 +283,42 @@ inline bool operator==(uniform_type_info const& lhs,
return
&
lhs
==
&
rhs
;
return
&
lhs
==
&
rhs
;
}
}
/**
* @relates uniform_type_info
*/
inline
bool
operator
!=
(
uniform_type_info
const
&
lhs
,
inline
bool
operator
!=
(
uniform_type_info
const
&
lhs
,
uniform_type_info
const
&
rhs
)
uniform_type_info
const
&
rhs
)
{
{
return
!
(
lhs
==
rhs
);
return
!
(
lhs
==
rhs
);
}
}
/**
* @relates uniform_type_info
*/
inline
bool
operator
==
(
uniform_type_info
const
&
lhs
,
std
::
type_info
const
&
rhs
)
inline
bool
operator
==
(
uniform_type_info
const
&
lhs
,
std
::
type_info
const
&
rhs
)
{
{
return
lhs
.
equals
(
rhs
);
return
lhs
.
equals
(
rhs
);
}
}
/**
* @relates uniform_type_info
*/
inline
bool
operator
!=
(
uniform_type_info
const
&
lhs
,
std
::
type_info
const
&
rhs
)
inline
bool
operator
!=
(
uniform_type_info
const
&
lhs
,
std
::
type_info
const
&
rhs
)
{
{
return
!
(
lhs
.
equals
(
rhs
));
return
!
(
lhs
.
equals
(
rhs
));
}
}
/**
* @relates uniform_type_info
*/
inline
bool
operator
==
(
std
::
type_info
const
&
lhs
,
uniform_type_info
const
&
rhs
)
inline
bool
operator
==
(
std
::
type_info
const
&
lhs
,
uniform_type_info
const
&
rhs
)
{
{
return
rhs
.
equals
(
lhs
);
return
rhs
.
equals
(
lhs
);
}
}
/**
* @relates uniform_type_info
*/
inline
bool
operator
!=
(
std
::
type_info
const
&
lhs
,
uniform_type_info
const
&
rhs
)
inline
bool
operator
!=
(
std
::
type_info
const
&
lhs
,
uniform_type_info
const
&
rhs
)
{
{
return
!
(
rhs
.
equals
(
lhs
));
return
!
(
rhs
.
equals
(
lhs
));
...
...
cppa/util/is_iterable.hpp
View file @
58318857
...
@@ -67,7 +67,7 @@ class is_iterable
...
@@ -67,7 +67,7 @@ class is_iterable
public:
public:
static
constexpr
bool
value
=
util
::
is_primitive
<
T
>::
value
==
false
static
constexpr
bool
value
=
util
::
is_primitive
<
T
>::
value
==
false
&&
std
::
is_same
<
bool
,
result_type
>::
value
;
&&
std
::
is_same
<
bool
,
result_type
>::
value
;
};
};
...
...
cppa/util/static_foreach.hpp
View file @
58318857
...
@@ -31,6 +31,8 @@
...
@@ -31,6 +31,8 @@
#ifndef STATIC_FOREACH_HPP
#ifndef STATIC_FOREACH_HPP
#define STATIC_FOREACH_HPP
#define STATIC_FOREACH_HPP
#include "cppa/get.hpp"
namespace
cppa
{
namespace
util
{
namespace
cppa
{
namespace
util
{
/**
/**
...
...
src/converted_thread_context.cpp
View file @
58318857
...
@@ -32,8 +32,8 @@
...
@@ -32,8 +32,8 @@
#include <algorithm>
#include <algorithm>
#include "cppa/self.hpp"
#include "cppa/self.hpp"
#include "cppa/match.hpp"
#include "cppa/exception.hpp"
#include "cppa/exception.hpp"
#include "cppa/detail/matches.hpp"
#include "cppa/detail/invokable.hpp"
#include "cppa/detail/invokable.hpp"
#include "cppa/detail/intermediate.hpp"
#include "cppa/detail/intermediate.hpp"
#include "cppa/detail/converted_thread_context.hpp"
#include "cppa/detail/converted_thread_context.hpp"
...
@@ -111,7 +111,7 @@ void converted_thread_context::dequeue(behavior& rules) /*override*/
...
@@ -111,7 +111,7 @@ void converted_thread_context::dequeue(behavior& rules) /*override*/
converted_thread_context
::
throw_on_exit_result
converted_thread_context
::
throw_on_exit_result
converted_thread_context
::
throw_on_exit
(
any_tuple
const
&
msg
)
converted_thread_context
::
throw_on_exit
(
any_tuple
const
&
msg
)
{
{
if
(
match
(
msg
,
m_exit_msg_pattern
))
if
(
match
es
(
msg
,
m_exit_msg_pattern
))
{
{
auto
reason
=
msg
.
get_as
<
std
::
uint32_t
>
(
1
);
auto
reason
=
msg
.
get_as
<
std
::
uint32_t
>
(
1
);
if
(
reason
!=
exit_reason
::
normal
)
if
(
reason
!=
exit_reason
::
normal
)
...
...
unit_testing/Makefile.am
View file @
58318857
...
@@ -15,6 +15,7 @@ unit_tests_SOURCES = main.cpp \
...
@@ -15,6 +15,7 @@ unit_tests_SOURCES = main.cpp \
test__queue_performance.cpp
\
test__queue_performance.cpp
\
test__remote_actor.cpp
\
test__remote_actor.cpp
\
test__ripemd_160.cpp
\
test__ripemd_160.cpp
\
test__match.cpp
\
test__serialization.cpp
\
test__serialization.cpp
\
test__spawn.cpp
\
test__spawn.cpp
\
test__tuple.cpp
\
test__tuple.cpp
\
...
...
unit_testing/main.cpp
View file @
58318857
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
#include "cppa/cppa.hpp"
#include "cppa/cppa.hpp"
#include "cppa/tuple.hpp"
#include "cppa/tuple.hpp"
#include "cppa/match.hpp"
#include "cppa/config.hpp"
#include "cppa/config.hpp"
#include "cppa/anything.hpp"
#include "cppa/anything.hpp"
#include "cppa/detail/demangle.hpp"
#include "cppa/detail/demangle.hpp"
...
@@ -86,10 +87,9 @@ std::vector<std::string> split(std::string const& str, char delim)
...
@@ -86,10 +87,9 @@ std::vector<std::string> split(std::string const& str, char delim)
return
result
;
return
result
;
}
}
std
::
map
<
std
::
string
,
std
::
string
>
std
::
vector
<
string_pair
>
get_kv_pairs
(
int
argc
,
char
**
argv
,
int
begin
=
1
)
get_kv_pairs
(
int
argc
,
char
**
argv
,
int
begin
=
1
)
{
{
std
::
map
<
std
::
string
,
std
::
string
>
result
;
std
::
vector
<
string_pair
>
result
;
for
(
int
i
=
begin
;
i
<
argc
;
++
i
)
for
(
int
i
=
begin
;
i
<
argc
;
++
i
)
{
{
auto
vec
=
split
(
argv
[
i
],
'='
);
auto
vec
=
split
(
argv
[
i
],
'='
);
...
@@ -97,60 +97,18 @@ get_kv_pairs(int argc, char** argv, int begin = 1)
...
@@ -97,60 +97,18 @@ get_kv_pairs(int argc, char** argv, int begin = 1)
{
{
cerr
<<
"
\"
"
<<
argv
[
i
]
<<
"
\"
is not a key-value pair"
<<
endl
;
cerr
<<
"
\"
"
<<
argv
[
i
]
<<
"
\"
is not a key-value pair"
<<
endl
;
}
}
else
if
(
result
.
insert
(
std
::
make_pair
(
vec
[
0
],
vec
[
1
])).
second
==
false
)
else
if
(
std
::
any_of
(
result
.
begin
(),
result
.
end
(),
[
&
](
string_pair
const
&
p
)
{
return
p
.
first
==
vec
[
0
];
}))
{
{
cerr
<<
"key
\"
"
<<
vec
[
0
]
<<
"
\"
is already defined"
<<
endl
;
cerr
<<
"key
\"
"
<<
vec
[
0
]
<<
"
\"
is already defined"
<<
endl
;
exit
(
1
);
}
}
}
else
return
result
;
}
template
<
typename
Iterator
,
class
Container
,
typename
Key
>
inline
bool
found_key
(
Iterator
&
i
,
Container
&
cont
,
Key
&&
key
)
{
return
(
i
=
cont
.
find
(
std
::
forward
<
Key
>
(
key
)))
!=
cont
.
end
();
}
template
<
typename
F
,
typename
S
>
any_tuple
to_tuple
(
std
::
pair
<
F
,
S
>
const
&
p
)
{
return
make_tuple
(
p
.
first
,
p
.
second
);
}
struct
match_helper
{
any_tuple
tup
;
template
<
class
...
Args
>
void
operator
()(
partial_function
&&
pf
,
Args
&&
...
args
)
{
partial_function
tmp
;
tmp
.
splice
(
std
::
move
(
pf
),
std
::
forward
<
Args
>
(
args
)...);
tmp
(
tup
);
}
};
template
<
typename
F
,
typename
S
>
match_helper
match
(
std
::
pair
<
F
,
S
>
const
&
what
)
{
return
{
to_tuple
(
what
)};
}
template
<
class
Container
>
struct
match_each_helper
{
Container
const
&
args
;
template
<
typename
...
Args
>
void
operator
()(
partial_function
&&
pf
,
Args
&&
...
args
)
{
partial_function
tmp
;
tmp
.
splice
(
std
::
move
(
pf
),
std
::
forward
<
Args
>
(
args
)...);
for
(
auto
&
arg
:
args
)
{
{
tmp
(
to_tuple
(
arg
)
);
result
.
emplace_back
(
vec
[
0
],
vec
[
1
]
);
}
}
}
}
};
return
result
;
}
void
usage
(
char
const
*
argv0
)
void
usage
(
char
const
*
argv0
)
{
{
...
@@ -162,39 +120,67 @@ void usage(char const* argv0)
...
@@ -162,39 +120,67 @@ void usage(char const* argv0)
int
main
(
int
argc
,
char
**
argv
)
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)
{
cout << "matched \"" << str << "\"" << endl;
}
);
pmatch_each(argv + 1, argv + argc, [](char const* cstr) { return split(cstr, '='); })
(
on_arg_match >> [](std::string const& key, std::string const& value)
{
cout << "key = \"" << key << "\", value = \"" << value << "\""
<< endl;
}
);
return 0;
*/
auto
args
=
get_kv_pairs
(
argc
,
argv
);
auto
args
=
get_kv_pairs
(
argc
,
argv
);
for
(
auto
&
kvp
:
args
)
match_each
(
args
)
{
(
match
(
kvp
)
on
(
"run"
,
arg_match
)
>>
[
&
](
std
::
string
const
&
what
)
(
{
on
(
"run"
,
arg_match
)
>>
[
&
](
std
::
string
const
&
what
)
if
(
what
==
"remote_actor"
)
{
{
if
(
what
==
"remote_actor"
)
test__remote_actor
(
argv
[
0
],
true
,
args
);
{
exit
(
0
);
test__remote_actor
(
argv
[
0
],
true
,
args
);
}
exit
(
0
);
},
}
on
(
"scheduler"
,
arg_match
)
>>
[](
std
::
string
const
&
sched
)
},
{
on
(
"scheduler"
,
arg_match
)
>>
[](
std
::
string
const
&
sched
)
if
(
sched
==
"thread_pool_scheduler"
)
{
{
if
(
sched
==
"thread_pool_scheduler"
)
cout
<<
"using thread_pool_scheduler"
<<
endl
;
{
set_scheduler
(
new
cppa
::
detail
::
thread_pool_scheduler
);
cout
<<
"using thread_pool_scheduler"
<<
endl
;
set_scheduler
(
new
cppa
::
detail
::
thread_pool_scheduler
);
}
else
if
(
sched
==
"mock_scheduler"
)
{
cout
<<
"using mock_scheduler"
<<
endl
;
set_scheduler
(
new
cppa
::
detail
::
mock_scheduler
);
}
else
{
cerr
<<
"unknown scheduler: "
<<
sched
<<
endl
;
exit
(
1
);
}
}
}
);
else
if
(
sched
==
"mock_scheduler"
)
}
{
cout
<<
"using mock_scheduler"
<<
endl
;
set_scheduler
(
new
cppa
::
detail
::
mock_scheduler
);
}
else
{
cerr
<<
"unknown scheduler: "
<<
sched
<<
endl
;
exit
(
1
);
}
}
);
//print_node_id();
//print_node_id();
std
::
cout
<<
std
::
boolalpha
;
std
::
cout
<<
std
::
boolalpha
;
size_t
errors
=
0
;
size_t
errors
=
0
;
...
@@ -203,6 +189,7 @@ int main(int argc, char** argv)
...
@@ -203,6 +189,7 @@ int main(int argc, char** argv)
RUN_TEST
(
test__intrusive_containers
);
RUN_TEST
(
test__intrusive_containers
);
RUN_TEST
(
test__uniform_type
);
RUN_TEST
(
test__uniform_type
);
RUN_TEST
(
test__pattern
);
RUN_TEST
(
test__pattern
);
RUN_TEST
(
test__match
);
RUN_TEST
(
test__intrusive_ptr
);
RUN_TEST
(
test__intrusive_ptr
);
RUN_TEST
(
test__type_list
);
RUN_TEST
(
test__type_list
);
RUN_TEST
(
test__fixed_vector
);
RUN_TEST
(
test__fixed_vector
);
...
...
unit_testing/test.hpp
View file @
58318857
#ifndef TEST_HPP
#ifndef TEST_HPP
#define TEST_HPP
#define TEST_HPP
#include <
map
>
#include <
vector
>
#include <string>
#include <string>
#include <cstddef>
#include <cstddef>
#include <iostream>
#include <iostream>
...
@@ -88,14 +88,17 @@ std::cerr << err_msg << std::endl; \
...
@@ -88,14 +88,17 @@ std::cerr << err_msg << std::endl; \
#define CPPA_CHECK_NOT_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)))
typedef
std
::
pair
<
std
::
string
,
std
::
string
>
string_pair
;
size_t
test__yield_interface
();
size_t
test__yield_interface
();
size_t
test__remote_actor
(
c
onst
char
*
app_path
,
bool
is_client
,
size_t
test__remote_actor
(
c
har
const
*
app_path
,
bool
is_client
,
const
std
::
map
<
std
::
string
,
std
::
string
>
&
args
);
std
::
vector
<
string_pair
>
const
&
args
);
size_t
test__ripemd_160
();
size_t
test__ripemd_160
();
size_t
test__uniform_type
();
size_t
test__uniform_type
();
size_t
test__type_list
();
size_t
test__type_list
();
size_t
test__atom
();
size_t
test__atom
();
size_t
test__tuple
();
size_t
test__tuple
();
size_t
test__match
();
size_t
test__spawn
();
size_t
test__spawn
();
size_t
test__pattern
();
size_t
test__pattern
();
size_t
test__intrusive_ptr
();
size_t
test__intrusive_ptr
();
...
...
unit_testing/test__match.cpp
0 → 100644
View file @
58318857
#include "test.hpp"
#include "cppa/match.hpp"
size_t
test__match
()
{
CPPA_TEST
(
test__match
);
return
CPPA_TEST_RESULT
;
}
unit_testing/test__remote_actor.cpp
View file @
58318857
...
@@ -16,9 +16,10 @@ using namespace cppa;
...
@@ -16,9 +16,10 @@ using namespace cppa;
namespace
{
namespace
{
void
client_part
(
std
::
map
<
std
::
string
,
std
::
string
>
const
&
args
)
void
client_part
(
std
::
vector
<
string_pair
>
const
&
args
)
{
{
auto
i
=
args
.
find
(
"port"
);
auto
i
=
std
::
find_if
(
args
.
begin
(),
args
.
end
(),
[](
string_pair
const
&
p
)
{
return
p
.
first
==
"port"
;
});
if
(
i
==
args
.
end
())
if
(
i
==
args
.
end
())
{
{
throw
std
::
runtime_error
(
"no port specified"
);
throw
std
::
runtime_error
(
"no port specified"
);
...
@@ -34,7 +35,7 @@ void client_part(std::map<std::string, std::string> const& args)
...
@@ -34,7 +35,7 @@ void client_part(std::map<std::string, std::string> const& args)
}
// namespace <anonymous>
}
// namespace <anonymous>
size_t
test__remote_actor
(
char
const
*
app_path
,
bool
is_client
,
size_t
test__remote_actor
(
char
const
*
app_path
,
bool
is_client
,
std
::
map
<
std
::
string
,
std
::
string
>
const
&
args
)
std
::
vector
<
string_pair
>
const
&
args
)
{
{
if
(
is_client
)
if
(
is_client
)
{
{
...
...
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