26#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() : id_(TId()), idx_(InvalidIdx) {}
163 NoVirtualDestructorDeleter(TId
id,
unsigned idx) : id_(id), idx_(idx) {}
165 void operator()(TInterface* obj)
169 TDeleteHandler handler;
170 comms::dispatchMsgStaticBinSearch<TAllMessages>(id_, 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), allocated_(&allocated) {}
191 NoVirtualDestructorInPlaceDeleter(
const NoVirtualDestructorInPlaceDeleter&) =
delete;
192 NoVirtualDestructorInPlaceDeleter(NoVirtualDestructorInPlaceDeleter&& other) :
193 Base(
std::move(other)),
194 allocated_(other.allocated_)
196 other.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 allocated_ = other.allocated_;
212 other.allocated_ =
nullptr;
216 void operator()(TInterface* obj)
220 Base::operator()(obj);
222 allocated_ =
nullptr;
225 bool* allocated_ =
nullptr;
232 friend class InPlaceDeleter;
235 InPlaceDeleter(
bool* allocated =
nullptr)
236 : allocated_(allocated)
240 InPlaceDeleter(
const InPlaceDeleter& other) =
delete;
242 template <
typename U>
243 InPlaceDeleter(InPlaceDeleter<U>&& other)
244 : allocated_(other.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.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 allocated_ = other.allocated_;
278 other.allocated_ =
nullptr;
282 void operator()(T* obj) {
287 allocated_ =
nullptr;
291 bool* allocated_ =
nullptr;
302template <
typename TInterface>
307 using Ptr = std::unique_ptr<TInterface>;
315 template <
typename TObj,
typename... TArgs>
318 static_assert(std::is_base_of<TInterface, TObj>::value,
319 "TObj does not inherit from TInterface");
320 return Ptr(
new TObj(std::forward<TArgs>(args)...));
328 template <
typename TObj>
331 static_assert(std::is_base_of<TInterface, TObj>::value,
332 "TObj does not inherit from TInterface");
353template <
typename TInterface,
typename TAllMessages,
typename TId,
typename TDefaultType =
void>
357 details::NoVirtualDestructorDeleter<
360 details::DynMemoryDeleteHandler<TInterface, TDefaultType>,
364 using Ptr = std::unique_ptr<TInterface, Deleter>;
375 template <
typename TObj,
typename... TArgs>
376 static Ptr alloc(TId
id,
unsigned idx, TArgs&&... args)
378 static_assert(std::is_base_of<TInterface, TObj>::value,
379 "TObj does not inherit from TInterface");
380 return Ptr(
new TObj(std::forward<TArgs>(args)...), Deleter(
id, idx));
401template <
typename TInterface,
typename TAllTypes>
408 using Ptr = std::unique_ptr<TInterface, details::InPlaceDeleter<TInterface> >;
425 template <
typename TObj,
typename... TArgs>
432 static_assert(std::is_base_of<TInterface, TObj>::value,
433 "TObj does not inherit from TInterface");
436 "TObj must be in provided tuple of supported types");
439 std::has_virtual_destructor<TInterface>::value ||
440 std::is_same<TInterface, TObj>::value,
441 "TInterface is expected to have virtual destructor");
443 static_assert(
sizeof(TObj) <=
sizeof(place_),
"Object is too big");
445 new (&place_) TObj(std::forward<TArgs>(args)...);
447 reinterpret_cast<TInterface*
>(&place_),
448 details::InPlaceDeleter<TInterface>(&allocated_));
470 template <
typename TObj>
473 if (obj ==
nullptr) {
477 static_assert(std::is_base_of<TInterface, TObj>::value,
478 "TObj does not inherit from TInterface");
479 COMMS_ASSERT(obj ==
reinterpret_cast<TInterface*
>(&place_));
482 reinterpret_cast<TInterface*
>(&place_),
483 details::InPlaceDeleter<TInterface>(&allocated_));
495 alignas(8) AlignedStorage place_;
496 bool allocated_ =
false;
517 typename TAllocMessages,
518 typename TOrigMessages,
520 typename TDefaultType =
void>
524 details::NoVirtualDestructorInPlaceDeleter<
527 details::InPlaceDeleteHandler<TInterface, TDefaultType>,
534 using Ptr = std::unique_ptr<TInterface, Deleter>;
545 template <
typename TObj,
typename... TArgs>
552 static_assert(std::is_base_of<TInterface, TObj>::value,
553 "TObj does not inherit from TInterface");
556 "TObj must be in provided tuple of supported types");
558 static_assert(
sizeof(TObj) <=
sizeof(place_),
"Object is too big");
560 new (&place_) TObj(std::forward<TArgs>(args)...);
562 reinterpret_cast<TInterface*
>(&place_),
563 Deleter(
id, idx, allocated_));
589 alignas(8) AlignedStorage place_;
590 bool allocated_ =
false;
602template <
typename TInterface, std::
size_t TSize,
typename TAllTypes = std::tuple<TInterface> >
606 using Pool = std::array<PoolElem, TSize>;
614 template <
typename TObj,
typename... TArgs>
617 auto iter = std::find_if(
618 pool_.begin(), pool_.end(),
621 return !elem.allocated();
624 if (iter == pool_.end()) {
628 return iter->template alloc<TObj>(std::forward<TArgs>(args)...);
636 template <
typename TObj>
641 pool_.begin(), pool_.end(),
644 return elem.allocated() && (elem.allocAddr() == obj);
647 if (iter == pool_.end()) {
651 return iter->wrap(obj);
661template <
typename...>
662struct InPlaceSingleDeepCondWrap
664 template <
typename TInterface,
typename TAllTypes,
typename...>
668template <
typename...>
669struct InPlaceSingleNoVirtualDestructorDeepCondWrap
673 typename TAllocMessages,
674 typename TOrigMessages,
676 typename TDefaultType,
688template <
typename...>
689struct DynMemoryDeepCondWrap
691 template <
typename TInterface,
typename...>
695template <
typename...>
696struct DynMemoryNoVirtualDestructorDeepCondWrap
700 typename TAllMessages,
702 typename TDefaultType,
723COMMS_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:355
std::unique_ptr< TInterface, Deleter > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:364
static Ptr alloc(TId id, unsigned idx, TArgs &&... args)
Allocation function.
Definition alloc.h:376
static constexpr bool canAllocate()
Inquiry whether allocation is possible.
Definition alloc.h:385
Dynamic memory allocator.
Definition alloc.h:304
static Ptr wrap(TObj *obj)
Function used to wrap raw pointer into a smart one.
Definition alloc.h:329
std::unique_ptr< TInterface > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:307
static Ptr alloc(TArgs &&... args)
Allocation function.
Definition alloc.h:316
static constexpr bool canAllocate()
Inquiry whether allocation is possible.
Definition alloc.h:338
In-place object pool allocator.
Definition alloc.h:604
Ptr wrap(TObj *obj)
Function used to wrap raw pointer into a smart one.
Definition alloc.h:637
Ptr alloc(TArgs &&... args)
Allocation function.
Definition alloc.h:615
typename PoolElem::Ptr Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:611
In-place single object allocator for message objects without virtual destructor.
Definition alloc.h:522
Ptr alloc(TId id, unsigned idx, TArgs &&... args)
Allocation function.
Definition alloc.h:546
bool canAllocate() const
Inquiry whether allocation is possible.
Definition alloc.h:581
std::unique_ptr< TInterface, Deleter > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:534
const void * allocAddr() const
Get address of the objects being allocated using this allocator.
Definition alloc.h:575
bool allocated() const
Inquire whether the object is already allocated.
Definition alloc.h:569
In-place single object allocator.
Definition alloc.h:403
bool allocated() const
Inquire whether the object is already allocated.
Definition alloc.h:454
~InPlaceSingle()
Destructor.
Definition alloc.h:411
Ptr wrap(TObj *obj)
Function used to wrap raw pointer into a smart one.
Definition alloc.h:471
bool canAllocate() const
Inquiry whether allocation is possible.
Definition alloc.h:487
const void * allocAddr() const
Get address of the objects being allocated using this allocator.
Definition alloc.h:460
std::unique_ptr< TInterface, details::InPlaceDeleter< TInterface > > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition alloc.h:408
Ptr alloc(TArgs &&... args)
Allocation function.
Definition alloc.h:426
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.