same_fringe.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // Copyright Nat Goodspeed 2013.
  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. #include <boost/coroutine/all.hpp>
  6. #include <cstddef>
  7. #include <cstdlib>
  8. #include <iostream>
  9. #include <iterator>
  10. #include <string>
  11. #include <utility>
  12. #include <boost/bind.hpp>
  13. #include <boost/range.hpp>
  14. #include <boost/shared_ptr.hpp>
  15. struct node
  16. {
  17. typedef boost::shared_ptr< node > ptr_t;
  18. // Each tree node has an optional left subtree, an optional right subtree
  19. // and a value of its own. The value is considered to be between the left
  20. // subtree and the right.
  21. ptr_t left, right;
  22. std::string value;
  23. // construct leaf
  24. node(const std::string& v):
  25. left(), right(), value(v)
  26. {}
  27. // construct nonleaf
  28. node(ptr_t l, const std::string& v, ptr_t r):
  29. left(l), right(r), value(v)
  30. {}
  31. static ptr_t create(const std::string& v)
  32. {
  33. return ptr_t(new node(v));
  34. }
  35. static ptr_t create(ptr_t l, const std::string& v, ptr_t r)
  36. {
  37. return ptr_t(new node(l, v, r));
  38. }
  39. };
  40. node::ptr_t create_left_tree_from(const std::string& root)
  41. {
  42. /* --------
  43. root
  44. / \
  45. b e
  46. / \
  47. a c
  48. -------- */
  49. return node::create(
  50. node::create(
  51. node::create("a"),
  52. "b",
  53. node::create("c")),
  54. root,
  55. node::create("e"));
  56. }
  57. node::ptr_t create_right_tree_from(const std::string& root)
  58. {
  59. /* --------
  60. root
  61. / \
  62. a d
  63. / \
  64. c e
  65. -------- */
  66. return node::create(
  67. node::create("a"),
  68. root,
  69. node::create(
  70. node::create("c"),
  71. "d",
  72. node::create("e")));
  73. }
  74. // recursively walk the tree, delivering values in order
  75. void traverse(node::ptr_t n,boost::coroutines::asymmetric_coroutine<std::string>::push_type& out)
  76. {
  77. if (n->left) traverse(n->left,out);
  78. out(n->value);
  79. if (n->right) traverse(n->right,out);
  80. }
  81. int main()
  82. {
  83. {
  84. node::ptr_t left_d(create_left_tree_from("d"));
  85. boost::coroutines::asymmetric_coroutine<std::string>::pull_type left_d_reader(
  86. boost::bind(traverse, left_d, _1));
  87. std::cout << "left tree from d:\n";
  88. std::copy(boost::begin(left_d_reader),
  89. boost::end(left_d_reader),
  90. std::ostream_iterator<std::string>(std::cout, " "));
  91. std::cout << std::endl;
  92. node::ptr_t right_b(create_right_tree_from("b"));
  93. boost::coroutines::asymmetric_coroutine<std::string>::pull_type right_b_reader(
  94. boost::bind(traverse, right_b, _1));
  95. std::cout << "right tree from b:\n";
  96. std::copy(boost::begin(right_b_reader),
  97. boost::end(right_b_reader),
  98. std::ostream_iterator<std::string>(std::cout, " "));
  99. std::cout << std::endl;
  100. node::ptr_t right_x(create_right_tree_from("x"));
  101. boost::coroutines::asymmetric_coroutine<std::string>::pull_type right_x_reader(
  102. boost::bind(traverse, right_x, _1));
  103. std::cout << "right tree from x:\n";
  104. std::copy(boost::begin(right_x_reader),
  105. boost::end(right_x_reader),
  106. std::ostream_iterator<std::string>(std::cout, " "));
  107. std::cout << std::endl;
  108. }
  109. {
  110. node::ptr_t left_d(create_left_tree_from("d"));
  111. boost::coroutines::asymmetric_coroutine<std::string>::pull_type left_d_reader(
  112. boost::bind(traverse, left_d, _1));
  113. node::ptr_t right_b(create_right_tree_from("b"));
  114. boost::coroutines::asymmetric_coroutine<std::string>::pull_type right_b_reader(
  115. boost::bind(traverse, right_b, _1));
  116. std::cout << "left tree from d == right tree from b? "
  117. << std::boolalpha
  118. << std::equal(boost::begin(left_d_reader),
  119. boost::end(left_d_reader),
  120. boost::begin(right_b_reader))
  121. << std::endl;
  122. }
  123. {
  124. node::ptr_t left_d(create_left_tree_from("d"));
  125. boost::coroutines::asymmetric_coroutine<std::string>::pull_type left_d_reader(
  126. boost::bind(traverse, left_d, _1));
  127. node::ptr_t right_x(create_right_tree_from("x"));
  128. boost::coroutines::asymmetric_coroutine<std::string>::pull_type right_x_reader(
  129. boost::bind(traverse, right_x, _1));
  130. std::cout << "left tree from d == right tree from x? "
  131. << std::boolalpha
  132. << std::equal(boost::begin(left_d_reader),
  133. boost::end(left_d_reader),
  134. boost::begin(right_x_reader))
  135. << std::endl;
  136. }
  137. std::cout << "Done" << std::endl;
  138. return EXIT_SUCCESS;
  139. }