Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F27033577
MessageMatcher.hpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Authored By
Unknown
Size
7 KB
Referenced Files
None
Subscribers
None
MessageMatcher.hpp
View Options
//===-- rosa/core/MessageMatcher.hpp ----------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \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
/// \c 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 \c rosa::Message instance and extract
/// stored values from it into an \c std::tuple instance with matching type
/// arguments.
///
/// \tparam List \c rosa::TypeList to check the stored values against
template
<
typename
List
>
struct
MessageMatcher
;
/// Definition of \c rosa::MessageMatcher for non-empty lists of types, like
/// \c rosa::Message itself.
///
/// \tparam Type first mandatory type
/// \tparam Types any further types
template
<
typename
Type
,
typename
...
Types
>
struct
MessageMatcher
<
TypeList
<
Type
,
Types
...
>>
{
/// \c rosa::Token associated to the given \c rosa::TypeList.
static
constexpr
Token
T
=
TypeToken
<
Type
,
Types
...
>::
Value
;
/// Tells if the values stored in a \c rosa::Message instance are matching
/// types given as \c rosa::TypeList<T, Types...>, considering
/// \c rosa::AtomConstant instead of \c rosa::AtomValue.
///
/// \param Msg \c rosa::Message to match
///
/// \return whether the types of values stored in \p Msg matches
/// \c rosa::TypeList<Type, Types...>
static
inline
bool
doesStronglyMatch
(
const
Message
&
Msg
)
noexcept
;
/// Gives a \c std::tuple with references to the values stored in a
/// type-matching instance of \c rosa::Message.
///
/// \param Msg \c rosa::Message to extract values from
///
/// \return \c std::tuple with references to the values stored in \p Msg
///
/// \pre Types of the values stored in \p Msg matches
/// \c 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 \c rosa::TypeList for \c rosa::MessageMatcher.
template
<
typename
Type
,
typename
...
Types
>
using
MsgMatcher
=
MessageMatcher
<
TypeList
<
Type
,
Types
...
>>
;
/// Nested namespace with implementation for features of
/// \c rosa::MessageMatcher, consider it private.
namespace
{
/// \defgroup MessageMatcherImpl Implementation for rosa::MessageMatcher
///
/// An implementation of type-checking and value extraction for
/// \c rosa::MessageMatcher.
///
///@{
/// Template declaration of \c MessageMatcherImpl.
///
/// \tparam List \c rosa::TypeList to match against
template
<
typename
List
>
struct
MessageMatcherImpl
;
/// Specialization for \c rosa::EmptyTypeList.
template
<>
struct
MessageMatcherImpl
<
EmptyTypeList
>
{
static
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
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 \c rosa::AtomValue in the head.
template
<
AtomValue
V
,
typename
...
Ts
>
struct
MessageMatcherImpl
<
TypeList
<
AtomConstant
<
V
>
,
Ts
...
>>
{
static
bool
doesHeadStronglyMatchAt
(
const
Message
&
Msg
,
const
size_t
Pos
)
noexcept
{
// Matching a \c rosa::AtomConstant in the head if there is a type stored at
// \p Pos, the stored type is \c rosa::AtomValue, and the corresponding
// value matches the \c rosa::AtomValue \p V.
return
Pos
<
Msg
.
Size
&&
Msg
.
isTypeAt
<
AtomValue
>
(
Pos
)
&&
Msg
.
valueAt
<
AtomValue
>
(
Pos
)
==
V
;
}
static
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
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 \c rosa::AtomConstant in
// the head by getting the encoded \c rosa::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
/// \c rosa::AtomConstant) is in the head.
template
<
typename
T
,
typename
...
Ts
>
struct
MessageMatcherImpl
<
TypeList
<
T
,
Ts
...
>>
{
static
bool
doesHeadStronglyMatchAt
(
const
Message
&
Msg
,
const
size_t
Pos
)
noexcept
{
// Matching the head if there is a type stored at \p Pos, and the stored
// type is \p T.
return
Pos
<
Msg
.
Size
&&
Msg
.
isTypeAt
<
T
>
(
Pos
);
}
static
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
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
...
Types
>
bool
MessageMatcher
<
TypeList
<
Type
,
Types
...
>>::
doesStronglyMatch
(
const
Message
&
Msg
)
noexcept
{
// \note Fail quick on \c rosa::MessageMatcher::T, then match against list
// with squashed integers the way \c rosa::Token is generated.
return
T
==
Msg
.
T
&&
MessageMatcherImpl
<
typename
SquashedTypeList
<
TypeList
<
Type
,
Types
...
>>::
Type
>::
doesStronglyMatchFrom
(
Msg
,
0
);
}
template
<
typename
Type
,
typename
...
Types
>
std
::
tuple
<
const
Type
&
,
const
Types
&
...
>
MessageMatcher
<
TypeList
<
Type
,
Types
...
>>::
extractedValues
(
const
Message
&
Msg
)
noexcept
{
ASSERT
(
doesStronglyMatch
(
Msg
));
// \note Match against a list with squashed integers as \c rosa::Token is
// generated.
return
MessageMatcherImpl
<
typename
SquashedTypeList
<
TypeList
<
Type
,
Types
...
>>::
Type
>::
extractedValuesFrom
(
Msg
,
0
);
}
}
// End namespace rosa
#endif
// ROSA_CORE_MESSAGEMATCHER_HPP
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Tue, Oct 27, 4:36 PM (1 d, 6 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
408402
Default Alt Text
MessageMatcher.hpp (7 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline