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
271
272template <typename TBase, typename THandler>
273class MessageInterfaceHandlerBase : public TBase
274{
275public:
276 using Handler = THandler;
277 using DispatchRetType = MessageInterfaceDispatchRetType<Handler>;
278
279 DispatchRetType dispatch(Handler& handler)
280 {
281 return dispatchImpl(handler);
282 }
283
284protected:
285 ~MessageInterfaceHandlerBase() noexcept = default;
286 virtual DispatchRetType dispatchImpl(Handler& handler)
287 {
288 static_cast<void>(handler);
289 static constexpr bool Must_not_be_called = false;
290 static_cast<void>(Must_not_be_called);
291 COMMS_ASSERT(Must_not_be_called);
292 using Tag =
294 std::is_void<DispatchRetType>::value
295 >::template Type<
296 VoidHandleRetTypeTag,
297 NonVoidHandleRetTypeTag
298 >;
299 return dispatchInternal(Tag());
300 }
301
302private:
303 using VoidHandleRetTypeTag = comms::details::tag::Tag1<>;
304 using NonVoidHandleRetTypeTag = comms::details::tag::Tag2<>;
305
306 static DispatchRetType dispatchInternal(VoidHandleRetTypeTag)
307 {
308 return;
309 }
310
311 static DispatchRetType dispatchInternal(NonVoidHandleRetTypeTag)
312 {
313 using RetTypeInternal = typename std::decay<DispatchRetType>::type;
314 static const RetTypeInternal Ret = RetTypeInternal();
315 return Ret;
316 }
317};
318
319// ------------------------------------------------------
320
321template <typename TBase>
322class MessageInterfaceRefreshBase : public TBase
323{
324public:
325 bool refresh()
326 {
327 return refreshImpl();
328 }
329
330protected:
331 ~MessageInterfaceRefreshBase() noexcept = default;
332 virtual bool refreshImpl()
333 {
334 return false;
335 }
336};
337
338// ------------------------------------------------------
339
340template <typename TBase>
341class MessageInterfaceNameBase : public TBase
342{
343public:
344 const char* name() const
345 {
346 return nameImpl();
347 }
348
349protected:
350 ~MessageInterfaceNameBase() noexcept = default;
351 virtual const char* nameImpl() const = 0;
352};
353
354// ------------------------------------------------------
355
356template <typename TBase>
357class MessageInterfaceVirtDestructorBase : public TBase
358{
359protected:
360 virtual ~MessageInterfaceVirtDestructorBase() noexcept = default;
361};
362
363} // namespace details
364
365} // 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 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:1970
comms::option::app::Handler< T > Handler
Same as comms::option::app::Handler.
Definition options.h:1995
comms::option::app::ReadIterator< TIter > ReadIterator
Same as comms::option::app::ReadIterator.
Definition options.h:1965
comms::option::def::VersionType< T > VersionType
Same as comms::option::def::VersionType.
Definition options.h:1917
comms::option::def::Endian< TEndian > Endian
Same as comms::option::def::Endian.
Definition options.h:1460
comms::option::def::MsgIdType< T > MsgIdType
Same as comms::option::def::MsgIdType.
Definition options.h:1473
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.