#include <cstddef>
namespace std {
template <typename T_, T_...>
struct value_sequence {
};
template <size_t... Is_>
using index_sequence = value_sequence<size_t, Is_...>;
namespace detail {
template <typename Seq_, size_t N_>
struct make_index_seq_impl_even;
template <size_t... Is_, size_t N_>
struct make_index_seq_impl_even<value_sequence<size_t, Is_...>, N_> {
using type = value_sequence<size_t, Is_..., (Is_ + N_)...>;
};
template <typename Seq_, size_t N_>
struct make_index_seq_impl_odd;
template <size_t... Is_, size_t N_>
struct make_index_seq_impl_odd<value_sequence<size_t, Is_...>, N_> {
using type = value_sequence<size_t, Is_..., (Is_ + N_)..., (2 * N_)>;
};
template <size_t N_, bool IsOdd_ = (N_ % 2)>
struct make_index_seq_impl {
using type = typename make_index_seq_impl_even<
typename make_index_seq_impl<N_ / 2>::type, N_ / 2>::type;
};
template <size_t N_>
struct make_index_seq_impl<N_, true> {
using type = typename make_index_seq_impl_odd<
typename make_index_seq_impl<N_ / 2>::type, N_ / 2>::type;
};
template <>
struct make_index_seq_impl<0, false> {
using type = value_sequence<size_t>;
};
namespace {
template <typename T>
constexpr inline
T
identity_transform(size_t i) {
return i;
}
}
template <typename IndexSeq_, typename T_, T_ (*F_)(size_t) = identity_transform<T_>>
struct transform_seq;
template <size_t... Is_, typename T_, T_(*F_)(size_t)>
struct transform_seq<index_sequence<Is_...>, T_, F_> {
using type = value_sequence<T_, F_(Is_)...>;
};
} // namespace detail
template <size_t N_>
using make_index_sequence = typename detail::make_index_seq_impl<N_>::type;
template <typename... Ts_>
using index_sequence_for = make_index_sequence<sizeof...(Ts_)>;
template <typename IndexSeq_, typename T_, T_ (*F_)(size_t) = detail::identity_transform<T_>>
using transform_sequence = typename detail::transform_seq<IndexSeq_, T_, F_>::type;
template <typename T_, T_ N_>
using make_integer_sequence = typename detail::transform_seq<make_index_sequence<N_>, T_>::type;
//using make_integer_sequence = transform_sequence<make_index_sequence<N_>, T_>>;
// ------------------------------------------------------------------------- //
}
#include <iostream>
template <size_t... Is>
size_t
size(std::index_sequence<Is...>) {
return sizeof...(Is);
}
template <typename... Ts>
void
swallow(Ts &&...) {
}
void
print(size_t n) {
std::cout << n << " ";
}
template <size_t... Is>
void
print(std::index_sequence<Is...>) {
swallow((print(Is), 0)...);
std::cout << "\n";
}
constexpr
size_t
mul2(size_t i) {
return 2 * i;
}
int
main() {
using Seq = std::make_index_sequence<2345>;
std::cout << "Seq size: " << size(Seq()) << "\n";
using Seq11 = std::make_index_sequence<11>;
print(Seq11());
using Seq11Even = std::transform_sequence<Seq11, size_t, mul2>;
// using Seq11Even = std::transform_sequence<Seq11, size_t, [](const size_t i) { return 2 * i; }>;
print(Seq11Even());
return 0;
}
I2luY2x1ZGUgPGNzdGRkZWY+Cm5hbWVzcGFjZSBzdGQgewoKdGVtcGxhdGUgPHR5cGVuYW1lIFRfLCBUXy4uLj4Kc3RydWN0IHZhbHVlX3NlcXVlbmNlIHsKfTsKCnRlbXBsYXRlIDxzaXplX3QuLi4gSXNfPgp1c2luZyBpbmRleF9zZXF1ZW5jZSA9IHZhbHVlX3NlcXVlbmNlPHNpemVfdCwgSXNfLi4uPjsKCm5hbWVzcGFjZSBkZXRhaWwgewoKdGVtcGxhdGUgPHR5cGVuYW1lIFNlcV8sIHNpemVfdCBOXz4Kc3RydWN0IG1ha2VfaW5kZXhfc2VxX2ltcGxfZXZlbjsKCnRlbXBsYXRlIDxzaXplX3QuLi4gSXNfLCBzaXplX3QgTl8+CnN0cnVjdCBtYWtlX2luZGV4X3NlcV9pbXBsX2V2ZW48dmFsdWVfc2VxdWVuY2U8c2l6ZV90LCBJc18uLi4+LCBOXz4gewogICAgdXNpbmcgdHlwZSA9IHZhbHVlX3NlcXVlbmNlPHNpemVfdCwgSXNfLi4uLCAoSXNfICsgTl8pLi4uPjsKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBTZXFfLCBzaXplX3QgTl8+CnN0cnVjdCBtYWtlX2luZGV4X3NlcV9pbXBsX29kZDsKCnRlbXBsYXRlIDxzaXplX3QuLi4gSXNfLCBzaXplX3QgTl8+CnN0cnVjdCBtYWtlX2luZGV4X3NlcV9pbXBsX29kZDx2YWx1ZV9zZXF1ZW5jZTxzaXplX3QsIElzXy4uLj4sIE5fPiB7CiAgICB1c2luZyB0eXBlID0gdmFsdWVfc2VxdWVuY2U8c2l6ZV90LCBJc18uLi4sIChJc18gKyBOXykuLi4sICgyICogTl8pPjsKfTsKCnRlbXBsYXRlIDxzaXplX3QgTl8sIGJvb2wgSXNPZGRfID0gKE5fICUgMik+CnN0cnVjdCBtYWtlX2luZGV4X3NlcV9pbXBsIHsKICAgIHVzaW5nIHR5cGUgPSB0eXBlbmFtZSBtYWtlX2luZGV4X3NlcV9pbXBsX2V2ZW48CiAgICAgICAgIHR5cGVuYW1lIG1ha2VfaW5kZXhfc2VxX2ltcGw8Tl8gLyAyPjo6dHlwZSwgTl8gLyAyPjo6dHlwZTsKfTsKCnRlbXBsYXRlIDxzaXplX3QgTl8+CnN0cnVjdCBtYWtlX2luZGV4X3NlcV9pbXBsPE5fLCB0cnVlPiB7CiAgICB1c2luZyB0eXBlID0gdHlwZW5hbWUgbWFrZV9pbmRleF9zZXFfaW1wbF9vZGQ8CiAgICAgICAgIHR5cGVuYW1lIG1ha2VfaW5kZXhfc2VxX2ltcGw8Tl8gLyAyPjo6dHlwZSwgTl8gLyAyPjo6dHlwZTsKfTsKCnRlbXBsYXRlIDw+CnN0cnVjdCBtYWtlX2luZGV4X3NlcV9pbXBsPDAsIGZhbHNlPiB7CiAgICB1c2luZyB0eXBlID0gdmFsdWVfc2VxdWVuY2U8c2l6ZV90PjsKfTsKCm5hbWVzcGFjZSB7CnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpjb25zdGV4cHIgaW5saW5lClQKaWRlbnRpdHlfdHJhbnNmb3JtKHNpemVfdCBpKSB7CiAgICByZXR1cm4gaTsKfQoKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIEluZGV4U2VxXywgdHlwZW5hbWUgVF8sIFRfICgqRl8pKHNpemVfdCkgPSBpZGVudGl0eV90cmFuc2Zvcm08VF8+PgpzdHJ1Y3QgdHJhbnNmb3JtX3NlcTsKCnRlbXBsYXRlIDxzaXplX3QuLi4gSXNfLCB0eXBlbmFtZSBUXywgVF8oKkZfKShzaXplX3QpPgpzdHJ1Y3QgdHJhbnNmb3JtX3NlcTxpbmRleF9zZXF1ZW5jZTxJc18uLi4+LCBUXywgRl8+IHsKICAgIHVzaW5nIHR5cGUgPSB2YWx1ZV9zZXF1ZW5jZTxUXywgRl8oSXNfKS4uLj47Cn07Cgp9IC8vIG5hbWVzcGFjZSBkZXRhaWwKCgp0ZW1wbGF0ZSA8c2l6ZV90IE5fPgp1c2luZyBtYWtlX2luZGV4X3NlcXVlbmNlID0gdHlwZW5hbWUgZGV0YWlsOjptYWtlX2luZGV4X3NlcV9pbXBsPE5fPjo6dHlwZTsKCnRlbXBsYXRlIDx0eXBlbmFtZS4uLiBUc18+CnVzaW5nIGluZGV4X3NlcXVlbmNlX2ZvciA9IG1ha2VfaW5kZXhfc2VxdWVuY2U8c2l6ZW9mLi4uKFRzXyk+OwoKdGVtcGxhdGUgPHR5cGVuYW1lIEluZGV4U2VxXywgdHlwZW5hbWUgVF8sIFRfICgqRl8pKHNpemVfdCkgPSBkZXRhaWw6OmlkZW50aXR5X3RyYW5zZm9ybTxUXz4+CnVzaW5nIHRyYW5zZm9ybV9zZXF1ZW5jZSA9IHR5cGVuYW1lIGRldGFpbDo6dHJhbnNmb3JtX3NlcTxJbmRleFNlcV8sIFRfLCBGXz46OnR5cGU7Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVF8sIFRfIE5fPgp1c2luZyBtYWtlX2ludGVnZXJfc2VxdWVuY2UgPSB0eXBlbmFtZSBkZXRhaWw6OnRyYW5zZm9ybV9zZXE8bWFrZV9pbmRleF9zZXF1ZW5jZTxOXz4sIFRfPjo6dHlwZTsKLy91c2luZyBtYWtlX2ludGVnZXJfc2VxdWVuY2UgPSB0cmFuc2Zvcm1fc2VxdWVuY2U8bWFrZV9pbmRleF9zZXF1ZW5jZTxOXz4sIFRfPj47CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIC8vCgp9CgojaW5jbHVkZSA8aW9zdHJlYW0+Cgp0ZW1wbGF0ZSA8c2l6ZV90Li4uIElzPgpzaXplX3QKc2l6ZShzdGQ6OmluZGV4X3NlcXVlbmNlPElzLi4uPikgewogICAgcmV0dXJuIHNpemVvZi4uLihJcyk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZS4uLiBUcz4Kdm9pZApzd2FsbG93KFRzICYmLi4uKSB7Cn0KCnZvaWQKcHJpbnQoc2l6ZV90IG4pIHsKICAgIHN0ZDo6Y291dCA8PCBuIDw8ICIgIjsKfQoKdGVtcGxhdGUgPHNpemVfdC4uLiBJcz4Kdm9pZApwcmludChzdGQ6OmluZGV4X3NlcXVlbmNlPElzLi4uPikgewogICAgc3dhbGxvdygocHJpbnQoSXMpLCAwKS4uLik7CiAgICBzdGQ6OmNvdXQgPDwgIlxuIjsKfQoKY29uc3RleHByCnNpemVfdAptdWwyKHNpemVfdCBpKSB7CiAgICByZXR1cm4gMiAqIGk7Cn0KCmludAptYWluKCkgewogICAgdXNpbmcgU2VxID0gc3RkOjptYWtlX2luZGV4X3NlcXVlbmNlPDIzNDU+OwogICAgc3RkOjpjb3V0IDw8ICJTZXEgc2l6ZTogIiA8PCBzaXplKFNlcSgpKSA8PCAiXG4iOwogICAgdXNpbmcgU2VxMTEgPSBzdGQ6Om1ha2VfaW5kZXhfc2VxdWVuY2U8MTE+OwogICAgcHJpbnQoU2VxMTEoKSk7CiAgICB1c2luZyBTZXExMUV2ZW4gPSBzdGQ6OnRyYW5zZm9ybV9zZXF1ZW5jZTxTZXExMSwgc2l6ZV90LCBtdWwyPjsKLy8gICAgdXNpbmcgU2VxMTFFdmVuID0gc3RkOjp0cmFuc2Zvcm1fc2VxdWVuY2U8U2VxMTEsIHNpemVfdCwgW10oY29uc3Qgc2l6ZV90IGkpIHsgcmV0dXJuIDIgKiBpOyB9PjsKICAgIHByaW50KFNlcTExRXZlbigpKTsKICAgIHJldHVybiAwOwp9Cgo=