Guest User

Untitled

a guest
May 27th, 2016
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.23 KB | None | 0 0
  1. #include <iostream>
  2.  
  3. struct A {};
  4.  
  5. std::string to_string(const A&)
  6. {
  7. return "I am a A!";
  8. }
  9.  
  10. // Type B with a serialize method.
  11. struct B
  12. {
  13. std::string serialize() const
  14. {
  15. return "I am a B!";
  16. }
  17. };
  18.  
  19. // Type C with a "wrong" serialize member (not a method) and a to_string overload.
  20. struct C
  21. {
  22. std::string serialize;
  23. };
  24.  
  25. std::string to_string(const C&)
  26. {
  27. return "I am a C!";
  28. }
  29.  
  30. struct D : A
  31. {
  32. std::string serialize() const
  33. {
  34. return "I am a D!";
  35. }
  36. };
  37.  
  38. struct E
  39. {
  40. struct Functor
  41. {
  42. std::string operator()(){
  43. return "I am a E!";
  44. }
  45. };
  46.  
  47. Functor serialize;
  48. };
  49.  
  50. // Structures are good as they expose everything in public!
  51. template <class T> struct hasSerialize
  52. {
  53. // For the compile time comparison.
  54. typedef char yes[1];
  55. typedef yes no[2];
  56.  
  57. // This helper struct permits us to check two properties of a template argument.
  58. template <typename U, U u> struct reallyHas;
  59.  
  60. // Two overloads for yes: one if for the signature of a normal method, one is for the signature of a const method.
  61. template <typename C> static yes& test(reallyHas<std::string (C::*)(), &C::serialize>* /*unused*/) { }
  62. template <typename C> static yes& test(reallyHas<std::string (C::*)() const, &C::serialize>* /*unused*/) { }
  63.  
  64. // The famous C++ sink-hole.
  65. // Note that sink-hole must be templated too as we are testing test<T>(0).
  66. template <typename> static no& test(...) { /* dark matter */ }
  67.  
  68. // The constant used as a return value for the test.
  69. enum { value = sizeof(test<T>(0)) == sizeof(yes) };
  70. };
  71.  
  72. template <class T> bool testHasSerialize(const T& /*t*/) { return hasSerialize<T>::value; }
  73.  
  74. template<bool B, class T = void>
  75. struct enable_if {};
  76.  
  77. template<class T>
  78. struct enable_if<true, T> { typedef T type; };
  79.  
  80.  
  81. template <class T> typename enable_if<hasSerialize<T>::value, std::string>::type serialize(const T& obj)
  82. {
  83. return obj.serialize();
  84. }
  85.  
  86. template <class T> typename enable_if<!hasSerialize<T>::value, std::string>::type serialize(const T& obj)
  87. {
  88. return to_string(obj);
  89. }
  90.  
  91. int main() {
  92. A a;
  93. B b;
  94. C c;
  95.  
  96. std::cout << serialize(a) << std::endl;
  97. std::cout << serialize(b) << std::endl;
  98. std::cout << serialize(c) << std::endl;
  99.  
  100. return 0;
  101. }
Add Comment
Please, Sign In to add comment