#include <iostream>
using namespace std;
 
// Test struct.
template<class T>
struct Foo
{
    T foo;
};
 
// Struct specialization
template<>
struct Foo<bool>
{
    static const int val = 46;
};
 
// #1 Ordinary template
template<class T>
struct functionWrapper {
	static T foo() {
		return T();
	}
};
 
 
// #2 Template specialization
template<>
struct functionWrapper<int> {
	static int foo() {
		return 42;
	}
};
 
 
// #3 Template specialization with template as parameter
template<class T>
struct functionWrapper<struct Foo<T>> {
	static Foo<T>* foo() {
		return new Foo<T>();
	}
};
 
 
 
 
 
int main() {
	cout << functionWrapper<bool>::foo() << endl;
	cout << functionWrapper<int>::foo() << endl;
 
	Foo<bool> *obj = functionWrapper<Foo<bool>>::foo();
	cout << obj->val;
	delete obj;
 
	return 0;
}
				I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKLy8gVGVzdCBzdHJ1Y3QuCnRlbXBsYXRlPGNsYXNzIFQ+CnN0cnVjdCBGb28KewogICAgVCBmb287Cn07CgovLyBTdHJ1Y3Qgc3BlY2lhbGl6YXRpb24KdGVtcGxhdGU8PgpzdHJ1Y3QgRm9vPGJvb2w+CnsKICAgIHN0YXRpYyBjb25zdCBpbnQgdmFsID0gNDY7Cn07CgovLyAjMSBPcmRpbmFyeSB0ZW1wbGF0ZQp0ZW1wbGF0ZTxjbGFzcyBUPgpzdHJ1Y3QgZnVuY3Rpb25XcmFwcGVyIHsKCXN0YXRpYyBUIGZvbygpIHsKCQlyZXR1cm4gVCgpOwoJfQp9OwoKCi8vICMyIFRlbXBsYXRlIHNwZWNpYWxpemF0aW9uCnRlbXBsYXRlPD4Kc3RydWN0IGZ1bmN0aW9uV3JhcHBlcjxpbnQ+IHsKCXN0YXRpYyBpbnQgZm9vKCkgewoJCXJldHVybiA0MjsKCX0KfTsKCgovLyAjMyBUZW1wbGF0ZSBzcGVjaWFsaXphdGlvbiB3aXRoIHRlbXBsYXRlIGFzIHBhcmFtZXRlcgp0ZW1wbGF0ZTxjbGFzcyBUPgpzdHJ1Y3QgZnVuY3Rpb25XcmFwcGVyPHN0cnVjdCBGb288VD4+IHsKCXN0YXRpYyBGb288VD4qIGZvbygpIHsKCQlyZXR1cm4gbmV3IEZvbzxUPigpOwoJfQp9OwoKCgoKCmludCBtYWluKCkgewoJY291dCA8PCBmdW5jdGlvbldyYXBwZXI8Ym9vbD46OmZvbygpIDw8IGVuZGw7Cgljb3V0IDw8IGZ1bmN0aW9uV3JhcHBlcjxpbnQ+Ojpmb28oKSA8PCBlbmRsOwoJCglGb288Ym9vbD4gKm9iaiA9IGZ1bmN0aW9uV3JhcHBlcjxGb288Ym9vbD4+Ojpmb28oKTsKCWNvdXQgPDwgb2JqLT52YWw7CglkZWxldGUgb2JqOwoJCglyZXR1cm4gMDsKfQ==