19#include "comms/details/tag.h"
28COMMS_MSVC_WARNING_PUSH
29COMMS_MSVC_WARNING_DISABLE(4324)
43template <
typename TInterfaceType,
typename TDefaultType>
44struct DynMemoryDeleteHandler
46 template <
typename TObj>
47 void handle(TObj& obj)
const
50 typename comms::util::LazyShallowConditional<
51 std::is_void<TDefaultType>::value
57 handleInternal(obj, HandleTag());
61 template <
typename... TParams>
62 using NoDefaultCastTag = comms::details::tag::Tag1<>;
64 template <
typename... TParams>
65 using DefaultCastCheckTag = comms::details::tag::Tag2<>;
67 template <
typename... TParams>
68 using ForcedDefaultCastTag = comms::details::tag::Tag3<>;
70 template <
typename TObj,
typename... TParams>
71 void handleInternal(TObj& obj, NoDefaultCastTag<TParams...>)
const
76 template <
typename TObj,
typename... TParams>
77 void handleInternal(TObj& obj, ForcedDefaultCastTag<TParams...>)
const
79 delete static_cast<TDefaultType*
>(&obj);
82 template <
typename TObj,
typename... TParams>
83 void handleInternal(TObj& obj, DefaultCastCheckTag<TParams...>)
const
85 using ObjType =
typename std::decay<
decltype(obj)>::type;
87 typename comms::util::LazyShallowConditional<
88 std::is_same<ObjType, TInterfaceType>::value
93 handleInternal(obj, Tag());
98template <
typename TInterfaceType,
typename TDefaultType>
99struct InPlaceDeleteHandler
101 template <
typename TObj>
102 void handle(TObj& obj)
const
105 typename comms::util::LazyShallowConditional<
106 std::is_void<TDefaultType>::value
112 handleInternal(obj, HandleTag());
116 template <
typename... TParams>
117 using NoDefaultCastTag = comms::details::tag::Tag1<>;
119 template <
typename... TParams>
120 using DefaultCastCheckTag = comms::details::tag::Tag2<>;
122 template <
typename... TParams>
123 using ForcedDefaultCastTag = comms::details::tag::Tag3<>;
125 template <
typename TObj,
typename... TParams>
126 void handleInternal(TObj& obj, NoDefaultCastTag<TParams...>)
const
128 static_cast<void>(obj);
132 template <
typename TObj,
typename... TParams>
133 void handleInternal(TObj& obj, ForcedDefaultCastTag<TParams...>)
const
135 static_cast<TDefaultType&
>(obj).~TDefaultType();
138 template <
typename TObj,
typename... TParams>
139 void handleInternal(TObj& obj, DefaultCastCheckTag<TParams...>)
const
141 using ObjType =
typename std::decay<
decltype(obj)>::type;
143 typename comms::util::LazyShallowConditional<
144 std::is_same<ObjType, TInterfaceType>::value
146 ForcedDefaultCastTag,
149 handleInternal(obj, Tag());
155 typename TAllMessages,
156 typename TDeleteHandler,
158class NoVirtualDestructorDeleter
160 static const unsigned InvalidIdx = std::numeric_limits<unsigned>::max();
162 NoVirtualDestructorDeleter() : m_id(TId()), m_idx(InvalidIdx) {}
163 NoVirtualDestructorDeleter(TId
id,
unsigned idx) : m_id(id), m_idx(idx) {}
165 void operator()(TInterface* obj)
169 TDeleteHandler handler;
170 comms::dispatchMsgStaticBinSearch<TAllMessages>(m_id, m_idx, *obj, handler);
179 typename TAllMessages,
180 typename TDeleteHandler,
182class NoVirtualDestructorInPlaceDeleter :
public
183 NoVirtualDestructorDeleter<TInterface, TAllMessages, TDeleteHandler, TId>
185 using Base = NoVirtualDestructorDeleter<TInterface, TAllMessages, TDeleteHandler, TId>;
186 static const unsigned InvalidIdx = std::numeric_limits<unsigned>::max();
188 NoVirtualDestructorInPlaceDeleter() =
default;
189 NoVirtualDestructorInPlaceDeleter(TId
id,
unsigned idx,
bool& allocated) : Base(id, idx), m_allocated(&allocated) {}
191 NoVirtualDestructorInPlaceDeleter(
const NoVirtualDestructorInPlaceDeleter&) =
delete;
192 NoVirtualDestructorInPlaceDeleter(NoVirtualDestructorInPlaceDeleter&& other) :
193 Base(
std::move(other)),
194 m_allocated(other.m_allocated)
196 other.m_allocated =
nullptr;
199 ~NoVirtualDestructorInPlaceDeleter()
203 NoVirtualDestructorInPlaceDeleter& operator=(
const NoVirtualDestructorInPlaceDeleter&) =
delete;
204 NoVirtualDestructorInPlaceDeleter& operator=(NoVirtualDestructorInPlaceDeleter&& other)
206 if (
reinterpret_cast<void*
>(
this) ==
reinterpret_cast<const void*
>(&other)) {
210 Base::operator=(std::move(other));
211 m_allocated = other.m_allocated;
212 other.m_allocated =
nullptr;
216 void operator()(TInterface* obj)
220 Base::operator()(obj);
221 *m_allocated =
false;
222 m_allocated =
nullptr;
225 bool* m_allocated =
nullptr;
232 friend class InPlaceDeleter;
235 InPlaceDeleter(
bool* allocated =
nullptr)
236 : m_allocated(allocated)
240 InPlaceDeleter(
const InPlaceDeleter& other) =
delete;
242 template <
typename U>
243 InPlaceDeleter(InPlaceDeleter<U>&& other)
244 : m_allocated(other.m_allocated)
246 static_assert(std::is_base_of<T, U>::value ||
247 std::is_base_of<U, T>::value ||
248 std::is_convertible<U, T>::value ||
249 std::is_convertible<T, U>::value ,
250 "To make Deleter convertible, their template parameters "
251 "must be convertible.");
253 other.m_allocated =
nullptr;
256 ~InPlaceDeleter() noexcept
260 InPlaceDeleter& operator=(
const InPlaceDeleter& other) =
delete;
262 template <
typename U>
263 InPlaceDeleter& operator=(InPlaceDeleter<U>&& other)
265 static_assert(std::is_base_of<T, U>::value ||
266 std::is_base_of<U, T>::value ||
267 std::is_convertible<U, T>::value ||
268 std::is_convertible<T, U>::value ,
269 "To make Deleter convertible, their template parameters "
270 "must be convertible.");
272 if (
reinterpret_cast<void*
>(
this) ==
reinterpret_cast<const void*
>(&other)) {
277 m_allocated = other.m_allocated;
278 other.m_allocated =
nullptr;
282 void operator()(T* obj) {
286 *m_allocated =
false;
287 m_allocated =
nullptr;
291 bool* m_allocated =
nullptr;
301template <
typename TInterface>
306 using Ptr = std::unique_ptr<TInterface>;
314 template <
typename TObj,
typename... TArgs>
317 static_assert(std::is_base_of<TInterface, TObj>::value,
318 "TObj does not inherit from TInterface");
319 return Ptr(
new TObj(std::forward<TArgs>(args)...));
327 template <
typename TObj>
330 static_assert(std::is_base_of<TInterface, TObj>::value,
331 "TObj does not inherit from TInterface");
352template <
typename TInterface,
typename TAllMessages,
typename TId,
typename TDefaultType =
void>
356 details::NoVirtualDestructorDeleter<
359 details::DynMemoryDeleteHandler<TInterface, TDefaultType>,
363 using Ptr = std::unique_ptr<TInterface, Deleter>;
374 template <
typename TObj,
typename... TArgs>
375 static Ptr alloc(TId
id,
unsigned idx, TArgs&&... args)
377 static_assert(std::is_base_of<TInterface, TObj>::value,
378 "TObj does not inherit from TInterface");
379 return Ptr(
new TObj(std::forward<TArgs>(args)...), Deleter(
id, idx));
400template <
typename TInterface,
typename TAllTypes>
407 using Ptr = std::unique_ptr<TInterface, details::InPlaceDeleter<TInterface> >;
424 template <
typename TObj,
typename... TArgs>
431 static_assert(std::is_base_of<TInterface, TObj>::value,
432 "TObj does not inherit from TInterface");
435 "TObj must be in provided tuple of supported types");
438 std::has_virtual_destructor<TInterface>::value ||
439 std::is_same<TInterface, TObj>::value,
440 "TInterface is expected to have virtual destructor");
442 static_assert(
sizeof(TObj) <=
sizeof(m_place),
"Object is too big");
444 new (&m_place) TObj(std::forward<TArgs>(args)...);
446 reinterpret_cast<TInterface*
>(&m_place),
447 details::InPlaceDeleter<TInterface>(&m_allocated));
469 template <
typename TObj>
472 if (obj ==
nullptr) {
476 static_assert(std::is_base_of<TInterface, TObj>::value,
477 "TObj does not inherit from TInterface");
478 COMMS_ASSERT(obj ==
reinterpret_cast<TInterface*
>(&m_place));
481 reinterpret_cast<TInterface*
>(&m_place),
482 details::InPlaceDeleter<TInterface>(&m_allocated));
494 alignas(8) AlignedStorage m_place;
495 bool m_allocated =
false;
516 typename TAllocMessages,
517 typename TOrigMessages,
519 typename TDefaultType =
void>
523 details::NoVirtualDestructorInPlaceDeleter<
526 details::InPlaceDeleteHandler<TInterface, TDefaultType>,
533 using Ptr = std::unique_ptr<TInterface, Deleter>;
544 template <
typename TObj,
typename... TArgs>
551 static_assert(std::is_base_of<TInterface, TObj>::value,
552 "TObj does not inherit from TInterface");
555 "TObj must be in provided tuple of supported types");
557 static_assert(
sizeof(TObj) <=
sizeof(m_place),
"Object is too big");
559 new (&m_place) TObj(std::forward<TArgs>(args)...);
561 reinterpret_cast<TInterface*
>(&m_place),
562 Deleter(
id, idx, m_allocated));
588 alignas(8) AlignedStorage m_place;
589 bool m_allocated =
false;
601template <
typename TInterface, std::
size_t TSize,
typename TAllTypes = std::tuple<TInterface> >
605 using Pool = std::array<PoolElem, TSize>;
613 template <
typename TObj,
typename... TArgs>
616 auto iter = std::find_if(
617 m_pool.begin(), m_pool.end(),
620 return !elem.allocated();
623 if (iter == m_pool.end()) {
627 return iter->template alloc<TObj>(std::forward<TArgs>(args)...);
635 template <
typename TObj>
640 m_pool.begin(), m_pool.end(),
643 return elem.allocated() && (elem.allocAddr() == obj);
646 if (iter == m_pool.end()) {
650 return iter->wrap(obj);
660template <
typename...>
661struct InPlaceSingleDeepCondWrap
663 template <
typename TInterface,
typename TAllTypes,
typename...>
667template <
typename...>
668struct InPlaceSingleNoVirtualDestructorDeepCondWrap
672 typename TAllocMessages,
673 typename TOrigMessages,
675 typename TDefaultType,
687template <
typename...>
688struct DynMemoryDeepCondWrap
690 template <
typename TInterface,
typename...>
694template <
typename...>
695struct DynMemoryNoVirtualDestructorDeepCondWrap
699 typename TAllMessages,
701 typename TDefaultType,
721COMMS_MSVC_WARNING_POP
This file contains classes required for generic custom assertion functionality.
#define COMMS_ASSERT(expr)
Generic assert macro.
Definition Assert.h:168
Contains various compiler related definitions.
Contains various tuple type manipulation classes and functions.
Dynamic memory allocator for message types without virtual destructor.
Definition alloc.h:354
std::unique_ptr< TInterface, Deleter > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:363
static Ptr alloc(TId id, unsigned idx, TArgs &&... args)
Allocation function.
Definition alloc.h:375
static constexpr bool canAllocate()
Inquiry whether allocation is possible.
Definition alloc.h:384
Dynamic memory allocator.
Definition alloc.h:303
static Ptr wrap(TObj *obj)
Function used to wrap raw pointer into a smart one.
Definition alloc.h:328
std::unique_ptr< TInterface > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:306
static Ptr alloc(TArgs &&... args)
Allocation function.
Definition alloc.h:315
static constexpr bool canAllocate()
Inquiry whether allocation is possible.
Definition alloc.h:337
In-place object pool allocator.
Definition alloc.h:603
Ptr wrap(TObj *obj)
Function used to wrap raw pointer into a smart one.
Definition alloc.h:636
Ptr alloc(TArgs &&... args)
Allocation function.
Definition alloc.h:614
typename PoolElem::Ptr Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:610
In-place single object allocator for message objects without virtual destructor.
Definition alloc.h:521
Ptr alloc(TId id, unsigned idx, TArgs &&... args)
Allocation function.
Definition alloc.h:545
bool canAllocate() const
Inquiry whether allocation is possible.
Definition alloc.h:580
std::unique_ptr< TInterface, Deleter > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:533
const void * allocAddr() const
Get address of the objects being allocated using this allocator.
Definition alloc.h:574
bool allocated() const
Inquire whether the object is already allocated.
Definition alloc.h:568
In-place single object allocator.
Definition alloc.h:402
bool allocated() const
Inquire whether the object is already allocated.
Definition alloc.h:453
~InPlaceSingle()
Destructor.
Definition alloc.h:410
Ptr wrap(TObj *obj)
Function used to wrap raw pointer into a smart one.
Definition alloc.h:470
bool canAllocate() const
Inquiry whether allocation is possible.
Definition alloc.h:486
const void * allocAddr() const
Get address of the objects being allocated using this allocator.
Definition alloc.h:459
std::unique_ptr< TInterface, details::InPlaceDeleter< TInterface > > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:407
Ptr alloc(TArgs &&... args)
Allocation function.
Definition alloc.h:425
Contains extra logic to help with dispatching message types and objects.
Main namespace for all classes / functions of COMMS library.
Check whether TType type is included in the tuple TTuple.
Definition Tuple.h:95
void Type
Type definition is invalid for any type that is not std::tuple, will be specialised to proper value.
Definition Tuple.h:166
Replacement to some types from standard type_traits.