@@ -33,6 +33,35 @@ using provider_unique_handle_t =
3333 std::unique_ptr<umf_memory_provider_t ,
3434 std::function<void (umf_memory_provider_handle_t )>>;
3535
36+ #define DEFINE_CHECK_OP (op ) \
37+ template <typename T> class HAS_OP_ ##op { \
38+ typedef char check_success; \
39+ typedef long check_fail; \
40+ template <typename U> static check_success test (decltype (&U::op)); \
41+ template <typename U> static check_fail test (...); \
42+ \
43+ public: \
44+ static constexpr bool value = \
45+ sizeof (test<T>(0 )) == sizeof (check_success); \
46+ }; \
47+ \
48+ template <typename T, typename ... Args> \
49+ static inline \
50+ typename std::enable_if<HAS_OP_##op<T>::value, umf_result_t >::type \
51+ CALL_OP_##op(T *t, Args &&...args) { \
52+ return t->op (std::forward<Args>(args)...); \
53+ }; \
54+ \
55+ static inline umf_result_t CALL_OP_##op(...) { \
56+ return UMF_RESULT_ERROR_NOT_SUPPORTED; \
57+ }
58+
59+ DEFINE_CHECK_OP (get_ipc_handle_size);
60+ DEFINE_CHECK_OP (get_ipc_handle);
61+ DEFINE_CHECK_OP (put_ipc_handle);
62+ DEFINE_CHECK_OP (open_ipc_handle);
63+ DEFINE_CHECK_OP (close_ipc_handle);
64+
3665#define UMF_ASSIGN_OP (ops, type, func, default_return ) \
3766 ops.func = [](void *obj, auto ... args) { \
3867 try { \
@@ -50,6 +79,15 @@ using provider_unique_handle_t =
5079 } \
5180 }
5281
82+ #define UMF_ASSIGN_OP_OPT (ops, type, func, default_return ) \
83+ ops.func = [](void *obj, auto ... args) { \
84+ try { \
85+ return CALL_OP_##func (reinterpret_cast <type *>(obj), args...); \
86+ } catch (...) { \
87+ return default_return; \
88+ } \
89+ }
90+
5391namespace detail {
5492template <typename T, typename ArgsTuple>
5593umf_result_t initialize (T *obj, ArgsTuple &&args) {
@@ -133,6 +171,12 @@ auto memoryProviderMakeUnique(Args &&...args) {
133171 UMF_ASSIGN_OP (ops.ext , T, purge_force, UMF_RESULT_ERROR_UNKNOWN);
134172 UMF_ASSIGN_OP (ops.ext , T, allocation_merge, UMF_RESULT_ERROR_UNKNOWN);
135173 UMF_ASSIGN_OP (ops.ext , T, allocation_split, UMF_RESULT_ERROR_UNKNOWN);
174+ UMF_ASSIGN_OP_OPT (ops.ipc , T, get_ipc_handle_size,
175+ UMF_RESULT_ERROR_UNKNOWN);
176+ UMF_ASSIGN_OP_OPT (ops.ipc , T, get_ipc_handle, UMF_RESULT_ERROR_UNKNOWN);
177+ UMF_ASSIGN_OP_OPT (ops.ipc , T, put_ipc_handle, UMF_RESULT_ERROR_UNKNOWN);
178+ UMF_ASSIGN_OP_OPT (ops.ipc , T, open_ipc_handle, UMF_RESULT_ERROR_UNKNOWN);
179+ UMF_ASSIGN_OP_OPT (ops.ipc , T, close_ipc_handle, UMF_RESULT_ERROR_UNKNOWN);
136180
137181 umf_memory_provider_handle_t hProvider = nullptr ;
138182 auto ret = umfMemoryProviderCreate (&ops, &argsTuple, &hProvider);
0 commit comments