Elm  2
ELM is a library providing generic data structures, OS-independent interface, plugins and XML.
TreeBag.h
1 /*
2  * TreeSet class interface
3  *
4  * This file is part of OTAWA
5  * Copyright (c) 2004-07, IRIT UPS.
6  *
7  * OTAWA is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * OTAWA is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with OTAWA; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 #ifndef ELM_DATA_TREEBAG_H
22 #define ELM_DATA_TREEBAG_H
23 
24 #include <elm/utility.h>
25 #include <elm/PreIterator.h>
26 #include <elm/data/Vector.h>
27 #include <elm/data/VectorQueue.h>
28 #include <elm/inhstruct/BinTree.h>
29 #include <elm/compare.h>
30 #include <elm/adapter.h>
31 
32 namespace elm {
33 
34 template <class T, class C = Comparator<T>, class A = DefaultAlloc >
35 class TreeBag: public C, public A {
36 private:
37 
38  class Node: public inhstruct::BinTree::Node {
39  public:
40  inline Node(const T& value): val(value) { }
41  T val;
42  inline void *operator new(size_t size, TreeBag<T, C, A> *t)
43  { return t->A::allocate(size); }
44  inline void free(TreeBag<T, C, A> *t)
45  { this->~Node(); t->A::free(this); }
46  };
47 
48 public:
49 
50  // Methods
51  inline TreeBag() { }
52  inline TreeBag(const TreeBag<T, C>& t) { copy(t); }
53  inline ~TreeBag(void) { clear(); }
54  const C& comparator() const { return *this; }
55  C& comparator() { return *this; }
56  A& allocator() { return *this; }
57 
58  // Collection concept
59  inline int count(void) const { return root.count(); }
60  inline bool contains(const T& x) const { return find(x) != nullptr; }
61  inline bool isEmpty(void) const { return root.isEmpty(); }
62  inline operator bool(void) const { return !isEmpty(); }
63 
64  template <class CC> bool containsAll(const CC& c) const
65  { for(const auto x: c) if(!contains(x)) return false; return true; }
66 
67  class Iter: public PreIterator<Iter, const T&> {
68  friend class TreeBag;
69  inline Node *_(inhstruct::BinTree::Node *n) { return static_cast<Node *>(n); }
70  public:
71  inline Iter(const TreeBag& tree)
72  { if(tree.root.root()) downLeft(_(tree.root.root())); }
73  bool ended(void) const { return !s; }
74  void next(void)
75  { if(s.top()->right()) downLeft(_(s.top()->right()));
76  else { Node *n = s.pop(); if(s && n == s.top()->right()) upRight(n); } }
77  const T& item(void) const { return s.top()->val; }
78  inline bool equals(const Iter& i) const { return s == i.s; }
79 
80  private:
81  inline Iter() { }
82  inline void downLeft(Node *n)
83  { s.push(n); while(s.top()->left()) s.push(_(s.top()->left())); }
84  inline void upRight(Node *n)
85  { while(s && s.top()->right() == n) n = s.pop(); }
87  };
88 
89  inline Iter begin() const { return Iter(*this); }
90  inline Iter end() const { return Iter(); }
91 
92  inline bool equals(const TreeBag<T, C>& t) const {
93  Iter i(*this), j(t);
94  while(i() && j()) {
95  if(comparator().doComparator(*i, *j) != 0)
96  return false;
97  i++, j++;
98  }
99  return !i() && !j();
100  }
101  inline bool operator==(const TreeBag<T, C>& t) const { return equals(t); }
102  inline bool operator!=(const TreeBag<T, C>& t) const { return !equals(t); }
103 
104  // MutableCollection concept
105  void clear(void) {
106  if(isEmpty())
107  return;
108  VectorQueue<Node *> todo;
109  todo.put((Node *)root.root());
110  while(todo) {
111  Node *node = todo.get();
112  if(node->left())
113  todo.put((Node *)node->left());
114  if(node->right())
115  todo.put((Node *)node->right());
116  node->free(this);
117  }
118  }
119 
120 
121  void add(const T &x) {
122  Node *node = (Node *)root.root();
123  Node *new_node = new(this) Node(x);
124  if(!node)
125  root.setRoot(new_node);
126  else
127  while(node) {
128  int cmp = C::doCompare(x, node->val);
129  if(cmp >= 0) {
130  if(!node->right()) {
131  node->insertRight(new_node);
132  break;
133  }
134  else
135  node = (Node *)node->right();
136  }
137  else {
138  if(!node->left()) {
139  node->insertLeft(new_node);
140  break;
141  }
142  else
143  node = (Node *)node->left();
144  }
145  }
146  }
147 
148  template <class CC> void addAll (const CC &c)
149  { for(const auto x: c) add(x); }
150  void remove(const T& x) {
151  Node *node = (Node *)root.root(), *parent = 0;
152  while(true) {
153  ASSERT(node);
154  int cmp = C::compare(x, node->val);
155  if(cmp == 0)
156  break;
157  parent = node;
158  if(cmp > 0)
159  node = (Node *)node->right();
160  else
161  node = (Node *)node->left();
162  }
163  Node *left = (Node *)node->left(), *right = (Node *)node->right();
164  node->free(this);
165  if(!left)
166  replace(parent, node, right);
167  else if(!right)
168  replace(parent, node, left);
169  else {
170  replace(parent, node, left);
171  for(node = left; node->right(); node = (Node *)node->right());
172  node->insertRight(right);
173  }
174  }
175 
176  template <class CC> void removeAll(const CC &c)
177  { for(const auto x: c) remove(x); }
178  inline void remove(const Iter &iter) { remove(*iter); }
179 
180  void copy(const TreeBag<T, C>& t) {
181  // TODO improve it!
182  clear();
183  addAll(t);
184  }
185 
186  const T *find(const T& x) const {
187  Node *node = (Node *)root.root();
188  while(node) {
189  int cmp = C::compare(x, node->val);
190  if(cmp == 0)
191  return &node->val;
192  else if(cmp > 0)
193  node = (Node *)node->right();
194  else
195  node = (Node *)node->left();
196  }
197  return nullptr;
198  }
199 
200 private:
201  inhstruct::BinTree root;
202 
203  void replace(Node *parent, Node *old, Node *_new) {
204  if(!parent)
205  root.setRoot(_new);
206  else if(parent->left() == old)
207  parent->insertLeft(_new);
208  else
209  parent->insertRight(_new);
210  }
211 };
212 
213 } // elm
214 
215 #endif // ELM_GENSTRUCT_SORTEDBINTREE_H
elm::TreeBag
Definition: TreeBag.h:35
elm::TreeBag::comparator
const C & comparator() const
Definition: TreeBag.h:54
elm::iter
Definition: util_WAHVector.cpp:157
elm::inhstruct::BinTree
Definition: BinTree.h:13
elm::TreeBag::Iter::next
void next(void)
Definition: TreeBag.h:74
elm::TreeBag::Iter::Iter
Iter(const TreeBag &tree)
Definition: TreeBag.h:71
elm::TreeBag::Iter::item
const T & item(void) const
Definition: TreeBag.h:77
elm::VectorQueue::get
const T & get(void)
Definition: VectorQueue.h:114
elm::TreeBag::add
void add(const T &x)
Definition: TreeBag.h:121
elm::TreeBag::comparator
C & comparator()
Definition: TreeBag.h:55
elm::VectorQueue::put
void put(const T &value)
Definition: VectorQueue.h:104
elm::TreeBag::remove
void remove(const T &x)
Definition: TreeBag.h:150
elm::TreeBag::begin
Iter begin() const
Definition: TreeBag.h:89
elm::TreeBag::end
Iter end() const
Definition: TreeBag.h:90
elm::Vector::push
void push(const T &v)
Definition: Vector.h:173
elm::VectorQueue
Definition: VectorQueue.h:31
elm::TreeBag::containsAll
bool containsAll(const CC &c) const
Definition: TreeBag.h:64
value
bool
elm::TreeBag::equals
bool equals(const TreeBag< T, C > &t) const
Definition: TreeBag.h:92
elm::TreeBag::TreeBag
TreeBag(const TreeBag< T, C > &t)
Definition: TreeBag.h:52
elm::TreeBag::addAll
void addAll(const CC &c)
Definition: TreeBag.h:148
elm::inhstruct::BinTree::root
Node * root(void) const
Definition: BinTree.h:90
elm::TreeBag::copy
void copy(const TreeBag< T, C > &t)
Definition: TreeBag.h:180
elm::TreeBag::operator!=
bool operator!=(const TreeBag< T, C > &t) const
Definition: TreeBag.h:102
elm::Comparator::t
T t
Definition: compare.h:36
elm::TreeBag::Iter::ended
bool ended(void) const
Definition: TreeBag.h:73
elm::_
AutoStringStartup & _
Definition: debug_CrashHandler.cpp:232
elm::DefaultAllocatorDelegate::free
void free(t::ptr p) const
Definition: custom.h:32
elm::TreeBag::count
int count(void) const
Definition: TreeBag.h:59
elm
Definition: adapter.h:26
elm::TreeBag::removeAll
void removeAll(const CC &c)
Definition: TreeBag.h:176
elm::TreeBag::isEmpty
bool isEmpty(void) const
Definition: TreeBag.h:61
elm::Vector::top
const T & top(void) const
Definition: Vector.h:170
elm::TreeBag::remove
void remove(const Iter &iter)
Definition: TreeBag.h:178
elm::TreeBag::contains
bool contains(const T &x) const
Definition: TreeBag.h:60
elm::TreeBag::Iter::equals
bool equals(const Iter &i) const
Definition: TreeBag.h:78
elm::TreeBag::allocator
A & allocator()
Definition: TreeBag.h:56
elm::t::size
uint64 size
Definition: arch.h:35
elm::inhstruct::BinTree::isEmpty
bool isEmpty(void) const
Definition: BinTree.h:81
elm::TreeBag::~TreeBag
~TreeBag(void)
Definition: TreeBag.h:53
elm::inhstruct::BinTree::Node
Definition: BinTree.h:16
elm::TreeBag::TreeBag
TreeBag()
Definition: TreeBag.h:51
elm::io::right
IntFormat right(IntFormat fmt)
Definition: Output.h:264
elm::TreeBag::find
const T * find(const T &x) const
Definition: TreeBag.h:186
elm::io::left
IntFormat left(IntFormat fmt)
Definition: Output.h:263
elm::TreeBag::operator==
bool operator==(const TreeBag< T, C > &t) const
Definition: TreeBag.h:101
Vector
elm::PreIterator
Definition: iter.h:28
elm::TreeBag::clear
void clear(void)
Definition: TreeBag.h:105
elm::TreeBag::Iter
Definition: TreeBag.h:67
elm::Vector::pop
T pop(void)
Definition: Vector.h:172
elm::inhstruct::BinTree::setRoot
void setRoot(Node *node)
Definition: BinTree.h:93