SCL  1.0
Standard Control Library : Control, dynamics, physics, and simulation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Macros Groups Pages
CMappedTree.hpp
1 /* This file is part of sUtil, a random collection of utilities.
2 
3 sUtil is free software; you can redistribute it and/or
4 modify it under the terms of the GNU Lesser General Public
5 License as published by the Free Software Foundation; either
6 version 3 of the License, or (at your option) any later version.
7 
8 Alternatively, you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of
11 the License, or (at your option) any later version.
12 
13 sUtil is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU Lesser General Public
19 License and a copy of the GNU General Public License along with
20 sUtil. If not, see <http://www.gnu.org/licenses/>.
21  */
22 /* \file CMappedTree.hpp
23  *
24  * Created on: Dec 27, 2010
25  *
26  * Copyright (C) 2010, Samir Menon <smenon@stanford.edu>
27  */
28 
29 #ifndef CMAPPEDTREE_HPP_
30 #define CMAPPEDTREE_HPP_
31 
32 #include <sutil/CMappedList.hpp>
33 
34 #ifdef DEBUG
35 #include <iostream>
36 #endif
37 
38 namespace sutil
39 {
65  template <typename TIdx, typename TNode>
66  class CMappedTree : public sutil::CMappedList<TIdx,TNode>
67  {
68  protected:
70  TNode* root_node_;
71 
74 
79  virtual bool deepCopy(const CMappedTree<TIdx,TNode>* arg_mt);
80 
81  public:
83  struct SMTNodeBase;
84 
85  CMappedTree();
86  virtual ~CMappedTree();
87 
91  {
93  return *this;
94  }
95 
104  virtual TNode* create(const TIdx& arg_idx, const TNode & arg_node2add,
105  const bool arg_is_root_);
106 
113  virtual TNode* create(const TIdx& arg_idx, const bool arg_is_root_);
114 
121  virtual TNode* insert(const TIdx& arg_idx, TNode *arg_node2add,
122  const bool arg_is_root_);
123 
125  virtual bool linkNodes();
126 
128  virtual const TNode* getRootNodeConst() const
129  { return static_cast<const TNode*>(root_node_); }
130 
132  virtual TNode* getRootNode()
133  { return root_node_; }
134 
136  virtual bool isAncestor(const TIdx& arg_idx_child,
137  const TIdx& arg_idx_ancestor) const;
138 
140  virtual bool isAncestor(const TNode* arg_node_child,
141  const TNode* arg_node_ancestor) const;
142 
144  virtual bool isDescendant(const TIdx& arg_idx_parent,
145  const TIdx& arg_idx_descendant) const;
146 
148  virtual bool isDescendant(const TNode* arg_node_parent,
149  const TNode* arg_node_descendant) const;
150  }; //End of template class
151 
152 
154  template <typename TIdx, typename TNode>
155  struct CMappedTree<TIdx,TNode>::SMTNodeBase
156  {
157  public:
159  TIdx name_;
163  TNode* parent_addr_;
165  std::vector<TNode*> child_addrs_;
166 
169  {
170  name_ = "";
171  parent_name_ = "";
172  parent_addr_ = NULL;
173  child_addrs_.clear();
174  }
175  };
176 
177  /***************************************************************
178  *******************************Function Definitions*************
179  ****************************************************************
180  */
181 
185  template <typename TIdx, typename TNode>
187  {
188  root_node_ = NULL;
189  has_been_init_ = false;
190  }
191 
198  template <typename TIdx, typename TNode>
200  {}
201 
202  template <typename TIdx, typename TNode>
204  deepCopy(const CMappedTree<TIdx,TNode>* const arg_mt)
205  {//Deep copy.
206  bool flag;
208  deepCopy(arg_mt);
209  if(true == flag)
210  {
211  this->root_node_ = CMappedList<TIdx,TNode>::at(arg_mt->getRootNodeConst()->name_);
212  this->has_been_init_ = arg_mt->has_been_init_;
213  return true;
214  }
215  else
216  { return false; }
217  }
218 
228  template <typename TIdx, typename TNode>
230  const TIdx& arg_idx, const TNode & arg_node2add,
231  const bool arg_is_root_)
232  {
233  if((arg_is_root_)&&(NULL!=root_node_))
234  {
235 #ifdef DEBUG
236  std::cerr<<"\nCMappedTree::create() : Error. Tried to insert a root node when one already exists.";
237 #endif
238  return NULL;
239  }
240 
241  //Add the node.
242  TNode* tLnk =
243  sutil::CMappedList<TIdx,TNode>::create(arg_idx,arg_node2add);
244 
245  if((arg_is_root_) && (root_node_==NULL))
246  { root_node_ = tLnk; }
247 
248  return tLnk;
249  }
250 
257  template <typename TIdx, typename TNode>
259  const TIdx& arg_idx, const bool arg_is_root_)
260  {
261  if((arg_is_root_)&&(NULL!=root_node_))
262  {
263 #ifdef DEBUG
264  std::cerr<<"\nCMappedTree::create() : Error. Tried to insert a root node when one already exists.";
265 #endif
266  return NULL;
267  }
268 
269  //Add the node.
270  TNode* tLnk = sutil::CMappedList<TIdx,TNode>::create(arg_idx);
271 
272  if((arg_is_root_) && (NULL==root_node_))
273  { root_node_ = tLnk; }
274 
275  return tLnk;
276  }
277 
286  template <typename TIdx, typename TNode>
288  const TIdx& arg_idx, TNode *arg_node2add,
289  const bool arg_is_root_)
290  {
291  if((arg_is_root_)&&(NULL!=root_node_))
292  {
293 #ifdef DEBUG
294  std::cerr<<"\nCMappedTree::create() : Error. Tried to insert a root node when one already exists.";
295 #endif
296  return NULL;
297  }
298 
299  //Add the node.
300  TNode* tLnk = sutil::CMappedList<TIdx,TNode>::create(arg_idx,arg_node2add);
301 
302  if((arg_is_root_) && (root_node_==NULL))
303  { root_node_ = tLnk; }
304 
305  return tLnk;
306  }
307 
308 
315  template <typename TIdx, typename TNode>
317  {
318  if(NULL == getRootNodeConst())
319  { return false; }
320 
321  //Clear previous links (if any)
322  typename CMappedList<TIdx,TNode>::iterator it,ite;
325  it != ite; ++it)
326  {
327  TNode& tmp_node = *it;
328  tmp_node.parent_addr_ = NULL;
329  tmp_node.child_addrs_.clear();
330  }
331 
332  //Form the new links
335  it != ite; ++it)
336  {
337  TNode& tmp_node = *it;
338  //Iterate over all nodes and connect them to their
339  //parents
340  if(&tmp_node == root_node_)
341  {//No parents
342  has_been_init_ = true;
343  continue;
344  }
345  else
346  {
347  tmp_node.parent_addr_ =
348  sutil::CMappedList<TIdx,TNode>::at(tmp_node.parent_name_);
349  if(tmp_node.parent_addr_ == NULL)
350  {//No parent -- Ignore this node
351 #ifdef DEBUG
352  std::cerr<<"\nCMappedTree::linkNodes(): Warning.";
353  std::cerr<<"Orphan node found: "<<tmp_node.name_<<". Ignoring.";
354 #endif
355  continue;
356  }
357  tmp_node.parent_addr_->child_addrs_.push_back(&tmp_node);
358 
359 #ifdef DEBUG
360  std::cerr<<"\n\tAdding child "<<tmp_node.name_
361  <<" to (parent) "<<tmp_node.parent_addr_->name_;
362  std::cerr<<std::flush;
363 #endif
364  }
365  }//End of while loop
366  return has_been_init_;
367  }
368 
369 
371  template <typename TIdx, typename TNode>
372  bool CMappedTree<TIdx,TNode>::isAncestor(const TIdx& arg_idx_child,
373  const TIdx& arg_idx_ancestor) const
374  { return isAncestor(this->at_const(arg_idx_child), this->at_const(arg_idx_child)); }
375 
377  template <typename TIdx, typename TNode>
378  bool CMappedTree<TIdx,TNode>::isAncestor(const TNode* arg_node_child,
379  const TNode* arg_node_ancestor) const
380  {
381  const TNode *child = arg_node_child;
382  if( NULL == child || NULL == arg_node_ancestor)
383  { return false; }
384 
385  while(NULL != child)
386  {
387  if(arg_node_ancestor == child)
388  { return true; }
389  child = child->parent_addr_;
390  }
391  return false;
392  }
393 
395  template <typename TIdx, typename TNode>
396  bool CMappedTree<TIdx,TNode>::isDescendant(const TIdx& arg_idx_parent,
397  const TIdx& arg_idx_descendant) const
398  { return isDescendant(this->at_const(arg_idx_parent), this->at_const(arg_idx_descendant)); }
399 
401  template <typename TIdx, typename TNode>
402  bool CMappedTree<TIdx,TNode>::isDescendant(const TNode* arg_node_parent,
403  const TNode* arg_node_descendant) const
404  {
405  const TNode *parent = arg_node_parent;
406  if( NULL == parent || NULL == arg_node_descendant)
407  { return false; }
408 
409  if(NULL != parent)
410  {
411  if(arg_node_descendant == parent)
412  { return true; }
413 
414  typename std::vector<TNode*>::const_iterator it,ite;
415  for(it = parent->child_addrs_.begin(), ite = parent->child_addrs_.end(); it!=ite; ++it)
416  {
417  if(isDescendant(*it, arg_node_descendant))
418  { return true; }
419  }
420  }
421  return false;
422  }
423 
424 }//End of namespace sutil
425 
426 #endif /*CMAPPEDTREE_HPP_*/
virtual TNode * create(const TIdx &arg_idx, const TNode &arg_node2add, const bool arg_is_root_)
Definition: CMappedTree.hpp:229
virtual bool deepCopy(const CMappedTree< TIdx, TNode > *arg_mt)
Definition: CMappedTree.hpp:204
Definition: CMappedTree.hpp:155
SMTNodeBase()
Definition: CMappedTree.hpp:168
virtual bool isAncestor(const TIdx &arg_idx_child, const TIdx &arg_idx_ancestor) const
Definition: CMappedTree.hpp:372
TNode * parent_addr_
Definition: CMappedTree.hpp:163
TNode * root_node_
Definition: CMappedTree.hpp:70
CMappedTree()
Definition: CMappedTree.hpp:186
virtual CMappedTree< TIdx, TNode > & operator=(const CMappedTree< TIdx, TNode > &arg_rhs)
Definition: CMappedTree.hpp:90
Definition: CMappedList.hpp:85
virtual bool deepCopy(const CMappedList< Idx, T > *const arg_pmap)
Definition: CMappedList.hpp:572
virtual TNode * insert(const TIdx &arg_idx, TNode *arg_node2add, const bool arg_is_root_)
Definition: CMappedTree.hpp:287
bool has_been_init_
Definition: CMappedTree.hpp:73
virtual bool linkNodes()
Definition: CMappedTree.hpp:316
virtual T * at(const std::size_t arg_idx)
Definition: CMappedList.hpp:832
TIdx parent_name_
Definition: CMappedTree.hpp:161
Definition: CMappedTree.hpp:66
TIdx name_
Definition: CMappedTree.hpp:159
virtual TNode * getRootNode()
Definition: CMappedTree.hpp:132
virtual T * create(const Idx &arg_idx, const bool insert_at_start=true)
Definition: CMappedList.hpp:714
std::vector< TNode * > child_addrs_
Definition: CMappedTree.hpp:165
virtual const TNode * getRootNodeConst() const
Definition: CMappedTree.hpp:128
virtual bool isDescendant(const TIdx &arg_idx_parent, const TIdx &arg_idx_descendant) const
Definition: CMappedTree.hpp:396
virtual ~CMappedTree()
Definition: CMappedTree.hpp:199