tree.hpp
Go to the documentation of this file.
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright 2016-2017 Davide Faconti
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of Willow Garage, Inc. nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 * *******************************************************************/
34 
35 
36 #ifndef STRINGTREE_H
37 #define STRINGTREE_H
38 
39 #include <vector>
40 #include <deque>
41 #include <iostream>
42 #include <memory>
43 
45 
46 namespace RosMsgParser {
47 
48 namespace details{
49 
53 template <typename T> class TreeNode
54 {
55 
56 public:
57 
58  typedef std::vector<TreeNode> ChildrenVector; // dangerous because of pointer invalidation (but faster)
59 
60  TreeNode(const TreeNode* parent );
61 
62  const TreeNode* parent() const { return _parent; }
63 
64  const T& value() const { return _value; }
65  void setValue( const T& value) { _value = value; }
66 
67  const ChildrenVector& children()const { return _children; }
68  ChildrenVector& children() { return _children; }
69 
70  const TreeNode* child(size_t index) const { return &(_children[index]); }
71  TreeNode* child(size_t index) { return &(_children[index]); }
72 
73  TreeNode *addChild(const T& child );
74 
75  bool isLeaf() const { return _children.empty(); }
76 
77 private:
78  const TreeNode* _parent = nullptr;
79  T _value;
80  ChildrenVector _children;
81 };
82 
83 
84 template <typename T> class Tree
85 {
86 public:
87  Tree(): _root( new TreeNode<T>(nullptr) ) {}
88 
94  template<typename Vect> const TreeNode<T>* find( const Vect& concatenated_values, bool partial_allowed = false);
95 
97  const TreeNode<T>* croot() const { return _root.get(); }
98 
100  TreeNode<T>* root() { return _root.get(); }
101 
102 
103  friend std::ostream& operator<<(std::ostream& os, const Tree& _this){
104  _this.print_impl(os, _this.croot() , 0);
105  return os;
106  }
107 
108  template <class Functor>
109  void visit(Functor& func, const TreeNode<T>* node) const
110  {
111  func(node);
112  for(auto child: node->children())
113  {
114  visit(func, &child);
115  }
116  }
117 
118 private:
119 
120  void print_impl(std::ostream& os, const TreeNode<T> *node, int indent ) const;
121 
122  std::unique_ptr<TreeNode<T>> _root;
123 };
124 
125 //-----------------------------------------
126 
127 
128 template <typename T> inline
129 std::ostream& operator<<(std::ostream &os, const std::pair<const TreeNode<T>*, const TreeNode<T>* >& tail_head )
130 {
131  const TreeNode<T>* tail = tail_head.first;
132  const TreeNode<T>* head = tail_head.second;
133 
134  if( !head ) return os;
135 
136  const TreeNode<T>* array[64];
137  int index = 0;
138  array[index++] = head;
139 
140  while( !head || head != tail)
141  {
142  head = head->parent();
143  array[index++] = head;
144  };
145  array[index] = nullptr;
146  index--;
147 
148  while ( index >=0)
149  {
150  if( array[index] ){
151  os << array[index]->value();
152  }
153  if( index >0 ) os << ".";
154  index--;
155  }
156  return os;
157 }
158 
159 template <typename T> inline
160 void Tree<T>::print_impl(std::ostream &os, const TreeNode<T>* node, int indent) const
161 {
162  for (int i=0; i<indent; i++) os << " ";
163  os << node->value() << std::endl;
164 
165  for (const auto& child: node->children() )
166  {
167  print_impl(os, &child, indent+3);
168  }
169 }
170 
171 template <typename T> inline
173  _parent(parent)
174 {
175 
176 }
177 
178 template <typename T> inline
180 {
181  assert(_children.capacity() > _children.size() );
182  _children.emplace_back( this );
183  _children.back().setValue( value );
184  return &_children.back();
185 }
186 
187 
188 template <typename T> template<typename Vect> inline
189 const TreeNode<T> *Tree<T>::find(const Vect& concatenated_values, bool partial_allowed )
190 {
191  TreeNode<T>* node = &_root;
192 
193  for (const auto& value: concatenated_values)
194  {
195  bool found = false;
196  for (auto& child: (node->children() ) )
197  {
198  if( child.value() == value)
199  {
200  node = &(child);
201  found = true;
202  break;
203  }
204  }
205  if( !found ) return nullptr;
206  }
207 
208  if( partial_allowed || node->children().empty() )
209  {
210  return node;
211  }
212  return nullptr;
213 }
214 
215 }
216 
217 }
218 
219 
220 
221 #endif // STRINGTREE_H
void visit(Functor &func, const TreeNode< T > *node) const
Definition: tree.hpp:109
#define nullptr
Definition: backward.hpp:386
const TreeNode< T > * find(const Vect &concatenated_values, bool partial_allowed=false)
Definition: tree.hpp:189
const TreeNode * _parent
Definition: tree.hpp:78
const TreeNode * child(size_t index) const
Definition: tree.hpp:70
#define assert(condition)
Definition: lz4.c:245
friend std::ostream & operator<<(std::ostream &os, const Tree &_this)
Definition: tree.hpp:103
void setValue(const T &value)
Definition: tree.hpp:65
const ChildrenVector & children() const
Definition: tree.hpp:67
ChildrenVector & children()
Definition: tree.hpp:68
TreeNode * addChild(const T &child)
Definition: tree.hpp:179
const TreeNode< T > * croot() const
Constant pointer to the root of the tree.
Definition: tree.hpp:97
TreeNode(const TreeNode *parent)
Definition: tree.hpp:172
TreeNode * child(size_t index)
Definition: tree.hpp:71
TreeNode< T > * root()
Mutable pointer to the root of the tree.
Definition: tree.hpp:100
Definition: core.h:1131
std::unique_ptr< TreeNode< T > > _root
Definition: tree.hpp:122
std::vector< TreeNode > ChildrenVector
Definition: tree.hpp:58
void print_impl(std::ostream &os, const TreeNode< T > *node, int indent) const
Definition: tree.hpp:160
ChildrenVector _children
Definition: tree.hpp:80
const TreeNode * parent() const
Definition: tree.hpp:62
Element of the tree. it has a single parent and N >= 0 children.
Definition: tree.hpp:53
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr &out) -> bool
Definition: core.h:2089
const T & value() const
Definition: tree.hpp:64


plotjuggler
Author(s): Davide Faconti
autogenerated on Mon Jun 19 2023 03:12:53