#include <cassert>
#include <type_traits>
using std::is_same;
using std::declval;
using std::integral_constant;
using std::true_type;
using std::false_type;
using std::enable_if;
template <bool B, typename T = void>
using enable_if_t = typename enable_if<B, T>::type;
template <typename...> struct void_type { using type = void; };
template <typename... Ts> using void_t = typename void_type<Ts...>::type;
#define TYPIFY(x) integral_constant<decltype((x)), (x)>
#define DETYPIFY(x) x::value
// structure representing an array of types
template <typename...> struct type_array {};
/**** example starts here ****/
template <typename FirstCoef, typename T>
T combine(type_array<FirstCoef>, const T &value) {
return DETYPIFY(FirstCoef) * value;
}
template <typename FirstCoef, typename... OtherCoefs,
typename T, typename... Ts>
T combine(
type_array<FirstCoef, OtherCoefs...>, // dummy parameter
const T &value, const Ts &... other_values) {
return DETYPIFY(FirstCoef) * value +
combine(type_array<OtherCoefs...>{}, other_values...);
}
int main() {
using coefs = type_array<TYPIFY(5), TYPIFY(2), TYPIFY(3)>;
assert(combine(coefs{}, 1, 3, 2) == 5 + 3 * 2 + 3 * 2);
}
I2luY2x1ZGUgPGNhc3NlcnQ+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KCnVzaW5nIHN0ZDo6aXNfc2FtZTsKdXNpbmcgc3RkOjpkZWNsdmFsOwp1c2luZyBzdGQ6OmludGVncmFsX2NvbnN0YW50Owp1c2luZyBzdGQ6OnRydWVfdHlwZTsKdXNpbmcgc3RkOjpmYWxzZV90eXBlOwp1c2luZyBzdGQ6OmVuYWJsZV9pZjsKCnRlbXBsYXRlIDxib29sIEIsIHR5cGVuYW1lIFQgPSB2b2lkPgp1c2luZyBlbmFibGVfaWZfdCA9IHR5cGVuYW1lIGVuYWJsZV9pZjxCLCBUPjo6dHlwZTsKCnRlbXBsYXRlIDx0eXBlbmFtZS4uLj4gc3RydWN0IHZvaWRfdHlwZSB7IHVzaW5nIHR5cGUgPSB2b2lkOyB9Owp0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gVHM+IHVzaW5nIHZvaWRfdCA9IHR5cGVuYW1lIHZvaWRfdHlwZTxUcy4uLj46OnR5cGU7CgojZGVmaW5lIFRZUElGWSh4KSBpbnRlZ3JhbF9jb25zdGFudDxkZWNsdHlwZSgoeCkpLCAoeCk+CiNkZWZpbmUgREVUWVBJRlkoeCkgeDo6dmFsdWUKCi8vIHN0cnVjdHVyZSByZXByZXNlbnRpbmcgYW4gYXJyYXkgb2YgdHlwZXMKdGVtcGxhdGUgPHR5cGVuYW1lLi4uPiBzdHJ1Y3QgdHlwZV9hcnJheSB7fTsKCgovKioqKiBleGFtcGxlIHN0YXJ0cyBoZXJlICoqKiovCgoKdGVtcGxhdGUgPHR5cGVuYW1lIEZpcnN0Q29lZiwgdHlwZW5hbWUgVD4KVCBjb21iaW5lKHR5cGVfYXJyYXk8Rmlyc3RDb2VmPiwgY29uc3QgVCAmdmFsdWUpIHsKICAgIHJldHVybiBERVRZUElGWShGaXJzdENvZWYpICogdmFsdWU7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBGaXJzdENvZWYsIHR5cGVuYW1lLi4uIE90aGVyQ29lZnMsCiAgICAgICAgICB0eXBlbmFtZSBULCB0eXBlbmFtZS4uLiBUcz4KVCBjb21iaW5lKAogICAgdHlwZV9hcnJheTxGaXJzdENvZWYsIE90aGVyQ29lZnMuLi4+LCAvLyBkdW1teSBwYXJhbWV0ZXIKICAgIGNvbnN0IFQgJnZhbHVlLCBjb25zdCBUcyAmLi4uIG90aGVyX3ZhbHVlcykgewogICAgcmV0dXJuIERFVFlQSUZZKEZpcnN0Q29lZikgKiB2YWx1ZSArCiAgICAgICAgY29tYmluZSh0eXBlX2FycmF5PE90aGVyQ29lZnMuLi4+e30sIG90aGVyX3ZhbHVlcy4uLik7Cn0KCgppbnQgbWFpbigpIHsKICAgIHVzaW5nIGNvZWZzID0gdHlwZV9hcnJheTxUWVBJRlkoNSksIFRZUElGWSgyKSwgVFlQSUZZKDMpPjsKICAgIGFzc2VydChjb21iaW5lKGNvZWZze30sIDEsIDMsIDIpID09IDUgKyAzICogMiArIDMgKiAyKTsKfQ==