mirror of
https://github.com/boostorg/poly_collection.git
synced 2026-01-19 16:32:14 +00:00
* added variant_collection
* added variant_collection
* avoided &* on null pointers
* made (non-public) fixed_variant ctor explicit
* tested higher-arity visit
* implemented visit<void>
* fixed {boost::variant2|std}::variant insertion
* fixed lookup issues with invoke_visit
* removed unneeded constexpr qualifiers
* s/typeid_/index
* reverted c6bc62f6d2 as Clang 5.0 didnt seem to like it
* reinstated c6bc62f6d2
* dropped -std=c++1z for Clang 5.0
* updated docs and examples
* added boost::poly_collection::visit_by_index
* typo
* explicit cted tuple in make_iota_tuple
* changed function name to see if it helps with mangling-related Clang 3.8 ICE
* rewritten make_iota_tuple to try to make Clang 3.8 happier
* added boost::variant_collection_of
207 lines
5.2 KiB
C++
207 lines
5.2 KiB
C++
/* Copyright 2016-2024 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/poly_collection/variant_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;
|
|
}
|
|
|
|
template<typename... Ts>
|
|
struct overloaded:Ts...{using Ts::operator()...;};
|
|
template<class... Ts>
|
|
overloaded(Ts...)->overloaded<Ts...>;
|
|
|
|
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";
|
|
//]
|
|
|
|
{
|
|
//[algorithms_9
|
|
boost::variant_collection<
|
|
boost::mp11::mp_list<warrior,juggernaut,goblin,elf,std::string,window>
|
|
> c;
|
|
//= ...
|
|
//<-
|
|
c.insert(warrior(0));
|
|
c.insert(std::string("play again"));
|
|
c.insert(window("player one"));
|
|
//->
|
|
|
|
auto print_sprite=[](const sprite& s) { s.render(std::cout); };
|
|
auto print_string=[](const std::string& str){ std::cout<<str; };
|
|
auto print_window=[](const window& w) { w.display(std::cout); };
|
|
auto print=overloaded{print_sprite,print_string,print_window};
|
|
|
|
const char* comma="";
|
|
boost::poly_collection::for_each<boost::poly_collection::all_types>(
|
|
c.begin(),c.end(),[&](const auto& r){
|
|
std::cout<<comma;
|
|
print(r);
|
|
comma=",";
|
|
});
|
|
std::cout<<"\n";
|
|
|
|
//]
|
|
}
|
|
}
|