Commit 308d49dc authored by Ronan's avatar Ronan

feat(Object): provide a smart L_SIGNAL macro

parent f6648a8e
......@@ -267,11 +267,9 @@ namespace Private {
};
}
#define L_DECLTYPE(NOOP, VAR) decltype(VAR)
// Useful to select a specific overloaded function.
#define L_RESOLVE_OVERLOAD(...) \
LinphonePrivate::Private::ResolveOverload<L_APPLY(L_DECLTYPE, 0, __VA_ARGS__)>()
LinphonePrivate::Private::ResolveOverload<__VA_ARGS__>()
// -----------------------------------------------------------------------------
// Wrapper public.
......
......@@ -22,19 +22,30 @@
// =============================================================================
// -----------------------------------------------------------------------------
// Misc.
// -----------------------------------------------------------------------------
// Concat in depth context.
#define L_CONCAT__(A, B) A ## B
#define L_CONCAT_(A, B) L_CONCAT__(A, B)
#define L_CONCAT(A, B) L_CONCAT_(A, B)
// Expand X. Useful to deal with variadic on Windows.
#define L_EXPAND(X) X
#define L_EXPAND_VARIADIC(...) __VA_ARGS__
// -----------------------------------------------------------------------------
// Variadic arguments.
// -----------------------------------------------------------------------------
// Get argument numbers from variadic.
#define L_ARG_N( \
A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, \
A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, N, ... \
) N
#define L_EXPAND(X) X
#define L_GET_N_ARGS(...) L_EXPAND(L_ARG_N( \
__VA_ARGS__, \
21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
......@@ -94,10 +105,20 @@
L_CONCAT(L_GET_HEAP_, L_GET_N_ARGS_SUB(__VA_ARGS__)) (__VA_ARGS__) \
)
#define L_GET_TAIL(NOOP, ...) __VA_ARGS__
// -----------------------------------------------------------------------------
// Callers.
// -----------------------------------------------------------------------------
// Call a macro on args.
#define L_CALL(MACRO, ARGS) MACRO ARGS
#define L_CALL_HELPER(MACRO, ARGS) MACRO ARGS
// -----------------------------------------------------------------------------
// Apply.
// -----------------------------------------------------------------------------
// Map each variadic args.
#define L_APPLY_1(MACRONAME, DATA, A1) \
L_CALL_HELPER(MACRONAME, (DATA, A1))
......@@ -278,4 +299,59 @@
(MACRONAME, DATA, __VA_ARGS__) \
)
#endif // ifndef _L_MAGIC_MACROS_H_
// -----------------------------------------------------------------------------
// Apply on list.
// -----------------------------------------------------------------------------
#define L_APPLY_LIST_CALL_HELPER(MACRONAME, LIST, A1) \
L_CALL_HELPER(MACRONAME, (L_CALL_HELPER(L_GET_ARG_1, LIST), A1))
#define L_APPLY_LIST_GET_TAIL(LIST) \
(L_CALL_HELPER(L_GET_TAIL, LIST))
#define L_APPLY_LIST_1(MACRONAME, LIST, A1) \
L_APPLY_LIST_CALL_HELPER(MACRONAME, LIST, A1)
#define L_APPLY_LIST_2(MACRONAME, LIST, A1, A2) \
L_APPLY_LIST_CALL_HELPER(MACRONAME, LIST, A1), \
L_APPLY_LIST_1(MACRONAME, L_APPLY_LIST_GET_TAIL(LIST), A2)
#define L_APPLY_LIST_3(MACRONAME, LIST, A1, A2, A3) \
L_APPLY_LIST_CALL_HELPER(MACRONAME, LIST, A1), \
L_APPLY_LIST_2(MACRONAME, L_APPLY_LIST_GET_TAIL(LIST), A2, A3)
#define L_APPLY_LIST_4(MACRONAME, LIST, A1, A2, A3, A4) \
L_APPLY_LIST_CALL_HELPER(MACRONAME, LIST, A1), \
L_APPLY_LIST_3(MACRONAME, L_APPLY_LIST_GET_TAIL(LIST), A2, A3, A4)
#define L_APPLY_LIST_5(MACRONAME, LIST, A1, A2, A3, A4, A5) \
L_APPLY_LIST_CALL_HELPER(MACRONAME, LIST, A1), \
L_APPLY_LIST_4(MACRONAME, L_APPLY_LIST_GET_TAIL(LIST), A2, A3, A4, A5)
#define L_APPLY_LIST_6(MACRONAME, LIST, A1, A2, A3, A4, A5, A6) \
L_APPLY_LIST_CALL_HELPER(MACRONAME, LIST, A1), \
L_APPLY_LIST_5(MACRONAME, L_APPLY_LIST_GET_TAIL(LIST), A2, A3, A4, A5, A6)
#define L_APPLY_LIST_7(MACRONAME, LIST, A1, A2, A3, A4, A5, A6, A7) \
L_APPLY_LIST_CALL_HELPER(MACRONAME, LIST, A1), \
L_APPLY_LIST_6(MACRONAME, L_APPLY_LIST_GET_TAIL(LIST), A2, A3, A4, A5, A6, A7)
#define L_APPLY_LIST_8(MACRONAME, LIST, A1, A2, A3, A4, A5, A6, A7, A8) \
L_APPLY_LIST_CALL_HELPER(MACRONAME, LIST, A1), \
L_APPLY_LIST_7(MACRONAME, L_APPLY_LIST_GET_TAIL(LIST), A2, A3, A4, A5, A6, A7, A8)
#define L_APPLY_LIST_9(MACRONAME, LIST, A1, A2, A3, A4, A5, A6, A7, A8, A9) \
L_APPLY_LIST_CALL_HELPER(MACRONAME, LIST, A1), \
L_APPLY_LIST_8(MACRONAME, L_APPLY_LIST_GET_TAIL(LIST), A2, A3, A4, A5, A6, A7, A8, A9)
#define L_APPLY_LIST_10(MACRONAME, LIST, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) \
L_APPLY_LIST_CALL_HELPER(MACRONAME, LIST, A1), \
L_APPLY_LIST_9(MACRONAME, L_APPLY_LIST_GET_TAIL(LIST), A2, A3, A4, A5, A6, A7, A8, A9, A10)
#define L_APPLY_LIST(MACRONAME, LIST, ...) \
L_CALL( \
L_CONCAT(L_APPLY_LIST_, L_GET_N_ARGS(__VA_ARGS__)), \
(MACRONAME, LIST, __VA_ARGS__) \
)
#endif // ifndef _MAGIC_MACROS_H_
......@@ -38,7 +38,16 @@
); \
const std::lock_guard<Object::Lock> synchronized(const_cast<Object::Lock &>(getLock()));
#define CHECK_CONNECT_TYPES(SIGNAL_TYPE, SLOT_TYPE) \
#define L_SIGNAL_CONCAT_TYPE_ARG(TYPE, PARAM) TYPE PARAM
// Declare one signal method.
#define L_SIGNAL(NAME, TYPES, ...) void NAME (L_APPLY_LIST(L_SIGNAL_CONCAT_TYPE_ARG, TYPES, __VA_ARGS__)) { \
typedef std::remove_reference<decltype(*this)>::type ClassType; \
typedef decltype(L_CALL(L_RESOLVE_OVERLOAD, TYPES)(&ClassType::NAME)) SignalType; \
SignalType sig; (void)sig; \
}
#define L_CHECK_CONNECT_TYPES(SIGNAL_TYPE, SLOT_TYPE) \
static_assert( \
static_cast<int>(SIGNAL_TYPE::ArgumentsNumber) >= static_cast<int>(SLOT_TYPE::ArgumentsNumber), \
"Slot requires less arguments." \
......@@ -78,7 +87,7 @@ public:
typedef Private::FunctionPointer<Func1> SignalType;
typedef Private::FunctionPointer<Func2> SlotType;
CHECK_CONNECT_TYPES(SignalType, SlotType)
L_CHECK_CONNECT_TYPES(SignalType, SlotType)
return connectInternal(
sender, reinterpret_cast<void **>(&signal), sender, nullptr,
......@@ -99,7 +108,7 @@ public:
typedef Private::FunctionPointer<Func1> SignalType;
typedef Private::FunctionPointer<Func2> SlotType;
CHECK_CONNECT_TYPES(SignalType, SlotType)
L_CHECK_CONNECT_TYPES(SignalType, SlotType)
return connectInternal(sender, reinterpret_cast<void **>(&signal), receiver, reinterpret_cast<void **>(&slot),
new Private::SlotObjectMemberFunction<
......@@ -131,6 +140,6 @@ private:
LINPHONE_END_NAMESPACE
#undef CHECK_CONNECT_TYPES
#undef L_CHECK_CONNECT_TYPES
#endif // ifndef _L_OBJECT_H_
......@@ -38,6 +38,9 @@ class TestObject : public Object {
public:
TestObject () : Object(*new TestObjectPrivate) {}
L_SIGNAL(signal1, (int, float), toto, tata);
L_SIGNAL(signal2, (bool, float, int), a, b, c);
private:
L_DECLARE_PRIVATE(TestObject);
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment