fork(2) download
  1. #include <cassert>
  2. #include <memory>
  3. #include <sstream>
  4. #include <string>
  5. #include <iostream>
  6.  
  7. class MyClass {};
  8.  
  9. bool Post(std::string /*command*/, std::string /*payload*/) { std::cout << "Post\n"; return false;}
  10. std::string Get(std::string /*command*/) { std::cout << "Get\n"; return ""; }
  11. bool Delete(std::string /*command*/, std::string /*name*/) { std::cout << "Delete\n"; return false;}
  12. int OtherFunc(std::string /*command*/, const MyClass& /*name*/) { std::cout << "OtherFunc\n"; return 0;}
  13.  
  14. enum class CommandType
  15. {
  16. Get, Post, Delete, OtherFunc
  17. };
  18.  
  19. #define Stringify( T ) #T
  20. #define MakeString( M, L ) M(L)
  21. #define $Line MakeString( Stringify, __LINE__ )
  22. #define TemplateErrMsg __FILE__ "(" $Line ") : Invalid template used:" MakeString( Stringify, __FUNCTION__ )
  23. #define DO_PRAGMA(x) _Pragma ( #x )
  24. #define INVALID_TEMPLATE {DO_PRAGMA(message(TemplateErrMsg)); assert( false && TemplateErrMsg ); return 0; }
  25.  
  26. template<typename ... Ts>
  27. typename std::enable_if<sizeof...(Ts) != 1, int>::type
  28. Get (Ts&&...) INVALID_TEMPLATE
  29.  
  30. template<typename T>
  31. typename std::enable_if<!std::is_convertible<T, std::string>::value, int>::type
  32. Get (T&&...) INVALID_TEMPLATE
  33.  
  34. template<typename ... Ts>
  35. typename std::enable_if<sizeof...(Ts) != 2, int>::type
  36. Post (Ts&&...) INVALID_TEMPLATE
  37.  
  38. template<typename T1, typename T2>
  39. typename std::enable_if<!std::is_convertible<T1, std::string>::value
  40. || !std::is_convertible<T2, std::string>::value,
  41. int>::type
  42. Post (T1&&, T2&&) INVALID_TEMPLATE
  43.  
  44. template<typename ... Ts>
  45. typename std::enable_if<sizeof...(Ts) != 2, int>::type
  46. Delete (Ts&&...) INVALID_TEMPLATE
  47.  
  48. template<typename T1, typename T2>
  49. typename std::enable_if<!std::is_convertible<T1, std::string>::value
  50. || !std::is_convertible<T2, std::string>::value,
  51. int>::type
  52. Delete (T1&&, T2&&) INVALID_TEMPLATE
  53.  
  54. template<typename ... Ts>
  55. typename std::enable_if<sizeof...(Ts) != 2, int>::type
  56. OtherFunc (Ts&&...) INVALID_TEMPLATE
  57.  
  58. template<typename T1, typename T2>
  59. typename std::enable_if<!std::is_convertible<T1, std::string>::value
  60. || !std::is_convertible<T2, const MyClass&>::value,
  61. int>::type
  62. OtherFunc (T1&&, T2&&) INVALID_TEMPLATE
  63.  
  64. template<typename... Ts>
  65. std::unique_ptr<std::stringstream>
  66. Execute(CommandType command, Ts&&... parameters) {
  67. auto response = std::make_unique<std::stringstream>();
  68. if(command == CommandType::Get)
  69. *response << Get(std::forward<Ts>(parameters)...);
  70. else if(command == CommandType::Post)
  71. *response << Post(std::forward<Ts>(parameters)...);
  72. else if(command == CommandType::Delete)
  73. *response << Delete(std::forward<Ts>(parameters)...);
  74. else if(command == CommandType::OtherFunc)
  75. *response << OtherFunc(std::forward<Ts>(parameters)...);
  76.  
  77. return response;
  78. }
  79.  
  80.  
  81. int main(){
  82. Execute(CommandType::Get, "hello");
  83. Execute(CommandType::Post, "hello", "world");
  84. Execute(CommandType::Delete, "hello", "world");
  85. Execute(CommandType::OtherFunc , 123, "test", MyClass{});
  86. }
  87.  
Runtime error #stdin #stdout #stderr 0s 3280KB
stdin
Standard input is empty
stdout
Get
Post
Delete
stderr
prog: prog.cpp:56: typename std::enable_if<(sizeof... (Ts) != 2), int>::type OtherFunc(Ts&& ...) [with Ts = {int, const char (&)[5], MyClass}; typename std::enable_if<(sizeof... (Ts) != 2), int>::type = int]: Assertion `false && "prog.cpp" "(" "56" ") : Invalid template used:" "__FUNCTION__"' failed.