20#include "comms/details/tag.h"
29COMMS_MSVC_WARNING_PUSH
30COMMS_MSVC_WARNING_DISABLE(4324)
44template <
typename TInterfaceType,
typename TDefaultType>
45struct DynMemoryDeleteHandler
47 template <
typename TObj>
48 void handle(TObj& obj)
const
51 typename comms::util::LazyShallowConditional<
52 std::is_void<TDefaultType>::value
58 handleInternal(obj, HandleTag());
62 template <
typename... TParams>
63 using NoDefaultCastTag = comms::details::tag::Tag1<>;
65 template <
typename... TParams>
66 using DefaultCastCheckTag = comms::details::tag::Tag2<>;
68 template <
typename... TParams>
69 using ForcedDefaultCastTag = comms::details::tag::Tag3<>;
71 template <
typename TObj,
typename... TParams>
72 void handleInternal(TObj& obj, NoDefaultCastTag<TParams...>)
const
77 template <
typename TObj,
typename... TParams>
78 void handleInternal(TObj& obj, ForcedDefaultCastTag<TParams...>)
const
80 delete static_cast<TDefaultType*
>(&obj);
83 template <
typename TObj,
typename... TParams>
84 void handleInternal(TObj& obj, DefaultCastCheckTag<TParams...>)
const
86 using ObjType =
typename std::decay<
decltype(obj)>::type;
88 typename comms::util::LazyShallowConditional<
89 std::is_same<ObjType, TInterfaceType>::value
94 handleInternal(obj, Tag());
99template <
typename TInterfaceType,
typename TDefaultType>
100struct InPlaceDeleteHandler
102 template <
typename TObj>
103 void handle(TObj& obj)
const
106 typename comms::util::LazyShallowConditional<
107 std::is_void<TDefaultType>::value
113 handleInternal(obj, HandleTag());
117 template <
typename... TParams>
118 using NoDefaultCastTag = comms::details::tag::Tag1<>;
120 template <
typename... TParams>
121 using DefaultCastCheckTag = comms::details::tag::Tag2<>;
123 template <
typename... TParams>
124 using ForcedDefaultCastTag = comms::details::tag::Tag3<>;
126 template <
typename TObj,
typename... TParams>
127 void handleInternal(TObj& obj, NoDefaultCastTag<TParams...>)
const
129 static_cast<void>(obj);
133 template <
typename TObj,
typename... TParams>
134 void handleInternal(TObj& obj, ForcedDefaultCastTag<TParams...>)
const
136 static_cast<TDefaultType&
>(obj).~TDefaultType();
139 template <
typename TObj,
typename... TParams>
140 void handleInternal(TObj& obj, DefaultCastCheckTag<TParams...>)
const
142 using ObjType =
typename std::decay<
decltype(obj)>::type;
144 typename comms::util::LazyShallowConditional<
145 std::is_same<ObjType, TInterfaceType>::value
147 ForcedDefaultCastTag,
150 handleInternal(obj, Tag());
156 typename TAllMessages,
157 typename TDeleteHandler,
159class NoVirtualDestructorDeleter
161 static const unsigned InvalidIdx = std::numeric_limits<unsigned>::max();
163 NoVirtualDestructorDeleter() : m_id(TId()), m_idx(InvalidIdx) {}
164 NoVirtualDestructorDeleter(TId
id,
unsigned idx) : m_id(id), m_idx(idx) {}
166 void operator()(TInterface* obj)
170 TDeleteHandler handler;
171 comms::dispatchMsgStaticBinSearch<TAllMessages>(m_id, m_idx, *obj, handler);
180 typename TAllMessages,
181 typename TDeleteHandler,
183class NoVirtualDestructorInPlaceDeleter :
public
184 NoVirtualDestructorDeleter<TInterface, TAllMessages, TDeleteHandler, TId>
186 using Base = NoVirtualDestructorDeleter<TInterface, TAllMessages, TDeleteHandler, TId>;
187 static const unsigned InvalidIdx = std::numeric_limits<unsigned>::max();
189 NoVirtualDestructorInPlaceDeleter() =
default;
190 NoVirtualDestructorInPlaceDeleter(TId
id,
unsigned idx,
bool& allocated) : Base(id, idx), m_allocated(&allocated) {}
192 NoVirtualDestructorInPlaceDeleter(
const NoVirtualDestructorInPlaceDeleter&) =
delete;
193 NoVirtualDestructorInPlaceDeleter(NoVirtualDestructorInPlaceDeleter&& other) :
194 Base(
std::move(other)),
195 m_allocated(other.m_allocated)
197 other.m_allocated =
nullptr;
200 ~NoVirtualDestructorInPlaceDeleter()
204 NoVirtualDestructorInPlaceDeleter& operator=(
const NoVirtualDestructorInPlaceDeleter&) =
delete;
205 NoVirtualDestructorInPlaceDeleter& operator=(NoVirtualDestructorInPlaceDeleter&& other)
207 if (
reinterpret_cast<void*
>(
this) ==
reinterpret_cast<const void*
>(&other)) {
211 Base::operator=(std::move(other));
212 m_allocated = other.m_allocated;
213 other.m_allocated =
nullptr;
217 void operator()(TInterface* obj)
221 Base::operator()(obj);
222 *m_allocated =
false;
223 m_allocated =
nullptr;
226 bool* m_allocated =
nullptr;
233 friend class InPlaceDeleter;
236 InPlaceDeleter(
bool* allocated =
nullptr)
237 : m_allocated(allocated)
241 InPlaceDeleter(
const InPlaceDeleter& other) =
delete;
243 template <
typename U>
244 InPlaceDeleter(InPlaceDeleter<U>&& other)
245 : m_allocated(other.m_allocated)
247 static_assert(std::is_base_of<T, U>::value ||
248 std::is_base_of<U, T>::value ||
249 std::is_convertible<U, T>::value ||
250 std::is_convertible<T, U>::value ,
251 "To make Deleter convertible, their template parameters "
252 "must be convertible.");
254 other.m_allocated =
nullptr;
257 ~InPlaceDeleter() noexcept
261 InPlaceDeleter& operator=(
const InPlaceDeleter& other) =
delete;
263 template <
typename U>
264 InPlaceDeleter& operator=(InPlaceDeleter<U>&& other)
266 static_assert(std::is_base_of<T, U>::value ||
267 std::is_base_of<U, T>::value ||
268 std::is_convertible<U, T>::value ||
269 std::is_convertible<T, U>::value ,
270 "To make Deleter convertible, their template parameters "
271 "must be convertible.");
273 if (
reinterpret_cast<void*
>(
this) ==
reinterpret_cast<const void*
>(&other)) {
278 m_allocated = other.m_allocated;
279 other.m_allocated =
nullptr;
283 void operator()(T* obj) {
287 *m_allocated =
false;
288 m_allocated =
nullptr;
292 bool* m_allocated =
nullptr;
303template <
typename TInterface>
308 using Ptr = std::unique_ptr<TInterface>;
316 template <
typename TObj,
typename... TArgs>
319 static_assert(std::is_base_of<TInterface, TObj>::value,
320 "TObj does not inherit from TInterface");
321 return Ptr(
new TObj(std::forward<TArgs>(args)...));
329 template <
typename TObj>
332 static_assert(std::is_base_of<TInterface, TObj>::value,
333 "TObj does not inherit from TInterface");
354template <
typename TInterface,
typename TAllMessages,
typename TId,
typename TDefaultType =
void>
358 details::NoVirtualDestructorDeleter<
361 details::DynMemoryDeleteHandler<TInterface, TDefaultType>,
365 using Ptr = std::unique_ptr<TInterface, Deleter>;
376 template <
typename TObj,
typename... TArgs>
377 static Ptr alloc(TId
id,
unsigned idx, TArgs&&... args)
379 static_assert(std::is_base_of<TInterface, TObj>::value,
380 "TObj does not inherit from TInterface");
381 return Ptr(
new TObj(std::forward<TArgs>(args)...), Deleter(
id, idx));
402template <
typename TInterface,
typename TAllTypes>
409 using Ptr = std::unique_ptr<TInterface, details::InPlaceDeleter<TInterface> >;
426 template <
typename TObj,
typename... TArgs>
433 static_assert(std::is_base_of<TInterface, TObj>::value,
434 "TObj does not inherit from TInterface");
437 "TObj must be in provided tuple of supported types");
440 std::has_virtual_destructor<TInterface>::value ||
441 std::is_same<TInterface, TObj>::value,
442 "TInterface is expected to have virtual destructor");
444 static_assert(
sizeof(TObj) <=
sizeof(m_place),
"Object is too big");
446 new (&m_place) TObj(std::forward<TArgs>(args)...);
448 reinterpret_cast<TInterface*
>(&m_place),
449 details::InPlaceDeleter<TInterface>(&m_allocated));
471 template <
typename TObj>
474 if (obj ==
nullptr) {
478 static_assert(std::is_base_of<TInterface, TObj>::value,
479 "TObj does not inherit from TInterface");
480 COMMS_ASSERT(obj ==
reinterpret_cast<TInterface*
>(&m_place));
483 reinterpret_cast<TInterface*
>(&m_place),
484 details::InPlaceDeleter<TInterface>(&m_allocated));
496 alignas(8) AlignedStorage m_place;
497 bool m_allocated =
false;
518 typename TAllocMessages,
519 typename TOrigMessages,
521 typename TDefaultType =
void>
525 details::NoVirtualDestructorInPlaceDeleter<
528 details::InPlaceDeleteHandler<TInterface, TDefaultType>,
535 using Ptr = std::unique_ptr<TInterface, Deleter>;
546 template <
typename TObj,
typename... TArgs>
553 static_assert(std::is_base_of<TInterface, TObj>::value,
554 "TObj does not inherit from TInterface");
557 "TObj must be in provided tuple of supported types");
559 static_assert(
sizeof(TObj) <=
sizeof(m_place),
"Object is too big");
561 new (&m_place) TObj(std::forward<TArgs>(args)...);
563 reinterpret_cast<TInterface*
>(&m_place),
564 Deleter(
id, idx, m_allocated));
590 alignas(8) AlignedStorage m_place;
591 bool m_allocated =
false;
603template <
typename TInterface, std::
size_t TSize,
typename TAllTypes = std::tuple<TInterface> >
607 using Pool = std::array<PoolElem, TSize>;
615 template <
typename TObj,
typename... TArgs>
618 auto iter = std::find_if(
619 m_pool.begin(), m_pool.end(),
622 return !elem.allocated();
625 if (iter == m_pool.end()) {
629 return iter->template alloc<TObj>(std::forward<TArgs>(args)...);
637 template <
typename TObj>
642 m_pool.begin(), m_pool.end(),
645 return elem.allocated() && (elem.allocAddr() == obj);
648 if (iter == m_pool.end()) {
652 return iter->wrap(obj);
662template <
typename...>
663struct InPlaceSingleDeepCondWrap
665 template <
typename TInterface,
typename TAllTypes,
typename...>
669template <
typename...>
670struct InPlaceSingleNoVirtualDestructorDeepCondWrap
674 typename TAllocMessages,
675 typename TOrigMessages,
677 typename TDefaultType,
689template <
typename...>
690struct DynMemoryDeepCondWrap
692 template <
typename TInterface,
typename...>
696template <
typename...>
697struct DynMemoryNoVirtualDestructorDeepCondWrap
701 typename TAllMessages,
703 typename TDefaultType,
724COMMS_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:356
std::unique_ptr< TInterface, Deleter > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:365
static Ptr alloc(TId id, unsigned idx, TArgs &&... args)
Allocation function.
Definition alloc.h:377
static constexpr bool canAllocate()
Inquiry whether allocation is possible.
Definition alloc.h:386
Dynamic memory allocator.
Definition alloc.h:305
static Ptr wrap(TObj *obj)
Function used to wrap raw pointer into a smart one.
Definition alloc.h:330
std::unique_ptr< TInterface > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:308
static Ptr alloc(TArgs &&... args)
Allocation function.
Definition alloc.h:317
static constexpr bool canAllocate()
Inquiry whether allocation is possible.
Definition alloc.h:339
In-place object pool allocator.
Definition alloc.h:605
Ptr wrap(TObj *obj)
Function used to wrap raw pointer into a smart one.
Definition alloc.h:638
Ptr alloc(TArgs &&... args)
Allocation function.
Definition alloc.h:616
typename PoolElem::Ptr Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:612
In-place single object allocator for message objects without virtual destructor.
Definition alloc.h:523
Ptr alloc(TId id, unsigned idx, TArgs &&... args)
Allocation function.
Definition alloc.h:547
bool canAllocate() const
Inquiry whether allocation is possible.
Definition alloc.h:582
std::unique_ptr< TInterface, Deleter > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:535
const void * allocAddr() const
Get address of the objects being allocated using this allocator.
Definition alloc.h:576
bool allocated() const
Inquire whether the object is already allocated.
Definition alloc.h:570
In-place single object allocator.
Definition alloc.h:404
bool allocated() const
Inquire whether the object is already allocated.
Definition alloc.h:455
~InPlaceSingle()
Destructor.
Definition alloc.h:412
Ptr wrap(TObj *obj)
Function used to wrap raw pointer into a smart one.
Definition alloc.h:472
bool canAllocate() const
Inquiry whether allocation is possible.
Definition alloc.h:488
const void * allocAddr() const
Get address of the objects being allocated using this allocator.
Definition alloc.h:461
std::unique_ptr< TInterface, details::InPlaceDeleter< TInterface > > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:409
Ptr alloc(TArgs &&... args)
Allocation function.
Definition alloc.h:427
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.