13#include "comms/details/MsgFactoryOptionsParser.h"
14#include "comms/details/tag.h"
32template <
typename TAllMessages>
33constexpr bool msgFactoryAllHaveStaticNumId()
35 return allMessagesHaveStaticNumId<TAllMessages>();
38template <
typename TMessage>
39constexpr bool msgFactoryMessageHasStaticNumId()
41 return messageHasStaticNumId<TMessage>();
44template <
typename TMsgBase,
typename TAllMessages,
typename... TOptions>
47 static_assert(TMsgBase::hasMsgIdType(),
48 "Usage of MsgFactoryBase requires Message interface to provide ID type. "
49 "Use comms::option::def::MsgIdType option in message interface type definition.");
50 using ParsedOptionsInternal = details::MsgFactoryOptionsParser<TOptions...>;
52 static const bool InterfaceHasVirtualDestructor =
53 std::has_virtual_destructor<TMsgBase>::value;
55 using AllMessagesInternal =
56 typename ParsedOptionsInternal::template AllMessages<TAllMessages>;
57 using GenericMessageInternal =
typename ParsedOptionsInternal::GenericMessage;
59 template <
typename...>
60 struct InPlaceAllocDeepCondWrap
64 typename TAllocMessages,
65 typename TOrigMessages,
67 typename TDefaultType,
70 typename comms::util::LazyDeepConditional<
71 InterfaceHasVirtualDestructor
73 comms::util::alloc::details::InPlaceSingleDeepCondWrap,
74 comms::util::alloc::details::InPlaceSingleNoVirtualDestructorDeepCondWrap,
83 template <
typename...>
84 struct DynMemoryAllocDeepCondWrap
88 typename TAllocMessages,
89 typename TOrigMessages,
91 typename TDefaultType,
94 typename comms::util::LazyDeepConditional<
95 InterfaceHasVirtualDestructor
97 comms::util::alloc::details::DynMemoryDeepCondWrap,
98 comms::util::alloc::details::DynMemoryNoVirtualDestructorDeepCondWrap,
107 typename comms::util::LazyDeepConditional<
108 ParsedOptionsInternal::HasInPlaceAllocation
110 InPlaceAllocDeepCondWrap,
111 DynMemoryAllocDeepCondWrap,
115 typename TMsgBase::MsgIdType,
116 GenericMessageInternal
119 using ParsedOptions = ParsedOptionsInternal;
120 using Message = TMsgBase;
123 using MsgPtr =
typename Alloc::Ptr;
124 using AllMessages = TAllMessages;
128 MsgPtr createMsg(MsgIdParamType
id,
unsigned idx, CreateFailureReason* reason)
const
130 CreateFailureReason reasonTmp = CreateFailureReason::None;
132 MsgPtr msg = createMsgInternal(
id, idx, result, DestructorTag<>());
140 reasonTmp = CreateFailureReason::InvalidId;
144 reasonTmp = CreateFailureReason::AllocFailure;
147 if (reason !=
nullptr) {
154 MsgPtr createGenericMsg(MsgIdParamType
id,
unsigned idx)
const
156 static_cast<void>(
this);
158 typename comms::util::LazyShallowConditional<
159 ParsedOptions::HasSupportGenericMessage
165 return createGenericMsgInternal(
id, idx, Tag(), DestructorTag<>());
168 bool canAllocate()
const
170 return m_alloc.canAllocate();
173 std::size_t msgCount(MsgIdParamType
id)
const
175 return comms::dispatchMsgTypeCountStaticBinSearch<AllMessages>(
id);
178 static constexpr bool hasUniqueIds()
180 return comms::details::allMessagesAreStrongSorted<AllMessages>();
183 static constexpr bool isDispatchPolymorphic()
185 return isDispatchPolymorphicInternal(DispatchTag<>());
188 static constexpr bool isDispatchStaticBinSearch()
190 return isDispatchStaticBinSearchInternal(DispatchTag<>());
193 static constexpr bool isDispatchLinearSwitch()
195 return isDispatchLinearSwitchInternal(DispatchTag<>());
199 MsgFactoryBase() =
default;
200 MsgFactoryBase(
const MsgFactoryBase&) =
default;
201 MsgFactoryBase(MsgFactoryBase&&) =
default;
202 MsgFactoryBase& operator=(
const MsgFactoryBase&) =
default;
203 MsgFactoryBase& operator=(MsgFactoryBase&&) =
default;
205 template <
typename TObj,
typename... TArgs>
206 MsgPtr allocMsg(TArgs&&... args)
const
208 static_assert(std::is_base_of<Message, TObj>::value,
209 "TObj is not a proper message type");
211 static_assert(std::has_virtual_destructor<TObj>::value,
212 "This function is expected to be called for message objects with virtual destructor");
214 (!ParsedOptionsInternal::HasInPlaceAllocation) ||
216 "TObj must be in provided tuple of supported messages");
218 return m_alloc.template alloc<TObj>(std::forward<TArgs>(args)...);
221 template <
typename TObj,
typename... TArgs>
222 MsgPtr allocMsg(MsgIdParamType
id,
unsigned idx, TArgs&&... args)
const
224 static_assert(std::is_base_of<Message, TObj>::value,
225 "TObj is not a proper message type");
227 static_assert(!std::has_virtual_destructor<TObj>::value,
228 "This function is expected to be called for message objects without virtual destructor");
231 (!ParsedOptionsInternal::HasInPlaceAllocation) ||
233 "TObj must be in provided tuple of supported messages");
235 return m_alloc.template alloc<TObj>(
id, idx, std::forward<TArgs>(args)...);
239 template <
typename... TParams>
240 using AllocGenericTag = comms::details::tag::Tag1<>;
242 template <
typename... TParams>
243 using NoAllocTag = comms::details::tag::Tag2<>;
245 template <
typename... TParams>
246 using ForcedTag = comms::details::tag::Tag3<>;
248 template <
typename... TParams>
249 using StandardTag = comms::details::tag::Tag4<>;
251 template <
typename... TParams>
252 using VirtualDestructorTag = comms::details::tag::Tag5<>;
254 template <
typename... TParams>
255 using NonVirtualDestructorTag = comms::details::tag::Tag6<>;
257 template <
typename...>
259 typename comms::util::LazyShallowConditional<
260 ParsedOptions::HasForcedDispatch
266 template <
typename...>
267 using DestructorTag =
268 typename comms::util::LazyShallowConditional<
269 InterfaceHasVirtualDestructor
271 VirtualDestructorTag,
272 NonVirtualDestructorTag
278 explicit CreateHandler(Alloc& a) : m_a(a) {}
282 return std::move(m_msg);
285 template <
typename T>
288 m_msg = m_a.template alloc<T>();
296 class NonVirtualDestructorCreateHandler
299 explicit NonVirtualDestructorCreateHandler(MsgIdParamType
id,
unsigned idx, Alloc& a) :
308 return std::move(m_msg);
311 template <
typename T>
314 m_msg = m_a.template alloc<T>(m_id, m_idx);
324 template <
typename... TParams>
325 MsgPtr createGenericMsgInternal(MsgIdParamType
id,
unsigned idx, AllocGenericTag<TParams...>, VirtualDestructorTag<TParams...>)
const
327 static_cast<void>(idx);
328 static_assert(std::is_base_of<Message, typename ParsedOptions::GenericMessage>::value,
329 "The requested GenericMessage class must have the same interface class as all other messages");
330 return allocMsg<typename ParsedOptions::GenericMessage>(
id);
333 template <
typename... TParams>
334 MsgPtr createGenericMsgInternal(MsgIdParamType
id,
unsigned idx, AllocGenericTag<TParams...>, NonVirtualDestructorTag<TParams...>)
const
336 static_assert(std::is_base_of<Message, typename ParsedOptions::GenericMessage>::value,
337 "The requested GenericMessage class must have the same interface class as all other messages");
338 return allocMsg<typename ParsedOptions::GenericMessage>(
id, idx,
id);
341 template <
typename TDestructorTag,
typename... TParams>
342 static MsgPtr createGenericMsgInternal(MsgIdParamType, NoAllocTag<TParams...>, TDestructorTag)
347 template <
typename THandler,
typename... TParams>
348 static bool dispatchMsgTypeInternal(MsgIdParamType
id,
unsigned idx, THandler& handler, StandardTag<TParams...>)
350 return comms::dispatchMsgType<AllMessages>(
id, idx, handler);
353 template <
typename THandler,
typename... TParams>
354 static bool dispatchMsgTypeInternal(MsgIdParamType
id,
unsigned idx, THandler& handler, ForcedTag<TParams...>)
356 using Tag =
typename ParsedOptions::ForcedDispatch;
357 return dispatchMsgTypeInternal(
id, idx, handler, Tag());
360 template <
typename THandler>
363 return comms::dispatchMsgTypePolymorphic<AllMessages>(
id, idx, handler);
366 template <
typename THandler>
369 return comms::dispatchMsgTypeStaticBinSearch<AllMessages>(
id, idx, handler);
372 template <
typename THandler>
375 return comms::dispatchMsgTypeStaticBinSearch<AllMessages>(
id, idx, handler);
378 template <
typename... TParams>
379 static constexpr bool isDispatchPolymorphicInternal(ForcedTag<TParams...>)
381 return std::is_same<comms::traits::dispatch::Polymorphic, typename ParsedOptions::ForcedDispatch>::value;
384 template <
typename... TParams>
385 static constexpr bool isDispatchPolymorphicInternal(StandardTag<TParams...>)
387 return dispatchMsgTypeIsPolymorphic<AllMessages>();
390 template <
typename... TParams>
391 static constexpr bool isDispatchStaticBinSearchInternal(ForcedTag<TParams...>)
393 return std::is_same<comms::traits::dispatch::StaticBinSearch, typename ParsedOptions::ForcedDispatch>::value;
396 template <
typename... TParams>
397 static constexpr bool isDispatchStaticBinSearchInternal(StandardTag<TParams...>)
399 return dispatchMsgTypeIsStaticBinSearch<AllMessages>();
402 template <
typename... TParams>
403 static constexpr bool isDispatchLinearSwitchInternal(ForcedTag<TParams...>)
405 return std::is_same<comms::traits::dispatch::LinearSwitch, typename ParsedOptions::ForcedDispatch>::value;
408 template <
typename... TParams>
409 static constexpr bool isDispatchLinearSwitchInternal(StandardTag<TParams...>)
414 template <
typename... TParams>
415 MsgPtr createMsgInternal(MsgIdParamType
id,
unsigned idx,
bool& success, VirtualDestructorTag<TParams...>)
const
417 CreateHandler handler(m_alloc);
418 success = dispatchMsgTypeInternal(
id, idx, handler, DispatchTag<>());
419 return handler.getMsg();
422 template <
typename... TParams>
423 MsgPtr createMsgInternal(MsgIdParamType
id,
unsigned idx,
bool& success, NonVirtualDestructorTag<TParams...>)
const
425 NonVirtualDestructorCreateHandler handler(
id, idx, m_alloc);
426 success = dispatchMsgTypeInternal(
id, idx, handler, DispatchTag<>());
427 return handler.getMsg();
430 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.