mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 00:14:32 -08:00
[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:
@@ -8,11 +8,11 @@ using memory::page_offset;
|
||||
using frame_block_node = kutil::list_node<frame_block>;
|
||||
|
||||
int
|
||||
frame_block::compare(const frame_block *rhs) const
|
||||
frame_block::compare(const frame_block &rhs) const
|
||||
{
|
||||
if (address < rhs->address)
|
||||
if (address < rhs.address)
|
||||
return -1;
|
||||
else if (address > rhs->address)
|
||||
else if (address > rhs.address)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,6 @@ struct frame_block
|
||||
/// Compare two blocks by address.
|
||||
/// \arg rhs The right-hand comparator
|
||||
/// \returns <0 if this is sorts earlier, >0 if this sorts later, 0 for equal
|
||||
int compare(const frame_block *rhs) const;
|
||||
int compare(const frame_block &rhs) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -6,8 +6,8 @@ struct unsortableT {
|
||||
|
||||
struct sortableT {
|
||||
int value;
|
||||
int compare(const sortableT *other) const {
|
||||
return value - other->value;
|
||||
int compare(const sortableT &other) const {
|
||||
return value - other.value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user