複数の関数オブジェクトを1つにまとめる2

[複数の関数オブジェクトを1つにまとめる](http://qiita.com/quartorz/items/0670b5e4aa63a76def1e)の続きです
関数オブジェクトの戻り値をtupleにして返すようにしました

```cpp
#include <tuple>
#include <iostream>
#include <cstddef>

template <std::size_t... I>
class index_tuple{
public:
	using type = index_tuple<I...>;
};

template <class Left, class Right>
class concat_impl;
template <std::size_t... Left, std::size_t... Right>
class concat_impl<index_tuple<Left...>, index_tuple<Right...>>
	: public index_tuple<Left..., Right...>
{
};
template <class Left, class Right>
using concat = typename concat_impl<Left, Right>::type;

template <class Sequence, std::size_t N>
class shift_impl;
template <std::size_t N, std::size_t... I>
class shift_impl<index_tuple<I...>, N>
	: public index_tuple<(I + N)...>
{
};
template <class Sequence, std::size_t N>
using shift = typename shift_impl<Sequence, N>::type;

template <std::size_t Begin, std::size_t End>
class make_index_range_impl;
template <std::size_t Begin, std::size_t End>
using make_index_range = typename make_index_range_impl<Begin, End>::type;

template <std::size_t Begin, std::size_t End>
class make_index_range_impl:
	public shift< concat<
		make_index_range<0, (End - Begin) / 2>,
		shift<make_index_range<0, (End - Begin) / 2 + (End - Begin) % 2>, (End - Begin) / 2>
	>, Begin>
{
};

template <>
class make_index_range_impl<0, 1>: public index_tuple<0>
{
};
template <>
class make_index_range_impl<0, 0>: public index_tuple<>
{
};

template <std::size_t N>
using make_index = make_index_range<0, N>;


class nil{
public:
	template <class T>
	void operator=(const T&)
	{
	}
	template <class T>
	operator T()
	{
		return T();
	}
};


template <class ArgsTuple, class FunctionsTuple>
class combiner;
template <class... Args, class... Functions>
class combiner<std::tuple<Args...>, std::tuple<Functions...>>{

	template <class Function>
	class result{
		using result_type = typename std::result_of<Function(Args...)>::type;

	public:
		using type = std::conditional_t<std::is_void<result_type>::value, nil, result_type>;
	};

	using function_tuple = std::tuple<Functions...>;
	using arg_tuple = std::tuple<Args...>;
	using result_tuple = std::tuple<typename result<Functions>::type...>;

	function_tuple functions;
	result_tuple a;

public:
	combiner(Functions... functions): functions(functions...)
	{
	}

	result_tuple operator()(Args... args)
	{
		return operator_helper(make_index<sizeof...(Functions)>(), args...);
	}

private:
	template <std::size_t... Indices>
	result_tuple operator_helper(index_tuple<Indices...>, Args... args)
	{
		return result_tuple(bind<Indices>(args...)...);
	}

	template <std::size_t I>
	typename std::tuple_element<I, result_tuple>::type bind(Args... args)
	{
		using result_type = typename std::tuple_element<I, result_tuple>::type;
		return bind_helper<result_type>(std::get<I>(functions), args...);
	}

	template <class Result, class Function>
	class bind_helper_class{
		Result result;

	public:
		bind_helper_class(Function &f, Args... args): result(f(args...))
		{
		}
		operator Result()
		{
			return result;
		}
	};

	template <class Function>
	class bind_helper_class<nil, Function>{
	public:
		bind_helper_class(Function &f, Args... args)
		{
			f(args...);
		}
		operator nil()
		{
			return nil();
		}
	};

	template <class Result, class Function>
	bind_helper_class<Result, Function> bind_helper(Function &f, Args... args)
	{
		return bind_helper_class<Result, Function>(f, args...);
	}
};

template <class... Args, class... Functions>
combiner<std::tuple<Args...>, std::tuple<Functions...>> make_combiner(Functions... functions)
{
	return combiner<std::tuple<Args...>, std::tuple<Functions...>>(functions...);
}


double function(int x, double y)
{
	return x * y;
}

class Class{
public:
	int operator()(int x, double)
	{
		return x;
	}
};

int main()
{
	auto combiner = make_combiner<int, double>(function, Class(), [](int, double){});
	double a;
	int b;

	std::tie(a, b, std::ignore) = combiner(10, 20.);
	std::cout << a << ' ' << b << std::endl;
}
```