5 #ifndef UAVCAN_UTIL_MULTISET_HPP_INCLUDED 6 #define UAVCAN_UTIL_MULTISET_HPP_INCLUDED 16 #if !defined(UAVCAN_CPP_VERSION) || !defined(UAVCAN_CPP11) 17 # error UAVCAN_CPP_VERSION 35 #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11 36 alignas(T)
unsigned char pool[
sizeof(T)];
40 unsigned char pool[
sizeof(T)];
54 fill_n(pool,
sizeof(pool), static_cast<unsigned char>(0));
67 fill_n(pool,
sizeof(pool), static_cast<unsigned char>(0));
80 StaticAssert<(static_cast<unsigned>(NumItems) > 0)>::check();
92 return new (praw)
Chunk();
107 for (
unsigned i = 0; i < static_cast<unsigned>(NumItems); i++)
109 if (!items[i].isConstructed())
127 Item* findOrCreateFreeSlot();
133 template <
typename Predicate>
145 : index(target_index)
164 return reference == sample;
168 template<
typename Operator>
192 : allocator_(allocator)
207 Item*
const item = findOrCreateFreeSlot();
213 item->ptr =
new (item->pool) T();
217 template <
typename P1>
220 Item*
const item = findOrCreateFreeSlot();
226 item->ptr =
new (item->pool) T(p1);
230 template <
typename P1,
typename P2>
233 Item*
const item = findOrCreateFreeSlot();
239 item->ptr =
new (item->pool) T(p1, p2);
243 template <
typename P1,
typename P2,
typename P3>
246 Item*
const item = findOrCreateFreeSlot();
252 item->ptr =
new (item->pool) T(p1, p2, p3);
261 template <
typename Predicate>
262 void removeAllWhere(Predicate predicate) { removeWhere<Predicate>(predicate, RemoveAll); }
264 template <
typename Predicate>
265 void removeFirstWhere(Predicate predicate) { removeWhere<Predicate>(predicate, RemoveOne); }
267 void removeFirst(
const T& ref) { removeFirstWhere(ComparingPredicate(ref)); }
269 void removeAll(
const T& ref) { removeAllWhere(ComparingPredicate(ref)); }
271 void clear() { removeAllWhere(YesPredicate()); }
278 template <
typename Predicate>
279 T* find(Predicate predicate);
281 template <
typename Predicate>
282 const T*
find(Predicate predicate)
const 284 return const_cast<Multiset*
>(
this)->find<Predicate>(predicate);
293 template <
typename Operator>
296 OperatorToFalsePredicateAdapter<Operator> adapter(oper);
297 (void)find<OperatorToFalsePredicateAdapter<Operator>&>(adapter);
300 template <
typename Operator>
303 const OperatorToFalsePredicateAdapter<Operator> adapter(oper);
304 (void)find<
const OperatorToFalsePredicateAdapter<Operator>&>(adapter);
315 IndexPredicate predicate(index);
316 return find<IndexPredicate&>(predicate);
321 return const_cast<Multiset*
>(
this)->getByIndex(index);
333 unsigned getSize()
const;
341 template <
typename T>
346 Chunk* p = list_.get();
349 Item*
const dyn = p->findFreeSlot();
354 p = p->getNextListNode();
359 Chunk*
const chunk = Chunk::instantiate(allocator_);
365 return &chunk->items[0];
368 template <
typename T>
371 Chunk* p = list_.get();
374 Chunk*
const next = p->getNextListNode();
375 bool remove_this =
true;
376 for (
int i = 0; i < Chunk::NumItems; i++)
378 if (p->items[i].isConstructed())
387 Chunk::destroy(p, allocator_);
393 template <
typename T>
394 template <
typename Predicate>
397 unsigned num_removed = 0;
399 Chunk* p = list_.get();
402 Chunk*
const next_chunk = p->getNextListNode();
404 if ((num_removed > 0) && (strategy == RemoveOne))
409 for (
int i = 0; i < Chunk::NumItems; i++)
411 Item& item = p->items[i];
412 if (item.isConstructed())
414 if (predicate(*item.ptr))
418 if (strategy == RemoveOne)
435 template <
typename T>
436 template <
typename Predicate>
439 Chunk* p = list_.get();
442 Chunk*
const next_chunk = p->getNextListNode();
444 for (
int i = 0; i < Chunk::NumItems; i++)
446 if (p->items[i].isConstructed())
448 if (predicate(*p->items[i].ptr))
450 return p->items[i].ptr;
460 template <
typename T>
464 Chunk* p = list_.get();
467 for (
int i = 0; i < Chunk::NumItems; i++)
469 num += p->items[i].isConstructed() ? 1U : 0U;
471 p = p->getNextListNode();
478 #endif // Include guard void removeAllWhere(Predicate predicate)
IndexPredicate(unsigned target_index)
void removeFirst(const T &ref)
virtual void deallocate(const void *ptr)=0
IPoolAllocator & allocator_
static const unsigned MemPoolBlockSize
Safe default that should be OK for any platform.
void forEach(Operator oper) const
T * emplace(P1 p1, P2 p2, P3 p3)
bool operator()(const T &sample)
T * emplace(P1 p1, P2 p2)
bool operator()(const T &) const
LinkedListRoot< Chunk > list_
ComparingPredicate(const T &ref)
void removeWhere(Predicate predicate, RemoveStrategy strategy)
bool operator()(const T &)
bool operator()(const T &item) const
bool isConstructed() const
void removeAll(const T &ref)
const T * find(Predicate predicate) const
T * find(Predicate predicate)
const T * getByIndex(unsigned index) const
static Chunk * instantiate(IPoolAllocator &allocator)
Multiset(IPoolAllocator &allocator)
virtual void * allocate(std::size_t size)=0
UAVCAN_EXPORT void fill_n(OutputIt first, std::size_t n, const T &value)
OperatorToFalsePredicateAdapter(Operator o)
void forEach(Operator oper)
T * getByIndex(unsigned index)
Item * findOrCreateFreeSlot()
static void destroy(Chunk *&obj, IPoolAllocator &allocator)
void removeFirstWhere(Predicate predicate)