Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Range Iterators #50284

Merged
merged 1 commit into from
Jul 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions core/templates/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,83 @@ class List {
_FORCE_INLINE_ Element() {}
};

typedef T ValueType;

struct Iterator {
_FORCE_INLINE_ T &operator*() const {
return E->get();
}
_FORCE_INLINE_ T *operator->() const { return &E->get(); }
_FORCE_INLINE_ Iterator &operator++() {
E = E->next();
return *this;
}
_FORCE_INLINE_ Iterator &operator--() {
E = E->prev();
return *this;
}

_FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; }
_FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; }

Iterator(Element *p_E) { E = p_E; }
Iterator() {}
Iterator(const Iterator &p_it) { E = p_it.E; }

private:
Element *E = nullptr;
};

struct ConstIterator {
_FORCE_INLINE_ const T &operator*() const {
return E->get();
}
_FORCE_INLINE_ const T *operator->() const { return &E->get(); }
_FORCE_INLINE_ ConstIterator &operator++() {
E = E->next();
return *this;
}
_FORCE_INLINE_ ConstIterator &operator--() {
E = E->prev();
return *this;
}

_FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; }
_FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; }

_FORCE_INLINE_ ConstIterator(const Element *p_E) { E = p_E; }
_FORCE_INLINE_ ConstIterator() {}
_FORCE_INLINE_ ConstIterator(const ConstIterator &p_it) { E = p_it.E; }

private:
const Element *E = nullptr;
};

_FORCE_INLINE_ Iterator begin() {
return Iterator(front());
}
_FORCE_INLINE_ Iterator end() {
return Iterator(nullptr);
}

#if 0
//to use when replacing find()
_FORCE_INLINE_ Iterator find(const K &p_key) {
return Iterator(find(p_key));
}
#endif
_FORCE_INLINE_ ConstIterator begin() const {
return ConstIterator(front());
}
_FORCE_INLINE_ ConstIterator end() const {
return ConstIterator(nullptr);
}
#if 0
//to use when replacing find()
_FORCE_INLINE_ ConstIterator find(const K &p_key) const {
return ConstIterator(find(p_key));
}
#endif
private:
struct _Data {
Element *first = nullptr;
Expand Down
133 changes: 109 additions & 24 deletions core/templates/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

#include "core/error/error_macros.h"
#include "core/os/memory.h"
#include "core/templates/pair.h"

// based on the very nice implementation of rb-trees by:
// https://web.archive.org/web/20120507164830/http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
Expand All @@ -55,11 +56,12 @@ class Map {
Element *parent = nullptr;
Element *_next = nullptr;
Element *_prev = nullptr;
K _key;
V _value;
//_Data *data;
KeyValue<K, V> _data;

public:
KeyValue<K, V> &key_value() { return _data; }
const KeyValue<K, V> &key_value() const { return _data; }

const Element *next() const {
return _next;
}
Expand All @@ -73,23 +75,106 @@ class Map {
return _prev;
}
const K &key() const {
return _key;
return _data.key;
}
V &value() {
return _value;
return _data.value;
}
const V &value() const {
return _value;
return _data.value;
}
V &get() {
return _value;
return _data.value;
}
const V &get() const {
return _value;
return _data.value;
}
Element() {}
Element(const KeyValue<K, V> &p_data) :
_data(p_data) {}
};

typedef KeyValue<K, V> ValueType;

struct Iterator {
_FORCE_INLINE_ KeyValue<K, V> &operator*() const {
return E->key_value();
}
_FORCE_INLINE_ KeyValue<K, V> *operator->() const { return &E->key_value(); }
_FORCE_INLINE_ Iterator &operator++() {
E = E->next();
return *this;
}
_FORCE_INLINE_ Iterator &operator--() {
E = E->prev();
return *this;
}

_FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; }
_FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; }

Iterator(Element *p_E) { E = p_E; }
Iterator() {}
Iterator(const Iterator &p_it) { E = p_it.E; }

private:
Element *E = nullptr;
};

struct ConstIterator {
_FORCE_INLINE_ const KeyValue<K, V> &operator*() const {
return E->key_value();
}
_FORCE_INLINE_ const KeyValue<K, V> *operator->() const { return &E->key_value(); }
_FORCE_INLINE_ ConstIterator &operator++() {
E = E->next();
return *this;
}
_FORCE_INLINE_ ConstIterator &operator--() {
E = E->prev();
return *this;
}

_FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return E == b.E; }
_FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return E != b.E; }

ConstIterator(const Element *p_E) { E = p_E; }
ConstIterator() {}
ConstIterator(const ConstIterator &p_it) { E = p_it.E; }

private:
const Element *E = nullptr;
};

_FORCE_INLINE_ Iterator begin() {
return Iterator(front());
}
_FORCE_INLINE_ Iterator end() {
return Iterator(nullptr);
}

