|
libpsynth 0.2.1
|
00001 00012 /* 00013 * Copyright (C) 2008, 2009 Juan Pedro BolĂvar Puente 00014 * 00015 * This program is free software: you can redistribute it and/or modify 00016 * it under the terms of the GNU General Public License as published by 00017 * the Free Software Foundation, either version 3 of the License, or 00018 * (at your option) any later version. 00019 * 00020 * This program is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * You should have received a copy of the GNU General Public License 00026 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00027 * 00028 */ 00029 00030 #ifndef PSYNTH_TREE_H 00031 #define PSYNTH_TREE_H 00032 00033 #include <map> 00034 #include <unordered_map> 00035 #include <typeinfo> 00036 00037 #include <psynth/base/iterator.hpp> 00038 #include <psynth/base/pointer.hpp> 00039 #include <psynth/base/exception.hpp> 00040 #include <psynth/base/threads.hpp> 00041 00042 namespace psynth 00043 { 00044 namespace base 00045 { 00046 00051 template <typename Key> 00052 struct tree_node_traits 00053 { 00055 typedef typename Key::value_type value_type; 00056 00058 static const value_type separator = value_type (); 00059 }; 00060 00061 template <> 00062 struct tree_node_traits<std::string> 00063 { 00064 typedef char value_type; 00065 static const char separator = '.'; 00066 }; 00067 00071 PSYNTH_DECLARE_ERROR(error, tree_node_error); 00072 00097 template <class Node, 00098 class Key = std::string, 00099 class Traits = tree_node_traits<Key>, 00100 class ThreadingPolicy = PSYNTH_DEFAULT_THREADING <Node> > 00101 class tree_node 00102 { 00103 public: 00107 typedef std::unique_ptr<Node> node_ptr; 00108 00112 typedef ptr_iterator<map_iterator<Key, node_ptr > > iterator; 00113 00117 typedef ptr_const_iterator<map_const_iterator<Key, std::unique_ptr<Node> > > 00118 const_iterator; 00119 00123 typedef Traits traits; 00124 00126 tree_node () : 00127 _parent(NULL), _isinit(false) 00128 { 00129 }; 00130 00132 ~tree_node (); 00133 00138 iterator begin () 00139 { 00140 return _childs.begin(); 00141 } 00142 00147 const_iterator begin () const 00148 { 00149 return _childs.begin (); 00150 } 00151 00156 iterator end () 00157 { 00158 return _childs.end (); 00159 } 00160 00165 const_iterator end () const 00166 { 00167 return _childs.end (); 00168 } 00169 00174 const Node* parent () const 00175 { 00176 tree_lock lock (this); 00177 return _parent; 00178 } 00179 00184 Node* parent () 00185 { 00186 tree_lock lock (this); 00187 return _parent; 00188 } 00189 00193 const Key& name () const 00194 { 00195 tree_lock lock (this); 00196 return _name; 00197 } 00198 00203 iterator find_child (const Key& name) 00204 { 00205 tree_lock lock (this); 00206 return _childs.find (name); 00207 } 00208 00213 const_iterator find_child (const Key& name) const 00214 { 00215 tree_lock lock (this); 00216 return _childs.find (name); 00217 } 00218 00226 node_ptr detach (const Key& name) 00227 { 00228 tree_lock lock (this); 00229 return detach (_childs.find (name)); 00230 } 00231 00236 iterator remove_child (const Key& name) 00237 { 00238 tree_lock lock (this); 00239 return remove_child (_childs.find (name)); 00240 } 00241 00249 bool attach (const Key& name, node_ptr node); 00250 00259 node_ptr detach (iterator iter); 00260 00264 Key path_name () const; 00265 00271 iterator remove_child (iterator iter); 00272 00276 void clear_childs (); 00277 00283 Node& child (const Key& name); 00284 00290 Node& existing_child (const Key& name); 00291 00292 00298 const Node& existing_child (const Key& name) const; 00299 00304 Node& path (const Key& name); 00305 00311 Node& existing_path (const Key& name); 00312 00318 const Node& existing_path (const Key& name) const; 00319 00320 protected: 00321 virtual void on_new_child (Node& node) {} 00322 virtual void on_remove_child (Node& node) {} 00323 virtual void on_init () {} 00324 virtual void on_uninit () {} 00325 00326 private: 00327 typedef std::map<Key, std::unique_ptr<Node>> child_map; 00328 00329 child_map _childs; 00330 Node* _parent; 00331 Key _name; 00332 bool _isinit; 00333 00334 template <typename InputIterator> 00335 static void find_base (InputIterator& base_b, InputIterator& base_e); 00336 00337 const Node& 00338 existing_path (typename Key::const_iterator begin, 00339 typename Key::const_iterator end) const; 00340 00341 Node& 00342 existing_path (typename Key::const_iterator begin, 00343 typename Key::const_iterator end); 00344 00345 Node& path (typename Key::const_iterator begin, 00346 typename Key::const_iterator end); 00347 00348 void path_name (Key& prefix) const; 00349 00350 bool is_init() const 00351 { 00352 return _isinit; 00353 } 00354 00355 void init (const Key& name, Node* parent) 00356 { 00357 _isinit = true; 00358 _name = name; 00359 _parent = parent; 00360 on_init (); 00361 } 00362 00363 void uninit () 00364 { 00365 if (_isinit) { 00366 _isinit = false; 00367 _name = Key (); 00368 _parent = 0; 00369 on_uninit (); 00370 } 00371 } 00372 00373 struct tree_lock : public ThreadingPolicy::lock 00374 { 00375 tree_lock (const tree_node* self) 00376 : ThreadingPolicy::lock (dynamic_cast<const Node*> (self)) 00377 {} 00378 }; 00379 }; 00380 00381 } /* namespace base */ 00382 } /* namespace psynth */ 00383 00384 #endif /* PSYNTH_TREE_H */
1.7.4