• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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