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
3f194ef3
Commit
3f194ef3
authored
Feb 20, 2012
by
neverlord
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
maintenance
parent
f0cd281c
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
926 additions
and
580 deletions
+926
-580
Makefile.am
Makefile.am
+1
-0
cppa.files
cppa.files
+2
-2
cppa/detail/abstract_tuple.hpp
cppa/detail/abstract_tuple.hpp
+43
-1
cppa/detail/decorated_tuple.hpp
cppa/detail/decorated_tuple.hpp
+27
-19
cppa/detail/invokable.hpp
cppa/detail/invokable.hpp
+3
-3
cppa/detail/matches.hpp
cppa/detail/matches.hpp
+0
-346
cppa/detail/tuple_cast_impl.hpp
cppa/detail/tuple_cast_impl.hpp
+301
-0
cppa/detail/tuple_vals.hpp
cppa/detail/tuple_vals.hpp
+0
-5
cppa/match.hpp
cppa/match.hpp
+441
-46
cppa/tuple.hpp
cppa/tuple.hpp
+21
-13
cppa/tuple_cast.hpp
cppa/tuple_cast.hpp
+10
-109
cppa/util/fixed_vector.hpp
cppa/util/fixed_vector.hpp
+2
-11
cppa/util/type_list.hpp
cppa/util/type_list.hpp
+49
-3
src/converted_thread_context.cpp
src/converted_thread_context.cpp
+3
-2
unit_testing/test__pattern.cpp
unit_testing/test__pattern.cpp
+1
-1
unit_testing/test__tuple.cpp
unit_testing/test__tuple.cpp
+22
-19
No files found.
Makefile.am
View file @
3f194ef3
...
@@ -136,6 +136,7 @@ nobase_library_include_HEADERS = \
...
@@ -136,6 +136,7 @@ nobase_library_include_HEADERS = \
cppa/detail/tdata.hpp
\
cppa/detail/tdata.hpp
\
cppa/detail/thread_pool_scheduler.hpp
\
cppa/detail/thread_pool_scheduler.hpp
\
cppa/detail/to_uniform_name.hpp
\
cppa/detail/to_uniform_name.hpp
\
cppa/detail/tuple_cast_impl.hpp
\
cppa/detail/tuple_vals.hpp
\
cppa/detail/tuple_vals.hpp
\
cppa/detail/type_to_ptype.hpp
\
cppa/detail/type_to_ptype.hpp
\
cppa/detail/types_array.hpp
\
cppa/detail/types_array.hpp
\
...
...
cppa.files
View file @
3f194ef3
...
@@ -244,12 +244,10 @@ cppa/util/type_pair.hpp
...
@@ -244,12 +244,10 @@ cppa/util/type_pair.hpp
cppa/util/tbind.hpp
cppa/util/tbind.hpp
cppa/option.hpp
cppa/option.hpp
cppa/tuple_cast.hpp
cppa/tuple_cast.hpp
cppa/detail/matches.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
cppa/any_tuple_view.hpp
cppa/match.hpp
benchmarks/Matching.scala
benchmarks/Matching.scala
benchmarks/matching.cpp
benchmarks/matching.cpp
benchmarks/matching.erl
benchmarks/matching.erl
...
@@ -262,3 +260,5 @@ cppa/type_value_pair.hpp
...
@@ -262,3 +260,5 @@ cppa/type_value_pair.hpp
examples/dining_philosophers.cpp
examples/dining_philosophers.cpp
cppa/detail/disablable_delete.hpp
cppa/detail/disablable_delete.hpp
unit_testing/test__fixed_vector.cpp
unit_testing/test__fixed_vector.cpp
cppa/detail/tuple_cast_impl.hpp
cppa/match.hpp
cppa/detail/abstract_tuple.hpp
View file @
3f194ef3
...
@@ -101,13 +101,34 @@ struct abstract_tuple : ref_counted
...
@@ -101,13 +101,34 @@ struct abstract_tuple : ref_counted
return
{
m_tuple
,
m_pos
+
offset
};
return
{
m_tuple
,
m_pos
+
offset
};
}
}
inline
const_iterator
&
operator
+=
(
size_t
offset
)
{
m_pos
+=
offset
;
return
*
this
;
}
inline
const_iterator
operator
-
(
size_t
offset
)
{
CPPA_REQUIRE
(
m_pos
>=
offset
);
return
{
m_tuple
,
m_pos
-
offset
};
}
inline
const_iterator
&
operator
-=
(
size_t
offset
)
{
CPPA_REQUIRE
(
m_pos
>=
offset
);
m_pos
-=
offset
;
return
*
this
;
}
inline
size_t
position
()
const
{
return
m_pos
;
}
inline
size_t
position
()
const
{
return
m_pos
;
}
void
const
*
value
()
const
{
return
m_tuple
.
at
(
m_pos
);
}
void
const
*
value
()
const
{
return
m_tuple
.
at
(
m_pos
);
}
uniform_type_info
const
*
type
()
const
{
return
m_tuple
.
type_at
(
m_pos
);
}
uniform_type_info
const
*
type
()
const
{
return
m_tuple
.
type_at
(
m_pos
);
}
type_value_pair
operator
*
()
{
return
{
type
(),
value
()};
}
const_iterator
&
operator
*
()
{
return
*
this
;
}
operator
type_value_pair
()
const
{
return
{
type
(),
value
()};
}
};
};
...
@@ -117,6 +138,27 @@ struct abstract_tuple : ref_counted
...
@@ -117,6 +138,27 @@ struct abstract_tuple : ref_counted
};
};
inline
bool
full_eq
(
abstract_tuple
::
const_iterator
const
&
lhs
,
type_value_pair
const
&
rhs
)
{
return
lhs
.
type
()
==
rhs
.
first
&&
(
rhs
.
second
==
nullptr
||
lhs
.
type
()
->
equals
(
lhs
.
value
(),
rhs
.
second
));
}
inline
bool
values_only_eq
(
abstract_tuple
::
const_iterator
const
&
lhs
,
type_value_pair
const
&
rhs
)
{
return
rhs
.
second
==
nullptr
||
lhs
.
type
()
->
equals
(
lhs
.
value
(),
rhs
.
second
);
}
inline
bool
types_only_eq
(
abstract_tuple
::
const_iterator
const
&
lhs
,
type_value_pair
const
&
rhs
)
{
return
lhs
.
type
()
==
rhs
.
first
;
}
}
}
// namespace cppa::detail
}
}
// namespace cppa::detail
#endif // ABSTRACT_TUPLE_HPP
#endif // ABSTRACT_TUPLE_HPP
cppa/detail/decorated_tuple.hpp
View file @
3f194ef3
...
@@ -40,8 +40,10 @@
...
@@ -40,8 +40,10 @@
#include "cppa/uniform_type_info.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/apply_tuple.hpp"
#include "cppa/util/fixed_vector.hpp"
#include "cppa/util/fixed_vector.hpp"
#include "cppa/detail/tuple_vals.hpp"
#include "cppa/detail/abstract_tuple.hpp"
#include "cppa/detail/abstract_tuple.hpp"
#include "cppa/detail/serialize_tuple.hpp"
#include "cppa/detail/serialize_tuple.hpp"
...
@@ -71,11 +73,16 @@ class decorated_tuple : public abstract_tuple
...
@@ -71,11 +73,16 @@ class decorated_tuple : public abstract_tuple
return
{(
new
decorated_tuple
(
std
::
move
(
d
)))
->
init
()};
return
{(
new
decorated_tuple
(
std
::
move
(
d
)))
->
init
()};
}
}
// creates a subtuple form @p d with an offset
static
cow_pointer_type
create
(
cow_pointer_type
d
,
size_t
offset
)
{
return
{(
new
decorated_tuple
(
std
::
move
(
d
)))
->
init
(
offset
)};
}
virtual
void
*
mutable_at
(
size_t
pos
)
virtual
void
*
mutable_at
(
size_t
pos
)
{
{
CPPA_REQUIRE
(
pos
<
size
());
CPPA_REQUIRE
(
pos
<
size
());
// const_cast is safe because decorated_tuple is used in cow_ptrs only
return
m_decorated
->
mutable_at
(
m_mapping
[
pos
]);
return
const_cast
<
void
*>
(
m_data
[
pos
].
second
);
}
}
virtual
size_t
size
()
const
virtual
size_t
size
()
const
...
@@ -91,13 +98,13 @@ class decorated_tuple : public abstract_tuple
...
@@ -91,13 +98,13 @@ class decorated_tuple : public abstract_tuple
virtual
void
const
*
at
(
size_t
pos
)
const
virtual
void
const
*
at
(
size_t
pos
)
const
{
{
CPPA_REQUIRE
(
pos
<
size
());
CPPA_REQUIRE
(
pos
<
size
());
return
m_d
ata
[
pos
].
second
;
return
m_d
ecorated
->
at
(
m_mapping
[
pos
])
;
}
}
virtual
uniform_type_info
const
*
type_at
(
size_t
pos
)
const
virtual
uniform_type_info
const
*
type_at
(
size_t
pos
)
const
{
{
CPPA_REQUIRE
(
pos
<
size
());
CPPA_REQUIRE
(
pos
<
size
());
return
m_d
ata
[
pos
].
first
;
return
m_d
ecorated
->
type_at
(
m_mapping
[
pos
])
;
}
}
virtual
std
::
type_info
const
&
impl_type
()
const
virtual
std
::
type_info
const
&
impl_type
()
const
...
@@ -108,7 +115,7 @@ class decorated_tuple : public abstract_tuple
...
@@ -108,7 +115,7 @@ class decorated_tuple : public abstract_tuple
private:
private:
cow_pointer_type
m_decorated
;
cow_pointer_type
m_decorated
;
type_value_pair
m_data
[
sizeof
...(
ElementTypes
)]
;
vector_type
m_mapping
;
decorated_tuple
(
cow_pointer_type
const
&
d
)
:
m_decorated
(
d
)
{
}
decorated_tuple
(
cow_pointer_type
const
&
d
)
:
m_decorated
(
d
)
{
}
...
@@ -117,9 +124,8 @@ class decorated_tuple : public abstract_tuple
...
@@ -117,9 +124,8 @@ class decorated_tuple : public abstract_tuple
decorated_tuple
(
decorated_tuple
const
&
other
)
decorated_tuple
(
decorated_tuple
const
&
other
)
:
abstract_tuple
()
:
abstract_tuple
()
,
m_decorated
(
other
.
m_decorated
)
,
m_decorated
(
other
.
m_decorated
)
,
m_mapping
(
other
.
m_mapping
)
{
{
// both instances point to the same data
std
::
copy
(
other
.
begin
(),
other
.
end
(),
m_data
);
}
}
decorated_tuple
*
init
(
vector_type
const
&
v
)
decorated_tuple
*
init
(
vector_type
const
&
v
)
...
@@ -127,24 +133,26 @@ class decorated_tuple : public abstract_tuple
...
@@ -127,24 +133,26 @@ class decorated_tuple : public abstract_tuple
CPPA_REQUIRE
(
m_decorated
->
size
()
>=
sizeof
...(
ElementTypes
));
CPPA_REQUIRE
(
m_decorated
->
size
()
>=
sizeof
...(
ElementTypes
));
CPPA_REQUIRE
(
v
.
size
()
==
sizeof
...(
ElementTypes
));
CPPA_REQUIRE
(
v
.
size
()
==
sizeof
...(
ElementTypes
));
CPPA_REQUIRE
(
*
(
std
::
max_element
(
v
.
begin
(),
v
.
end
()))
<
m_decorated
->
size
());
CPPA_REQUIRE
(
*
(
std
::
max_element
(
v
.
begin
(),
v
.
end
()))
<
m_decorated
->
size
());
for
(
size_t
i
=
0
;
i
<
sizeof
...(
ElementTypes
);
++
i
)
m_mapping
.
resize
(
v
.
size
());
{
std
::
copy
(
v
.
begin
(),
v
.
end
(),
m_mapping
.
begin
());
auto
x
=
v
[
i
];
m_data
[
i
].
first
=
m_decorated
->
type_at
(
x
);
m_data
[
i
].
second
=
m_decorated
->
at
(
x
);
}
return
this
;
return
this
;
}
}
decorated_tuple
*
init
()
decorated_tuple
*
init
()
{
{
CPPA_REQUIRE
(
m_decorated
->
size
()
>=
sizeof
...(
ElementTypes
));
CPPA_REQUIRE
(
m_decorated
->
size
()
>=
sizeof
...(
ElementTypes
));
// copy first n elements
size_t
i
=
0
;
for
(
size_t
i
=
0
;
i
<
sizeof
...(
ElementTypes
);
++
i
)
m_mapping
.
resize
(
sizeof
...(
ElementTypes
));
{
std
::
generate
(
m_mapping
.
begin
(),
m_mapping
.
end
(),
[
&
](){
return
i
++
;});
m_data
[
i
].
first
=
m_decorated
->
type_at
(
i
);
return
this
;
m_data
[
i
].
second
=
m_decorated
->
at
(
i
);
}
}
decorated_tuple
*
init
(
size_t
offset
)
{
CPPA_REQUIRE
((
m_decorated
->
size
()
-
offset
)
==
sizeof
...(
ElementTypes
));
size_t
i
=
offset
;
m_mapping
.
resize
(
sizeof
...(
ElementTypes
));
std
::
generate
(
m_mapping
.
begin
(),
m_mapping
.
end
(),
[
&
](){
return
i
++
;});
return
this
;
return
this
;
}
}
...
...
cppa/detail/invokable.hpp
View file @
3f194ef3
...
@@ -35,6 +35,7 @@
...
@@ -35,6 +35,7 @@
#include <cstddef>
#include <cstddef>
#include <cstdint>
#include <cstdint>
#include "cppa/match.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/tuple_cast.hpp"
#include "cppa/tuple_cast.hpp"
#include "cppa/util/duration.hpp"
#include "cppa/util/duration.hpp"
...
@@ -42,7 +43,6 @@
...
@@ -42,7 +43,6 @@
#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
...
@@ -183,7 +183,7 @@ class invokable_impl<0, Fun, Tuple, Pattern> : public invokable
...
@@ -183,7 +183,7 @@ class invokable_impl<0, Fun, Tuple, Pattern> : public invokable
template
<
typename
T
>
template
<
typename
T
>
bool
invoke_impl
(
T
const
&
data
)
const
bool
invoke_impl
(
T
const
&
data
)
const
{
{
if
(
match
es
(
data
,
*
m_pattern
))
if
(
match
(
data
,
*
m_pattern
))
{
{
m_iimpl
.
m_fun
();
m_iimpl
.
m_fun
();
return
true
;
return
true
;
...
@@ -206,7 +206,7 @@ class invokable_impl<0, Fun, Tuple, Pattern> : public invokable
...
@@ -206,7 +206,7 @@ class invokable_impl<0, Fun, Tuple, Pattern> : public invokable
intermediate
*
get_intermediate
(
any_tuple
const
&
data
)
intermediate
*
get_intermediate
(
any_tuple
const
&
data
)
{
{
return
match
es
(
data
,
*
m_pattern
)
?
&
m_iimpl
:
nullptr
;
return
match
(
data
,
*
m_pattern
)
?
&
m_iimpl
:
nullptr
;
}
}
};
};
...
...
cppa/detail/matches.hpp
deleted
100644 → 0
View file @
f0cd281c
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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 DO_MATCH_HPP
#define DO_MATCH_HPP
#include <algorithm>
#include <type_traits>
#include "cppa/pattern.hpp"
#include "cppa/util/enable_if.hpp"
#include "cppa/util/disable_if.hpp"
#include "cppa/util/fixed_vector.hpp"
#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
{
template
<
class
MappingVector
,
typename
Iterator
>
class
push_mapping_decorator
{
Iterator
iter
;
MappingVector
&
mapping
;
size_t
commited_size
;
public:
typedef
MappingVector
mapping_vector
;
push_mapping_decorator
(
Iterator
const
&
i
,
MappingVector
&
mv
)
:
iter
(
i
),
mapping
(
mv
),
commited_size
(
0
)
{
}
push_mapping_decorator
(
push_mapping_decorator
const
&
)
=
default
;
inline
push_mapping_decorator
&
operator
++
()
{
++
iter
;
return
*
this
;
}
inline
push_mapping_decorator
&
operator
--
()
{
--
iter
;
return
*
this
;
}
inline
bool
operator
==
(
Iterator
const
&
i
)
{
return
iter
==
i
;
}
inline
bool
operator
!=
(
Iterator
const
&
i
)
{
return
iter
!=
i
;
}
inline
decltype
(
iter
.
value
())
value
()
const
{
return
iter
.
value
();
}
inline
decltype
(
iter
.
type
())
type
()
const
{
return
iter
.
type
();
}
inline
size_t
position
()
const
{
return
iter
.
position
();
}
inline
void
push_mapping
()
{
mapping
.
push_back
(
position
());
}
inline
void
commit_mapping
()
{
commited_size
=
mapping
.
size
();
}
inline
void
rollback_mapping
()
{
mapping
.
resize
(
commited_size
);
}
};
template
<
typename
Iterator
,
class
MappingVector
>
push_mapping_decorator
<
MappingVector
,
Iterator
>
pm_decorated
(
Iterator
i
,
MappingVector
&
mv
)
{
return
{
i
,
mv
};
}
template
<
typename
T
>
class
is_pm_decorated
{
template
<
class
C
>
static
bool
sfinae_fun
(
C
*
cptr
,
decltype
(
cptr
->
has_mapping
())
*
=
0
)
{
return
true
;
}
static
void
sfinae_fun
(
void
*
)
{
}
typedef
decltype
(
sfinae_fun
(
static_cast
<
T
*>
(
nullptr
)))
result_type
;
public:
static
constexpr
bool
value
=
std
::
is_same
<
bool
,
result_type
>::
value
;
};
template
<
typename
T
>
inline
typename
util
::
disable_if
<
is_pm_decorated
<
T
>
,
void
>::
type
push_mapping
(
T
&
)
{
}
template
<
typename
T
>
inline
typename
util
::
enable_if
<
is_pm_decorated
<
T
>
,
void
>::
type
push_mapping
(
T
&
iter
)
{
iter
.
push_mapping
();
}
template
<
typename
T
>
inline
typename
util
::
disable_if
<
is_pm_decorated
<
T
>
,
void
>::
type
commit_mapping
(
T
&
)
{
}
template
<
typename
T
>
inline
typename
util
::
enable_if
<
is_pm_decorated
<
T
>
,
void
>::
type
commit_mapping
(
T
&
iter
)
{
iter
.
commit_mapping
();
}
template
<
typename
T
>
inline
typename
util
::
disable_if
<
is_pm_decorated
<
T
>
,
void
>::
type
rollback_mapping
(
T
&
)
{
}
template
<
typename
T
>
inline
typename
util
::
enable_if
<
is_pm_decorated
<
T
>
,
void
>::
type
rollback_mapping
(
T
&
iter
)
{
iter
.
rollback_mapping
();
}
template
<
class
TupleBeginIterator
,
class
TupleEndIterator
,
class
PatternIterator
>
bool
matches
(
TupleBeginIterator
tbegin
,
TupleEndIterator
tend
,
PatternIterator
pbegin
,
PatternIterator
pend
)
{
while
(
!
(
pbegin
==
pend
&&
tbegin
==
tend
))
{
if
(
pbegin
==
pend
)
{
return
false
;
}
else
if
(
pbegin
.
type
()
==
nullptr
)
// nullptr == wildcard (anything)
{
// perform submatching
++
pbegin
;
if
(
pbegin
==
pend
)
{
// always true at the end of the pattern
return
true
;
}
// safe current mapping as fallback
commit_mapping
(
tbegin
);
// iterate over tu_args until we found a match
for
(;
tbegin
!=
tend
;
++
tbegin
)
{
if
(
matches
(
tbegin
,
tend
,
pbegin
,
pend
))
return
true
;
// restore mapping to fallback (delete invalid mappings)
rollback_mapping
(
tbegin
);
}
return
false
;
// no submatch found
}
// compare types
else
if
(
tbegin
!=
tend
&&
pbegin
.
type
()
==
tbegin
.
type
())
{
// compare values if needed
if
(
pbegin
.
value
()
==
nullptr
||
pbegin
.
type
()
->
equals
(
pbegin
.
value
(),
tbegin
.
value
()))
{
push_mapping
(
tbegin
);
}
else
{
return
false
;
// values didn't match
}
}
else
{
return
false
;
// no match
}
}
return
true
;
// pbegin == pend && targ.at_end()
}
// pattern does not contain "anything"
template
<
class
Tuple
,
class
Pattern
>
bool
matches
(
std
::
integral_constant
<
int
,
0
>
,
Tuple
const
&
tpl
,
Pattern
const
&
pttrn
,
util
::
fixed_vector
<
size_t
,
Pattern
::
filtered_size
>*
mv
)
{
// assertion "tpl.size() == pttrn.size()" is guaranteed from caller
typedef
typename
Pattern
::
types
ptypes
;
typedef
typename
decorated_tuple_from_type_list
<
ptypes
>::
type
dec_t
;
typedef
typename
tuple_vals_from_type_list
<
ptypes
>::
type
tv_t
;
std
::
type_info
const
&
tinfo
=
tpl
.
impl_type
();
auto
j
=
pttrn
.
begin
();
auto
end
=
tpl
.
end
();
if
(
tinfo
==
typeid
(
dec_t
)
||
tinfo
==
typeid
(
tv_t
))
{
if
(
pttrn
.
has_values
())
{
// compare values only (types are guaranteed to be equal)
for
(
auto
i
=
tpl
.
begin
();
i
!=
end
;
++
i
,
++
j
)
{
if
(
j
.
value
()
!=
nullptr
&&
i
.
type
()
->
equals
(
i
.
value
(),
j
.
value
())
==
false
)
{
return
false
;
}
}
}
}
else
if
(
tinfo
==
typeid
(
object_array
))
{
if
(
pttrn
.
has_values
())
{
// compares type and value
for
(
auto
i
=
tpl
.
begin
();
i
!=
end
;
++
i
,
++
j
)
{
if
(
i
.
type
()
!=
j
.
type
()
||
(
j
.
value
()
!=
nullptr
&&
i
.
type
()
->
equals
(
i
.
value
(),
j
.
value
())
==
false
))
{
return
false
;
}
}
}
else
{
// compares the types only
for
(
auto
i
=
tpl
.
begin
();
i
!=
end
;
++
i
,
++
j
)
{
if
(
i
.
type
()
!=
j
.
type
())
return
false
;
}
}
}
else
{
return
false
;
}
// ok => match
if
(
mv
)
for
(
size_t
i
=
0
;
i
<
Pattern
::
size
;
++
i
)
mv
->
push_back
(
i
);
return
true
;
}
// "anything" at end of pattern
template
<
class
Tuple
,
class
Pattern
>
bool
matches
(
std
::
integral_constant
<
int
,
1
>
,
Tuple
const
&
tpl
,
Pattern
const
&
pttrn
,
util
::
fixed_vector
<
size_t
,
Pattern
::
filtered_size
>*
mv
)
{
static_assert
(
Pattern
::
size
>
0
,
"empty pattern"
);
auto
end
=
pttrn
.
end
();
--
end
;
// iterate until we reach "anything"
size_t
i
=
0
;
if
(
pttrn
.
has_values
())
{
for
(
auto
iter
=
pttrn
.
begin
();
iter
!=
end
;
++
iter
,
++
i
)
{
if
(
iter
->
first
!=
tpl
.
type_at
(
i
))
return
false
;
if
(
iter
->
second
)
{
if
(
iter
->
first
->
equals
(
iter
->
second
,
tpl
.
at
(
i
))
==
false
)
return
false
;
}
}
}
else
{
for
(
auto
iter
=
pttrn
.
begin
();
iter
!=
end
;
++
iter
,
++
i
)
{
if
(
iter
->
first
!=
tpl
.
type_at
(
i
))
return
false
;
}
}
// ok => match, fill vector if needed and pattern is != <anything>
if
(
mv
)
{
// fill vector up to the position of 'anything'
size_t
end
=
Pattern
::
size
-
1
;
for
(
size_t
i
=
0
;
i
<
end
;
++
i
)
mv
->
push_back
(
i
);
}
return
true
;
}
// "anything" somewhere in between (ugh!)
template
<
class
Tuple
,
class
Pattern
>
bool
matches
(
std
::
integral_constant
<
int
,
2
>
,
Tuple
const
&
tpl
,
Pattern
const
&
ptrn
,
util
::
fixed_vector
<
size_t
,
Pattern
::
filtered_size
>*
mv
=
0
)
{
if
(
mv
)
return
matches
(
pm_decorated
(
tpl
.
begin
(),
*
mv
),
tpl
.
end
(),
ptrn
.
begin
(),
ptrn
.
end
());
return
matches
(
tpl
.
begin
(),
tpl
.
end
(),
ptrn
.
begin
(),
ptrn
.
end
());
}
template
<
class
Tuple
,
class
Pattern
>
inline
bool
matches
(
Tuple
const
&
tpl
,
Pattern
const
&
pttrn
,
util
::
fixed_vector
<
size_t
,
Pattern
::
filtered_size
>*
mv
=
0
)
{
typedef
typename
Pattern
::
types
ptypes
;
static
constexpr
int
first_anything
=
util
::
tl_find
<
ptypes
,
anything
>::
value
;
// impl0 = no anything
// impl1 = anything at end
// impl2 = anything somewhere in between
static
constexpr
int
impl
=
(
first_anything
==
-
1
)
?
0
:
((
first_anything
==
((
int
)
Pattern
::
size
)
-
1
)
?
1
:
2
);
std
::
integral_constant
<
int
,
impl
>
token
;
return
matches
(
token
,
tpl
,
pttrn
,
mv
);
}
}
}
// namespace cppa::detail
#endif // DO_MATCH_HPP
cppa/detail/tuple_cast_impl.hpp
0 → 100644
View file @
3f194ef3
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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 TUPLE_CAST_IMPL_HPP
#define TUPLE_CAST_IMPL_HPP
#include "cppa/pattern.hpp"
#include "cppa/type_value_pair.hpp"
#include "cppa/detail/tuple_vals.hpp"
#include "cppa/detail/types_array.hpp"
#include "cppa/detail/object_array.hpp"
#include "cppa/detail/abstract_tuple.hpp"
#include "cppa/detail/decorated_tuple.hpp"
namespace
cppa
{
namespace
detail
{
enum
class
tuple_cast_impl_id
{
no_wildcard
,
trailing_wildcard
,
leading_wildcard
,
wildcard_in_between
};
template
<
tuple_cast_impl_id
,
class
Result
,
typename
...
T
>
struct
tuple_cast_impl
;
template
<
class
Result
,
typename
...
T
>
struct
tuple_cast_impl
<
tuple_cast_impl_id
::
no_wildcard
,
Result
,
T
...
>
{
template
<
class
Tuple
>
inline
static
bool
types_match
(
Tuple
const
&
tup
)
{
auto
&
impl_typeid
=
tup
.
impl_type
();
if
(
impl_typeid
==
typeid
(
tuple_vals
<
T
...
>
)
||
impl_typeid
==
typeid
(
decorated_tuple
<
T
...
>
))
{
return
true
;
}
else
if
(
impl_typeid
==
typeid
(
object_array
))
{
if
(
tup
.
size
()
==
sizeof
...(
T
))
{
auto
&
tarr
=
static_types_array
<
T
...
>::
arr
;
for
(
size_t
i
=
0
;
i
<
sizeof
...(
T
);
++
i
)
{
if
(
tarr
[
i
]
!=
tup
.
type_at
(
i
))
return
false
;
}
return
true
;
}
}
return
false
;
}
template
<
class
Tuple
>
static
option
<
Result
>
_
(
Tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
if
(
types_match
(
tup
))
{
if
(
p
.
has_values
()
==
false
||
std
::
equal
(
tup
.
begin
(),
tup
.
end
(),
p
.
begin
(),
values_only_eq
))
{
return
{
Result
::
from
(
tup
.
vals
())};
}
}
return
{};
}
template
<
class
Tuple
>
static
option
<
Result
>
_
(
Tuple
const
&
tup
)
{
if
(
types_match
(
tup
))
{
return
{
Result
::
from
(
tup
.
vals
())};
}
return
{};
}
};
template
<
class
Result
,
typename
...
T
>
struct
tuple_cast_impl
<
tuple_cast_impl_id
::
trailing_wildcard
,
Result
,
T
...
>
{
static_assert
(
sizeof
...(
T
)
>
1
,
"tuple_cast<anything> (empty result)"
);
template
<
class
Tuple
>
inline
static
option
<
Result
>
_
(
Tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
if
(
tup
.
size
()
>=
(
sizeof
...(
T
)
-
1
))
{
// skip last element (wildcard)
auto
end
=
tup
.
end
();
--
end
;
if
(
std
::
equal
(
tup
.
begin
(),
end
,
p
.
begin
(),
(
p
.
has_values
()
?
full_eq
:
types_only_eq
)))
{
return
{
Result
::
subtuple
(
tup
.
vals
())};
}
}
return
{};
}
template
<
class
Tuple
>
static
option
<
Result
>
_
(
Tuple
const
&
tup
)
{
if
(
tup
.
size
()
>=
(
sizeof
...(
T
)
-
1
))
{
auto
&
tarr
=
static_types_array
<
T
...
>::
arr
;
for
(
size_t
i
=
0
;
i
<
(
sizeof
...(
T
)
-
1
);
++
i
)
{
if
(
tarr
[
i
]
!=
tup
.
type_at
(
i
))
return
{
};
}
return
{
Result
::
subtuple
(
tup
.
vals
())};
}
return
{};
}
};
template
<
class
Result
,
typename
...
T
>
struct
tuple_cast_impl
<
tuple_cast_impl_id
::
leading_wildcard
,
Result
,
T
...
>
{
static_assert
(
sizeof
...(
T
)
>
1
,
"tuple_cast<anything> (empty result)"
);
template
<
class
Tuple
>
inline
static
option
<
Result
>
_
(
Tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
if
(
tup
.
size
()
>=
(
sizeof
...(
T
)
-
1
))
{
size_t
offset
=
tup
.
size
()
-
(
sizeof
...(
T
)
-
1
);
// skip first elements in tuple
auto
begin
=
tup
.
begin
();
begin
+=
offset
;
// skip first element (wildcard) of pattern
auto
pbegin
=
p
.
begin
();
++
pbegin
;
if
(
std
::
equal
(
begin
,
tup
.
end
(),
pbegin
,
(
p
.
has_values
()
?
full_eq
:
types_only_eq
)))
{
return
{
Result
::
offset_subtuple
(
tup
.
vals
(),
offset
)};
}
}
return
{};
}
template
<
class
Tuple
>
static
option
<
Result
>
_
(
Tuple
const
&
tup
)
{
if
(
tup
.
size
()
>=
(
sizeof
...(
T
)
-
1
))
{
size_t
offset
=
tup
.
size
()
-
(
sizeof
...(
T
)
-
1
);
auto
&
tarr
=
static_types_array
<
T
...
>::
arr
;
for
(
size_t
i
=
offset
,
j
=
1
;
i
<
tup
.
size
();
++
i
,
++
j
)
{
if
(
tarr
[
j
]
!=
tup
.
type_at
(
i
))
return
{
};
}
return
{
Result
::
offset_subtuple
(
tup
.
vals
(),
offset
)};
}
return
{};
}
};
template
<
class
Result
,
typename
...
T
>
struct
tuple_cast_impl
<
tuple_cast_impl_id
::
wildcard_in_between
,
Result
,
T
...
>
{
static_assert
(
sizeof
...(
T
)
>
1
,
"tuple_cast<anything> (empty result)"
);
typedef
util
::
type_list
<
T
...
>
types
;
typedef
typename
util
::
tl_filter_not
<
types
,
util
::
tbind
<
std
::
is_same
,
anything
>::
type
>::
type
filtered_types
;
// mapping vector type
static
constexpr
size_t
filtered_size
=
filtered_types
::
size
;
typedef
util
::
fixed_vector
<
size_t
,
filtered_types
::
size
>
mapping_vector
;
// iterator types
typedef
type_value_pair_const_iterator
pattern_iterator
;
typedef
abstract_tuple
::
const_iterator
const_iterator
;
inline
static
bool
matches
(
mapping_vector
&
mv
,
const_iterator
tbegin
,
const_iterator
tend
,
pattern_iterator
pbegin
,
pattern_iterator
pend
)
{
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
;
if
(
pbegin
==
pend
)
{
// always true at the end of the pattern
return
true
;
}
// safe current mapping as fallback
auto
s
=
mv
.
size
();
// iterate over tuple values until we found a match
for
(;
tbegin
!=
tend
;
++
tbegin
)
{
if
(
matches
(
mv
,
tbegin
,
tend
,
pbegin
,
pend
))
return
true
;
// restore mapping to fallback (delete invalid mappings)
mv
.
resize
(
s
);
}
return
false
;
// no submatch found
}
else
if
(
full_eq
(
tbegin
,
*
pbegin
))
{
mv
.
push_back
(
tbegin
.
position
());
}
else
{
return
false
;
// no match
}
// next iteration
++
tbegin
;
++
pbegin
;
}
return
true
;
// pbegin == pend && tbegin == tend
}
template
<
class
Tuple
>
inline
static
option
<
Result
>
_
(
Tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
{
util
::
fixed_vector
<
size_t
,
Result
::
num_elements
>
mv
;
if
(
matches
(
mv
,
tup
.
begin
(),
tup
.
end
(),
p
.
begin
(),
p
.
end
()))
{
return
{
Result
::
from
(
tup
.
vals
(),
mv
)};
}
return
{};
}
template
<
class
Tuple
>
static
option
<
Result
>
_
(
Tuple
const
&
tup
)
{
util
::
fixed_vector
<
size_t
,
Result
::
num_elements
>
mv
;
auto
&
tarr
=
static_types_array
<
T
...
>::
arr
;
if
(
matches
(
mv
,
tup
.
begin
(),
tup
.
end
(),
tarr
.
begin
(),
tarr
.
end
()))
{
return
{
Result
::
from
(
tup
.
vals
(),
mv
)};
}
return
{};
}
};
template
<
typename
...
T
>
struct
select_tuple_cast_impl
{
typedef
util
::
type_list
<
T
...
>
types
;
typedef
util
::
tl_find
<
types
,
anything
>
result1
;
typedef
typename
result1
::
rest_list
rest_list
;
static
constexpr
int
wc1
=
result1
::
value
;
static
constexpr
int
wc2
=
(
wc1
<
0
)
?
-
1
:
(
util
::
tl_find
<
rest_list
,
anything
>::
value
+
wc1
+
1
);
static
constexpr
tuple_cast_impl_id
value
=
(
wc1
==
-
1
)
?
tuple_cast_impl_id
::
no_wildcard
:
((
wc1
==
0
&&
wc2
==
-
1
)
?
tuple_cast_impl_id
::
leading_wildcard
:
((
wc1
==
(
sizeof
...(
T
)
-
1
)
&&
wc2
==
-
1
)
?
tuple_cast_impl_id
::
trailing_wildcard
:
tuple_cast_impl_id
::
wildcard_in_between
));
};
}
}
#endif // TUPLE_CAST_IMPL_HPP
cppa/detail/tuple_vals.hpp
View file @
3f194ef3
...
@@ -74,11 +74,6 @@ class tuple_vals : public abstract_tuple
...
@@ -74,11 +74,6 @@ class tuple_vals : public abstract_tuple
return
m_data
;
return
m_data
;
}
}
inline
data_type
&
data_ref
()
{
return
m_data
;
}
size_t
size
()
const
size_t
size
()
const
{
{
return
sizeof
...(
ElementTypes
);
return
sizeof
...(
ElementTypes
);
...
...
cppa/match.hpp
View file @
3f194ef3
...
@@ -28,68 +28,463 @@
...
@@ -28,68 +28,463 @@
\******************************************************************************/
\******************************************************************************/
#ifndef MATCH_HPP
#ifndef MATCH
ES
_HPP
#define MATCH_HPP
#define MATCH
ES
_HPP
#include <type_traits>
#include <type_traits>
#include "cppa/tuple.hpp"
#include "cppa/pattern.hpp"
#include "cppa/invoke_rules.hpp"
#include "cppa/anything.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/util/tbind.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/
util/if_else
.hpp"
#include "cppa/
detail/tuple_vals
.hpp"
#include "cppa/
util/enable_if
.hpp"
#include "cppa/
detail/types_array
.hpp"
#include "cppa/detail/object_array.hpp"
#include "cppa/detail/
implicit_conversions
.hpp"
#include "cppa/detail/
decorated_tuple
.hpp"
namespace
cppa
{
namespace
cppa
{
enum
class
pattern_characteristic
{
no_wildcard
,
trailing_wildcard
,
leading_wildcard
,
wildcard_in_between
,
multiple_wildcards
};
template
<
typename
Types
>
constexpr
pattern_characteristic
get_pattern_characteristic
()
{
return
util
::
tl_exists
<
Types
,
util
::
tbind
<
std
::
is_same
,
anything
>::
type
>::
value
?
((
util
::
tl_count
<
Types
,
util
::
tbind
<
std
::
is_same
,
anything
>::
type
>::
value
==
1
)
?
(
std
::
is_same
<
typename
Types
::
head
,
anything
>::
value
?
pattern_characteristic
::
leading_wildcard
:
(
std
::
is_same
<
typename
Types
::
back
,
anything
>::
value
?
pattern_characteristic
::
trailing_wildcard
:
pattern_characteristic
::
wildcard_in_between
))
:
pattern_characteristic
::
multiple_wildcards
)
:
pattern_characteristic
::
no_wildcard
;
}
namespace
detail
{
namespace
detail
{
template
<
pattern_characteristic
,
typename
...
>
struct
matcher
;
}
// namespace cppa
template
<
typename
Tuple
>
template
<
pattern_characteristic
PC
,
typename
...
Ts
>
struct
match_
helper
struct
match_
impl
{
{
//static constexpr bool is_view = std::is_same<Tuple, any_tuple_view>::value;
static
inline
bool
_
(
any_tuple
const
&
tup
)
static
constexpr
bool
is_view
=
false
;
{
Tuple
what
;
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
)
;
template
<
typename
T
>
}
match_helper
(
T
const
&
w
,
typename
util
::
enable_if_c
<
std
::
is_same
<
T
,
T
>::
value
&&
is_view
>::
type
*
=
0
)
template
<
size_t
Size
>
:
what
(
w
)
{
}
static
inline
bool
_
(
any_tuple
const
&
tup
,
util
::
fixed_vector
<
size_t
,
Size
>&
mv
)
//template<typename T>
{
//match_helper(T const& w, typename util::enable_if_c<std::is_same<T, T>::value && !is_view>::type* =0)
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
,
mv
);
// : what(make_tuple(w)) {
}
}
void
operator
()(
invoke_rules
&
rules
)
{
rules
(
what
);
}
static
inline
bool
_
(
any_tuple
const
&
tup
,
void
operator
()(
invoke_rules
&&
rules
)
{
rules
(
what
);
}
pattern
<
Ts
...
>
const
&
p
)
template
<
typename
Head
,
typename
...
Tail
>
{
void
operator
()(
invoke_rules
&&
bhvr
,
Head
&&
head
,
Tail
&&
...
tail
)
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
)
{
&&
(
p
.
has_values
()
==
false
invoke_rules
tmp
(
std
::
move
(
bhvr
));
||
detail
::
matcher
<
PC
,
Ts
...
>::
vmatch
(
tup
,
p
));
(
*
this
)(
tmp
.
splice
(
std
::
forward
<
Head
>
(
head
)),
}
std
::
forward
<
Tail
>
(
tail
)...);
static
inline
bool
_
(
any_tuple
const
&
tup
,
}
pattern
<
Ts
...
>
const
&
p
,
template
<
typename
Head
,
typename
...
Tail
>
typename
pattern
<
Ts
...
>::
mapping_vector
&
mv
)
void
operator
()(
invoke_rules
&
bhvr
,
Head
&&
head
,
Tail
&&
...
tail
)
{
{
return
detail
::
matcher
<
PC
,
Ts
...
>::
tmatch
(
tup
,
mv
)
(
*
this
)(
bhvr
.
splice
(
std
::
forward
<
Head
>
(
head
)),
&&
(
p
.
has_values
()
==
false
std
::
forward
<
Tail
>
(
tail
)...
);
||
detail
::
matcher
<
PC
,
Ts
...
>::
vmatch
(
tup
,
p
)
);
}
}
};
};
}
// namespace detail
template
<
typename
...
Ts
>
struct
match_impl
<
pattern_characteristic
::
multiple_wildcards
,
Ts
...
>
{
static
constexpr
auto
PC
=
pattern_characteristic
::
multiple_wildcards
;
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
);
}
};
/*
template
<
typename
...
Ts
>
template<typename T>
inline
bool
match
(
any_tuple
const
&
tup
)
auto match(T const& x)
-> detail::match_helper<
typename util::if_else<
std::is_same<typename detail::implicit_conversions<T>::type, T>,
any_tuple_view,
util::wrapped<any_tuple> >::type>
{
{
return {x};
typedef
util
::
type_list
<
Ts
...
>
tl
;
return
match_impl
<
get_pattern_characteristic
<
tl
>
(),
Ts
...
>::
_
(
tup
);
}
}
*/
template
<
typename
...
Ts
>
inline
bool
match
(
any_tuple
const
&
tup
,
util
::
fixed_vector
<
size_t
,
util
::
tl_count_not
<
util
::
type_list
<
Ts
...
>
,
util
::
tbind
<
std
::
is_same
,
anything
>::
type
>::
value
>&
mv
)
{
typedef
util
::
type_list
<
Ts
...
>
tl
;
return
match_impl
<
get_pattern_characteristic
<
tl
>
(),
Ts
...
>::
_
(
tup
,
mv
);
}
template
<
typename
...
Ts
>
inline
bool
match
(
any_tuple
const
&
tup
,
pattern
<
Ts
...
>
const
&
ptrn
)
{
typedef
util
::
type_list
<
Ts
...
>
tl
;
return
match_impl
<
get_pattern_characteristic
<
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_pattern_characteristic
<
tl
>
(),
Ts
...
>::
_
(
tup
,
ptrn
,
mv
);
}
/******************************************************************************\
** implementation details **
\******************************************************************************/
namespace
detail
{
template
<
typename
...
T
>
struct
matcher
<
pattern_characteristic
::
no_wildcard
,
T
...
>
{
static
inline
bool
tmatch
(
any_tuple
const
&
tup
)
{
auto
&
impl_typeid
=
tup
.
impl_type
();
if
(
impl_typeid
==
typeid
(
tuple_vals
<
T
...
>
)
||
impl_typeid
==
typeid
(
decorated_tuple
<
T
...
>
))
{
return
true
;
}
else
if
(
impl_typeid
==
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
))
{
size_t
i
=
0
;
mv
.
resize
(
sizeof
...(
T
));
std
::
generate
(
mv
.
begin
(),
mv
.
end
(),
[
&
]()
{
return
i
++
;
});
return
true
;
}
return
false
;
}
static
inline
bool
vmatch
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
ptrn
)
{
return
std
::
equal
(
tup
.
begin
(),
tup
.
end
(),
ptrn
.
begin
(),
detail
::
values_only_eq
);
}
};
template
<
typename
...
T
>
struct
matcher
<
pattern_characteristic
::
trailing_wildcard
,
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
))
{
size_t
i
=
0
;
mv
.
resize
(
size
);
std
::
generate
(
mv
.
begin
(),
mv
.
end
(),
[
&
]()
{
return
i
++
;
});
return
true
;
}
return
false
;
}
static
inline
bool
vmatch
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
ptrn
)
{
auto
begin
=
tup
.
begin
();
return
std
::
equal
(
begin
,
begin
+
size
,
ptrn
.
begin
(),
detail
::
values_only_eq
);
}
};
template
<
>
struct
matcher
<
pattern_characteristic
::
leading_wildcard
,
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
<
pattern_characteristic
::
leading_wildcard
,
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
(),
detail
::
types_only_eq
);
}
return
false
;
}
static
inline
bool
tmatch
(
any_tuple
const
&
tup
,
util
::
fixed_vector
<
size_t
,
size
>&
mv
)
{
if
(
tmatch
(
tup
))
{
size_t
i
=
tup
.
size
()
-
size
;
mv
.
resize
(
size
);
std
::
generate
(
mv
.
begin
(),
mv
.
end
(),
[
&
]()
{
return
i
++
;
});
return
true
;
}
return
false
;
}
static
inline
bool
vmatch
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
ptrn
)
{
auto
begin
=
tup
.
begin
();
begin
+=
(
tup
.
size
()
-
size
);
return
std
::
equal
(
begin
,
tup
.
end
(),
ptrn
.
begin
()
+
1
,
detail
::
values_only_eq
);
}
};
template
<
typename
...
T
>
struct
matcher
<
pattern_characteristic
::
wildcard_in_between
,
T
...
>
{
static
constexpr
int
signed_wc_pos
=
util
::
tl_find
<
util
::
type_list
<
T
...
>
,
anything
>::
value
;
static_assert
(
signed_wc_pos
!=
-
1
&&
signed_wc_pos
!=
0
&&
signed_wc_pos
!=
(
sizeof
...(
T
)
-
1
),
"illegal wildcard position"
);
static
constexpr
size_t
wc_pos
=
static_cast
<
size_t
>
(
signed_wc_pos
);
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
;
// 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
>&
mv
)
{
if
(
tmatch
(
tup
))
{
// first range
size_t
i
=
0
;
mv
.
resize
(
size
);
auto
begin
=
mv
.
begin
();
std
::
generate
(
begin
,
begin
+
wc_pos
,
[
&
]()
{
return
i
++
;
});
// second range
i
=
tup
.
size
()
-
(
size
-
(
wc_pos
+
1
));
begin
=
mv
.
begin
()
+
wc_pos
;
std
::
generate
(
begin
,
mv
.
end
(),
[
&
]()
{
return
i
++
;
});
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
<
pattern_characteristic
::
multiple_wildcards
,
T
...
>
{
static
constexpr
size_t
wc_count
=
util
::
tl_count
<
util
::
type_list
<
T
...
>
,
util
::
tbind
<
std
::
is_same
,
anything
>::
type
>::
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_HPP
#endif // MATCH
ES
_HPP
cppa/tuple.hpp
View file @
3f194ef3
...
@@ -119,26 +119,34 @@ class tuple
...
@@ -119,26 +119,34 @@ class tuple
tuple
&
operator
=
(
tuple
&&
)
=
default
;
tuple
&
operator
=
(
tuple
&&
)
=
default
;
tuple
&
operator
=
(
tuple
const
&
)
=
default
;
tuple
&
operator
=
(
tuple
const
&
)
=
default
;
static
tuple
from
(
cow_ptr_type
ptr
)
inline
static
tuple
from
(
cow_ptr_type
ptr
)
{
{
if
(
ptr
->
size
()
==
sizeof
...(
ElementTypes
))
return
{
priv_ctor
(),
std
::
move
(
ptr
)};
{
// *this == *ptr
return
{
priv_ctor
(),
std
::
move
(
ptr
)};
}
else
{
// *this is a subtuple of *ptr
return
{
priv_ctor
(),
decorated_type
::
create
(
std
::
move
(
ptr
))};
}
}
}
static
tuple
from
(
cow_ptr_type
ptr
,
inline
static
tuple
from
(
cow_ptr_type
ptr
,
util
::
fixed_vector
<
size_t
,
num_elements
>
const
&
mv
)
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
)};
}
}
// *this is a [0, N) subtuple
inline
static
tuple
subtuple
(
cow_ptr_type
ptr
)
{
// N == ptr->size() ?
if
(
ptr
->
size
()
==
num_elements
)
return
from
(
std
::
move
(
ptr
));
// no, create subtuple
return
{
priv_ctor
(),
decorated_type
::
create
(
std
::
move
(
ptr
))};
}
inline
static
tuple
offset_subtuple
(
cow_ptr_type
ptr
,
size_t
offset
)
{
// N == ptr->size() ?
if
(
ptr
->
size
()
==
num_elements
)
return
from
(
std
::
move
(
ptr
));
// no, create subtuple
return
{
priv_ctor
(),
decorated_type
::
create
(
std
::
move
(
ptr
),
offset
)};
}
/**
/**
* @brief Gets the size of this tuple.
* @brief Gets the size of this tuple.
*/
*/
...
...
cppa/tuple_cast.hpp
View file @
3f194ef3
...
@@ -35,93 +35,23 @@
...
@@ -35,93 +35,23 @@
#include "cppa/option.hpp"
#include "cppa/option.hpp"
#include "cppa/pattern.hpp"
#include "cppa/pattern.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/detail/matches.hpp"
#include "cppa/detail/types_array.hpp"
#include "cppa/detail/decorated_tuple.hpp"
#include "cppa/detail/implicit_conversions.hpp"
namespace
cppa
{
#include "cppa/detail/tuple_cast_impl.hpp"
// cast using a pattern
namespace
cppa
{
template
<
class
ResultTuple
,
class
Tuple
,
typename
...
P
>
option
<
ResultTuple
>
tuple_cast_impl
(
Tuple
const
&
tup
,
pattern
<
P
...
>
const
&
p
)
{
typedef
util
::
type_list
<
P
...
>
types
;
static
constexpr
int
apos
=
util
::
tl_find
<
types
,
anything
>::
value
;
// no anything in given template parameter pack
// or anything at end of template parameter pack
if
(
apos
==
-
1
||
apos
==
(
sizeof
...(
P
)
-
1
))
{
if
(
detail
::
matches
(
tup
,
p
))
{
return
{
ResultTuple
::
from
(
tup
.
vals
())};
}
}
else
{
typename
pattern
<
P
...
>::
mapping_vector
mv
;
if
(
detail
::
matches
(
tup
,
p
,
&
mv
))
{
if
(
mv
.
size
()
==
tup
.
size
())
// perfect match
{
return
{
ResultTuple
::
from
(
tup
.
vals
())};
}
else
{
return
{
ResultTuple
::
from
(
tup
.
vals
(),
mv
)};
}
}
}
return
{
};
}
// cast using types
template
<
class
ResultTuple
,
class
Tuple
,
typename
...
T
>
option
<
ResultTuple
>
tuple_cast_impl
(
Tuple
const
&
tup
)
{
typedef
util
::
type_list
<
T
...
>
types
;
static
constexpr
int
apos
=
util
::
tl_find
<
types
,
anything
>::
value
;
// no anything in given template parameter pack
// or anything at end of template parameter pack
if
(
apos
==
-
1
||
apos
==
(
sizeof
...(
T
)
-
1
))
{
if
(
tup
.
size
()
>=
sizeof
...(
T
))
{
auto
&
tarr
=
detail
::
static_types_array
<
T
...
>::
arr
;
static
constexpr
int
end
=
(
apos
==
-
1
)
?
sizeof
...(
T
)
:
apos
;
for
(
int
i
=
0
;
i
<
end
;
++
i
)
{
if
(
tarr
[
i
]
!=
tup
.
type_at
(
i
))
return
{
};
}
// always a perfect match or subtuple
return
{
ResultTuple
::
from
(
tup
.
vals
())};
}
}
else
{
util
::
fixed_vector
<
size_t
,
ResultTuple
::
num_elements
>
mv
;
if
(
detail
::
matches
(
tup
,
detail
::
static_types_array
<
T
...
>::
arr
,
&
mv
))
{
// never a perfect match
return
{
ResultTuple
::
from
(
tup
.
vals
(),
mv
)};
}
}
return
{
};
}
// cast using a pattern
// cast using a pattern
template
<
typename
...
P
>
template
<
typename
...
T
>
auto
tuple_cast
(
any_tuple
const
&
tup
,
pattern
<
P
...
>
const
&
p
)
auto
tuple_cast
(
any_tuple
const
&
tup
,
pattern
<
T
...
>
const
&
p
)
->
option
<
->
option
<
typename
tuple_from_type_list
<
typename
tuple_from_type_list
<
typename
pattern
<
P
...
>::
filtered_types
typename
pattern
<
T
...
>::
filtered_types
>::
type
>
>::
type
>
{
{
typedef
typename
pattern
<
P
...
>::
filtered_types
filtered_types
;
typedef
typename
pattern
<
T
...
>::
filtered_types
filtered_types
;
typedef
typename
tuple_from_type_list
<
filtered_types
>::
type
tuple_type
;
typedef
typename
tuple_from_type_list
<
filtered_types
>::
type
tuple_type
;
return
tuple_cast_impl
<
tuple_type
,
any_tuple
,
P
...
>
(
tup
,
p
);
static
constexpr
auto
impl
=
detail
::
select_tuple_cast_impl
<
T
...
>::
value
;
return
detail
::
tuple_cast_impl
<
impl
,
tuple_type
,
T
...
>::
_
(
tup
,
p
);
}
}
// cast using types
// cast using types
...
@@ -137,38 +67,9 @@ auto tuple_cast(any_tuple const& tup)
...
@@ -137,38 +67,9 @@ auto tuple_cast(any_tuple const& tup)
{
{
typedef
decltype
(
tuple_cast
<
T
...
>
(
tup
))
result_type
;
typedef
decltype
(
tuple_cast
<
T
...
>
(
tup
))
result_type
;
typedef
typename
result_type
::
value_type
tuple_type
;
typedef
typename
result_type
::
value_type
tuple_type
;
return
tuple_cast_impl
<
tuple_type
,
any_tuple
,
T
...
>
(
tup
);
static
constexpr
auto
impl
=
detail
::
select_tuple_cast_impl
<
T
...
>::
value
;
}
return
detail
::
tuple_cast_impl
<
impl
,
tuple_type
,
T
...
>::
_
(
tup
);
/*
template<typename... P>
auto tuple_cast(any_tuple_view const& tup, pattern<P...> const& p)
-> option<
typename tuple_view_from_type_list<
typename pattern<P...>::filtered_types
>::type>
{
typedef typename pattern<P...>::filtered_types filtered_types;
typedef typename tuple_view_from_type_list<filtered_types>::type tuple_type;
return tuple_cast_impl<tuple_type, any_tuple_view, P...>(tup, p);
}
// cast using types
template<typename... T>
auto tuple_cast(any_tuple_view const& tup)
-> option<
typename tuple_view_from_type_list<
typename util::tl_filter_not<
util::type_list<T...>,
util::tbind<std::is_same, anything>::type
>::type
>::type>
{
typedef decltype(tuple_cast<T...>(tup)) result_type;
typedef typename result_type::value_type tuple_type;
return tuple_cast_impl<tuple_type, any_tuple_view, T...>(tup);
}
}
*/
}
// namespace cppa
}
// namespace cppa
...
...
cppa/util/fixed_vector.hpp
View file @
3f194ef3
...
@@ -84,17 +84,8 @@ class fixed_vector
...
@@ -84,17 +84,8 @@ class fixed_vector
void
resize
(
size_type
s
)
void
resize
(
size_type
s
)
{
{
CPPA_REQUIRE
(
s
<
MaxSize
);
CPPA_REQUIRE
(
s
<=
MaxSize
);
if
(
s
>
m_size
)
m_size
=
s
;
{
auto
x
=
T
();
auto
old_size
=
m_size
;
for
(
auto
i
=
old_size
;
i
<
s
;
++
i
)
push_back
(
x
);
}
else
{
m_size
=
s
;
}
}
}
fixed_vector
(
std
::
initializer_list
<
T
>
init
)
:
m_size
(
init
.
size
())
fixed_vector
(
std
::
initializer_list
<
T
>
init
)
:
m_size
(
init
.
size
())
...
...
cppa/util/type_list.hpp
View file @
3f194ef3
...
@@ -135,14 +135,21 @@ template<typename What, int Pos>
...
@@ -135,14 +135,21 @@ template<typename What, int Pos>
struct
tl_find
<
type_list
<>
,
What
,
Pos
>
struct
tl_find
<
type_list
<>
,
What
,
Pos
>
{
{
static
constexpr
int
value
=
-
1
;
static
constexpr
int
value
=
-
1
;
typedef
type_list
<>
rest_list
;
};
template
<
typename
What
,
int
Pos
,
typename
...
Tail
>
struct
tl_find
<
type_list
<
What
,
Tail
...
>
,
What
,
Pos
>
{
static
constexpr
int
value
=
Pos
;
typedef
type_list
<
Tail
...
>
rest_list
;
};
};
template
<
typename
What
,
int
Pos
,
typename
Head
,
typename
...
Tail
>
template
<
typename
What
,
int
Pos
,
typename
Head
,
typename
...
Tail
>
struct
tl_find
<
type_list
<
Head
,
Tail
...
>
,
What
,
Pos
>
struct
tl_find
<
type_list
<
Head
,
Tail
...
>
,
What
,
Pos
>
{
{
static
constexpr
int
value
=
std
::
is_same
<
Head
,
What
>::
value
static
constexpr
int
value
=
tl_find
<
type_list
<
Tail
...
>
,
What
,
Pos
+
1
>::
value
;
?
Pos
typedef
typename
tl_find
<
type_list
<
Tail
...
>
,
What
,
Pos
+
1
>::
rest_list
rest_list
;
:
tl_find
<
type_list
<
Tail
...
>
,
What
,
Pos
+
1
>::
value
;
};
};
// list list::first_n(size_t)
// list list::first_n(size_t)
...
@@ -209,6 +216,45 @@ struct tl_exists<type_list<>, Predicate>
...
@@ -209,6 +216,45 @@ struct tl_exists<type_list<>, Predicate>
static
constexpr
bool
value
=
false
;
static
constexpr
bool
value
=
false
;
};
};
// size_t list::count(predicate)
/**
* @brief Counts the number of elements in the list which satisfy a predicate.
*/
template
<
class
List
,
template
<
typename
>
class
Predicate
>
struct
tl_count
{
static
constexpr
size_t
value
=
(
Predicate
<
typename
List
::
head
>::
value
?
1
:
0
)
+
tl_count
<
typename
List
::
tail
,
Predicate
>::
value
;
};
template
<
template
<
typename
>
class
Predicate
>
struct
tl_count
<
type_list
<>
,
Predicate
>
{
static
constexpr
size_t
value
=
0
;
};
// size_t list::count_not(predicate)
/**
* @brief Counts the number of elements in the list which satisfy a predicate.
*/
template
<
class
List
,
template
<
typename
>
class
Predicate
>
struct
tl_count_not
{
static
constexpr
size_t
value
=
(
Predicate
<
typename
List
::
head
>::
value
?
0
:
1
)
+
tl_count_not
<
typename
List
::
tail
,
Predicate
>::
value
;
};
template
<
template
<
typename
>
class
Predicate
>
struct
tl_count_not
<
type_list
<>
,
Predicate
>
{
static
constexpr
size_t
value
=
0
;
};
// bool list::zipped_forall(predicate)
// bool list::zipped_forall(predicate)
/**
/**
...
...
src/converted_thread_context.cpp
View file @
3f194ef3
...
@@ -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"
...
@@ -100,10 +100,11 @@ void converted_thread_context::dequeue(timed_invoke_rules& rules) /*override*/
...
@@ -100,10 +100,11 @@ void converted_thread_context::dequeue(timed_invoke_rules& rules) /*override*/
}
}
while
(
dq
(
node
,
rules
,
buffer
)
==
false
);
while
(
dq
(
node
,
rules
,
buffer
)
==
false
);
}
}
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
es
(
msg
,
m_exit_msg_pattern
))
if
(
match
(
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/test__pattern.cpp
View file @
3f194ef3
...
@@ -5,8 +5,8 @@
...
@@ -5,8 +5,8 @@
#include "cppa/on.hpp"
#include "cppa/on.hpp"
#include "cppa/atom.hpp"
#include "cppa/atom.hpp"
#include "cppa/tuple.hpp"
#include "cppa/match.hpp"
#include "cppa/match.hpp"
#include "cppa/tuple.hpp"
#include "cppa/option.hpp"
#include "cppa/option.hpp"
#include "cppa/pattern.hpp"
#include "cppa/pattern.hpp"
#include "cppa/announce.hpp"
#include "cppa/announce.hpp"
...
...
unit_testing/test__tuple.cpp
View file @
3f194ef3
...
@@ -39,30 +39,14 @@ size_t test__tuple()
...
@@ -39,30 +39,14 @@ size_t test__tuple()
CPPA_CHECK
((
std
::
is_same
<
decltype
(
t0_1
),
int
>::
value
));
CPPA_CHECK
((
std
::
is_same
<
decltype
(
t0_1
),
int
>::
value
));
CPPA_CHECK_EQUAL
(
t0_0
,
"1"
);
CPPA_CHECK_EQUAL
(
t0_0
,
"1"
);
CPPA_CHECK_EQUAL
(
t0_1
,
2
);
CPPA_CHECK_EQUAL
(
t0_1
,
2
);
// get a view of t0
any_tuple
atup0
(
t0
);
CPPA_CHECK
(
atup0
.
size
()
==
2
&&
atup0
.
at
(
0
)
==
&
get
<
0
>
(
t0
));
/*
auto v1opt = tuple_cast<std::string, anything>(any_tuple_view(atup0));
// the tuple_view forces atup0 to detach from t0
CPPA_CHECK(atup0.size() == 2 && atup0.at(0) != &get<0>(t0));
CPPA_CHECK((v1opt));
if (v1opt)
{
auto& v1 = *v1opt;
CPPA_CHECK((std::is_same<decltype(v1), tuple_view<std::string>&>::value));
CPPA_CHECK_EQUAL(v1.size(), 1);
auto& v1_0 = get<0>(v1);
CPPA_CHECK_EQUAL(v1_0, "1");
CPPA_CHECK_EQUAL(atup0.at(0), &(get<0>(v1))); // point to the same
}
*/
// use tuple cast to get a subtuple
// use tuple cast to get a subtuple
any_tuple
at0
(
t0
);
any_tuple
at0
(
t0
);
auto
v0opt
=
tuple_cast
<
std
::
string
,
anything
>
(
at0
);
auto
v0opt
=
tuple_cast
<
std
::
string
,
anything
>
(
at0
);
CPPA_CHECK
((
std
::
is_same
<
decltype
(
v0opt
),
option
<
tuple
<
std
::
string
>>>::
value
));
CPPA_CHECK
((
std
::
is_same
<
decltype
(
v0opt
),
option
<
tuple
<
std
::
string
>>>::
value
));
CPPA_CHECK
((
v0opt
));
CPPA_CHECK
((
v0opt
));
CPPA_CHECK
(
at0
.
size
()
==
2
&&
at0
.
at
(
0
)
==
&
get
<
0
>
(
t0
));
CPPA_CHECK
(
at0
.
size
()
==
2
&&
at0
.
at
(
0
)
==
&
get
<
0
>
(
t0
)
&&
at0
.
at
(
1
)
==
&
get
<
1
>
(
t0
));
if
(
v0opt
)
if
(
v0opt
)
{
{
auto
&
v0
=
*
v0opt
;
auto
&
v0
=
*
v0opt
;
...
@@ -84,5 +68,24 @@ size_t test__tuple()
...
@@ -84,5 +68,24 @@ size_t test__tuple()
CPPA_CHECK_EQUAL
(
lhs
,
rhs
);
CPPA_CHECK_EQUAL
(
lhs
,
rhs
);
CPPA_CHECK_EQUAL
(
rhs
,
lhs
);
CPPA_CHECK_EQUAL
(
rhs
,
lhs
);
}
}
any_tuple
at1
=
make_tuple
(
"one"
,
2
,
3.
f
,
4.0
);
{
// perfect match
auto
opt0
=
tuple_cast
<
std
::
string
,
int
,
float
,
double
>
(
at1
);
CPPA_CHECK
(
opt0
);
if
(
opt0
)
{
CPPA_CHECK_EQUAL
(
*
opt0
,
make_tuple
(
"one"
,
2
,
3.
f
,
4.0
));
}
// leading wildcard
auto
opt1
=
tuple_cast
<
anything
,
double
>
(
at1
);
CPPA_CHECK
(
opt1
);
if
(
opt1
)
{
CPPA_CHECK_EQUAL
(
get
<
0
>
(
*
opt1
),
4.0
);
}
// trailing wildcard
auto
opt2
=
tuple_cast
<
std
::
string
,
anything
>
(
at1
);
CPPA_CHECK
(
opt2
);
if
(
opt2
)
{
CPPA_CHECK_EQUAL
(
get
<
0
>
(
*
opt2
),
"one"
);
}
// wildcard in between
auto
opt3
=
tuple_cast
<
std
::
string
,
anything
,
double
>
(
at1
);
CPPA_CHECK
(
opt3
);
if
(
opt3
)
{
CPPA_CHECK_EQUAL
(
*
opt3
,
make_tuple
(
"one"
,
4.0
));
}
}
return
CPPA_TEST_RESULT
;
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