diff --git a/CMakeLists.txt b/CMakeLists.txt index 082d3b0..bb499ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -272,6 +272,7 @@ pkg_check_modules(GMOCK gmock) add_executable(alltests test/msleep.cc test/mock_authenticator.cc + test/test_container_of.cc test/test_response_parser.cc test/test_server.cc test/test_timepoint.cc diff --git a/lib/webfuse/core/container_of.h b/lib/webfuse/core/container_of.h new file mode 100644 index 0000000..6ddbb82 --- /dev/null +++ b/lib/webfuse/core/container_of.h @@ -0,0 +1,16 @@ +#ifndef WF_CONTAINER_OF_H +#define WF_CONTAINER_OF_H + +#ifndef __cplusplus +#include +#else +#include +#endif + +#define WF_CONTAINER_OF(pointer, type, member) \ + ({ \ + const typeof( ((type *)0)->member ) *__mptr = (pointer); \ + (type *)( (char *)__mptr - offsetof(type, member) ); \ + }) + +#endif diff --git a/test/test_container_of.cc b/test/test_container_of.cc new file mode 100644 index 0000000..91a96ef --- /dev/null +++ b/test/test_container_of.cc @@ -0,0 +1,29 @@ +#include +#include "webfuse/core/container_of.h" + +namespace +{ + +struct MyStruct +{ + int first; + int second; +}; + +} + +TEST(ContainerOf, FirstMember) +{ + MyStruct my_struct = {23, 42}; + + int * first = &my_struct.first; + ASSERT_EQ(&my_struct, WF_CONTAINER_OF(first, MyStruct, first)); +} + +TEST(ContainerOf, SecondMember) +{ + MyStruct my_struct = {23, 42}; + + int * second = &my_struct.second; + ASSERT_EQ(&my_struct, WF_CONTAINER_OF(second, MyStruct, second)); +} \ No newline at end of file