- #include <iostream>     // For std::cout, std::boolalpha, std::endl. 
- #include <string> 
- #include <cstdint>      // For int16_t. 
- #include <type_traits>  // For is_void<T>. 
-   
- using FilePath = std::string; 
-   
- // --------------------- 
- // ExecuteMethod() functor: 
- // --------------------- 
-   
- // Default functor. 
- template<typename... Ts> 
- struct Executor { }; 
-   
- // General case. 
- template<typename M, typename ReturnType, typename... Params> 
- struct Executor<M, ReturnType (*)(Params...)> { 
-     public: 
-         // Parameter match: 
-         bool operator()(M method, Params... params) { 
-            	ReturnType r = method(params...); 
-             std::cout << "Valid call.  Return value: " << r << "." << std::endl; 
-             return true; 
-         } 
-   
-         // Parameter mismatch: 
-         template<typename... Invalid_Params> 
-         bool operator()(M method, Invalid_Params... ts) { 
-             std::cout << "Invalid call." << std::endl; 
-             return false; 
-         } 
- }; 
-   
- // Special case to catch void return type. 
- template<typename M, typename... Params> 
- struct Executor<M, void (*)(Params...)> { 
-     public: 
-         // Parameter match: 
-         bool operator()(M method, Params... params) { 
-      		method(params...); 
-             std::cout << "Valid call.  Return value: None, 'cuz it's void." << std::endl; 
-             return true; 
-         } 
-   
-         // Parameter mismatch: 
-         template<typename... Invalid_Params> 
-         bool operator()(M method, Invalid_Params... ts) { 
-             std::cout << "Invalid call." << std::endl; 
-             return false; 
-         } 
- }; 
-   
- #define ExecuteMethod(C, M, ...)                    \ 
-     do {                                            \ 
-         Executor<decltype(&M), decltype(&M)> temp;  \ 
-         C = temp(M, ##__VA_ARGS__);                 \ 
-     } while (false) 
-   
-   
- // --------------------- 
- // Example functions: 
- // --------------------- 
-   
- int GetColor(int16_t* color) { *color = 0xF249; return 42; } 
- int GetFile(FilePath& file) { std::cout << "You want " << file << "?  You can't handle the file!" << std::endl; return 24; } 
- int WriteDocument(const FilePath &file, const char *fileFormatName, bool askForParms) { std::cout << "Do it yerself!" << std::endl; return 195; } 
-   
- // Returns gibberish, to lighten everyone's day. 
- int f0(int a) { std::cout << "You passed " << a << std::endl; } 
-   
- bool f1(int& a, const float b) { 
- 	std::cout << ((b > a) ? "b's bigger." : "a's bigger.") << std::endl; 
- 	return (a > b); 
- } 
- float f2(float* a, const float* b) { return ++(*a) * (*b); } 
-   
- char f3() { return 'c'; } 
-   
- void f4(std::string& s) { s = "A different string."; } 
-   
- // --------------------- 
- // main(): 
- // --------------------- 
-   
- int main() { 
-     int a = 8; 
-     float b1 = 2.0, b2 = 3.14; 
-     bool c = false; 
-     std::int16_t i16 = 0b1100010100001111; // Suddenly, binary literal! 
-     std::string s = "A string."; 
-     FilePath fp = "C:\\Windows\\system32\\chkntfs.exe"; 
-   
-     std::cout << "Testing:" << std::endl; 
-     std::cout << "- - -" << std::endl; 
-     std::cout << std::boolalpha; 
-   
-     std::cout << "(int(*)(int), int):" << std::endl; 
-     ExecuteMethod(c, f0, a); 
-     std::cout << "c: " << c << std::endl << std::endl; 
-   
-     std::cout << "(int(*)(int), int, float):" << std::endl; 
-     ExecuteMethod(c, f0, a, b1); 
-     std::cout << "c: " << c << std::endl << std::endl; 
-   
-     std::cout << "(bool(*)(int&, const float), int&, const float):" << std::endl; 
-     ExecuteMethod(c, f1, a, b1); 
-     std::cout << "c: " << c << std::endl << std::endl; 
-   
-     std::cout << "(float(*)(float*, const float*):" << std::endl; 
-     ExecuteMethod(c, f2, &b1, &b2); 
-     std::cout << "Well, then.  Once again, with const-ness!" << std::endl; 
-     std::cout << "Old values: " << b1 << ", " << b2 << std::endl; 
-     ExecuteMethod(c, f2, &b1, const_cast<const float*>(&b2)); 
-     std::cout << "New values: " << b1 << ", " << b2 << std::endl; 
-     std::cout << "c: " << c << std::endl << std::endl; 
-   
-     std::cout << "(char(*)()):" << std::endl; 
-     ExecuteMethod(c, f3); 
-     std::cout << "c: " << c << std::endl << std::endl; 
-   
-     std::cout << "Reference testing:" << std::endl; 
-     std::cout << "(void(*)(std::string&), std::string&):" << std::endl; 
-     std::cout << "Original string: \"" << s << "\"" << std::endl; 
-     ExecuteMethod(c, f4, s); 
-     std::cout << "New string: \"" << s << "\"" <<  std::endl; 
-     std::cout << "c: " << c << std::endl << std::endl; 
-     std::cout << std::endl; 
-   
-     std::cout << "Now, let's try your example functions:" << std::endl; 
-     std::cout << "- - -" << std::endl; 
-     std::cout << "int GetColor(int16_t*):" << std::endl; 
-     std::cout << "Old value: " << i16 << std::endl; 
-     ExecuteMethod(c, GetColor, &i16); 
-     std::cout << "New value: " << i16 << std::endl; 
-     std::cout << "c: " << c << std::endl << std::endl; 
-   
-     std::cout << "int GetFile(FilePath&):" << std::endl; 
-     ExecuteMethod(c, GetFile, fp); 
-     std::cout << "c: " << c << std::endl << std::endl; 
-   
-     std::cout << "int WriteDocument(const FilePath&, const char*, bool):" << std::endl; 
-     ExecuteMethod(c, WriteDocument, fp, s.c_str(), true); 
-     std::cout << "c: " << c << std::endl << std::endl; 
-   
- }