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
f360df15
Commit
f360df15
authored
Apr 11, 2012
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
pattern matching
parent
cc1c3445
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
480 additions
and
421 deletions
+480
-421
cppa/tpartial_function.hpp
cppa/tpartial_function.hpp
+2
-1
cppa/util/apply_tuple.hpp
cppa/util/apply_tuple.hpp
+2
-2
cppa/util/callable_trait.hpp
cppa/util/callable_trait.hpp
+2
-1
cppa/util/compare_tuples.hpp
cppa/util/compare_tuples.hpp
+12
-13
cppa/util/type_list.hpp
cppa/util/type_list.hpp
+158
-82
unit_testing/test__tuple.cpp
unit_testing/test__tuple.cpp
+304
-322
No files found.
cppa/tpartial_function.hpp
View file @
f360df15
...
...
@@ -78,7 +78,8 @@ class tpartial_function
tpartial_function
(
tpartial_function
const
&
)
=
default
;
bool
defined_at
(
typename
util
::
rm_ref
<
Args
>::
type
const
&
...
args
)
const
//bool defined_at(typename util::rm_ref<Args>::type const&... args) const
bool
defined_at
(
Args
...
args
)
const
{
return
m_guard
(
args
...);
}
...
...
cppa/util/apply_tuple.hpp
View file @
f360df15
...
...
@@ -143,8 +143,8 @@ template<typename Result, typename F,
template
<
typename
...
>
class
Tuple
,
typename
...
T
>
Result
unchecked_apply_tuple
(
F
&&
fun
,
Tuple
<
T
...
>&
tup
)
{
return
unchecked_apply_tuple_in_range
<
Result
,
0
,
sizeof
...(
T
)
-
1
>
(
std
::
forward
<
F
>
(
fun
),
tup
);
return
apply_tuple_util
<
Result
,
true
,
0
,
sizeof
...(
T
)
-
1
>
::
apply
(
std
::
forward
<
F
>
(
fun
),
tup
);
}
}
}
// namespace cppa::util
...
...
cppa/util/callable_trait.hpp
View file @
f360df15
...
...
@@ -133,7 +133,8 @@ struct is_callable
static
void
_fun
(
void
*
)
{
}
typedef
decltype
(
_fun
(
static_cast
<
T
*>
(
nullptr
)))
result_type
;
typedef
decltype
(
_fun
(
static_cast
<
typename
rm_ref
<
T
>::
type
*>
(
nullptr
)))
result_type
;
public:
...
...
cppa/util/compare_tuples.hpp
View file @
f360df15
...
...
@@ -76,8 +76,11 @@ bool compare_tuples(LhsTuple<LhsTypes...> const& lhs,
static_assert
(
sizeof
...(
LhsTypes
)
==
sizeof
...(
RhsTypes
),
"could not compare tuples of different size"
);
static_assert
(
tl_zipped_forall
<
type_list
<
type_pair
<
LhsTypes
,
RhsTypes
>
...
>
,
is_comparable
>::
value
,
static_assert
(
tl_binary_forall
<
type_list
<
LhsTypes
...
>
,
type_list
<
RhsTypes
...
>
,
is_comparable
>::
value
,
"types of lhs are not comparable to the types of rhs"
);
return
detail
::
cmp_helper
<
(
sizeof
...(
LhsTypes
)
-
1
),
...
...
@@ -90,20 +93,16 @@ template<template<typename...> class LhsTuple, typename... LhsTypes,
bool
compare_first_elements
(
LhsTuple
<
LhsTypes
...
>
const
&
lhs
,
RhsTuple
<
RhsTypes
...
>
const
&
rhs
)
{
static
constexpr
size_t
cmp_size
=
(
sizeof
...(
LhsTypes
)
<
sizeof
...(
RhsTypes
))
?
sizeof
...(
LhsTypes
)
:
sizeof
...(
RhsTypes
);
typedef
typename
tl_zip
<
util
::
type_list
<
LhsTypes
...
>
,
util
::
type_list
<
RhsTypes
...
>
>::
type
zipped_types
;
typedef
util
::
type_list
<
LhsTypes
...
>
lhs_tlist
;
typedef
util
::
type_list
<
RhsTypes
...
>
rhs_tlist
;
typedef
typename
tl_first_n
<
lhs_tlist
,
cmp_size
>::
type
lhs_sublist
;
typedef
typename
tl_first_n
<
rhs_tlist
,
cmp_size
>::
type
rhs_sublist
;
typedef
typename
tl_zip
<
lhs_sublist
,
rhs_sublist
>::
type
zipped_sublists
;
static_assert
(
tl_zipped_forall
<
zipped_sublists
,
is_comparable
>::
value
,
static_assert
(
tl_zipped_forall
<
zipped_types
,
is_comparable
>::
value
,
"types of lhs are not comparable to the types of rhs"
);
return
detail
::
cmp_helper
<
(
cmp_
size
-
1
),
return
detail
::
cmp_helper
<
(
zipped_types
::
size
-
1
),
LhsTuple
<
LhsTypes
...
>
,
RhsTuple
<
RhsTypes
...
>>::
cmp
(
lhs
,
rhs
);
}
...
...
cppa/util/type_list.hpp
View file @
f360df15
...
...
@@ -101,7 +101,87 @@ struct is_type_list<type_list<Ts...> >
static
constexpr
bool
value
=
true
;
};
// static list zip(list, list)
// list slice(size_t, size_t)
template
<
size_t
LeftOffset
,
size_t
Remaining
,
typename
PadType
,
class
List
,
typename
...
T
>
struct
tl_slice_impl
{
typedef
typename
tl_slice_impl
<
LeftOffset
-
1
,
Remaining
,
PadType
,
typename
List
::
tail
,
T
...
>::
type
type
;
};
template
<
size_t
Remaining
,
typename
PadType
,
class
List
,
typename
...
T
>
struct
tl_slice_impl
<
0
,
Remaining
,
PadType
,
List
,
T
...
>
{
typedef
typename
tl_slice_impl
<
0
,
Remaining
-
1
,
PadType
,
typename
List
::
tail
,
T
...,
typename
List
::
head
>::
type
type
;
};
template
<
size_t
Remaining
,
typename
PadType
,
typename
...
T
>
struct
tl_slice_impl
<
0
,
Remaining
,
PadType
,
type_list
<>
,
T
...
>
{
typedef
typename
tl_slice_impl
<
0
,
Remaining
-
1
,
PadType
,
type_list
<>
,
T
...,
PadType
>::
type
type
;
};
template
<
typename
PadType
,
class
List
,
typename
...
T
>
struct
tl_slice_impl
<
0
,
0
,
PadType
,
List
,
T
...
>
{
typedef
type_list
<
T
...
>
type
;
};
template
<
typename
PadType
,
typename
...
T
>
struct
tl_slice_impl
<
0
,
0
,
PadType
,
type_list
<>
,
T
...
>
{
typedef
type_list
<
T
...
>
type
;
};
template
<
class
List
,
size_t
ListSize
,
size_t
First
,
size_t
Last
,
typename
PadType
=
void_type
>
struct
tl_slice_
{
typedef
typename
tl_slice_impl
<
First
,
(
Last
-
First
),
PadType
,
List
>::
type
type
;
};
template
<
class
List
,
size_t
ListSize
,
typename
PadType
>
struct
tl_slice_
<
List
,
ListSize
,
0
,
ListSize
,
PadType
>
{
typedef
List
type
;
};
/**
* @brief Creates a new list from range (First, Last].
*/
template
<
class
List
,
size_t
First
,
size_t
Last
>
struct
tl_slice
{
static_assert
(
First
<=
Last
,
"First > Last"
);
typedef
typename
tl_slice_
<
List
,
List
::
size
,
First
,
Last
>::
type
type
;
};
/**
* @brief Zips two lists of equal size.
...
...
@@ -112,11 +192,11 @@ struct is_type_list<type_list<Ts...> >
*/
template
<
class
ListA
,
class
ListB
,
template
<
typename
,
typename
>
class
Fun
=
to_type_pair
>
struct
tl_zip
;
struct
tl_zip
_impl
;
template
<
typename
...
LhsElements
,
typename
...
RhsElements
,
template
<
typename
,
typename
>
class
Fun
>
struct
tl_zip
<
type_list
<
LhsElements
...
>
,
type_list
<
RhsElements
...
>
,
Fun
>
struct
tl_zip
_impl
<
type_list
<
LhsElements
...
>
,
type_list
<
RhsElements
...
>
,
Fun
>
{
static_assert
(
sizeof
...(
LhsElements
)
==
sizeof
...(
RhsElements
),
...
...
@@ -124,6 +204,51 @@ struct tl_zip<type_list<LhsElements...>, type_list<RhsElements...>, Fun>
typedef
type_list
<
typename
Fun
<
LhsElements
,
RhsElements
>::
type
...
>
type
;
};
template
<
class
ListA
,
class
ListB
,
template
<
typename
,
typename
>
class
Fun
=
to_type_pair
>
struct
tl_zip
{
static
constexpr
size_t
result_size
=
(
ListA
::
size
<
ListB
::
size
)
?
ListA
::
size
:
ListB
::
size
;
typedef
typename
tl_zip_impl
<
typename
tl_slice
<
ListA
,
0
,
result_size
>::
type
,
typename
tl_slice
<
ListB
,
0
,
result_size
>::
type
,
Fun
>::
type
type
;
};
template
<
class
ListA
,
class
ListB
,
typename
PadA
=
void_type
,
typename
PadB
=
void_type
,
template
<
typename
,
typename
>
class
Fun
=
to_type_pair
>
struct
tl_zip_all
{
static
constexpr
size_t
result_size
=
(
ListA
::
size
>
ListB
::
size
)
?
ListA
::
size
:
ListB
::
size
;
typedef
typename
tl_zip_impl
<
typename
tl_slice_
<
ListA
,
ListA
::
size
,
0
,
result_size
>::
type
,
typename
tl_slice_
<
ListB
,
ListB
::
size
,
0
,
result_size
>::
type
,
Fun
>::
type
type
;
};
template
<
class
ListA
>
struct
tl_unzip
;
...
...
@@ -240,102 +365,53 @@ struct tl_find_if
static
constexpr
int
value
=
tl_find_impl
<
List
,
Predicate
,
Pos
>::
value
;
};
// list first_n(size_t)
template
<
size_t
N
,
class
List
,
typename
...
T
>
struct
tl_first_n_impl
{
typedef
typename
tl_first_n_impl
<
N
-
1
,
typename
List
::
tail
,
T
...,
typename
List
::
head
>::
type
type
;
};
template
<
class
List
,
typename
...
T
>
struct
tl_first_n_impl
<
0
,
List
,
T
...
>
{
typedef
type_list
<
T
...
>
type
;
};
// bool forall(predicate)
/**
* @brief
Creates a new list from the first @p N elements of @p L
ist.
* @brief
Tests whether a predicate holds for all elements of a l
ist.
*/
template
<
class
List
,
size_t
N
>
struct
tl_first_n
{
static_assert
(
List
::
size
>=
N
,
"List::size < N"
);
typedef
typename
tl_first_n_impl
<
N
,
List
>::
type
type
;
};
template
<
class
List
>
struct
tl_first_n
<
List
,
0
>
{
typedef
type_list
<>
type
;
};
// list last_n(size_t)
template
<
size_t
TargetSize
,
size_t
Size
,
class
List
,
typename
...
T
>
struct
tl_last_n_impl
;
template
<
size_t
TargetSize
,
size_t
Size
,
typename
T0
,
typename
...
T
>
struct
tl_last_n_impl
<
TargetSize
,
Size
,
type_list
<>
,
T0
,
T
...
>
{
typedef
typename
tl_last_n_impl
<
TargetSize
,
Size
-
1
,
type_list
<>
,
T
...
>::
type
type
;
};
template
<
size_t
Size
,
typename
...
T
>
struct
tl_last_n_impl
<
Size
,
Size
,
type_list
<>
,
T
...
>
template
<
class
List
,
template
<
typename
>
class
Predicate
>
struct
tl_forall
{
typedef
type_list
<
T
...
>
type
;
static
constexpr
bool
value
=
Predicate
<
typename
List
::
head
>::
value
&&
tl_forall
<
typename
List
::
tail
,
Predicate
>::
value
;
};
template
<
size_t
TargetSize
,
size_t
Size
,
typename
L0
,
typename
...
L
,
typename
...
T
>
struct
tl_
last_n_impl
<
TargetSize
,
Size
,
type_list
<
L0
,
L
...
>
,
T
...
>
template
<
template
<
typename
>
class
Predicate
>
struct
tl_
forall
<
type_list
<>
,
Predicate
>
{
typedef
typename
tl_last_n_impl
<
TargetSize
,
Size
,
type_list
<
L
...
>
,
T
...,
L0
>::
type
type
;
static
constexpr
bool
value
=
true
;
};
/**
* @brief Creates a new list from the first @p N elements of @p List.
*/
template
<
class
List
,
size_t
N
>
struct
tl_last_n
template
<
class
ListA
,
class
ListB
,
template
<
typename
,
typename
>
class
Predicate
>
struct
tl_forall2_impl
{
static_assert
(
List
::
size
>=
N
,
"List::size < N"
);
typedef
typename
tl_last_n_impl
<
N
,
List
::
size
,
List
>::
type
type
;
static
constexpr
bool
value
=
Predicate
<
typename
ListA
::
head
,
typename
ListB
::
head
>::
value
&&
tl_forall2_impl
<
typename
ListA
::
tail
,
typename
ListB
::
tail
,
Predicate
>::
value
;
};
template
<
class
List
>
struct
tl_
last_n
<
List
,
0
>
template
<
template
<
typename
,
typename
>
class
Predicate
>
struct
tl_
forall2_impl
<
type_list
<>
,
type_list
<>
,
Predicate
>
{
typedef
type_list
<>
typ
e
;
static
constexpr
bool
value
=
tru
e
;
};
// bool forall(predicate)
/**
* @brief Tests whether a predicate holds for all elements of a list.
* @brief Tests whether a binary predicate holds for all
* corresponding elements of @p ListA and @p ListB.
*/
template
<
class
List
,
template
<
typename
>
class
Predicate
>
struct
tl_forall
template
<
class
List
A
,
class
ListB
,
template
<
typename
,
typename
>
class
Predicate
>
struct
tl_
binary_
forall
{
static
constexpr
bool
value
=
Predicate
<
class
List
::
head
>::
value
&&
tl_forall
<
class
List
::
tail
,
Predicate
>::
value
;
};
template
<
template
<
typename
>
class
Predicate
>
struct
tl_forall
<
type_list
<>
,
Predicate
>
{
static
constexpr
bool
value
=
true
;
ListA
::
size
==
ListB
::
size
&&
tl_forall2_impl
<
ListA
,
ListB
,
Predicate
>::
value
;
};
/**
...
...
@@ -677,7 +753,7 @@ struct tl_pad_right_impl;
template
<
class
List
,
size_t
OldSize
,
size_t
NewSize
,
typename
FillType
>
struct
tl_pad_right_impl
<
List
,
false
,
OldSize
,
NewSize
,
FillType
>
{
typedef
typename
tl_
first_n
<
List
,
NewSize
>::
type
type
;
typedef
typename
tl_
slice
<
List
,
0
,
NewSize
>::
type
type
;
};
template
<
class
List
,
size_t
Size
,
typename
FillType
>
...
...
@@ -703,7 +779,7 @@ struct tl_pad_right_impl<List, true, OldSize, NewSize, FillType>
* @brief Resizes the list to contain @p NewSize elements and uses
* @p FillType to initialize the new elements with.
*/
template
<
class
List
,
size_t
NewSize
,
typename
FillType
>
template
<
class
List
,
size_t
NewSize
,
typename
FillType
=
void_type
>
struct
tl_pad_right
{
typedef
typename
tl_pad_right_impl
<
...
...
unit_testing/test__tuple.cpp
View file @
f360df15
...
...
@@ -90,11 +90,6 @@ struct invoke_policy_helper
{
storage
=
*
reinterpret_cast
<
T
const
*>
(
tup
.
at
(
i
++
));
}
//template<typename T>
//void operator()(ge_mutable_reference_wrapper<T>& storage)
//{
// storage = *reinterpret_cast<T*>(tup.mutable_at(i++));
//}
};
template
<
typename
T
>
...
...
@@ -103,14 +98,26 @@ struct std_ref_wrapped
typedef
std
::
reference_wrapper
<
T
>
type
;
};
template
<
typename
T
>
struct
std_ref_wrapped
<
T
&>
{
typedef
std
::
reference_wrapper
<
T
>
type
;
};
template
<
typename
T
>
struct
gref_wrapped
{
typedef
ge_reference_wrapper
<
T
>
type
;
typedef
ge_reference_wrapper
<
typename
util
::
rm_ref
<
T
>::
type
>
type
;
};
template
<
typename
T
>
struct
gref_mutable_wrapped
{
typedef
ge_mutable_reference_wrapper
<
const
typename
util
::
rm_ref
<
T
>::
type
>
type
;
};
template
<
typename
T
>
struct
gref_mutable_wrapped
<
T
&>
{
typedef
ge_mutable_reference_wrapper
<
T
>
type
;
};
...
...
@@ -131,44 +138,54 @@ struct invoke_policy_impl<wildcard_position::nil, Pattern, FilteredPattern>
>::
type
arr_type
;
template
<
typename
Target
,
typename
...
Ts
>
static
bool
_invoke_args
(
std
::
integral_constant
<
bool
,
true
>
,
Target
&
target
,
Ts
&&
...
args
)
{
return
target
(
std
::
forward
<
Ts
>
(
args
)...);
}
template
<
class
Target
,
class
Tup
>
static
inline
bool
shortcut
(
Target
&
,
Tup
&
)
{
return
false
;
}
template
<
typename
Target
,
typename
...
Ts
>
static
bool
_invoke_args
(
std
::
integral_constant
<
bool
,
false
>
,
Target
&
,
Ts
&&
...)
template
<
class
Target
,
typename
...
T
>
static
inline
bool
shortcut
(
Target
&
target
,
detail
::
tdata
<
T
...
>
const
&
tup
,
typename
util
::
enable_if
<
util
::
tl_binary_forall
<
util
::
type_list
<
T
...
>
,
FilteredPattern
,
std
::
is_convertible
>
>::
type
*
=
0
)
{
return
false
;
util
::
unchecked_apply_tuple
<
bool
>
(
target
,
tup
);
return
true
;
}
template
<
typename
Target
,
typename
...
Ts
>
static
bool
invoke_args
(
Target
&
target
,
Ts
&&
...
args
)
template
<
class
Target
,
typename
...
T
>
static
inline
bool
shortcut
(
Target
&
target
,
detail
::
tdata
<
T
...
>&
tup
,
typename
util
::
enable_if
<
util
::
tl_binary_forall
<
util
::
type_list
<
T
...
>
,
FilteredPattern
,
std
::
is_convertible
>
>::
type
*
=
0
)
{
typedef
util
::
type_list
<
typename
util
::
rm_ref
<
Ts
>::
type
...
>
incoming
;
std
::
integral_constant
<
bool
,
std
::
is_same
<
incoming
,
Pattern
>::
value
>
token
;
return
_invoke_args
(
token
,
target
,
std
::
forward
<
Ts
>
(
args
)...);
//static_assert(false, "");
util
::
unchecked_apply_tuple
<
bool
>
(
target
,
tup
);
return
true
;
}
template
<
class
Target
,
typename
NativeArg
,
typename
Tuple
>
static
bool
invoke
_tuple
(
Target
&
target
,
static
bool
invoke
(
Target
&
target
,
std
::
type_info
const
&
arg_types
,
detail
::
tuple_impl_info
timpl
,
NativeArg
native_arg
,
NativeArg
*
native_arg
,
Tuple
&
tup
)
{
if
(
shortcut
(
target
,
tup
))
return
true
;
if
(
arg_types
==
typeid
(
FilteredPattern
))
{
if
(
native_arg
)
{
typedef
typename
util
::
if_else_c
<
std
::
is_const
<
typename
std
::
remove_pointer
<
NativeArg
>::
type
>::
value
,
std
::
is_const
<
NativeArg
>::
value
,
native_data_type
const
*
,
util
::
wrapped
<
native_data_type
*>
>::
type
...
...
@@ -200,8 +217,6 @@ struct invoke_policy_impl<wildcard_position::nil, Pattern, FilteredPattern>
}
// either dynamically typed or statically typed but not a native tuple
// Tup::types is a type list with const qualified types if
// Tup represents 'encapsulated arguments'
typedef
typename
detail
::
tdata_from_type_list
<
typename
util
::
tl_map
<
typename
util
::
if_else
<
...
...
@@ -240,8 +255,9 @@ struct deduce_tup_type<wildcard_position::trailing, Tuple, FilteredPattern>
{
typedef
typename
detail
::
tdata_from_type_list
<
typename
util
::
tl_map
<
typename
util
::
tl_
first_n
<
typename
util
::
tl_
slice
<
typename
Tuple
::
types
,
0
,
FilteredPattern
::
size
>::
type
,
gref_mutable_wrapped
...
...
@@ -286,13 +302,12 @@ template<class Pattern, class FilteredPattern>
struct
invoke_policy_impl
<
wildcard_position
::
trailing
,
Pattern
,
FilteredPattern
>
{
template
<
class
Target
,
typename
NativeArg
,
class
Tuple
>
static
bool
invoke
_tuple
(
Target
&
target
,
static
bool
invoke
(
Target
&
target
,
std
::
type_info
const
&
,
detail
::
tuple_impl_info
,
NativeArg
,
Tuple
&
tup
)
{
cout
<<
__LINE__
<<
endl
;
typedef
typename
detail
::
static_types_array_from_type_list
<
FilteredPattern
>::
type
...
...
@@ -330,91 +345,11 @@ cout << __LINE__ << endl;
template
<
class
Pattern
>
struct
invoke_policy
{
typedef
typename
util
::
tl_filter_not_type
<
Pattern
,
anything
>::
type
filtered_pattern
;
static
constexpr
wildcard_position
wc_pos
=
get_wildcard_position
<
Pattern
>
();
typedef
invoke_policy_impl
<
:
invoke_policy_impl
<
get_wildcard_position
<
Pattern
>
(),
Pattern
,
filtered_pattern
>
impl
;
typedef
typename
detail
::
tdata_from_type_list
<
filtered_pattern
>::
type
native_data_type
;
template
<
typename
Target
,
typename
...
Ts
>
static
bool
_invoke_args
(
std
::
integral_constant
<
bool
,
false
>
,
Target
&
,
Ts
&&
...)
{
return
false
;
}
template
<
typename
Target
,
typename
...
Ts
>
static
bool
_invoke_args
(
std
::
integral_constant
<
bool
,
true
>
,
Target
&
target
,
Ts
&&
...
args
)
{
detail
::
tdata
<
std
::
reference_wrapper
<
typename
std
::
remove_reference
<
Ts
>::
type
>
...
>
wrapped_args
{
std
::
forward
<
Ts
>
(
args
)...};
auto
const
&
arg_types
=
typeid
(
util
::
type_list
<
typename
util
::
rm_ref
<
Ts
>::
type
...
>
);
return
impl
::
invoke_tuple
(
target
,
arg_types
,
detail
::
statically_typed
,
static_cast
<
native_data_type
*>
(
nullptr
),
wrapped_args
);
}
template
<
typename
Target
,
typename
...
Ts
>
static
bool
invoke_args
(
std
::
integral_constant
<
bool
,
false
>
,
Target
&
target
,
Ts
&&
...
args
)
{
std
::
integral_constant
<
bool
,
sizeof
...(
Ts
)
>=
filtered_pattern
::
size
>
x
;
return
_invoke_args
(
x
,
target
,
std
::
forward
<
Ts
>
(
args
)...);
}
template
<
typename
Target
,
typename
...
Ts
>
static
bool
invoke_args
(
std
::
integral_constant
<
bool
,
true
>
,
Target
&
target
,
Ts
&&
...
args
)
{
return
impl
::
invoke_args
(
target
,
std
::
forward
<
Ts
>
(
args
)...);
}
template
<
typename
Target
,
typename
...
Ts
>
static
bool
invoke
(
Target
&
target
,
Ts
&&
...
args
)
{
std
::
integral_constant
<
bool
,
wc_pos
==
wildcard_position
::
nil
>
token
;
return
invoke_args
(
token
,
target
,
std
::
forward
<
Ts
>
(
args
)...);
}
template
<
class
Target
>
static
bool
invoke
(
Target
&
target
,
std
::
type_info
const
&
arg0
,
detail
::
tuple_impl_info
arg1
,
void
const
*
arg2
,
detail
::
abstract_tuple
const
&
arg3
)
{
return
impl
::
invoke_tuple
(
target
,
arg0
,
arg1
,
arg2
,
arg3
);
}
template
<
typename
Target
>
static
bool
invoke
(
Target
&
target
,
std
::
type_info
const
&
arg1
,
detail
::
tuple_impl_info
arg2
,
void
*
arg3
,
detail
::
abstract_tuple
&
arg4
)
{
return
impl
::
invoke_tuple
(
target
,
arg1
,
arg2
,
arg3
,
arg4
);
}
typename
util
::
tl_filter_not_type
<
Pattern
,
anything
>::
type
>
{
};
template
<
class
PartialFun
>
...
...
@@ -440,6 +375,85 @@ struct add_const_ref
typedef
T
const
&
type
;
};
template
<
bool
IsInvokable
,
typename
T
>
struct
pj_wrap_
{
typedef
T
type
;
};
template
<
typename
T
>
struct
pj_wrap_
<
true
,
T
>
{
typedef
typename
util
::
get_callable_trait
<
T
>::
type
ctrait
;
typedef
typename
util
::
rm_option
<
typename
ctrait
::
result_type
>::
type
type
;
};
template
<
typename
T
>
struct
pj_wrap_
<
false
,
ge_mutable_reference_wrapper
<
T
>&>
{
typedef
ge_mutable_reference_wrapper
<
T
>
type
;
};
template
<
typename
T
>
struct
pj_wrap_
<
false
,
ge_mutable_reference_wrapper
<
T
>
const
&>
{
typedef
ge_mutable_reference_wrapper
<
T
>
type
;
};
template
<
typename
T
>
struct
pj_wrap_
<
false
,
T
&>
{
typedef
ge_mutable_reference_wrapper
<
T
>
type
;
};
template
<
typename
T
>
struct
pj_wrap
{
typedef
typename
pj_wrap_
<
util
::
is_callable
<
T
>::
value
,
T
>::
type
type
;
};
template
<
typename
T
>
struct
result_inference
{
typedef
typename
util
::
rm_option
<
typename
util
::
get_result_type
<
T
>::
type
>::
type
type
;
};
template
<
>
struct
result_inference
<
util
::
void_type
>
{
typedef
util
::
void_type
type
;
};
template
<
typename
T0
,
typename
T1
>
struct
mutable_ref_inference
{
typedef
T1
type
;
};
template
<
typename
T
>
struct
mutable_ref_inference
<
T
&
,
T
>
{
typedef
T
&
type
;
};
template
<
typename
T
>
struct
wrap_ref
{
typedef
T
type
;
};
template
<
typename
T
>
struct
wrap_ref
<
ge_mutable_reference_wrapper
<
T
>&>
{
typedef
ge_mutable_reference_wrapper
<
T
>
type
;
};
template
<
typename
T
>
struct
wrap_ref
<
T
&>
{
typedef
ge_mutable_reference_wrapper
<
T
>
type
;
};
/**
* @brief Projection implemented by a set of functors.
*/
...
...
@@ -460,50 +474,47 @@ class projection
pattern_type
,
anything
>::
type
filtered_pattern
_type
;
filtered_pattern
;
static_assert
(
ProjectionFuns
::
size
<=
filtered_pattern
_type
::
size
,
static_assert
(
ProjectionFuns
::
size
<=
filtered_pattern
::
size
,
"invalid projection (too many functions)"
);
typedef
TargetSignature
arg_types
;
typedef
typename
util
::
tl_pad_left
<
TargetSignature
,
filtered_pattern
::
size
>::
type
padded_signature
;
// fill arg_types with first arguments of const-references
// deduced from filtered_pattern_type
typedef
typename
util
::
tl_zipped_map
<
typedef
typename
util
::
tl_zip
<
typename
util
::
tl_zip
<
typename
util
::
tl_pad_left
<
arg_types
,
filtered_pattern_type
::
size
,
util
::
void_type
typename
util
::
tl_map
<
ProjectionFuns
,
result_inference
>::
type
,
filtered_pattern
::
size
>::
type
,
padded_signature
,
util
::
left_or_right
>::
type
,
typename
util
::
tl_map
<
filtered_pattern_type
,
filtered_pattern
,
add_const_ref
>::
type
>::
type
,
util
::
left_or_right
>::
type
fill
ed_arg_types
;
project
ed_arg_types
;
// get a container that manages const and non-const references
typedef
typename
util
::
tl_zipped_map
<
typename
util
::
tl_zip
<
filled_arg_types
,
typename
util
::
tl_pad_right
<
ProjectionFuns
,
filtered_pattern_type
::
size
,
util
::
void_type
>::
type
/*
typedef typename util::tl_zip<
padded_signature,
typename util::tl_map<
filtered_pattern,
add_const_ref
>::type,
cf_transformed_type
util::left_or_right
>::type
projection_map
;
typedef
typename
util
::
tl_map
<
projection_map
,
cf_unwrap
>::
type
projected_arg_types;
typedef
typename
detail
::
tdata_from_type_list
<
projection_map
>::
type
collected_arg_types
;
*/
projection
(
fun_container
const
&
args
)
:
m_funs
(
args
)
{
...
...
@@ -511,89 +522,66 @@ class projection
projection
(
projection
const
&
)
=
default
;
/**
* @brief Invokes @p fun with a projection of <tt>args...</tt>.
*/
template
<
class
PartialFun
,
typename
...
Args
>
bool
_arg_impl
(
std
::
integral_constant
<
bool
,
true
>
,
PartialFun
&
fun
,
Args
&&
...
args
)
const
{
collected_arg_types
pargs
;
if
(
collect
(
pargs
,
m_funs
,
std
::
forward
<
Args
>
(
args
)...))
bool
operator
()(
PartialFun
&
fun
,
Args
&&
...
args
)
const
{
projection_helper
<
PartialFun
>
helper
{
fun
};
return
util
::
unchecked_apply_tuple
<
bool
>
(
helper
,
pargs
);
}
return
false
;
static
constexpr
bool
can_collect
=
util
::
tl_binary_forall
<
util
::
type_list
<
Args
...
>
,
typename
util
::
tl_zip
<
padded_signature
,
filtered_pattern
,
mutable_ref_inference
>::
type
,
std
::
is_convertible
>::
value
;
std
::
integral_constant
<
bool
,
can_collect
>
token
;
return
invoke
(
token
,
fun
,
std
::
forward
<
Args
>
(
args
)...);
}
private:
template
<
class
PartialFun
,
typename
...
Args
>
inline
bool
_arg_impl
(
std
::
integral_constant
<
bool
,
false
>
,
bool
invoke
(
std
::
integral_constant
<
bool
,
false
>
,
PartialFun
&
,
Args
&&
...
)
const
{
return
false
;
}
template
<
class
PartialFun
,
typename
...
Args
>
bool
_arg_fwd
(
std
::
integral_constant
<
bool
,
fals
e
>
,
PartialFun
&
,
Args
&&
...
)
const
bool
invoke
(
std
::
integral_constant
<
bool
,
tru
e
>
,
PartialFun
&
,
Args
&&
...
)
const
{
return
false
;
}
/*
typedef typename util::tl_map<
projected_arg_types,
wrap_ref
>::type
collected_arg_types;
template
<
class
PartialFun
,
typename
...
Args
>
bool
_arg_fwd
(
std
::
integral_constant
<
bool
,
true
>
,
PartialFun
&
fun
,
Args
&&
...
args
)
const
//typedef projected_arg_types collected_arg_types;
typename detail::tdata_from_type_list<collected_arg_types>::type pargs;
if (collect(pargs, m_funs, std::forward<Args>(args)...))
{
typedef
util
::
type_list
<
typename
util
::
rm_ref
<
Args
>::
type
...
>
incoming
;
std
::
integral_constant
<
bool
,
util
::
tl_zipped_forall
<
typename
util
::
tl_zip
<
incoming
,
filtered_pattern_type
>::
type
,
std
::
is_convertible
>::
value
>
token
;
return
_arg_impl
(
token
,
fun
,
std
::
forward
<
Args
>
(
args
)...);
projection_helper<PartialFun> helper{fun};
return util::unchecked_apply_tuple<bool>(helper, pargs);
}
/**
* @brief Invokes @p fun with a projection of <tt>args...</tt>.
*/
template
<
class
PartialFun
,
typename
...
Args
>
bool
operator
()(
PartialFun
&
fun
,
Args
&&
...
args
)
const
{
std
::
integral_constant
<
bool
,
sizeof
...(
Args
)
==
filtered_pattern_type
::
size
>
token
;
return
_arg_fwd
(
token
,
fun
,
std
::
forward
<
Args
>
(
args
)...);
return
false
;
}
private:
template
<
typename
Storage
,
typename
T
>
static
inline
bool
fetch_
(
Storage
&
storage
,
T
&
value
)
static
inline
bool
fetch_
(
Storage
&
storage
,
T
&
&
value
)
{
storage
=
value
;
storage
=
std
::
forward
<
T
>
(
value
)
;
return
true
;
}
template
<
typename
T
>
static
inline
bool
fetch_
(
T
&
,
T
const
&
)
{
return
false
;
}
template
<
typename
T
>
static
inline
bool
fetch_
(
ge_mutable_reference_wrapper
<
T
>&
,
ge_mutable_reference_wrapper
<
const
T
>&
)
{
return
false
;
}
template
<
typename
T
>
static
inline
bool
fetch_
(
ge_mutable_reference_wrapper
<
T
>&
,
T
const
&
)
{
return
false
;
}
template
<
class
Storage
>
static
inline
bool
fetch_
(
Storage
&
storage
,
option
<
Storage
>&&
value
)
{
...
...
@@ -612,12 +600,9 @@ class projection
}
template
<
typename
Storage
,
typename
T
>
static
inline
bool
fetch
(
Storage
&
storage
,
util
::
void_type
const
&
,
T
&&
value
)
static
inline
bool
fetch
(
Storage
&
storage
,
util
::
void_type
const
&
,
T
&&
arg
)
{
storage
=
std
::
forward
<
T
>
(
value
);
return
true
;
return
fetch_
(
storage
,
std
::
forward
<
T
>
(
arg
));
}
static
inline
bool
collect
(
detail
::
tdata
<>&
,
detail
::
tdata
<>
const
&
)
...
...
@@ -625,16 +610,6 @@ class projection
return
true
;
}
template
<
class
TData
,
typename
T0
,
typename
...
Ts
>
static
inline
bool
collect
(
TData
&
td
,
detail
::
tdata
<>
const
&
tr
,
T0
&&
arg0
,
Ts
&&
...
args
)
{
return
fetch_
(
td
.
head
,
std
::
forward
<
T0
>
(
arg0
))
&&
collect
(
td
.
tail
(),
tr
.
tail
(),
std
::
forward
<
Ts
>
(
args
)...);
//td.set(std::forward<T0>(arg0), std::forward<Ts>(args)...);
return
true
;
}
template
<
class
TData
,
class
Trans
,
typename
T0
,
typename
...
Ts
>
static
inline
bool
collect
(
TData
&
td
,
Trans
const
&
tr
,
T0
&&
arg0
,
Ts
&&
...
args
)
...
...
@@ -645,37 +620,6 @@ class projection
};
/*
template<class Pattern, class TargetSignature>
class projection<Pattern, TargetSignature, util::type_list<> >
{
public:
typedef Pattern pattern_type;
typedef typename util::tl_filter_not_type<
pattern_type,
anything
>::type
filtered_pattern_type;
typedef filtered_pattern_type projected_arg_types;
projection(detail::tdata<>) { }
projection(projection&&) = default;
projection(projection const&) = default;
template<class PartialFun, typename... Args>
bool operator()(PartialFun& fun, Args&&... args) const
{
projection_helper<PartialFun> helper{fun};
return helper(std::forward<Args>(args)...);
}
};
*/
template
<
class
Expr
,
class
Guard
,
class
Transformers
,
class
Pattern
>
struct
get_cfl
{
...
...
@@ -731,6 +675,7 @@ struct invoke_helper2
template
<
typename
...
Args
>
bool
operator
()(
Args
&&
...
args
)
const
{
//static_assert(false, "foo");
Token
token
;
invoke_helper3
<
Data
>
fun
{
data
};
return
util
::
static_foreach
<
0
,
Token
::
size
>::
eval_or
(
token
,
fun
,
std
::
forward
<
Args
>
(
args
)...);
...
...
@@ -788,51 +733,6 @@ struct is_manipulator_leaf<std::pair<First, Second> >
static
constexpr
bool
value
=
Second
::
manipulates_args
;
};
template
<
bool
ManipulatesArgs
,
class
EvalOrder
>
struct
pjf_invoke
{
template
<
typename
Leaves
>
static
bool
_
(
Leaves
const
&
leaves
,
any_tuple
const
&
tup
)
{
EvalOrder
token
;
invoke_helper
<
decltype
(
leaves
)
>
fun
{
leaves
};
auto
const
&
cvals
=
*
(
tup
.
cvals
());
return
util
::
static_foreach
<
0
,
EvalOrder
::
size
>
::
eval_or
(
token
,
fun
,
*
(
cvals
.
type_token
()),
cvals
.
impl_type
(),
cvals
.
native_data
(),
cvals
);
}
};
template
<
class
EvalOrder
>
struct
pjf_invoke
<
true
,
EvalOrder
>
{
template
<
typename
Leaves
>
static
bool
_
(
Leaves
const
&
leaves
,
any_tuple
&
tup
)
{
EvalOrder
token
;
invoke_helper
<
decltype
(
leaves
)
>
fun
{
leaves
};
tup
.
force_detach
();
auto
&
vals
=
*
(
tup
.
vals
());
return
util
::
static_foreach
<
0
,
EvalOrder
::
size
>
::
eval_or
(
token
,
fun
,
*
(
vals
.
type_token
()),
vals
.
impl_type
(),
vals
.
mutable_native_data
(),
vals
);
}
template
<
typename
Leaves
>
static
bool
_
(
Leaves
const
&
leaves
,
any_tuple
const
&
tup
)
{
any_tuple
tup_copy
{
tup
};
return
_
(
leaves
,
tup_copy
);
}
};
void
collect_tdata
(
detail
::
tdata
<>&
)
{
}
...
...
@@ -850,6 +750,37 @@ void collect_tdata(Storage& storage, Arg0 const& arg0, Args const&... args)
collect_tdata
(
storage
.
tail
(),
arg0
.
tail
(),
args
...);
}
template
<
bool
IsManipulator
,
typename
T0
,
typename
T1
>
struct
pj_fwd_
{
typedef
T1
type
;
};
template
<
bool
IsManipulator
,
typename
T
>
struct
pj_fwd_
<
IsManipulator
,
T
const
&
,
T
>
{
typedef
std
::
reference_wrapper
<
const
T
>
type
;
};
template
<
typename
T
>
struct
pj_fwd_
<
true
,
T
&
,
T
>
{
typedef
std
::
reference_wrapper
<
T
>
type
;
};
template
<
bool
IsManipulator
,
typename
T
>
struct
pj_fwd
{
typedef
typename
pj_fwd_
<
IsManipulator
,
T
,
typename
detail
::
implicit_conversions
<
typename
util
::
rm_ref
<
T
>::
type
>::
type
>::
type
type
;
};
/**
* @brief A function that works on the projection of given data rather than
* on the data itself.
...
...
@@ -879,16 +810,47 @@ class projected_fun
projected_fun
(
projected_fun
const
&
)
=
default
;
bool
_invoke
(
any_tuple
const
&
tup
)
const
{
eval_order
token
;
invoke_helper
<
decltype
(
m_leaves
)
>
fun
{
m_leaves
};
auto
&
cvals
=
*
(
tup
.
cvals
());
return
util
::
static_foreach
<
0
,
eval_order
::
size
>
::
eval_or
(
token
,
fun
,
*
(
cvals
.
type_token
()),
cvals
.
impl_type
(),
cvals
.
native_data
(),
cvals
);
}
bool
_invoke
(
any_tuple
&
tup
)
const
{
eval_order
token
;
invoke_helper
<
decltype
(
m_leaves
)
>
fun
{
m_leaves
};
tup
.
force_detach
();
auto
&
vals
=
*
(
tup
.
vals
());
return
util
::
static_foreach
<
0
,
eval_order
::
size
>
::
eval_or
(
token
,
fun
,
*
(
vals
.
type_token
()),
vals
.
impl_type
(),
vals
.
mutable_native_data
(),
vals
);
}
bool
invoke
(
any_tuple
const
&
tup
)
const
{
return
pjf_invoke
<
has_manipulator
,
eval_order
>
::
_
(
m_leaves
,
tup
);
if
(
has_manipulator
)
return
invoke
(
any_tuple
{
tup
});
return
_invoke
(
tup
);
}
bool
invoke
(
any_tuple
&
tup
)
const
{
return
pjf_invoke
<
has_manipulator
,
eval_order
>
::
_
(
m_leaves
,
tup
);
if
(
!
has_manipulator
)
return
_invoke
(
static_cast
<
any_tuple
const
&>
(
tup
));
return
_invoke
(
tup
);
}
bool
invoke
(
any_tuple
&&
tup
)
const
...
...
@@ -898,19 +860,36 @@ class projected_fun
}
template
<
typename
...
Args
>
bool
invoke_args
(
Args
&&
...
args
)
const
bool
operator
()
(
Args
&&
...
args
)
const
{
typedef
detail
::
tdata
<
typename
pj_fwd
<
has_manipulator
,
Args
>::
type
...
>
tuple_type
;
// applies implicit conversions etc
tuple_type
tup
{
std
::
forward
<
Args
>
(
args
)...};
typedef
typename
util
::
if_else_c
<
has_manipulator
,
tuple_type
&
,
util
::
wrapped
<
tuple_type
const
&>
>::
type
ref_type
;
typedef
typename
util
::
if_else_c
<
has_manipulator
,
void
*
,
util
::
wrapped
<
void
const
*>
>::
type
ptr_type
;
eval_order
token
;
invoke_helper
<
decltype
(
m_leaves
)
>
fun
{
m_leaves
};
return
util
::
static_foreach
<
0
,
eval_order
::
size
>
::
eval_or
(
token
,
fun
,
std
::
forward
<
Args
>
(
args
)...);
}
template
<
typename
...
Args
>
bool
operator
()(
Args
&&
...
args
)
const
{
// applies implicit conversions and passes rvalues as const lvalue refs
return
invoke_args
(
pjf_fwd
<
Args
>::
_
(
args
)...);
::
eval_or
(
token
,
fun
,
typeid
(
util
::
type_list
<
typename
util
::
rm_ref
<
Args
>::
type
...
>
),
detail
::
statically_typed
,
static_cast
<
ptr_type
>
(
nullptr
),
static_cast
<
ref_type
>
(
tup
));
}
template
<
class
...
Rhs
>
...
...
@@ -1270,6 +1249,7 @@ size_t test__tuple()
{
CPPA_TEST
(
test__tuple
);
/*
using namespace cppa::placeholders;
typedef typename util::tl_group_by<zz0, std::is_same>::type zz1;
...
...
@@ -1410,7 +1390,9 @@ size_t test__tuple()
CPPA_CHECK(f11("10"));
CPPA_CHECK_EQUAL(10, f11_fun);
//exit(0);
exit(0);
*/
/*
VERBOSE(f00(42, 42));
...
...
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