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
23std::ostream& operator<<(std::ostream& os,const sprite& s)
24{
25 s.render(os);
26 return os;
27}
28
29std::ostream& operator<<(std::ostream& os,const window& w)
30{
31 w.display(os);
32 return os;
33}
34
35int 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(x: warrior{i});break;
46 case 1: c.insert(x: juggernaut{i});break;
47 case 2: c.insert(x: 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(first: c.begin(),last: c.end(),f: [&](const sprite& s){
55 std::cout<<comma;
56 s.render(os&: 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(os&: 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(first: c.begin(),last: c.end(),f: [&](const sprite& s){
86 std::cout<<comma;
87 s.render(os&: 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 first: c.begin(),last: c.end(),pred: [](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&>(arg&: r);
124//]
125
126//[algorithms_6
127 // render r with std::string restitution
128 if(boost::type_erasure::typeid_of(arg: r)==typeid(std::string)){
129 std::string& str=boost::type_erasure::any_cast<std::string&>(arg&: 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(first: bc.begin<warrior>(),last: bc.end<warrior>());
142 c.insert(first: bc.begin<juggernaut>(),last: bc.end<juggernaut>());
143 c.insert(first: bc.begin<goblin>(),last: bc.end<goblin>());
144 c.insert(x: std::string{"\"stamina: 10,000\""});
145 c.insert(x: std::string{"\"game over\""});
146 c.insert(x: window{"pop-up 1"});
147 c.insert(x: 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 first: c.begin(),last: c.end(),f: [&](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 first: c.begin(),last: c.end(),f: [&](const auto& s){
165 std::cout<<comma;
166 s.render(std::cout);
167 comma=",";
168 });
169 std::cout<<"\n";
170//]
171}
172

source code of boost/libs/poly_collection/example/algorithms.cpp