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
37d81618
Commit
37d81618
authored
Aug 27, 2013
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
return result of match_expr from match functions
parent
b6056bf1
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
113 additions
and
74 deletions
+113
-74
cppa/match.hpp
cppa/match.hpp
+113
-74
No files found.
cppa/match.hpp
View file @
37d81618
...
@@ -46,20 +46,29 @@
...
@@ -46,20 +46,29 @@
namespace
cppa
{
namespace
detail
{
namespace
cppa
{
namespace
detail
{
struct
match_helper
{
class
match_helper
{
match_helper
(
const
match_helper
&
)
=
delete
;
match_helper
(
const
match_helper
&
)
=
delete
;
match_helper
&
operator
=
(
const
match_helper
&
)
=
delete
;
match_helper
&
operator
=
(
const
match_helper
&
)
=
delete
;
any_tuple
tup
;
match_helper
(
any_tuple
t
)
:
tup
(
std
::
move
(
t
))
{
}
public:
match_helper
(
match_helper
&&
)
=
default
;
match_helper
(
match_helper
&&
)
=
default
;
inline
match_helper
(
any_tuple
t
)
:
tup
(
std
::
move
(
t
))
{
}
template
<
typename
...
Ts
>
template
<
typename
...
Ts
>
bool
operator
()(
Ts
&&
...
args
)
{
auto
operator
()(
Ts
&&
...
args
)
->
decltype
(
match_expr_collect
(
std
::
forward
<
Ts
>
(
args
)...)(
any_tuple
{}))
{
static_assert
(
sizeof
...(
Ts
)
>
0
,
"at least one argument required"
);
static_assert
(
sizeof
...(
Ts
)
>
0
,
"at least one argument required"
);
auto
tmp
=
match_expr_convert
(
std
::
forward
<
Ts
>
(
args
)...);
auto
tmp
=
match_expr_collect
(
std
::
forward
<
Ts
>
(
args
)...);
static_assert
(
std
::
is_same
<
partial_function
,
decltype
(
tmp
)
>::
value
,
"match statement contains timeout"
);
return
tmp
(
tup
);
return
tmp
(
tup
);
}
}
private:
any_tuple
tup
;
};
};
struct
identity_fun
{
struct
identity_fun
{
...
@@ -72,22 +81,25 @@ struct identity_fun {
...
@@ -72,22 +81,25 @@ struct identity_fun {
template
<
typename
Iterator
,
typename
Projection
=
identity_fun
>
template
<
typename
Iterator
,
typename
Projection
=
identity_fun
>
class
match_each_helper
{
class
match_each_helper
{
match_each_helper
(
const
match_each_helper
&
)
=
delete
;
match_each_helper
&
operator
=
(
const
match_each_helper
&
)
=
delete
;
public:
public:
match_each_helper
(
match_each_helper
&&
)
=
default
;
match_each_helper
(
match_each_helper
&&
)
=
default
;
match_each_helper
(
const
match_each_helper
&
)
=
delete
;
match_each_helper
&
operator
=
(
const
match_each_helper
&
)
=
delete
;
match_each_helper
(
Iterator
first
,
Iterator
last
,
Projection
proj
=
Projection
{})
match_each_helper
(
Iterator
first
,
Iterator
last
)
:
i
(
first
),
e
(
last
)
{
}
:
i
(
std
::
move
(
first
)),
e
(
std
::
move
(
last
)),
p
(
std
::
move
(
proj
))
{
}
match_each_helper
(
Iterator
first
,
Iterator
last
,
Projection
proj
)
:
i
(
first
),
e
(
last
),
p
(
proj
)
{
}
template
<
typename
...
Ts
>
template
<
typename
...
Ts
>
void
operator
()(
Ts
&&
...
args
)
{
Iterator
operator
()(
Ts
&&
...
args
)
{
static_assert
(
sizeof
...(
Ts
)
>
0
,
"at least one argument required"
);
static_assert
(
sizeof
...(
Ts
)
>
0
,
"at least one argument required"
);
auto
expr
=
match_expr_collect
(
std
::
forward
<
Ts
>
(
args
)...);
auto
expr
=
match_expr_collect
(
std
::
forward
<
Ts
>
(
args
)...);
for
(;
i
!=
e
;
++
i
)
{
for
(;
i
!=
e
;
++
i
)
{
expr
(
p
(
*
i
));
auto
res
=
expr
(
p
(
*
i
));
if
(
!
res
)
return
i
;
}
}
return
e
;
}
}
private:
private:
...
@@ -103,17 +115,20 @@ struct advance_once {
...
@@ -103,17 +115,20 @@ struct advance_once {
inline
void
operator
()(
T
&
what
)
{
++
what
;
}
inline
void
operator
()(
T
&
what
)
{
++
what
;
}
};
};
template
<
class
Iterator
,
class
Predicate
,
template
<
class
Iterator
,
class
Predicate
,
class
Advance
=
advance_once
,
class
Advance
=
advance_once
,
class
Projection
=
identity_fun
>
class
Projection
=
identity_fun
>
class
match_for_helper
{
class
match_for_helper
{
match_for_helper
(
const
match_for_helper
&
)
=
delete
;
match_for_helper
&
operator
=
(
const
match_for_helper
&
)
=
delete
;
public:
public:
match_for_helper
(
match_for_helper
&&
)
=
default
;
match_for_helper
(
match_for_helper
&&
)
=
default
;
match_for_helper
(
const
match_for_helper
&
)
=
delete
;
match_for_helper
&
operator
=
(
const
match_for_helper
&
)
=
delete
;
match_for_helper
(
Iterator
first
,
Predicate
p
,
Advance
a
=
Advance
{},
Projection
pj
=
Projection
{})
match_for_helper
(
Iterator
first
,
Predicate
p
,
Advance
a
=
Advance
(),
Projection
pj
=
Projection
())
:
i
(
first
),
adv
(
a
),
pred
(
p
),
proj
(
pj
)
{
}
:
i
(
first
),
adv
(
a
),
pred
(
p
),
proj
(
pj
)
{
}
template
<
typename
...
Ts
>
template
<
typename
...
Ts
>
...
@@ -142,59 +157,80 @@ size_t run_case(std::vector<T>& vec,
...
@@ -142,59 +157,80 @@ size_t run_case(std::vector<T>& vec,
const
InputIterator
&
end
,
const
InputIterator
&
end
,
Case
&
target
);
Case
&
target
);
template
<
size_t
N
,
size_t
Size
>
template
<
size_t
Pos
,
size_t
Max
>
struct
unwind_
and_call
{
struct
unwind_
pos_token
{
};
typedef
unwind_and_call
<
N
+
1
,
Size
>
next
;
template
<
size_t
Pos
,
size_t
Max
>
constexpr
unwind_pos_token
<
Pos
+
1
,
Max
>
next
(
unwind_pos_token
<
Pos
,
Max
>
)
{
return
{};
}
template
<
class
Target
,
typename
T
,
typename
...
Unwinded
>
template
<
typename
T
>
static
inline
bool
_
(
Target
&
target
,
bool
&
skipped
,
std
::
vector
<
T
>&
vec
,
Unwinded
&&
...
args
)
{
static
inline
bool
eval_res
(
const
optional
<
T
>&
res
,
bool
&
)
{
return
next
::
_
(
target
,
skipped
,
vec
,
std
::
forward
<
Unwinded
>
(
args
)...,
vec
[
N
]
);
return
static_cast
<
bool
>
(
res
);
}
}
template
<
typename
T
,
typename
InputIterator
,
class
MatchExpr
>
static
inline
bool
eval_res
(
const
optional
<
match_hint
>&
res
,
bool
&
skipped
)
{
static
inline
bool
_
(
std
::
vector
<
T
>&
vec
,
InputIterator
&
pos
,
InputIterator
end
,
MatchExpr
&
ex
)
{
if
(
res
)
{
bool
skipped
=
false
;
if
(
*
res
==
match_hint
::
skip
)
{
if
(
run_case
(
vec
,
skipped
,
pos
,
end
,
get
<
N
>
(
ex
.
cases
()))
==
0
)
{
skipped
=
true
;
return
(
skipped
)
?
false
:
next
::
_
(
vec
,
pos
,
end
,
ex
)
;
return
false
;
}
}
return
true
;
return
true
;
}
}
return
false
;
}
};
template
<
size_t
Max
,
class
Target
,
typename
T
,
typename
...
Ts
>
bool
unwind_and_call
(
unwind_pos_token
<
Max
,
Max
>
,
template
<
size_t
Size
>
Target
&
target
,
struct
unwind_and_call
<
Size
,
Size
>
{
bool
&
skipped
,
std
::
vector
<
T
>&
,
Ts
&&
...
args
)
{
return
eval_res
(
target
.
first
(
target
.
second
,
std
::
forward
<
Ts
>
(
args
)...),
skipped
);
}
template
<
typename
T
>
template
<
size_t
Max
,
typename
T
,
typename
InputIterator
,
class
MatchExpr
>
static
inline
bool
eval_res
(
const
optional
<
T
>&
res
,
bool
&
)
{
bool
unwind_and_call
(
unwind_pos_token
<
Max
,
Max
>
,
return
static_cast
<
bool
>
(
res
);
std
::
vector
<
T
>&
,
}
InputIterator
&
,
InputIterator
,
MatchExpr
&
)
{
return
false
;
}
static
inline
bool
eval_res
(
const
optional
<
match_hint
>&
res
,
bool
&
skipped
)
{
template
<
size_t
Pos
,
size_t
Max
,
class
Target
,
typename
T
,
typename
...
Ts
>
if
(
res
)
{
bool
unwind_and_call
(
unwind_pos_token
<
Pos
,
Max
>
pt
,
if
(
*
res
==
match_hint
::
skip
)
{
Target
&
target
,
skipped
=
true
;
bool
&
skipped
,
return
false
;
std
::
vector
<
T
>&
vec
,
}
Ts
&&
...
args
)
{
return
true
;
return
unwind_and_call
(
next
(
pt
),
}
target
,
return
false
;
skipped
,
}
vec
,
std
::
forward
<
Ts
>
(
args
)...,
vec
[
Pos
]);
}
template
<
class
Target
,
typename
T
,
typename
...
Unwinded
>
template
<
size_t
Pos
,
size_t
Max
,
typename
T
,
typename
InputIterator
,
class
MatchExpr
>
static
inline
bool
_
(
Target
&
target
,
bool
&
skipped
,
std
::
vector
<
T
>&
,
Unwinded
&&
...
args
)
{
bool
unwind_and_call
(
unwind_pos_token
<
Pos
,
Max
>
pt
,
return
eval_res
(
target
.
first
(
target
.
second
,
std
::
forward
<
Unwinded
>
(
args
)...),
skipped
);
std
::
vector
<
T
>&
vec
,
InputIterator
&
pos
,
InputIterator
end
,
MatchExpr
&
ex
)
{
bool
skipped
=
false
;
if
(
run_case
(
vec
,
skipped
,
pos
,
end
,
get
<
Pos
>
(
ex
.
cases
()))
==
0
)
{
return
(
skipped
)
?
false
:
unwind_and_call
(
next
(
pt
),
vec
,
pos
,
end
,
ex
);
}
}
return
true
;
template
<
typename
T
,
typename
...
Ts
>
}
static
inline
bool
_
(
std
::
vector
<
T
>&
,
Ts
&&
...)
{
return
false
;
}
};
template
<
class
Case
,
typename
T
>
template
<
class
Case
,
typename
T
>
inline
bool
run_case_impl
(
Case
&
target
,
std
::
vector
<
T
>&
vec
,
bool
&
skipped
)
{
inline
bool
run_case_impl
(
Case
&
target
,
std
::
vector
<
T
>&
vec
,
bool
&
skipped
)
{
return
unwind_and_call
<
0
,
util
::
tl_size
<
typename
Case
::
pattern_type
>::
value
>::
_
(
target
,
skipped
,
vec
);
unwind_pos_token
<
0
,
util
::
tl_size
<
typename
Case
::
pattern_type
>::
value
>
pt
;
return
unwind_and_call
(
pt
,
target
,
skipped
,
vec
);
}
}
// Case is a projection_partial_function_pair
// Case is a projection_partial_function_pair
...
@@ -212,7 +248,7 @@ size_t run_case(std::vector<T>& vec,
...
@@ -212,7 +248,7 @@ size_t run_case(std::vector<T>& vec,
"empty match expressions are not allowed in stream matching"
);
"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
,
static_assert
(
util
::
tl_forall
<
plain_args
,
util
::
tbind
<
std
::
is_same
,
T
>::
template
type
>
::
value
,
"match_stream<T>: at least one callback argument "
"match_stream<T>: at least one callback argument "
"
is not of type T"
);
"is not of type T"
);
while
(
vec
.
size
()
<
num_args
)
{
while
(
vec
.
size
()
<
num_args
)
{
if
(
pos
==
end
)
{
if
(
pos
==
end
)
{
return
0
;
return
0
;
...
@@ -244,9 +280,10 @@ class stream_matcher {
...
@@ -244,9 +280,10 @@ class stream_matcher {
template
<
typename
...
Ts
>
template
<
typename
...
Ts
>
bool
operator
()(
Ts
&&
...
args
)
{
bool
operator
()(
Ts
&&
...
args
)
{
auto
expr
=
match_expr_collect
(
std
::
forward
<
Ts
>
(
args
)...);
auto
expr
=
match_expr_collect
(
std
::
forward
<
Ts
>
(
args
)...);
typedef
decltype
(
expr
)
expr_type
;
typedef
decltype
(
expr
)
et
;
unwind_pos_token
<
0
,
util
::
tl_size
<
typename
et
::
cases_list
>::
value
>
pt
;
while
(
m_pos
!=
m_end
)
{
while
(
m_pos
!=
m_end
)
{
if
(
!
unwind_and_call
<
0
,
util
::
tl_size
<
typename
expr_type
::
cases_list
>::
value
>::
_
(
m_cache
,
m_pos
,
m_end
,
expr
))
{
if
(
!
unwind_and_call
(
pt
,
m_cache
,
m_pos
,
m_end
,
expr
))
{
return
false
;
return
false
;
}
}
}
}
...
@@ -285,7 +322,8 @@ detail::match_helper match(T&& what) {
...
@@ -285,7 +322,8 @@ detail::match_helper match(T&& what) {
/**
/**
* @brief Splits @p str using @p delim and match the resulting strings.
* @brief Splits @p str using @p delim and match the resulting strings.
*/
*/
detail
::
match_helper
match_split
(
const
std
::
string
&
str
,
char
delim
,
bool
keep_empties
=
false
);
detail
::
match_helper
match_split
(
const
std
::
string
&
str
,
char
delim
,
bool
keep_empties
=
false
);
/**
/**
* @brief Starts a match expression that matches each element in
* @brief Starts a match expression that matches each element in
...
@@ -295,8 +333,8 @@ detail::match_helper match_split(const std::string& str, char delim, bool keep_e
...
@@ -295,8 +333,8 @@ detail::match_helper match_split(const std::string& str, char delim, bool keep_e
* @returns A helper object providing <tt>operator(...)</tt>.
* @returns A helper object providing <tt>operator(...)</tt>.
*/
*/
template
<
typename
InputIterator
>
template
<
typename
InputIterator
>
auto
match_each
(
InputIterator
first
,
InputIterator
last
)
detail
::
match_each_helper
<
InputIterator
>
->
detail
::
match_each_helper
<
InputIterator
>
{
match_each
(
InputIterator
first
,
InputIterator
last
)
{
return
{
first
,
last
};
return
{
first
,
last
};
}
}
...
@@ -309,39 +347,40 @@ auto match_each(InputIterator first, InputIterator last)
...
@@ -309,39 +347,40 @@ auto match_each(InputIterator first, InputIterator last)
* @returns A helper object providing <tt>operator(...)</tt>.
* @returns A helper object providing <tt>operator(...)</tt>.
*/
*/
template
<
typename
InputIterator
,
typename
Projection
>
template
<
typename
InputIterator
,
typename
Projection
>
auto
match_each
(
InputIterator
first
,
InputIterator
last
,
Projection
proj
)
detail
::
match_each_helper
<
InputIterator
,
Projection
>
->
detail
::
match_each_helper
<
InputIterator
,
Projection
>
{
match_each
(
InputIterator
first
,
InputIterator
last
,
Projection
proj
)
{
return
{
first
,
last
,
std
::
move
(
proj
)};
return
{
first
,
last
,
std
::
move
(
proj
)};
}
}
template
<
typename
InputIterator
,
typename
Predicate
>
template
<
typename
InputIterator
,
typename
Predicate
>
auto
match_for
(
InputIterator
first
,
Predicate
pred
)
detail
::
match_for_helper
<
InputIterator
,
Predicate
>
->
detail
::
match_for_helper
<
InputIterator
,
Predicate
>
{
match_for
(
InputIterator
first
,
Predicate
pred
)
{
return
{
first
,
std
::
move
(
pred
)};
return
{
first
,
std
::
move
(
pred
)};
}
}
template
<
typename
InputIterator
,
typename
Predicate
,
typename
Advance
>
template
<
typename
InputIterator
,
typename
Predicate
,
typename
Advance
>
auto
match_for
(
InputIterator
first
,
Predicate
pred
,
Advance
adv
)
detail
::
match_for_helper
<
InputIterator
,
Predicate
,
Advance
>
->
detail
::
match_for_helper
<
InputIterator
,
Predicate
,
Advance
>
{
match_for
(
InputIterator
first
,
Predicate
pred
,
Advance
adv
)
{
return
{
first
,
std
::
move
(
pred
),
std
::
move
(
adv
)};
return
{
first
,
std
::
move
(
pred
),
std
::
move
(
adv
)};
}
}
template
<
class
InputIterator
,
class
Predicate
,
class
Advance
,
class
Projection
>
template
<
class
InputIterator
,
class
Predicate
,
class
Advance
,
class
Projection
>
auto
match_for
(
InputIterator
first
,
Predicate
pred
,
Advance
adv
,
Projection
pj
)
detail
::
match_for_helper
<
InputIterator
,
Predicate
,
Advance
,
Projection
>
->
detail
::
match_for_helper
<
InputIterator
,
Predicate
,
Advance
,
Projection
>
{
match_for
(
InputIterator
first
,
Predicate
pred
,
Advance
adv
,
Projection
pj
)
{
return
{
first
,
std
::
move
(
pred
),
std
::
move
(
adv
),
std
::
move
(
pj
)};
return
{
first
,
std
::
move
(
pred
),
std
::
move
(
adv
),
std
::
move
(
pj
)};
}
}
template
<
typename
T
>
template
<
typename
T
>
detail
::
stream_matcher
<
T
,
std
::
istream_iterator
<
T
>
>
match_stream
(
std
::
istream
&
stream
)
{
detail
::
stream_matcher
<
T
,
std
::
istream_iterator
<
T
>>
match_stream
(
std
::
istream
&
stream
)
{
std
::
istream_iterator
<
T
>
first
(
stream
);
std
::
istream_iterator
<
T
>
first
(
stream
);
std
::
istream_iterator
<
T
>
last
;
// 'end of stream' iterator
std
::
istream_iterator
<
T
>
last
;
// 'end of stream' iterator
return
{
first
,
last
};
return
{
first
,
last
};
}
}
template
<
typename
T
,
typename
InputIterator
>
template
<
typename
T
,
typename
InputIterator
>
detail
::
stream_matcher
<
T
,
InputIterator
>
match_stream
(
InputIterator
first
,
detail
::
stream_matcher
<
T
,
InputIterator
>
InputIterator
last
)
{
match_stream
(
InputIterator
first
,
InputIterator
last
)
{
return
{
first
,
last
};
return
{
first
,
last
};
}
}
...
...
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