#include <assert.h>
// Helper to map any type to void, needed by SFINAE below
template <typename T>
struct void_type {
typedef void type;
};
// Selects a nested typedef or a default type D (using a macro to reduce boilerplate):
#define SELECT_NESTED_TYPE( TYPE ) \
template <typename T, typename D, typename _ = void> \
struct select_##TYPE{ \
typedef D type; \
}; \
template <typename T, typename D> \
struct select_##TYPE<T, D, typename void_type<typename T::TYPE>::type> { \
typedef typename T::TYPE type; \
};
SELECT_NESTED_TYPE( int_t );
SELECT_NESTED_TYPE( float_t );
//...
#undef SELECT_NESTED_TYPE
// Use
template <typename T>
class TheTemplate {
public:
typedef typename select_int_t<T,int>::type int_t;
typedef typename select_float_t<T,double>::type float_t;
//....
};
// Test:
template <typename T, typename U> struct same_type {
static const bool value = false;
};
template <typename T> struct same_type<T,T> {
static const bool value = true;
};
struct test1 {
};
struct test2 {
typedef long long int_t;
typedef float float_t;
};
int main() {
// test1 has the default typedefs
assert(( same_type< TheTemplate<test1>::int_t, int>::value ));
assert(( same_type< TheTemplate<test1>::float_t, double>::value ));
// test2 has the ones in the type
assert(( same_type< TheTemplate<test2>::int_t, long long>::value ));
assert(( same_type< TheTemplate<test2>::float_t, float>::value ));
}
I2luY2x1ZGUgPGFzc2VydC5oPgoKLy8gSGVscGVyIHRvIG1hcCBhbnkgdHlwZSB0byB2b2lkLCBuZWVkZWQgYnkgU0ZJTkFFIGJlbG93CnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdHJ1Y3Qgdm9pZF90eXBlIHsKICAgIHR5cGVkZWYgdm9pZCB0eXBlOwp9OwoKLy8gU2VsZWN0cyBhIG5lc3RlZCB0eXBlZGVmIG9yIGEgZGVmYXVsdCB0eXBlIEQgKHVzaW5nIGEgbWFjcm8gdG8gcmVkdWNlIGJvaWxlcnBsYXRlKToKI2RlZmluZSBTRUxFQ1RfTkVTVEVEX1RZUEUoIFRZUEUgKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEQsIHR5cGVuYW1lIF8gPSB2b2lkPiAgICAgICAgICAgICAgICAgICAgIFwKc3RydWN0IHNlbGVjdF8jI1RZUEV7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIHR5cGVkZWYgRCB0eXBlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEQ+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKc3RydWN0IHNlbGVjdF8jI1RZUEU8VCwgRCwgdHlwZW5hbWUgdm9pZF90eXBlPHR5cGVuYW1lIFQ6OlRZUEU+Ojp0eXBlPiB7IFwKICAgIHR5cGVkZWYgdHlwZW5hbWUgVDo6VFlQRSB0eXBlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCgpTRUxFQ1RfTkVTVEVEX1RZUEUoIGludF90ICk7ClNFTEVDVF9ORVNURURfVFlQRSggZmxvYXRfdCApOwovLy4uLgojdW5kZWYgU0VMRUNUX05FU1RFRF9UWVBFCgovLyBVc2UKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CmNsYXNzIFRoZVRlbXBsYXRlIHsKcHVibGljOgogICB0eXBlZGVmIHR5cGVuYW1lIHNlbGVjdF9pbnRfdDxULGludD46OnR5cGUgaW50X3Q7CiAgIHR5cGVkZWYgdHlwZW5hbWUgc2VsZWN0X2Zsb2F0X3Q8VCxkb3VibGU+Ojp0eXBlIGZsb2F0X3Q7CiAgIC8vLi4uLgp9OwoKLy8gVGVzdDoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFU+IHN0cnVjdCBzYW1lX3R5cGUgewogICBzdGF0aWMgY29uc3QgYm9vbCB2YWx1ZSA9IGZhbHNlOwp9Owp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gc3RydWN0IHNhbWVfdHlwZTxULFQ+IHsKICAgc3RhdGljIGNvbnN0IGJvb2wgdmFsdWUgPSB0cnVlOwp9OwpzdHJ1Y3QgdGVzdDEgewp9OwpzdHJ1Y3QgdGVzdDIgewogICB0eXBlZGVmIGxvbmcgbG9uZyBpbnRfdDsKICAgdHlwZWRlZiBmbG9hdCBmbG9hdF90Owp9OwppbnQgbWFpbigpIHsKICAgLy8gdGVzdDEgaGFzIHRoZSBkZWZhdWx0IHR5cGVkZWZzCiAgIGFzc2VydCgoIHNhbWVfdHlwZTwgVGhlVGVtcGxhdGU8dGVzdDE+OjppbnRfdCwgaW50Pjo6dmFsdWUgKSk7CiAgIGFzc2VydCgoIHNhbWVfdHlwZTwgVGhlVGVtcGxhdGU8dGVzdDE+OjpmbG9hdF90LCBkb3VibGU+Ojp2YWx1ZSApKTsKICAgLy8gdGVzdDIgaGFzIHRoZSBvbmVzIGluIHRoZSB0eXBlCiAgIGFzc2VydCgoIHNhbWVfdHlwZTwgVGhlVGVtcGxhdGU8dGVzdDI+OjppbnRfdCwgbG9uZyBsb25nPjo6dmFsdWUgKSk7CiAgIGFzc2VydCgoIHNhbWVfdHlwZTwgVGhlVGVtcGxhdGU8dGVzdDI+OjpmbG9hdF90LCBmbG9hdD46OnZhbHVlICkpOwp9