fork(1) download
  1. #include <stdio.h>
  2. #include <stddef.h>
  3.  
  4. template <typename T> struct list_node_base
  5. {
  6. T *next;
  7. T *prev;
  8. };
  9.  
  10. template <typename T>
  11. struct linked_list_node
  12. {
  13. list_node_base<T> list_node;
  14. };
  15.  
  16. template <typename T, linked_list_node<T> T::*NODE, bool is_member>
  17. struct list_base
  18. {
  19.  
  20. };
  21.  
  22. template <typename T, typename R, R T::*M>
  23. size_t offset_of()
  24. {
  25. return reinterpret_cast<size_t>(&(((T*)0)->*M));
  26. }
  27.  
  28. template <typename T, typename M> M get_member_type(M T::*);
  29. template <typename T, typename M> T get_class_type(M T::*);
  30.  
  31. #define OFFSET_OF(m) offset_of<decltype(get_class_type(m)), decltype(get_member_type(m)), m>()
  32.  
  33. template <typename T, linked_list_node<T> T::*NODE>
  34. struct list_base<T, NODE, true> : linked_list_node<T>
  35. {
  36. size_t offset()
  37. {
  38. return OFFSET_OF(&T::*NODE);
  39. }
  40. };
  41.  
  42. template <typename T, linked_list_node<T> T::*NODE>
  43. struct list_base<T, NODE, false> : linked_list_node<T>
  44. {
  45. size_t offset()
  46. {
  47. return OFFSET_OF(&T::list_node);
  48. }
  49. };
  50.  
  51. template <typename T, linked_list_node<T> T::*NODE = nullptr>
  52. struct linked_list : list_base<T, NODE, (linked_list_node<T> T::*)nullptr != NODE>
  53. //struct linked_list : list_base<T, NODE, NODE>
  54. {
  55. };
  56.  
  57. struct foo : linked_list_node<foo>
  58. {
  59. };
  60.  
  61. struct bar
  62. {
  63. linked_list_node<bar> node;
  64. };
  65.  
  66. linked_list<foo> foo_list;
  67. linked_list<bar, &bar::node> bar_list;
  68.  
  69. int main(int, char **)
  70. {
  71. return 0;
  72. }
  73.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp: In member function ‘size_t list_base<T, NODE, true>::offset()’:
prog.cpp:31:22: error: parse error in template argument list
 #define OFFSET_OF(m) offset_of<decltype(get_class_type(m)), decltype(get_member_type(m)), m>()
                      ^
prog.cpp:38:10: note: in expansion of macro ‘OFFSET_OF’
   return OFFSET_OF(&T::*NODE);
          ^
stdout
Standard output is empty