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
1bede491
Commit
1bede491
authored
Aug 29, 2012
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added match_stream functions
parent
5b11dc0f
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
178 additions
and
0 deletions
+178
-0
cppa/match.hpp
cppa/match.hpp
+178
-0
No files found.
cppa/match.hpp
View file @
1bede491
...
...
@@ -31,11 +31,17 @@
#ifndef CPPA_MATCH_HPP
#define CPPA_MATCH_HPP
#include <vector>
#include <istream>
#include <iterator>
#include <type_traits>
#include "cppa/any_tuple.hpp"
#include "cppa/partial_function.hpp"
#include "cppa/util/tbind.hpp"
#include "cppa/util/type_list.hpp"
namespace
cppa
{
namespace
detail
{
struct
match_helper
{
...
...
@@ -126,6 +132,165 @@ struct pmatch_each_helper {
}
};
// Case is a projection_partial_function_pair
template
<
typename
T
,
typename
InputIterator
,
class
Case
>
size_t
run_case
(
std
::
vector
<
T
>&
vec
,
bool
&
match_returned_false
,
InputIterator
&
pos
,
const
InputIterator
&
end
,
Case
&
target
);
template
<
size_t
N
,
size_t
Size
>
struct
unwind_and_call
{
typedef
unwind_and_call
<
N
+
1
,
Size
>
next
;
template
<
class
Target
,
typename
T
,
typename
...
Unwinded
>
static
inline
bool
_
(
Target
&
target
,
std
::
vector
<
T
>&
vec
,
Unwinded
&&
...
args
)
{
return
next
::
_
(
target
,
vec
,
std
::
forward
<
Unwinded
>
(
args
)...,
vec
[
N
]);
}
template
<
class
Target
,
typename
T
,
typename
...
Unwinded
>
static
inline
bool
_
(
Target
&
target
,
bool
&
sub_result
,
std
::
vector
<
T
>&
vec
,
Unwinded
&&
...
args
)
{
return
next
::
_
(
target
,
sub_result
,
vec
,
std
::
forward
<
Unwinded
>
(
args
)...,
vec
[
N
]);
}
template
<
typename
T
,
typename
InputIterator
,
class
MatchExpr
>
static
inline
bool
_
(
std
::
vector
<
T
>&
vec
,
InputIterator
&
pos
,
InputIterator
end
,
MatchExpr
&
ex
)
{
bool
match_returned_false
=
false
;
if
(
run_case
(
vec
,
match_returned_false
,
pos
,
end
,
get
<
N
>
(
ex
.
cases
()))
==
0
)
{
if
(
match_returned_false
)
{
return
false
;
}
return
next
::
_
(
vec
,
pos
,
end
,
ex
);
}
return
true
;
}
};
template
<
size_t
Size
>
struct
unwind_and_call
<
Size
,
Size
>
{
template
<
class
Target
,
typename
T
,
typename
...
Unwinded
>
static
inline
bool
_
(
Target
&
target
,
std
::
vector
<
T
>&
,
Unwinded
&&
...
args
)
{
return
target
.
first
(
target
.
second
,
std
::
forward
<
Unwinded
>
(
args
)...);
}
template
<
class
Target
,
typename
T
,
typename
...
Unwinded
>
static
inline
bool
_
(
Target
&
target
,
bool
&
sub_result
,
std
::
vector
<
T
>&
,
Unwinded
&&
...
args
)
{
return
target
.
first
.
invoke
(
target
.
second
,
sub_result
,
std
::
forward
<
Unwinded
>
(
args
)...);
}
template
<
typename
T
,
typename
...
Args
>
static
inline
bool
_
(
std
::
vector
<
T
>&
,
Args
&&
...)
{
return
false
;
}
};
template
<
bool
EvaluateSubResult
>
// default = false
struct
run_case_impl
{
template
<
class
Case
,
typename
T
>
static
inline
bool
_
(
Case
&
target
,
std
::
vector
<
T
>&
vec
,
bool
&
)
{
return
unwind_and_call
<
0
,
Case
::
pattern_type
::
size
>::
_
(
target
,
vec
);
}
};
template
<
>
struct
run_case_impl
<
true
>
{
template
<
class
Case
,
typename
T
>
static
inline
bool
_
(
Case
&
target
,
std
::
vector
<
T
>&
vec
,
bool
&
match_returned_false
)
{
bool
sub_result
;
if
(
unwind_and_call
<
0
,
Case
::
pattern_type
::
size
>::
_
(
target
,
sub_result
,
vec
))
{
if
(
sub_result
==
false
)
{
match_returned_false
=
true
;
}
return
true
;
}
return
false
;
}
};
// Case is a projection_partial_function_pair
template
<
typename
T
,
typename
InputIterator
,
class
Case
>
size_t
run_case
(
std
::
vector
<
T
>&
vec
,
bool
&
match_returned_false
,
InputIterator
&
pos
,
const
InputIterator
&
end
,
Case
&
target
)
{
static
constexpr
size_t
num_args
=
Case
::
pattern_type
::
size
;
typedef
typename
Case
::
second_type
partial_fun_type
;
typedef
typename
partial_fun_type
::
result_type
result_type
;
typedef
typename
partial_fun_type
::
arg_types
arg_types
;
typedef
typename
util
::
tl_map
<
arg_types
,
util
::
rm_ref
>::
type
plain_args
;
static_assert
(
num_args
>
0
,
"empty match expressions are not allowed in stream matching"
);
static_assert
(
util
::
tl_forall
<
plain_args
,
util
::
tbind
<
std
::
is_same
,
T
>::
template
type
>
::
value
,
"match_stream<T>: at least one callback argument "
" is not of type T"
);
while
(
vec
.
size
()
<
num_args
)
{
if
(
pos
==
end
)
{
return
0
;
}
vec
.
emplace_back
(
*
pos
++
);
}
if
(
run_case_impl
<
std
::
is_same
<
result_type
,
bool
>::
value
>::
_
(
target
,
vec
,
match_returned_false
))
{
if
(
vec
.
size
()
==
num_args
)
{
vec
.
clear
();
}
else
{
auto
i
=
vec
.
begin
();
vec
.
erase
(
i
,
i
+
num_args
);
}
return
match_returned_false
?
0
:
num_args
;
}
return
0
;
}
template
<
typename
T
,
typename
InputIterator
>
class
stream_matcher
{
public:
typedef
InputIterator
iter
;
stream_matcher
(
iter
first
,
iter
last
)
:
m_pos
(
first
),
m_end
(
last
)
{
}
template
<
typename
...
Cases
>
bool
operator
()(
match_expr
<
Cases
...
>&
expr
)
{
while
(
m_pos
!=
m_end
)
{
if
(
!
unwind_and_call
<
0
,
match_expr
<
Cases
...
>::
cases_list
::
size
>::
_
(
m_cache
,
m_pos
,
m_end
,
expr
))
{
return
false
;
}
}
return
true
;
}
template
<
typename
...
Cases
>
bool
operator
()(
match_expr
<
Cases
...
>&&
expr
)
{
auto
tmp
=
std
::
move
(
expr
);
return
(
*
this
)(
tmp
);
}
template
<
typename
...
Cases
>
bool
operator
()(
const
match_expr
<
Cases
...
>&
expr
)
{
auto
tmp
=
expr
;
return
(
*
this
)(
tmp
);
}
template
<
typename
Arg0
,
typename
...
Args
>
bool
operator
()(
Arg0
&&
arg0
,
Args
&&
...
args
)
{
return
(
*
this
)(
match_expr_collect
(
std
::
forward
<
Arg0
>
(
arg0
),
std
::
forward
<
Args
>
(
args
)...));
}
private:
iter
m_pos
;
iter
m_end
;
std
::
vector
<
T
>
m_cache
;
};
}
}
// namespace cppa::detail
namespace
cppa
{
...
...
@@ -199,6 +364,19 @@ auto match_each(InputIterator first, InputIterator last, Projection proj)
return
{
first
,
last
,
std
::
move
(
proj
)};
}
template
<
typename
T
>
detail
::
stream_matcher
<
T
,
std
::
istream_iterator
<
T
>
>
match_stream
(
std
::
istream
&
stream
)
{
std
::
istream_iterator
<
T
>
first
(
stream
);
std
::
istream_iterator
<
T
>
last
;
// 'end of stream' iterator
return
{
first
,
last
};
}
template
<
typename
T
,
typename
InputIterator
>
detail
::
stream_matcher
<
T
,
InputIterator
>
match_stream
(
InputIterator
first
,
InputIterator
last
)
{
return
{
first
,
last
};
}
}
// namespace cppa
#endif // CPPA_MATCH_HPP
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