16 #include <type_traits>
25 #include "comms/details/tag.h"
39 template <
typename TInterfaceType,
typename TDefaultType>
40 struct DynMemoryDeleteHandler
42 template <
typename TObj>
43 void handle(TObj& obj)
const
46 typename comms::util::LazyShallowConditional<
47 std::is_void<TDefaultType>::value
53 handleInternal(obj, HandleTag());
57 template <
typename... TParams>
58 using NoDefaultCastTag = comms::details::tag::Tag1<>;
60 template <
typename... TParams>
61 using DefaultCastCheckTag = comms::details::tag::Tag2<>;
63 template <
typename... TParams>
64 using ForcedDefaultCastTag = comms::details::tag::Tag3<>;
66 template <
typename TObj,
typename... TParams>
67 void handleInternal(TObj& obj, NoDefaultCastTag<TParams...>)
const
72 template <
typename TObj,
typename... TParams>
73 void handleInternal(TObj& obj, ForcedDefaultCastTag<TParams...>)
const
75 delete static_cast<TDefaultType*
>(&obj);
78 template <
typename TObj,
typename... TParams>
79 void handleInternal(TObj& obj, DefaultCastCheckTag<TParams...>)
const
81 using ObjType =
typename std::decay<decltype(obj)>::type;
83 typename comms::util::LazyShallowConditional<
84 std::is_same<ObjType, TInterfaceType>::value
89 handleInternal(obj, Tag());
94 template <
typename TInterfaceType,
typename TDefaultType>
95 struct InPlaceDeleteHandler
97 template <
typename TObj>
98 void handle(TObj& obj)
const
101 typename comms::util::LazyShallowConditional<
102 std::is_void<TDefaultType>::value
108 handleInternal(obj, HandleTag());
112 template <
typename... TParams>
113 using NoDefaultCastTag = comms::details::tag::Tag1<>;
115 template <
typename... TParams>
116 using DefaultCastCheckTag = comms::details::tag::Tag2<>;
118 template <
typename... TParams>
119 using ForcedDefaultCastTag = comms::details::tag::Tag3<>;
121 template <
typename TObj,
typename... TParams>
122 void handleInternal(TObj& obj, NoDefaultCastTag<TParams...>)
const
124 static_cast<void>(obj);
128 template <
typename TObj,
typename... TParams>
129 void handleInternal(TObj& obj, ForcedDefaultCastTag<TParams...>)
const
131 static_cast<TDefaultType&
>(obj).~TDefaultType();
134 template <
typename TObj,
typename... TParams>
135 void handleInternal(TObj& obj, DefaultCastCheckTag<TParams...>)
const
137 using ObjType =
typename std::decay<decltype(obj)>::type;
139 typename comms::util::LazyShallowConditional<
140 std::is_same<ObjType, TInterfaceType>::value
142 ForcedDefaultCastTag,
145 handleInternal(obj, Tag());
151 typename TAllMessages,
152 typename TDeleteHandler,
154 class NoVirtualDestructorDeleter
156 static const unsigned InvalidIdx = std::numeric_limits<unsigned>::max();
158 NoVirtualDestructorDeleter() : id_(TId()), idx_(InvalidIdx) {}
159 NoVirtualDestructorDeleter(TId
id,
unsigned idx) : id_(id), idx_(idx) {}
161 void operator()(TInterface* obj)
165 TDeleteHandler handler;
166 comms::dispatchMsgStaticBinSearch<TAllMessages>(id_, idx_, *obj, handler);
175 typename TAllMessages,
176 typename TDeleteHandler,
178 class NoVirtualDestructorInPlaceDeleter :
public
179 NoVirtualDestructorDeleter<TInterface, TAllMessages, TDeleteHandler, TId>
181 using Base = NoVirtualDestructorDeleter<TInterface, TAllMessages, TDeleteHandler, TId>;
182 static const unsigned InvalidIdx = std::numeric_limits<unsigned>::max();
184 NoVirtualDestructorInPlaceDeleter() =
default;
185 NoVirtualDestructorInPlaceDeleter(TId
id,
unsigned idx,
bool& allocated) : Base(id, idx), allocated_(&allocated) {}
187 NoVirtualDestructorInPlaceDeleter(
const NoVirtualDestructorInPlaceDeleter&) =
delete;
188 NoVirtualDestructorInPlaceDeleter(NoVirtualDestructorInPlaceDeleter&& other) :
189 Base(std::move(other)),
190 allocated_(other.allocated_)
192 other.allocated_ =
nullptr;
195 ~NoVirtualDestructorInPlaceDeleter()
199 NoVirtualDestructorInPlaceDeleter& operator=(
const NoVirtualDestructorInPlaceDeleter&) =
delete;
200 NoVirtualDestructorInPlaceDeleter& operator=(NoVirtualDestructorInPlaceDeleter&& other)
202 if (
reinterpret_cast<void*
>(
this) ==
reinterpret_cast<const void*
>(&other)) {
206 Base::operator=(std::move(other));
207 allocated_ = other.allocated_;
208 other.allocated_ =
nullptr;
212 void operator()(TInterface* obj)
216 Base::operator()(obj);
218 allocated_ =
nullptr;
221 bool* allocated_ =
nullptr;
224 template <
typename T>
228 friend class InPlaceDeleter;
231 InPlaceDeleter(
bool* allocated =
nullptr)
232 : allocated_(allocated)
236 InPlaceDeleter(
const InPlaceDeleter& other) =
delete;
238 template <
typename U>
239 InPlaceDeleter(InPlaceDeleter<U>&& other)
240 : allocated_(other.allocated_)
242 static_assert(std::is_base_of<T, U>::value ||
243 std::is_base_of<U, T>::value ||
244 std::is_convertible<U, T>::value ||
245 std::is_convertible<T, U>::value ,
246 "To make Deleter convertible, their template parameters "
247 "must be convertible.");
249 other.allocated_ =
nullptr;
252 ~InPlaceDeleter() noexcept
256 InPlaceDeleter& operator=(
const InPlaceDeleter& other) =
delete;
258 template <
typename U>
259 InPlaceDeleter& operator=(InPlaceDeleter<U>&& other)
261 static_assert(std::is_base_of<T, U>::value ||
262 std::is_base_of<U, T>::value ||
263 std::is_convertible<U, T>::value ||
264 std::is_convertible<T, U>::value ,
265 "To make Deleter convertible, their template parameters "
266 "must be convertible.");
268 if (
reinterpret_cast<void*
>(
this) ==
reinterpret_cast<const void*
>(&other)) {
273 allocated_ = other.allocated_;
274 other.allocated_ =
nullptr;
278 void operator()(T* obj) {
283 allocated_ =
nullptr;
287 bool* allocated_ =
nullptr;
298 template <
typename TInterface>
303 using Ptr = std::unique_ptr<TInterface>;
311 template <
typename TObj,
typename... TArgs>
314 static_assert(std::is_base_of<TInterface, TObj>::value,
315 "TObj does not inherit from TInterface");
316 return Ptr(
new TObj(std::forward<TArgs>(args)...));
324 template <
typename TObj>
327 static_assert(std::is_base_of<TInterface, TObj>::value,
328 "TObj does not inherit from TInterface");
349 template <
typename TInterface,
typename TAllMessages,
typename TId,
typename TDefaultType =
void>
353 details::NoVirtualDestructorDeleter<
356 details::DynMemoryDeleteHandler<TInterface, TDefaultType>,
360 using Ptr = std::unique_ptr<TInterface, Deleter>;
371 template <
typename TObj,
typename... TArgs>
372 static Ptr alloc(TId
id,
unsigned idx, TArgs&&... args)
374 static_assert(std::is_base_of<TInterface, TObj>::value,
375 "TObj does not inherit from TInterface");
376 return Ptr(
new TObj(std::forward<TArgs>(args)...), Deleter(
id, idx));
397 template <
typename TInterface,
typename TAllTypes>
404 using Ptr = std::unique_ptr<TInterface, details::InPlaceDeleter<TInterface> >;
421 template <
typename TObj,
typename... TArgs>
428 static_assert(std::is_base_of<TInterface, TObj>::value,
429 "TObj does not inherit from TInterface");
432 "TObj must be in provided tuple of supported types");
435 std::has_virtual_destructor<TInterface>::value ||
436 std::is_same<TInterface, TObj>::value,
437 "TInterface is expected to have virtual destructor");
439 static_assert(
sizeof(TObj) <=
sizeof(place_),
"Object is too big");
441 new (&place_) TObj(std::forward<TArgs>(args)...);
443 reinterpret_cast<TInterface*
>(&place_),
444 details::InPlaceDeleter<TInterface>(&allocated_));
466 template <
typename TObj>
469 if (obj ==
nullptr) {
473 static_assert(std::is_base_of<TInterface, TObj>::value,
474 "TObj does not inherit from TInterface");
475 COMMS_ASSERT(obj ==
reinterpret_cast<TInterface*
>(&place_));
478 reinterpret_cast<TInterface*
>(&place_),
479 details::InPlaceDeleter<TInterface>(&allocated_));
491 AlignedStorage place_;
492 bool allocated_ =
false;
513 typename TAllocMessages,
514 typename TOrigMessages,
516 typename TDefaultType =
void>
520 details::NoVirtualDestructorInPlaceDeleter<
523 details::InPlaceDeleteHandler<TInterface, TDefaultType>,
530 using Ptr = std::unique_ptr<TInterface, Deleter>;
541 template <
typename TObj,
typename... TArgs>
548 static_assert(std::is_base_of<TInterface, TObj>::value,
549 "TObj does not inherit from TInterface");
552 "TObj must be in provided tuple of supported types");
554 static_assert(
sizeof(TObj) <=
sizeof(place_),
"Object is too big");
556 new (&place_) TObj(std::forward<TArgs>(args)...);
558 reinterpret_cast<TInterface*
>(&place_),
559 Deleter(
id, idx, allocated_));
585 AlignedStorage place_;
586 bool allocated_ =
false;
598 template <
typename TInterface, std::
size_t TSize,
typename TAllTypes = std::tuple<TInterface> >
602 using Pool = std::array<PoolElem, TSize>;
610 template <
typename TObj,
typename... TArgs>
613 auto iter = std::find_if(
614 pool_.begin(), pool_.end(),
617 return !elem.allocated();
620 if (iter == pool_.end()) {
624 return iter->template alloc<TObj>(std::forward<TArgs>(args)...);
632 template <
typename TObj>
637 pool_.begin(), pool_.end(),
640 return elem.allocated() && (elem.allocAddr() == obj);
643 if (iter == pool_.end()) {
647 return iter->wrap(obj);
657 template <
typename...>
658 struct InPlaceSingleDeepCondWrap
660 template <
typename TInterface,
typename TAllTypes,
typename...>
664 template <
typename...>
665 struct InPlaceSingleNoVirtualDestructorDeepCondWrap
669 typename TAllocMessages,
670 typename TOrigMessages,
672 typename TDefaultType,
684 template <
typename...>
685 struct DynMemoryDeepCondWrap
687 template <
typename TInterface,
typename...>
691 template <
typename...>
692 struct DynMemoryNoVirtualDestructorDeepCondWrap
696 typename TAllMessages,
698 typename TDefaultType,
This file contains classes required for generic custom assertion functionality.
#define COMMS_ASSERT(expr)
Generic assert macro.
Definition: Assert.h:170
Contains various tuple type manipulation classes and functions.
Dynamic memory allocator for message types without virtual destructor.
Definition: alloc.h:351
std::unique_ptr< TInterface, Deleter > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition: alloc.h:360
static Ptr alloc(TId id, unsigned idx, TArgs &&... args)
Allocation function.
Definition: alloc.h:372
static constexpr bool canAllocate()
Inquiry whether allocation is possible.
Definition: alloc.h:381
Dynamic memory allocator.
Definition: alloc.h:300
static Ptr wrap(TObj *obj)
Function used to wrap raw pointer into a smart one.
Definition: alloc.h:325
std::unique_ptr< TInterface > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition: alloc.h:303
static Ptr alloc(TArgs &&... args)
Allocation function.
Definition: alloc.h:312
static constexpr bool canAllocate()
Inquiry whether allocation is possible.
Definition: alloc.h:334
In-place object pool allocator.
Definition: alloc.h:600
Ptr wrap(TObj *obj)
Function used to wrap raw pointer into a smart one.
Definition: alloc.h:633
Ptr alloc(TArgs &&... args)
Allocation function.
Definition: alloc.h:611
typename PoolElem::Ptr Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition: alloc.h:607
In-place single object allocator for message objects without virtual destructor.
Definition: alloc.h:518
Ptr alloc(TId id, unsigned idx, TArgs &&... args)
Allocation function.
Definition: alloc.h:542
const void * allocAddr() const
Get address of the objects being allocated using this allocator.
Definition: alloc.h:571
bool canAllocate() const
Inquiry whether allocation is possible.
Definition: alloc.h:577
std::unique_ptr< TInterface, Deleter > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition: alloc.h:530
bool allocated() const
Inquire whether the object is already allocated.
Definition: alloc.h:565
In-place single object allocator.
Definition: alloc.h:399
bool allocated() const
Inquire whether the object is already allocated.
Definition: alloc.h:450
~InPlaceSingle()
Destructor.
Definition: alloc.h:407
Ptr wrap(TObj *obj)
Function used to wrap raw pointer into a smart one.
Definition: alloc.h:467
bool canAllocate() const
Inquiry whether allocation is possible.
Definition: alloc.h:483
std::unique_ptr< TInterface, details::InPlaceDeleter< TInterface > > Ptr
Smart pointer (std::unique_ptr) to the allocated object.
Definition: alloc.h:404
Ptr alloc(TArgs &&... args)
Allocation function.
Definition: alloc.h:422
const void * allocAddr() const
Get address of the objects being allocated using this allocator.
Definition: alloc.h:456
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:94
Calculated "aligned union" storage type for all the types in provided tuple.
Definition: Tuple.h:157
Replacement to some types from standard type_traits.