mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 22:02:58 -06:00
132 lines
4 KiB
C++
132 lines
4 KiB
C++
#ifndef _Tree_Tree_h
|
|
#define _Tree_Tree_h
|
|
|
|
#include <Core/Core.h>
|
|
using namespace Upp;
|
|
|
|
template <class T>
|
|
class Tree
|
|
: protected Array<T>
|
|
{
|
|
protected:
|
|
typedef Array<T> B;
|
|
T * parent;
|
|
T * root;
|
|
|
|
inline void Link(T & t) { t.root = root; t.parent = (T *)this; }
|
|
inline void Unlink(T & t) { t.root = NULL; t.parent = NULL; }
|
|
|
|
void Relink() { for(int i = 0; i < B::GetCount(); i++) { T & t = B::operator[](i); Link(t); t.Relink();} }
|
|
|
|
public:
|
|
T *GetPtr() { return (T *) this; }
|
|
const T *GetPtr() const { return (const T *) this; }
|
|
T *GetParent() { return parent; }
|
|
const T *GetParent() const { return parent; }
|
|
T *GetRoot() { return root; }
|
|
const T *GetRoot() const { return root; }
|
|
void SetAsRoot() { ASSERT(parent == NULL); root = (T *)this; Relink(); }
|
|
|
|
// Array interface
|
|
|
|
T& Add() { T & t = B::Add(); Link(t); return t; }
|
|
void Add(const T& x) { T & t = B::Add(DeepCopyNew(x)); Link(t); }// return t; }
|
|
void AddPick(pick_ T& x) { T & t = B::Add(new T(x)); Link(t); }// return t; }
|
|
T& Add(T *newt) { ASSERT(newt->parent == NULL); T & t = B::Add(newt); Link(t); return t; }
|
|
|
|
using B::operator[];
|
|
using B::GetCount;
|
|
using B::IsEmpty;
|
|
|
|
using B::Trim;
|
|
void SetCount(int n) { B::SetCount(n); for(int i = 0; i < B::GetCount(); i++) Link(B::operator[](i)); }
|
|
void SetCountR(int n) { B::SetCountR(n); for(int i = 0; i < B::GetCount(); i++) Link(B::operator[](i)); }
|
|
using B::Clear;
|
|
|
|
T& At(int i) { if(i >= GetCount()) SetCountR(i + 1); return B::Get(i); }
|
|
T& At(int i, const T& x) { if(i >= GetCount()) SetCountR(i + 1, x); return B::Get(i); }
|
|
|
|
using B::Remove;
|
|
T& Insert(int i) { T & t = B::Insert(i); Link(t); return t; }
|
|
void InsertPick(int i, pick_ T& x) { Link(x); B::InsertPick(i, x); }
|
|
|
|
using B::GetIndex;
|
|
using B::Swap;
|
|
using B::Move;
|
|
|
|
T *Detach(int i) { T *t = B::Detach(i); Unlink(t); }
|
|
T& Set(int i, T *newt) { ASSERT(newt->parent == NULL); T & t = B::Set(i, newt); Link(t); return t; }
|
|
void Insert(int i, T *newt) { ASSERT(newt->parent == NULL); B::Insert(i, newt); Link(*newt); }
|
|
|
|
using B::Drop;
|
|
using B::Top;
|
|
|
|
T *PopDetach() { T * t = B::PopDetach(); Unlink(*t); return t; }
|
|
|
|
void Swap(Tree& b) { B::Swap(b); for(int i = 0; i < B::GetCount(); i++) Link(B::operator[](i)); for(int i = 0; i < b.GetCount(); i++) b.Link(b[i]); }
|
|
|
|
Tree& operator<<(const T& x) { Add(x); return *this; }
|
|
Tree& operator<<(T *newt) { Add(newt); return *this; }
|
|
Tree& operator|(pick_ T& x) { AddPick(x); return *this; }
|
|
|
|
#ifdef UPP
|
|
//void Serialize(Stream& s) { B::Serialize(); }
|
|
using B::Serialize;
|
|
#endif
|
|
|
|
// Array Interface end
|
|
|
|
Tree()
|
|
: parent(NULL)
|
|
, root(NULL)
|
|
{}
|
|
|
|
private:
|
|
Tree(const Tree&);
|
|
void operator=(const Tree&);
|
|
|
|
public:
|
|
#ifdef _DEBUG
|
|
void Dump() {
|
|
for(int i = 0; i < GetCount(); i++)
|
|
LOG((*this)[i]);
|
|
LOG("-------------------------------------");
|
|
}
|
|
#endif
|
|
};
|
|
|
|
template<class T>
|
|
void Xmlize(XmlIO xml, Tree<T>& data)
|
|
{
|
|
XmlizeContainer(xml, "item", data);
|
|
}
|
|
|
|
//Tree Node helper class
|
|
|
|
template<class T>
|
|
class Node
|
|
: public Tree<Node<T> >
|
|
{
|
|
public:
|
|
typedef Node CLASSNAME;
|
|
Node() {}
|
|
Node(const T& leaf) : leaf(leaf) {}
|
|
|
|
void Xmlize(XmlIO xml) { xml("leaf", leaf); XmlizeContainer(xml, "item", (Tree<Node<T> >&)*this); }
|
|
void Serialize(Stream& s) { s % leaf % (Tree<Node<T> >&)*this; }
|
|
|
|
T leaf;
|
|
};
|
|
|
|
template<class BB> //B conflicts with Tree::B
|
|
class Leaf
|
|
: public Tree<Leaf<BB> >
|
|
, public BB
|
|
{
|
|
public:
|
|
typedef Leaf<BB> CLASSNAME;
|
|
void Xmlize(XmlIO xml) { xml("leaf", (BB&)*this); XmlizeContainer(xml, "item", (Tree<Leaf<BB> >&)*this); }
|
|
void Serialize(Stream& s) { s % (BB&)*this % (Tree<Leaf<BB> >&)*this; }
|
|
};
|
|
|
|
#endif
|