fork(1) download
  1. #include <utility>
  2.  
  3. #define EXEC_MEMBER_PROC_IF_PRESENT(ProcName) namespace ProcName {\
  4.   void ExecIfPresent(...) throw() {}\
  5.   \
  6.   template <class C, typename... TArgs>\
  7.   void ExecIfPresent(C& obj, TArgs&... args) {\
  8.   obj.ProcName(std::forward<TArgs>(args)...);\
  9.   }\
  10. };
  11.  
  12. // If NOT exists - returns the 'DefaultValue'
  13. // 'DefaultValue' SHOULD be the same type as a decltype(*.FuncName())
  14. // Works with static/const/virtual funcs
  15. #define EXEC_MEMBER_FUNC_IF_PRESENT(FuncName, DefaultValue) namespace FuncName {\
  16.   template <typename TReturnType = decltype(DefaultValue)>\
  17.   auto ExecIfPresent(...) -> TReturnType {\
  18.   return std::move(DefaultValue);\
  19.   }\
  20.   \
  21.   template <class C, typename... TArgs>\
  22.   auto ExecIfPresent(C& obj, TArgs&... args)\
  23.   -> decltype(obj.FuncName(std::forward<TArgs>(args)...))\
  24.   {/* do NOT use 'const C& obj' NOR 'C::FuncName()!'*/\
  25.   return std::move(obj.FuncName(std::forward<TArgs>(args)...));\
  26.   }\
  27. };
  28.  
  29. EXEC_MEMBER_FUNC_IF_PRESENT(getHashIfKnown, 0U);
  30.  
  31. #include<cassert>
  32. #include<cstring>
  33. #include<string>
  34. #include<iostream>
  35.  
  36. int main() {
  37. std::string str = "test str";
  38. auto hash = getHashIfKnown::ExecIfPresent(str);
  39. assert(!hash);
  40. std::cout << "str: " << hash << std::endl;
  41.  
  42. struct MyStr {
  43. MyStr(const char* str) throw() {
  44. if(str) {
  45. strcpy(buf, str);
  46. len = strlen(buf);
  47. }
  48. }
  49.  
  50. size_t getHashIfKnown() const throw() {
  51. size_t hash = 0U;
  52. for(size_t idx = 0U; idx < len; ++idx) {
  53. hash += buf[idx] * (idx + 1U);
  54. }
  55. return hash;
  56. }
  57.  
  58. size_t len = 0U;
  59. char buf[256U];
  60. } myStr = "we don't need no water!";
  61.  
  62. hash = getHashIfKnown::ExecIfPresent(myStr);
  63. assert(hash);
  64. std::cout << "myStr: " << hash << std::endl;
  65. }
Success #stdin #stdout 0s 3456KB
stdin
Standard input is empty
stdout
str: 0
myStr: 24355