13#include "comms/details/MsgFactoryOptionsParser.h"
14#include "comms/details/tag.h"
31template <
typename TAllMessages>
32constexpr bool msgFactoryAllHaveStaticNumId()
34 return allMessagesHaveStaticNumId<TAllMessages>();
37template <
typename TMessage>
38constexpr bool msgFactoryMessageHasStaticNumId()
40 return messageHasStaticNumId<TMessage>();
43template <
typename TMsgBase,
typename TAllMessages,
typename... TOptions>
46 static_assert(TMsgBase::hasMsgIdType(),
47 "Usage of MsgFactoryBase requires Message interface to provide ID type. "
48 "Use comms::option::def::MsgIdType option in message interface type definition.");
49 using ParsedOptionsInternal = details::MsgFactoryOptionsParser<TOptions...>;
51 static const bool InterfaceHasVirtualDestructor =
52 std::has_virtual_destructor<TMsgBase>::value;
54 using AllMessagesInternal =
55 typename ParsedOptionsInternal::template AllMessages<TAllMessages>;
56 using GenericMessageInternal =
typename ParsedOptionsInternal::GenericMessage;
58 template <
typename...>
59 struct InPlaceAllocDeepCondWrap
63 typename TAllocMessages,
64 typename TOrigMessages,
66 typename TDefaultType,
69 typename comms::util::LazyDeepConditional<
70 InterfaceHasVirtualDestructor
72 comms::util::alloc::details::InPlaceSingleDeepCondWrap,
73 comms::util::alloc::details::InPlaceSingleNoVirtualDestructorDeepCondWrap,
82 template <
typename...>
83 struct DynMemoryAllocDeepCondWrap
87 typename TAllocMessages,
88 typename TOrigMessages,
90 typename TDefaultType,
93 typename comms::util::LazyDeepConditional<
94 InterfaceHasVirtualDestructor
96 comms::util::alloc::details::DynMemoryDeepCondWrap,
97 comms::util::alloc::details::DynMemoryNoVirtualDestructorDeepCondWrap,
106 typename comms::util::LazyDeepConditional<
107 ParsedOptionsInternal::HasInPlaceAllocation
109 InPlaceAllocDeepCondWrap,
110 DynMemoryAllocDeepCondWrap,
114 typename TMsgBase::MsgIdType,
115 GenericMessageInternal
118 using ParsedOptions = ParsedOptionsInternal;
119 using Message = TMsgBase;
122 using MsgPtr =
typename Alloc::Ptr;
123 using AllMessages = TAllMessages;
127 MsgPtr createMsg(MsgIdParamType
id,
unsigned idx, CreateFailureReason* reason)
const
129 CreateFailureReason reasonTmp = CreateFailureReason::None;
131 MsgPtr msg = createMsgInternal(
id, idx, result, DestructorTag<>());
139 reasonTmp = CreateFailureReason::InvalidId;
143 reasonTmp = CreateFailureReason::AllocFailure;
146 if (reason !=
nullptr) {
153 MsgPtr createGenericMsg(MsgIdParamType
id,
unsigned idx)
const
155 static_cast<void>(
this);
157 typename comms::util::LazyShallowConditional<
158 ParsedOptions::HasSupportGenericMessage
164 return createGenericMsgInternal(
id, idx, Tag(), DestructorTag<>());
167 bool canAllocate()
const
169 return m_alloc.canAllocate();
172 std::size_t msgCount(MsgIdParamType
id)
const
174 return comms::dispatchMsgTypeCountStaticBinSearch<AllMessages>(
id);
177 static constexpr bool hasUniqueIds()
179 return comms::details::allMessagesAreStrongSorted<AllMessages>();
182 static constexpr bool isDispatchPolymorphic()
184 return isDispatchPolymorphicInternal(DispatchTag<>());
187 static constexpr bool isDispatchStaticBinSearch()
189 return isDispatchStaticBinSearchInternal(DispatchTag<>());
192 static constexpr bool isDispatchLinearSwitch()
194 return isDispatchLinearSwitchInternal(DispatchTag<>());
198 MsgFactoryBase() =
default;
199 MsgFactoryBase(
const MsgFactoryBase&) =
default;
200 MsgFactoryBase(MsgFactoryBase&&) =
default;
201 MsgFactoryBase& operator=(
const MsgFactoryBase&) =
default;
202 MsgFactoryBase& operator=(MsgFactoryBase&&) =
default;
204 template <
typename TObj,
typename... TArgs>
205 MsgPtr allocMsg(TArgs&&... args)
const
207 static_assert(std::is_base_of<Message, TObj>::value,
208 "TObj is not a proper message type");
210 static_assert(std::has_virtual_destructor<TObj>::value,
211 "This function is expected to be called for message objects with virtual destructor");
213 (!ParsedOptionsInternal::HasInPlaceAllocation) ||
215 "TObj must be in provided tuple of supported messages");
217 return m_alloc.template alloc<TObj>(std::forward<TArgs>(args)...);
220 template <
typename TObj,
typename... TArgs>
221 MsgPtr allocMsg(MsgIdParamType
id,
unsigned idx, TArgs&&... args)
const
223 static_assert(std::is_base_of<Message, TObj>::value,
224 "TObj is not a proper message type");
226 static_assert(!std::has_virtual_destructor<TObj>::value,
227 "This function is expected to be called for message objects without virtual destructor");
230 (!ParsedOptionsInternal::HasInPlaceAllocation) ||
232 "TObj must be in provided tuple of supported messages");
234 return m_alloc.template alloc<TObj>(
id, idx, std::forward<TArgs>(args)...);
238 template <
typename... TParams>
239 using AllocGenericTag = comms::details::tag::Tag1<>;
241 template <
typename... TParams>
242 using NoAllocTag = comms::details::tag::Tag2<>;
244 template <
typename... TParams>
245 using ForcedTag = comms::details::tag::Tag3<>;
247 template <
typename... TParams>
248 using StandardTag = comms::details::tag::Tag4<>;
250 template <
typename... TParams>
251 using VirtualDestructorTag = comms::details::tag::Tag5<>;
253 template <
typename... TParams>
254 using NonVirtualDestructorTag = comms::details::tag::Tag6<>;
256 template <
typename...>
258 typename comms::util::LazyShallowConditional<
259 ParsedOptions::HasForcedDispatch
265 template <
typename...>
266 using DestructorTag =
267 typename comms::util::LazyShallowConditional<
268 InterfaceHasVirtualDestructor
270 VirtualDestructorTag,
271 NonVirtualDestructorTag
277 explicit CreateHandler(Alloc& a) : m_a(a) {}
281 return std::move(m_msg);
284 template <
typename T>
287 m_msg = m_a.template alloc<T>();
295 class NonVirtualDestructorCreateHandler
298 explicit NonVirtualDestructorCreateHandler(MsgIdParamType
id,
unsigned idx, Alloc& a) :
307 return std::move(m_msg);
310 template <
typename T>
313 m_msg = m_a.template alloc<T>(m_id, m_idx);
323 template <
typename... TParams>
324 MsgPtr createGenericMsgInternal(MsgIdParamType
id,
unsigned idx, AllocGenericTag<TParams...>, VirtualDestructorTag<TParams...>)
const
326 static_cast<void>(idx);
327 static_assert(std::is_base_of<Message, typename ParsedOptions::GenericMessage>::value,
328 "The requested GenericMessage class must have the same interface class as all other messages");
329 return allocMsg<typename ParsedOptions::GenericMessage>(
id);
332 template <
typename... TParams>
333 MsgPtr createGenericMsgInternal(MsgIdParamType
id,
unsigned idx, AllocGenericTag<TParams...>, NonVirtualDestructorTag<TParams...>)
const
335 static_assert(std::is_base_of<Message, typename ParsedOptions::GenericMessage>::value,
336 "The requested GenericMessage class must have the same interface class as all other messages");
337 return allocMsg<typename ParsedOptions::GenericMessage>(
id, idx,
id);
340 template <
typename TDestructorTag,
typename... TParams>
341 static MsgPtr createGenericMsgInternal(MsgIdParamType, NoAllocTag<TParams...>, TDestructorTag)
346 template <
typename THandler,
typename... TParams>
347 static bool dispatchMsgTypeInternal(MsgIdParamType
id,
unsigned idx, THandler& handler, StandardTag<TParams...>)
349 return comms::dispatchMsgType<AllMessages>(
id, idx, handler);
352 template <
typename THandler,
typename... TParams>
353 static bool dispatchMsgTypeInternal(MsgIdParamType
id,
unsigned idx, THandler& handler, ForcedTag<TParams...>)
355 using Tag =
typename ParsedOptions::ForcedDispatch;
356 return dispatchMsgTypeInternal(
id, idx, handler, Tag());
359 template <
typename THandler>
362 return comms::dispatchMsgTypePolymorphic<AllMessages>(
id, idx, handler);
365 template <
typename THandler>
368 return comms::dispatchMsgTypeStaticBinSearch<AllMessages>(
id, idx, handler);
371 template <
typename THandler>
374 return comms::dispatchMsgTypeStaticBinSearch<AllMessages>(
id, idx, handler);
377 template <
typename... TParams>
378 static constexpr bool isDispatchPolymorphicInternal(ForcedTag<TParams...>)
380 return std::is_same<comms::traits::dispatch::Polymorphic, typename ParsedOptions::ForcedDispatch>::value;
383 template <
typename... TParams>
384 static constexpr bool isDispatchPolymorphicInternal(StandardTag<TParams...>)
386 return dispatchMsgTypeIsPolymorphic<AllMessages>();
389 template <
typename... TParams>
390 static constexpr bool isDispatchStaticBinSearchInternal(ForcedTag<TParams...>)
392 return std::is_same<comms::traits::dispatch::StaticBinSearch, typename ParsedOptions::ForcedDispatch>::value;
395 template <
typename... TParams>
396 static constexpr bool isDispatchStaticBinSearchInternal(StandardTag<TParams...>)
398 return dispatchMsgTypeIsStaticBinSearch<AllMessages>();
401 template <
typename... TParams>
402 static constexpr bool isDispatchLinearSwitchInternal(ForcedTag<TParams...>)
404 return std::is_same<comms::traits::dispatch::LinearSwitch, typename ParsedOptions::ForcedDispatch>::value;
407 template <
typename... TParams>
408 static constexpr bool isDispatchLinearSwitchInternal(StandardTag<TParams...>)
413 template <
typename... TParams>
414 MsgPtr createMsgInternal(MsgIdParamType
id,
unsigned idx,
bool& success, VirtualDestructorTag<TParams...>)
const
416 CreateHandler handler(m_alloc);
417 success = dispatchMsgTypeInternal(
id, idx, handler, DispatchTag<>());
418 return handler.getMsg();
421 template <
typename... TParams>
422 MsgPtr createMsgInternal(MsgIdParamType
id,
unsigned idx,
bool& success, NonVirtualDestructorTag<TParams...>)
const
424 NonVirtualDestructorCreateHandler handler(
id, idx, m_alloc);
425 success = dispatchMsgTypeInternal(
id, idx, handler, DispatchTag<>());
426 return handler.getMsg();
429 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:195
typename BaseImpl::MsgIdParamType MsgIdParamType
Type used for message ID passed as parameter or returned from function.
Definition Message.h:202
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:1473
Main namespace for all classes / functions of COMMS library.
MsgFactoryCreateFailureReason
Definition MsgFactoryCreateFailureReason.h:18
Tag class used to indicate linear switch dispatch.
Definition traits.h:208
Tag class used to indicate polymorphic dispatch.
Definition traits.h:202
Tag class used to indicate static binary search dispatch.
Definition traits.h:205
Check whether TType type is included in the tuple TTuple.
Definition Tuple.h:95
This file contains all the classes necessary to properly define message traits.
Replacement to some types from standard type_traits.