fork(1) download
  1. #include <exception>
  2. #include <iomanip>
  3. #include <iostream>
  4. #include <stdexcept>
  5. #include <string>
  6. #include <tuple>
  7. #include <vector>
  8.  
  9. template <std::size_t... Indices>
  10. struct indices {};
  11.  
  12. template <std::size_t Count, std::size_t... Indices>
  13. struct get_indices : public get_indices<Count - 1, Count - 1, Indices...> {};
  14.  
  15. template <std::size_t... Indices>
  16. struct get_indices<0, Indices...> : public indices<Indices...> {};
  17.  
  18. template <class TupleT, class Fn, std::size_t Index>
  19. static void do_get(const TupleT& tuple, Fn fn)
  20. {
  21. fn(std::get<Index>(tuple));
  22. }
  23.  
  24. template <class TupleT, class Fn, std::size_t... Indices>
  25. static void tuple_get(const TupleT& tuple, std::size_t index, Fn fn, indices<Indices...>)
  26. {
  27. using FunT = void(const TupleT&, Fn);
  28. static constexpr FunT* getters[] = { &do_get<TupleT, Fn, Indices>... };
  29. return (getters[index])(tuple, fn);
  30. }
  31.  
  32. template <class Fn, typename... ArgsT>
  33. void tuple_get(const std::tuple<ArgsT...>& tuple, std::size_t index, Fn fn)
  34. {
  35. if (index >= sizeof...(ArgsT))
  36. throw std::logic_error("Cannot index past the end of tuple");
  37. return tuple_get<std::tuple<ArgsT...>, Fn>(tuple, index, fn, get_indices<sizeof...(ArgsT)>());
  38. }
  39.  
  40. enum weekday { monday, tuesday, wednesday, thursday, friday, saturday, sunday };
  41.  
  42. static std::ostream& operator<<(std::ostream& stream, weekday wd)
  43. {
  44. switch (wd) {
  45. case monday: stream << "Monday"; break;
  46. case tuesday: stream << "Tuesday"; break;
  47. case wednesday: stream << "Wednesday"; break;
  48. case thursday: stream << "Thursday"; break;
  49. case friday: stream << "Friday"; break;
  50. case saturday: stream << "Satudrday"; break;
  51. case sunday: stream << "Sunday"; break;
  52. }
  53. return stream;
  54. }
  55.  
  56. struct print_tuple_value {
  57. template <typename T>
  58. void operator()(const T& value)
  59. {
  60. std::cout << value;
  61. }
  62.  
  63. void operator()(weekday day)
  64. {
  65. std::cout << std::setw(10) << std::setfill(' ') << day;
  66. }
  67.  
  68. void operator()(int time)
  69. {
  70. std::cout << std::setw(4) << std::setfill('0') << time;
  71. }
  72. };
  73.  
  74. template <class TupleT>
  75. std::size_t tuple_size(TupleT)
  76. {
  77. return std::tuple_size<TupleT>::value;
  78. }
  79.  
  80. int main()
  81. {
  82. std::vector<std::tuple<weekday, int, std::string>> todo_list = {
  83. std::make_tuple( monday, 900, "purchase meat"),
  84. std::make_tuple( tuesday, 1400, "beat meat"),
  85. std::make_tuple(wednesday, 1100, "make sandwiches"),
  86. std::make_tuple( thursday, 1200, "eat sandwiches"),
  87. std::make_tuple( friday, 1200, "reinvent wheel"),
  88. std::make_tuple( saturday, 800, "post cats"),
  89. std::make_tuple( sunday, 2200, "post sinks (mods asleep)")
  90. };
  91. std::cout << "To-do list:\n";
  92. for (std::size_t j = 0; j < todo_list.size(); ++j) {
  93. std::cout.put('\t');
  94. for (std::size_t i = 0; i < tuple_size(todo_list[j]); ++i) {
  95. tuple_get(todo_list[j], i, print_tuple_value());
  96. std::cout.put(' ');
  97. }
  98. std::cout.put('\n');
  99. }
  100. return 0;
  101. }
  102.  
Success #stdin #stdout 0s 3476KB
stdin
Standard input is empty
stdout
To-do list:
	    Monday 0900 purchase meat 
	   Tuesday 1400 beat meat 
	 Wednesday 1100 make sandwiches 
	  Thursday 1200 eat sandwiches 
	    Friday 1200 reinvent wheel 
	 Satudrday 0800 post cats 
	    Sunday 2200 post sinks (mods asleep)