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
11e0d02b
Commit
11e0d02b
authored
Jun 23, 2018
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement SumType trait for config_value
parent
90026f8e
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
237 additions
and
196 deletions
+237
-196
libcaf_core/caf/config_value.hpp
libcaf_core/caf/config_value.hpp
+111
-122
libcaf_core/caf/default_sum_type_access.hpp
libcaf_core/caf/default_sum_type_access.hpp
+20
-11
libcaf_core/caf/fwd.hpp
libcaf_core/caf/fwd.hpp
+0
-25
libcaf_core/caf/make_config_option.hpp
libcaf_core/caf/make_config_option.hpp
+1
-0
libcaf_core/caf/sum_type.hpp
libcaf_core/caf/sum_type.hpp
+35
-38
libcaf_core/caf/sum_type_token.hpp
libcaf_core/caf/sum_type_token.hpp
+30
-0
libcaf_core/test/sum_type_token.cpp
libcaf_core/test/sum_type_token.cpp
+40
-0
No files found.
libcaf_core/caf/config_value.hpp
View file @
11e0d02b
...
@@ -30,6 +30,9 @@
...
@@ -30,6 +30,9 @@
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
#include "caf/optional.hpp"
#include "caf/optional.hpp"
#include "caf/string_algorithms.hpp"
#include "caf/string_algorithms.hpp"
#include "caf/sum_type.hpp"
#include "caf/sum_type_access.hpp"
#include "caf/sum_type_token.hpp"
#include "caf/timestamp.hpp"
#include "caf/timestamp.hpp"
#include "caf/variant.hpp"
#include "caf/variant.hpp"
...
@@ -122,6 +125,16 @@ public:
...
@@ -122,6 +125,16 @@ public:
return
data_
;
return
data_
;
}
}
/// Returns a pointer to the underlying variant.
inline
variant_type
*
get_data_ptr
()
{
return
&
data_
;
}
/// Returns a pointer to the underlying variant.
inline
const
variant_type
*
get_data_ptr
()
const
{
return
&
data_
;
}
private:
private:
// -- properties -------------------------------------------------------------
// -- properties -------------------------------------------------------------
...
@@ -158,54 +171,122 @@ private:
...
@@ -158,54 +171,122 @@ private:
variant_type
data_
;
variant_type
data_
;
};
};
// -- related type aliases -----------------------------------------------------
/// Organizes config values into categories.
/// Organizes config values into categories.
/// @relates config_value
/// @relates config_value
using
config_value_map
=
std
::
map
<
std
::
string
,
config_value
::
dictionary
>
;
using
config_value_map
=
std
::
map
<
std
::
string
,
config_value
::
dictionary
>
;
// -- SumType-like access ------------------------------------------------------
/// @relates config_value
/// @relates config_value
template
<
class
T
>
template
<
class
T
>
struct
config_value_access
{
struct
config_value_access
;
static
constexpr
bool
specialized
=
false
;
/// Delegates to config_value_access for all specialized versions.
template
<
class
T
,
bool
IsIntegral
=
std
::
is_integral
<
T
>
::
value
>
struct
select_config_value_access
{
using
type
=
config_value_access
<
T
>
;
};
/// Catches all non-specialized integer types.
template
<
class
T
>
struct
select_config_value_access
<
T
,
true
>
{
struct
type
{
static
bool
is
(
const
config_value
&
x
)
{
auto
ptr
=
caf
::
get_if
<
typename
config_value
::
integer
>
(
x
.
get_data_ptr
());
return
ptr
!=
nullptr
&&
detail
::
bounds_checker
<
T
>::
check
(
*
ptr
);
}
static
optional
<
T
>
get_if
(
const
config_value
*
x
)
{
auto
ptr
=
caf
::
get_if
<
typename
config_value
::
integer
>
(
x
->
get_data_ptr
());
if
(
ptr
!=
nullptr
&&
detail
::
bounds_checker
<
T
>::
check
(
*
ptr
))
return
static_cast
<
T
>
(
*
ptr
);
return
none
;
}
static
T
get
(
const
config_value
&
x
)
{
auto
res
=
get_if
(
&
x
);
CAF_ASSERT
(
res
!=
none
);
return
*
res
;
}
};
};
};
/// @relates config_value_access
template
<
class
T
>
template
<
class
T
>
struct
default_config_value_access
{
using
select_config_value_access_t
=
typename
select_config_value_access
<
T
>::
type
;
template
<
>
struct
sum_type_access
<
config_value
>
{
using
types
=
typename
config_value
::
types
;
using
type0
=
typename
detail
::
tl_head
<
types
>::
type
;
static
constexpr
bool
specialized
=
true
;
static
constexpr
bool
specialized
=
true
;
static
bool
is
(
const
config_value
&
x
)
{
template
<
class
U
,
int
Pos
>
return
holds_alternative
<
T
>
(
x
.
get_data
());
static
bool
is
(
const
config_value
&
x
,
sum_type_token
<
U
,
Pos
>
token
)
{
return
x
.
get_data
().
is
(
token
.
pos
);
}
}
static
T
*
get_if
(
config_value
*
x
)
{
template
<
class
U
>
return
caf
::
get_if
<
T
>
(
&
(
x
->
get_data
()));
static
bool
is
(
const
config_value
&
x
,
sum_type_token
<
U
,
-
1
>
)
{
return
select_config_value_access_t
<
U
>::
is
(
x
);
}
}
static
const
T
*
get_if
(
const
config_value
*
x
)
{
template
<
class
U
,
int
Pos
>
return
caf
::
get_if
<
T
>
(
&
(
x
->
get_data
()));
static
U
&
get
(
config_value
&
x
,
sum_type_token
<
U
,
Pos
>
token
)
{
return
x
.
get_data
().
get
(
token
.
pos
);
}
}
static
T
&
get
(
config_value
&
x
)
{
template
<
class
U
>
return
caf
::
get
<
T
>
(
x
.
get_data
());
static
U
get
(
config_value
&
x
,
sum_type_token
<
U
,
-
1
>
)
{
return
select_config_value_access_t
<
U
>::
get
(
x
);
}
}
static
const
T
&
get
(
const
config_value
&
x
)
{
return
caf
::
get
<
T
>
(
x
.
get_data
());
template
<
class
U
,
int
Pos
>
static
const
U
&
get
(
const
config_value
&
x
,
sum_type_token
<
U
,
Pos
>
token
)
{
return
x
.
get_data
().
get
(
token
.
pos
);
}
}
};
#define CAF_CONFIG_VALUE_DEFAULT_ACCESS(subtype) \
template
<
class
U
>
template <> \
static
U
get
(
const
config_value
&
x
,
sum_type_token
<
U
,
-
1
>
)
{
struct config_value_access<config_value::subtype> \
return
select_config_value_access_t
<
U
>::
get
(
x
);
: default_config_value_access<config_value::subtype> {
}
}
CAF_CONFIG_VALUE_DEFAULT_ACCESS
(
integer
);
template
<
class
U
,
int
Pos
>
CAF_CONFIG_VALUE_DEFAULT_ACCESS
(
boolean
);
static
U
*
get_if
(
config_value
*
x
,
sum_type_token
<
U
,
Pos
>
token
)
{
CAF_CONFIG_VALUE_DEFAULT_ACCESS
(
real
);
return
is
(
*
x
,
token
)
?
&
get
(
*
x
,
token
)
:
nullptr
;
CAF_CONFIG_VALUE_DEFAULT_ACCESS
(
atom
);
}
CAF_CONFIG_VALUE_DEFAULT_ACCESS
(
timespan
);
CAF_CONFIG_VALUE_DEFAULT_ACCESS
(
string
);
template
<
class
U
>
CAF_CONFIG_VALUE_DEFAULT_ACCESS
(
list
);
static
optional
<
U
>
get_if
(
config_value
*
x
,
sum_type_token
<
U
,
-
1
>
)
{
CAF_CONFIG_VALUE_DEFAULT_ACCESS
(
dictionary
);
return
select_config_value_access_t
<
U
>::
get_if
(
x
);
}
template
<
class
U
,
int
Pos
>
static
const
U
*
get_if
(
const
config_value
*
x
,
sum_type_token
<
U
,
Pos
>
token
)
{
return
is
(
*
x
,
token
)
?
&
get
(
*
x
,
token
)
:
nullptr
;
}
template
<
class
U
>
static
optional
<
U
>
get_if
(
const
config_value
*
x
,
sum_type_token
<
U
,
-
1
>
)
{
return
select_config_value_access_t
<
U
>::
get_if
(
x
);
}
template
<
class
Result
,
class
Visitor
,
class
...
Ts
>
static
Result
apply
(
config_value
&
x
,
Visitor
&&
visitor
,
Ts
&&
...
xs
)
{
return
x
.
get_data
().
template
apply
<
Result
>(
std
::
forward
<
Visitor
>
(
visitor
),
std
::
forward
<
Ts
>
(
xs
)...);
}
template
<
class
Result
,
class
Visitor
,
class
...
Ts
>
static
Result
apply
(
const
config_value
&
x
,
Visitor
&&
visitor
,
Ts
&&
...
xs
)
{
return
x
.
get_data
().
template
apply
<
Result
>(
std
::
forward
<
Visitor
>
(
visitor
),
std
::
forward
<
Ts
>
(
xs
)...);
}
};
template
<
>
template
<
>
struct
config_value_access
<
float
>
{
struct
config_value_access
<
float
>
{
...
@@ -285,7 +366,7 @@ struct config_value_access<std::map<std::string, V>> {
...
@@ -285,7 +366,7 @@ struct config_value_access<std::map<std::string, V>> {
auto
lst
=
caf
::
get_if
<
config_value
::
dictionary
>
(
&
x
);
auto
lst
=
caf
::
get_if
<
config_value
::
dictionary
>
(
&
x
);
if
(
lst
!=
nullptr
)
{
if
(
lst
!=
nullptr
)
{
return
std
::
all_of
(
lst
->
begin
(),
lst
->
end
(),
[](
const
kvp
&
x
)
{
return
std
::
all_of
(
lst
->
begin
(),
lst
->
end
(),
[](
const
kvp
&
x
)
{
return
config_value_access
<
V
>::
is
(
x
.
second
);
return
holds_alternative
<
V
>
(
x
.
second
);
});
});
}
}
return
false
;
return
false
;
...
@@ -315,6 +396,8 @@ struct config_value_access<std::map<std::string, V>> {
...
@@ -315,6 +396,8 @@ struct config_value_access<std::map<std::string, V>> {
}
}
};
};
// -- SumType-like access of dictionary values ---------------------------------
/// Tries to retrieve the value associated to `name` from `xs`.
/// Tries to retrieve the value associated to `name` from `xs`.
/// @relates config_value
/// @relates config_value
template
<
class
T
>
template
<
class
T
>
...
@@ -446,100 +529,6 @@ T get_or(const actor_system_config& cfg, const std::string& name,
...
@@ -446,100 +529,6 @@ T get_or(const actor_system_config& cfg, const std::string& name,
std
::
string
get_or
(
const
actor_system_config
&
cfg
,
const
std
::
string
&
name
,
std
::
string
get_or
(
const
actor_system_config
&
cfg
,
const
std
::
string
&
name
,
const
char
*
default_value
);
const
char
*
default_value
);
// -- SumType-like access ------------------------------------------------------
/// Delegates to config_value_access for all specialized versions.
template
<
class
T
,
bool
Specialized
=
config_value_access
<
T
>
::
specialized
>
struct
select_config_value_access
{
using
type
=
config_value_access
<
T
>
;
};
/// Catches all non-specialized integer types.
template
<
class
T
>
struct
select_config_value_access
<
T
,
false
>
{
static_assert
(
std
::
is_integral
<
T
>::
value
,
"T must be integral or specialize config_value_access"
);
struct
type
{
static
bool
is
(
const
config_value
&
x
)
{
using
cvi
=
typename
config_value
::
integer
;
auto
ptr
=
config_value_access
<
cvi
>::
get_if
(
&
x
);
return
ptr
!=
nullptr
&&
detail
::
bounds_checker
<
T
>::
check
(
*
ptr
);
}
static
optional
<
T
>
get_if
(
const
config_value
*
x
)
{
using
cvi
=
typename
config_value
::
integer
;
auto
ptr
=
config_value_access
<
cvi
>::
get_if
(
x
);
if
(
ptr
!=
nullptr
&&
detail
::
bounds_checker
<
T
>::
check
(
*
ptr
))
return
static_cast
<
T
>
(
*
ptr
);
return
none
;
}
static
T
get
(
const
config_value
&
x
)
{
auto
res
=
get_if
(
&
x
);
CAF_ASSERT
(
res
!=
none
);
return
*
res
;
}
};
};
template
<
class
T
>
using
select_config_value_access_t
=
typename
select_config_value_access
<
T
>::
type
;
/// @relates config_value
template
<
class
T
>
bool
holds_alternative
(
const
config_value
&
x
)
{
return
select_config_value_access_t
<
T
>::
is
(
x
);
}
/// @relates config_value
template
<
class
T
>
typename
std
::
conditional
<
detail
::
is_primitive_config_value
<
T
>::
value
,
const
T
*
,
optional
<
T
>>::
type
get_if
(
const
config_value
*
x
)
{
return
select_config_value_access_t
<
T
>::
get_if
(
x
);
}
/// @relates config_value
template
<
class
T
>
typename
std
::
conditional
<
detail
::
is_primitive_config_value
<
T
>::
value
,
T
*
,
optional
<
T
>>::
type
get_if
(
config_value
*
x
)
{
return
select_config_value_access_t
<
T
>::
get_if
(
x
);
}
/// @relates config_value
template
<
class
T
>
typename
std
::
conditional
<
detail
::
is_primitive_config_value
<
T
>::
value
,
const
T
&
,
T
>::
type
get
(
const
config_value
&
x
)
{
return
select_config_value_access_t
<
T
>::
get
(
x
);
}
/// @relates config_value
template
<
class
T
>
typename
std
::
conditional
<
detail
::
is_primitive_config_value
<
T
>::
value
,
T
&
,
T
>::
type
get
(
config_value
&
x
)
{
return
select_config_value_access_t
<
T
>::
get
(
x
);
}
/// @relates config_value
template
<
class
Visitor
>
auto
visit
(
Visitor
&&
f
,
config_value
&
x
)
->
decltype
(
visit
(
std
::
forward
<
Visitor
>
(
f
),
x
.
get_data
()))
{
return
visit
(
std
::
forward
<
Visitor
>
(
f
),
x
.
get_data
());
}
/// @relates config_value
template
<
class
Visitor
>
auto
visit
(
Visitor
&&
f
,
const
config_value
&
x
)
->
decltype
(
visit
(
std
::
forward
<
Visitor
>
(
f
),
x
.
get_data
()))
{
return
visit
(
std
::
forward
<
Visitor
>
(
f
),
x
.
get_data
());
}
/// @relates config_value
/// @relates config_value
bool
operator
<
(
const
config_value
&
x
,
const
config_value
&
y
);
bool
operator
<
(
const
config_value
&
x
,
const
config_value
&
y
);
...
...
libcaf_core/caf/default_sum_type_access.hpp
View file @
11e0d02b
...
@@ -23,6 +23,7 @@
...
@@ -23,6 +23,7 @@
#include <utility>
#include <utility>
#include "caf/detail/type_list.hpp"
#include "caf/detail/type_list.hpp"
#include "caf/sum_type_token.hpp"
namespace
caf
{
namespace
caf
{
...
@@ -36,21 +37,29 @@ struct default_sum_type_access {
...
@@ -36,21 +37,29 @@ struct default_sum_type_access {
static
constexpr
bool
specialized
=
true
;
static
constexpr
bool
specialized
=
true
;
template
<
int
Pos
>
template
<
class
U
,
int
Pos
>
static
bool
is
(
const
T
&
x
,
s
td
::
integral_constant
<
int
,
Pos
>
token
)
{
static
bool
is
(
const
T
&
x
,
s
um_type_token
<
U
,
Pos
>
token
)
{
return
x
.
get_data
().
is
(
token
);
return
x
.
get_data
().
is
(
token
.
pos
);
}
}
template
<
int
Pos
>
template
<
class
U
,
int
Pos
>
static
typename
detail
::
tl_at
<
types
,
Pos
>::
type
&
static
U
&
get
(
T
&
x
,
sum_type_token
<
U
,
Pos
>
token
)
{
get
(
T
&
x
,
std
::
integral_constant
<
int
,
Pos
>
token
)
{
return
x
.
get_data
().
get
(
token
.
pos
);
return
x
.
get_data
().
get
(
token
);
}
}
template
<
int
Pos
>
template
<
class
U
,
int
Pos
>
static
const
typename
detail
::
tl_at
<
types
,
Pos
>::
type
&
static
const
U
&
get
(
const
T
&
x
,
sum_type_token
<
U
,
Pos
>
token
)
{
get
(
const
T
&
x
,
std
::
integral_constant
<
int
,
Pos
>
token
)
{
return
x
.
get_data
().
get
(
token
.
pos
);
return
x
.
get_data
().
get
(
token
);
}
template
<
class
U
,
int
Pos
>
static
U
*
get_if
(
T
*
x
,
sum_type_token
<
U
,
Pos
>
token
)
{
return
is
(
*
x
,
token
)
?
&
get
(
*
x
,
token
)
:
nullptr
;
}
template
<
class
U
,
int
Pos
>
static
const
U
*
get_if
(
const
T
*
x
,
sum_type_token
<
U
,
Pos
>
token
)
{
return
is
(
*
x
,
token
)
?
&
get
(
*
x
,
token
)
:
nullptr
;
}
}
template
<
class
Result
,
class
Visitor
,
class
...
Ts
>
template
<
class
Result
,
class
Visitor
,
class
...
Ts
>
...
...
libcaf_core/caf/fwd.hpp
View file @
11e0d02b
...
@@ -159,31 +159,6 @@ enum class atom_value : uint64_t;
...
@@ -159,31 +159,6 @@ enum class atom_value : uint64_t;
using
actor_id
=
uint64_t
;
using
actor_id
=
uint64_t
;
using
stream_slot
=
uint16_t
;
using
stream_slot
=
uint16_t
;
// -- free functions related to forwarded types --------------------------------
template
<
class
T
>
bool
holds_alternative
(
const
config_value
&
);
template
<
class
T
>
typename
std
::
conditional
<
detail
::
is_primitive_config_value
<
T
>::
value
,
const
T
*
,
optional
<
T
>>::
type
get_if
(
const
config_value
*
);
template
<
class
T
>
typename
std
::
conditional
<
detail
::
is_primitive_config_value
<
T
>::
value
,
T
*
,
optional
<
T
>>::
type
get_if
(
config_value
*
);
template
<
class
T
>
typename
std
::
conditional
<
detail
::
is_primitive_config_value
<
T
>::
value
,
const
T
&
,
T
>::
type
get
(
const
config_value
&
);
template
<
class
T
>
typename
std
::
conditional
<
detail
::
is_primitive_config_value
<
T
>::
value
,
T
&
,
T
>::
type
get
(
config_value
&
);
// -- functions ----------------------------------------------------------------
// -- functions ----------------------------------------------------------------
/// @relates actor_system_config
/// @relates actor_system_config
...
...
libcaf_core/caf/make_config_option.hpp
View file @
11e0d02b
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
#include <memory>
#include <memory>
#include "caf/config_option.hpp"
#include "caf/config_option.hpp"
#include "caf/config_value.hpp"
#include "caf/detail/type_name.hpp"
#include "caf/detail/type_name.hpp"
#include "caf/error.hpp"
#include "caf/error.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
...
...
libcaf_core/caf/sum_type.hpp
View file @
11e0d02b
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
#include "caf/detail/type_list.hpp"
#include "caf/detail/type_list.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/sum_type_access.hpp"
#include "caf/sum_type_access.hpp"
#include "caf/sum_type_token.hpp"
namespace
caf
{
namespace
caf
{
...
@@ -40,59 +41,57 @@ constexpr bool SumTypes() {
...
@@ -40,59 +41,57 @@ constexpr bool SumTypes() {
return
tl_forall
<
types
,
has_sum_type_access
>::
value
;
return
tl_forall
<
types
,
has_sum_type_access
>::
value
;
}
}
template
<
class
Trait
,
class
T
,
bool
=
Trait
::
specialized
>
struct
sum_type_index
{
static
constexpr
int
value
=
-
1
;
};
template
<
class
Trait
,
class
T
>
struct
sum_type_index
<
Trait
,
T
,
true
>
{
static
constexpr
int
value
=
detail
::
tl_index_of
<
typename
Trait
::
types
,
T
>::
value
;
};
template
<
class
Trait
,
class
T
>
constexpr
sum_type_token
<
T
,
sum_type_index
<
Trait
,
T
>::
value
>
make_sum_type_token
()
{
return
{};
}
/// Returns a reference to the value of a sum type.
/// Returns a reference to the value of a sum type.
/// @pre `holds_alternative<T>(x)`
/// @pre `holds_alternative<T>(x)`
/// @relates SumType
/// @relates SumType
template
<
class
T
,
class
U
>
template
<
class
T
,
class
U
,
class
Trait
=
sum_type_access
<
U
>
>
detail
::
enable_if_t
<
SumType
<
U
>
(),
T
&>
get
(
U
&
x
)
{
auto
get
(
U
&
x
)
->
decltype
(
Trait
::
get
(
x
,
make_sum_type_token
<
Trait
,
T
>
()))
{
using
namespace
detail
;
return
Trait
::
get
(
x
,
make_sum_type_token
<
Trait
,
T
>
());
using
trait
=
sum_type_access
<
U
>
;
int_token
<
tl_index_where
<
typename
trait
::
types
,
tbind
<
is_same_ish
,
T
>::
template
type
>
::
value
>
token
;
// Silence compiler error about "binding to unrelated types" such as
// 'signed char' to 'char' (which is obvious bullshit).
return
reinterpret_cast
<
T
&>
(
trait
::
get
(
x
,
token
));
}
}
/// Returns a reference to the value of a sum type.
/// Returns a reference to the value of a sum type.
/// @pre `holds_alternative<T>(x)`
/// @pre `holds_alternative<T>(x)`
/// @relates SumType
/// @relates SumType
template
<
class
T
,
class
U
>
template
<
class
T
,
class
U
,
class
Trait
=
sum_type_access
<
U
>
>
detail
::
enable_if_t
<
SumType
<
U
>
(),
const
T
&>
get
(
const
U
&
x
)
{
auto
get
(
const
U
&
x
)
using
namespace
detail
;
->
decltype
(
Trait
::
get
(
x
,
make_sum_type_token
<
Trait
,
T
>
()))
{
using
trait
=
sum_type_access
<
U
>
;
return
Trait
::
get
(
x
,
make_sum_type_token
<
Trait
,
T
>
());
int_token
<
tl_index_where
<
typename
trait
::
types
,
tbind
<
is_same_ish
,
T
>::
template
type
>
::
value
>
token
;
// Silence compiler error about "binding to unrelated types" such as
// 'signed char' to 'char' (which is obvious bullshit).
return
reinterpret_cast
<
const
T
&>
(
trait
::
get
(
x
,
token
));
}
}
/// Returns a pointer to the value of a sum type if it is of type `T`,
/// Returns a pointer to the value of a sum type if it is of type `T`,
/// `nullptr` otherwise.
/// `nullptr` otherwise.
/// @relates SumType
/// @relates SumType
template
<
class
T
,
class
U
>
template
<
class
T
,
class
U
,
class
Trait
=
sum_type_access
<
U
>
>
detail
::
enable_if_t
<
SumType
<
U
>
(),
T
*>
get_if
(
U
*
x
)
{
auto
get_if
(
U
*
x
)
using
namespace
detail
;
->
decltype
(
Trait
::
get_if
(
x
,
make_sum_type_token
<
Trait
,
T
>
()))
{
using
trait
=
sum_type_access
<
U
>
;
return
Trait
::
get_if
(
x
,
make_sum_type_token
<
Trait
,
T
>
());
int_token
<
tl_index_where
<
typename
trait
::
types
,
tbind
<
is_same_ish
,
T
>::
template
type
>
::
value
>
token
;
return
trait
::
is
(
*
x
,
token
)
?
&
trait
::
get
(
*
x
,
token
)
:
nullptr
;
}
}
/// Returns a pointer to the value of a sum type if it is of type `T`,
/// Returns a pointer to the value of a sum type if it is of type `T`,
/// `nullptr` otherwise.
/// `nullptr` otherwise.
/// @relates SumType
/// @relates SumType
template
<
class
T
,
class
U
>
template
<
class
T
,
class
U
,
class
Trait
=
sum_type_access
<
U
>
>
detail
::
enable_if_t
<
SumType
<
U
>
(),
const
T
*>
get_if
(
const
U
*
x
)
{
auto
get_if
(
const
U
*
x
)
using
namespace
detail
;
->
decltype
(
Trait
::
get_if
(
x
,
make_sum_type_token
<
Trait
,
T
>
()))
{
using
trait
=
sum_type_access
<
U
>
;
return
Trait
::
get_if
(
x
,
make_sum_type_token
<
Trait
,
T
>
());
using
token_type
=
int_token
<
tl_index_where
<
typename
trait
::
types
,
tbind
<
is_same_ish
,
T
>::
template
type
>
::
value
>
;
token_type
token
;
static_assert
(
token_type
::
value
!=
-
1
,
"T is not part of the sum type"
);
return
trait
::
is
(
*
x
,
token
)
?
&
trait
::
get
(
*
x
,
token
)
:
nullptr
;
}
}
/// Returns whether a sum type has a value of type `T`.
/// Returns whether a sum type has a value of type `T`.
...
@@ -101,9 +100,7 @@ template <class T, class U>
...
@@ -101,9 +100,7 @@ template <class T, class U>
bool
holds_alternative
(
const
U
&
x
)
{
bool
holds_alternative
(
const
U
&
x
)
{
using
namespace
detail
;
using
namespace
detail
;
using
trait
=
sum_type_access
<
U
>
;
using
trait
=
sum_type_access
<
U
>
;
int_token
<
tl_index_where
<
typename
trait
::
types
,
return
trait
::
is
(
x
,
make_sum_type_token
<
trait
,
T
>
());
tbind
<
is_same_ish
,
T
>::
template
type
>
::
value
>
token
;
return
trait
::
is
(
x
,
token
);
}
}
template
<
bool
Valid
,
class
F
,
class
...
Ts
>
template
<
bool
Valid
,
class
F
,
class
...
Ts
>
...
...
libcaf_core/caf/sum_type_token.hpp
0 → 100644
View file @
11e0d02b
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include <type_traits>
namespace
caf
{
template
<
class
T
,
int
Pos
>
struct
sum_type_token
{
static
constexpr
auto
pos
=
std
::
integral_constant
<
int
,
Pos
>
{};
};
}
// namespace caf
libcaf_core/test/sum_type_token.cpp
0 → 100644
View file @
11e0d02b
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/config.hpp"
#define CAF_SUITE sum_type_token
#include "caf/test/dsl.hpp"
#include "caf/sum_type_token.hpp"
namespace
{
struct
fixture
{
};
}
// namespace <anonymous>
CAF_TEST_FIXTURE_SCOPE
(
sum_type_token_tests
,
fixture
)
CAF_TEST
(
todo
)
{
// implement me
}
CAF_TEST_FIXTURE_SCOPE_END
()
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