#include <stdio.h>
#include <stddef.h>
template < typename T> struct list_node_base
{
T * next;
T * prev;
} ;
template < typename T>
struct linked_list_node
{
list_node_base< T> list_node;
} ;
template < typename T, linked_list_node< T> T:: * NODE, bool is_member>
struct list_base
{
} ;
template < typename T, typename R, R T:: * M>
size_t offset_of( )
{
return reinterpret_cast < size_t > ( & ( ( ( T* ) 0 ) - > * M) ) ;
}
template < typename T, typename M> M get_member_type( M T:: * ) ;
template < typename T, typename M> T get_class_type( M T:: * ) ;
#define OFFSET_OF(m) offset_of<decltype(get_class_type(m)), decltype(get_member_type(m)), m>()
template < typename T, linked_list_node< T> T:: * NODE>
struct list_base< T, NODE, true > : linked_list_node< T>
{
size_t offset( )
{
return OFFSET_OF( & T:: * NODE) ;
}
} ;
template < typename T, linked_list_node< T> T:: * NODE>
struct list_base< T, NODE, false > : linked_list_node< T>
{
size_t offset( )
{
return OFFSET_OF( & T:: list_node ) ;
}
} ;
template < typename T, linked_list_node< T> T:: * NODE = nullptr>
struct linked_list : list_base< T, NODE, ( linked_list_node< T> T:: * ) nullptr ! = NODE>
//struct linked_list : list_base<T, NODE, NODE>
{
} ;
struct foo : linked_list_node< foo>
{
} ;
struct bar
{
linked_list_node< bar> node;
} ;
linked_list< foo> foo_list;
linked_list< bar, & bar:: node > bar_list;
int main( int , char ** )
{
return 0 ;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRkZWYuaD4KCnRlbXBsYXRlIDx0eXBlbmFtZSBUPiBzdHJ1Y3QgbGlzdF9ub2RlX2Jhc2UKewoJVCAqbmV4dDsKCVQgKnByZXY7Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kc3RydWN0IGxpbmtlZF9saXN0X25vZGUKewoJbGlzdF9ub2RlX2Jhc2U8VD4gbGlzdF9ub2RlOwp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIGxpbmtlZF9saXN0X25vZGU8VD4gVDo6Kk5PREUsIGJvb2wgaXNfbWVtYmVyPgpzdHJ1Y3QgbGlzdF9iYXNlCnsKCn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgUiwgUiBUOjoqTT4Kc2l6ZV90IG9mZnNldF9vZigpCnsKICAgIHJldHVybiByZWludGVycHJldF9jYXN0PHNpemVfdD4oJigoKFQqKTApLT4qTSkpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgTT4gTSBnZXRfbWVtYmVyX3R5cGUoTSBUOjoqKTsKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIE0+IFQgZ2V0X2NsYXNzX3R5cGUoTSBUOjoqKTsKCiNkZWZpbmUgT0ZGU0VUX09GKG0pIG9mZnNldF9vZjxkZWNsdHlwZShnZXRfY2xhc3NfdHlwZShtKSksIGRlY2x0eXBlKGdldF9tZW1iZXJfdHlwZShtKSksIG0+KCkKCnRlbXBsYXRlIDx0eXBlbmFtZSBULCBsaW5rZWRfbGlzdF9ub2RlPFQ+IFQ6OipOT0RFPgpzdHJ1Y3QgbGlzdF9iYXNlPFQsIE5PREUsIHRydWU+IDogbGlua2VkX2xpc3Rfbm9kZTxUPgp7CglzaXplX3Qgb2Zmc2V0KCkKCXsKCQlyZXR1cm4gT0ZGU0VUX09GKCZUOjoqTk9ERSk7Cgl9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgbGlua2VkX2xpc3Rfbm9kZTxUPiBUOjoqTk9ERT4Kc3RydWN0IGxpc3RfYmFzZTxULCBOT0RFLCBmYWxzZT4gOiBsaW5rZWRfbGlzdF9ub2RlPFQ+CnsKCXNpemVfdCBvZmZzZXQoKQoJewoJCXJldHVybiBPRkZTRVRfT0YoJlQ6Omxpc3Rfbm9kZSk7Cgl9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgbGlua2VkX2xpc3Rfbm9kZTxUPiBUOjoqTk9ERSA9IG51bGxwdHI+CnN0cnVjdCBsaW5rZWRfbGlzdCA6IGxpc3RfYmFzZTxULCBOT0RFLCAobGlua2VkX2xpc3Rfbm9kZTxUPiBUOjoqKW51bGxwdHIgIT0gTk9ERT4KLy9zdHJ1Y3QgbGlua2VkX2xpc3QgOiBsaXN0X2Jhc2U8VCwgTk9ERSwgTk9ERT4Kewp9OwoKc3RydWN0IGZvbyA6IGxpbmtlZF9saXN0X25vZGU8Zm9vPgp7Cn07CgpzdHJ1Y3QgYmFyCnsKCWxpbmtlZF9saXN0X25vZGU8YmFyPiBub2RlOwp9OwoKbGlua2VkX2xpc3Q8Zm9vPiBmb29fbGlzdDsKbGlua2VkX2xpc3Q8YmFyLCAmYmFyOjpub2RlPiBiYXJfbGlzdDsKCmludCBtYWluKGludCwgY2hhciAqKikKewoJcmV0dXJuIDA7Cn0K
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