From bb1c49dfa484db080938cff6f8f70167c9026a1c Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 24 Jul 2007 19:26:47 +0000 Subject: Consistently rename all C++ files .cpp/.hpp. Fix (some) inclusion guard names to not clash with other libs. git-svn-id: http://svn.drobilla.net/lad/ingen@613 a436a847-0d15-0410-975c-d299462d15a1 --- src/libs/engine/Tree.hpp | 141 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 src/libs/engine/Tree.hpp (limited to 'src/libs/engine/Tree.hpp') diff --git a/src/libs/engine/Tree.hpp b/src/libs/engine/Tree.hpp new file mode 100644 index 00000000..c6e36926 --- /dev/null +++ b/src/libs/engine/Tree.hpp @@ -0,0 +1,141 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef TREE_H +#define TREE_H + +#include +#include +#include +#include +using std::string; + +template class Tree; + + +/** A node in a Tree. + */ +template +class TreeNode : public Raul::Deletable +{ +public: + TreeNode(const string& key) + : _parent(NULL), _left_child(NULL), _right_child(NULL), + _key(key), _node(NULL) {} + + TreeNode(const string& key, T n) + : _parent(NULL), _left_child(NULL), _right_child(NULL), + _key(key), _node(n) {} + + ~TreeNode() { + assert(_parent == NULL || _parent->left_child() != this); + assert(_parent == NULL || _parent->right_child() != this); + assert(_left_child == NULL || _left_child->parent() != this); + assert(_right_child == NULL || _right_child->parent() != this); + _parent = _left_child = _right_child = NULL; + } + + string key() const { return _key; } + void key(const string& key) { _key = key; } + TreeNode* parent() const { return _parent; } + void parent(TreeNode* n) { _parent = n; } + TreeNode* left_child() const { return _left_child; } + void left_child(TreeNode* n) { _left_child = n; } + TreeNode* right_child() const { return _right_child; } + void right_child(TreeNode* n) { _right_child = n; } + + bool is_leaf() { return (_left_child == NULL && _right_child == NULL); } + bool is_left_child() { return (_parent != NULL && _parent->left_child() == this); } + bool is_right_child() { return (_parent != NULL && _parent->right_child() == this); } + + T node() { return _node; } + + friend class Tree; + +protected: + TreeNode* _parent; + TreeNode* _left_child; + TreeNode* _right_child; + string _key; + T _node; +}; + + +/** The tree all objects are stored in. + * + * Textbook naive (unbalanced) Binary Search Tree. Slightly different + * from a usual BST implementation in that the "Node" classes (TreeNode) are + * exposed to the user. This is so QueuedEvent's can create the TreeNode in + * another thread, and the realtime jack thread can insert them (without having + * to allocating a TreeNode which is a no-no). + * + * It's also a more annoying implementation because there's no leaf type (since + * a leaf object would have to be deleted on insert). + * + * Tree::iterator is not realtime safe, but the insert/remove/find methods + * of Tree do not use them. + */ +template +class Tree : boost::noncopyable +{ +public: + Tree() : _root(0), _size(0) {} + ~Tree(); + + void insert(TreeNode* const n); + TreeNode* remove(const string& key); + T find(const string& key) const; + TreeNode* find_treenode(const string& key) const; + + size_t size() const { return _size; } + + /** NON realtime safe iterator for a Tree. */ + class iterator + { + public: + iterator(const Tree* tree, size_t size); + ~iterator(); + + T operator*() const; + iterator& operator++(); + bool operator!=(const iterator& iter) const; + + friend class Tree; + + iterator(const iterator& copy); + iterator& operator=(const iterator& copy); + + private: + int _depth; + size_t _size; + TreeNode** _stack; + const Tree* _tree; + }; + + iterator begin() const; + iterator end() const; + +private: + TreeNode* _find_smallest(TreeNode* root); + TreeNode* _find_largest(TreeNode* root); + + TreeNode* _root; + size_t _size; +}; + + +#endif // TREE_H -- cgit v1.2.1