#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 {std::get<I>(input)...}; }
Output operator()(Input&& input) const { return {std::move(std::get<I>(input))...}; }
};
template <typename T, typename From>
using RemoveFromOutput = typename RemoveFromHelper<T, std::decay_t<From>>::Output;
template <typename T, typename From>
RemoveFromOutput<T, From> remove_from(From&& t)
{
return RemoveFromHelper<T, std::decay_t<From>>()(std::forward<From>(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+OwoKICBPdXRwdXQgb3BlcmF0b3IoKShjb25zdCBJbnB1dCYgaW5wdXQpIGNvbnN0IHsgcmV0dXJuIHtzdGQ6OmdldDxJPihpbnB1dCkuLi59OyB9CiAgT3V0cHV0IG9wZXJhdG9yKCkoSW5wdXQmJiBpbnB1dCkgY29uc3QgeyByZXR1cm4ge3N0ZDo6bW92ZShzdGQ6OmdldDxJPihpbnB1dCkpLi4ufTsgfQp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEZyb20+CnVzaW5nIFJlbW92ZUZyb21PdXRwdXQgPSB0eXBlbmFtZSBSZW1vdmVGcm9tSGVscGVyPFQsIHN0ZDo6ZGVjYXlfdDxGcm9tPj46Ok91dHB1dDsgCgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgRnJvbT4KUmVtb3ZlRnJvbU91dHB1dDxULCBGcm9tPiByZW1vdmVfZnJvbShGcm9tJiYgdCkKewogIHJldHVybiBSZW1vdmVGcm9tSGVscGVyPFQsIHN0ZDo6ZGVjYXlfdDxGcm9tPj4oKShzdGQ6OmZvcndhcmQ8RnJvbT4odCkpOwp9CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi8vIEEgdXNhZ2Ugc2FtcGxlCgp0ZW1wbGF0ZSA8dHlwZW5hbWUuLi5ULCBzaXplX3QuLi5JPgp2b2lkIHByaW50KGNvbnN0IHN0ZDo6dHVwbGU8VC4uLj4mIHQsIHN0ZDo6aW5kZXhfc2VxdWVuY2U8SS4uLj4pCnsKICBjaGFyIGF1eFtdeyAoc3RkOjpjb3V0IDw8ICIgIiA8PCBzdGQ6OmdldDxJPih0KSwgMCkuLi59OwogIHN0ZDo6Y291dCA8PCBzdGQ6OmVuZGw7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZS4uLlQ+CnZvaWQgcHJpbnQoY29uc3Qgc3RkOjp0dXBsZTxULi4uPiYgdCkKewogIHByaW50KHQsIHN0ZDo6bWFrZV9pbmRleF9zZXF1ZW5jZTxzaXplb2YuLi4oVCk+KCkpOwp9CgppbnQgbWFpbigpCnsKICBwcmludChyZW1vdmVfZnJvbTxpbnQ+KHN0ZDo6bWFrZV90dXBsZSgib25lIiwgMSwgInR3byIsIDIsICJ0aHJlZSIsIDMsICJmb3VydHkiLCA0MCkpKTsKfQ==