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