// Generic TMP-Library
template <typename T> struct identity_ { using type = T; };
template <typename... T> struct type_list { using type=type_list; };
template <int N, int... i>
struct make_index_list_ : make_index_list_<N-1, 0, (1+i)...> {};
template <int N>
using make_index_list = typename make_index_list_<N>::type;
template <int... i>
struct make_index_list_<0, i...> : type_list<std::integral_constant<int, i>...> {};
template <typename TL>
struct size_;
template <typename TL>
using size = typename size_<TL>::type;
template <typename... T>
struct size_<type_list<T...>>
: std::integral_constant<int, sizeof...(T)> {};
template <typename TL, template <typename> class F>
struct transform_;
template <typename TL, template <typename> class F>
using transform = typename transform_<TL, F>::type;
template <typename... T, template <typename> class F>
struct transform_<type_list<T...>, F>
: type_list<typename F<T>::type...> {};
template <typename, typename, template <typename> class> struct filter_;
template <typename... L, typename M, typename... R, template <typename> class Pred>
struct filter_<type_list<L...>, type_list<M, R...>, Pred>
: std::conditional<Pred<M>::value,
filter_<type_list<L..., M>, type_list<R...>, Pred>,
filter_<type_list<L...>, type_list<R...>, Pred> >::type {};
template <typename TL, template <typename> class Pred>
struct filter_<TL, type_list<>, Pred> : identity_<TL> {};
template <typename TL, template <typename> class Pred>
using filter = typename filter_<type_list<>, TL, Pred>::type;
template <template<typename,typename>class F, typename TL, typename TL2> struct zip_with_;
template <template<typename,typename>class F, typename TL, typename TL2>
using zip_with = typename zip_with_<F, TL, TL2>::type;
template <template<typename,typename>class F, typename... Ts, typename... Us>
struct zip_with_<F, type_list<Ts...>, type_list<Us...> >
: type_list<typename F<Ts, Us>::type...> {};
template <template<typename>class P>
struct static_not {
template <typename T>
using action = std::integral_constant<bool, !P<T>::value>;
};
struct expression_sequence{template<typename...T>expression_sequence(T&&...){}};
// Subsets (eigentlicher Code ab hier)
#include <iostream>
template <int I> using element = std::integral_constant<int, I>; // für tmper
template <typename TL> struct go {
template <typename I> struct go2 {
template <typename J, typename T> struct go3
: std::conditional<static_cast<bool>(I::value & (1 << J::value)), T, void> {};
using type = filter<zip_with<go3, make_index_list<size<TL>::value>, TL>,
static_not<std::is_void>::template action>;
};
};
template <typename... E>
using all_subsets = transform<make_index_list<(1<<(sizeof...(E)))>, go<type_list<E...> >::template go2>;
template <typename T> struct print_ { static void print(std::ostream& os) { os << T::value; } };
template <typename... Ts> struct print_<type_list<Ts...> > {
static void print(std::ostream& os)
{ os << "{ "; (void)expression_sequence((print_<Ts>::print(os),os<<' ')...); os << "}"; }
};
template <typename TL> void print(std::ostream&os=std::cout) { print_<TL>::print(os);os<<'\n'; }
int main()
{
print<all_subsets<element<0>, element<1>, element<2>>>();
print<all_subsets<>>();
}
Ly8gR2VuZXJpYyBUTVAtTGlicmFyeQoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IHN0cnVjdCBpZGVudGl0eV8geyB1c2luZyB0eXBlID0gVDsgfTsKdGVtcGxhdGUgPHR5cGVuYW1lLi4uIFQ+IHN0cnVjdCB0eXBlX2xpc3QgeyB1c2luZyB0eXBlPXR5cGVfbGlzdDsgfTsgIAoKdGVtcGxhdGUgPGludCBOLCBpbnQuLi4gaT4Kc3RydWN0IG1ha2VfaW5kZXhfbGlzdF8gOiBtYWtlX2luZGV4X2xpc3RfPE4tMSwgMCwgKDEraSkuLi4+IHt9Owp0ZW1wbGF0ZSA8aW50IE4+CnVzaW5nIG1ha2VfaW5kZXhfbGlzdCA9IHR5cGVuYW1lIG1ha2VfaW5kZXhfbGlzdF88Tj46OnR5cGU7CnRlbXBsYXRlIDxpbnQuLi4gaT4Kc3RydWN0IG1ha2VfaW5kZXhfbGlzdF88MCwgaS4uLj4gOiB0eXBlX2xpc3Q8c3RkOjppbnRlZ3JhbF9jb25zdGFudDxpbnQsIGk+Li4uPiB7fTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUTD4Kc3RydWN0IHNpemVfOwp0ZW1wbGF0ZSA8dHlwZW5hbWUgVEw+CnVzaW5nIHNpemUgPSB0eXBlbmFtZSBzaXplXzxUTD46OnR5cGU7CnRlbXBsYXRlIDx0eXBlbmFtZS4uLiBUPgpzdHJ1Y3Qgc2l6ZV88dHlwZV9saXN0PFQuLi4+PgogIDogc3RkOjppbnRlZ3JhbF9jb25zdGFudDxpbnQsIHNpemVvZi4uLihUKT4ge307Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVEwsIHRlbXBsYXRlIDx0eXBlbmFtZT4gY2xhc3MgRj4Kc3RydWN0IHRyYW5zZm9ybV87CnRlbXBsYXRlIDx0eXBlbmFtZSBUTCwgdGVtcGxhdGUgPHR5cGVuYW1lPiBjbGFzcyBGPgp1c2luZyB0cmFuc2Zvcm0gPSB0eXBlbmFtZSB0cmFuc2Zvcm1fPFRMLCBGPjo6dHlwZTsKdGVtcGxhdGUgPHR5cGVuYW1lLi4uIFQsIHRlbXBsYXRlIDx0eXBlbmFtZT4gY2xhc3MgRj4Kc3RydWN0IHRyYW5zZm9ybV88dHlwZV9saXN0PFQuLi4+LCBGPgogIDogdHlwZV9saXN0PHR5cGVuYW1lIEY8VD46OnR5cGUuLi4+IHt9OwoKdGVtcGxhdGUgPHR5cGVuYW1lLCB0eXBlbmFtZSwgdGVtcGxhdGUgPHR5cGVuYW1lPiBjbGFzcz4gc3RydWN0IGZpbHRlcl87CnRlbXBsYXRlIDx0eXBlbmFtZS4uLiBMLCB0eXBlbmFtZSBNLCB0eXBlbmFtZS4uLiBSLCB0ZW1wbGF0ZSA8dHlwZW5hbWU+IGNsYXNzIFByZWQ+CnN0cnVjdCBmaWx0ZXJfPHR5cGVfbGlzdDxMLi4uPiwgdHlwZV9saXN0PE0sIFIuLi4+LCBQcmVkPgogIDogc3RkOjpjb25kaXRpb25hbDxQcmVkPE0+Ojp2YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgZmlsdGVyXzx0eXBlX2xpc3Q8TC4uLiwgTT4sIHR5cGVfbGlzdDxSLi4uPiwgUHJlZD4sCiAgICAgICAgICAgICAgICAgICAgIGZpbHRlcl88dHlwZV9saXN0PEwuLi4+LCB0eXBlX2xpc3Q8Ui4uLj4sIFByZWQ+ID46OnR5cGUge307CnRlbXBsYXRlIDx0eXBlbmFtZSBUTCwgdGVtcGxhdGUgPHR5cGVuYW1lPiBjbGFzcyBQcmVkPgpzdHJ1Y3QgZmlsdGVyXzxUTCwgdHlwZV9saXN0PD4sIFByZWQ+IDogaWRlbnRpdHlfPFRMPiB7fTsKdGVtcGxhdGUgPHR5cGVuYW1lIFRMLCB0ZW1wbGF0ZSA8dHlwZW5hbWU+IGNsYXNzIFByZWQ+CnVzaW5nIGZpbHRlciA9IHR5cGVuYW1lIGZpbHRlcl88dHlwZV9saXN0PD4sIFRMLCBQcmVkPjo6dHlwZTsKCnRlbXBsYXRlIDx0ZW1wbGF0ZTx0eXBlbmFtZSx0eXBlbmFtZT5jbGFzcyBGLCB0eXBlbmFtZSBUTCwgdHlwZW5hbWUgVEwyPiBzdHJ1Y3QgemlwX3dpdGhfOwp0ZW1wbGF0ZSA8dGVtcGxhdGU8dHlwZW5hbWUsdHlwZW5hbWU+Y2xhc3MgRiwgdHlwZW5hbWUgVEwsIHR5cGVuYW1lIFRMMj4KdXNpbmcgemlwX3dpdGggPSB0eXBlbmFtZSB6aXBfd2l0aF88RiwgVEwsIFRMMj46OnR5cGU7CiAgdGVtcGxhdGUgPHRlbXBsYXRlPHR5cGVuYW1lLHR5cGVuYW1lPmNsYXNzIEYsIHR5cGVuYW1lLi4uIFRzLCB0eXBlbmFtZS4uLiBVcz4Kc3RydWN0IHppcF93aXRoXzxGLCB0eXBlX2xpc3Q8VHMuLi4+LCB0eXBlX2xpc3Q8VXMuLi4+ID4KICAgIDogdHlwZV9saXN0PHR5cGVuYW1lIEY8VHMsIFVzPjo6dHlwZS4uLj4ge307Cgp0ZW1wbGF0ZSA8dGVtcGxhdGU8dHlwZW5hbWU+Y2xhc3MgUD4Kc3RydWN0IHN0YXRpY19ub3QgewogIHRlbXBsYXRlIDx0eXBlbmFtZSBUPgogIHVzaW5nIGFjdGlvbiA9IHN0ZDo6aW50ZWdyYWxfY29uc3RhbnQ8Ym9vbCwgIVA8VD46OnZhbHVlPjsKfTsKCnN0cnVjdCBleHByZXNzaW9uX3NlcXVlbmNle3RlbXBsYXRlPHR5cGVuYW1lLi4uVD5leHByZXNzaW9uX3NlcXVlbmNlKFQmJi4uLil7fX07CgovLyBTdWJzZXRzIChlaWdlbnRsaWNoZXIgQ29kZSBhYiBoaWVyKQojaW5jbHVkZSA8aW9zdHJlYW0+Cgp0ZW1wbGF0ZSA8aW50IEk+IHVzaW5nIGVsZW1lbnQgPSBzdGQ6OmludGVncmFsX2NvbnN0YW50PGludCwgST47IC8vIGbDvHIgdG1wZXIKCnRlbXBsYXRlIDx0eXBlbmFtZSBUTD4gc3RydWN0IGdvIHsKICB0ZW1wbGF0ZSA8dHlwZW5hbWUgST4gc3RydWN0IGdvMiB7CiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgSiwgdHlwZW5hbWUgVD4gc3RydWN0IGdvMwogICAgICA6IHN0ZDo6Y29uZGl0aW9uYWw8c3RhdGljX2Nhc3Q8Ym9vbD4oSTo6dmFsdWUgJiAoMSA8PCBKOjp2YWx1ZSkpLCBULCB2b2lkPiB7fTsKICAgIHVzaW5nIHR5cGUgPSBmaWx0ZXI8emlwX3dpdGg8Z28zLCBtYWtlX2luZGV4X2xpc3Q8c2l6ZTxUTD46OnZhbHVlPiwgVEw+LAogICAgICAgICAgICAgICAgICAgICAgICBzdGF0aWNfbm90PHN0ZDo6aXNfdm9pZD46OnRlbXBsYXRlIGFjdGlvbj47CiAgfTsKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZS4uLiBFPgp1c2luZyBhbGxfc3Vic2V0cyA9IHRyYW5zZm9ybTxtYWtlX2luZGV4X2xpc3Q8KDE8PChzaXplb2YuLi4oRSkpKT4sIGdvPHR5cGVfbGlzdDxFLi4uPiA+Ojp0ZW1wbGF0ZSBnbzI+OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IHN0cnVjdCBwcmludF8geyBzdGF0aWMgdm9pZCBwcmludChzdGQ6Om9zdHJlYW0mIG9zKSB7IG9zIDw8IFQ6OnZhbHVlOyB9IH07CnRlbXBsYXRlIDx0eXBlbmFtZS4uLiBUcz4gc3RydWN0IHByaW50Xzx0eXBlX2xpc3Q8VHMuLi4+ID4gewogIHN0YXRpYyB2b2lkIHByaW50KHN0ZDo6b3N0cmVhbSYgb3MpCiAgeyBvcyA8PCAieyAiOyAodm9pZClleHByZXNzaW9uX3NlcXVlbmNlKChwcmludF88VHM+OjpwcmludChvcyksb3M8PCcgJykuLi4pOyBvcyA8PCAifSI7IH0KfTsKdGVtcGxhdGUgPHR5cGVuYW1lIFRMPiB2b2lkIHByaW50KHN0ZDo6b3N0cmVhbSZvcz1zdGQ6OmNvdXQpIHsgcHJpbnRfPFRMPjo6cHJpbnQob3MpO29zPDwnXG4nOyB9CgppbnQgbWFpbigpCnsKICBwcmludDxhbGxfc3Vic2V0czxlbGVtZW50PDA+LCBlbGVtZW50PDE+LCBlbGVtZW50PDI+Pj4oKTsKICBwcmludDxhbGxfc3Vic2V0czw+PigpOwp9