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>
134 void removeWhere(Predicate predicate, RemoveStrategy strategy);
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