#include <string>
#include <iostream>
#define static_type(name) static constexpr const char* type_name() { return name; }
struct disabled_type { static_type("disabled"); };
struct deferred_type { static_type("deferred"); };
struct deferred_type_2 { static_type("deferred2!"); };
struct deadline_type { static_type("deadline"); };
struct deadline_type_2 { static_type("deadline2!"); };
template <typename T = deferred_type>
struct deferred_tag { typedef T type; };
template <typename T = deadline_type>
struct deadline_tag {typedef T type; };
template<template <class> class Expected, typename...T>
struct match { typedef disabled_type type; };
template <typename V, template <class> class Expected, typename...T>
struct match<Expected, Expected<V>, T...> { typedef typename Expected<V>::type type; };
template <template <class> class Expected, typename Actual, typename...T>
struct match<Expected, Actual, T...> { typedef typename match<Expected, T...>::type type; };
template<class T, typename... Plugins>
struct container
{
typedef typename match<deferred_tag, Plugins...>::type deferred_;
typedef typename match<deadline_tag, Plugins...>::type deadline_;
static std::string type_name()
{
return std::string("container<") + deferred_::type_name() + ", " + deadline_::type_name() + ">";
}
};
int main()
{
using namespace std;
cout << container<int>::type_name() << std::endl;
cout << container<int, deadline_tag<deadline_type>>::type_name() << std::endl;
cout << container<int, deferred_tag<deferred_type>>::type_name() << std::endl;
cout << container<int, deferred_tag<deferred_type>, deadline_tag<deadline_type>>::type_name() << std::endl;
cout << container<int, deadline_tag<deadline_type>, deferred_tag<deferred_type>>::type_name() << std::endl;
cout << container<int, deadline_tag<deadline_type_2>, deferred_tag<deferred_type_2>>::type_name() << std::endl;
cout << container<int, deadline_tag<deadline_type_2>>::type_name() << std::endl;
cout << container<int, deferred_tag<deferred_type_2>, deadline_tag<>>::type_name() << std::endl;
}
I2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGlvc3RyZWFtPgoKI2RlZmluZSBzdGF0aWNfdHlwZShuYW1lKSBzdGF0aWMgY29uc3RleHByIGNvbnN0IGNoYXIqIHR5cGVfbmFtZSgpIHsgcmV0dXJuIG5hbWU7IH0gCgpzdHJ1Y3QgZGlzYWJsZWRfdHlwZSB7IHN0YXRpY190eXBlKCJkaXNhYmxlZCIpOyB9OwoKc3RydWN0IGRlZmVycmVkX3R5cGUgeyBzdGF0aWNfdHlwZSgiZGVmZXJyZWQiKTsgfTsKc3RydWN0IGRlZmVycmVkX3R5cGVfMiB7IHN0YXRpY190eXBlKCJkZWZlcnJlZDIhIik7IH07CgpzdHJ1Y3QgZGVhZGxpbmVfdHlwZSB7IHN0YXRpY190eXBlKCJkZWFkbGluZSIpOyB9OwpzdHJ1Y3QgZGVhZGxpbmVfdHlwZV8yIHsgc3RhdGljX3R5cGUoImRlYWRsaW5lMiEiKTsgfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUID0gZGVmZXJyZWRfdHlwZT4Kc3RydWN0IGRlZmVycmVkX3RhZyB7IHR5cGVkZWYgVCB0eXBlOyB9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQgPSBkZWFkbGluZV90eXBlPgpzdHJ1Y3QgZGVhZGxpbmVfdGFnIHt0eXBlZGVmIFQgdHlwZTsgfTsKCnRlbXBsYXRlPHRlbXBsYXRlIDxjbGFzcz4gY2xhc3MgRXhwZWN0ZWQsIHR5cGVuYW1lLi4uVD4gCnN0cnVjdCBtYXRjaCB7IHR5cGVkZWYgZGlzYWJsZWRfdHlwZSB0eXBlOyB9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFYsIHRlbXBsYXRlIDxjbGFzcz4gY2xhc3MgRXhwZWN0ZWQsIHR5cGVuYW1lLi4uVD4Kc3RydWN0IG1hdGNoPEV4cGVjdGVkLCBFeHBlY3RlZDxWPiwgVC4uLj4geyB0eXBlZGVmIHR5cGVuYW1lIEV4cGVjdGVkPFY+Ojp0eXBlIHR5cGU7IH07Cgp0ZW1wbGF0ZSA8dGVtcGxhdGUgPGNsYXNzPiBjbGFzcyBFeHBlY3RlZCwgdHlwZW5hbWUgQWN0dWFsLCB0eXBlbmFtZS4uLlQ+CnN0cnVjdCBtYXRjaDxFeHBlY3RlZCwgQWN0dWFsLCBULi4uPiB7IHR5cGVkZWYgdHlwZW5hbWUgbWF0Y2g8RXhwZWN0ZWQsIFQuLi4+Ojp0eXBlIHR5cGU7IH07CgoKdGVtcGxhdGU8Y2xhc3MgVCwgdHlwZW5hbWUuLi4gUGx1Z2lucz4Kc3RydWN0IGNvbnRhaW5lcgp7CiAgICB0eXBlZGVmIHR5cGVuYW1lIG1hdGNoPGRlZmVycmVkX3RhZywgUGx1Z2lucy4uLj46OnR5cGUgZGVmZXJyZWRfOwogICAgdHlwZWRlZiB0eXBlbmFtZSBtYXRjaDxkZWFkbGluZV90YWcsIFBsdWdpbnMuLi4+Ojp0eXBlIGRlYWRsaW5lXzsKICAgIAogICAgc3RhdGljIHN0ZDo6c3RyaW5nIHR5cGVfbmFtZSgpCiAgICB7CiAgICAJcmV0dXJuIHN0ZDo6c3RyaW5nKCJjb250YWluZXI8IikgKyBkZWZlcnJlZF86OnR5cGVfbmFtZSgpICsgIiwgIiArIGRlYWRsaW5lXzo6dHlwZV9uYW1lKCkgKyAiPiI7CiAgICB9Cn07CgppbnQgbWFpbigpCnsKCXVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgljb3V0IDw8IGNvbnRhaW5lcjxpbnQ+Ojp0eXBlX25hbWUoKSA8PCBzdGQ6OmVuZGw7CiAgICBjb3V0IDw8IGNvbnRhaW5lcjxpbnQsIGRlYWRsaW5lX3RhZzxkZWFkbGluZV90eXBlPj46OnR5cGVfbmFtZSgpIDw8IHN0ZDo6ZW5kbDsKICAgIGNvdXQgPDwgY29udGFpbmVyPGludCwgZGVmZXJyZWRfdGFnPGRlZmVycmVkX3R5cGU+Pjo6dHlwZV9uYW1lKCkgPDwgc3RkOjplbmRsOwogICAgY291dCA8PCBjb250YWluZXI8aW50LCBkZWZlcnJlZF90YWc8ZGVmZXJyZWRfdHlwZT4sIGRlYWRsaW5lX3RhZzxkZWFkbGluZV90eXBlPj46OnR5cGVfbmFtZSgpIDw8IHN0ZDo6ZW5kbDsKICAgIGNvdXQgPDwgY29udGFpbmVyPGludCwgZGVhZGxpbmVfdGFnPGRlYWRsaW5lX3R5cGU+LCBkZWZlcnJlZF90YWc8ZGVmZXJyZWRfdHlwZT4+Ojp0eXBlX25hbWUoKSA8PCBzdGQ6OmVuZGw7CgogICAgY291dCA8PCBjb250YWluZXI8aW50LCBkZWFkbGluZV90YWc8ZGVhZGxpbmVfdHlwZV8yPiwgZGVmZXJyZWRfdGFnPGRlZmVycmVkX3R5cGVfMj4+Ojp0eXBlX25hbWUoKSA8PCBzdGQ6OmVuZGw7CiAgICBjb3V0IDw8IGNvbnRhaW5lcjxpbnQsIGRlYWRsaW5lX3RhZzxkZWFkbGluZV90eXBlXzI+Pjo6dHlwZV9uYW1lKCkgPDwgc3RkOjplbmRsOwogICAgY291dCA8PCBjb250YWluZXI8aW50LCBkZWZlcnJlZF90YWc8ZGVmZXJyZWRfdHlwZV8yPiwgZGVhZGxpbmVfdGFnPD4+Ojp0eXBlX25hbWUoKSA8PCBzdGQ6OmVuZGw7Cn0K
container<disabled, disabled>
container<disabled, deadline>
container<deferred, disabled>
container<deferred, deadline>
container<deferred, deadline>
container<deferred2!, deadline2!>
container<disabled, deadline2!>
container<deferred2!, deadline>