poly_collection/example/algorithms.cpp
2017-11-16 14:50:19 +01:00

172 lines
4.2 KiB
C++

/* Copyright 2016-2017 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/poly_collection for library home page.
*/
/* Boost.PolyCollection algorithms */
#include <algorithm>
#include <boost/poly_collection/algorithm.hpp>
#include <boost/poly_collection/any_collection.hpp>
#include <boost/poly_collection/base_collection.hpp>
#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/any_cast.hpp>
#include <boost/type_erasure/builtin.hpp>
#include <boost/type_erasure/operators.hpp>
#include <boost/type_erasure/typeid_of.hpp>
#include <random>
#include "rolegame.hpp"
std::ostream& operator<<(std::ostream& os,const sprite& s)
{
s.render(os);
return os;
}
std::ostream& operator<<(std::ostream& os,const window& w)
{
w.display(os);
return os;
}
int main()
{
boost::base_collection<sprite> c;
// populate c
std::mt19937 gen{92748}; // some arbitrary random seed
std::discrete_distribution<> rnd{{1,1,1}};
for(int i=0;i<8;++i){ // assign each type with 1/3 probability
switch(rnd(gen)){
case 0: c.insert(warrior{i});break;
case 1: c.insert(juggernaut{i});break;
case 2: c.insert(goblin{i});break;
}
}
auto render1=[](const boost::base_collection<sprite>& c){
//[algorithms_1
const char* comma="";
std::for_each(c.begin(),c.end(),[&](const sprite& s){
std::cout<<comma;
s.render(std::cout);
comma=",";
});
std::cout<<"\n";
//]
};
render1(c);
auto render2=[](const boost::base_collection<sprite>& c){
//[algorithms_2
const char* comma="";
for(auto seg_info:c.segment_traversal()){
for(const sprite& s:seg_info){
std::cout<<comma;
s.render(std::cout);
comma=",";
}
}
std::cout<<"\n";
//]
};
render2(c);
auto render3=[](const boost::base_collection<sprite>& c){
//[algorithms_3
//= #include <boost/poly_collection/algorithm.hpp>
//= ...
//=
const char* comma="";
boost::poly_collection::for_each(c.begin(),c.end(),[&](const sprite& s){
std::cout<<comma;
s.render(std::cout);
comma=",";
});
std::cout<<"\n";
//]
};
render3(c);
//[algorithms_4
auto n=boost::poly_collection::count_if(
c.begin(),c.end(),[](const sprite& s){return s.id%2==0;});
std::cout<<n<<" sprites with even id\n";
//]
using renderable=boost::type_erasure::ostreamable<>;
using standalone_renderable=boost::mpl::vector<
renderable,
boost::type_erasure::copy_constructible<>,
boost::type_erasure::typeid_<>
>;
{
//[algorithms_5
sprite* ps=new warrior{5};
// sprite -> warrior
warrior* pw=static_cast<warrior*>(ps);
//<-
(void)pw;
delete ps;
//->
//<-
boost::type_erasure::any<standalone_renderable> r=std::string{"hello"};
//->
//= boost::type_erasure::any<renderable> r=std::string{"hello"};
// renderable -> std::string
std::string& str=boost::type_erasure::any_cast<std::string&>(r);
//]
//[algorithms_6
// render r with std::string restitution
if(boost::type_erasure::typeid_of(r)==typeid(std::string)){
std::string& str=boost::type_erasure::any_cast<std::string&>(r);
std::cout<<str<<"\n";
}
else{
std::cout<<r<<"\n";
}
//]
}
auto& bc=c;
{
boost::any_collection<renderable> c;
c.insert(bc.begin<warrior>(),bc.end<warrior>());
c.insert(bc.begin<juggernaut>(),bc.end<juggernaut>());
c.insert(bc.begin<goblin>(),bc.end<goblin>());
c.insert(std::string{"\"stamina: 10,000\""});
c.insert(std::string{"\"game over\""});
c.insert(window{"pop-up 1"});
c.insert(window{"pop-up 2"});
//[algorithms_7
const char* comma="";
boost::poly_collection::for_each
<warrior,juggernaut,goblin>( // restituted types
c.begin(),c.end(),[&](const auto& x){ // loop traverses *all* elements
std::cout<<comma<<x;
comma=",";
});
std::cout<<"\n";
//]
}
//[algorithms_8
const char* comma="";
boost::poly_collection::for_each<warrior,juggernaut,goblin>(
c.begin(),c.end(),[&](const auto& s){
std::cout<<comma;
s.render(std::cout);
comma=",";
});
std::cout<<"\n";
//]
}