mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-04-14 10:07:39 +08:00
Simplified Multiset<>
This commit is contained in:
parent
16a9d206c6
commit
02fe76cd6f
@ -24,11 +24,12 @@ namespace uavcan
|
||||
* they don't have to be copyable.
|
||||
*
|
||||
* Items can be allocated in a static buffer or in the node's memory pool if the static buffer is exhausted.
|
||||
*
|
||||
* Number of static entries must not be less than 1.
|
||||
*/
|
||||
template <typename T>
|
||||
class UAVCAN_EXPORT MultisetBase : Noncopyable
|
||||
template <typename T, unsigned NumStaticEntries>
|
||||
class UAVCAN_EXPORT Multiset : Noncopyable
|
||||
{
|
||||
protected:
|
||||
struct Item : ::uavcan::Noncopyable
|
||||
{
|
||||
T* ptr;
|
||||
@ -116,13 +117,16 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Data
|
||||
*/
|
||||
LinkedListRoot<Chunk> list_;
|
||||
IPoolAllocator& allocator_;
|
||||
#if !UAVCAN_TINY
|
||||
Item* const static_;
|
||||
const unsigned num_static_entries_;
|
||||
#endif
|
||||
Item static_[NumStaticEntries];
|
||||
|
||||
/*
|
||||
* Methods
|
||||
*/
|
||||
Item* findOrCreateFreeSlot();
|
||||
|
||||
void compact();
|
||||
@ -186,28 +190,16 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
#if UAVCAN_TINY
|
||||
MultisetBase(IPoolAllocator& allocator)
|
||||
: allocator_(allocator)
|
||||
{
|
||||
UAVCAN_ASSERT(Item() == Item());
|
||||
}
|
||||
#else
|
||||
MultisetBase(Item* static_buf, unsigned num_static_entries, IPoolAllocator& allocator)
|
||||
: allocator_(allocator)
|
||||
, static_(static_buf)
|
||||
, num_static_entries_(num_static_entries)
|
||||
{ }
|
||||
#endif
|
||||
|
||||
/// Derived class destructor must call clear();
|
||||
~MultisetBase()
|
||||
{
|
||||
UAVCAN_ASSERT(getSize() == 0);
|
||||
}
|
||||
|
||||
public:
|
||||
Multiset(IPoolAllocator& allocator)
|
||||
: allocator_(allocator)
|
||||
{ }
|
||||
|
||||
~Multiset()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates one item in-place and returns a pointer to it.
|
||||
* If creation fails due to lack of memory, NULL will be returned.
|
||||
@ -292,7 +284,7 @@ public:
|
||||
template <typename Predicate>
|
||||
const T* find(Predicate predicate) const
|
||||
{
|
||||
return const_cast<MultisetBase<T>*>(this)->find<Predicate>(predicate);
|
||||
return const_cast<Multiset*>(this)->find<Predicate>(predicate);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -329,7 +321,7 @@ public:
|
||||
|
||||
const T* getByIndex(unsigned index) const
|
||||
{
|
||||
return const_cast<MultisetBase<T>*>(this)->getByIndex(index);
|
||||
return const_cast<Multiset*>(this)->getByIndex(index);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -350,53 +342,17 @@ public:
|
||||
unsigned getNumDynamicItems() const;
|
||||
};
|
||||
|
||||
|
||||
template <typename T, unsigned NumStaticEntries = 0>
|
||||
class UAVCAN_EXPORT Multiset : public MultisetBase<T>
|
||||
{
|
||||
typename MultisetBase<T>::Item static_[NumStaticEntries];
|
||||
|
||||
public:
|
||||
|
||||
#if !UAVCAN_TINY
|
||||
|
||||
// This instantiation will not be valid in UAVCAN_TINY mode
|
||||
explicit Multiset(IPoolAllocator& allocator)
|
||||
: MultisetBase<T>(static_, NumStaticEntries, allocator)
|
||||
{ }
|
||||
|
||||
~Multiset() { this->clear(); }
|
||||
|
||||
#endif // !UAVCAN_TINY
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
class UAVCAN_EXPORT Multiset<T, 0> : public MultisetBase<T>
|
||||
{
|
||||
public:
|
||||
explicit Multiset(IPoolAllocator& allocator)
|
||||
#if UAVCAN_TINY
|
||||
: MultisetBase<T>(allocator)
|
||||
#else
|
||||
: MultisetBase<T>(NULL, 0, allocator)
|
||||
#endif
|
||||
{ }
|
||||
|
||||
~Multiset() { this->clear(); }
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* MultisetBase<>
|
||||
* Multiset<>
|
||||
*/
|
||||
template <typename T>
|
||||
typename MultisetBase<T>::Item* MultisetBase<T>::findOrCreateFreeSlot()
|
||||
template <typename T, unsigned NumStaticEntries>
|
||||
typename Multiset<T, NumStaticEntries>::Item* Multiset<T, NumStaticEntries>::findOrCreateFreeSlot()
|
||||
{
|
||||
#if !UAVCAN_TINY
|
||||
// Search in static pool
|
||||
for (unsigned i = 0; i < num_static_entries_; i++)
|
||||
for (unsigned i = 0; i < NumStaticEntries; i++)
|
||||
{
|
||||
if (!static_[i].isConstructed())
|
||||
{
|
||||
@ -429,8 +385,8 @@ typename MultisetBase<T>::Item* MultisetBase<T>::findOrCreateFreeSlot()
|
||||
return &chunk->items[0];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void MultisetBase<T>::compact()
|
||||
template <typename T, unsigned NumStaticEntries>
|
||||
void Multiset<T, NumStaticEntries>::compact()
|
||||
{
|
||||
Chunk* p = list_.get();
|
||||
while (p)
|
||||
@ -454,14 +410,14 @@ void MultisetBase<T>::compact()
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename T, unsigned NumStaticEntries>
|
||||
template <typename Predicate>
|
||||
void MultisetBase<T>::removeWhere(Predicate predicate, const RemoveStrategy strategy)
|
||||
void Multiset<T, NumStaticEntries>::removeWhere(Predicate predicate, const RemoveStrategy strategy)
|
||||
{
|
||||
unsigned num_removed = 0;
|
||||
|
||||
#if !UAVCAN_TINY
|
||||
for (unsigned i = 0; i < num_static_entries_; i++)
|
||||
for (unsigned i = 0; i < NumStaticEntries; i++)
|
||||
{
|
||||
if (static_[i].isConstructed())
|
||||
{
|
||||
@ -512,12 +468,12 @@ void MultisetBase<T>::removeWhere(Predicate predicate, const RemoveStrategy stra
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename T, unsigned NumStaticEntries>
|
||||
template <typename Predicate>
|
||||
T* MultisetBase<T>::find(Predicate predicate)
|
||||
T* Multiset<T, NumStaticEntries>::find(Predicate predicate)
|
||||
{
|
||||
#if !UAVCAN_TINY
|
||||
for (unsigned i = 0; i < num_static_entries_; i++)
|
||||
for (unsigned i = 0; i < NumStaticEntries; i++)
|
||||
{
|
||||
if (static_[i].isConstructed())
|
||||
{
|
||||
@ -547,12 +503,12 @@ T* MultisetBase<T>::find(Predicate predicate)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
unsigned MultisetBase<T>::getNumStaticItems() const
|
||||
template <typename T, unsigned NumStaticEntries>
|
||||
unsigned Multiset<T, NumStaticEntries>::getNumStaticItems() const
|
||||
{
|
||||
unsigned num = 0;
|
||||
#if !UAVCAN_TINY
|
||||
for (unsigned i = 0; i < num_static_entries_; i++)
|
||||
for (unsigned i = 0; i < NumStaticEntries; i++)
|
||||
{
|
||||
num += static_[i].isConstructed() ? 1U : 0U;
|
||||
}
|
||||
@ -560,8 +516,8 @@ unsigned MultisetBase<T>::getNumStaticItems() const
|
||||
return num;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
unsigned MultisetBase<T>::getNumDynamicItems() const
|
||||
template <typename T, unsigned NumStaticEntries>
|
||||
unsigned Multiset<T, NumStaticEntries>::getNumDynamicItems() const
|
||||
{
|
||||
unsigned num = 0;
|
||||
Chunk* p = list_.get();
|
||||
|
||||
@ -214,40 +214,6 @@ TEST(Multiset, Basic)
|
||||
}
|
||||
|
||||
|
||||
TEST(Multiset, NoStatic)
|
||||
{
|
||||
using uavcan::Multiset;
|
||||
|
||||
static const int POOL_BLOCKS = 3;
|
||||
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * POOL_BLOCKS, uavcan::MemPoolBlockSize> pool;
|
||||
uavcan::PoolManager<2> poolmgr;
|
||||
poolmgr.addPool(&pool);
|
||||
|
||||
typedef Multiset<std::string> MultisetType;
|
||||
std::auto_ptr<MultisetType> mset(new MultisetType(poolmgr));
|
||||
|
||||
// Empty
|
||||
mset->removeFirst("foo");
|
||||
ASSERT_EQ(0, pool.getNumUsedBlocks());
|
||||
ASSERT_FALSE(mset->getByIndex(0));
|
||||
|
||||
// Insertion
|
||||
ASSERT_EQ("a", *mset->emplace("a"));
|
||||
ASSERT_EQ("b", *mset->emplace("b"));
|
||||
ASSERT_LE(1, pool.getNumUsedBlocks());
|
||||
ASSERT_EQ(0, mset->getNumStaticItems());
|
||||
ASSERT_EQ(2, mset->getNumDynamicItems());
|
||||
|
||||
#if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
|
||||
// Only C++11 because C++03 uses one entry per pool block which breaks ordering
|
||||
ASSERT_EQ("a", *mset->getByIndex(0));
|
||||
ASSERT_EQ("b", *mset->getByIndex(1));
|
||||
ASSERT_FALSE(mset->getByIndex(3));
|
||||
ASSERT_FALSE(mset->getByIndex(1000));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
TEST(Multiset, PrimitiveKey)
|
||||
{
|
||||
using uavcan::Multiset;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user