From 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 20:24:20 +0200 Subject: Adding upstream version 14.2.21. Signed-off-by: Daniel Baumann --- src/boost/libs/poly_collection/example/Jamfile.v2 | 49 ++ .../libs/poly_collection/example/algorithms.cpp | 171 ++++++ .../libs/poly_collection/example/basic_any.cpp | 73 +++ .../libs/poly_collection/example/basic_base.cpp | 59 ++ .../poly_collection/example/basic_function.cpp | 103 ++++ .../libs/poly_collection/example/exceptions.cpp | 62 +++ .../example/insertion_emplacement.cpp | 109 ++++ src/boost/libs/poly_collection/example/perf.cpp | 604 +++++++++++++++++++++ .../libs/poly_collection/example/rolegame.hpp | 78 +++ .../example/segmented_structure.cpp | 181 ++++++ 10 files changed, 1489 insertions(+) create mode 100644 src/boost/libs/poly_collection/example/Jamfile.v2 create mode 100644 src/boost/libs/poly_collection/example/algorithms.cpp create mode 100644 src/boost/libs/poly_collection/example/basic_any.cpp create mode 100644 src/boost/libs/poly_collection/example/basic_base.cpp create mode 100644 src/boost/libs/poly_collection/example/basic_function.cpp create mode 100644 src/boost/libs/poly_collection/example/exceptions.cpp create mode 100644 src/boost/libs/poly_collection/example/insertion_emplacement.cpp create mode 100644 src/boost/libs/poly_collection/example/perf.cpp create mode 100644 src/boost/libs/poly_collection/example/rolegame.hpp create mode 100644 src/boost/libs/poly_collection/example/segmented_structure.cpp (limited to 'src/boost/libs/poly_collection/example') diff --git a/src/boost/libs/poly_collection/example/Jamfile.v2 b/src/boost/libs/poly_collection/example/Jamfile.v2 new file mode 100644 index 00000000..9bd5760e --- /dev/null +++ b/src/boost/libs/poly_collection/example/Jamfile.v2 @@ -0,0 +1,49 @@ +# Copyright 2016-2017 Joaquín M López Muñoz. +# 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. + +project + : requirements + $(BOOST_ROOT) + 11 + ; + +exe algorithms + : algorithms.cpp + : 14 + ; + +exe basic_any + : basic_any.cpp + ; + +exe basic_base + : basic_base.cpp + ; + +exe basic_function + : basic_function.cpp + : 14 + ; + +exe exceptions + : exceptions.cpp + ; + +exe insertion_emplacement + : insertion_emplacement.cpp + ; + +exe perf + : perf.cpp + : + : release + ; + +exe segmented_structure + : segmented_structure.cpp + : 14 + ; diff --git a/src/boost/libs/poly_collection/example/algorithms.cpp b/src/boost/libs/poly_collection/example/algorithms.cpp new file mode 100644 index 00000000..30a7e09e --- /dev/null +++ b/src/boost/libs/poly_collection/example/algorithms.cpp @@ -0,0 +1,171 @@ +/* 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 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& c){ +//[algorithms_1 + const char* comma=""; + std::for_each(c.begin(),c.end(),[&](const sprite& s){ + std::cout<& c){ +//[algorithms_2 + const char* comma=""; + for(auto seg_info:c.segment_traversal()){ + for(const sprite& s:seg_info){ + std::cout<& c){ +//[algorithms_3 +//= #include +//= ... +//= + const char* comma=""; + boost::poly_collection::for_each(c.begin(),c.end(),[&](const sprite& s){ + std::cout<; + 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(ps); +//<- + (void)pw; + delete ps; +//-> + +//<- + boost::type_erasure::any r=std::string{"hello"}; +//-> +//= boost::type_erasure::any r=std::string{"hello"}; + // renderable -> std::string + std::string& str=boost::type_erasure::any_cast(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(r); + std::cout< c; + c.insert(bc.begin(),bc.end()); + c.insert(bc.begin(),bc.end()); + c.insert(bc.begin(),bc.end()); + 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 + ( // restituted types + c.begin(),c.end(),[&](const auto& x){ // loop traverses *all* elements + std::cout<( + c.begin(),c.end(),[&](const auto& s){ + std::cout< +#include +#include +#include "rolegame.hpp" + +//[basic_any_1 +std::ostream& operator<<(std::ostream& os,const sprite& s) +{ + s.render(os); + return os; +} + +// std::string already has a suitable operator<< + +std::ostream& operator<<(std::ostream& os,const window& w) +{ + w.display(os); + return os; +} +//] + +int main() +{ +//[basic_any_2 +//= #include +//= #include +//= ... +//= + using renderable=boost::type_erasure::ostreamable<>; + boost::any_collection c; +//] + +//[basic_any_3 + // populate with sprites + std::mt19937 gen{92748}; // some arbitrary random seed + std::discrete_distribution<> rnd{{1,1,1}}; + for(int i=0;i<4;++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; + } + } + + // populate with messages + c.insert(std::string{"\"stamina: 10,000\""}); + c.insert(std::string{"\"game over\""}); + + // populate with windows + c.insert(window{"pop-up 1"}); + c.insert(window{"pop-up 2"}); +//] + + +//[basic_any_4 + const char* comma=""; + for(const auto& r:c){ + std::cout< +#include +#include +#include "rolegame.hpp" + +int main() +{ +//[basic_base_1 +//= #include +//= ... +//= + boost::base_collection 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 render=[&](){ +//[basic_base_2 + const char* comma=""; + for(const sprite& s:c){ + std::cout< +#include +#include +#include +#include +#include "rolegame.hpp" + +int main() +{ +//[basic_function_1 + std::vector> sprs; + std::vector msgs; + std::vector wnds; +//] + + // populate sprs + std::mt19937 gen{92748}; // some arbitrary random seed + std::discrete_distribution<> rnd{{1,1,1}}; + for(int i=0;i<4;++i){ // assign each type with 1/3 probability + switch(rnd(gen)){ + case 0: sprs.push_back(std::make_unique(i));;break; + case 1: sprs.push_back(std::make_unique(i));break; + case 2: sprs.push_back(std::make_unique(i));break; + } + } + + // populate msgs + msgs.push_back("\"stamina: 10,000\""); + msgs.push_back("\"game over\""); + + // populate wnds + wnds.emplace_back("pop-up 1"); + wnds.emplace_back("pop-up 2"); + +//[basic_function_2 +//= #include +//= ... +//= + // function signature accepting std::ostream& and returning nothing + using render_callback=void(std::ostream&); + + boost::function_collection c; +//] + +//[basic_function_3 +//<- + auto render_sprite=[](const sprite& s){ +//-> +//= auto render_sprite(const sprite& s){ + return [&](std::ostream& os){s.render(os);}; + }/*<-*/;/*->*/ + +//<- + auto render_message=[](const std::string& m){ +//-> +//= auto render_message(const std::string& m){ + return [&](std::ostream& os){os<*/ + +//<- + auto render_window=[](const window& w){ +//-> +//= auto render_window(const window& w){ + return [&](std::ostream& os){w.display(os);}; + }/*<-*/;/*->*/ +//= ... +//= + for(const auto& ps:sprs)c.insert(render_sprite(*ps)); + for(const auto& m:msgs)c.insert(render_message(m)); + for(const auto& w:wnds)c.insert(render_window(w)); +//] + +//[basic_function_4 + const char* comma=""; + for(const auto& cbk:c){ + std::cout< f=cbk; + f(std::cout); // exactly the same +//] + +//[basic_function_6 +//= *c.begin()=render_message("last minute message"); // compile-time error +//] +} diff --git a/src/boost/libs/poly_collection/example/exceptions.cpp b/src/boost/libs/poly_collection/example/exceptions.cpp new file mode 100644 index 00000000..d5e946dc --- /dev/null +++ b/src/boost/libs/poly_collection/example/exceptions.cpp @@ -0,0 +1,62 @@ +/* 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 exceptions */ + +#include +#include +#include +#include +#include "rolegame.hpp" + +int main() +{ + boost::base_collection c,c2; + + // 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 render=[](const boost::base_collection& c){ + const char* comma=""; + for(const sprite& s:c){ + std::cout<(); // get rid of non-copyable elfs + c2=c; // now it works + // check that the two are indeed equal + std::cout<<(c==c2)<<"\n"; + // throws boost::poly_collection::not_equality_comparable +//] + }catch(boost::poly_collection::not_equality_comparable&){} +} diff --git a/src/boost/libs/poly_collection/example/insertion_emplacement.cpp b/src/boost/libs/poly_collection/example/insertion_emplacement.cpp new file mode 100644 index 00000000..a7beafb8 --- /dev/null +++ b/src/boost/libs/poly_collection/example/insertion_emplacement.cpp @@ -0,0 +1,109 @@ +/* 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. + */ + +/* examples of insertion and emplacement */ + +#include +#include +#include +#include +#include "rolegame.hpp" + +int main() +{ + boost::base_collection 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 render=[](const boost::base_collection& c){ + const char* comma=""; + for(const sprite& s:c){ + std::cout<()+2,juggernaut{10}); + // ^^ remember local iterators are random access +//] + render(c); + +//[insertion_emplacement_4] +//= c.insert(c.begin(typeid(warrior)),juggernaut{11}); // undefined behavior!! +//] + +//[insertion_emplacement_5] + boost::base_collection c2; + + c2.insert(c.begin(),c.end()); // read below +//<- + render(c2); +//-> + + // add some more warriors + std::array aw={{11,12,13}}; + c2.insert(aw.begin(),aw.end()); +//<- + render(c2); +//-> + + // add some goblins at the beginning of their segment + std::array ag={{14,15,16}}; + c2.insert(c2.begin(),ag.begin(),ag.end()); +//<- + render(c2); +//-> +//] + +//[insertion_emplacement_6] +//<- + // same as line at beginning of previous snippet +//-> + c2.insert(c.begin(),c.end()); +//] + +//[insertion_emplacement_7] +//= c.emplace(11); // does not compile +//] + +//[insertion_emplacement_8] + c.emplace(11); // now it works +//] + render(c); + +//[insertion_emplacement_9] + c.emplace_hint(c.begin(),12); // at the beginning if possible + c.emplace_pos(c.begin()+2,13); // amidst the goblins + c.emplace_pos(c.begin(typeid(warrior)),14); // local_base_iterator +//] + render(c); +} diff --git a/src/boost/libs/poly_collection/example/perf.cpp b/src/boost/libs/poly_collection/example/perf.cpp new file mode 100644 index 00000000..4d19a9f6 --- /dev/null +++ b/src/boost/libs/poly_collection/example/perf.cpp @@ -0,0 +1,604 @@ +/* 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 performance tests */ + +#include +#include +#include +#include +#include + +std::chrono::high_resolution_clock::time_point measure_start,measure_pause; + +template +double measure(F f) +{ + using namespace std::chrono; + + static const int num_trials=10; + static const milliseconds min_time_per_trial(200); + std::array trials; + volatile decltype(f()) res; /* to avoid optimizing f() away */ + + for(int i=0;i>(t2-measure_start).count()/runs; + } + (void)res; /* var not used warn */ + + std::sort(trials.begin(),trials.end()); + return std::accumulate( + trials.begin()+2,trials.end()-2,0.0)/(trials.size()-4); +} + +template +double measure(unsigned int n,F f) +{ + double t=measure(f); + return (t/n)*10E9; +} + +void pause_timing() +{ + measure_pause=std::chrono::high_resolution_clock::now(); +} + +void resume_timing() +{ + measure_start+=std::chrono::high_resolution_clock::now()-measure_pause; +} + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//[perf_base_types +struct base +{ + virtual ~base()=default; + virtual int operator()(int)const=0; +}; + +struct derived1 final:base +{ + derived1(int n):n{n}{} + virtual int operator()(int)const{return n;} + + int n; +}; + +struct derived2 final:base +{ + derived2(int n):n{n}{} + virtual int operator()(int x)const{return x*n;} + + int unused,n; +}; + +struct derived3 final:base +{ + derived3(int n):n{n}{} + virtual int operator()(int x)const{return x*x*n;} + + int unused,n; +}; +//] + +//[perf_function_types +struct concrete1 +{ + concrete1(int n):n{n}{} + int operator()(int)const{return n;} + + int n; +}; + +struct concrete2 +{ + concrete2(int n):n{n}{} + int operator()(int x)const{return x*n;} + + int unused,n; +}; + +struct concrete3 +{ + concrete3(int n):n{n}{} + int operator()(int x)const{return x*x*n;} + + int unused,n; +}; +//] + +template +struct ptr_vector:boost::ptr_vector +{ +public: + template + void insert(const T& x) + { + this->push_back(new T{x}); + } + + template + void for_each(F f) + { + std::for_each(this->begin(),this->end(),f); + } + + void prepare_for_for_each(){} +}; + +template +struct sorted_ptr_vector:ptr_vector +{ + void prepare_for_for_each() + { + std::sort( + this->c_array(),this->c_array()+this->size(), + [](Base* x,Base* y){return typeid(*x).before(typeid(*y));}); + } +}; + +template +struct shuffled_ptr_vector:ptr_vector +{ + void prepare_for_for_each() + { + std::shuffle( + this->c_array(),this->c_array()+this->size(),std::mt19937(1)); + } +}; + +template +struct base_collection:boost::base_collection +{ + template + void for_each(F f) + { + std::for_each(this->begin(),this->end(),f); + } + + void prepare_for_for_each(){} +}; + +template +struct poly_for_each_base_collection:base_collection +{ + template + void for_each(F f) + { + boost::poly_collection::for_each(this->begin(),this->end(),f); + } +}; + +template +struct func_vector:std::vector> +{ + template void insert(const T& x) + { + this->push_back(x); + } + + template + void for_each(F f) + { + std::for_each(this->begin(),this->end(),f); + } + + void prepare_for_for_each(){} +}; + +template +struct sorted_func_vector:func_vector +{ + void prepare_for_for_each() + { + using value_type=typename sorted_func_vector::value_type; + std::sort( + this->begin(),this->end(),[](const value_type& x,const value_type& y){ + return x.target_type().before(y.target_type()); + }); + } +}; + +template +struct shuffled_func_vector:func_vector +{ + void prepare_for_for_each() + { + std::shuffle(this->begin(),this->end(),std::mt19937(1)); + } +}; + +template +struct func_collection:boost::function_collection +{ + template + void for_each(F f) + { + std::for_each(this->begin(),this->end(),f); + } + + void prepare_for_for_each(){} +}; + +template +struct poly_for_each_func_collection:func_collection +{ + template + void for_each(F f) + { + boost::poly_collection::for_each(this->begin(),this->end(),f); + } +}; + +template +struct any_vector:std::vector> +{ + template void insert(const T& x) + { + this->push_back(x); + } + + template + void for_each(F f) + { + std::for_each(this->begin(),this->end(),f); + } + + void prepare_for_for_each(){} +}; + +template +struct sorted_any_vector:any_vector +{ + void prepare_for_for_each() + { + using value_type=typename sorted_any_vector::value_type; + std::sort( + this->begin(),this->end(),[](const value_type& x,const value_type& y){ + return typeid_of(x).before(typeid_of(y)); + }); + } +}; + +template +struct shuffled_any_vector:any_vector +{ + void prepare_for_for_each() + { + std::shuffle(this->begin(),this->end(),std::mt19937(1)); + } +}; + +template +struct any_collection:boost::any_collection +{ + template + void for_each(F f) + { + std::for_each(this->begin(),this->end(),f); + } + + void prepare_for_for_each(){} +}; + +template +struct poly_for_each_any_collection:any_collection +{ + template + void for_each(F f) + { + boost::poly_collection::for_each(this->begin(),this->end(),f); + } +}; + +#include + +template +void print(Printables... ps) +{ + const char* delim=""; + using seq=int[1+sizeof...(ps)]; + (void)seq{0,(std::cout< +struct label +{ + label(const char* str):str{str}{} + operator const char*()const{return str;} + const char* str; +}; + +template +struct element_sequence{}; + +template< + typename... Element, + typename Container +> +void container_fill(unsigned int n,element_sequence,Container& c) +{ + auto m=n/sizeof...(Element); + for(unsigned int i=0;i!=m;++i){ + using seq=int[sizeof...(Element)]; + (void)seq{(c.insert(Element(i)),0)...}; + } +} + +struct insert_perf_functor +{ + template< + typename... Element, + typename Container + > + std::size_t operator()( + unsigned int n,element_sequence elements,label)const + { + pause_timing(); + std::size_t res=0; + { + Container c; + resume_timing(); + container_fill(n,elements,c); + pause_timing(); + res=c.size(); + } + resume_timing(); + return res; + } +}; + +template< + typename... Element, + typename Container +> +double insert_perf( + unsigned int n,element_sequence elements,label label) +{ + return measure(n,std::bind(insert_perf_functor{},n,elements,label)); +} + +template< + typename... Element, + typename... Container +> +void insert_perf( + unsigned int n0,unsigned int n1,unsigned int dsav, + element_sequence elements,label... labels) +{ + std::cout<<"insert:\n"; + print("n",labels...); + + for(unsigned int s=0,n=n0; + (n=(unsigned int)std::round(n0*std::pow(10.0,s/1000.0)))<=n1; + s+=dsav){ + unsigned int m=(unsigned int)std::round(n/sizeof...(Element)), + nn=m*sizeof...(Element); + print(nn,insert_perf(nn,elements,labels)...); + } +} + +struct for_each_perf_functor +{ + template + auto operator()(F f,Container& c)const->decltype(f.res) + { + c.for_each(std::ref(f)); + return f.res; + } +}; + +template< + typename... Element, + typename F, + typename Container +> +double for_each_perf( + unsigned int n, + element_sequence elements,F f,label) +{ + Container c; + container_fill(n,elements,c); + c.prepare_for_for_each(); + return measure(n,std::bind(for_each_perf_functor{},f,std::ref(c))); +} + +template< + typename... Element, + typename F, + typename... Container +> +void for_each_perf( + unsigned int n0,unsigned int n1,unsigned int dsav, + element_sequence elements,F f,label... labels) +{ + std::cout<<"for_each:\n"; + print("n",labels...); + + for(unsigned int s=0,n=n0; + (n=(unsigned int)std::round(n0*std::pow(10.0,s/1000.0)))<=n1; + s+=dsav){ + unsigned int m=(unsigned int)std::round(n/sizeof...(Element)), + nn=m*sizeof...(Element); + print(nn,for_each_perf(nn,elements,f,labels)...); + } +} + +//[perf_for_each_callable +struct for_each_callable +{ + for_each_callable():res{0}{} + + template + void operator()(T& x){ + res+=x(2); + } + + int res; +}; +//] + +//[perf_for_each_incrementable +struct for_each_incrementable +{ + for_each_incrementable():res{0}{} + + template + void operator()(T& x){ + ++x; + ++res; + } + + int res; +}; +//] + +int main(int argc, char *argv[]) +{ + using test=std::pair; + + bool all=false, + insert_base=false, + for_each_base=false, + insert_function=false, + for_each_function=false, + insert_any=false, + for_each_any=false; + std::array tests={{ + {"all",all}, + {"insert_base",insert_base}, + {"for_each_base",for_each_base}, + {"insert_function",insert_function}, + {"for_each_function",for_each_function}, + {"insert_any",insert_any}, + {"for_each_any",for_each_any} + }}; + + if(argc<2){ + std::cout<<"specify one or more tests to execute:\n"; + for(const auto& p:tests)std::cout<<" "<second=true; + } + + unsigned int n0=100,n1=10000000,dsav=50; /* sav for savart */ + + { + auto seq= element_sequence< + derived1,derived1,derived2,derived2,derived3>{}; + auto f= for_each_callable{}; + auto pv= label> + {"ptr_vector"}; + auto spv= label> + {"sorted ptr_vector"}; + auto shpv= label> + {"shuffled ptr_vector"}; + auto bc= label> + {"base_collection"}; + auto fbc= label> + {"base_collection (poly::for_each)"}; + auto rfbc= label< + poly_for_each_base_collection + > + {"base_collection (restituted poly::for_each)"}; + + if(all||insert_base)insert_perf(n0,n1,dsav,seq,pv,bc); + if(all||for_each_base)for_each_perf( + n0,n1,dsav,seq,f,pv,spv,shpv,bc,fbc,rfbc); + } + { + using signature=int(int); + + auto seq= element_sequence< + concrete1,concrete1,concrete2,concrete2,concrete3>{}; + auto f = for_each_callable{}; + auto fv= label> + {"func_vector"}; + auto sfv= label> + {"sorted func_vector"}; + auto shfv= label> + {"shuffled func_vector"}; + auto fc= label> + {"function_collection"}; + auto ffc= label> + {"function_collection (poly::for_each)"}; + auto rffc= label> + {"function_collection (restituted poly::for_each)"}; + + if(all||insert_function)insert_perf(n0,n1,dsav,seq,fv,fc); + if(all||for_each_function)for_each_perf( + n0,n1,dsav,seq,f,fv,sfv,shfv,fc,ffc,rffc); + } + { +//[perf_any_types + using concept_=boost::mpl::vector< + boost::type_erasure::copy_constructible<>, + boost::type_erasure::relaxed, + boost::type_erasure::typeid_<>, + boost::type_erasure::incrementable<> + >; +//] + + auto seq= element_sequence{}; + auto f= for_each_incrementable{}; + auto av= label> + {"any_vector"}; + auto sav= label> + {"sorted any_vector"}; + auto shav= label> + {"shuffled any_vector"}; + auto ac= label> + {"any_collection"}; + auto fac= label> + {"any_collection (poly::for_each)"}; + auto rfac= label> + {"any_collection (restituted poly::for_each)"}; + + if(all||insert_any)insert_perf(n0,n1,dsav,seq,av,ac); + if(all||for_each_any)for_each_perf( + n0,n1,dsav,seq,f,av,sav,shav,ac,fac,rfac); + } +} diff --git a/src/boost/libs/poly_collection/example/rolegame.hpp b/src/boost/libs/poly_collection/example/rolegame.hpp new file mode 100644 index 00000000..cb1e9b1f --- /dev/null +++ b/src/boost/libs/poly_collection/example/rolegame.hpp @@ -0,0 +1,78 @@ +/* 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. + */ + +#ifndef BOOST_POLY_COLLECTION_EXAMPLE_ROLEGAME_HPP +#define BOOST_POLY_COLLECTION_EXAMPLE_ROLEGAME_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +/* entities of a purported role game used in the examples */ + +#include +#include +#include + +//[rolegame_1 +struct sprite +{ + sprite(int id):id{id}{} + virtual ~sprite()=default; + virtual void render(std::ostream& os)const=0; + + int id; +}; +//] + +//[rolegame_2 +struct warrior:sprite +{ + using sprite::sprite; + warrior(std::string rank,int id):sprite{id},rank{std::move(rank)}{} + + void render(std::ostream& os)const override{os< +#include +#include +#include +#include +#include +#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 c; + +//[segmented_structure_1 +//= std::unique_ptr make_sprite() +//= { +//<- + auto make_sprite=[]()->std::unique_ptr{ +//-> + static std::mt19937 gen{92748}; + static std::discrete_distribution<> rnd{{1,1,1}}; + static int id=0; + + switch(rnd(gen)){ +//<- + default: +//-> + case 0: return std::make_unique(id++);break; + case 1: return std::make_unique(id++);break; + case 2: return std::make_unique(id++);break; + } +//<- + }; +//-> +//= } +//= ... +//= +//<- + try{ +//-> + for(int i=0;i<8;++i)c.insert(*make_sprite()); + // throws boost::poly_collection::unregistered_type +//<- + }catch(boost::poly_collection::unregistered_type&){} +//-> +//] + +//[segmented_structure_2 + std::cout<()<<"\n"; // prints 0 + std::cout<(); + // everything works fine now + for(int i=0;i<8;++i)c.insert(*make_sprite()); +//] + + using renderable=boost::type_erasure::ostreamable<>; +//[segmented_structure_4 + boost::any_collection c1,c2; +//= ... // populate c2 +//= +//<- + c2.insert(window{"pop-up"}); + try{ +//-> + c1.insert(*c2.begin()); // throws: actual type of *c2.begin() not known by c1 +//<- + }catch(boost::poly_collection::unregistered_type&){} +//-> +//] + +//[segmented_structure_5 +//= ... // populate c with 8 assorted entities +//= + std::cout<()<<"\n"; // 2 juggernauts + std::cout<(); // remove juggenauts only + std::cout<()<<"\n"; // 1 (no juggernauts left) + std::cout<render(std::cout); + comma=","; + } + std::cout<<"\n"; +//] + +//[segmented_structure_7 + /*=const char**/ comma=""; + for(const auto& x:c.segment(typeid(warrior))){ + std::cout<(),last=c.end(); + first!=last;++first){ + first->rank.insert(0,"super"); + std::cout<render(std::cout); + comma=","; + } + std::cout<<"\n"; + + // range-based for loop alternative + + /*=const char**/ comma=""; + for(auto& x:c.segment()){ + x.rank.insert(0,"super"); +//<- + auto it=x.rank.begin(); + x.rank.erase(it,it+5); // undo previos op, 5==len("super"); +//-> + std::cout<(100); // no reallocation till we exceed 100 goblins + std::cout<()<<"\n"; // prints 100 +//] + +//[segmented_structure_11 + c.reserve(1000); // reserve(1000) for each segment + std::cout<()<<", " + <()<<", " + <()<<"\n"; // prints 1000, 1000, 1000 +//] +} -- cgit v1.2.3