Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F25860978
MessageMatcher.hpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
7 KB
Referenced Files
None
Subscribers
None
MessageMatcher.hpp
View Options
/***************************************************************************//**
*
* \file rosa/core/MessageMatcher.hpp
*
* \author David Juhasz (david.juhasz@tuwien.ac.at)
*
* \date 2017
*
* \brief Facilities for checking and matching types of values stored in
* `rosa::Message` instances.
*
******************************************************************************/
#ifndef ROSA_CORE_MESSAGEMATCHER_HPP
#define ROSA_CORE_MESSAGEMATCHER_HPP
#include
"rosa/core/Message.hpp"
#include
<tuple>
namespace
rosa
{
/// Provides features to type-check a `rosa::Message` instance and extract
/// stored values from it into an `std::tuple` instance with matching type
/// arguments.
///
/// \tparam List `rosa::TypeList` to check the stored values against
template
<
typename
List
>
struct
MessageMatcher
;
/// Definition of `rosa::MessageMatcher` for non-empty lists of types, like
/// `rosa::Message` itself.
///
/// \tparam Type first mandatory type
/// \tparam Types any further types
template
<
typename
Type
,
typename
...
Types
>
struct
MessageMatcher
<
TypeList
<
Type
,
Types
...
>>
{
/// `rosa::Token` associated to the give `rosa::TypeList`.
static
constexpr
Token
T
=
TypeToken
<
Type
,
Types
...
>::
Value
;
/// Tells if the values stored in a `rosa::Message` instance are matching
/// types given as `rosa::TypeList<T, Types...>`, considering
/// `rosa::AtomConstant` instead of `rosa::AtomValue`.
///
/// \param Msg `Message` to match
///
/// \return whether the types of values stored in `Msg` matches
/// `rosa::TypeList<Type, Types...>`
static
inline
bool
doesStronglyMatch
(
const
Message
&
Msg
)
noexcept
;
/// Gives a `std::tuple` with references to the values stored in a
/// type-matching instance of `rosa::Message`.
///
/// \param Msg `Message` to extract values from
///
/// \return `tuple` with references to the values stored in `Msg`
///
/// \pre Types of the values stored in `Msg` matches
/// `rosa::TypeList<Type, Types...>`:\code
/// doesStronglyMatch(Msg)
/// \endcode
static
inline
std
::
tuple
<
const
Type
&
,
const
Types
&
...
>
extractedValues
(
const
Message
&
Msg
)
noexcept
;
};
/// Turns a list of types into a `rosa::TypeList` for `rosa::MessageMatcher`.
template
<
typename
Type
,
typename
...
Types
>
using
MsgMatcher
=
MessageMatcher
<
TypeList
<
Type
,
Types
...
>>
;
/// Nested namespace with implementation for features of `rosa::MessageMatcher`,
/// consider it private.
namespace
{
/// \defgroup MessageMatcherImpl
///
/// An implementation of type-checking and value extraction for
/// `rosa::MessageMatcher`.
///
///@{
/// Template declaration of `rosa::MessageMatcherImpl.
///
/// \tparam List `rosa::TypeList` to match against
template
<
typename
List
>
struct
MessageMatcherImpl
;
/// Specialization for `rosa::EmptyTypeList`.
template
<>
struct
MessageMatcherImpl
<
EmptyTypeList
>
{
static
inline
bool
doesStronglyMatchFrom
(
const
Message
&
Msg
,
const
size_t
Pos
)
noexcept
{
// Matching EmptyTypeList only if reached the end of the stored types.
return
Pos
==
Msg
.
Size
;
}
static
inline
std
::
tuple
<>
extractedValuesFrom
(
const
Message
&
Msg
,
const
size_t
Pos
)
noexcept
{
// It is valid to extract an empty list only if we reached the end of
// stored values.
ASSERT
(
doesStronglyMatchFrom
(
Msg
,
Pos
));
return
std
::
tie
();
}
};
/// Specialization for `rosa::AtomValue` in the head.
template
<
AtomValue
V
,
typename
...
Ts
>
struct
MessageMatcherImpl
<
TypeList
<
AtomConstant
<
V
>
,
Ts
...
>>
{
static
inline
bool
doesHeadStronglyMatchAt
(
const
Message
&
Msg
,
const
size_t
Pos
)
noexcept
{
// Matching an AtomConstant in the head if there is a type stored at Pos,
// the stored type is AtomValue, and the corresponding value matches the
// AtomValue V.
return
Pos
<
Msg
.
Size
&&
Msg
.
isTypeAt
<
AtomValue
>
(
Pos
)
&&
Msg
.
valueAt
<
AtomValue
>
(
Pos
)
==
V
;
}
static
inline
bool
doesStronglyMatchFrom
(
const
Message
&
Msg
,
const
size_t
Pos
)
noexcept
{
// Matching a non-empty list if the head is matching and the rest of the
// list is matching.
return
doesHeadStronglyMatchAt
(
Msg
,
Pos
)
&&
MessageMatcherImpl
<
TypeList
<
Ts
...
>>::
doesStronglyMatchFrom
(
Msg
,
Pos
+
1
);
}
static
inline
std
::
tuple
<
const
AtomConstant
<
V
>
&
,
const
Ts
&
...
>
extractedValuesFrom
(
const
Message
&
Msg
,
const
size_t
Pos
)
noexcept
{
// Extracting for a non-empty list with a matching AtomConstant in the head
// by getting the encoded AtomConstant and concatenating it with values
// extracted for the rest of the list.
ASSERT
(
doesHeadStronglyMatchAt
(
Msg
,
Pos
));
return
std
::
tuple_cat
(
std
::
tie
(
AtomConstant
<
V
>::
Value
),
MessageMatcherImpl
<
TypeList
<
Ts
...
>>::
extractedValuesFrom
(
Msg
,
Pos
+
1
));
}
};
/// Definition for the general case when a regular built-in type (not a
/// `rosa::AtomConstant`) is in the head.
template
<
typename
T
,
typename
...
Ts
>
struct
MessageMatcherImpl
<
TypeList
<
T
,
Ts
...
>>
{
static
inline
bool
doesHeadStronglyMatchAt
(
const
Message
&
Msg
,
const
size_t
Pos
)
noexcept
{
// Matching the head if there is a type stored at Pos, and the stored type
// is T.
return
Pos
<
Msg
.
Size
&&
Msg
.
isTypeAt
<
T
>
(
Pos
);
}
static
inline
bool
doesStronglyMatchFrom
(
const
Message
&
Msg
,
const
size_t
Pos
)
noexcept
{
// Matching a non-empty list if the head is matching and the rest of the
// list is matching.
return
doesHeadStronglyMatchAt
(
Msg
,
Pos
)
&&
MessageMatcherImpl
<
TypeList
<
Ts
...
>>::
doesStronglyMatchFrom
(
Msg
,
Pos
+
1
);
}
static
inline
std
::
tuple
<
const
T
&
,
const
Ts
&
...
>
extractedValuesFrom
(
const
Message
&
Msg
,
const
size_t
Pos
)
noexcept
{
// Extracting for a non-empty list with a matching head by getting the
// value for the head and concatenating it with values extracted for the
// rest of the list.
ASSERT
(
doesHeadStronglyMatchAt
(
Msg
,
Pos
));
return
std
::
tuple_cat
(
std
::
tie
(
Msg
.
valueAt
<
T
>
(
Pos
)),
MessageMatcherImpl
<
TypeList
<
Ts
...
>>::
extractedValuesFrom
(
Msg
,
Pos
+
1
));
}
};
///@}
}
// End namespace
template
<
typename
Type
,
typename
...
Ts
>
bool
MessageMatcher
<
TypeList
<
Type
,
Ts
...
>>::
doesStronglyMatch
(
const
Message
&
Msg
)
noexcept
{
// \note Fail quick on T, then match against list with squashed integers the
// way `rosa::Token` is generated.
return
T
==
Msg
.
T
&&
MessageMatcherImpl
<
typename
SquashedTypeList
<
TypeList
<
Type
,
Ts
...
>>::
Type
>::
doesStronglyMatchFrom
(
Msg
,
0
);
}
template
<
typename
Type
,
typename
...
Ts
>
std
::
tuple
<
const
Type
&
,
const
Ts
&
...
>
MessageMatcher
<
TypeList
<
Type
,
Ts
...
>>::
extractedValues
(
const
Message
&
Msg
)
noexcept
{
ASSERT
(
doesStronglyMatch
(
Msg
));
// \note Match against a list with squashed integers as `rosa::Token` is
// generated.
return
MessageMatcherImpl
<
typename
SquashedTypeList
<
TypeList
<
Type
,
Ts
...
>>::
Type
>::
extractedValuesFrom
(
Msg
,
0
);
}
}
// End namespace rosa
#endif
// ROSA_CORE_MESSAGEMATCHER_HPP
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Sat, Aug 29, 5:13 PM (10 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
328130
Default Alt Text
MessageMatcher.hpp (7 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment