fork download
  1. #include <iostream>
  2. #include <type_traits>
  3.  
  4. template<template<typename...> class C, typename... T>
  5. struct is_valid_specialization {
  6. typedef struct { char _; } yes;
  7. typedef struct { yes _[2]; } no;
  8.  
  9. template<template<typename...> class D>
  10. static yes test(D<T...>*);
  11. template<template<typename...> class D>
  12. static no test(...);
  13.  
  14. constexpr static bool value = (sizeof(test<C>(0)) == sizeof(yes));
  15. };
  16.  
  17. namespace detail {
  18.  
  19. template<template<typename...> class BeCurry, bool = false, typename... S>
  20. struct Currying {
  21.  
  22. template<typename... T>
  23. using apply = Currying<BeCurry, is_valid_specialization<BeCurry, S..., T...>::value, S..., T...>;
  24. };
  25.  
  26. template<template<typename...> class BeCurry, typename... S>
  27. struct Currying<BeCurry, true, S...> {
  28.  
  29. template<typename... T>
  30. using apply = Currying<BeCurry, is_valid_specialization<BeCurry, S..., T...>::value, S..., T...>;
  31.  
  32. using type = typename BeCurry<S...>::type;
  33. };
  34. }
  35.  
  36. template<template<typename...> class BeCurry>
  37. using Currying = detail::Currying<BeCurry, is_valid_specialization<BeCurry>::value>;
  38.  
  39. template<typename T>
  40. struct Test1 { using type = int; };
  41.  
  42. template<typename T1, typename T2>
  43. struct Test2 { using type = char*; };
  44.  
  45. template<typename...>
  46. struct Test3 { using type = double; };
  47.  
  48. using curry = Currying<Test1>;
  49. using curry2 = Currying<Test2>;
  50. using curry3 = Currying<Test3>;
  51.  
  52. template<typename T>
  53. void pretty_print(T) {
  54. std::cout << __PRETTY_FUNCTION__ << std::endl;
  55. }
  56.  
  57. int main() {
  58. pretty_print(typename curry::apply<char>::type{});
  59. pretty_print(typename curry2::apply<int>::apply<char>::type{});
  60. pretty_print(typename curry3::type{});
  61. }
Success #stdin #stdout 0s 3296KB
stdin
Standard input is empty
stdout
void pretty_print(T) [with T = int]
void pretty_print(T) [with T = char*]
void pretty_print(T) [with T = double]