#include <exception>
#include <iomanip>
#include <iostream>
#include <stdexcept>
#include <string>
#include <tuple>
#include <vector>
template <std::size_t... Indices>
struct indices {};
template <std::size_t Count, std::size_t... Indices>
struct get_indices : public get_indices<Count - 1, Count - 1, Indices...> {};
template <std::size_t... Indices>
struct get_indices<0, Indices...> : public indices<Indices...> {};
template <class TupleT, class Fn, std::size_t Index>
static void do_get(const TupleT& tuple, Fn fn)
{
fn(std::get<Index>(tuple));
}
template <class TupleT, class Fn, std::size_t... Indices>
static void tuple_get(const TupleT& tuple, std::size_t index, Fn fn, indices<Indices...>)
{
using FunT = void(const TupleT&, Fn);
static constexpr FunT* getters[] = { &do_get<TupleT, Fn, Indices>... };
return (getters[index])(tuple, fn);
}
template <class Fn, typename... ArgsT>
void tuple_get(const std::tuple<ArgsT...>& tuple, std::size_t index, Fn fn)
{
if (index >= sizeof...(ArgsT))
throw std::logic_error("Cannot index past the end of tuple");
return tuple_get<std::tuple<ArgsT...>, Fn>(tuple, index, fn, get_indices<sizeof...(ArgsT)>());
}
enum weekday { monday, tuesday, wednesday, thursday, friday, saturday, sunday };
static std::ostream& operator<<(std::ostream& stream, weekday wd)
{
switch (wd) {
case monday: stream << "Monday"; break;
case tuesday: stream << "Tuesday"; break;
case wednesday: stream << "Wednesday"; break;
case thursday: stream << "Thursday"; break;
case friday: stream << "Friday"; break;
case saturday: stream << "Satudrday"; break;
case sunday: stream << "Sunday"; break;
}
return stream;
}
struct print_tuple_value {
template <typename T>
void operator()(const T& value)
{
std::cout << value;
}
void operator()(weekday day)
{
std::cout << std::setw(10) << std::setfill(' ') << day;
}
void operator()(int time)
{
std::cout << std::setw(4) << std::setfill('0') << time;
}
};
template <class TupleT>
std::size_t tuple_size(TupleT)
{
return std::tuple_size<TupleT>::value;
}
int main()
{
std::vector<std::tuple<weekday, int, std::string>> todo_list = {
std::make_tuple( monday, 900, "purchase meat"),
std::make_tuple( tuesday, 1400, "beat meat"),
std::make_tuple(wednesday, 1100, "make sandwiches"),
std::make_tuple( thursday, 1200, "eat sandwiches"),
std::make_tuple( friday, 1200, "reinvent wheel"),
std::make_tuple( saturday, 800, "post cats"),
std::make_tuple( sunday, 2200, "post sinks (mods asleep)")
};
std::cout << "To-do list:\n";
for (std::size_t j = 0; j < todo_list.size(); ++j) {
std::cout.put('\t');
for (std::size_t i = 0; i < tuple_size(todo_list[j]); ++i) {
tuple_get(todo_list[j], i, print_tuple_value());
std::cout.put(' ');
}
std::cout.put('\n');
}
return 0;
}
I2luY2x1ZGUgPGV4Y2VwdGlvbj4KI2luY2x1ZGUgPGlvbWFuaXA+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHN0ZGV4Y2VwdD4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHR1cGxlPgojaW5jbHVkZSA8dmVjdG9yPgoKdGVtcGxhdGUgPHN0ZDo6c2l6ZV90Li4uIEluZGljZXM+CnN0cnVjdCBpbmRpY2VzIHt9OwoKdGVtcGxhdGUgPHN0ZDo6c2l6ZV90IENvdW50LCBzdGQ6OnNpemVfdC4uLiBJbmRpY2VzPgpzdHJ1Y3QgZ2V0X2luZGljZXMgOiBwdWJsaWMgZ2V0X2luZGljZXM8Q291bnQgLSAxLCBDb3VudCAtIDEsIEluZGljZXMuLi4+IHt9OwoKdGVtcGxhdGUgPHN0ZDo6c2l6ZV90Li4uIEluZGljZXM+CnN0cnVjdCBnZXRfaW5kaWNlczwwLCBJbmRpY2VzLi4uPiA6IHB1YmxpYyBpbmRpY2VzPEluZGljZXMuLi4+IHt9OwoKdGVtcGxhdGUgPGNsYXNzIFR1cGxlVCwgY2xhc3MgRm4sIHN0ZDo6c2l6ZV90IEluZGV4PgpzdGF0aWMgdm9pZCBkb19nZXQoY29uc3QgVHVwbGVUJiB0dXBsZSwgRm4gZm4pCnsKICAgIGZuKHN0ZDo6Z2V0PEluZGV4Pih0dXBsZSkpOwp9Cgp0ZW1wbGF0ZSA8Y2xhc3MgVHVwbGVULCBjbGFzcyBGbiwgc3RkOjpzaXplX3QuLi4gSW5kaWNlcz4Kc3RhdGljIHZvaWQgdHVwbGVfZ2V0KGNvbnN0IFR1cGxlVCYgdHVwbGUsIHN0ZDo6c2l6ZV90IGluZGV4LCBGbiBmbiwgaW5kaWNlczxJbmRpY2VzLi4uPikKewogICAgdXNpbmcgRnVuVCA9IHZvaWQoY29uc3QgVHVwbGVUJiwgRm4pOwogICAgc3RhdGljIGNvbnN0ZXhwciBGdW5UKiBnZXR0ZXJzW10gPSB7ICZkb19nZXQ8VHVwbGVULCBGbiwgSW5kaWNlcz4uLi4gfTsKICAgIHJldHVybiAoZ2V0dGVyc1tpbmRleF0pKHR1cGxlLCBmbik7Cn0KCnRlbXBsYXRlIDxjbGFzcyBGbiwgdHlwZW5hbWUuLi4gQXJnc1Q+CnZvaWQgdHVwbGVfZ2V0KGNvbnN0IHN0ZDo6dHVwbGU8QXJnc1QuLi4+JiB0dXBsZSwgc3RkOjpzaXplX3QgaW5kZXgsIEZuIGZuKQp7CiAgICBpZiAoaW5kZXggPj0gc2l6ZW9mLi4uKEFyZ3NUKSkKICAgICAgICB0aHJvdyBzdGQ6OmxvZ2ljX2Vycm9yKCJDYW5ub3QgaW5kZXggcGFzdCB0aGUgZW5kIG9mIHR1cGxlIik7CiAgICByZXR1cm4gdHVwbGVfZ2V0PHN0ZDo6dHVwbGU8QXJnc1QuLi4+LCBGbj4odHVwbGUsIGluZGV4LCBmbiwgZ2V0X2luZGljZXM8c2l6ZW9mLi4uKEFyZ3NUKT4oKSk7Cn0KCmVudW0gd2Vla2RheSB7IG1vbmRheSwgdHVlc2RheSwgd2VkbmVzZGF5LCB0aHVyc2RheSwgZnJpZGF5LCBzYXR1cmRheSwgc3VuZGF5IH07CgpzdGF0aWMgc3RkOjpvc3RyZWFtJiBvcGVyYXRvcjw8KHN0ZDo6b3N0cmVhbSYgc3RyZWFtLCB3ZWVrZGF5IHdkKQp7CiAgICBzd2l0Y2ggKHdkKSB7CiAgICAgICAgY2FzZSAgICBtb25kYXk6IHN0cmVhbSA8PCAgICAiTW9uZGF5IjsgYnJlYWs7CiAgICAgICAgY2FzZSAgIHR1ZXNkYXk6IHN0cmVhbSA8PCAgICJUdWVzZGF5IjsgYnJlYWs7CiAgICAgICAgY2FzZSB3ZWRuZXNkYXk6IHN0cmVhbSA8PCAiV2VkbmVzZGF5IjsgYnJlYWs7CiAgICAgICAgY2FzZSAgdGh1cnNkYXk6IHN0cmVhbSA8PCAgIlRodXJzZGF5IjsgYnJlYWs7CiAgICAgICAgY2FzZSAgICBmcmlkYXk6IHN0cmVhbSA8PCAgICAiRnJpZGF5IjsgYnJlYWs7CiAgICAgICAgY2FzZSAgc2F0dXJkYXk6IHN0cmVhbSA8PCAiU2F0dWRyZGF5IjsgYnJlYWs7CiAgICAgICAgY2FzZSAgICBzdW5kYXk6IHN0cmVhbSA8PCAgICAiU3VuZGF5IjsgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gc3RyZWFtOwp9CgpzdHJ1Y3QgcHJpbnRfdHVwbGVfdmFsdWUgewogICAgdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CiAgICB2b2lkIG9wZXJhdG9yKCkoY29uc3QgVCYgdmFsdWUpCiAgICB7CiAgICAgICAgc3RkOjpjb3V0IDw8IHZhbHVlOwogICAgfQoKICAgIHZvaWQgb3BlcmF0b3IoKSh3ZWVrZGF5IGRheSkKICAgIHsKICAgICAgICBzdGQ6OmNvdXQgPDwgc3RkOjpzZXR3KDEwKSA8PCBzdGQ6OnNldGZpbGwoJyAnKSA8PCBkYXk7CiAgICB9CgogICAgdm9pZCBvcGVyYXRvcigpKGludCB0aW1lKQogICAgewogICAgICAgIHN0ZDo6Y291dCA8PCBzdGQ6OnNldHcoNCkgPDwgc3RkOjpzZXRmaWxsKCcwJykgPDwgdGltZTsKICAgIH0KfTsKCnRlbXBsYXRlIDxjbGFzcyBUdXBsZVQ+CnN0ZDo6c2l6ZV90IHR1cGxlX3NpemUoVHVwbGVUKQp7CiAgICByZXR1cm4gc3RkOjp0dXBsZV9zaXplPFR1cGxlVD46OnZhbHVlOwp9CgppbnQgbWFpbigpCnsKICAgIHN0ZDo6dmVjdG9yPHN0ZDo6dHVwbGU8d2Vla2RheSwgaW50LCBzdGQ6OnN0cmluZz4+IHRvZG9fbGlzdCA9IHsKICAgICAgICBzdGQ6Om1ha2VfdHVwbGUoICAgbW9uZGF5LCAgOTAwLCAgICAgICAgICAgICJwdXJjaGFzZSBtZWF0IiksCiAgICAgICAgc3RkOjptYWtlX3R1cGxlKCAgdHVlc2RheSwgMTQwMCwgICAgICAgICAgICAgICAgImJlYXQgbWVhdCIpLAogICAgICAgIHN0ZDo6bWFrZV90dXBsZSh3ZWRuZXNkYXksIDExMDAsICAgICAgICAgICJtYWtlIHNhbmR3aWNoZXMiKSwKICAgICAgICBzdGQ6Om1ha2VfdHVwbGUoIHRodXJzZGF5LCAxMjAwLCAgICAgICAgICAgImVhdCBzYW5kd2ljaGVzIiksCiAgICAgICAgc3RkOjptYWtlX3R1cGxlKCAgIGZyaWRheSwgMTIwMCwgICAgICAgICAgICJyZWludmVudCB3aGVlbCIpLAogICAgICAgIHN0ZDo6bWFrZV90dXBsZSggc2F0dXJkYXksICA4MDAsICAgICAgICAgICAgICAgICJwb3N0IGNhdHMiKSwKICAgICAgICBzdGQ6Om1ha2VfdHVwbGUoICAgc3VuZGF5LCAyMjAwLCAicG9zdCBzaW5rcyAobW9kcyBhc2xlZXApIikKICAgIH07CiAgICBzdGQ6OmNvdXQgPDwgIlRvLWRvIGxpc3Q6XG4iOwogICAgZm9yIChzdGQ6OnNpemVfdCBqID0gMDsgaiA8IHRvZG9fbGlzdC5zaXplKCk7ICsraikgewogICAgICAgIHN0ZDo6Y291dC5wdXQoJ1x0Jyk7CiAgICAgICAgZm9yIChzdGQ6OnNpemVfdCBpID0gMDsgaSA8IHR1cGxlX3NpemUodG9kb19saXN0W2pdKTsgKytpKSB7CiAgICAgICAgICAgIHR1cGxlX2dldCh0b2RvX2xpc3Rbal0sIGksIHByaW50X3R1cGxlX3ZhbHVlKCkpOwogICAgICAgICAgICBzdGQ6OmNvdXQucHV0KCcgJyk7CiAgICAgICAgfQogICAgICAgIHN0ZDo6Y291dC5wdXQoJ1xuJyk7CiAgICB9CiAgICByZXR1cm4gMDsKfQo=