ultimatepp/bazaar/Tree/Tree.h
kohait 669624d1fc bazaar: Gen, VTypes, Tree: recent Xmlize changes port
git-svn-id: svn://ultimatepp.org/upp/trunk@4592 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2012-02-13 22:59:31 +00:00

401 lines
12 KiB
C++

#ifndef _Tree_Tree_h
#define _Tree_Tree_h
#include <Core/Core.h>
NAMESPACE_UPP
template <class T>
class Tree
: protected Array<T>, MoveableAndDeepCopyOption<Tree<T> >
{
protected:
typedef Array<T> B;
T* parent;
T* root;
inline void DoLink(T& t) { t.root = root; t.parent = (T *)this; }
inline void Unlink(T& t) { t.root = NULL; t.parent = NULL; }
public:
void Relink() { for(int i = 0; i < B::GetCount(); i++) { T& t = B::operator[](i); DoLink(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(); DoLink(t); return t; }
T& Add(const T& x) { T& t = B::Add(x); DoLink(t); t.Relink(); return t; }
T& AddPick(pick_ T& x) { T& t = B::Add(x); DoLink(t); t.Relink(); return t; }
T& Add(T *newt) { ASSERT(newt->parent == NULL); T& t = B::Add(newt); DoLink(t); t.Relink(); 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++) DoLink(B::operator[](i)); }
void SetCountR(int n) { B::SetCountR(n); for(int i = 0; i < B::GetCount(); i++) DoLink(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); DoLink(t); return t; }
void InsertPick(int i, pick_ T& x) { DoLink(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); return t;}
T& Set(int i, T *newt) { ASSERT(newt->parent == NULL); T& t = B::Set(i, newt); DoLink(t); return t; }
void Insert(int i, T *newt) { ASSERT(newt->parent == NULL); B::Insert(i, newt); DoLink(*newt); }
using B::Drop;
using B::Top;
// using B::Pop;
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++) DoLink(B::operator[](i)); for(int i = 0; i < b.GetCount(); i++) b.DoLink(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; }
using B::IsPicked;
#ifdef UPP
void Serialize(Stream& s) { StreamContainer(s, *this); }
#endif
Tree()
: parent(NULL)
, root(NULL)
{}
//pick
Tree(pick_ Tree& v)
: parent(NULL)
, root(NULL)
, B(v)
{ Relink(); }
void operator=(pick_ Tree& v) { (B&)(*this) = v; Relink(); }
// Deep copy
Tree(const Tree& v, int)
: parent(NULL)
, root(NULL)
, B(v, 0)
{ Relink(); }
using B::ConstIterator;
using B::Iterator;
using B::ValueType;
using B::Begin;
using B::End;
using B::GetIter;
// Array Interface end
public:
#ifdef _DEBUG
void Dump() {
for(int i = 0; i < GetCount(); i++)
LOG((*this)[i]);
LOG("-------------------------------------");
}
#endif
};
template<class T>
inline void Xmlize(XmlIO& xml, Tree<T>& data)
{
XmlizeContainer(xml, "tree", data);
}
template <class T>
inline void DumpContainer(Stream& s, const Tree<T>& c) {
DumpContainer(s, c.Begin(), c.End());
}
//Tree Node helper class
template<class T>
class Node
: public Tree<Node<T> >
{
public:
typedef Node<T> CLASSNAME;
typedef Tree<Node<T> > R;
Node() {}
Node(const T& leaf) : leaf(leaf) {}
T leaf;
};
template <class T>
inline Stream& operator%(Stream& s, Node<T>& x)
{
s % x.leaf % (Tree<Node<T> >&)x;
return s;
}
template<class T>
inline void Xmlize(XmlIO& xml, Node<T>& a)
{
xml("leaf", a.leaf); Xmlize(xml, (Tree<Node<T> >&)a);
}
template<class BB> //B conflicts with Tree::B
class NodeB
: public Tree<NodeB<BB> >
, public BB //leaf
{
public:
typedef NodeB<BB> CLASSNAME;
typedef Tree<NodeB<BB> > R;
};
template <class BB>
inline Stream& operator%(Stream& s, NodeB<BB>& x)
{
s % (BB&)x % (Tree<NodeB<BB> >&)x;
return s;
}
template<class BB>
inline void Xmlize(XmlIO& xml, NodeB<BB>& a)
{
xml("leaf", (BB&)a); Xmlize(xml, (Tree<NodeB<BB> >&)a);
}
////
template <class K, class T, class HashFn = StdHash<K> >
class TreeMap
: protected ArrayMap<K,T,HashFn>, MoveableAndDeepCopyOption<TreeMap<T,K,HashFn> >
{
protected:
typedef ArrayMap<K,T,HashFn> B;
T* parent;
T* root;
inline void DoLink(T& t) { t.root = root; t.parent = (T *)this; }
inline void Unlink(T& t) { t.root = NULL; t.parent = NULL; }
public:
void Relink() { for(int i = 0; i < B::GetCount(); i++) { T& t = B::operator[](i); DoLink(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(); }
// AMap interface
T& Add(const K& k, const T& x) { T& t = B::Add(k, x); DoLink(t); t.Relink(); return t; }
T& Add(const K& k) { T& t = B::Add(k); DoLink(t); return t; }
T& AddPick(const K& k, pick_ T& x) { T& t = B::AddPick(); DoLink(t); t.Relink(); return t; }
using B::Find;
using B::FindNext;
using B::FindLast;
using B::FindPrev;
int FindAdd(const K& k) { int i = B::FindAdd(k); DoLink(operator[](i)); return i; }
int FindAdd(const K& k, const T& init) { int i = B::FindAdd(k, init); DoLink(operator[](i)); return i; }
int FindAddPick(const K& k, pick_ T& init) { int i = B::FindAddPick(k, init); DoLink(operator[](i)); return i; }
int Put(const K& k, const T& x) { int i = B::Put(k, x); DoLink(operator[](i)); return i; }
int PutPick(const K& k, pick_ T& x) { int i = B::PutPick(k, x); DoLink(operator[](i)); return i; }
T& Put(const K& k) { T& t = B::Put(k); DoLink(t); return t; }
int FindPut(const K& k) { int i = B::FindPut(k); DoLink(operator[](i)); return i; }
int FindPut(const K& k, const T& init) { int i = B::FindPut(k, init); DoLink(operator[](i)); return i; }
int FindPutPick(const K& k, pick_ T& init) { int i = B::FindPutPick(k, init); DoLink(operator[](i)); return i; }
using B::Get;
T& GetAdd(const K& k) {T& t = B::GetAdd(k); DoLink(t); return t; }
T& GetAdd(const K& k, const T& x) {T& t = B::GetAdd(k, x); DoLink(t); return t; }
T& GetAddPick(const K& k, pick_ T& x) {T& t = B::GetAddPick(k, x); DoLink(t); return t; }
T& GetPut(const K& k) {T& t = B::GetPut(k); DoLink(t); return t; }
T& GetPut(const K& k, const T& x) {T& t = B::GetPut(k, x); DoLink(t); return t; }
T& GetPutPick(const K& k, pick_ T& x) {T& t = B::GetPutPick(k, x); DoLink(t); return t; }
using B::SetKey;
using B::FindPtr;
using B::Unlink;
using B::UnlinkKey;
using B::IsUnlinked;
using B::Sweep;
T& Insert(int i, const K& k) { T& t = B::Insert(i, k); DoLink(t); return t; }
T& Insert(int i, const K& k, const T& x) { T& t = B::Insert(i, k, x); DoLink(t); return t; }
using B::Remove;
using B::RemoveKey;
using B::operator[];
using B::GetCount;
using B::IsEmpty;
using B::Clear;
using B::Shrink;
using B::Reserve;
using B::GetAlloc;
using B::GetHash;
using B::Drop;
using B::Top;
using B::TopKey;
// using B::Pop;
using B::PopKey;
using B::Trim;
using B::GetKey;
#ifdef UPP
void Serialize(Stream& s) {
int version = 0;
s / version % B::key % B::value;
for(int i = 0; i < B::GetCount(); i++)
{
T& t = B::operator[](i); DoLink(t);
//t.Relink(); //serialize will recurse
}
}
#endif
void Swap(TreeMap& b) { B::Swap(b); for(int i = 0; i < B::GetCount(); i++) DoLink(B::operator[](i)); for(int i = 0; i < b.GetCount(); i++) b.DoLink(b[i]); }
using B::GetIndex;
using B::PickIndex;
using B::GetKeys;
using B::PickKeys;
using B::GetValues;
Vector<T> PickValues() pick_ { Vector<T> v = B::PickValues(); for(int i = 0; i < v.GetCount(); i++) v[i].SetAsRoot(); return v; }
using B::IsPicked;
using B::KeyType;
using B::KeyConstIterator;
using B::KeyBegin;
using B::KeyEnd;
using B::KeyGetIter;
using B::ValueType;
using B::ConstIterator;
using B::Iterator;
using B::Begin;
using B::End;
using B::GetIter;
// ArrayMap interface
T& Add(const K& k, T *newt) { T& t = B::Add(k, newt); DoLink(t); t.Relink(); return t; }
template <class TT> TT& CreateB(const K& k) { TT *q = B::Create(k); DoLink(q); return *q; }
T& Set(int i, T *ptr) { ASSERT(ptr->parent == NULL); T& t = B::Set(i, ptr); DoLink(t); return t; }
T* PopDetach() { T* t = B::PopDetach(); Unlink(*t); return t; }
T* Detach(int i) { T* t = B::Detach(i); Unlink(*t); return t;}
TreeMap(const TreeMap& s, int)
: parent(NULL)
, root(NULL)
, B(s, 1)
{ Relink(); }
#if 0
ArrayMap(pick_ Index<K, HashFn>& ndx, pick_ Array<T>& val) : AMap<K, T, Array<T>, HashFn>(ndx, val) {}
ArrayMap(pick_ Vector<K>& ndx, pick_ Array<T>& val) : AMap<K, T, Array<T>, HashFn>(ndx, val) {}
#endif
TreeMap()
: parent(NULL)
, root(NULL)
{}
friend void Swap(TreeMap& a, TreeMap& b) { a.B::Swap(b); for(int i = 0; i < a.GetCount(); i++) DoLink(a[i]); for(int i = 0; i < b.GetCount(); i++) b.DoLink(b[i]); }
};
template<class K, class T, class H>
inline void Xmlize(XmlIO& xml, TreeMap<K, T, H>& data)
{
XmlizeMap<K, T>(xml, "tkey", "tvalue", data);
}
template <class K, class T, class H>
inline void DumpContainer(Stream& s, const TreeMap<K, T, H>& c) {
DumpContainer(s, c.Begin(), c.End());
}
template<class K, class T, class H = StdHash<K> >
class MapNode
: public TreeMap<K, MapNode<K,T,H>, H>
{
public:
typedef MapNode<K, T, H> CLASSNAME;
typedef TreeMap<K, MapNode<K,T,H>, H> R;
MapNode() {}
MapNode(const T& leaf) : leaf(leaf) {}
T leaf;
};
template <class K, class T, class H>
inline Stream& operator%(Stream& s, MapNode<K, T, H>& x)
{
s % x.leaf % (TreeMap<K, MapNode<K,T,H>, H>&)x;
return s;
}
template<class K, class T, class H>
inline void Xmlize(XmlIO& xml, MapNode<K, T, H>& a)
{
xml("leaf", a.leaf); Xmlize(xml, (TreeMap<K, MapNode<K,T,H>, H>&)a);
}
template<class K, class BB, class H = StdHash<K> > //B conflicts with Tree::B
class MapNodeB
: public TreeMap<K, MapNodeB<K, BB, H>, H>
, public BB //leaf
{
public:
typedef MapNodeB<K, BB, H> CLASSNAME;
typedef TreeMap<MapNodeB<K,BB,H>, H> R;
};
template <class K, class BB, class H>
inline Stream& operator%(Stream& s, MapNodeB<K, BB, H>& x)
{
s % (BB&)x % (TreeMap<K, MapNodeB<K,BB,H>, H>&)x;
return s;
}
template<class K, class BB, class H>
inline void Xmlize(XmlIO& xml, MapNodeB<K, BB, H>& a)
{
xml("leaf", (BB&)a); Xmlize(xml, (TreeMap<K, MapNodeB<K,BB,H>, H>&)a);
}
END_UPP_NAMESPACE
#endif