#include <iostream>
#include <type_traits>
// List of factors
template<std::intmax_t ... Misc>
struct factors { };
// Declaration
template<std::intmax_t ... Misc>
struct factorization;
// Initial specialization
template<std::intmax_t Value>
struct factorization<Value>
{
typedef typename std::conditional<Value % 2 == 0,
typename factorization<Value / 2, 2, 2>::type,
typename factorization<Value / 2, 2 + 1>::type>::type type;
};
// Initial specialization when the value is not divisible by 2
template<std::intmax_t Value, std::intmax_t Divisor>
struct factorization<Value, Divisor>
{
typedef typename std::conditional<Value % Divisor == 0,
typename factorization<Value / Divisor, Divisor, Divisor>::type,
typename factorization<Value / Divisor, Divisor + 1>::type>::type type;
};
// Specialization after the first recusion step
template<std::intmax_t Value, std::intmax_t Divisor, std::intmax_t Prime>
struct factorization<Value, Divisor, Prime>
{
typedef typename std::conditional<Value % Divisor == 0,
typename factorization<Value / Divisor, Divisor, Divisor>::type,
typename factorization<Value / Divisor, Divisor + 1>::type>::type type;
};
// Recursion specialization
template<std::intmax_t Value, std::intmax_t Divisor, std::intmax_t Prime, std::intmax_t ... Primes>
struct factorization<Value, Divisor, Prime, Primes...>
{
typedef typename std::conditional<Value % Divisor == 0 && Divisor != Prime,
typename factorization<Value / Divisor, Divisor, Divisor, Prime,
Primes...>::type,
typename factorization<
Value % Divisor == 0 ? Value / Divisor : Value,
Divisor + (Value % Divisor != 0), Prime, Primes...>::type>::type type;
};
// Last recursion step
template<std::intmax_t Value, std::intmax_t ... Primes>
struct factorization<Value, Value, Primes...>
{
typedef typename factorization<1, Value, Value, Primes...>::type type;
};
// Finalize
template<std::intmax_t Divisor, std::intmax_t ... Primes>
struct factorization<1, Divisor, Primes...>
{
typedef factors<Primes...> type;
};
// Main
int main() {
typename factorization<18>::type x;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgovLyBMaXN0IG9mIGZhY3RvcnMKdGVtcGxhdGU8c3RkOjppbnRtYXhfdCAuLi4gTWlzYz4gCnN0cnVjdCBmYWN0b3JzIHsgfTsKCi8vIERlY2xhcmF0aW9uCnRlbXBsYXRlPHN0ZDo6aW50bWF4X3QgLi4uIE1pc2M+IApzdHJ1Y3QgZmFjdG9yaXphdGlvbjsKCi8vIEluaXRpYWwgc3BlY2lhbGl6YXRpb24KdGVtcGxhdGU8c3RkOjppbnRtYXhfdCBWYWx1ZT4gCnN0cnVjdCBmYWN0b3JpemF0aW9uPFZhbHVlPgp7CiAgICB0eXBlZGVmIHR5cGVuYW1lIHN0ZDo6Y29uZGl0aW9uYWw8VmFsdWUgJSAyID09IDAsCiAgICAgICAgICAgIHR5cGVuYW1lIGZhY3Rvcml6YXRpb248VmFsdWUgLyAyLCAyLCAyPjo6dHlwZSwKICAgICAgICAgICAgdHlwZW5hbWUgZmFjdG9yaXphdGlvbjxWYWx1ZSAvIDIsIDIgKyAxPjo6dHlwZT46OnR5cGUgdHlwZTsKfTsKCi8vIEluaXRpYWwgc3BlY2lhbGl6YXRpb24gd2hlbiB0aGUgdmFsdWUgaXMgbm90IGRpdmlzaWJsZSBieSAyCnRlbXBsYXRlPHN0ZDo6aW50bWF4X3QgVmFsdWUsIHN0ZDo6aW50bWF4X3QgRGl2aXNvcj4gCnN0cnVjdCBmYWN0b3JpemF0aW9uPFZhbHVlLCBEaXZpc29yPgp7CiAgICB0eXBlZGVmIHR5cGVuYW1lIHN0ZDo6Y29uZGl0aW9uYWw8VmFsdWUgJSBEaXZpc29yID09IDAsCiAgICAgICAgICAgIHR5cGVuYW1lIGZhY3Rvcml6YXRpb248VmFsdWUgLyBEaXZpc29yLCBEaXZpc29yLCBEaXZpc29yPjo6dHlwZSwKICAgICAgICAgICAgdHlwZW5hbWUgZmFjdG9yaXphdGlvbjxWYWx1ZSAvIERpdmlzb3IsIERpdmlzb3IgKyAxPjo6dHlwZT46OnR5cGUgdHlwZTsKfTsKCi8vIFNwZWNpYWxpemF0aW9uIGFmdGVyIHRoZSBmaXJzdCByZWN1c2lvbiBzdGVwCnRlbXBsYXRlPHN0ZDo6aW50bWF4X3QgVmFsdWUsIHN0ZDo6aW50bWF4X3QgRGl2aXNvciwgc3RkOjppbnRtYXhfdCBQcmltZT4gCnN0cnVjdCBmYWN0b3JpemF0aW9uPFZhbHVlLCBEaXZpc29yLCBQcmltZT4KewogICAgdHlwZWRlZiB0eXBlbmFtZSBzdGQ6OmNvbmRpdGlvbmFsPFZhbHVlICUgRGl2aXNvciA9PSAwLAogICAgICAgICAgICB0eXBlbmFtZSBmYWN0b3JpemF0aW9uPFZhbHVlIC8gRGl2aXNvciwgRGl2aXNvciwgRGl2aXNvcj46OnR5cGUsCiAgICAgICAgICAgIHR5cGVuYW1lIGZhY3Rvcml6YXRpb248VmFsdWUgLyBEaXZpc29yLCBEaXZpc29yICsgMT46OnR5cGU+Ojp0eXBlIHR5cGU7Cn07CgovLyBSZWN1cnNpb24gc3BlY2lhbGl6YXRpb24KdGVtcGxhdGU8c3RkOjppbnRtYXhfdCBWYWx1ZSwgc3RkOjppbnRtYXhfdCBEaXZpc29yLCBzdGQ6OmludG1heF90IFByaW1lLCBzdGQ6OmludG1heF90IC4uLiBQcmltZXM+IApzdHJ1Y3QgZmFjdG9yaXphdGlvbjxWYWx1ZSwgRGl2aXNvciwgUHJpbWUsIFByaW1lcy4uLj4KewogICAgdHlwZWRlZiB0eXBlbmFtZSBzdGQ6OmNvbmRpdGlvbmFsPFZhbHVlICUgRGl2aXNvciA9PSAwICYmIERpdmlzb3IgIT0gUHJpbWUsCiAgICAgICAgICAgIHR5cGVuYW1lIGZhY3Rvcml6YXRpb248VmFsdWUgLyBEaXZpc29yLCBEaXZpc29yLCBEaXZpc29yLCBQcmltZSwKICAgICAgICAgICAgICAgICAgICBQcmltZXMuLi4+Ojp0eXBlLAogICAgICAgICAgICB0eXBlbmFtZSBmYWN0b3JpemF0aW9uPAogICAgICAgICAgICAgICAgICAgIFZhbHVlICUgRGl2aXNvciA9PSAwID8gVmFsdWUgLyBEaXZpc29yIDogVmFsdWUsCiAgICAgICAgICAgICAgICAgICAgRGl2aXNvciArIChWYWx1ZSAlIERpdmlzb3IgIT0gMCksIFByaW1lLCBQcmltZXMuLi4+Ojp0eXBlPjo6dHlwZSB0eXBlOwp9OwoKLy8gTGFzdCByZWN1cnNpb24gc3RlcAp0ZW1wbGF0ZTxzdGQ6OmludG1heF90IFZhbHVlLCBzdGQ6OmludG1heF90IC4uLiBQcmltZXM+IApzdHJ1Y3QgZmFjdG9yaXphdGlvbjxWYWx1ZSwgVmFsdWUsIFByaW1lcy4uLj4KewogICAgdHlwZWRlZiB0eXBlbmFtZSBmYWN0b3JpemF0aW9uPDEsIFZhbHVlLCBWYWx1ZSwgUHJpbWVzLi4uPjo6dHlwZSB0eXBlOwp9OwoKLy8gRmluYWxpemUKdGVtcGxhdGU8c3RkOjppbnRtYXhfdCBEaXZpc29yLCBzdGQ6OmludG1heF90IC4uLiBQcmltZXM+IApzdHJ1Y3QgZmFjdG9yaXphdGlvbjwxLCBEaXZpc29yLCBQcmltZXMuLi4+CnsKICAgIHR5cGVkZWYgZmFjdG9yczxQcmltZXMuLi4+IHR5cGU7Cn07CgovLyBNYWluCmludCBtYWluKCkgewoJdHlwZW5hbWUgZmFjdG9yaXphdGlvbjwxOD46OnR5cGUgeDsKCXJldHVybiAwOwp9
prog.cpp: In instantiation of ‘struct factorization<4ll, 2ll, 2ll>’:
prog.cpp:36:79: required from ‘struct factorization<9ll, 2ll, 2ll>’
prog.cpp:18:67: required from ‘struct factorization<18ll>’
prog.cpp:67:28: required from here
prog.cpp:36:79: error: ambiguous class template instantiation for ‘struct factorization<2ll, 2ll, 2ll>’
typename factorization<Value / Divisor, Divisor + 1>::type>::type type;
^
prog.cpp:32:8: error: candidates are: struct factorization<Value, Divisor, Prime>
struct factorization<Value, Divisor, Prime>
^
prog.cpp:41:8: error: struct factorization<Value, Divisor, Prime, Primes ...>
struct factorization<Value, Divisor, Prime, Primes...>
^
prog.cpp:53:8: error: struct factorization<Value, Value, Primes ...>
struct factorization<Value, Value, Primes...>
^
prog.cpp:36:79: error: invalid use of incomplete type ‘struct factorization<2ll, 2ll, 2ll>’
typename factorization<Value / Divisor, Divisor + 1>::type>::type type;
^
prog.cpp:10:8: error: declaration of ‘struct factorization<2ll, 2ll, 2ll>’
struct factorization;
^
prog.cpp: In function ‘int main()’:
prog.cpp:67:30: error: invalid combination of multiple type-specifiers
typename factorization<18>::type x;
^
prog.cpp:67:36: error: invalid type in declaration before ‘;’ token
typename factorization<18>::type x;
^
prog.cpp:67:35: warning: unused variable ‘x’ [-Wunused-variable]
typename factorization<18>::type x;
^