#include <iostream>
#include <type_traits>

template<template<typename...> class C, typename... T>
struct is_valid_specialization {
	typedef struct { char _; } yes;
	typedef struct { yes _[2]; } no;

	template<template<typename...> class D>
	static yes test(D<T...>*);
	template<template<typename...> class D>
	static no test(...);

	constexpr static bool value = (sizeof(test<C>(0)) == sizeof(yes));
};

namespace detail {

	template<template<typename...> class BeCurry, bool = false, typename... S>
	struct Currying {

		template<typename... T>
		using apply = Currying<BeCurry, is_valid_specialization<BeCurry, S..., T...>::value, S..., T...>;
	};

	template<template<typename...> class BeCurry, typename... S>
	struct Currying<BeCurry, true, S...> {

		template<typename... T>
		using apply = Currying<BeCurry, is_valid_specialization<BeCurry, S..., T...>::value, S..., T...>;

		using type = typename BeCurry<S...>::type;
	};
}

template<template<typename...> class BeCurry>
using Currying = detail::Currying<BeCurry, is_valid_specialization<BeCurry>::value>;

template<typename T>
struct Test1 { using type = int; };

template<typename T1, typename T2>
struct Test2 { using type = char*; };

template<typename...>
struct Test3 { using type = double; };

using curry  = Currying<Test1>;
using curry2 = Currying<Test2>;
using curry3 = Currying<Test3>;

template<typename T>
void pretty_print(T) {
	std::cout << __PRETTY_FUNCTION__ << std::endl;
}

int main() {
	pretty_print(typename curry::apply<char>::type{});
	pretty_print(typename curry2::apply<int>::apply<char>::type{});
	pretty_print(typename curry3::type{});
}