#include <iostream>
#include <type_traits>
using namespace std;
struct alfa {};
struct foo { foo() { cout << "foo(void)" << endl; }};
struct bar { explicit bar(alfa&) { cout << "bar(alfa&)" << endl; } };
template<class T> struct with_allocator
{
struct unspecified_type;
T var;
T& operator*() { return var; }
T const& operator*() const { return var; }
template<class A>
explicit with_allocator(A& a, typename enable_if< is_constructible<T,A&>::value, unspecified_type* >::type _ = nullptr)
: var(a)
{ cout << "with allocator" << endl; }
template<class A>
explicit with_allocator(A& a, typename enable_if<!is_constructible<T,A&>::value, unspecified_type* >::type _ = nullptr)
{ cout << "without allocator" << endl; }
};
void run(foo&, bar&) { cout << "run(foo,bar)" << endl; }
int main() {
// your code goes here
alfa a;
with_allocator<foo> f (a);
with_allocator<bar> b (a);
run(*f, *b);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgpzdHJ1Y3QgYWxmYSB7fTsKCnN0cnVjdCBmb28geyBmb28oKSB7IGNvdXQgPDwgImZvbyh2b2lkKSIgPDwgZW5kbDsgfX07CgpzdHJ1Y3QgYmFyIHsgZXhwbGljaXQgYmFyKGFsZmEmKSB7IGNvdXQgPDwgImJhcihhbGZhJikiIDw8IGVuZGw7IH0gfTsKCnRlbXBsYXRlPGNsYXNzIFQ+IHN0cnVjdCB3aXRoX2FsbG9jYXRvcgp7CglzdHJ1Y3QgdW5zcGVjaWZpZWRfdHlwZTsKCglUIHZhcjsKCVQmIG9wZXJhdG9yKigpIHsgcmV0dXJuIHZhcjsgfQoJVCBjb25zdCYgb3BlcmF0b3IqKCkgY29uc3QgeyByZXR1cm4gdmFyOyB9CgoJdGVtcGxhdGU8Y2xhc3MgQT4KCWV4cGxpY2l0IHdpdGhfYWxsb2NhdG9yKEEmIGEsIHR5cGVuYW1lIGVuYWJsZV9pZjwgaXNfY29uc3RydWN0aWJsZTxULEEmPjo6dmFsdWUsIHVuc3BlY2lmaWVkX3R5cGUqID46OnR5cGUgXyA9IG51bGxwdHIpCgk6IHZhcihhKQoJeyBjb3V0IDw8ICJ3aXRoIGFsbG9jYXRvciIgPDwgZW5kbDsgfQoJCgl0ZW1wbGF0ZTxjbGFzcyBBPgoJZXhwbGljaXQgd2l0aF9hbGxvY2F0b3IoQSYgYSwgdHlwZW5hbWUgZW5hYmxlX2lmPCFpc19jb25zdHJ1Y3RpYmxlPFQsQSY+Ojp2YWx1ZSwgdW5zcGVjaWZpZWRfdHlwZSogPjo6dHlwZSBfID0gbnVsbHB0cikKCXsgY291dCA8PCAid2l0aG91dCBhbGxvY2F0b3IiIDw8IGVuZGw7IH0KfTsKCnZvaWQgcnVuKGZvbyYsIGJhciYpIHsgY291dCA8PCAicnVuKGZvbyxiYXIpIiA8PCBlbmRsOyB9CgppbnQgbWFpbigpIHsKCS8vIHlvdXIgY29kZSBnb2VzIGhlcmUKCWFsZmEgYTsKCQoJd2l0aF9hbGxvY2F0b3I8Zm9vPiBmIChhKTsKCXdpdGhfYWxsb2NhdG9yPGJhcj4gYiAoYSk7CgkKCXJ1bigqZiwgKmIpOwoJcmV0dXJuIDA7Cn0K