#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <valarray>
#include <string>
template <template <typename ...> class P, typename ... Args>
void f(const P<Args...> &p) { std::cout << sizeof...(Args) << " parameters! " << __PRETTY_FUNCTION__ << '\n'; }
template <template <typename ...> class P, typename ... Args>
struct c
{
using type = P<Args...>;
const std::size_t count = sizeof...(Args);
void f(const type &t) { std::cout << sizeof...(Args) << " parameters! " << __PRETTY_FUNCTION__ << '\n'; }
};
template <template <typename, typename> class P, typename A, typename B>
struct c<P, A, B>
{
using type = P<A, B>;
void f(const type &t) { std::cout << "Specialized --> " << __PRETTY_FUNCTION__ << '\n'; }
};
int main()
{
f(std::valarray<int>{});
f(std::pair<char, char>{});
f(std::vector<double>{});
f(std::set<float>{});
f(std::map<int, int>{});
std::cout << '\n';
c<std::valarray, int> c_valarray_int;
c<std::pair, int, char> c_pair_int_char;
c<std::vector, int, std::allocator<int>> c_vector_int;
c<std::map, int, int> c_map_int_int;
c_valarray_int.f({});
c_pair_int_char.f({});
c_vector_int.f({});
c_map_int_int.f({});
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWFwPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8c2V0PgojaW5jbHVkZSA8dmFsYXJyYXk+CiNpbmNsdWRlIDxzdHJpbmc+Cgp0ZW1wbGF0ZSA8dGVtcGxhdGUgPHR5cGVuYW1lIC4uLj4gY2xhc3MgUCwgdHlwZW5hbWUgLi4uIEFyZ3M+CnZvaWQgZihjb25zdCBQPEFyZ3MuLi4+ICZwKSB7IHN0ZDo6Y291dCA8PCBzaXplb2YuLi4oQXJncykgPDwgIiBwYXJhbWV0ZXJzISAiIDw8IF9fUFJFVFRZX0ZVTkNUSU9OX18gPDwgJ1xuJzsgIH0KCnRlbXBsYXRlIDx0ZW1wbGF0ZSA8dHlwZW5hbWUgLi4uPiBjbGFzcyBQLCB0eXBlbmFtZSAuLi4gQXJncz4Kc3RydWN0IGMKewoJdXNpbmcgdHlwZSA9IFA8QXJncy4uLj47IAoJY29uc3Qgc3RkOjpzaXplX3QgY291bnQgPSBzaXplb2YuLi4oQXJncyk7CgoJdm9pZCBmKGNvbnN0IHR5cGUgJnQpIHsgc3RkOjpjb3V0IDw8IHNpemVvZi4uLihBcmdzKSA8PCAiIHBhcmFtZXRlcnMhICIgPDwgX19QUkVUVFlfRlVOQ1RJT05fXyA8PCAnXG4nOyAgfQp9OwoKdGVtcGxhdGUgPHRlbXBsYXRlIDx0eXBlbmFtZSwgdHlwZW5hbWU+IGNsYXNzIFAsIHR5cGVuYW1lIEEsIHR5cGVuYW1lIEI+CnN0cnVjdCBjPFAsIEEsIEI+IAp7Cgl1c2luZyB0eXBlID0gUDxBLCBCPjsgCgoJdm9pZCBmKGNvbnN0IHR5cGUgJnQpIHsgc3RkOjpjb3V0IDw8ICJTcGVjaWFsaXplZCAtLT4gIiA8PCBfX1BSRVRUWV9GVU5DVElPTl9fIDw8ICdcbic7ICB9Cn07CgppbnQgbWFpbigpCnsKCWYoc3RkOjp2YWxhcnJheTxpbnQ+e30pOwoJZihzdGQ6OnBhaXI8Y2hhciwgY2hhcj57fSk7CglmKHN0ZDo6dmVjdG9yPGRvdWJsZT57fSk7CglmKHN0ZDo6c2V0PGZsb2F0Pnt9KTsKCWYoc3RkOjptYXA8aW50LCBpbnQ+e30pOwoJc3RkOjpjb3V0IDw8ICdcbic7CgljPHN0ZDo6dmFsYXJyYXksIGludD4gY192YWxhcnJheV9pbnQ7CgljPHN0ZDo6cGFpciwgaW50LCBjaGFyPiBjX3BhaXJfaW50X2NoYXI7CgljPHN0ZDo6dmVjdG9yLCBpbnQsIHN0ZDo6YWxsb2NhdG9yPGludD4+IGNfdmVjdG9yX2ludDsKCWM8c3RkOjptYXAsIGludCwgaW50PiBjX21hcF9pbnRfaW50OwoKCWNfdmFsYXJyYXlfaW50LmYoe30pOwoJY19wYWlyX2ludF9jaGFyLmYoe30pOwoJY192ZWN0b3JfaW50LmYoe30pOwoJY19tYXBfaW50X2ludC5mKHt9KTsKCglyZXR1cm4gMDsKfQ==
1 parameters! void f(const P<Args ...>&) [with P = std::valarray; Args = {int}]
2 parameters! void f(const P<Args ...>&) [with P = std::pair; Args = {char, char}]
2 parameters! void f(const P<Args ...>&) [with P = std::vector; Args = {double, std::allocator<double>}]
3 parameters! void f(const P<Args ...>&) [with P = std::set; Args = {float, std::less<float>, std::allocator<float>}]
4 parameters! void f(const P<Args ...>&) [with P = std::map; Args = {int, int, std::less<int>, std::allocator<std::pair<const int, int> >}]
1 parameters! void c<P, Args>::f(const type&) [with P = std::valarray; Args = {int}; c<P, Args>::type = std::valarray<int>]
Specialized --> void c<P, A, B>::f(const type&) [with P = std::pair; A = int; B = char; c<P, A, B>::type = std::pair<int, char>]
Specialized --> void c<P, A, B>::f(const type&) [with P = std::vector; A = int; B = std::allocator<int>; c<P, A, B>::type = std::vector<int, std::allocator<int> >]
2 parameters! void c<P, Args>::f(const type&) [with P = std::map; Args = {int, int}; c<P, Args>::type = std::map<int, int>]