22#include "comms/details/tag.h"
30template <
typename TAllMessages>
31constexpr bool msgFactoryAllHaveStaticNumId()
33 return allMessagesHaveStaticNumId<TAllMessages>();
36template <
typename TMessage>
37constexpr bool msgFactoryMessageHasStaticNumId()
39 return messageHasStaticNumId<TMessage>();
42template <
typename TMsgBase,
typename TAllMessages,
typename... TOptions>
45 static_assert(TMsgBase::hasMsgIdType(),
46 "Usage of MsgFactoryBase requires Message interface to provide ID type. "
47 "Use comms::option::def::MsgIdType option in message interface type definition.");
48 using ParsedOptionsInternal = details::MsgFactoryOptionsParser<TOptions...>;
50 static const bool InterfaceHasVirtualDestructor =
51 std::has_virtual_destructor<TMsgBase>::value;
53 using AllMessagesInternal =
54 typename ParsedOptionsInternal::template AllMessages<TAllMessages>;
55 using GenericMessageInternal =
typename ParsedOptionsInternal::GenericMessage;
57 template <
typename...>
58 struct InPlaceAllocDeepCondWrap
62 typename TAllocMessages,
63 typename TOrigMessages,
65 typename TDefaultType,
68 typename comms::util::LazyDeepConditional<
69 InterfaceHasVirtualDestructor
71 comms::util::alloc::details::InPlaceSingleDeepCondWrap,
72 comms::util::alloc::details::InPlaceSingleNoVirtualDestructorDeepCondWrap,
81 template <
typename...>
82 struct DynMemoryAllocDeepCondWrap
86 typename TAllocMessages,
87 typename TOrigMessages,
89 typename TDefaultType,
92 typename comms::util::LazyDeepConditional<
93 InterfaceHasVirtualDestructor
95 comms::util::alloc::details::DynMemoryDeepCondWrap,
96 comms::util::alloc::details::DynMemoryNoVirtualDestructorDeepCondWrap,
105 typename comms::util::LazyDeepConditional<
106 ParsedOptionsInternal::HasInPlaceAllocation
108 InPlaceAllocDeepCondWrap,
109 DynMemoryAllocDeepCondWrap,
113 typename TMsgBase::MsgIdType,
114 GenericMessageInternal
117 using ParsedOptions = ParsedOptionsInternal;
118 using Message = TMsgBase;
121 using MsgPtr =
typename Alloc::Ptr;
122 using AllMessages = TAllMessages;
126 MsgPtr createMsg(MsgIdParamType
id,
unsigned idx, CreateFailureReason* reason)
const
128 CreateFailureReason reasonTmp = CreateFailureReason::None;
130 MsgPtr msg = createMsgInternal(
id, idx, result, DestructorTag<>());
138 reasonTmp = CreateFailureReason::InvalidId;
142 reasonTmp = CreateFailureReason::AllocFailure;
145 if (reason !=
nullptr) {
152 MsgPtr createGenericMsg(MsgIdParamType
id,
unsigned idx)
const
154 static_cast<void>(
this);
156 typename comms::util::LazyShallowConditional<
157 ParsedOptions::HasSupportGenericMessage
163 return createGenericMsgInternal(
id, idx, Tag(), DestructorTag<>());
166 bool canAllocate()
const
168 return alloc_.canAllocate();
171 std::size_t msgCount(MsgIdParamType
id)
const
173 return comms::dispatchMsgTypeCountStaticBinSearch<AllMessages>(
id);
176 static constexpr bool hasUniqueIds()
178 return comms::details::allMessagesAreStrongSorted<AllMessages>();
181 static constexpr bool isDispatchPolymorphic()
183 return isDispatchPolymorphicInternal(DispatchTag<>());
186 static constexpr bool isDispatchStaticBinSearch()
188 return isDispatchStaticBinSearchInternal(DispatchTag<>());
191 static constexpr bool isDispatchLinearSwitch()
193 return isDispatchLinearSwitchInternal(DispatchTag<>());
197 MsgFactoryBase() =
default;
198 MsgFactoryBase(
const MsgFactoryBase&) =
default;
199 MsgFactoryBase(MsgFactoryBase&&) =
default;
200 MsgFactoryBase& operator=(
const MsgFactoryBase&) =
default;
201 MsgFactoryBase& operator=(MsgFactoryBase&&) =
default;
203 template <
typename TObj,
typename... TArgs>
204 MsgPtr allocMsg(TArgs&&... args)
const
206 static_assert(std::is_base_of<Message, TObj>::value,
207 "TObj is not a proper message type");
209 static_assert(std::has_virtual_destructor<TObj>::value,
210 "This function is expected to be called for message objects with virtual destructor");
212 (!ParsedOptionsInternal::HasInPlaceAllocation) ||
214 "TObj must be in provided tuple of supported messages");
216 return alloc_.template alloc<TObj>(std::forward<TArgs>(args)...);
219 template <
typename TObj,
typename... TArgs>
220 MsgPtr allocMsg(MsgIdParamType
id,
unsigned idx, TArgs&&... args)
const
222 static_assert(std::is_base_of<Message, TObj>::value,
223 "TObj is not a proper message type");
225 static_assert(!std::has_virtual_destructor<TObj>::value,
226 "This function is expected to be called for message objects without virtual destructor");
229 (!ParsedOptionsInternal::HasInPlaceAllocation) ||
231 "TObj must be in provided tuple of supported messages");
233 return alloc_.template alloc<TObj>(
id, idx, std::forward<TArgs>(args)...);
237 template <
typename... TParams>
238 using AllocGenericTag = comms::details::tag::Tag1<>;
240 template <
typename... TParams>
241 using NoAllocTag = comms::details::tag::Tag2<>;
243 template <
typename... TParams>
244 using ForcedTag = comms::details::tag::Tag3<>;
246 template <
typename... TParams>
247 using StandardTag = comms::details::tag::Tag4<>;
249 template <
typename... TParams>
250 using VirtualDestructorTag = comms::details::tag::Tag5<>;
252 template <
typename... TParams>
253 using NonVirtualDestructorTag = comms::details::tag::Tag6<>;
255 template <
typename...>
257 typename comms::util::LazyShallowConditional<
258 ParsedOptions::HasForcedDispatch
264 template <
typename...>
265 using DestructorTag =
266 typename comms::util::LazyShallowConditional<
267 InterfaceHasVirtualDestructor
269 VirtualDestructorTag,
270 NonVirtualDestructorTag
276 explicit CreateHandler(Alloc& a) : a_(a) {}
280 return std::move(msg_);
283 template <
typename T>
286 msg_ = a_.template alloc<T>();
294 class NonVirtualDestructorCreateHandler
297 explicit NonVirtualDestructorCreateHandler(MsgIdParamType
id,
unsigned idx, Alloc& a) :
306 return std::move(msg_);
309 template <
typename T>
312 msg_ = a_.template alloc<T>(id_, idx_);
322 template <
typename... TParams>
323 MsgPtr createGenericMsgInternal(MsgIdParamType
id,
unsigned idx, AllocGenericTag<TParams...>, VirtualDestructorTag<TParams...>)
const
325 static_cast<void>(idx);
326 static_assert(std::is_base_of<Message, typename ParsedOptions::GenericMessage>::value,
327 "The requested GenericMessage class must have the same interface class as all other messages");
328 return allocMsg<typename ParsedOptions::GenericMessage>(
id);
331 template <
typename... TParams>
332 MsgPtr createGenericMsgInternal(MsgIdParamType
id,
unsigned idx, AllocGenericTag<TParams...>, NonVirtualDestructorTag<TParams...>)
const
334 static_assert(std::is_base_of<Message, typename ParsedOptions::GenericMessage>::value,
335 "The requested GenericMessage class must have the same interface class as all other messages");
336 return allocMsg<typename ParsedOptions::GenericMessage>(
id, idx,
id);
339 template <
typename TDestructorTag,
typename... TParams>
340 static MsgPtr createGenericMsgInternal(MsgIdParamType, NoAllocTag<TParams...>, TDestructorTag)
345 template <
typename THandler,
typename... TParams>
346 static bool dispatchMsgTypeInternal(MsgIdParamType
id,
unsigned idx, THandler& handler, StandardTag<TParams...>)
348 return comms::dispatchMsgType<AllMessages>(
id, idx, handler);
351 template <
typename THandler,
typename... TParams>
352 static bool dispatchMsgTypeInternal(MsgIdParamType
id,
unsigned idx, THandler& handler, ForcedTag<TParams...>)
354 using Tag =
typename ParsedOptions::ForcedDispatch;
355 return dispatchMsgTypeInternal(
id, idx, handler, Tag());
358 template <
typename THandler>
361 return comms::dispatchMsgTypePolymorphic<AllMessages>(
id, idx, handler);
364 template <
typename THandler>
367 return comms::dispatchMsgTypeStaticBinSearch<AllMessages>(
id, idx, handler);
370 template <
typename THandler>
373 return comms::dispatchMsgTypeStaticBinSearch<AllMessages>(
id, idx, handler);
376 template <
typename... TParams>
377 static constexpr bool isDispatchPolymorphicInternal(ForcedTag<TParams...>)
379 return std::is_same<comms::traits::dispatch::Polymorphic, typename ParsedOptions::ForcedDispatch>::value;
382 template <
typename... TParams>
383 static constexpr bool isDispatchPolymorphicInternal(StandardTag<TParams...>)
385 return dispatchMsgTypeIsPolymorphic<AllMessages>();
388 template <
typename... TParams>
389 static constexpr bool isDispatchStaticBinSearchInternal(ForcedTag<TParams...>)
391 return std::is_same<comms::traits::dispatch::StaticBinSearch, typename ParsedOptions::ForcedDispatch>::value;
394 template <
typename... TParams>
395 static constexpr bool isDispatchStaticBinSearchInternal(StandardTag<TParams...>)
397 return dispatchMsgTypeIsStaticBinSearch<AllMessages>();
400 template <
typename... TParams>
401 static constexpr bool isDispatchLinearSwitchInternal(ForcedTag<TParams...>)
403 return std::is_same<comms::traits::dispatch::LinearSwitch, typename ParsedOptions::ForcedDispatch>::value;
406 template <
typename... TParams>
407 static constexpr bool isDispatchLinearSwitchInternal(StandardTag<TParams...>)
412 template <
typename... TParams>
413 MsgPtr createMsgInternal(MsgIdParamType
id,
unsigned idx,
bool& success, VirtualDestructorTag<TParams...>)
const
415 CreateHandler handler(alloc_);
416 success = dispatchMsgTypeInternal(
id, idx, handler, DispatchTag<>());
417 return handler.getMsg();
420 template <
typename... TParams>
421 MsgPtr createMsgInternal(MsgIdParamType
id,
unsigned idx,
bool& success, NonVirtualDestructorTag<TParams...>)
const
423 NonVirtualDestructorCreateHandler handler(
id, idx, alloc_);
424 success = dispatchMsgTypeInternal(
id, idx, handler, DispatchTag<>());
425 return handler.getMsg();
428 mutable Alloc 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 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:1448
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:207
Tag class used to indicate polymorphic dispatch.
Definition traits.h:201
Tag class used to indicate static binary search dispatch.
Definition traits.h:204
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.