tree.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // Copyright Oliver Kowalke 2009.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef TREE_H
  6. #define TREE_H
  7. #include <boost/coroutine/all.hpp>
  8. #include <cstddef>
  9. #include <string>
  10. #include <boost/assert.hpp>
  11. #include <boost/config.hpp>
  12. #include <boost/intrusive_ptr.hpp>
  13. #if defined(_MSC_VER)
  14. # pragma warning(push)
  15. # pragma warning(disable:4355)
  16. #endif
  17. struct branch;
  18. struct leaf;
  19. struct visitor
  20. {
  21. virtual ~visitor() {};
  22. virtual void visit( branch & b) = 0;
  23. virtual void visit( leaf & l) = 0;
  24. };
  25. struct node
  26. {
  27. typedef boost::intrusive_ptr< node > ptr_t;
  28. std::size_t use_count;
  29. node() :
  30. use_count( 0)
  31. {}
  32. virtual ~node() {}
  33. virtual void accept( visitor & v) = 0;
  34. friend inline void intrusive_ptr_add_ref( node * p)
  35. { ++p->use_count; }
  36. friend inline void intrusive_ptr_release( node * p)
  37. { if ( 0 == --p->use_count) delete p; }
  38. };
  39. struct branch : public node
  40. {
  41. node::ptr_t left;
  42. node::ptr_t right;
  43. static ptr_t create( node::ptr_t left_, node::ptr_t right_)
  44. { return ptr_t( new branch( left_, right_) ); }
  45. branch( node::ptr_t left_, node::ptr_t right_) :
  46. left( left_), right( right_)
  47. {}
  48. void accept( visitor & v)
  49. { v.visit( * this); }
  50. };
  51. struct leaf : public node
  52. {
  53. std::string value;
  54. static ptr_t create( std::string const& value_)
  55. { return ptr_t( new leaf( value_) ); }
  56. leaf( std::string const& value_) :
  57. value( value_)
  58. {}
  59. void accept( visitor & v)
  60. { v.visit( * this); }
  61. };
  62. inline
  63. bool operator==( leaf const& l, leaf const& r)
  64. { return l.value == r.value; }
  65. inline
  66. bool operator!=( leaf const& l, leaf const& r)
  67. { return l.value != r.value; }
  68. class tree_visitor : public visitor
  69. {
  70. private:
  71. boost::coroutines::asymmetric_coroutine< leaf & >::push_type & c_;
  72. public:
  73. tree_visitor( boost::coroutines::asymmetric_coroutine< leaf & >::push_type & c) :
  74. c_( c)
  75. {}
  76. void visit( branch & b)
  77. {
  78. if ( b.left) b.left->accept( * this);
  79. if ( b.right) b.right->accept( * this);
  80. }
  81. void visit( leaf & l)
  82. { c_( l); }
  83. };
  84. void enumerate_leafs( boost::coroutines::asymmetric_coroutine< leaf & >::push_type & c, node::ptr_t root)
  85. {
  86. tree_visitor v( c);
  87. root->accept( v);
  88. }
  89. #if defined(_MSC_VER)
  90. # pragma warning(pop)
  91. #endif
  92. #endif // TREE_H