Lexeme::Lexeme(const LexemeType type, const std::wstring &text, const int line, const int row, const LexerErrorCode error) : Type(type) , Text(text) , Line(line) , Row(row) , Error(error) { CheckInvariant(); }
/** * Remove a single element from the tree, if it exists. * Since elements are stored in interior nodes as well as leaf nodes, removing one may * require a larger sub-tree to be re-built. Because of this, worst case run time is * as bad as a full tree rebuild. */ void Remove(const T &element) { size_t count = this->Count(); if (count == 0) return; if (!this->IsUnbalanced() || !this->Rebuild(nullptr, &element)) { /* If the removed element is the root node, this modifies this->root */ this->root = this->RemoveRecursive(element, this->root, 0); this->IncrementUnbalanced(); } CheckInvariant(); }
void Build(It begin, It end) { this->nodes.clear(); this->free_list.clear(); this->unbalanced = 0; if (begin == end) return; this->nodes.reserve(end - begin); this->root = this->BuildSubtree(begin, end, 0); CheckInvariant(); }
/** * Insert a single element in the tree. * Repeatedly inserting single elements may cause the tree to become unbalanced. * Undefined behaviour if the element already exists in the tree. */ void Insert(const T &element) { if (this->Count() == 0) { this->root = this->AddNode(element); } else { if (!this->IsUnbalanced() || !this->Rebuild(&element, nullptr)) { this->InsertRecursive(element, this->root, 0); this->IncrementUnbalanced(); } CheckInvariant(); } }
/** Verify that the invariant is true for a sub-tree, assert if not */ void CheckInvariant(size_t node_idx, int level, CoordT min_x, CoordT max_x, CoordT min_y, CoordT max_y) { if (node_idx == INVALID_NODE) return; const node &n = this->nodes[node_idx]; CoordT cx = this->xyfunc(n.element, 0); CoordT cy = this->xyfunc(n.element, 1); assert(cx >= min_x); assert(cx < max_x); assert(cy >= min_y); assert(cy < max_y); if (level % 2 == 0) { // split in dimension 0 = x CheckInvariant(n.left, level + 1, min_x, cx, min_y, max_y); CheckInvariant(n.right, level + 1, cx, max_x, min_y, max_y); } else { // split in dimension 1 = y CheckInvariant(n.left, level + 1, min_x, max_x, min_y, cy); CheckInvariant(n.right, level + 1, min_x, max_x, cy, max_y); } }
/** Verify the invariant for the entire tree, does nothing unless KDTREE_DEBUG is defined */ void CheckInvariant() { #ifdef KDTREE_DEBUG CheckInvariant(this->root, 0, std::numeric_limits<CoordT>::min(), std::numeric_limits<CoordT>::max(), std::numeric_limits<CoordT>::min(), std::numeric_limits<CoordT>::max()); #endif }
bool Lexeme::IsError() const { CheckInvariant(); return (Type == LexemeType::Error); }