#ifndef RedBlack_h
#define RedBlack_h
// std::swap is available in this context
//template <class T> inline void swap(T& a, T& b)
//{
// T c(a); a = b; b = c;
//};
template<typename T, typename K>
class RedBlack {
public:
using RBIter = bool(*)(K, T*);
RedBlack(bool = false);
~RedBlack();
bool deleteNode(K);
bool insertNode(K, T*);
int blackHeight();
int nodeCount(bool=false);
T* nodeSearch(K);
void iterate(RBIter);
void reverseIterate(RBIter);
void clear();
void allowUpdate(bool);
protected:
enum Colour { RED, BLACK };
struct rbNode {
K key;
uint8_t colour;
rbNode *left, *right, *parent;
void* data;
};
rbNode* root;
uint8_t tSize;
uint8_t nodeSize;
T* rbSearch(K, rbNode*);
rbNode* rbMinimum(rbNode*);
rbNode* rbMaximum(rbNode*);
rbNode* rbInsert(rbNode*, rbNode*);
rbNode* rbMakeNode(K key, T* data);
bool memoryError;
void rbPostInsertFix(rbNode*, rbNode*&);
rbNode* rbFind(K, rbNode*);
private:
bool updateOK;
bool rbRepeat;
int rbCount(bool, rbNode*);
int rbHeight(rbNode*);
int rbMax(int, int);
void rbDeleteTree(rbNode*);
void rbRotateRight(rbNode*, rbNode*&);
void rbRotateLeft(rbNode*, rbNode*&);
rbNode* rbPreDeleteFix(rbNode*, rbNode*&);
void rbIterate(rbNode*, RBIter);
void rbRevIterate(rbNode*, RBIter);
};
// Constructor / destructor
template<typename T, typename K>
RedBlack<T, K>::RedBlack(bool noUpdates = false) {
root = NULL;
nodeSize = sizeof(rbNode);
tSize = sizeof(T);
updateOK = !noUpdates;
}
template<typename T, typename K>
RedBlack<T, K>::~RedBlack() {
rbDeleteTree(root);
}
//Public Methods
template<typename T, typename K>
bool RedBlack<T, K>::insertNode(K key, T* data) {
memoryError = false;
rbNode* temp = rbMakeNode(key, data);
root = rbInsert(temp, root);
rbPostInsertFix(temp, root);
return !memoryError;
}
template<typename T, typename K>
bool RedBlack<T, K>::deleteNode(K key) {
rbNode* found = rbFind(key, root);
if (found) {
rbNode* del = rbPreDeleteFix(found, root);
// now zap whatever is no longer needed
free(del->data);
free(del);
return true;
}
return false;
}
template<typename T, typename K>
T* RedBlack<T, K>::nodeSearch(K key) {
return rbSearch(key, root);
}
template<typename T, typename K>
void RedBlack<T, K>::iterate(RBIter callBack) {
rbRepeat = true;
rbIterate(root, callBack);
}
template<typename T, typename K>
void RedBlack<T, K>::reverseIterate(RBIter callBack) {
rbRepeat = true;
rbRevIterate(root, callBack);
}
template<typename T, typename K>
int RedBlack<T, K>::blackHeight() {
return rbHeight(root);
}
template<typename T, typename K>
int RedBlack<T, K>::nodeCount(bool blackOnly = false) {
return rbCount(blackOnly, root);
}
template<typename T, typename K>
void RedBlack<T, K>::clear() {
rbDeleteTree(root);
root = NULL;
}
template<typename T, typename K>
void RedBlack<T, K>::allowUpdate(bool allow) {
updateOK = allow;
}
//private methods
template<typename T, typename K>
typename RedBlack<T, K>::rbNode* RedBlack<T, K>::rbMakeNode(K key, T* data) {
rbNode* temp = (rbNode*)malloc(nodeSize);
if (temp == NULL) {
memoryError = true;
}
temp->key = key;
temp->left = temp->right = temp->parent = NULL;
temp->colour = RED;
temp->data = malloc(tSize);
if (temp->data) {
if (data) {
// allows for no data presented in Map subclass
memcpy(temp->data, data, tSize);
}
else {
memset(temp->data, '\0', tSize);
}
}
else {
memoryError = true;
}
return temp;
}
template<typename T, typename K>
typename RedBlack<T, K>::rbNode* RedBlack<T, K>::rbInsert(rbNode* node, rbNode* leaf) {
if (leaf == NULL) {
return node;
}
if (node->key == leaf->key) {
if (updateOK) {
memcpy(leaf->data, node->data, tSize);
free(node->data);
free(node);
}
else {
memoryError = true; // well sort of
}
return leaf;
}
if (node->key < leaf->key) {
leaf->left = rbInsert(node, leaf->left);
leaf->left->parent = leaf;
}
else if (node->key > leaf->key) {
leaf->right = rbInsert(node, leaf->right);
leaf->right->parent = leaf;
}
return leaf;
}
template<typename T, typename K>
void RedBlack<T, K>::rbPostInsertFix(rbNode* node, rbNode*& root) {
rbNode* grandMa = NULL;
rbNode* aunty = NULL;
while (node != root && node->parent->colour == RED) {
grandMa = node->parent->parent;
if (node->parent == grandMa->left) {
aunty = grandMa->right;
if (aunty && aunty->colour == RED) {
node->parent->colour = BLACK;
aunty->colour = BLACK;
grandMa->colour = RED;
node = grandMa;
}
else {
if (node == node->parent->right) {
node = node->parent;
rbRotateLeft(node, root);
}
node->parent->colour = BLACK;
grandMa->colour = RED;
rbRotateRight(grandMa, root);
}
}
else {
aunty = grandMa->left;
if (aunty && aunty->colour == RED) {
node->parent->colour = BLACK;
aunty->colour = BLACK;
grandMa->colour = RED;
node = grandMa;
}
else {
if (node == node->parent->left) {
node = node->parent;
rbRotateRight(node, root);
}
node->parent->colour = BLACK;
grandMa->colour = RED;
rbRotateLeft(grandMa, root);
}
}
}
root->colour = BLACK;
}
template<typename T, typename K>
typename RedBlack<T, K>::rbNode* RedBlack<T, K>::rbFind(K key, rbNode* leaf) {
if (leaf) {
if (leaf->key == key) {
return leaf;
}
if (key < leaf->key) {
return rbFind(key, leaf->left);
}
return rbFind(key, leaf->right);
}
return NULL;
}
template<typename T, typename K>
typename RedBlack<T, K>::rbNode* RedBlack<T, K>::rbPreDeleteFix(rbNode* node, rbNode*& root) {
rbNode* nodeToDelete = node;
rbNode* child = NULL;
rbNode* parentNode = NULL;
if (nodeToDelete->left == NULL) { // node has one or no children
child = nodeToDelete->right; // which might be NULL
}
else {
if (nodeToDelete->right == NULL) // node has one child
child = nodeToDelete->left; // child is not NULL
else { // node has two children
nodeToDelete = rbMinimum(nodeToDelete->right);
// so we reset to the minimum key node
// from the right child (so next largest key)
child = nodeToDelete->right;
}
}
if (nodeToDelete != node) {
// if the nodeToDelete got changed above
node->left->parent = nodeToDelete;
nodeToDelete->left = node->left;
if (nodeToDelete != node->right) {
parentNode = nodeToDelete->parent;
if (child) {
child->parent = nodeToDelete->parent;
}
nodeToDelete->parent->left = child;
nodeToDelete->right = node->right;
node->right->parent = nodeToDelete;
}
else {
parentNode = nodeToDelete;
}
if (root == node) {
root = nodeToDelete;
}
else if (node->parent->left == node) {
node->parent->left = nodeToDelete;
}
else {
node->parent->right = nodeToDelete;
}
nodeToDelete->parent = node->parent;
std::swap(nodeToDelete->colour, node->colour);
nodeToDelete = node;
// nodeToDelete now deinately points to node to be deleted
}
else {
parentNode = nodeToDelete->parent;
if (child) {
child->parent = nodeToDelete->parent;
}
if (root == node) {
root = child;
}
else {
if (node->parent->left == node) {
node->parent->left = child;
}
else {
node->parent->right = child;
}
}
}
if (nodeToDelete->colour != RED) {
while (child != root && (child == NULL || child->colour == BLACK)) {
if (child == parentNode->left) {
rbNode* sisterNode = parentNode->right;
if (sisterNode->colour == RED) {
sisterNode->colour = BLACK;
parentNode->colour = RED;
rbRotateLeft(parentNode, root);
sisterNode = parentNode->right;
}
if ((sisterNode->left == NULL ||
sisterNode->left->colour == BLACK) &&
(sisterNode->right == NULL ||
sisterNode->right->colour == BLACK)) {
sisterNode->colour = RED;
child = parentNode;
parentNode = parentNode->parent;
}
else {
if (sisterNode->right == NULL ||
sisterNode->right->colour == BLACK) {
if (sisterNode->left) sisterNode->left->colour = BLACK;
sisterNode->colour = RED;
rbRotateRight(sisterNode, root);
sisterNode = parentNode->right;
}
sisterNode->colour = parentNode->colour;
parentNode->colour = BLACK;
if (sisterNode->right) {
sisterNode->right->colour = BLACK;
}
rbRotateLeft(parentNode, root);
break;
}
}
else { // same as above but the other way about
rbNode* sisterNode = parentNode->left;
if (sisterNode->colour == RED) {
sisterNode->colour = BLACK;
parentNode->colour = RED;
rbRotateRight(parentNode, root);
sisterNode = parentNode->left;
}
if ((sisterNode->right == NULL ||
sisterNode->right->colour == BLACK) &&
(sisterNode->left == NULL ||
sisterNode->left->colour == BLACK)) {
sisterNode->colour = RED;
child = parentNode;
parentNode = parentNode->parent;
}
else {
if (sisterNode->left == NULL ||
sisterNode->left->colour == BLACK) {
if (sisterNode->right) {
sisterNode->right->colour = BLACK;
}
sisterNode->colour = RED;
rbRotateLeft(sisterNode, root);
sisterNode = parentNode->left;
}
sisterNode->colour = parentNode->colour;
parentNode->colour = BLACK;
if (sisterNode->left) {
sisterNode->left->colour = BLACK;
}
rbRotateRight(parentNode, root);
break;
}
}
}
if (child) {
child->colour = BLACK;
}
}
return nodeToDelete;
}
template<typename T, typename K>
void RedBlack<T, K>::rbRotateLeft(rbNode* node, rbNode*& root) {
rbNode* child = node->right;
node->right = child->left;
if (child->left) {
child->left->parent = node;
}
child->parent = node->parent;
if (node == root) {
root = child;
}
else if (node == node->parent->left) {
node->parent->left = child;
}
else {
node->parent->right = child;
}
child->left = node;
node->parent = child;
}
template<typename T, typename K>
void RedBlack<T, K>::rbRotateRight(rbNode* node, rbNode*& root) {
rbNode* child = node->left;
node->left = child->right;
if (child->right != 0) {
child->right->parent = node;
}
child->parent = node->parent;
if (node == root) {
root = child;
}
else if (node == node->parent->right) {
node->parent->right = child;
}
else {
node->parent->left = child;
}
child->right = node;
node->parent = child;
}
template<typename T, typename K>
T* RedBlack<T, K>::rbSearch(K key, rbNode* leaf) {
if (leaf) {
if (leaf->key == key) {
return (T*)leaf->data;
}
if (key < leaf->key) {
return rbSearch(key, leaf->left);
}
return rbSearch(key, leaf->right);
}
return NULL;
}
template<typename T, typename K>
void RedBlack<T, K>::rbIterate(rbNode* leaf, RBIter callBack) {
if (leaf && rbRepeat) {
rbIterate(leaf->left, callBack);
if (rbRepeat) {
rbRepeat = callBack(leaf->key, (T*)leaf->data);
rbIterate(leaf->right, callBack);
}
}
}
template<typename T, typename K>
void RedBlack<T, K>::rbRevIterate(rbNode* leaf, RBIter callBack) {
if (leaf && rbRepeat) {
rbRevIterate(leaf->right, callBack);
if (rbRepeat) {
rbRepeat = callBack(leaf->key, (T*)leaf->data);
rbRevIterate(leaf->left, callBack);
}
}
}
template<typename T, typename K>
typename RedBlack<T, K>::rbNode* RedBlack<T, K>::rbMinimum(rbNode* node) {
while (node->left) {
node = node->left;
}
return node;
}
template<typename T, typename K>
typename RedBlack<T, K>::rbNode* RedBlack<T, K>::rbMaximum(rbNode* node) {
while (node->right) {
node = node->right;
}
return node;
}
template<typename T, typename K>
int RedBlack<T, K>::rbHeight(rbNode* leaf) {
if (leaf) {
int subMax = rbMax(rbHeight(leaf->left), rbHeight(leaf->right));
if (leaf->colour == BLACK) { subMax++; }
return subMax;
}
return 0;
}
template<typename T, typename K>
int RedBlack<T, K>::rbMax(int a, int b) {
return (a <= b) ? b : a;
}
template<typename T, typename K>
int RedBlack<T, K>::rbCount(bool blackOnly, rbNode* leaf) {
if (leaf) {
int rVal = (blackOnly && leaf->colour == RED) ? 0 : 1;
return rVal + rbCount(blackOnly, leaf->left) + rbCount(blackOnly, leaf->right);
}
return 0;
}
template<typename T, typename K>
void RedBlack<T, K>::rbDeleteTree(rbNode* leaf) {
if (leaf) {
rbDeleteTree(leaf->left);
rbDeleteTree(leaf->right);
free(leaf->data);
free(leaf);
}
}
#endif
const float locations[][2] = {
{ 50.88896, -3.22276 },
{ 50.97296, -0.14434 },
{ 52.40201, -2.89624 },
{ 52.11315, -4.22539 },
{ 52.24226, -4.25925 },
{ 51.69282, -3.34593 },
{ 54.04421, -2.81772 },
{ 53.69139, -1.37831 },
{ 52.44573, -1.82716 },
{ 51.01786, 0.71719 },
{ 52.85295, -2.3481 },
{ 51.0029, -2.206 },
{ 52.86107, 1.24202 },
{ 51.24989, -0.76169 },
{ 57.2319, -2.70206 }
};
char places[][30] = {
"Abbey",
"Abbotsford",
"Abcott",
"Aber",
"Aberaeron",
"Aberfan",
"Abraham Heights",
"Ackton",
"Acocks Green",
"Acton",
"Adbaston",
"Alcester",
"Aldborough",
"Aldershot",
"Alford"
};
class Town {
public:
char* name;
Town() {
name = (char*)malloc(4);
memset(name, '\0', 1);
}
Town(char* tname) {
size_t sLen = strlen(tname);
name = (char*)malloc((++sLen));
strncpy(name, tname, sLen);
}
bool operator==(Town& t) {
char *a = &name[0], *b = &t.name[0];
for (; *a == *b; a++, b++) {
if (*a == '\0' || *b == '\0') {
if (*a == *b) { return true; }
break;
}
}
return false;
}
bool operator<(Town& t) {
char *a = &name[0], *b = &t.name[0];
for (; *a == *b; a++, b++) {
if (*a == '\0' || *b == '\0') {
break;
}
}
return (*a < *b) ? true : false;
}
bool operator>(Town& t) {
char *a = &name[0], *b = &t.name[0];
for (; *a == *b; a++, b++) {
if (*a == '\0' || *b == '\0') {
break;
}
}
return (*a > *b) ? true : false;
}
};
class Location {
public:
float latitude;
float longitude;
Location() {
latitude = longitude = 0;
}
Location(float lat, float lng) {
latitude = lat;
longitude = lng;
}
Location(pair<float, float> p) {
latitude = p.first;
longitude = p.second;
}
};
template <class T1, class T2>
struct pair {
T1 first;
T2 second;
pair() : first(T1()), second(T2()) {}
pair(const T1& a, const T2& b) : first(a), second(b) {}
};
template <class T1, class T2>
inline pair<T1, T2> make_pair(const T1& k, const T2& t)
{
return pair<T1, T2>(k, t);
}
#ifndef Map_h
#define Map_h
#include "RedBlack.h"
#include "Pair.h"
template<typename T, typename K>
class Map : public RedBlack<T, K> {
public:
typedef typename RedBlack<T, K>::rbNode tNode; // save typing
class iterator; // forward declaration
bool empty();
size_t size();
size_t erase(K); // plus erase(iterator position)
pair<iterator, bool> insert(pair<K, T>);
iterator begin();
iterator end();
iterator rbegin();
iterator rend();
iterator find(K);
void erase(iterator);
T &operator[](K k) {
T* found = this->nodeSearch(k);
if (found == NULL) {
tNode* temp = this->rbMakeNode(k, NULL);
found = (T*)temp->data;
this->root = this->rbInsert(temp, this->root);
this->rbPostInsertFix(temp, this->root);
}
return *found;
}
};
template<typename T, typename K>
class Map<T, K>::iterator : public pair<K, T> {
public:
iterator(tNode*, bool forward = true);
K getKey(); // avoids making node public
iterator &operator++() {
if (isForward) { increment(); }
else { decrement(); }
return *this;
};
iterator &operator++(int) {
if (isForward) { increment(); }
else { decrement(); }
return *this;
};
iterator &operator--() {
if (isForward) { decrement(); }
else { increment(); }
return *this;
};
iterator &operator--(int) {
if (isForward) { decrement(); }
else { increment(); }
return *this;
};
bool operator!=(const iterator a) {
return (this->node != (a.node));
};
bool operator==(const iterator a) {
return(this->node == a.node);
};
protected:
tNode* node;
private:
void increment();
void decrement();
void setPair();
bool isForward;
};
template<typename T, typename K>
Map<T, K>::iterator::iterator(tNode* iNode, bool forward = true) {
isForward = forward;
node = iNode;
if (node) {
setPair(); // node could be NULL
}
}
template<typename T, typename K>
void Map<T, K>::iterator::setPair() {
this->first = node->key;
this->second = *(T*)node->data;
}
template<typename T, typename K>
void Map<T, K>::iterator::increment() {
if (node->right) {
node = node->right;
while (node->left) {
node = node->left;
}
}
else {
if (node->parent) {
tNode* parent = node->parent;
while (parent && (node == parent->right)) {
node = parent;
parent = node->parent;
}
if (node->right != parent) {
node = parent;
}
}
else {
node = node->right; // if no right branch
}
}
if (node) {
setPair();
}
}
template<typename T, typename K>
void Map<T, K>::iterator::decrement() {
if (node->colour == RedBlack<T, K>::RED &&
node->parent->parent == node) {
node = node->right;
}
else if (node->left) {
tNode* child = node->left;
while (child->right) {
child = child->right;
}
node = child;
}
else {
if (node->parent) {
tNode* parent = node->parent;
while (parent && (node == parent->left)) {
node = parent;
parent = parent->parent;
}
node = parent;
}
else {
node = node->left;
}
}
if (node) {
setPair();
}
}
template<typename T, typename K>
K Map<T, K>::iterator::getKey() {
return node->key;
}
template<typename T, typename K>
typename Map<T, K>::iterator Map<T, K>::begin() {
iterator it(this->rbMinimum(this->root));
return it;
}
template<typename T, typename K>
typename Map<T, K>::iterator Map<T, K>::end() {
iterator it(this->rbMaximum(this->root)->right);
return it;
}
template<typename T, typename K>
typename Map<T, K>::iterator Map<T, K>::rbegin() {
iterator it(this->rbMaximum(this->root), false);
return it;
}
template<typename T, typename K>
typename Map<T, K>::iterator Map<T, K>::rend() {
iterator it(this->rbMinimum(this->root)->left);
return it;
}
template<typename T, typename K>
typename Map<T, K>::iterator Map<T, K>::find(K key) {
typename Map<T, K>::rbNode* found = this->rbFind(key, this->root);
if (found) {
iterator it(found);
return it;
}
return end();
}
template<typename T, typename K>
bool Map<T, K>::empty() {
return (this->nodeCount() == 0);
}
template<typename T, typename K>
size_t Map<T, K>::size() {
return this->nodeCount();
}
template<typename T, typename K>
size_t Map<T, K>::erase(K key) {
if (this->deleteNode(key)) {
return 1;
}
return 0;
}
template<typename T, typename K>
void Map<T, K>::erase(iterator what) {
this->deleteNode(what.getKey());
}
template<typename T, typename K>
pair<typename Map<T, K>::iterator, bool> Map<T, K>::insert(pair<K, T> newData) {
this->allowUpdate(false);
this->memoryError = false;
tNode* temp = this->rbMakeNode(newData.first, &newData.second);
this->root = this->rbInsert(temp, this->root);
this->allowUpdate(true);
bool insertOK = !this->memoryError;
if (insertOK) {
this->rbPostInsertFix(temp, this->root);
}
else {
temp = this->rbFind(newData.first, this->root);
}
iterator it(temp);
return make_pair(it, insertOK);
}
#endif
#include "stdafx.h"
#include <stdint.h>
#include <stdlib.h>
#include <iostream>
#include "Map.h"
#include "Town.h"
#include "Demodata.h"
void testX();
//void test2();
int main()
{
testX();
std::cin.get();
return 0;
}
void testX() {
Map<Location, std::string> myMap;
myMap["Chester"].latitude = 53.196;
myMap["Chester"].longitude = -2.887;
for (int i = 0; i < 5; i++) {
// // we can use the underlying RB tree methods
myMap.insertNode(&places[i][0], new Location(locations[i][0], locations[i][1]));
}
std::cout << "Count: " << myMap.size() << '\n';
}
//void test2() {
// Map<Location, Town> myMap;
// for (int i = 0; i < 5; i++) {
// Town t(&places[i][0]);
// // we can use the underlying RB tree methods
// myMap.insertNode(t, new Location(locations[i][0], locations[i][1]));
// }
// // we can treat the map as an associative array
// for (int i = 5; i < 10; i++) {
// Town t(&places[i][0]);
// myMap[t].latitude = locations[i][0];
// myMap[t].longitude = locations[i][1];
// }
// // we can iterate through the map values in ascending town name order
// for (Map<Location, Town>::iterator it = myMap.begin(); it != myMap.end(); it++) {
// std::cout << it.first.name << " Lat: " << it.second.latitude << " Long: " << it.second.longitude << '\n';
// }
// std::cout << "using insert\n";
// // we can get an iterator from the map insert
// Town t(&places[10][0]);
// Location l(locations[10][0], locations[10][1]);
// pair<Town, Location> p = make_pair(t, l);
// pair<Map<Location, Town>::iterator, bool> r = myMap.insert(p);
// if (r.second) {
// // the insert was good but we could also iterate to end
// for (; r.first != myMap.end(); r.first++) {
// std::cout << r.first.first.name << " Lat: " << r.first.second.latitude << " Long: " << r.first.second.longitude << '\n';
// }
// }
// // that insert format was a bit clumsy
// // how about?
// Location s(52.7068, -2.755);
// myMap.insert(pair<Town, Location>("Shrewsbury", s));
// // or
// myMap.insert(pair<Town, Location>("Birmingham", pair<float, float>(52.484, -1.9007)));
// // or
// myMap["Chester"].latitude = 53.196;
// myMap["Chester"].longitude = -2.887;
// //
// std::cout << "now a reverse iteration\n";
// for (Map<Location, Town>::iterator it = myMap.rbegin(); it != myMap.rend(); it++) {
// std::cout << it.first.name << " Lat: " << it.second.latitude << " Long: " << it.second.longitude << '\n';
// }
// std::cout << "Count: " << myMap.size() << '\n';
// std::cout << "Erase an item from map\n";
// myMap.erase(t);
//
// std::cout << "Count now: " << myMap.size() << '\n';
// for (Map<Location, Town>::iterator it = myMap.rbegin(); it != myMap.rend(); it++) {
// std::cout << it.first.name << " Lat: " << it.second.latitude << " Long: " << it.second.longitude << '\n';
// }
// Town f(&places[4][0]);
// Map<Location, Town>::iterator it = myMap.find(f);
// if (it != myMap.end()) {
// std::cout << "Found: " << it.first.name << " Lat: " << it.second.latitude << " Long: " << it.second.longitude << '\n';
// // we can also erase using the iterator
// myMap.erase(it);
// std::cout << "But now erased, so count: " << myMap.size() << '\n';
// }
// Town g(&places[11][0]);
// float lt = myMap[g].latitude; // value not previouly created
// std::cout << "Created entry " << g.name << " Latitude: " << lt << '\n';
// myMap.clear();
// std::cout << "Clear method run so count: " << myMap.size() << '\n';
//}
#include "Map.h"
#include "Town.h"
#include "Demodata.h"
struct cBoard{
uint8_t player;
uint8_t piece;
};
template<class T> inline Print &operator <<(Print &obj, T arg) { obj.print(arg); return obj; }
void setup() {
Serial.begin(115200);
Map<cBoard, uint8_t> myMap;
Serial << "Is Empty is " << (myMap.empty() ? "true\n" : "false\n");
cBoard mBoard = {1,2};
myMap.insertNode(5, &mBoard);
cBoard nBoard = myMap[5];
Serial << nBoard.player << " " << nBoard.piece << '\n';
nBoard.player = 25;
myMap[5] = nBoard;
Serial << myMap[5].player << '\n';
myMap[7].player = 26; // remember 7 has not be inserted
myMap[7].piece = 8;
nBoard = myMap[7];
Serial << nBoard.player << " " << nBoard.piece << '\n';
Serial << "Size: " << myMap.size() << '\n';
mBoard.player = 2;
mBoard.piece = 4;
myMap.insertNode(2, &mBoard);
for(Map<cBoard, uint8_t>::iterator it = myMap.begin(); it != myMap.end(); ++it) {
cBoard c = it.second;
Serial << "Square: " << it.first << " Player: " << c.player << " Piece: " << c.piece << '\n';
}
for(Map<cBoard, uint8_t>::iterator it = myMap.rbegin(); it != myMap.rend(); ++it) {
cBoard c = it.second;
Serial << "Square: " << it.first << " Player: " << c.player << " Piece: " << c.piece << '\n';
}
Map<cBoard, uint8_t>::iterator it = myMap.find(5);
myMap.erase(it);
Serial << "Erased: 5\n"; // exposes a bug in the delete fix in Red-Black
for(Map<cBoard, uint8_t>::iterator it = myMap.begin(); it != myMap.end(); ++it) {
cBoard c = it.second;
Serial << "Square: " << it.first << " Player: " << c.player << " Piece: " << c.piece << '\n';
}
myMap.insert(make_pair((uint8_t)9, mBoard));
for(Map<cBoard, uint8_t>::iterator it = myMap.rbegin(); it != myMap.rend(); ++it) {
cBoard c = it.second;
Serial << "Square: " << it.first << " Player: " << c.player << " Piece: " << c.piece << '\n';
}
}
Read the chapter in my book C++ Data Structures with immediate download from Amazon