COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
MessageInterfaceBases.h
1//
2// Copyright 2015 - 2025 (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 "comms/Assert.h"
11#include "comms/details/tag.h"
12#include "comms/ErrorStatus.h"
13#include "comms/Field.h"
14#include "comms/options.h"
15#include "comms/util/access.h"
16#include "comms/util/Tuple.h"
18
19#include <cstddef>
20#include <tuple>
21
22namespace comms
23{
24
25namespace details
26{
27
28using MessageInterfaceEmptyBase = comms::util::EmptyStruct<>;
29
30// ------------------------------------------------------
31
32template <typename TEndian>
33class MessageInterfaceEndianBase
34{
35public:
36 using Endian = TEndian;
37
39
40protected:
41 ~MessageInterfaceEndianBase() noexcept = default;
42
43 template <typename T, typename TIter>
44 static void writeData(T value, TIter& iter)
45 {
46 writeData<sizeof(T), T>(value, iter);
47 }
48
49 template <std::size_t TSize, typename T, typename TIter>
50 static void writeData(T value, TIter& iter)
51 {
52 static_assert(TSize <= sizeof(T),
53 "Cannot put more bytes than type contains");
54 return util::writeData<TSize, T>(value, iter, Endian());
55 }
56
57 template <typename T, typename TIter>
58 static T readData(TIter& iter)
59 {
60 return readData<T, sizeof(T)>(iter);
61 }
62
63 template <typename T, std::size_t TSize, typename TIter>
64 static T readData(TIter& iter)
65 {
66 static_assert(TSize <= sizeof(T),
67 "Cannot get more bytes than type contains");
68 return util::readData<T, TSize>(iter, Endian());
69 }
70};
71
72// ------------------------------------------------------
73
74template <typename TBase, typename TId>
75class MessageInterfaceIdTypeBase : public TBase
76{
77public:
78 using MsgIdType = TId;
79 using MsgIdParamType =
81 std::is_integral<MsgIdType>::value || std::is_enum<MsgIdType>::value
82 >::template Type<
84 const MsgIdType&
85 >;
86
87protected:
88 ~MessageInterfaceIdTypeBase() noexcept = default;
89};
90
91// ------------------------------------------------------
92
93template <typename TBase, typename TFields>
94class MessageInterfaceExtraTransportFieldsBase : public TBase
95{
96public:
97 using TransportFields = TFields;
98
99 static_assert(comms::util::isTuple<TransportFields>(),
100 "TransportFields is expected to be tuple");
101
102 TransportFields& transportFields()
103 {
104 return m_transportFields;
105 }
106
107 const TransportFields& transportFields() const
108 {
109 return m_transportFields;
110 }
111
112protected:
113 ~MessageInterfaceExtraTransportFieldsBase() noexcept = default;
114private:
115 TransportFields m_transportFields;
116};
117
118// ------------------------------------------------------
119
120template <typename TBase, std::size_t TIdx>
121class MessageInterfaceVersionInExtraTransportFieldsBase : public TBase
122{
123public:
124 using TransportFields = typename TBase::TransportFields;
125
126 static_assert(comms::util::isTuple<TransportFields>(),
127 "TransportFields is expected to be tuple");
128
129 static_assert(TIdx < std::tuple_size<TransportFields>::value,
130 "Index provided to comms::option::def::VersionInExtraTransportFields exceeds size of the tuple");
131
132 using VersionType = typename std::tuple_element<TIdx, TransportFields>::type::ValueType;
133
135 {
136 return std::get<TIdx>(TBase::transportFields()).value();
137 }
138
139 const VersionType& version() const
140 {
141 return std::get<TIdx>(TBase::transportFields()).value();
142 }
143
144protected:
145 ~MessageInterfaceVersionInExtraTransportFieldsBase() noexcept = default;
146};
147
148// ------------------------------------------------------
149
150template <typename TBase>
151class MessageInterfaceIdInfoBase : public TBase
152{
153public:
154 using MsgIdParamType = typename TBase::MsgIdParamType;
155
156 MsgIdParamType getId() const
157 {
158 return getIdImpl();
159 }
160
161protected:
162 ~MessageInterfaceIdInfoBase() noexcept = default;
163 virtual MsgIdParamType getIdImpl() const = 0;
164};
165
166// ------------------------------------------------------
167
168template <typename TBase, typename TReadIter>
169class MessageInterfaceReadBase : public TBase
170{
171public:
172 using ReadIterator = TReadIter;
173 comms::ErrorStatus read(ReadIterator& iter, std::size_t size)
174 {
175 return this->readImpl(iter, size);
176 }
177
178protected:
179 ~MessageInterfaceReadBase() noexcept = default;
180 virtual comms::ErrorStatus readImpl(ReadIterator& iter, std::size_t size)
181 {
182 static_cast<void>(iter);
183 static_cast<void>(size);
185 }
186};
187
188// ------------------------------------------------------
189
190template <typename TBase, typename TWriteIter>
191class MessageInterfaceWriteBase : public TBase
192{
193public:
194 using WriteIterator = TWriteIter;
195 comms::ErrorStatus write(WriteIterator& iter, std::size_t size) const
196 {
197 return this->writeImpl(iter, size);
198 }
199
200protected:
201 ~MessageInterfaceWriteBase() noexcept = default;
202 virtual comms::ErrorStatus writeImpl(WriteIterator& iter, std::size_t size) const
203 {
204 static_cast<void>(iter);
205 static_cast<void>(size);
207 }
208};
209
210// ------------------------------------------------------
211
212template <typename TBase>
213class MessageInterfaceValidBase : public TBase
214{
215public:
216 bool valid() const
217 {
218 return validImpl();
219 }
220
221protected:
222 ~MessageInterfaceValidBase() noexcept = default;
223 virtual bool validImpl() const
224 {
225 return true;
226 }
227};
228
229// ------------------------------------------------------
230
231template <typename TBase>
232class MessageInterfaceLengthBase : public TBase
233{
234public:
235 std::size_t length() const
236 {
237 return lengthImpl();
238 }
239
240protected:
241 ~MessageInterfaceLengthBase() noexcept = default;
242 virtual std::size_t lengthImpl() const
243 {
244 static constexpr bool Not_overriden = false;
245 static_cast<void>(Not_overriden);
246 COMMS_ASSERT(Not_overriden);
247 return 0;
248 }
249};
250
251// ------------------------------------------------------
252
253template <class T, class R = void>
254struct MessageInterfaceIfHasRetType { using Type = R; };
255
256template <class T, class Enable = void>
257struct MessageInterfaceDispatchRetTypeHelper
258{
259 using Type = void;
260};
261
262template <class T>
263struct MessageInterfaceDispatchRetTypeHelper<T, typename MessageInterfaceIfHasRetType<typename T::RetType>::Type>
264{
265 using Type = typename T::RetType;
266};
267
268template <class T>
269using MessageInterfaceDispatchRetType = typename MessageInterfaceDispatchRetTypeHelper<T>::Type;
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:168
This file contain definition of error statuses used by comms module.
Contains definition of comms::Field class.
Contains various tuple type manipulation classes and functions.
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:1981
comms::option::app::Handler< T > Handler
Same as comms::option::app::Handler.
Definition options.h:2006
comms::option::app::ReadIterator< TIter > ReadIterator
Same as comms::option::app::ReadIterator.
Definition options.h:1976
comms::option::def::VersionType< T > VersionType
Same as comms::option::def::VersionType.
Definition options.h:1928
comms::option::def::Endian< TEndian > Endian
Same as comms::option::def::Endian.
Definition options.h:1471
comms::option::def::MsgIdType< T > MsgIdType
Same as comms::option::def::MsgIdType.
Definition options.h:1484
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:29
Replacement to some types from standard type_traits.