fork(2) download
  1.  
  2. #include <cstddef>
  3. #include <utility>
  4. #include <vector>
  5. #include <tuple>
  6. #include <string>
  7. #include <iostream>
  8.  
  9. using std::size_t;
  10.  
  11. template<size_t...> struct seq {};
  12. template<size_t Min, size_t Max, size_t... s>
  13. struct make_seq:make_seq< Min, Max-1, Max-1, s... > {};
  14. template<size_t Min, size_t... s>
  15. struct make_seq< Min, Min, s... > {
  16. typedef seq<s...> type;
  17. };
  18. template<size_t Max, size_t Min=0>
  19. using MakeSeq = typename make_seq<Min, Max>::type;
  20.  
  21. size_t product_size() {
  22. return 1;
  23. }
  24. template<typename... Sizes>
  25. size_t product_size( size_t x, Sizes... tail ) {
  26. return x * product_size(tail...);
  27. }
  28. namespace details {
  29. template<typename max_iterator, typename Lambda>
  30. void for_each_index( max_iterator mbegin, max_iterator mend, Lambda&& f, std::vector<size_t>& idx ) {
  31. if (mbegin == mend) {
  32. f(idx);
  33. } else {
  34. for (size_t i = 0; i < *mbegin; ++i) {
  35. idx.push_back(i);
  36. for_each_index(mbegin+1, mend, f, idx);
  37. idx.pop_back();
  38. }
  39. }
  40. }
  41. template<typename Lambda>
  42. void for_each_index( std::vector<size_t> const& maxes, Lambda&& f ) {
  43. std::vector<size_t> idx;
  44. details::for_each_index( maxes.begin(), maxes.end(), f, idx );
  45. }
  46. template<size_t... s, typename... Ts>
  47. std::vector< std::tuple<Ts...> > does_it_blend( seq<s...>, std::tuple< std::vector<Ts>... >const& input ) {
  48. std::vector< std::tuple<Ts...> > retval;
  49. retval.reserve( product_size( std::get<s>(input).size()... ) );
  50. std::vector<size_t> maxes = {
  51. (std::get<s>(input).size())...
  52. };
  53. for_each_index( maxes, [&](std::vector<size_t> const& idx){
  54. retval.emplace_back( std::get<s>(input)[idx[s]]... );
  55. });
  56. return retval;
  57. }
  58. }
  59. template<typename... Ts>
  60. std::vector< std::tuple<Ts...> > does_it_blend( std::tuple< std::vector<Ts>... >const& input ) {
  61. return details::does_it_blend( MakeSeq< sizeof...(Ts) >(), input );
  62. }
  63.  
  64. int main() {
  65. std::tuple< std::vector<int>, std::vector<bool>, std::vector<std::string> > input {
  66. { 1, 2, 3}, { false, true}, { "Hello", "World"}
  67. };
  68.  
  69. // should become 3 x 2 x 2 = 12 cases { {1, false, "Hello"}, ... , {3, true, "World"} }
  70. std::vector< std::tuple<int, bool, std::string> > test_cases = does_it_blend( input );
  71.  
  72. for( auto&& x:test_cases ) {
  73. std::cout << std::get<0>(x) << "," << std::get<1>(x) << "," << std::get<2>(x) << "\n";
  74. }
  75. }
  76.  
  77.  
Success #stdin #stdout 0s 2992KB
stdin
Standard input is empty
stdout
1,0,Hello
1,0,World
1,1,Hello
1,1,World
2,0,Hello
2,0,World
2,1,Hello
2,1,World
3,0,Hello
3,0,World
3,1,Hello
3,1,World