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
54ea98cb
Commit
54ea98cb
authored
Feb 09, 2018
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reduce metaprogramming noise in variant::apply
parent
58fc8dd8
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
47 additions
and
42 deletions
+47
-42
libcaf_core/caf/variant.hpp
libcaf_core/caf/variant.hpp
+47
-42
No files found.
libcaf_core/caf/variant.hpp
View file @
54ea98cb
...
@@ -48,6 +48,10 @@ namespace caf {
...
@@ -48,6 +48,10 @@ namespace caf {
constexpr
size_t
variant_npos
=
static_cast
<
size_t
>
(
-
1
);
constexpr
size_t
variant_npos
=
static_cast
<
size_t
>
(
-
1
);
struct
variant_marker_t
{};
constexpr
variant_marker_t
variant_marker
=
variant_marker_t
{};
template
<
class
T
>
template
<
class
T
>
struct
variant_assign_helper
{
struct
variant_assign_helper
{
using
result_type
=
void
;
using
result_type
=
void
;
...
@@ -70,6 +74,17 @@ struct variant_move_helper {
...
@@ -70,6 +74,17 @@ struct variant_move_helper {
}
}
};
};
template
<
class
F
,
class
...
Ts
>
struct
variant_visit_result
{
using
type
=
decltype
((
std
::
declval
<
F
&>
())(
std
::
declval
<
typename
Ts
::
type0
&>
()...));
};
template
<
class
F
,
class
...
Ts
>
using
variant_visit_result_t
=
typename
variant_visit_result
<
detail
::
decay_t
<
F
>
,
detail
::
decay_t
<
Ts
>
...
>::
type
;
template
<
class
T
,
class
U
,
template
<
class
T
,
class
U
,
bool
Enable
=
std
::
is_integral
<
T
>
::
value
bool
Enable
=
std
::
is_integral
<
T
>
::
value
&&
std
::
is_integral
<
U
>::
value
&&
std
::
is_integral
<
U
>::
value
...
@@ -114,13 +129,13 @@ public:
...
@@ -114,13 +129,13 @@ public:
variant
&
operator
=
(
const
variant
&
other
)
{
variant
&
operator
=
(
const
variant
&
other
)
{
variant_assign_helper
<
variant
>
helper
{
*
this
};
variant_assign_helper
<
variant
>
helper
{
*
this
};
other
.
apply
(
helper
);
other
.
template
apply
<
void
>
(
helper
);
return
*
this
;
return
*
this
;
}
}
variant
&
operator
=
(
variant
&&
other
)
{
variant
&
operator
=
(
variant
&&
other
)
{
variant_move_helper
<
variant
>
helper
{
*
this
};
variant_move_helper
<
variant
>
helper
{
*
this
};
other
.
apply
(
helper
);
other
.
template
apply
<
void
>
(
helper
);
return
*
this
;
return
*
this
;
}
}
...
@@ -144,12 +159,12 @@ public:
...
@@ -144,12 +159,12 @@ public:
variant
(
const
variant
&
other
)
:
type_
(
variant_npos
)
{
variant
(
const
variant
&
other
)
:
type_
(
variant_npos
)
{
variant_assign_helper
<
variant
>
helper
{
*
this
};
variant_assign_helper
<
variant
>
helper
{
*
this
};
other
.
apply
(
helper
);
other
.
template
apply
<
void
>
(
helper
);
}
}
variant
(
variant
&&
other
)
:
type_
(
variant_npos
)
{
variant
(
variant
&&
other
)
:
type_
(
variant_npos
)
{
variant_move_helper
<
variant
>
helper
{
*
this
};
variant_move_helper
<
variant
>
helper
{
*
this
};
other
.
apply
(
helper
);
other
.
template
apply
<
void
>
(
helper
);
}
}
~
variant
()
{
~
variant
()
{
...
@@ -191,21 +206,20 @@ public:
...
@@ -191,21 +206,20 @@ public:
return
data_
.
get
(
token
);
return
data_
.
get
(
token
);
}
}
template
<
class
Visitor
>
template
<
class
Result
,
class
Visitor
>
auto
apply
(
Visitor
&&
visitor
)
const
Result
apply
(
Visitor
&&
visitor
)
const
{
->
decltype
(
visitor
(
std
::
declval
<
const
type0
&>
()))
{
return
apply_impl
<
Result
>
(
*
this
,
std
::
forward
<
Visitor
>
(
visitor
),
return
apply_impl
(
*
this
,
std
::
forward
<
Visitor
>
(
visitor
)
);
variant_marker
);
}
}
template
<
class
Visitor
>
template
<
class
Result
,
class
Visitor
>
auto
apply
(
Visitor
&&
visitor
)
->
decltype
(
visitor
(
std
::
declval
<
type0
&>
()))
{
Result
apply
(
Visitor
&&
visitor
)
{
return
apply_impl
(
*
this
,
std
::
forward
<
Visitor
>
(
visitor
));
return
apply_impl
<
Result
>
(
*
this
,
std
::
forward
<
Visitor
>
(
visitor
),
variant_marker
);
}
}
template
<
class
Self
,
class
Visitor
>
template
<
class
Result
,
class
Self
,
class
Visitor
>
static
auto
apply_impl
(
Self
&
x
,
Visitor
&&
f
)
->
decltype
(
static
Result
apply_impl
(
Self
&
x
,
Visitor
&&
f
,
variant_marker_t
)
{
f
(
std
::
declval
<
typename
std
::
conditional
<
std
::
is_const
<
Self
>::
value
,
const
type0
,
type0
>::
type
&>
()))
{
switch
(
x
.
type_
)
{
switch
(
x
.
type_
)
{
default:
CAF_RAISE_ERROR
(
"invalid type found"
);
default:
CAF_RAISE_ERROR
(
"invalid type found"
);
CAF_VARIANT_CASE
(
0
);
CAF_VARIANT_CASE
(
0
);
...
@@ -236,7 +250,7 @@ private:
...
@@ -236,7 +250,7 @@ private:
inline
void
destroy_data
()
{
inline
void
destroy_data
()
{
if
(
type_
==
variant_npos
)
return
;
// nothing to do
if
(
type_
==
variant_npos
)
return
;
// nothing to do
detail
::
variant_data_destructor
f
;
detail
::
variant_data_destructor
f
;
apply
(
f
);
apply
<
void
>
(
f
);
}
}
template
<
class
U
>
template
<
class
U
>
...
@@ -267,7 +281,7 @@ private:
...
@@ -267,7 +281,7 @@ private:
"unless the element types of A are a strict subset of "
"unless the element types of A are a strict subset of "
"the element types of B"
);
"the element types of B"
);
variant_assign_helper
<
variant
>
helper
{
*
this
};
variant_assign_helper
<
variant
>
helper
{
*
this
};
other
.
apply
(
helper
);
other
.
template
apply
<
void
>
(
helper
);
}
}
template
<
class
...
Us
>
template
<
class
...
Us
>
...
@@ -283,7 +297,7 @@ private:
...
@@ -283,7 +297,7 @@ private:
"unless the element types of A are a strict subset of "
"unless the element types of A are a strict subset of "
"the element types of B"
);
"the element types of B"
);
variant_move_helper
<
variant
>
helper
{
*
this
};
variant_move_helper
<
variant
>
helper
{
*
this
};
other
.
apply
(
helper
);
other
.
template
apply
<
void
>
(
helper
);
}
}
size_t
type_
;
size_t
type_
;
...
@@ -296,6 +310,15 @@ struct is_variant : std::false_type {};
...
@@ -296,6 +310,15 @@ struct is_variant : std::false_type {};
template
<
class
...
Ts
>
template
<
class
...
Ts
>
struct
is_variant
<
variant
<
Ts
...
>>
:
std
::
true_type
{};
struct
is_variant
<
variant
<
Ts
...
>>
:
std
::
true_type
{};
template
<
class
...
Ts
>
struct
is_variant
<
variant
<
Ts
...
>&>
:
std
::
true_type
{};
template
<
class
...
Ts
>
struct
is_variant
<
const
variant
<
Ts
...
>&>
:
std
::
true_type
{};
template
<
class
...
Ts
>
struct
is_variant
<
const
variant
<
Ts
...
>&&>
:
std
::
true_type
{};
/// @relates variant
/// @relates variant
template
<
class
T
,
class
...
Us
>
template
<
class
T
,
class
...
Us
>
T
&
get
(
variant
<
Us
...
>&
value
)
{
T
&
get
(
variant
<
Us
...
>&
value
)
{
...
@@ -333,28 +356,11 @@ const T* get_if(const variant<Us...>* value) {
...
@@ -333,28 +356,11 @@ const T* get_if(const variant<Us...>* value) {
}
}
/// @relates variant
/// @relates variant
template
<
class
Visitor
,
class
...
Ts
>
template
<
class
Visitor
,
class
Variant
,
class
...
Variants
,
typename
Visitor
::
result_type
class
Result
=
variant_visit_result_t
<
Visitor
,
Variant
,
Variants
...>
>
CAF_DEPRECATED
apply_visitor
(
Visitor
&
visitor
,
const
variant
<
Ts
...
>&
data
)
{
Result
visit
(
Visitor
&&
f
,
Variant
&&
x
,
Variants
&&
...
xs
)
{
return
data
.
apply
(
visitor
);
return
x
.
template
apply
<
Result
>(
std
::
forward
<
Visitor
>
(
f
),
}
std
::
forward
<
Variants
>
(
xs
)...);
/// @relates variant
template
<
class
Visitor
,
class
Variant
,
class
E
=
typename
std
::
enable_if
<
is_variant
<
typename
std
::
decay
<
Variant
>
::
type
>::
value
>::
type
>
auto
visit
(
Visitor
&&
visitor
,
Variant
&&
data
)
->
decltype
(
data
.
apply
(
std
::
forward
<
Visitor
>
(
visitor
)))
{
return
data
.
apply
(
visitor
);
}
/// @relates variant
template
<
class
Visitor
,
class
...
Ts
>
typename
Visitor
::
result_type
CAF_DEPRECATED
apply_visitor
(
Visitor
&
visitor
,
variant
<
Ts
...
>&
data
)
{
return
data
.
apply
(
visitor
);
}
}
template
<
class
T
,
class
...
Ts
>
template
<
class
T
,
class
...
Ts
>
...
@@ -408,8 +414,7 @@ struct variant_reader {
...
@@ -408,8 +414,7 @@ struct variant_reader {
template
<
class
Inspector
,
class
...
Ts
>
template
<
class
Inspector
,
class
...
Ts
>
typename
Inspector
::
result_type
typename
Inspector
::
result_type
inspect
(
Inspector
&
f
,
variant_reader
<
variant
<
Ts
...
>>&
x
)
{
inspect
(
Inspector
&
f
,
variant_reader
<
variant
<
Ts
...
>>&
x
)
{
return
x
.
x
.
apply
(
f
);
return
x
.
x
.
template
apply
<
typename
Inspector
::
result_type
>(
f
);
//return variant<Ts...>::apply_impl(x.x, f);
}
}
/// @relates variant
/// @relates variant
...
...
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