same_fringe.cpp 5.5 KB

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