COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
MessageInterfaceBases.h
1//
2// Copyright 2015 - 2024 (C). Alex Robenko. All rights reserved.
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
8#pragma once
9
10#include <tuple>
11#include <cstddef>
12
13#include "comms/Field.h"
14#include "comms/util/access.h"
16#include "comms/options.h"
17#include "comms/Assert.h"
18#include "comms/details/tag.h"
19#include "comms/ErrorStatus.h"
20
21namespace comms
22{
23
24namespace details
25{
26
27using MessageInterfaceEmptyBase = comms::util::EmptyStruct<>;
28
29// ------------------------------------------------------
30
31template <typename TEndian>
32class MessageInterfaceEndianBase
33{
34public:
35 using Endian = TEndian;
36
38
39protected:
40 ~MessageInterfaceEndianBase() noexcept = default;
41
42 template <typename T, typename TIter>
43 static void writeData(T value, TIter& iter)
44 {
45 writeData<sizeof(T), T>(value, iter);
46 }
47
48 template <std::size_t TSize, typename T, typename TIter>
49 static void writeData(T value, TIter& iter)
50 {
51 static_assert(TSize <= sizeof(T),
52 "Cannot put more bytes than type contains");
53 return util::writeData<TSize, T>(value, iter, Endian());
54 }
55
56 template <typename T, typename TIter>
57 static T readData(TIter& iter)
58 {
59 return readData<T, sizeof(T)>(iter);
60 }
61
62 template <typename T, std::size_t TSize, typename TIter>
63 static T readData(TIter& iter)
64 {
65 static_assert(TSize <= sizeof(T),
66 "Cannot get more bytes than type contains");
67 return util::readData<T, TSize>(iter, Endian());
68 }
69};
70
71// ------------------------------------------------------
72
73template <typename TBase, typename TId>
74class MessageInterfaceIdTypeBase : public TBase
75{
76public:
77 using MsgIdType = TId;
78 using MsgIdParamType =
80 std::is_integral<MsgIdType>::value || std::is_enum<MsgIdType>::value
81 >::template Type<
83 const MsgIdType&
84 >;
85
86protected:
87 ~MessageInterfaceIdTypeBase() noexcept = default;
88};
89
90// ------------------------------------------------------
91
92template <typename TBase, typename TFields>
93class MessageInterfaceExtraTransportFieldsBase : public TBase
94{
95public:
96 using TransportFields = TFields;
97
98 static_assert(comms::util::isTuple<TransportFields>(),
99 "TransportFields is expected to be tuple");
100
101 TransportFields& transportFields()
102 {
103 return transportFields_;
104 }
105
106 const TransportFields& transportFields() const
107 {
108 return transportFields_;
109 }
110
111protected:
112 ~MessageInterfaceExtraTransportFieldsBase() noexcept = default;
113private:
114 TransportFields transportFields_;
115};
116
117// ------------------------------------------------------
118
119template <typename TBase, std::size_t TIdx>
120class MessageInterfaceVersionInExtraTransportFieldsBase : public TBase
121{
122public:
123 using TransportFields = typename TBase::TransportFields;
124
125 static_assert(comms::util::isTuple<TransportFields>(),
126 "TransportFields is expected to be tuple");
127
128 static_assert(TIdx < std::tuple_size<TransportFields>::value,
129 "Index provided to comms::option::def::VersionInExtraTransportFields exceeds size of the tuple");
130
131 using VersionType = typename std::tuple_element<TIdx, TransportFields>::type::ValueType;
132
134 {
135 return std::get<TIdx>(TBase::transportFields()).value();
136 }
137
138 const VersionType& version() const
139 {
140 return std::get<TIdx>(TBase::transportFields()).value();
141 }
142
143protected:
144 ~MessageInterfaceVersionInExtraTransportFieldsBase() noexcept = default;
145};
146
147// ------------------------------------------------------
148
149template <typename TBase>
150class MessageInterfaceIdInfoBase : public TBase
151{
152public:
153 using MsgIdParamType = typename TBase::MsgIdParamType;
154
155 MsgIdParamType getId() const
156 {
157 return getIdImpl();
158 }
159
160protected:
161 ~MessageInterfaceIdInfoBase() noexcept = default;
162 virtual MsgIdParamType getIdImpl() const = 0;
163};
164
165// ------------------------------------------------------
166
167template <typename TBase, typename TReadIter>
168class MessageInterfaceReadBase : public TBase
169{
170public:
171 using ReadIterator = TReadIter;
172 comms::ErrorStatus read(ReadIterator& iter, std::size_t size)
173 {
174 return this->readImpl(iter, size);
175 }
176
177protected:
178 ~MessageInterfaceReadBase() noexcept = default;
179 virtual comms::ErrorStatus readImpl(ReadIterator& iter, std::size_t size)
180 {
181 static_cast<void>(iter);
182 static_cast<void>(size);
184 }
185};
186
187// ------------------------------------------------------
188
189template <typename TBase, typename TWriteIter>
190class MessageInterfaceWriteBase : public TBase
191{
192public:
193 using WriteIterator = TWriteIter;
194 comms::ErrorStatus write(WriteIterator& iter, std::size_t size) const
195 {
196 return this->writeImpl(iter, size);
197 }
198
199protected:
200 ~MessageInterfaceWriteBase() noexcept = default;
201 virtual comms::ErrorStatus writeImpl(WriteIterator& iter, std::size_t size) const
202 {
203 static_cast<void>(iter);
204 static_cast<void>(size);
206 }
207};
208
209// ------------------------------------------------------
210
211template <typename TBase>
212class MessageInterfaceValidBase : public TBase
213{
214public:
215 bool valid() const
216 {
217 return validImpl();
218 }
219
220protected:
221 ~MessageInterfaceValidBase() noexcept = default;
222 virtual bool validImpl() const
223 {
224 return true;
225 }
226};
227
228// ------------------------------------------------------
229
230template <typename TBase>
231class MessageInterfaceLengthBase : public TBase
232{
233public:
234 std::size_t length() const
235 {
236 return lengthImpl();
237 }
238
239protected:
240 ~MessageInterfaceLengthBase() noexcept = default;
241 virtual std::size_t lengthImpl() const
242 {
243 static constexpr bool Not_overriden = false;
244 static_cast<void>(Not_overriden);
245 COMMS_ASSERT(Not_overriden);
246 return 0;
247 }
248};
249
250// ------------------------------------------------------
251
252template <class T, class R = void>
253struct MessageInterfaceIfHasRetType { using Type = R; };
254
255template <class T, class Enable = void>
256struct MessageInterfaceDispatchRetTypeHelper
257{
258 using Type = void;
259};
260
261template <class T>
262struct MessageInterfaceDispatchRetTypeHelper<T, typename MessageInterfaceIfHasRetType<typename T::RetType>::Type>
263{
264 using Type = typename T::RetType;
265};
266
267template <class T>
268using MessageInterfaceDispatchRetType = typename MessageInterfaceDispatchRetTypeHelper<T>::Type;
269
270
271template <typename TBase, typename THandler>
272class MessageInterfaceHandlerBase : public TBase
273{
274public:
275 using Handler = THandler;
276 using DispatchRetType = MessageInterfaceDispatchRetType<Handler>;
277
278 DispatchRetType dispatch(Handler& handler)
279 {
280 return dispatchImpl(handler);
281 }
282
283protected:
284 ~MessageInterfaceHandlerBase() noexcept = default;
285 virtual DispatchRetType dispatchImpl(Handler& handler)
286 {
287 static_cast<void>(handler);
288 static constexpr bool Must_not_be_called = false;
289 static_cast<void>(Must_not_be_called);
290 COMMS_ASSERT(Must_not_be_called);
291 using Tag =
293 std::is_void<DispatchRetType>::value
294 >::template Type<
295 VoidHandleRetTypeTag,
296 NonVoidHandleRetTypeTag
297 >;
298 return dispatchInternal(Tag());
299 }
300
301private:
302 using VoidHandleRetTypeTag = comms::details::tag::Tag1<>;
303 using NonVoidHandleRetTypeTag = comms::details::tag::Tag2<>;
304
305 static DispatchRetType dispatchInternal(VoidHandleRetTypeTag)
306 {
307 return;
308 }
309
310 static DispatchRetType dispatchInternal(NonVoidHandleRetTypeTag)
311 {
312 using RetTypeInternal = typename std::decay<DispatchRetType>::type;
313 static const RetTypeInternal Ret = RetTypeInternal();
314 return Ret;
315 }
316};
317
318// ------------------------------------------------------
319
320template <typename TBase>
321class MessageInterfaceRefreshBase : public TBase
322{
323public:
324 bool refresh()
325 {
326 return refreshImpl();
327 }
328
329protected:
330 ~MessageInterfaceRefreshBase() noexcept = default;
331 virtual bool refreshImpl()
332 {
333 return false;
334 }
335};
336
337// ------------------------------------------------------
338
339template <typename TBase>
340class MessageInterfaceNameBase : public TBase
341{
342public:
343 const char* name() const
344 {
345 return nameImpl();
346 }
347
348protected:
349 ~MessageInterfaceNameBase() noexcept = default;
350 virtual const char* nameImpl() const = 0;
351};
352
353// ------------------------------------------------------
354
355template <typename TBase>
356class MessageInterfaceVirtDestructorBase : public TBase
357{
358protected:
359 virtual ~MessageInterfaceVirtDestructorBase() noexcept = default;
360};
361
362} // namespace details
363
364} // namespace comms
This file contains classes required for generic custom assertion functionality.
#define COMMS_ASSERT(expr)
Generic assert macro.
Definition Assert.h:170
This file contain definition of error statuses used by comms module.
Contains definition of comms::Field class.
Contains functions for raw data access / (de)serialization.
Base class to all the field classes.
Definition Field.h:33
comms::option::app::WriteIterator< TIter > WriteIterator
Same as comms::option::app::WriteIterator.
Definition options.h:1839
comms::option::app::Handler< T > Handler
Same as comms::option::app::Handler.
Definition options.h:1858
comms::option::app::ReadIterator< TIter > ReadIterator
Same as comms::option::app::ReadIterator.
Definition options.h:1835
comms::option::def::VersionType< T > VersionType
Same as comms::option::def::VersionType.
Definition options.h:1797
comms::option::def::Endian< TEndian > Endian
Same as comms::option::def::Endian.
Definition options.h:1438
comms::option::def::MsgIdType< T > MsgIdType
Same as comms::option::def::MsgIdType.
Definition options.h:1448
T readData(TIter &iter, const traits::endian::Big &endian)
Same as readBig<T, TIter>()
Definition access.h:774
void writeData(T value, TIter &iter, const traits::endian::Big &endian)
Same as writeBig<T, TIter>()
Definition access.h:706
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:17
@ NotSupported
The operation is not supported.
constexpr unsigned version()
Version of the COMMS library as single numeric value.
Definition version.h:64
STL namespace.
Contains definition of all the options used by the COMMS library.
Replacement to std::conditional.
Definition type_traits.h:28
Replacement to some types from standard type_traits.