15#include "comms/details/MsgFactoryOptionsParser.h"
16#include "comms/details/tag.h"
34template <
typename TAllMessages>
35constexpr bool msgFactoryAllHaveStaticNumId()
37 return allMessagesHaveStaticNumId<TAllMessages>();
40template <
typename TMessage>
41constexpr bool msgFactoryMessageHasStaticNumId()
43 return messageHasStaticNumId<TMessage>();
46template <
typename TMsgBase,
typename TAllMessages,
typename... TOptions>
49 static_assert(TMsgBase::hasMsgIdType(),
50 "Usage of MsgFactoryBase requires Message interface to provide ID type. "
51 "Use comms::option::def::MsgIdType option in message interface type definition.");
52 using ParsedOptionsInternal = details::MsgFactoryOptionsParser<TOptions...>;
54 static const bool InterfaceHasVirtualDestructor =
55 std::has_virtual_destructor<TMsgBase>::value;
57 using AllMessagesInternal =
58 typename ParsedOptionsInternal::template AllMessages<TAllMessages>;
59 using GenericMessageInternal =
typename ParsedOptionsInternal::GenericMessage;
61 template <
typename...>
62 struct InPlaceAllocDeepCondWrap
66 typename TAllocMessages,
67 typename TOrigMessages,
69 typename TDefaultType,
72 typename comms::util::LazyDeepConditional<
73 InterfaceHasVirtualDestructor
75 comms::util::alloc::details::InPlaceSingleDeepCondWrap,
76 comms::util::alloc::details::InPlaceSingleNoVirtualDestructorDeepCondWrap,
85 template <
typename...>
86 struct DynMemoryAllocDeepCondWrap
90 typename TAllocMessages,
91 typename TOrigMessages,
93 typename TDefaultType,
96 typename comms::util::LazyDeepConditional<
97 InterfaceHasVirtualDestructor
99 comms::util::alloc::details::DynMemoryDeepCondWrap,
100 comms::util::alloc::details::DynMemoryNoVirtualDestructorDeepCondWrap,
109 typename comms::util::LazyDeepConditional<
110 ParsedOptionsInternal::HasInPlaceAllocation
112 InPlaceAllocDeepCondWrap,
113 DynMemoryAllocDeepCondWrap,
117 typename TMsgBase::MsgIdType,
118 GenericMessageInternal
121 using ParsedOptions = ParsedOptionsInternal;
122 using Message = TMsgBase;
125 using MsgPtr =
typename Alloc::Ptr;
126 using AllMessages = TAllMessages;
130 MsgPtr createMsg(MsgIdParamType
id,
unsigned idx, CreateFailureReason* reason)
const
132 CreateFailureReason reasonTmp = CreateFailureReason::None;
134 MsgPtr msg = createMsgInternal(
id, idx, result, DestructorTag<>());
142 reasonTmp = CreateFailureReason::InvalidId;
146 reasonTmp = CreateFailureReason::AllocFailure;
149 if (reason !=
nullptr) {
156 MsgPtr createGenericMsg(MsgIdParamType
id,
unsigned idx)
const
158 static_cast<void>(
this);
160 typename comms::util::LazyShallowConditional<
161 ParsedOptions::HasSupportGenericMessage
167 return createGenericMsgInternal(
id, idx, Tag(), DestructorTag<>());
170 bool canAllocate()
const
172 return m_alloc.canAllocate();
175 std::size_t msgCount(MsgIdParamType
id)
const
177 return comms::dispatchMsgTypeCountStaticBinSearch<AllMessages>(
id);
180 static constexpr bool hasUniqueIds()
182 return comms::details::allMessagesAreStrongSorted<AllMessages>();
185 static constexpr bool isDispatchPolymorphic()
187 return isDispatchPolymorphicInternal(DispatchTag<>());
190 static constexpr bool isDispatchStaticBinSearch()
192 return isDispatchStaticBinSearchInternal(DispatchTag<>());
195 static constexpr bool isDispatchLinearSwitch()
197 return isDispatchLinearSwitchInternal(DispatchTag<>());
201 MsgFactoryBase() =
default;
202 MsgFactoryBase(
const MsgFactoryBase&) =
default;
203 MsgFactoryBase(MsgFactoryBase&&) =
default;
204 MsgFactoryBase& operator=(
const MsgFactoryBase&) =
default;
205 MsgFactoryBase& operator=(MsgFactoryBase&&) =
default;
207 template <
typename TObj,
typename... TArgs>
208 MsgPtr allocMsg(TArgs&&... args)
const
210 static_assert(std::is_base_of<Message, TObj>::value,
211 "TObj is not a proper message type");
213 static_assert(std::has_virtual_destructor<TObj>::value,
214 "This function is expected to be called for message objects with virtual destructor");
216 (!ParsedOptionsInternal::HasInPlaceAllocation) ||
218 "TObj must be in provided tuple of supported messages");
220 return m_alloc.template alloc<TObj>(std::forward<TArgs>(args)...);
223 template <
typename TObj,
typename... TArgs>
224 MsgPtr allocMsg(MsgIdParamType
id,
unsigned idx, TArgs&&... args)
const
226 static_assert(std::is_base_of<Message, TObj>::value,
227 "TObj is not a proper message type");
229 static_assert(!std::has_virtual_destructor<TObj>::value,
230 "This function is expected to be called for message objects without virtual destructor");
233 (!ParsedOptionsInternal::HasInPlaceAllocation) ||
235 "TObj must be in provided tuple of supported messages");
237 return m_alloc.template alloc<TObj>(
id, idx, std::forward<TArgs>(args)...);
241 template <
typename... TParams>
242 using AllocGenericTag = comms::details::tag::Tag1<>;
244 template <
typename... TParams>
245 using NoAllocTag = comms::details::tag::Tag2<>;
247 template <
typename... TParams>
248 using ForcedTag = comms::details::tag::Tag3<>;
250 template <
typename... TParams>
251 using StandardTag = comms::details::tag::Tag4<>;
253 template <
typename... TParams>
254 using VirtualDestructorTag = comms::details::tag::Tag5<>;
256 template <
typename... TParams>
257 using NonVirtualDestructorTag = comms::details::tag::Tag6<>;
259 template <
typename...>
261 typename comms::util::LazyShallowConditional<
262 ParsedOptions::HasForcedDispatch
268 template <
typename...>
269 using DestructorTag =
270 typename comms::util::LazyShallowConditional<
271 InterfaceHasVirtualDestructor
273 VirtualDestructorTag,
274 NonVirtualDestructorTag
280 explicit CreateHandler(Alloc& a) : m_a(a) {}
284 return std::move(m_msg);
287 template <
typename T>
290 m_msg = m_a.template alloc<T>();
298 class NonVirtualDestructorCreateHandler
301 explicit NonVirtualDestructorCreateHandler(MsgIdParamType
id,
unsigned idx, Alloc& a) :
310 return std::move(m_msg);
313 template <
typename T>
316 m_msg = m_a.template alloc<T>(m_id, m_idx);
326 template <
typename... TParams>
327 MsgPtr createGenericMsgInternal(MsgIdParamType
id,
unsigned idx, AllocGenericTag<TParams...>, VirtualDestructorTag<TParams...>)
const
329 static_cast<void>(idx);
330 static_assert(std::is_base_of<Message, typename ParsedOptions::GenericMessage>::value,
331 "The requested GenericMessage class must have the same interface class as all other messages");
332 return allocMsg<typename ParsedOptions::GenericMessage>(
id);
335 template <
typename... TParams>
336 MsgPtr createGenericMsgInternal(MsgIdParamType
id,
unsigned idx, AllocGenericTag<TParams...>, NonVirtualDestructorTag<TParams...>)
const
338 static_assert(std::is_base_of<Message, typename ParsedOptions::GenericMessage>::value,
339 "The requested GenericMessage class must have the same interface class as all other messages");
340 return allocMsg<typename ParsedOptions::GenericMessage>(
id, idx,
id);
343 template <
typename TDestructorTag,
typename... TParams>
344 static MsgPtr createGenericMsgInternal(MsgIdParamType, NoAllocTag<TParams...>, TDestructorTag)
349 template <
typename THandler,
typename... TParams>
350 static bool dispatchMsgTypeInternal(MsgIdParamType
id,
unsigned idx, THandler& handler, StandardTag<TParams...>)
352 return comms::dispatchMsgType<AllMessages>(
id, idx, handler);
355 template <
typename THandler,
typename... TParams>
356 static bool dispatchMsgTypeInternal(MsgIdParamType
id,
unsigned idx, THandler& handler, ForcedTag<TParams...>)
358 using Tag =
typename ParsedOptions::ForcedDispatch;
359 return dispatchMsgTypeInternal(
id, idx, handler, Tag());
362 template <
typename THandler>
365 return comms::dispatchMsgTypePolymorphic<AllMessages>(
id, idx, handler);
368 template <
typename THandler>
371 return comms::dispatchMsgTypeStaticBinSearch<AllMessages>(
id, idx, handler);
374 template <
typename THandler>
377 return comms::dispatchMsgTypeStaticBinSearch<AllMessages>(
id, idx, handler);
380 template <
typename... TParams>
381 static constexpr bool isDispatchPolymorphicInternal(ForcedTag<TParams...>)
383 return std::is_same<comms::traits::dispatch::Polymorphic, typename ParsedOptions::ForcedDispatch>::value;
386 template <
typename... TParams>
387 static constexpr bool isDispatchPolymorphicInternal(StandardTag<TParams...>)
389 return dispatchMsgTypeIsPolymorphic<AllMessages>();
392 template <
typename... TParams>
393 static constexpr bool isDispatchStaticBinSearchInternal(ForcedTag<TParams...>)
395 return std::is_same<comms::traits::dispatch::StaticBinSearch, typename ParsedOptions::ForcedDispatch>::value;
398 template <
typename... TParams>
399 static constexpr bool isDispatchStaticBinSearchInternal(StandardTag<TParams...>)
401 return dispatchMsgTypeIsStaticBinSearch<AllMessages>();
404 template <
typename... TParams>
405 static constexpr bool isDispatchLinearSwitchInternal(ForcedTag<TParams...>)
407 return std::is_same<comms::traits::dispatch::LinearSwitch, typename ParsedOptions::ForcedDispatch>::value;
410 template <
typename... TParams>
411 static constexpr bool isDispatchLinearSwitchInternal(StandardTag<TParams...>)
416 template <
typename... TParams>
417 MsgPtr createMsgInternal(MsgIdParamType
id,
unsigned idx,
bool& success, VirtualDestructorTag<TParams...>)
const
419 CreateHandler handler(m_alloc);
420 success = dispatchMsgTypeInternal(
id, idx, handler, DispatchTag<>());
421 return handler.getMsg();
424 template <
typename... TParams>
425 MsgPtr createMsgInternal(MsgIdParamType
id,
unsigned idx,
bool& success, NonVirtualDestructorTag<TParams...>)
const
427 NonVirtualDestructorCreateHandler handler(
id, idx, m_alloc);
428 success = dispatchMsgTypeInternal(
id, idx, handler, DispatchTag<>());
429 return handler.getMsg();
432 mutable Alloc m_alloc;
This file contains classes required for generic custom assertion functionality.
#define COMMS_ASSERT(expr)
Generic assert macro.
Definition Assert.h:170
Provides common base class for the custom messages with default implementation.
Contains definition of comms::MsgFactoryCreateFailureReason enum.
Contains various tuple type manipulation classes and functions.
This file contains various generic allocator classes that may be used to allocate objects using dynam...
typename BaseImpl::MsgIdType MsgIdType
Type used for message ID.
Definition Message.h:196
typename BaseImpl::MsgIdParamType MsgIdParamType
Type used for message ID passed as parameter or returned from function.
Definition Message.h:203
Contains extra logic to help with dispatching message types and objects.
comms::option::def::MsgIdType< T > MsgIdType
Same as comms::option::def::MsgIdType.
Definition options.h:1486
Main namespace for all classes / functions of COMMS library.
MsgFactoryCreateFailureReason
Definition MsgFactoryCreateFailureReason.h:20
Tag class used to indicate linear switch dispatch.
Definition traits.h:209
Tag class used to indicate polymorphic dispatch.
Definition traits.h:203
Tag class used to indicate static binary search dispatch.
Definition traits.h:206
Check whether TType type is included in the tuple TTuple.
Definition Tuple.h:98
This file contains all the classes necessary to properly define message traits.
Replacement to some types from standard type_traits.