fork(1) download
  1. #include <vector>
  2. #include <iostream>
  3. #include <iterator>
  4. #include <array>
  5. using namespace std;
  6.  
  7. class Generator {
  8. protected:
  9. vector<int> v;
  10. public:
  11. Generator(unsigned length): v(length) {}
  12.  
  13. template<class Outputter>
  14. void do_calculations_with_output(Outputter& out){
  15. // perform first part of some complex operations on v
  16. out.output(v);
  17. // perform second part of some complex operations on v
  18. out.output(v);
  19. // perform some final actions
  20. }
  21.  
  22. };
  23.  
  24. class SimpleDumpOutputter {
  25. private:
  26.  
  27. ostream* out;
  28. unsigned count;
  29. public:
  30. SimpleDumpOutputter(ostream& os): out(&os), count() {}
  31. template<class C>
  32. void output(const C& c) {
  33. *out << "Step " << ++count << " of calculation: ";
  34. copy(c.begin(),c.end(), ostream_iterator<int>(*out, " "));
  35. *out << endl;
  36. }
  37. };
  38.  
  39. class FancyOutputter {
  40. ostream* out;
  41. int count;
  42. public:
  43. FancyOutputter(ostream& os): out(&os),count() {}
  44. template<class C>
  45. void output(const C& c) {
  46. // create a graph using graphviz's dot language to ease visualisation of v
  47. *out << "Step " << ++count << " of calculation: ";
  48. *out << "Graphviz output\n";
  49. }
  50. };
  51.  
  52. template<class... Outputters> class AggregateOutputter : private Outputters... {
  53. private:
  54. template<class First, class... Rest>
  55. struct output_helper{
  56. template<class C>
  57. static void do_output(AggregateOutputter* pthis,const C& c){
  58. static_cast<First*>(pthis)->output(c);
  59. output_helper<Rest...>::do_output(pthis,c);
  60. }
  61.  
  62. };
  63.  
  64. template<class First>
  65. struct output_helper<First>{
  66. template<class C>
  67. static void do_output(AggregateOutputter* pthis,const C& c){
  68. static_cast<First*>(pthis)->output(c);
  69. }
  70.  
  71. };
  72. public:
  73. template<class... Out>
  74. AggregateOutputter( Out&... out): Outputters(out)...{}
  75. template<class C>
  76. void output(const C& c) {
  77. output_helper<Outputters...>::do_output(this,c);
  78. }
  79. // first argument is dummy, because we would use the ostreams in destinations
  80. };
  81. int main(){
  82.  
  83. AggregateOutputter<FancyOutputter,SimpleDumpOutputter> out(cout,cout);
  84.  
  85. Generator g(10);
  86.  
  87. g.do_calculations_with_output(out);
  88.  
  89. }
Success #stdin #stdout 0s 2984KB
stdin
Standard input is empty
stdout
Step 1 of calculation: Graphviz output
Step 1 of calculation: 0 0 0 0 0 0 0 0 0 0 
Step 2 of calculation: Graphviz output
Step 2 of calculation: 0 0 0 0 0 0 0 0 0 0