#include <iostream>
#include <typeinfo>
// mapping :: TYPE -> TYPE
// ---------------------------------------------------------
// ?? --> int (default "value")
template<typename X> struct mapping {
using type = int;
};
// if instead you want it to be undefined for unknown types:
//template<typename X> struct mapping;
// bool --> double
template<> struct mapping<bool> {
using type = double;
};
// map :: ([T] -> T) -> (T -> T) -> ([T] -> T)
// "List" "Mapping" result "type" (also a "List")
// --------------------------------------------------------
template<template<typename...> class List,
template<typename> class Mapping>
struct map {
template<typename... Elements>
using type = List<typename Mapping<Elements>::type...>;
};
template<typename...> struct Example {};
template<typename... S>
using MappedExample = map<Example, mapping>::type<S...>;
template<typename... S>
MappedExample<S...> f() {
return MappedExample<S...>{};
}
int main() {
std::cout
<< typeid(Example<bool,int,char,double>).name()
<< std::endl
<< typeid(decltype(f<bool, int, char, double>())).name()
<< std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZWluZm8+CgovLyBtYXBwaW5nIDo6IFRZUEUgLT4gVFlQRQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gPz8gLS0+IGludCAoZGVmYXVsdCAidmFsdWUiKQp0ZW1wbGF0ZTx0eXBlbmFtZSBYPiBzdHJ1Y3QgbWFwcGluZyB7CiAgdXNpbmcgdHlwZSA9IGludDsKfTsKLy8gaWYgaW5zdGVhZCB5b3Ugd2FudCBpdCB0byBiZSB1bmRlZmluZWQgZm9yIHVua25vd24gdHlwZXM6Ci8vdGVtcGxhdGU8dHlwZW5hbWUgWD4gc3RydWN0IG1hcHBpbmc7Ci8vIGJvb2wgLS0+IGRvdWJsZQp0ZW1wbGF0ZTw+IHN0cnVjdCBtYXBwaW5nPGJvb2w+IHsKICB1c2luZyB0eXBlID0gZG91YmxlOwp9OwoKCgovLyBtYXAgOjogKFtUXSAtPiBUKSAtPiAoVCAtPiBUKSAtPiAoW1RdIC0+IFQpCi8vICAgICAgICAgIkxpc3QiICAgICAgICJNYXBwaW5nIiAgIHJlc3VsdCAidHlwZSIgKGFsc28gYSAiTGlzdCIpCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnRlbXBsYXRlPHRlbXBsYXRlPHR5cGVuYW1lLi4uPiBjbGFzcyBMaXN0LAogICAgICAgICB0ZW1wbGF0ZTx0eXBlbmFtZT4gY2xhc3MgTWFwcGluZz4Kc3RydWN0IG1hcCB7CiAgdGVtcGxhdGU8dHlwZW5hbWUuLi4gRWxlbWVudHM+CiAgdXNpbmcgdHlwZSA9IExpc3Q8dHlwZW5hbWUgTWFwcGluZzxFbGVtZW50cz46OnR5cGUuLi4+Owp9OwoKCnRlbXBsYXRlPHR5cGVuYW1lLi4uPiBzdHJ1Y3QgRXhhbXBsZSB7fTsKCgoKdGVtcGxhdGU8dHlwZW5hbWUuLi4gUz4KdXNpbmcgTWFwcGVkRXhhbXBsZSA9IG1hcDxFeGFtcGxlLCBtYXBwaW5nPjo6dHlwZTxTLi4uPjsKCnRlbXBsYXRlPHR5cGVuYW1lLi4uIFM+Ck1hcHBlZEV4YW1wbGU8Uy4uLj4gZigpIHsKICByZXR1cm4gTWFwcGVkRXhhbXBsZTxTLi4uPnt9Owp9CgoKaW50IG1haW4oKSB7CiAgc3RkOjpjb3V0CiAgICA8PCB0eXBlaWQoRXhhbXBsZTxib29sLGludCxjaGFyLGRvdWJsZT4pLm5hbWUoKQogICAgPDwgc3RkOjplbmRsCiAgICA8PCB0eXBlaWQoZGVjbHR5cGUoZjxib29sLCBpbnQsIGNoYXIsIGRvdWJsZT4oKSkpLm5hbWUoKQogICAgPDwgc3RkOjplbmRsOwp9