#include <iostream>
#include <tuple>
#include <type_traits>
using namespace std;
template<int Ins, int Outs>
class Filter
{
// implementation
};
template <int... Args>
struct FiltersFor;
template <typename Tuple1, typename Tuple2>
using tuple_cat_t = decltype(std::tuple_cat(std::declval<Tuple1>(),
std::declval<Tuple2>()));
template <int Ins, int Outs, int... Others>
struct FiltersFor<Ins,Outs,Others...>
{
using type = tuple_cat_t<std::tuple<Filter<Ins,Outs>>, typename FiltersFor<Outs,Others...>::type>;
};
template <int Dummy>
struct FiltersFor<Dummy>
{
using type = std::tuple<>;
};
template <>
struct FiltersFor<>
{
using type = std::tuple<>;
};
template<int... args>
using Chain = typename FiltersFor<args...>::type;
static_assert(std::is_same<Chain<1,2,3,4>, std::tuple<Filter<1,2>,Filter<2,3>,Filter<3,4>>>::value, "wat");
static_assert(std::is_same<Chain<1,2>, std::tuple<Filter<1,2>>>::value, "wat");
static_assert(std::is_same<Chain<>, std::tuple<>>::value, "wat");
int main() {
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHVwbGU+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnRlbXBsYXRlPGludCBJbnMsIGludCBPdXRzPgpjbGFzcyBGaWx0ZXIKewogICAgLy8gaW1wbGVtZW50YXRpb24KfTsKCnRlbXBsYXRlIDxpbnQuLi4gQXJncz4Kc3RydWN0IEZpbHRlcnNGb3I7Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVHVwbGUxLCB0eXBlbmFtZSBUdXBsZTI+CnVzaW5nIHR1cGxlX2NhdF90ID0gZGVjbHR5cGUoc3RkOjp0dXBsZV9jYXQoc3RkOjpkZWNsdmFsPFR1cGxlMT4oKSwKCQkJCQkJCQkJCQlzdGQ6OmRlY2x2YWw8VHVwbGUyPigpKSk7IAoKdGVtcGxhdGUgPGludCBJbnMsIGludCBPdXRzLCBpbnQuLi4gT3RoZXJzPgpzdHJ1Y3QgRmlsdGVyc0ZvcjxJbnMsT3V0cyxPdGhlcnMuLi4+CnsKCXVzaW5nIHR5cGUgPSB0dXBsZV9jYXRfdDxzdGQ6OnR1cGxlPEZpbHRlcjxJbnMsT3V0cz4+LCB0eXBlbmFtZSBGaWx0ZXJzRm9yPE91dHMsT3RoZXJzLi4uPjo6dHlwZT47CQp9OwoKdGVtcGxhdGUgPGludCBEdW1teT4Kc3RydWN0IEZpbHRlcnNGb3I8RHVtbXk+CnsKCXVzaW5nIHR5cGUgPSBzdGQ6OnR1cGxlPD47Cn07Cgp0ZW1wbGF0ZSA8PgpzdHJ1Y3QgRmlsdGVyc0Zvcjw+CnsKCXVzaW5nIHR5cGUgPSBzdGQ6OnR1cGxlPD47Cn07Cgp0ZW1wbGF0ZTxpbnQuLi4gYXJncz4KdXNpbmcgQ2hhaW4gPSB0eXBlbmFtZSBGaWx0ZXJzRm9yPGFyZ3MuLi4+Ojp0eXBlOwoKCnN0YXRpY19hc3NlcnQoc3RkOjppc19zYW1lPENoYWluPDEsMiwzLDQ+LCBzdGQ6OnR1cGxlPEZpbHRlcjwxLDI+LEZpbHRlcjwyLDM+LEZpbHRlcjwzLDQ+Pj46OnZhbHVlLCAid2F0Iik7CnN0YXRpY19hc3NlcnQoc3RkOjppc19zYW1lPENoYWluPDEsMj4sIHN0ZDo6dHVwbGU8RmlsdGVyPDEsMj4+Pjo6dmFsdWUsICJ3YXQiKTsKc3RhdGljX2Fzc2VydChzdGQ6OmlzX3NhbWU8Q2hhaW48Piwgc3RkOjp0dXBsZTw+Pjo6dmFsdWUsICJ3YXQiKTsKCmludCBtYWluKCkgewoJcmV0dXJuIDA7Cn0=