#include <iostream>
#include <utility>
#include <type_traits>
namespace details {
template<class...>struct types{using type=types;};
template<class U, class Types, class=void>
struct smart_cast_t:std::false_type {
using type=U;
template<class A>
U operator()(A&& a)const{return std::forward<A>(a);}
};
template<class U, class T0, class...Ts>
struct smart_cast_t<
U, types<T0, Ts...>,
typename std::enable_if<std::is_convertible<U, T0>::value>::type
>:std::true_type
{
using type=T0;
template<class A>
T0 operator()(A&& a)const{return std::forward<A>(a);}
};
template<class U, class T0, class...Ts>
struct smart_cast_t<
U, types<T0, Ts...>,
typename std::enable_if<!std::is_convertible<U, T0>::value>::type
>:smart_cast_t< U, types<Ts...> >
{};
}
template<class... Ts, class U>
auto smart_cast( U&& u )
-> decltype(details::smart_cast_t< U, details::types<Ts...> >{}( std::forward<U>(u) ))
{
return details::smart_cast_t< U, details::types<Ts...> >{}( std::forward<U>(u) );
}
int main() {
std::cout << smart_cast< char, double >( int('a') ) << "\n";
std::cout << smart_cast< double, char >( int('a') ) << "\n";
// your code goes here
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dXRpbGl0eT4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKICAgIG5hbWVzcGFjZSBkZXRhaWxzIHsKICAgICAgdGVtcGxhdGU8Y2xhc3MuLi4+c3RydWN0IHR5cGVze3VzaW5nIHR5cGU9dHlwZXM7fTsKICAgICAgdGVtcGxhdGU8Y2xhc3MgVSwgY2xhc3MgVHlwZXMsIGNsYXNzPXZvaWQ+CiAgICAgIHN0cnVjdCBzbWFydF9jYXN0X3Q6c3RkOjpmYWxzZV90eXBlIHsKICAgICAgICB1c2luZyB0eXBlPVU7CiAgICAgICAgdGVtcGxhdGU8Y2xhc3MgQT4KICAgICAgICBVIG9wZXJhdG9yKCkoQSYmIGEpY29uc3R7cmV0dXJuIHN0ZDo6Zm9yd2FyZDxBPihhKTt9CiAgICAgIH07CiAgICAgIHRlbXBsYXRlPGNsYXNzIFUsIGNsYXNzIFQwLCBjbGFzcy4uLlRzPgogICAgICBzdHJ1Y3Qgc21hcnRfY2FzdF90PAogICAgICAgIFUsIHR5cGVzPFQwLCBUcy4uLj4sCiAgICAgICAgdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8c3RkOjppc19jb252ZXJ0aWJsZTxVLCBUMD46OnZhbHVlPjo6dHlwZQogICAgICA+OnN0ZDo6dHJ1ZV90eXBlCiAgICAgIHsKICAgICAgICB1c2luZyB0eXBlPVQwOwogICAgICAgIHRlbXBsYXRlPGNsYXNzIEE+CiAgICAgICAgVDAgb3BlcmF0b3IoKShBJiYgYSljb25zdHtyZXR1cm4gc3RkOjpmb3J3YXJkPEE+KGEpO30KICAgICAgfTsKICAgICAgdGVtcGxhdGU8Y2xhc3MgVSwgY2xhc3MgVDAsIGNsYXNzLi4uVHM+CiAgICAgIHN0cnVjdCBzbWFydF9jYXN0X3Q8CiAgICAgICAgVSwgdHlwZXM8VDAsIFRzLi4uPiwKICAgICAgICB0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjwhc3RkOjppc19jb252ZXJ0aWJsZTxVLCBUMD46OnZhbHVlPjo6dHlwZQogICAgICA+OnNtYXJ0X2Nhc3RfdDwgVSwgdHlwZXM8VHMuLi4+ID4KICAgICAge307CiAgICB9CiAgICAKICAgIHRlbXBsYXRlPGNsYXNzLi4uIFRzLCBjbGFzcyBVPgogICAgYXV0byBzbWFydF9jYXN0KCBVJiYgdSApCiAgICAtPiBkZWNsdHlwZShkZXRhaWxzOjpzbWFydF9jYXN0X3Q8IFUsIGRldGFpbHM6OnR5cGVzPFRzLi4uPiA+e30oIHN0ZDo6Zm9yd2FyZDxVPih1KSApKQogICAgewogICAgICByZXR1cm4gZGV0YWlsczo6c21hcnRfY2FzdF90PCBVLCBkZXRhaWxzOjp0eXBlczxUcy4uLj4gPnt9KCBzdGQ6OmZvcndhcmQ8VT4odSkgKTsKICAgIH0KCmludCBtYWluKCkgewoJc3RkOjpjb3V0IDw8IHNtYXJ0X2Nhc3Q8IGNoYXIsIGRvdWJsZSA+KCBpbnQoJ2EnKSApIDw8ICJcbiI7CglzdGQ6OmNvdXQgPDwgc21hcnRfY2FzdDwgZG91YmxlLCBjaGFyID4oIGludCgnYScpICkgPDwgIlxuIjsKCS8vIHlvdXIgY29kZSBnb2VzIGhlcmUKCXJldHVybiAwOwp9