[kutil] Update map iteration

Add an iterator type to kutil::map, and allow for each loops. Also
unify the compare() signature expected by sorting containers, and fixes
to adding and sorting in kutil::vector.
This commit is contained in:
2020-09-15 00:21:28 -07:00
parent e8564c755b
commit dcb4d1823f
6 changed files with 61 additions and 18 deletions

View File

@@ -321,7 +321,7 @@ public:
if (!item) return;
item_type *cur = m_head;
while (cur && item->compare(cur) > 0)
while (cur && item->compare(*cur) > 0)
cur = cur->m_next;
insert_before(cur, item);

View File

@@ -70,6 +70,21 @@ public:
static constexpr size_t min_capacity = 8;
static constexpr size_t max_load = 90;
class iterator
{
public:
iterator(node *n) : m_node(n) {}
inline node & operator*() { return *m_node; }
inline node * operator->() { return m_node; }
inline const node & operator*() const { return *m_node; }
inline iterator & operator++() { incr(); return *this; }
inline iterator operator++(int) { node *old = m_node; incr(); return iterator(old); }
inline bool operator!=(const iterator &o) { return m_node != o.m_node; }
private:
void incr() { do { m_node++; } while ( m_node && m_node->hash() == 0 ); }
node *m_node;
};
/// Default constructor. Creates an empty map with the given capacity.
base_map(size_t capacity = 0) :
m_count(0),
@@ -86,6 +101,18 @@ public:
kfree(m_nodes);
}
iterator begin() {
return iterator(m_nodes);
}
const iterator begin() const {
return iterator(m_nodes);
}
const iterator end() const {
return iterator(m_nodes + m_capacity);
}
void insert(K k, V v) {
if (++m_count > threshold()) grow();
insert_node(hash(k), std::move(k), std::move(v));

View File

@@ -125,19 +125,21 @@ public:
}
/// Insert an item into the list in a sorted position. Depends on T
/// having a method `int compare(const T *other)`.
void sorted_insert(const T& item)
/// having a method `int compare(const T &other)`.
/// \returns index of the new item
size_t sorted_insert(const T& item)
{
size_t start = 0;
size_t end = m_size;
while (end > start) {
size_t m = start + (end - start) / 2;
int c = item.compare(&m_elements[m]);
int c = item.compare(m_elements[m]);
if (c < 0) end = m;
else start = m + 1;
}
insert(start, item);
return start;
}
/// Remove an item from the end of the array.
@@ -156,16 +158,30 @@ public:
remove_at(0);
}
/// Remove the item at the given index from the array, not
/// order-preserving.
void remove_at(size_t i)
/// Remove an item from the array.
void remove(const T &item)
{
if (i >= count()) return;
kassert(m_size, "Called remove() on an empty array");
for (size_t i = 0; i < m_size; ++i) {
if (m_elements[i] == item) {
remove_at(i);
break;
}
}
}
m_elements[i].~T();
for (; i < m_size - 1; ++i)
m_elements[i] = m_elements[i+1];
m_size -= 1;
/// Remove n items starting at the given index from the array,
/// order-preserving.
void remove_at(size_t i, size_t n = 1)
{
for (size_t j = i; j < i + n; ++j) {
if (j >= m_size) return;
m_elements[j].~T();
}
for (; i < m_size - n; ++i)
m_elements[i] = m_elements[i+n];
m_size -= n;
}
/// Remove the first occurance of an item from the array, not