#if 0
//to use when replacing find()
_FORCE_INLINE_ Iterator find(const K &p_key) {
return Iterator(find(p_key));
}
#endif
_FORCE_INLINE_ void remove(const Iterator &p_iter) {
return erase(p_iter.E);
}

_FORCE_INLINE_ ConstIterator begin() const {
return ConstIterator(front());
}
_FORCE_INLINE_ ConstIterator end() const {
return ConstIterator(nullptr);
}

#if 0
//to use when replacing find()
_FORCE_INLINE_ ConstIterator find(const K &p_key) const {
return ConstIterator(find(p_key));
}
#endif
private:
struct _Data {
Element *_root = nullptr;
Expand All @@ -107,7 +192,7 @@ class Map {
}

void _create_root() {
_root = memnew_allocator(Element, A);
_root = memnew_allocator(Element(KeyValue<K, V>(K(), V())), A);
_root->parent = _root->left = _root->right = _nil;
_root->color = BLACK;
}
Expand Down Expand Up @@ -216,9 +301,9 @@ class Map {
C less;

while (node != _data._nil) {
if (less(p_key, node->_key)) {
if (less(p_key, node->_data.key)) {
node = node->left;
} else if (less(node->_key, p_key)) {
} else if (less(node->_data.key, p_key)) {
node = node->right;
} else {
return node; // found
Expand All @@ -236,9 +321,9 @@ class Map {
while (node != _data._nil) {
prev = node;

if (less(p_key, node->_key)) {
if (less(p_key, node->_data.key)) {
node = node->left;
} else if (less(node->_key, p_key)) {
} else if (less(node->_data.key, p_key)) {
node = node->right;
} else {
return node; // found
Expand All @@ -249,7 +334,7 @@ class Map {
return nullptr; // tree empty
}

if (less(p_key, prev->_key)) {
if (less(p_key, prev->_data.key)) {
prev = prev->_prev;
}

Expand Down Expand Up @@ -312,25 +397,25 @@ class Map {
while (node != _data._nil) {
new_parent = node;

if (less(p_key, node->_key)) {
if (less(p_key, node->_data.key)) {
node = node->left;
} else if (less(node->_key, p_key)) {
} else if (less(node->_data.key, p_key)) {
node = node->right;
} else {
node->_value = p_value;
node->_data.value = p_value;
return node; // Return existing node with new value
}
}

Element *new_node = memnew_allocator(Element, A);
typedef KeyValue<K, V> KV;
Element *new_node = memnew_allocator(Element(KV(p_key, p_value)), A);
akien-mga marked this conversation as resolved.
Show resolved Hide resolved
new_node->parent = new_parent;
new_node->right = _data._nil;
new_node->left = _data._nil;
new_node->_key = p_key;
new_node->_value = p_value;

//new_node->data=_data;

if (new_parent == _data._root || less(p_key, new_parent->_key)) {
if (new_parent == _data._root || less(p_key, new_parent->_data.key)) {
new_parent->left = new_node;
} else {
new_parent->right = new_node;
Expand Down Expand Up @@ -575,7 +660,7 @@ class Map {
CRASH_COND(!_data._root);
const Element *e = find(p_key);
CRASH_COND(!e);
return e->_value;
return e->_data.value;
}

V &operator[](const K &p_key) {
Expand All @@ -588,7 +673,7 @@ class Map {
e = insert(p_key, V());
}

return e->_value;
return e->_data.value;
}

Element *front() const {
Expand Down
35 changes: 35 additions & 0 deletions core/templates/pair.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#ifndef PAIR_H
#define PAIR_H

#include "core/typedefs.h"

template <class F, class S>
struct Pair {
F first;
Expand Down Expand Up @@ -64,4 +66,37 @@ struct PairSort {
}
};

template <class K, class V>
struct KeyValue {
const K key;
V value;

void operator=(const KeyValue &p_kv) = delete;
_FORCE_INLINE_ KeyValue(const KeyValue &p_kv) :
key(p_kv.key),
value(p_kv.value) {
}
_FORCE_INLINE_ KeyValue(const K &p_key, const V &p_value) :
key(p_key),
value(p_value) {
}
};

template <class K, class V>
bool operator==(const KeyValue<K, V> &pair, const KeyValue<K, V> &other) {
return (pair.key == other.key) && (pair.value == other.value);
}

template <class K, class V>
bool operator!=(const KeyValue<K, V> &pair, const KeyValue<K, V> &other) {
return (pair.key != other.key) || (pair.value != other.value);
}

template <class K, class V>
struct KeyValueSort {
bool operator()(const KeyValue<K, V> &A, const KeyValue<K, V> &B) const {
return A.key < B.key;
}
};

#endif // PAIR_H
Loading