Skip to content

Commit 4797ead

Browse files
committed
Release v2.0.2
2 parents 5909e5b + dd03cf6 commit 4797ead

File tree

13 files changed

+481
-17
lines changed

13 files changed

+481
-17
lines changed

comms/include/comms/GenericHandler.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ template <
9595
typename... TRest,
9696
typename TRetType>
9797
class GenericHandler<TDefault, std::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TRest...>, TRetType>
98-
: public GenericHandler<TDefault, std::tuple<TRest...> >
98+
: public GenericHandler<TDefault, std::tuple<TRest...>, TRetType>
9999
{
100-
using BaseImpl = GenericHandler<TDefault, std::tuple<TRest...> >;
100+
using BaseImpl = GenericHandler<TDefault, std::tuple<TRest...>, TRetType>;
101101
public:
102102

103103
using BaseImpl::handle;

comms/include/comms/details/DispatchMsgPolymorphicHelper.h

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,29 @@ static constexpr bool dispatchMsgPolymorphicIsDirectSuitable()
476476
DispatchMsgPolymorphicIsDirectSuitable<TAllMessages, std::tuple_size<TAllMessages>::value>::Value;
477477
}
478478

479+
template <typename TMsg, typename THandler, bool THasDispatch>
480+
struct DispatchMsgPolymorphicCompatibleHandlerDetector;
481+
482+
template <typename TMsg, typename THandler>
483+
struct DispatchMsgPolymorphicCompatibleHandlerDetector<TMsg, THandler, false>
484+
{
485+
static const bool Value = false;
486+
};
487+
488+
template <typename TMsg, typename THandler>
489+
struct DispatchMsgPolymorphicCompatibleHandlerDetector<TMsg, THandler, true>
490+
{
491+
static const bool Value = std::is_base_of<typename TMsg::Handler, THandler>::value;
492+
};
493+
494+
template <typename TMsg, typename THandler>
495+
constexpr bool dispatchMsgPolymorphicIsCompatibleHandler()
496+
{
497+
return
498+
DispatchMsgPolymorphicCompatibleHandlerDetector<TMsg, THandler, TMsg::hasDispatch()>::Value;
499+
}
500+
501+
479502
template <typename TAllMessages, typename TMsgBase, typename THandler>
480503
class DispatchMsgPolymorphicHelper
481504
{
@@ -502,7 +525,7 @@ class DispatchMsgPolymorphicHelper
502525

503526
using Tag =
504527
typename std::conditional<
505-
TMsgBase::hasDispatch(),
528+
dispatchMsgPolymorphicIsCompatibleHandler<TMsgBase, THandler>(),
506529
DispatchInterfaceTag,
507530
typename std::conditional<
508531
allMessagesAreStrongSorted<TAllMessages>(),
@@ -534,7 +557,7 @@ class DispatchMsgPolymorphicHelper
534557
comms::isMessageBase<MsgType>(),
535558
EmptyTag,
536559
typename std::conditional<
537-
TMsgBase::hasDispatch(),
560+
dispatchMsgPolymorphicIsCompatibleHandler<TMsgBase, THandler>(),
538561
NoIdInterfaceTag,
539562
typename std::conditional<
540563
TMsgBase::hasGetId(),

comms/include/comms/details/MessageInterfaceBuilder.h

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,34 @@ class MessageInterfaceHandlerBase : public TBase
432432

433433
protected:
434434
~MessageInterfaceHandlerBase() noexcept = default;
435-
virtual DispatchRetType dispatchImpl(Handler& handler) = 0;
435+
virtual DispatchRetType dispatchImpl(Handler& handler)
436+
{
437+
static_cast<void>(handler);
438+
COMMS_ASSERT(!"Mustn't be called");
439+
using Tag =
440+
typename std::conditional<
441+
std::is_void<DispatchRetType>::value,
442+
VoidHandleRetTypeTag,
443+
NonVoidHandleRetTypeTag
444+
>::type;
445+
return dispatchInternal(Tag());
446+
}
447+
448+
private:
449+
struct VoidHandleRetTypeTag {};
450+
struct NonVoidHandleRetTypeTag {};
451+
452+
static DispatchRetType dispatchInternal(VoidHandleRetTypeTag)
453+
{
454+
return;
455+
}
456+
457+
static DispatchRetType dispatchInternal(NonVoidHandleRetTypeTag)
458+
{
459+
using RetTypeInternal = typename std::decay<DispatchRetType>::type;
460+
static const RetTypeInternal Ret = RetTypeInternal();
461+
return Ret;
462+
}
436463
};
437464

438465
template <bool THasHandler>

comms/include/comms/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#define COMMS_MINOR_VERSION 0U
2828

2929
/// @brief Patch level of the library
30-
#define COMMS_PATCH_VERSION 1U
30+
#define COMMS_PATCH_VERSION 2U
3131

3232
/// @brief Macro to create numeric version as single unsigned number
3333
#define COMMS_MAKE_VERSION(major_, minor_, patch_) \

comms/test/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,18 @@ endfunction ()
109109

110110
#################################################################
111111

