#include <iostream>
#include <iomanip>
#include <type_traits>
#include <sstream>
template<typename T>
struct has_size_method
{
private:
typedef std::true_type yes;
typedef std::false_type no;
template<typename C>
static yes test(int (C::*f)() const){
return yes{};
}
template<typename C>
static yes test(size_t (C::*f)() const){
return yes{};
}
template<typename C>
static auto test(decltype(&C::size),void*) -> decltype(test(&C::size)){
return test(&C::size);
}
template<typename C>
static no test(...){
return no{};
}
public:
static constexpr bool value = std::is_same<decltype(test<T>(0,0)),yes>::value;
};
struct int_size{
int size() const { return 42; };
};
struct derived_int_size : int_size{};
struct size_t_size{
std::size_t size() const { return 42; }
};
struct derived_size_t_size : size_t_size{};
struct void_size{
void size() {}
};
struct no_size{};
struct template_int_size{
template<typename=int>
int size() const { return 42; }
};
struct overloaded_size{
size_t size() const { return 42; }
int size() { return 41; }
};
int main()
{
using namespace std;
#define dbg(x) { stringstream s; s << boolalpha << left << setw(8) << has_size_method<x>::value << #x; cout << s.str() << endl; }
dbg(int_size);
dbg(derived_int_size);
dbg(size_t_size);
dbg(derived_size_t_size);
dbg(void_size);
dbg(no_size);
dbg(template_int_size);
dbg(overloaded_size);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aW9tYW5pcD4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8c3N0cmVhbT4KCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBoYXNfc2l6ZV9tZXRob2QKewpwcml2YXRlOgogICAgICAgIHR5cGVkZWYgc3RkOjp0cnVlX3R5cGUgeWVzOwogICAgICAgIHR5cGVkZWYgc3RkOjpmYWxzZV90eXBlIG5vOwoKICAgICAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBDPgogICAgICAgIHN0YXRpYyB5ZXMgdGVzdChpbnQgKEM6OipmKSgpIGNvbnN0KXsKICAgICAgICAgICAgICAgIHJldHVybiB5ZXN7fTsKICAgICAgICB9CgogICAgICAgIHRlbXBsYXRlPHR5cGVuYW1lIEM+CiAgICAgICAgc3RhdGljIHllcyB0ZXN0KHNpemVfdCAoQzo6KmYpKCkgY29uc3QpewogICAgICAgICAgICAgICAgcmV0dXJuIHllc3t9OwogICAgICAgIH0KCiAgICAgICAgdGVtcGxhdGU8dHlwZW5hbWUgQz4KICAgICAgICBzdGF0aWMgYXV0byB0ZXN0KGRlY2x0eXBlKCZDOjpzaXplKSx2b2lkKikgLT4gZGVjbHR5cGUodGVzdCgmQzo6c2l6ZSkpewogICAgICAgICAgICAgICAgcmV0dXJuIHRlc3QoJkM6OnNpemUpOwogICAgICAgIH0KCiAgICAgICAgdGVtcGxhdGU8dHlwZW5hbWUgQz4KICAgICAgICBzdGF0aWMgbm8gdGVzdCguLi4pewogICAgICAgICAgICAgICAgcmV0dXJuIG5ve307CiAgICAgICAgfQoKcHVibGljOgoKICAgICAgICBzdGF0aWMgY29uc3RleHByIGJvb2wgdmFsdWUgPSBzdGQ6OmlzX3NhbWU8ZGVjbHR5cGUodGVzdDxUPigwLDApKSx5ZXM+Ojp2YWx1ZTsKfTsKCnN0cnVjdCBpbnRfc2l6ZXsKCWludCBzaXplKCkgY29uc3QgeyByZXR1cm4gNDI7IH07Cn07CgpzdHJ1Y3QgZGVyaXZlZF9pbnRfc2l6ZSA6IGludF9zaXple307CgpzdHJ1Y3Qgc2l6ZV90X3NpemV7CglzdGQ6OnNpemVfdCBzaXplKCkgY29uc3QgeyByZXR1cm4gNDI7IH0KfTsKCnN0cnVjdCBkZXJpdmVkX3NpemVfdF9zaXplIDogc2l6ZV90X3NpemV7fTsKCnN0cnVjdCB2b2lkX3NpemV7Cgl2b2lkIHNpemUoKSB7fQp9OwoKc3RydWN0IG5vX3NpemV7fTsKCnN0cnVjdCB0ZW1wbGF0ZV9pbnRfc2l6ZXsKCXRlbXBsYXRlPHR5cGVuYW1lPWludD4KCWludCBzaXplKCkgY29uc3QgeyByZXR1cm4gNDI7IH0KfTsKCnN0cnVjdCBvdmVybG9hZGVkX3NpemV7CglzaXplX3Qgc2l6ZSgpIGNvbnN0IHsgcmV0dXJuIDQyOyB9CglpbnQgc2l6ZSgpIHsgcmV0dXJuIDQxOyB9Cn07CgppbnQgbWFpbigpCnsKCXVzaW5nIG5hbWVzcGFjZSBzdGQ7CiNkZWZpbmUgZGJnKHgpIHsgc3RyaW5nc3RyZWFtIHM7IHMgPDwgYm9vbGFscGhhIDw8IGxlZnQgPDwgc2V0dyg4KSA8PCBoYXNfc2l6ZV9tZXRob2Q8eD46OnZhbHVlIDw8ICN4OyBjb3V0IDw8IHMuc3RyKCkgPDwgZW5kbDsgfQoKCWRiZyhpbnRfc2l6ZSk7CglkYmcoZGVyaXZlZF9pbnRfc2l6ZSk7CglkYmcoc2l6ZV90X3NpemUpOwoJZGJnKGRlcml2ZWRfc2l6ZV90X3NpemUpOwoJZGJnKHZvaWRfc2l6ZSk7CglkYmcobm9fc2l6ZSk7CglkYmcodGVtcGxhdGVfaW50X3NpemUpOwoJZGJnKG92ZXJsb2FkZWRfc2l6ZSk7Cn0=