fork download
  1. #include <iostream>
  2. #include <map>
  3.  
  4. namespace detail {
  5. struct FuncPtrMap {
  6. friend struct FuncPtrRegisterer;
  7. typedef void(*FuncPtr)();
  8. static std::map<std::string, FuncPtr> const &getMap() {
  9. return getWritableMap();
  10. }
  11.  
  12. private:
  13. // SIOF-proof singleton
  14. static std::map<std::string, FuncPtr> &getWritableMap() {
  15. static std::map<std::string, FuncPtr> theMap;
  16. return theMap;
  17. }
  18. };
  19.  
  20. // Each static instance will register one function pointer
  21. struct FuncPtrRegisterer {
  22. FuncPtrRegisterer(FuncPtrMap::FuncPtr funcPtr, char const *funcName) {
  23. FuncPtrMap::getWritableMap().insert(std::make_pair(funcName, funcPtr));
  24. }
  25. };
  26. }
  27.  
  28. // Public access to the function pointers map
  29. typedef std::map<std::string, detail::FuncPtrMap::FuncPtr> FunctionPointersMap;
  30. FunctionPointersMap const &gFunctionPointersMap = detail::FuncPtrMap::getMap();
  31.  
  32. #define DO_CAT(A, B) A##B
  33. #define CAT(A, B) DO_CAT(A, B)
  34.  
  35. // Registering macro : defines a static registerer
  36. // with a (hopefully) unique name.
  37. #define REGISTER_FUNC(NAME) detail::FuncPtrRegisterer \
  38.   CAT(fpreg, __COUNTER__) (&NAME, #NAME)
  39.  
  40.  
  41. //
  42. // Test
  43. //
  44.  
  45. void myFunc1() {
  46. std::cout << "func1\n";
  47. }
  48. REGISTER_FUNC(myFunc1);
  49.  
  50. void myFunc2() {
  51. std::cout << "func2\n";
  52. }
  53. REGISTER_FUNC(myFunc2);
  54.  
  55. int main()
  56. {
  57. for(FunctionPointersMap::const_iterator
  58. ite = gFunctionPointersMap.begin(),
  59. end = gFunctionPointersMap.end();
  60. ite != end; ++ite) {
  61. std::cout << "Calling " << ite->first << " : ";
  62. ite->second();
  63. }
  64.  
  65. return 0;
  66. }
Success #stdin #stdout 0s 3432KB
stdin
Standard input is empty
stdout
Calling myFunc1 : func1
Calling myFunc2 : func2