112+
function (test_dispatch)
113+
test_func ("Dispatch")
114+
endfunction ()
115+
116+
#################################################################
117+
118+
function (test_msg_factory)
119+
test_func ("MsgFactory")
120+
endfunction ()
121+
122+
#################################################################
123+
112124
include_directories ("${CXXTEST_INCLUDE_DIR}")
113125

114126
if (CMAKE_COMPILER_IS_GNUCC)
@@ -138,3 +150,6 @@ test_transport_value_layer()
138150
test_util()
139151
test_custom_msg_id_layer()
140152
test_custom_msg_size_layer()
153+
test_dispatch()
154+
test_msg_factory ()
155+

comms/test/CommsTestCommon.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ static_assert(0U < COMMS_MAKE_VERSION(0, 29, 0), "Invalid version definition");
3030

3131
enum MessageType {
3232
MessageType1,
33-
UnusedValue1,
3433
MessageType2,
34+
UnusedValue1,
3535
UnusedValue2,
3636
UnusedValue3,
3737
MessageType3,

comms/test/Dispatch.th

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
//
2+
// Copyright 2019 (C). Alex Robenko. All rights reserved.
3+
//
4+
5+
// This file is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU General Public License as published by
7+
// the Free Software Foundation, either version 3 of the License, or
8+
// (at your option) any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU General Public License
16+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
18+
#include <cstdint>
19+
#include <cstddef>
20+
#include <algorithm>
21+
#include <iterator>
22+
23+
#include "comms/comms.h"
24+
#include "comms/dispatch.h"
25+
#include "CommsTestCommon.h"
26+
27+
CC_DISABLE_WARNINGS()
28+
#include "cxxtest/TestSuite.h"
29+
CC_ENABLE_WARNINGS()
30+
31+
class DispatchTestSuite : public CxxTest::TestSuite
32+
{
33+
public:
34+
35+
void test1();
36+
37+
class TypeHandler
38+
{
39+
public:
40+
template <typename TMsg>
41+
void handle()
42+
{
43+
static_assert(comms::isMessageBase<TMsg>(), "Wrong dispatch");
44+
++m_detectedCnt;
45+
m_lastId = static_cast<decltype(m_lastId)>(TMsg::ImplOptions::MsgId);
46+
}
47+
48+
unsigned detectedCnt() const
49+
{
50+
return m_detectedCnt;
51+
}
52+
53+
MessageType lastId() const
54+
{
55+
return m_lastId;
56+
}
57+
58+
void reset()
59+
{
60+
m_detectedCnt = 0U;
61+
m_lastId = InvalidMessageId;
62+
}
63+
64+
private:
65+
static const MessageType InvalidMessageId = static_cast<MessageType>(99);
66+
unsigned m_detectedCnt = 0U;
67+
MessageType m_lastId = InvalidMessageId;
68+
};
69+
70+
using Interface1 =
71+
comms::Message<
72+
comms::option::def::MsgIdType<MessageType>,
73+
comms::option::def::BigEndian
74+
>;
75+
76+
private:
77+
};
78+
79+
void DispatchTestSuite::test1()
80+
{
81+
do {
82+
using AllMessages = std::tuple<>;
83+
TypeHandler handler;
84+
TS_ASSERT(!comms::dispatchMsgTypePolymorphic<AllMessages>(MessageType1, handler));
85+
TS_ASSERT(!comms::dispatchMsgTypeStaticBinSearch<AllMessages>(MessageType1, handler));
86+
TS_ASSERT(!comms::dispatchMsgTypeLinearSwitch<AllMessages>(MessageType1, handler));
87+
TS_ASSERT_EQUALS(handler.detectedCnt(), 0U);
88+
} while (false);
89+
90+
do {
91+
using AllMessages =
92+
std::tuple<
93+
Message1<Interface1>
94+
>;
95+
96+
TypeHandler handler;
97+
TS_ASSERT(comms::dispatchMsgTypePolymorphic<AllMessages>(MessageType1, handler));
98+
TS_ASSERT_EQUALS(handler.lastId(), MessageType1);
99+
TS_ASSERT(comms::dispatchMsgTypeStaticBinSearch<AllMessages>(MessageType1, handler));
100+
TS_ASSERT_EQUALS(handler.lastId(), MessageType1);
101+
TS_ASSERT(comms::dispatchMsgTypeLinearSwitch<AllMessages>(MessageType1, handler));
102+
TS_ASSERT_EQUALS(handler.lastId(), MessageType1);
103+
TS_ASSERT_EQUALS(handler.detectedCnt(), 3U);
104+
105+
TS_ASSERT(!comms::dispatchMsgTypePolymorphic<AllMessages>(MessageType2, handler));
106+
TS_ASSERT(!comms::dispatchMsgTypeStaticBinSearch<AllMessages>(MessageType2, handler));
107+
TS_ASSERT(!comms::dispatchMsgTypeLinearSwitch<AllMessages>(MessageType2, handler));
108+
TS_ASSERT_EQUALS(handler.detectedCnt(), 3U);
109+
} while (false);
110+
111+
do {
112+
using AllMessages =
113+
std::tuple<
114+
Message1<Interface1>,
115+
Message2<Interface1>
116+
>;
117+
118+
TypeHandler handler;
119+
TS_ASSERT(comms::dispatchMsgTypePolymorphic<AllMessages>(MessageType1, handler));
120+
TS_ASSERT_EQUALS(handler.lastId(), MessageType1);
121+
TS_ASSERT(comms::dispatchMsgTypeStaticBinSearch<AllMessages>(MessageType1, handler));
122+
TS_ASSERT_EQUALS(handler.lastId(), MessageType1);
123+
TS_ASSERT(comms::dispatchMsgTypeLinearSwitch<AllMessages>(MessageType1, handler));
124+
TS_ASSERT_EQUALS(handler.lastId(), MessageType1);
125+
TS_ASSERT_EQUALS(handler.detectedCnt(), 3U);
126+
127+
TS_ASSERT(comms::dispatchMsgTypePolymorphic<AllMessages>(MessageType2, handler));
128+
TS_ASSERT_EQUALS(handler.lastId(), MessageType2);
129+
TS_ASSERT(comms::dispatchMsgTypeStaticBinSearch<AllMessages>(MessageType2, handler));
130+
TS_ASSERT_EQUALS(handler.lastId(), MessageType2);
131+
TS_ASSERT(comms::dispatchMsgTypeLinearSwitch<AllMessages>(MessageType2, handler));
132+
TS_ASSERT_EQUALS(handler.lastId(), MessageType2);
133+
TS_ASSERT_EQUALS(handler.detectedCnt(), 6U);
134+
135+
TS_ASSERT(!comms::dispatchMsgTypePolymorphic<AllMessages>(MessageType3, handler));
136+
TS_ASSERT(!comms::dispatchMsgTypeStaticBinSearch<AllMessages>(MessageType3, handler));
137+
TS_ASSERT(!comms::dispatchMsgTypeLinearSwitch<AllMessages>(MessageType3, handler));
138+
TS_ASSERT_EQUALS(handler.detectedCnt(), 6U);
139+
} while (false);
140+
141+
do {
142+
using AllMessages =
143+
std::tuple<
144+
Message1<Interface1>,
145+
Message2<Interface1>,
146+
Message3<Interface1>
147+
>;
148+
149+
TypeHandler handler;
150+
TS_ASSERT(comms::dispatchMsgTypePolymorphic<AllMessages>(MessageType1, handler));
151+
TS_ASSERT_EQUALS(handler.lastId(), MessageType1);
152+
TS_ASSERT(comms::dispatchMsgTypeStaticBinSearch<AllMessages>(MessageType1, handler));
153+
TS_ASSERT_EQUALS(handler.lastId(), MessageType1);
154+
TS_ASSERT(comms::dispatchMsgTypeLinearSwitch<AllMessages>(MessageType1, handler));
155+
TS_ASSERT_EQUALS(handler.lastId(), MessageType1);
156+
TS_ASSERT_EQUALS(handler.detectedCnt(), 3U);
157+
158+
TS_ASSERT(comms::dispatchMsgTypePolymorphic<AllMessages>(MessageType2, handler));
159+
TS_ASSERT_EQUALS(handler.lastId(), MessageType2);
160+
TS_ASSERT(comms::dispatchMsgTypeStaticBinSearch<AllMessages>(MessageType2, handler));
161+
TS_ASSERT_EQUALS(handler.lastId(), MessageType2);
162+
TS_ASSERT(comms::dispatchMsgTypeLinearSwitch<AllMessages>(MessageType2, handler));
163+
TS_ASSERT_EQUALS(handler.lastId(), MessageType2);
164+
TS_ASSERT_EQUALS(handler.detectedCnt(), 6U);
165+
166+
TS_ASSERT(comms::dispatchMsgTypePolymorphic<AllMessages>(MessageType3, handler));
167+
TS_ASSERT_EQUALS(handler.lastId(), MessageType3);
168+
TS_ASSERT(comms::dispatchMsgTypeStaticBinSearch<AllMessages>(MessageType3, handler));
169+
TS_ASSERT_EQUALS(handler.lastId(), MessageType3);
170+
TS_ASSERT(comms::dispatchMsgTypeLinearSwitch<AllMessages>(MessageType3, handler));
171+
TS_ASSERT_EQUALS(handler.lastId(), MessageType3);
172+
TS_ASSERT_EQUALS(handler.detectedCnt(), 9U);
173+
174+
TS_ASSERT(!comms::dispatchMsgTypePolymorphic<AllMessages>(MessageType4, handler));
175+
TS_ASSERT(!comms::dispatchMsgTypeStaticBinSearch<AllMessages>(MessageType4, handler));
176+
TS_ASSERT(!comms::dispatchMsgTypeLinearSwitch<AllMessages>(MessageType4, handler));
177+
TS_ASSERT_EQUALS(handler.detectedCnt(), 9U);
178+
179+
} while (false);
180+
181+
}
182+

0 commit comments

Comments
 (0)