21#include "comms/details/tag.h"
32COMMS_MSVC_WARNING_PUSH
33COMMS_MSVC_WARNING_DISABLE(4324)
47template <
typename TInterfaceType,
typename TDefaultType>
48struct DynMemoryDeleteHandler
50 template <
typename TObj>
51 void handle(TObj& obj)
const
54 typename comms::util::LazyShallowConditional<
55 std::is_void<TDefaultType>::value
61 handleInternal(obj, HandleTag());
65 template <
typename... TParams>
66 using NoDefaultCastTag = comms::details::tag::Tag1<>;
68 template <
typename... TParams>
69 using DefaultCastCheckTag = comms::details::tag::Tag2<>;
71 template <
typename... TParams>
72 using ForcedDefaultCastTag = comms::details::tag::Tag3<>;
74 template <
typename TObj,
typename... TParams>
75 void handleInternal(TObj& obj, NoDefaultCastTag<TParams...>)
const
80 template <
typename TObj,
typename... TParams>
81 void handleInternal(TObj& obj, ForcedDefaultCastTag<TParams...>)
const
83 delete static_cast<TDefaultType*
>(&obj);
86 template <
typename TObj,
typename... TParams>
87 void handleInternal(TObj& obj, DefaultCastCheckTag<TParams...>)
const
89 using ObjType =
typename std::decay<
decltype(obj)>::type;
91 typename comms::util::LazyShallowConditional<
92 std::is_same<ObjType, TInterfaceType>::value
97 handleInternal(obj, Tag());
102template <
typename TInterfaceType,
typename TDefaultType>
103struct InPlaceDeleteHandler
105 template <
typename TObj>
106 void handle(TObj& obj)
const
109 typename comms::util::LazyShallowConditional<
110 std::is_void<TDefaultType>::value
116 handleInternal(obj, HandleTag());
120 template <
typename... TParams>
121 using NoDefaultCastTag = comms::details::tag::Tag1<>;
123 template <
typename... TParams>
124 using DefaultCastCheckTag = comms::details::tag::Tag2<>;
126 template <
typename... TParams>
127 using ForcedDefaultCastTag = comms::details::tag::Tag3<>;
129 template <
typename TObj,
typename... TParams>
130 void handleInternal(TObj& obj, NoDefaultCastTag<TParams...>)
const
132 static_cast<void>(obj);
136 template <
typename TObj,
typename... TParams>
137 void handleInternal(TObj& obj, ForcedDefaultCastTag<TParams...>)
const
139 static_cast<TDefaultType&
>(obj).~TDefaultType();
142 template <
typename TObj,
typename... TParams>
143 void handleInternal(TObj& obj, DefaultCastCheckTag<TParams...>)
const
145 using ObjType =
typename std::decay<
decltype(obj)>::type;
147 typename comms::util::LazyShallowConditional<
148 std::is_same<ObjType, TInterfaceType>::value
150 ForcedDefaultCastTag,
153 handleInternal(obj, Tag());
159 typename TAllMessages,
160 typename TDeleteHandler,
162class NoVirtualDestructorDeleter
164 static const unsigned InvalidIdx = std::numeric_limits<unsigned>::max();
166 NoVirtualDestructorDeleter() : m_id(TId()), m_idx(InvalidIdx) {}
167 NoVirtualDestructorDeleter(TId
id,
unsigned idx) : m_id(id), m_idx(idx) {}
169 void operator()(TInterface* obj)
173 TDeleteHandler handler;
174 comms::dispatchMsgStaticBinSearch<TAllMessages>(m_id, m_idx, *obj, handler);
183 typename TAllMessages,
184 typename TDeleteHandler,
186class NoVirtualDestructorInPlaceDeleter :
public
187 NoVirtualDestructorDeleter<TInterface, TAllMessages, TDeleteHandler, TId>
189 using Base = NoVirtualDestructorDeleter<TInterface, TAllMessages, TDeleteHandler, TId>;
190 static const unsigned InvalidIdx = std::numeric_limits<unsigned>::max();
192 NoVirtualDestructorInPlaceDeleter() =
default;
193 NoVirtualDestructorInPlaceDeleter(TId
id,
unsigned idx,
bool& allocated) : Base(id, idx), m_allocated(&allocated) {}
195 NoVirtualDestructorInPlaceDeleter(
const NoVirtualDestructorInPlaceDeleter&) =
delete;
196 NoVirtualDestructorInPlaceDeleter(NoVirtualDestructorInPlaceDeleter&& other) :
197 Base(
std::move(other)),
198 m_allocated(other.m_allocated)
200 other.m_allocated =
nullptr;
203 ~NoVirtualDestructorInPlaceDeleter()
207 NoVirtualDestructorInPlaceDeleter& operator=(
const NoVirtualDestructorInPlaceDeleter&) =
delete;
208 NoVirtualDestructorInPlaceDeleter& operator=(NoVirtualDestructorInPlaceDeleter&& other)
210 if (
reinterpret_cast<void*
>(
this) ==
reinterpret_cast<const void*
>(&other)) {
214 Base::operator=(std::move(other));
215 m_allocated = other.m_allocated;
216 other.m_allocated =
nullptr;
220 void operator()(TInterface* obj)
224 Base::operator()(obj);
225 *m_allocated =
false;
226 m_allocated =
nullptr;
229 bool* m_allocated =
nullptr;
236 friend class InPlaceDeleter;
239 InPlaceDeleter(
bool* allocated =
nullptr)
240 : m_allocated(allocated)
244 InPlaceDeleter(
const InPlaceDeleter& other) =
delete;
246 template <
typename U>
247 InPlaceDeleter(InPlaceDeleter<U>&& other)
248 : m_allocated(other.m_allocated)
250 static_assert(std::is_base_of<T, U>::value ||
251 std::is_base_of<U, T>::value ||
252 std::is_convertible<U, T>::value ||
253 std::is_convertible<T, U>::value ,
254 "To make Deleter convertible, their template parameters "
255 "must be convertible.");
257 other.m_allocated =
nullptr;
260 ~InPlaceDeleter() noexcept
264 InPlaceDeleter& operator=(
const InPlaceDeleter& other) =
delete;
266 template <
typename U>
267 InPlaceDeleter& operator=(InPlaceDeleter<U>&& other)
269 static_assert(std::is_base_of<T, U>::value ||
270 std::is_base_of<U, T>::value ||
271 std::is_convertible<U, T>::value ||
272 std::is_convertible<T, U>::value ,
273 "To make Deleter convertible, their template parameters "
274 "must be convertible.");
276 if (
reinterpret_cast<void*
>(
this) ==
reinterpret_cast<const void*
>(&other)) {
281 m_allocated = other.m_allocated;
282 other.m_allocated =
nullptr;
286 void operator()(T* obj) {
290 *m_allocated =
false;
291 m_allocated =
nullptr;
295 bool* m_allocated =
nullptr;
305template <
typename TInterface>
310 using Ptr = std::unique_ptr<TInterface>;
318 template <
typename TObj,
typename... TArgs>
321 static_assert(std::is_base_of<TInterface, TObj>::value,
322 "TObj does not inherit from TInterface");
323 return Ptr(
new TObj(std::forward<TArgs>(args)...));
331 template <
typename TObj>
334 static_assert(std::is_base_of<TInterface, TObj>::value,
335 "TObj does not inherit from TInterface");
356template <
typename TInterface,
typename TAllMessages,
typename TId,
typename TDefaultType =
void>
360 details::NoVirtualDestructorDeleter<
363 details::DynMemoryDeleteHandler<TInterface, TDefaultType>,
367 using Ptr = std::unique_ptr<TInterface, Deleter>;
378 template <
typename TObj,
typename... TArgs>
379 static Ptr alloc(TId
id,
unsigned idx, TArgs&&... args)
381 static_assert(std::is_base_of<TInterface, TObj>::value,
382 "TObj does not inherit from TInterface");
383 return Ptr(
new TObj(std::forward<TArgs>(args)...), Deleter(
id, idx));
404template <
typename TInterface,
typename TAllTypes>
411 using Ptr = std::unique_ptr<TInterface, details::InPlaceDeleter<TInterface> >;
428 template <
typename TObj,
typename... TArgs>
435 static_assert(std::is_base_of<TInterface, TObj>::value,
436 "TObj does not inherit from TInterface");
439 "TObj must be in provided tuple of supported types");
442 std::has_virtual_destructor<TInterface>::value ||
443 std::is_same<TInterface, TObj>::value,
444 "TInterface is expected to have virtual destructor");
446 static_assert(
sizeof(TObj) <=
sizeof(m_place),
"Object is too big");
448 new (&m_place) TObj(std::forward<TArgs>(args)...);
450 reinterpret_cast<TInterface*
>(&m_place),
451 details::InPlaceDeleter<TInterface>(&m_allocated));
473 template <
typename TObj>
476 if (obj ==
nullptr) {
480 static_assert(std::is_base_of<TInterface, TObj>::value,
481 "TObj does not inherit from TInterface");
482 COMMS_ASSERT(obj ==
reinterpret_cast<TInterface*
>(&m_place));
485 reinterpret_cast<TInterface*
>(&m_place),
486 details::InPlaceDeleter<TInterface>(&m_allocated));
498 alignas(8) AlignedStorage m_place;
499 bool m_allocated =
false;
520 typename TAllocMessages,
521 typename TOrigMessages,
523 typename TDefaultType =
void>
527 details::NoVirtualDestructorInPlaceDeleter<
530 details::InPlaceDeleteHandler<TInterface, TDefaultType>,
537 using Ptr = std::unique_ptr<TInterface, Deleter>;
548 template <
typename TObj,
typename... TArgs>
555 static_assert(std::is_base_of<TInterface, TObj>::value,
556 "TObj does not inherit from TInterface");
559 "TObj must be in provided tuple of supported types");
561 static_assert(
sizeof(TObj) <=
sizeof(m_place),
"Object is too big");
563 new (&m_place) TObj(std::forward<TArgs>(args)...);
565 reinterpret_cast<TInterface*
>(&m_place),
566 Deleter(
id, idx, m_allocated));
592 alignas(8) AlignedStorage m_place;
593 bool m_allocated =
false;
605template <
typename TInterface, std::
size_t TSize,
typename TAllTypes = std::tuple<TInterface> >
609 using Pool = std::array<PoolElem, TSize>;
617 template <
typename TObj,
typename... TArgs>
620 auto iter = std::find_if(
621 m_pool.begin(), m_pool.end(),
624 return !elem.allocated();
627 if (iter == m_pool.end()) {
631 return iter->template alloc<TObj>(std::forward<TArgs>(args)...);
639 template <
typename TObj>
644 m_pool.begin(), m_pool.end(),
647 return elem.allocated() && (elem.allocAddr() == obj);
650 if (iter == m_pool.end()) {
654 return iter->wrap(obj);
664template <
typename...>
665struct InPlaceSingleDeepCondWrap
667 template <
typename TInterface,
typename TAllTypes,
typename...>
671template <
typename...>
672struct InPlaceSingleNoVirtualDestructorDeepCondWrap
676 typename TAllocMessages,
677 typename TOrigMessages,
679 typename TDefaultType,
691template <
typename...>
692struct DynMemoryDeepCondWrap
694 template <
typename TInterface,
typename...>
698template <
typename...>
699struct DynMemoryNoVirtualDestructorDeepCondWrap
703 typename TAllMessages,
705 typename TDefaultType,
725COMMS_MSVC_WARNING_POP
This file contains classes required for generic custom assertion functionality.
#define COMMS_ASSERT(expr)
Generic assert macro.
Definition Assert.h:170
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:358
std::unique_ptr< TInterface, Deleter > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:367
static Ptr alloc(TId id, unsigned idx, TArgs &&... args)
Allocation function.
Definition alloc.h:379
static constexpr bool canAllocate()
Inquiry whether allocation is possible.
Definition alloc.h:388
Dynamic memory allocator.
Definition alloc.h:307
static Ptr wrap(TObj *obj)
Function used to wrap raw pointer into a smart one.
Definition alloc.h:332
std::unique_ptr< TInterface > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:310
static Ptr alloc(TArgs &&... args)
Allocation function.
Definition alloc.h:319
static constexpr bool canAllocate()
Inquiry whether allocation is possible.
Definition alloc.h:341
In-place object pool allocator.
Definition alloc.h:607
Ptr wrap(TObj *obj)
Function used to wrap raw pointer into a smart one.
Definition alloc.h:640
Ptr alloc(TArgs &&... args)
Allocation function.
Definition alloc.h:618
typename PoolElem::Ptr Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:614
In-place single object allocator for message objects without virtual destructor.
Definition alloc.h:525
Ptr alloc(TId id, unsigned idx, TArgs &&... args)
Allocation function.
Definition alloc.h:549
bool canAllocate() const
Inquiry whether allocation is possible.
Definition alloc.h:584
std::unique_ptr< TInterface, Deleter > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:537
const void * allocAddr() const
Get address of the objects being allocated using this allocator.
Definition alloc.h:578
bool allocated() const
Inquire whether the object is already allocated.
Definition alloc.h:572
In-place single object allocator.
Definition alloc.h:406
bool allocated() const
Inquire whether the object is already allocated.
Definition alloc.h:457
~InPlaceSingle()
Destructor.
Definition alloc.h:414
Ptr wrap(TObj *obj)
Function used to wrap raw pointer into a smart one.
Definition alloc.h:474
bool canAllocate() const
Inquiry whether allocation is possible.
Definition alloc.h:490
const void * allocAddr() const
Get address of the objects being allocated using this allocator.
Definition alloc.h:463
std::unique_ptr< TInterface, details::InPlaceDeleter< TInterface > > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:411
Ptr alloc(TArgs &&... args)
Allocation function.
Definition alloc.h:429
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:98
void Type
Type definition is invalid for any type that is not std::tuple, will be specialised to proper value.
Definition Tuple.h:169
Replacement to some types from standard type_traits.