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
18bcf49c
Commit
18bcf49c
authored
Jan 20, 2015
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement new syntax for atom constants
parent
7b9905de
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
102 additions
and
48 deletions
+102
-48
libcaf_core/caf/atom.hpp
libcaf_core/caf/atom.hpp
+20
-4
libcaf_core/caf/detail/ctm.hpp
libcaf_core/caf/detail/ctm.hpp
+31
-2
libcaf_core/caf/detail/lifted_fun.hpp
libcaf_core/caf/detail/lifted_fun.hpp
+7
-2
libcaf_core/caf/detail/try_match.hpp
libcaf_core/caf/detail/try_match.hpp
+13
-31
libcaf_core/caf/message.hpp
libcaf_core/caf/message.hpp
+7
-6
libcaf_core/src/try_match.cpp
libcaf_core/src/try_match.cpp
+24
-3
No files found.
libcaf_core/caf/atom.hpp
View file @
18bcf49c
...
...
@@ -47,11 +47,27 @@ constexpr atom_value atom(char const (&str)[Size]) {
}
/**
* Type alias for treating atom constants at compile-time
* (cf. "Int-ToType" idiom).
* Lifts an `atom_value` to a compile-time constant.
*/
template
<
atom_value
Value
>
using
atom_constant
=
std
::
integral_constant
<
atom_value
,
Value
>
;
template
<
atom_value
V
>
struct
atom_constant
{
constexpr
atom_constant
()
{
// nop
}
/**
* Returns the wrapped value.
*/
constexpr
operator
atom_value
()
const
{
return
V
;
}
/**
* Returns an instance *of this constant* (*not* an `atom_value`).
*/
static
const
atom_constant
value
;
};
template
<
atom_value
V
>
const
atom_constant
<
V
>
atom_constant
<
V
>::
value
=
atom_constant
<
V
>
{};
/**
* Generic 'GET' atom for request operations.
...
...
libcaf_core/caf/detail/ctm.hpp
View file @
18bcf49c
...
...
@@ -35,8 +35,25 @@ namespace detail {
template
<
class
A
,
class
B
>
struct
ctm_cmp
:
std
::
false_type
{
};
template
<
class
T
>
struct
ctm_cmp
<
T
,
T
>
:
std
::
true_type
{
};
template
<
class
In
,
class
L
,
class
R1
,
class
R2
>
struct
ctm_cmp
<
typed_mpi
<
In
,
L
,
R1
>
,
typed_mpi
<
In
,
L
,
R2
>>
{
static
constexpr
bool
value
=
std
::
is_same
<
R1
,
R2
>::
value
||
std
::
is_same
<
R2
,
empty_type_list
>::
value
;
};
/*
template <class In, class Out>
struct ctm_cmp<typed_mpi<In, Out, empty_type_list>,
typed_mpi<In, Out, empty_type_list>>
: std::true_type { };
template <class In, class L, class R>
struct ctm_cmp<typed_mpi<In, L, R>,
typed_mpi<In, L, R>>
: std::true_type { };
*/
template
<
class
In
,
class
Out
>
struct
ctm_cmp
<
typed_mpi
<
In
,
Out
,
empty_type_list
>
,
...
...
@@ -58,6 +75,18 @@ struct ctm_cmp<typed_mpi<In, L, R>,
typed_mpi
<
In
,
type_list
<
typed_response_promise
<
either_or_t
<
L
,
R
>>>
,
empty_type_list
>>
:
std
::
true_type
{
};
/*
template <class In, class L, class R>
struct ctm_cmp<typed_mpi<In, L, R>,
typed_mpi<In, L, empty_type_list>>
: std::true_type { };
*/
template
<
class
In
,
class
L
,
class
R
>
struct
ctm_cmp
<
typed_mpi
<
In
,
L
,
R
>
,
typed_mpi
<
In
,
R
,
empty_type_list
>>
:
std
::
true_type
{
};
template
<
class
A
,
class
B
>
struct
ctm
:
std
::
false_type
{
};
...
...
libcaf_core/caf/detail/lifted_fun.hpp
View file @
18bcf49c
...
...
@@ -148,10 +148,15 @@ class lifted_fun_invoker<bool, F> {
*/
template
<
class
F
,
class
ListOfProjections
,
class
...
Args
>
class
lifted_fun
{
public:
using
plain_result_type
=
typename
get_callable_trait
<
F
>::
result_type
;
using
result_type
=
typename
get_callable_trait
<
F
>::
result_type
;
using
result_type
=
typename
std
::
conditional
<
std
::
is_reference
<
plain_result_type
>::
value
,
plain_result_type
,
typename
std
::
remove_const
<
plain_result_type
>::
type
>::
type
;
// Let F be "R (Ts...)" then lifted_fun<F...> returns optional<R>
// unless R is void in which case bool is returned
...
...
libcaf_core/caf/detail/try_match.hpp
View file @
18bcf49c
...
...
@@ -24,6 +24,7 @@
#include <numeric>
#include <typeinfo>
#include "caf/atom.hpp"
#include "caf/message.hpp"
#include "caf/wildcard_position.hpp"
...
...
@@ -33,56 +34,37 @@
namespace
caf
{
namespace
detail
{
bool
match_element
(
const
std
::
type_info
*
type
,
const
message_iterator
&
iter
,
void
**
storage
);
bool
match_element
(
const
atom_value
&
,
const
std
::
type_info
*
type
,
const
message_iterator
&
iter
,
void
**
storage
);
template
<
class
T
>
bool
match_integral_constant_element
(
const
std
::
type_info
*
type
,
const
message_iterator
&
iter
,
void
**
storage
)
{
auto
value
=
T
::
value
;
auto
uti
=
iter
.
type
();
if
(
!
uti
->
equal_to
(
*
type
)
||
!
uti
->
equals
(
iter
.
value
(),
&
value
))
{
return
false
;
}
if
(
storage
)
{
// This assignment implicitly casts `T*` to `integral_constant<T, V>*`.
// This type violation could theoretically cause undefined behavior.
// However, `T::value` does have an address that is guaranteed to be valid
// throughout the runtime of the program and the integral constant
// objects does not have any members. Hence, this is nonetheless safe.
auto
ptr
=
reinterpret_cast
<
const
void
*>
(
&
T
::
value
);
// Again, this const cast is always safe because we will never derefence
// this pointer since `integral_constant<T, V>` has no members.
*
storage
=
const_cast
<
void
*>
(
ptr
);
}
return
true
;
}
bool
match_atom_constant
(
const
atom_value
&
,
const
std
::
type_info
*
type
,
const
message_iterator
&
iter
,
void
**
storage
);
struct
meta_element
{
atom_value
v
;
const
std
::
type_info
*
type
;
bool
(
*
fun
)(
const
std
::
type_info
*
,
const
message_iterator
&
,
void
**
);
bool
(
*
fun
)(
const
atom_value
&
,
const
std
::
type_info
*
,
const
message_iterator
&
,
void
**
);
};
template
<
class
T
>
struct
meta_element_factory
{
static
meta_element
create
()
{
return
{
&
typeid
(
T
),
match_element
};
return
{
static_cast
<
atom_value
>
(
0
),
&
typeid
(
T
),
match_element
};
}
};
template
<
class
T
,
T
V
>
struct
meta_element_factory
<
std
::
integral_constant
<
T
,
V
>>
{
template
<
atom_value
V
>
struct
meta_element_factory
<
atom_constant
<
V
>>
{
static
meta_element
create
()
{
return
{
&
typeid
(
T
),
match_integral_constant_element
<
std
::
integral_constant
<
T
,
V
>>
};
return
{
V
,
&
typeid
(
atom_value
),
match_atom_constant
};
}
};
template
<
>
struct
meta_element_factory
<
anything
>
{
static
meta_element
create
()
{
return
{
nullptr
,
nullptr
};
return
{
static_cast
<
atom_value
>
(
0
),
nullptr
,
nullptr
};
}
};
...
...
libcaf_core/caf/message.hpp
View file @
18bcf49c
...
...
@@ -22,6 +22,7 @@
#include <type_traits>
#include "caf/atom.hpp"
#include "caf/config.hpp"
#include "caf/detail/int_list.hpp"
...
...
@@ -282,13 +283,13 @@ inline bool operator!=(const message& lhs, const message& rhs) {
}
template
<
class
T
>
struct
lift
_message_element
{
struct
unbox
_message_element
{
using
type
=
T
;
};
template
<
class
T
,
T
V
>
struct
lift_message_element
<
std
::
integral_constant
<
T
,
V
>>
{
using
type
=
T
;
template
<
atom_value
V
>
struct
unbox_message_element
<
atom_constant
<
V
>>
{
using
type
=
atom_value
;
};
/**
...
...
@@ -303,10 +304,10 @@ typename std::enable_if<
>::
type
make_message
(
T
&&
arg
,
Ts
&&
...
args
)
{
using
storage
=
detail
::
tuple_vals
<
typename
lift
_message_element
<
=
detail
::
tuple_vals
<
typename
unbox
_message_element
<
typename
detail
::
strip_and_convert
<
T
>::
type
>::
type
,
typename
lift
_message_element
<
typename
unbox
_message_element
<
typename
detail
::
strip_and_convert
<
Ts
>::
type
>::
type
...
>
;
auto
ptr
=
new
storage
(
std
::
forward
<
T
>
(
arg
),
std
::
forward
<
Ts
>
(
args
)...);
...
...
libcaf_core/src/try_match.cpp
View file @
18bcf49c
...
...
@@ -28,8 +28,8 @@ bool is_wildcard(const meta_element& me) {
return
me
.
type
==
nullptr
;
}
bool
match_element
(
const
std
::
type_info
*
type
,
const
message_iterator
&
iter
,
void
**
storage
)
{
bool
match_element
(
const
atom_value
&
,
const
std
::
type_info
*
type
,
const
message_iterator
&
iter
,
void
**
storage
)
{
if
(
!
iter
.
type
()
->
equal_to
(
*
type
))
{
return
false
;
}
...
...
@@ -39,6 +39,27 @@ bool match_element(const std::type_info* type, const message_iterator& iter,
return
true
;
}
bool
match_atom_constant
(
const
atom_value
&
value
,
const
std
::
type_info
*
type
,
const
message_iterator
&
iter
,
void
**
storage
)
{
auto
uti
=
iter
.
type
();
if
(
!
uti
->
equal_to
(
*
type
))
{
return
false
;
}
if
(
storage
)
{
if
(
!
uti
->
equals
(
iter
.
value
(),
&
value
))
{
return
false
;
}
// This assignment casts `uniform_type_info*` to `atom_constant<V>*`.
// This type violation could theoretically cause undefined behavior.
// However, `uti` does have an address that is guaranteed to be valid
// throughout the runtime of the program and the atom constant
// does not have any members. Hence, this is nonetheless safe since
// we are never actually going to dereference the pointer.
*
storage
=
const_cast
<
void
*>
(
reinterpret_cast
<
const
void
*>
(
uti
));
}
return
true
;
}
class
set_commit_rollback
{
public:
using
pointer
=
void
**
;
...
...
@@ -92,7 +113,7 @@ bool try_match(message_iterator mbegin, message_iterator mend,
return
false
;
// no submatch found
}
// inspect current element
if
(
!
pbegin
->
fun
(
pbegin
->
type
,
mbegin
,
storage
.
current
()))
{
if
(
!
pbegin
->
fun
(
pbegin
->
v
,
pbegin
->
type
,
mbegin
,
storage
.
current
()))
{
// type mismatch
return
false
;
}
...
...
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