#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <functional>
template <class T, class U>
class Conversion {
public:
Conversion(const std::function<U(const T&)>& f) : f(f) {}
U convert (const T& v) const { return f(v); }
private:
std::function<U(const T&)> f;
};
template <class T>
class Conversion<T,T> {
public:
T convert (const T& v) const { return v; }
};
template <class T>
class ConvertFunctions0 : public Conversion<T,T> {};
template <class T, class V1>
class ConvertFunctions1 : public Conversion<T,T>, public Conversion<T,V1> {
public:
ConvertFunctions1(std::function<V1(const T&)> f1) : Conversion<T,V1>(f1) {}
};
template <class T, class V1, class V2>
class ConvertFunctions2 : public Conversion<T,T>, public Conversion<T,V1>, public Conversion<T,V2> {
public:
ConvertFunctions2(std::function<V1(const T&)> f1, std::function<V2(const T&)> f2)
: Conversion<T,V1>(f1), Conversion<T,V2>(f2)
{}
};
template <class T, class CF>
class MultiUnitValue {
public:
MultiUnitValue(T v, const CF& cf) : v(v), cf(cf) {}
template <class U>
U in() const
{
return cf.Conversion<T,U>::convert(v);
}
private:
T v;
CF cf;
};
int main(){
auto f1 = [](int i){return i*2.54;};
auto f2 = [](int i){ std::stringstream ss; ss << i; return ss.str(); };
typedef ConvertFunctions2<int, float, std::string> CF_f1_f2;
MultiUnitValue<int, CF_f1_f2> vv(1, CF_f1_f2(f1, f2));
std::cout << vv.in<int>() << "\n";
std::cout << vv.in<float>() << "\n";
std::cout << vv.in<std::string>() << "\n";
// std::cout << vv.in<long>() << "\n"; // error to compile
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3N0cmVhbT4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+Cgp0ZW1wbGF0ZSA8Y2xhc3MgVCwgY2xhc3MgVT4KY2xhc3MgQ29udmVyc2lvbiB7CnB1YmxpYzoKICAgIENvbnZlcnNpb24oY29uc3Qgc3RkOjpmdW5jdGlvbjxVKGNvbnN0IFQmKT4mIGYpIDogZihmKSB7fQogICAgVSBjb252ZXJ0IChjb25zdCBUJiB2KSBjb25zdCB7IHJldHVybiBmKHYpOyB9CnByaXZhdGU6CiAgIHN0ZDo6ZnVuY3Rpb248VShjb25zdCBUJik+ICBmOwp9Owp0ZW1wbGF0ZSA8Y2xhc3MgVD4KY2xhc3MgQ29udmVyc2lvbjxULFQ+IHsKcHVibGljOgogICAgVCBjb252ZXJ0IChjb25zdCBUJiB2KSBjb25zdCB7IHJldHVybiB2OyB9Cn07CgoKdGVtcGxhdGUgPGNsYXNzIFQ+CmNsYXNzIENvbnZlcnRGdW5jdGlvbnMwIDogcHVibGljIENvbnZlcnNpb248VCxUPiB7fTsKCnRlbXBsYXRlIDxjbGFzcyBULCBjbGFzcyBWMT4KY2xhc3MgQ29udmVydEZ1bmN0aW9uczEgOiBwdWJsaWMgQ29udmVyc2lvbjxULFQ+LCBwdWJsaWMgQ29udmVyc2lvbjxULFYxPiB7CnB1YmxpYzoKICBDb252ZXJ0RnVuY3Rpb25zMShzdGQ6OmZ1bmN0aW9uPFYxKGNvbnN0IFQmKT4gZjEpIDogQ29udmVyc2lvbjxULFYxPihmMSkge30KfTsKCnRlbXBsYXRlIDxjbGFzcyBULCBjbGFzcyBWMSwgY2xhc3MgVjI+CmNsYXNzIENvbnZlcnRGdW5jdGlvbnMyIDogcHVibGljIENvbnZlcnNpb248VCxUPiwgcHVibGljIENvbnZlcnNpb248VCxWMT4sIHB1YmxpYyBDb252ZXJzaW9uPFQsVjI+IHsKcHVibGljOgogIENvbnZlcnRGdW5jdGlvbnMyKHN0ZDo6ZnVuY3Rpb248VjEoY29uc3QgVCYpPiBmMSwgc3RkOjpmdW5jdGlvbjxWMihjb25zdCBUJik+IGYyKSAKICA6IENvbnZlcnNpb248VCxWMT4oZjEpLCBDb252ZXJzaW9uPFQsVjI+KGYyKSAKICB7fQp9OwoKdGVtcGxhdGUgPGNsYXNzIFQsIGNsYXNzIENGPgpjbGFzcyBNdWx0aVVuaXRWYWx1ZSB7CnB1YmxpYzoKICAgTXVsdGlVbml0VmFsdWUoVCB2LCBjb25zdCBDRiYgY2YpIDogdih2KSwgY2YoY2YpIHt9CiAgIAogICB0ZW1wbGF0ZSA8Y2xhc3MgVT4KICAgVSBpbigpIGNvbnN0CiAgIHsKICAgICAgcmV0dXJuIGNmLkNvbnZlcnNpb248VCxVPjo6Y29udmVydCh2KTsKICAgfQoKcHJpdmF0ZToKICAgVCB2OwogICBDRiBjZjsKfTsKCmludCBtYWluKCl7CiAgYXV0byBmMSA9IFtdKGludCBpKXtyZXR1cm4gaSoyLjU0O307CiAgYXV0byBmMiA9IFtdKGludCBpKXsgc3RkOjpzdHJpbmdzdHJlYW0gc3M7IHNzIDw8IGk7IHJldHVybiBzcy5zdHIoKTsgfTsKICB0eXBlZGVmIENvbnZlcnRGdW5jdGlvbnMyPGludCwgZmxvYXQsIHN0ZDo6c3RyaW5nPiBDRl9mMV9mMjsKICBNdWx0aVVuaXRWYWx1ZTxpbnQsIENGX2YxX2YyPiAgdnYoMSwgQ0ZfZjFfZjIoZjEsIGYyKSk7CiAgc3RkOjpjb3V0IDw8IHZ2LmluPGludD4oKSA8PCAiXG4iOwogIHN0ZDo6Y291dCA8PCB2di5pbjxmbG9hdD4oKSA8PCAiXG4iOwogIHN0ZDo6Y291dCA8PCB2di5pbjxzdGQ6OnN0cmluZz4oKSA8PCAiXG4iOwogIC8vIHN0ZDo6Y291dCA8PCB2di5pbjxsb25nPigpIDw8ICJcbiI7IC8vIGVycm9yIHRvIGNvbXBpbGUKfQ==