Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F10709273
MessageMatcher.hpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
6 KB
Referenced Files
None
Subscribers
None
MessageMatcher.hpp
View Options
/*******************************************************************************
*
* File: MessageMatcher.hpp
*
* Contents: Implementation of MessageMatcher.
*
* Copyright 2017
*
* Author: David Juhasz (david.juhasz@tuwien.ac.at)
*
******************************************************************************/
#ifndef ROSA_CORE_MESSAGEMATCHER_HPP
#define ROSA_CORE_MESSAGEMATCHER_HPP
#include
"rosa/core/Message.hpp"
#include
<tuple>
namespace
rosa
{
// Template class with static functions type-checking a Message instance and
// extracting stored values from Message instsances into std::tuple instances
// with matching type arguments.
template
<
typename
List
>
struct
MessageMatcher
;
// Definition of MessageMatcher for non-empty lists of types, like Message
// itself.
template
<
typename
Type
,
typename
...
Ts
>
struct
MessageMatcher
<
TypeList
<
Type
,
Ts
...
>>
{
// Type Token associated with the give TypeList.
static
constexpr
Token
T
=
TypeToken
<
Type
,
Ts
...
>::
Value
;
// Tells if stored values in Msg are matching types given as
// TypeList<T, Ts...>, considering exact AtomConstants instead of AtomValues.
static
inline
bool
doesStronglyMatch
(
const
Message
&
Msg
)
noexcept
;
// Gives a std::tuple with references to values stored in a type-matching Msg.
// PRE: doesStronglyMatch(Msg)
static
inline
std
::
tuple
<
const
Type
&
,
const
Ts
&
...
>
extractedValues
(
const
Message
&
Msg
)
noexcept
;
};
// Convenience template alias turning a list of types into a TypeList for
// MessageMatcher.
template
<
typename
Type
,
typename
...
Ts
>
using
MsgMatcher
=
MessageMatcher
<
TypeList
<
Type
,
Ts
...
>>
;
// Nested namespace with implementation for features of MessageMatcher,
// consider it private.
namespace
{
// Helper struct implementing type-checking and value extraction for
// MessageMatcher.
template
<
typename
List
>
struct
MessageMatcherImpl
;
// Specialization handling the empty list of types.
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 handling an 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
));
}
};
// Specialization handling an regular builtin type (not an AtomConstant) 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 Tokens are 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 list with squashed integers as Tokens are 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
Sun, May 31, 5:05 PM (1 d, 5 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
328320
Default Alt Text
MessageMatcher.hpp (6 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment