#include <iostream>
#include <tuple>
#include <type_traits>
#include <utility>
template <typename T, typename From, typename = From, typename = std::index_sequence<>>
struct RemoveFromHelper;
template <typename T, typename...E, typename Head, typename...Tail, size_t...I>
struct RemoveFromHelper<T, std::tuple<E...>, std::tuple<Head, Tail...>, std::index_sequence<I...>>
: RemoveFromHelper<T, std::tuple<E...>, std::tuple<Tail...>, std::index_sequence<I..., sizeof...(E) - sizeof...(Tail) - 1>> {};
template <typename T, typename...E, typename...Tail, size_t...I>
struct RemoveFromHelper<T, std::tuple<E...>, std::tuple<T, Tail...>, std::index_sequence<I...>>
: RemoveFromHelper<T, std::tuple<E...>, std::tuple<Tail...>, std::index_sequence<I...>> {};
template <typename T, typename...E, size_t...I>
struct RemoveFromHelper<T, std::tuple<E...>, std::tuple<>, std::index_sequence<I...>>
{
using Input = std::tuple<E...>;
using Output = std::tuple<std::tuple_element_t<I, Input>...>;
Output operator()(const Input& input) const { return Output(std::get<I>(input)...); }
};
template <typename T, typename From>
using RemoveFromOutput = typename RemoveFromHelper<T, From>::Output;
template <typename T, typename...E>
RemoveFromOutput<T, std::tuple<E...>> remove_from(const std::tuple<E...>& t)
{
return RemoveFromHelper<T, std::tuple<E...>>()(t);
}
/////////////////////////////////////////////////
// A usage sample
template <typename...T, size_t...I>
void print(const std::tuple<T...>& t, std::index_sequence<I...>)
{
char aux[]{ (std::cout << " " << std::get<I>(t), 0)...};
std::cout << std::endl;
}
template <typename...T>
void print(const std::tuple<T...>& t)
{
print(t, std::make_index_sequence<sizeof...(T)>());
}
int main()
{
print(remove_from<int>(std::make_tuple("one", 1, "two", 2, "three", 3, "fourty", 40)));
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHVwbGU+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KI2luY2x1ZGUgPHV0aWxpdHk+Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgRnJvbSwgdHlwZW5hbWUgPSBGcm9tLCB0eXBlbmFtZSA9IHN0ZDo6aW5kZXhfc2VxdWVuY2U8Pj4Kc3RydWN0IFJlbW92ZUZyb21IZWxwZXI7Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUuLi5FLCB0eXBlbmFtZSBIZWFkLCB0eXBlbmFtZS4uLlRhaWwsIHNpemVfdC4uLkk+CnN0cnVjdCBSZW1vdmVGcm9tSGVscGVyPFQsIHN0ZDo6dHVwbGU8RS4uLj4sIHN0ZDo6dHVwbGU8SGVhZCwgVGFpbC4uLj4sIHN0ZDo6aW5kZXhfc2VxdWVuY2U8SS4uLj4+CiA6IFJlbW92ZUZyb21IZWxwZXI8VCwgc3RkOjp0dXBsZTxFLi4uPiwgc3RkOjp0dXBsZTxUYWlsLi4uPiwgc3RkOjppbmRleF9zZXF1ZW5jZTxJLi4uLCBzaXplb2YuLi4oRSkgLSBzaXplb2YuLi4oVGFpbCkgLSAxPj4ge307Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUuLi5FLCB0eXBlbmFtZS4uLlRhaWwsIHNpemVfdC4uLkk+CnN0cnVjdCBSZW1vdmVGcm9tSGVscGVyPFQsIHN0ZDo6dHVwbGU8RS4uLj4sIHN0ZDo6dHVwbGU8VCwgVGFpbC4uLj4sIHN0ZDo6aW5kZXhfc2VxdWVuY2U8SS4uLj4+CiA6IFJlbW92ZUZyb21IZWxwZXI8VCwgc3RkOjp0dXBsZTxFLi4uPiwgc3RkOjp0dXBsZTxUYWlsLi4uPiwgc3RkOjppbmRleF9zZXF1ZW5jZTxJLi4uPj4ge307Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUuLi5FLCBzaXplX3QuLi5JPgpzdHJ1Y3QgUmVtb3ZlRnJvbUhlbHBlcjxULCBzdGQ6OnR1cGxlPEUuLi4+LCBzdGQ6OnR1cGxlPD4sIHN0ZDo6aW5kZXhfc2VxdWVuY2U8SS4uLj4+CnsKICB1c2luZyBJbnB1dCA9IHN0ZDo6dHVwbGU8RS4uLj47CiAgdXNpbmcgT3V0cHV0ID0gc3RkOjp0dXBsZTxzdGQ6OnR1cGxlX2VsZW1lbnRfdDxJLCBJbnB1dD4uLi4+OwoKICBPdXRwdXQgb3BlcmF0b3IoKShjb25zdCBJbnB1dCYgaW5wdXQpIGNvbnN0IHsgcmV0dXJuIE91dHB1dChzdGQ6OmdldDxJPihpbnB1dCkuLi4pOyB9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgRnJvbT4KdXNpbmcgUmVtb3ZlRnJvbU91dHB1dCA9IHR5cGVuYW1lIFJlbW92ZUZyb21IZWxwZXI8VCwgRnJvbT46Ok91dHB1dDsgCgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUuLi5FPgpSZW1vdmVGcm9tT3V0cHV0PFQsIHN0ZDo6dHVwbGU8RS4uLj4+IHJlbW92ZV9mcm9tKGNvbnN0IHN0ZDo6dHVwbGU8RS4uLj4mIHQpCnsKICByZXR1cm4gUmVtb3ZlRnJvbUhlbHBlcjxULCBzdGQ6OnR1cGxlPEUuLi4+PigpKHQpOwp9CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi8vIEEgdXNhZ2Ugc2FtcGxlCgp0ZW1wbGF0ZSA8dHlwZW5hbWUuLi5ULCBzaXplX3QuLi5JPgp2b2lkIHByaW50KGNvbnN0IHN0ZDo6dHVwbGU8VC4uLj4mIHQsIHN0ZDo6aW5kZXhfc2VxdWVuY2U8SS4uLj4pCnsKICBjaGFyIGF1eFtdeyAoc3RkOjpjb3V0IDw8ICIgIiA8PCBzdGQ6OmdldDxJPih0KSwgMCkuLi59OwogIHN0ZDo6Y291dCA8PCBzdGQ6OmVuZGw7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZS4uLlQ+CnZvaWQgcHJpbnQoY29uc3Qgc3RkOjp0dXBsZTxULi4uPiYgdCkKewogIHByaW50KHQsIHN0ZDo6bWFrZV9pbmRleF9zZXF1ZW5jZTxzaXplb2YuLi4oVCk+KCkpOwp9CgppbnQgbWFpbigpCnsKICBwcmludChyZW1vdmVfZnJvbTxpbnQ+KHN0ZDo6bWFrZV90dXBsZSgib25lIiwgMSwgInR3byIsIDIsICJ0aHJlZSIsIDMsICJmb3VydHkiLCA0MCkpKTsKfQ==