algorithms.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /* Copyright 2016-2017 Joaquin M Lopez Munoz.
  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. *
  6. * See http://www.boost.org/libs/poly_collection for library home page.
  7. */
  8. /* Boost.PolyCollection algorithms */
  9. #include <algorithm>
  10. #include <boost/poly_collection/algorithm.hpp>
  11. #include <boost/poly_collection/any_collection.hpp>
  12. #include <boost/poly_collection/base_collection.hpp>
  13. #include <boost/type_erasure/any.hpp>
  14. #include <boost/type_erasure/any_cast.hpp>
  15. #include <boost/type_erasure/builtin.hpp>
  16. #include <boost/type_erasure/operators.hpp>
  17. #include <boost/type_erasure/typeid_of.hpp>
  18. #include <random>
  19. #include "rolegame.hpp"
  20. std::ostream& operator<<(std::ostream& os,const sprite& s)
  21. {
  22. s.render(os);
  23. return os;
  24. }
  25. std::ostream& operator<<(std::ostream& os,const window& w)
  26. {
  27. w.display(os);
  28. return os;
  29. }
  30. int main()
  31. {
  32. boost::base_collection<sprite> c;
  33. // populate c
  34. std::mt19937 gen{92748}; // some arbitrary random seed
  35. std::discrete_distribution<> rnd{{1,1,1}};
  36. for(int i=0;i<8;++i){ // assign each type with 1/3 probability
  37. switch(rnd(gen)){
  38. case 0: c.insert(warrior{i});break;
  39. case 1: c.insert(juggernaut{i});break;
  40. case 2: c.insert(goblin{i});break;
  41. }
  42. }
  43. auto render1=[](const boost::base_collection<sprite>& c){
  44. //[algorithms_1
  45. const char* comma="";
  46. std::for_each(c.begin(),c.end(),[&](const sprite& s){
  47. std::cout<<comma;
  48. s.render(std::cout);
  49. comma=",";
  50. });
  51. std::cout<<"\n";
  52. //]
  53. };
  54. render1(c);
  55. auto render2=[](const boost::base_collection<sprite>& c){
  56. //[algorithms_2
  57. const char* comma="";
  58. for(auto seg_info:c.segment_traversal()){
  59. for(const sprite& s:seg_info){
  60. std::cout<<comma;
  61. s.render(std::cout);
  62. comma=",";
  63. }
  64. }
  65. std::cout<<"\n";
  66. //]
  67. };
  68. render2(c);
  69. auto render3=[](const boost::base_collection<sprite>& c){
  70. //[algorithms_3
  71. //= #include <boost/poly_collection/algorithm.hpp>
  72. //= ...
  73. //=
  74. const char* comma="";
  75. boost::poly_collection::for_each(c.begin(),c.end(),[&](const sprite& s){
  76. std::cout<<comma;
  77. s.render(std::cout);
  78. comma=",";
  79. });
  80. std::cout<<"\n";
  81. //]
  82. };
  83. render3(c);
  84. //[algorithms_4
  85. auto n=boost::poly_collection::count_if(
  86. c.begin(),c.end(),[](const sprite& s){return s.id%2==0;});
  87. std::cout<<n<<" sprites with even id\n";
  88. //]
  89. using renderable=boost::type_erasure::ostreamable<>;
  90. using standalone_renderable=boost::mpl::vector<
  91. renderable,
  92. boost::type_erasure::copy_constructible<>,
  93. boost::type_erasure::typeid_<>
  94. >;
  95. {
  96. //[algorithms_5
  97. sprite* ps=new warrior{5};
  98. // sprite -> warrior
  99. warrior* pw=static_cast<warrior*>(ps);
  100. //<-
  101. (void)pw;
  102. delete ps;
  103. //->
  104. //<-
  105. boost::type_erasure::any<standalone_renderable> r=std::string{"hello"};
  106. //->
  107. //= boost::type_erasure::any<renderable> r=std::string{"hello"};
  108. // renderable -> std::string
  109. std::string& str=boost::type_erasure::any_cast<std::string&>(r);
  110. //]
  111. //[algorithms_6
  112. // render r with std::string restitution
  113. if(boost::type_erasure::typeid_of(r)==typeid(std::string)){
  114. std::string& str=boost::type_erasure::any_cast<std::string&>(r);
  115. std::cout<<str<<"\n";
  116. }
  117. else{
  118. std::cout<<r<<"\n";
  119. }
  120. //]
  121. }
  122. auto& bc=c;
  123. {
  124. boost::any_collection<renderable> c;
  125. c.insert(bc.begin<warrior>(),bc.end<warrior>());
  126. c.insert(bc.begin<juggernaut>(),bc.end<juggernaut>());
  127. c.insert(bc.begin<goblin>(),bc.end<goblin>());
  128. c.insert(std::string{"\"stamina: 10,000\""});
  129. c.insert(std::string{"\"game over\""});
  130. c.insert(window{"pop-up 1"});
  131. c.insert(window{"pop-up 2"});
  132. //[algorithms_7
  133. const char* comma="";
  134. boost::poly_collection::for_each
  135. <warrior,juggernaut,goblin>( // restituted types
  136. c.begin(),c.end(),[&](const auto& x){ // loop traverses *all* elements
  137. std::cout<<comma<<x;
  138. comma=",";
  139. });
  140. std::cout<<"\n";
  141. //]
  142. }
  143. //[algorithms_8
  144. const char* comma="";
  145. boost::poly_collection::for_each<warrior,juggernaut,goblin>(
  146. c.begin(),c.end(),[&](const auto& s){
  147. std::cout<<comma;
  148. s.render(std::cout);
  149. comma=",";
  150. });
  151. std::cout<<"\n";
  152. //]
  153. }