#include <iostream>
template<class T>
class IQueue
{
protected:
T Data[10];
public:
virtual const T pop() = 0;
virtual void push(const T&) = 0;
};
template<class T>
class QueueA : public IQueue<T>
{
public:
const T pop() final {
std::cout << "pop queue A" << std::endl;
return T{};
}
void push(const T& aItemRef) final {
std::cout << "PUSH queue A" << std::endl;
}
};
template<class T>
class QueueB : public IQueue<T>
{
public:
const T pop() final {
std::cout << "pop queue B" << std::endl;
return T{};
}
void push(const T& aItemRef) final {
std::cout << "PUSH queue B" << std::endl;
}
};
template <class... Ts>
struct Tester;
template <class T, class... Ts>
struct Tester<T, Ts...>
{
template<class U>
static void test_push_pop(IQueue<U>&& aQueueP)
{
aQueueP.push(U{});
aQueueP.pop();
}
static void test_push_pops()
{
test_push_pop(T{});
Tester<Ts...>::test_push_pops();
}
};
template<>
struct Tester<>
{
static void test_push_pops() {}
};
template<class... Ts>
void tester_queues()
{
Tester<Ts...>::test_push_pops();
};
int main()
{
tester_queues< QueueA<int>, QueueB<char> >();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGU8Y2xhc3MgVD4KY2xhc3MgSVF1ZXVlCnsKcHJvdGVjdGVkOgogICAgVCBEYXRhWzEwXTsKcHVibGljOgogICAgdmlydHVhbCBjb25zdCBUIHBvcCgpICAgICAgICAgID0gMDsKICAgIHZpcnR1YWwgdm9pZCAgICBwdXNoKGNvbnN0IFQmKSA9IDA7Cn07Cgp0ZW1wbGF0ZTxjbGFzcyBUPgpjbGFzcyBRdWV1ZUEgOiBwdWJsaWMgSVF1ZXVlPFQ+CnsKcHVibGljOgoJY29uc3QgVCBwb3AoKSBmaW5hbCB7CiAgICAgICAgc3RkOjpjb3V0IDw8ICJwb3AgcXVldWUgQSIgPDwgc3RkOjplbmRsOwogICAgICAgIHJldHVybiBUe307CiAgICB9CgogICAgdm9pZCBwdXNoKGNvbnN0IFQmIGFJdGVtUmVmKSBmaW5hbCB7CiAgICAgICAgc3RkOjpjb3V0IDw8ICJQVVNIIHF1ZXVlIEEiIDw8IHN0ZDo6ZW5kbDsKICAgIH0KfTsKCnRlbXBsYXRlPGNsYXNzIFQ+CmNsYXNzIFF1ZXVlQiA6IHB1YmxpYyBJUXVldWU8VD4KewpwdWJsaWM6Cgljb25zdCBUIHBvcCgpIGZpbmFsIHsKICAgICAgICBzdGQ6OmNvdXQgPDwgInBvcCBxdWV1ZSBCIiA8PCBzdGQ6OmVuZGw7CiAgICAgICAgcmV0dXJuIFR7fTsKICAgIH0KCiAgICB2b2lkIHB1c2goY29uc3QgVCYgYUl0ZW1SZWYpIGZpbmFsIHsKICAgICAgICBzdGQ6OmNvdXQgPDwgIlBVU0ggcXVldWUgQiIgPDwgc3RkOjplbmRsOwogICAgfQp9OwoKdGVtcGxhdGUgPGNsYXNzLi4uIFRzPgpzdHJ1Y3QgVGVzdGVyOwoKdGVtcGxhdGUgPGNsYXNzIFQsIGNsYXNzLi4uIFRzPgpzdHJ1Y3QgVGVzdGVyPFQsIFRzLi4uPgp7Cgl0ZW1wbGF0ZTxjbGFzcyBVPgoJc3RhdGljIHZvaWQgdGVzdF9wdXNoX3BvcChJUXVldWU8VT4mJiBhUXVldWVQKQoJewoJCWFRdWV1ZVAucHVzaChVe30pOwoJCWFRdWV1ZVAucG9wKCk7Cgl9CgoJc3RhdGljIHZvaWQgdGVzdF9wdXNoX3BvcHMoKQoJewoJCXRlc3RfcHVzaF9wb3AoVHt9KTsKICAgIAlUZXN0ZXI8VHMuLi4+Ojp0ZXN0X3B1c2hfcG9wcygpOwoJfQp9OwoKdGVtcGxhdGU8PgpzdHJ1Y3QgVGVzdGVyPD4KewoJc3RhdGljIHZvaWQgdGVzdF9wdXNoX3BvcHMoKSB7fQp9OwoKdGVtcGxhdGU8Y2xhc3MuLi4gVHM+CnZvaWQgdGVzdGVyX3F1ZXVlcygpCnsKCVRlc3RlcjxUcy4uLj46OnRlc3RfcHVzaF9wb3BzKCk7Cn07CgppbnQgbWFpbigpCnsKICAgIHRlc3Rlcl9xdWV1ZXM8IFF1ZXVlQTxpbnQ+LCBRdWV1ZUI8Y2hhcj4gPigpOwogICAgcmV0dXJuIDA7Cn0=