From 9e25d8ef7e82c3542de2b8760e765ae1d5980339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Wed, 21 Feb 2024 09:27:56 +0100 Subject: [PATCH] core: Refactor TimerImpl with variadic templates --- src/core/model/timer-impl.h | 1086 ++--------------------------------- 1 file changed, 56 insertions(+), 1030 deletions(-) diff --git a/src/core/model/timer-impl.h b/src/core/model/timer-impl.h index 88996f227..a49696dbf 100644 --- a/src/core/model/timer-impl.h +++ b/src/core/model/timer-impl.h @@ -21,9 +21,9 @@ #define TIMER_IMPL_H #include "fatal-error.h" -#include "int-to-type.h" #include "simulator.h" -#include "type-traits.h" + +#include /** * \file @@ -49,75 +49,12 @@ class TimerImpl /** * Set the arguments to be used when invoking the expire function. + * + * \tparam Args \deduced Type template parameter pack + * \param [in] args The arguments to pass to the invoked method */ - /**@{*/ - /** - * \tparam T1 \deduced Type of the first argument. - * \param [in] a1 The first argument - */ - template - void SetArgs(T1 a1); - /** - * \tparam T1 \deduced Type of the first argument. - * \tparam T2 \deduced Type of the second argument. - * \param [in] a1 the first argument - * \param [in] a2 the second argument - */ - template - void SetArgs(T1 a1, T2 a2); - /** - * \tparam T1 \deduced Type of the first argument. - * \tparam T2 \deduced Type of the second argument. - * \tparam T3 \deduced Type of the third argument. - * \param [in] a1 the first argument - * \param [in] a2 the second argument - * \param [in] a3 the third argument - */ - template - void SetArgs(T1 a1, T2 a2, T3 a3); - /** - * \tparam T1 \deduced Type of the first argument. - * \tparam T2 \deduced Type of the second argument. - * \tparam T3 \deduced Type of the third argument. - * \tparam T4 \deduced Type of the fourth argument. - * \param [in] a1 the first argument - * \param [in] a2 the second argument - * \param [in] a3 the third argument - * \param [in] a4 the fourth argument - */ - template - void SetArgs(T1 a1, T2 a2, T3 a3, T4 a4); - /** - * \tparam T1 \deduced Type of the first argument. - * \tparam T2 \deduced Type of the second argument. - * \tparam T3 \deduced Type of the third argument. - * \tparam T4 \deduced Type of the fourth argument. - * \tparam T5 \deduced Type of the fifth argument. - * \param [in] a1 the first argument - * \param [in] a2 the second argument - * \param [in] a3 the third argument - * \param [in] a4 the fourth argument - * \param [in] a5 the fifth argument - */ - template - void SetArgs(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5); - /** - * \tparam T1 \deduced Type of the first argument. - * \tparam T2 \deduced Type of the second argument. - * \tparam T3 \deduced Type of the third argument. - * \tparam T4 \deduced Type of the fourth argument. - * \tparam T5 \deduced Type of the fifth argument. - * \tparam T6 \deduced Type of the sixth argument. - * \param [in] a1 the first argument - * \param [in] a2 the second argument - * \param [in] a3 the third argument - * \param [in] a4 the fourth argument - * \param [in] a5 the fifth argument - * \param [in] a6 the sixth argument - */ - template - void SetArgs(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6); - /**@}*/ + template + void SetArgs(Args... args); /** * Schedule the callback for a future time. @@ -144,932 +81,111 @@ namespace ns3 * \defgroup timerimpl TimerImpl Implementation * @{ */ - /** TimerImpl specialization class for varying numbers of arguments. */ -template -struct TimerImplOne : public TimerImpl +template +struct TimerImplX : public TimerImpl { /** * Bind the arguments to be used when the callback function is invoked. * - * \param [in] a1 The first argument. + * \param [in] args The arguments to pass to the invoked method. */ - virtual void SetArguments(T1 a1) = 0; -}; - -/** TimerImpl specialization class for varying numbers of arguments. */ -template -struct TimerImplTwo : public TimerImpl -{ - /** - * Bind the arguments to be used when the callback function is invoked. - * - * \param [in] a1 The first argument. - * \param [in] a2 The second argument. - */ - virtual void SetArguments(T1 a1, T2 a2) = 0; -}; - -/** TimerImpl specialization class for varying numbers of arguments. */ -template -struct TimerImplThree : public TimerImpl -{ - /** - * Bind the arguments to be used when the callback function is invoked. - * - * \param [in] a1 The first argument. - * \param [in] a2 The second argument. - * \param [in] a3 The third argument. - */ - virtual void SetArguments(T1 a1, T2 a2, T3 a3) = 0; -}; - -/** TimerImpl specialization class for varying numbers of arguments. */ -template -struct TimerImplFour : public TimerImpl -{ - /** - * Bind the arguments to be used when the callback function is invoked. - * - * \param [in] a1 The first argument. - * \param [in] a2 The second argument. - * \param [in] a3 The third argument. - * \param [in] a4 The fourth argument. - */ - virtual void SetArguments(T1 a1, T2 a2, T3 a3, T4 a4) = 0; -}; - -/** TimerImpl specialization class for varying numbers of arguments. */ -template -struct TimerImplFive : public TimerImpl -{ - /** - * Bind the arguments to be used when the callback function is invoked. - * - * \param [in] a1 The first argument. - * \param [in] a2 The second argument. - * \param [in] a3 The third argument. - * \param [in] a4 The fourth argument. - * \param [in] a5 The fifth argument. - */ - virtual void SetArguments(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) = 0; -}; - -/** TimerImpl specialization class for varying numbers of arguments. */ -template -struct TimerImplSix : public TimerImpl -{ - /** - * Bind the arguments to be used when the callback function is invoked. - * - * \param [in] a1 The first argument. - * \param [in] a2 The second argument. - * \param [in] a3 The third argument. - * \param [in] a4 The fourth argument. - * \param [in] a5 The fifth argument. - * \param [in] a6 The sixth argument. - */ - virtual void SetArguments(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6) = 0; -}; - -/** Type and reference traits for TimerImpl arguments. */ -template -struct TimerTraits -{ - /** Storage type for an argument. */ - typedef typename TypeTraits::ReferencedType>::NonConstType StoredType; - /** Parameter type for an argument. */ - typedef const StoredType& ParameterType; + virtual void SetArguments(Args... args) = 0; }; /** * Make a TimerImpl from a function pointer taking varying numbers of arguments. * - * \tparam FN \deduced Function signature type of the callback function. - * \param [in] fn The function pointer to invoke when the timer expires. + * \tparam U \deduced Return type of the callback function. + * \tparam Ts \deduced Argument types of the callback function. * \returns The TimerImpl. */ -template +template TimerImpl* -MakeTimerImpl(FN fn) +MakeTimerImpl(U(fn)(Ts...)) { - NS_ASSERT(TypeTraits::IsFunctionPointer); - return MakeTimerImpl(IntToType::FunctionPointerTraits::nArgs>(), fn); -} - -/** - * Make a TimerImpl from a function pointer taking zero arguments. - * \copydetails MakeTimerImpl(FN) - */ -template -TimerImpl* -MakeTimerImpl(IntToType<0>, FN fn) -{ - struct FnTimerImplZero : public TimerImpl + struct FnTimerImpl : public TimerImplX&...> { - FnTimerImplZero(FN fn) + using FN = U (*)(Ts...); + + FnTimerImpl(void (*fn)(Ts...)) : m_fn(fn) { } + void SetArguments(const std::remove_cvref_t&... args) override + { + m_arguments = std::tuple(args...); + } + EventId Schedule(const Time& delay) override { - return Simulator::Schedule(delay, m_fn); + return std::apply( + [&, this](Ts... args) { return Simulator::Schedule(delay, m_fn, args...); }, + m_arguments); } void Invoke() override { - m_fn(); + std::apply([this](Ts... args) { (m_fn)(args...); }, m_arguments); } FN m_fn; - }* function = new FnTimerImplZero(fn); + std::tuple...> m_arguments; + }* function = new FnTimerImpl(fn); return function; } -/** - * Make a TimerImpl from a function pointer taking one argument. - * \copydetails MakeTimerImpl(FN) - */ -template -TimerImpl* -MakeTimerImpl(IntToType<1>, FN fn) -{ - typedef typename TypeTraits::FunctionPointerTraits::Arg1Type T1; - typedef typename TimerTraits::ParameterType T1Parameter; - typedef typename TimerTraits::StoredType T1Stored; - - struct FnTimerImplOne : public TimerImplOne - { - FnTimerImplOne(FN fn) - : m_fn(fn) - { - } - - void SetArguments(T1Parameter a1) override - { - m_a1 = a1; - } - - EventId Schedule(const Time& delay) override - { - return Simulator::Schedule(delay, m_fn, m_a1); - } - - void Invoke() override - { - m_fn(m_a1); - } - - FN m_fn; - T1Stored m_a1; - }* function = new FnTimerImplOne(fn); - - return function; -} - -/** - * Make a TimerImpl from a function pointer taking two arguments. - * \copydetails MakeTimerImpl(FN) - */ -template -TimerImpl* -MakeTimerImpl(IntToType<2>, FN fn) -{ - typedef typename TypeTraits::FunctionPointerTraits::Arg1Type T1; - typedef typename TimerTraits::ParameterType T1Parameter; - typedef typename TimerTraits::StoredType T1Stored; - typedef typename TypeTraits::FunctionPointerTraits::Arg2Type T2; - typedef typename TimerTraits::ParameterType T2Parameter; - typedef typename TimerTraits::StoredType T2Stored; - - struct FnTimerImplTwo : public TimerImplTwo - { - FnTimerImplTwo(FN fn) - : m_fn(fn) - { - } - - void SetArguments(T1Parameter a1, T2Parameter a2) override - { - m_a1 = a1; - m_a2 = a2; - } - - EventId Schedule(const Time& delay) override - { - return Simulator::Schedule(delay, m_fn, m_a1, m_a2); - } - - void Invoke() override - { - m_fn(m_a1, m_a2); - } - - FN m_fn; - T1Stored m_a1; - T2Stored m_a2; - }* function = new FnTimerImplTwo(fn); - - return function; -} - -/** - * Make a TimerImpl from a function pointer taking three arguments. - * \copydetails MakeTimerImpl(FN) - */ -template -TimerImpl* -MakeTimerImpl(IntToType<3>, FN fn) -{ - typedef typename TypeTraits::FunctionPointerTraits::Arg1Type T1; - typedef typename TimerTraits::ParameterType T1Parameter; - typedef typename TimerTraits::StoredType T1Stored; - typedef typename TypeTraits::FunctionPointerTraits::Arg2Type T2; - typedef typename TimerTraits::ParameterType T2Parameter; - typedef typename TimerTraits::StoredType T2Stored; - typedef typename TypeTraits::FunctionPointerTraits::Arg3Type T3; - typedef typename TimerTraits::ParameterType T3Parameter; - typedef typename TimerTraits::StoredType T3Stored; - - struct FnTimerImplThree : public TimerImplThree - { - FnTimerImplThree(FN fn) - : m_fn(fn) - { - } - - void SetArguments(T1Parameter a1, T2Parameter a2, T3Parameter a3) override - { - m_a1 = a1; - m_a2 = a2; - m_a3 = a3; - } - - EventId Schedule(const Time& delay) override - { - return Simulator::Schedule(delay, m_fn, m_a1, m_a2, m_a3); - } - - void Invoke() override - { - m_fn(m_a1, m_a2, m_a3); - } - - FN m_fn; - T1Stored m_a1; - T2Stored m_a2; - T3Stored m_a3; - }* function = new FnTimerImplThree(fn); - - return function; -} - -/** - * Make a TimerImpl from a function pointer taking four arguments. - * \copydetails MakeTimerImpl(FN) - */ -template -TimerImpl* -MakeTimerImpl(IntToType<4>, FN fn) -{ - typedef typename TypeTraits::FunctionPointerTraits::Arg1Type T1; - typedef typename TimerTraits::ParameterType T1Parameter; - typedef typename TimerTraits::StoredType T1Stored; - typedef typename TypeTraits::FunctionPointerTraits::Arg2Type T2; - typedef typename TimerTraits::ParameterType T2Parameter; - typedef typename TimerTraits::StoredType T2Stored; - typedef typename TypeTraits::FunctionPointerTraits::Arg3Type T3; - typedef typename TimerTraits::ParameterType T3Parameter; - typedef typename TimerTraits::StoredType T3Stored; - typedef typename TypeTraits::FunctionPointerTraits::Arg4Type T4; - typedef typename TimerTraits::ParameterType T4Parameter; - typedef typename TimerTraits::StoredType T4Stored; - - struct FnTimerImplFour - : public TimerImplFour - { - FnTimerImplFour(FN fn) - : m_fn(fn) - { - } - - void SetArguments(T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4) override - { - m_a1 = a1; - m_a2 = a2; - m_a3 = a3; - m_a4 = a4; - } - - EventId Schedule(const Time& delay) override - { - return Simulator::Schedule(delay, m_fn, m_a1, m_a2, m_a3, m_a4); - } - - void Invoke() override - { - m_fn(m_a1, m_a2, m_a3, m_a4); - } - - FN m_fn; - T1Stored m_a1; - T2Stored m_a2; - T3Stored m_a3; - T4Stored m_a4; - }* function = new FnTimerImplFour(fn); - - return function; -} - -/** - * Make a TimerImpl from a function pointer taking five arguments. - * \copydetails MakeTimerImpl(FN) - */ -template -TimerImpl* -MakeTimerImpl(IntToType<5>, FN fn) -{ - typedef typename TypeTraits::FunctionPointerTraits::Arg1Type T1; - typedef typename TimerTraits::ParameterType T1Parameter; - typedef typename TimerTraits::StoredType T1Stored; - typedef typename TypeTraits::FunctionPointerTraits::Arg2Type T2; - typedef typename TimerTraits::ParameterType T2Parameter; - typedef typename TimerTraits::StoredType T2Stored; - typedef typename TypeTraits::FunctionPointerTraits::Arg3Type T3; - typedef typename TimerTraits::ParameterType T3Parameter; - typedef typename TimerTraits::StoredType T3Stored; - typedef typename TypeTraits::FunctionPointerTraits::Arg4Type T4; - typedef typename TimerTraits::ParameterType T4Parameter; - typedef typename TimerTraits::StoredType T4Stored; - typedef typename TypeTraits::FunctionPointerTraits::Arg5Type T5; - typedef typename TimerTraits::ParameterType T5Parameter; - typedef typename TimerTraits::StoredType T5Stored; - - struct FnTimerImplFive - : public TimerImplFive - { - FnTimerImplFive(FN fn) - : m_fn(fn) - { - } - - void SetArguments(T1Parameter a1, - T2Parameter a2, - T3Parameter a3, - T4Parameter a4, - T5Parameter a5) override - { - m_a1 = a1; - m_a2 = a2; - m_a3 = a3; - m_a4 = a4; - m_a5 = a5; - } - - EventId Schedule(const Time& delay) override - { - return Simulator::Schedule(delay, m_fn, m_a1, m_a2, m_a3, m_a4, m_a5); - } - - void Invoke() override - { - m_fn(m_a1, m_a2, m_a3, m_a4, m_a5); - } - - FN m_fn; - T1Stored m_a1; - T2Stored m_a2; - T3Stored m_a3; - T4Stored m_a4; - T5Stored m_a5; - }* function = new FnTimerImplFive(fn); - - return function; -} - -/** - * Make a TimerImpl from a function pointer taking six arguments. - * \copydetails MakeTimerImpl(FN) - */ -template -TimerImpl* -MakeTimerImpl(IntToType<6>, FN fn) -{ - typedef typename TypeTraits::FunctionPointerTraits::Arg1Type T1; - typedef typename TimerTraits::ParameterType T1Parameter; - typedef typename TimerTraits::StoredType T1Stored; - typedef typename TypeTraits::FunctionPointerTraits::Arg2Type T2; - typedef typename TimerTraits::ParameterType T2Parameter; - typedef typename TimerTraits::StoredType T2Stored; - typedef typename TypeTraits::FunctionPointerTraits::Arg3Type T3; - typedef typename TimerTraits::ParameterType T3Parameter; - typedef typename TimerTraits::StoredType T3Stored; - typedef typename TypeTraits::FunctionPointerTraits::Arg4Type T4; - typedef typename TimerTraits::ParameterType T4Parameter; - typedef typename TimerTraits::StoredType T4Stored; - typedef typename TypeTraits::FunctionPointerTraits::Arg5Type T5; - typedef typename TimerTraits::ParameterType T5Parameter; - typedef typename TimerTraits::StoredType T5Stored; - typedef typename TypeTraits::FunctionPointerTraits::Arg6Type T6; - typedef typename TimerTraits::ParameterType T6Parameter; - typedef typename TimerTraits::StoredType T6Stored; - - struct FnTimerImplSix : public TimerImplSix - { - FnTimerImplSix(FN fn) - : m_fn(fn) - { - } - - virtual void SetArguments(T1Parameter a1, - T2Parameter a2, - T3Parameter a3, - T4Parameter a4, - T5Parameter a5, - T6Parameter a6) - { - m_a1 = a1; - m_a2 = a2; - m_a3 = a3; - m_a4 = a4; - m_a5 = a5; - m_a6 = a6; - } - - virtual EventId Schedule(const Time& delay) - { - return Simulator::Schedule(delay, m_fn, m_a1, m_a2, m_a3, m_a4, m_a5, m_a6); - } - - virtual void Invoke() - { - m_fn(m_a1, m_a2, m_a3, m_a4, m_a5, m_a6); - } - - FN m_fn; - T1Stored m_a1; - T2Stored m_a2; - T3Stored m_a3; - T4Stored m_a4; - T5Stored m_a5; - T6Stored m_a6; - }* function = new FnTimerImplSix(fn); - - return function; -} - -/** - * Helper for the MakeTimerImpl functions which take a class method. - * - * This helper converts a pointer to a reference. - * - * This is the generic template declaration (with empty body). - * - * \tparam T \explicit The object type. - */ -template -struct TimerImplMemberTraits; - -/** - * Helper for the MakeTimerImpl functions which take a class method. - * - * This helper converts a pointer to a reference. - * - * This is the specialization for pointer to \c T. - * - * \tparam T \explicit The object type. - */ -template -struct TimerImplMemberTraits -{ - /** - * Convert a pointer type to a reference. - * - * \param [in] p The pointer. - * \returns A reference to the object pointed to by \c p. - */ - static T& GetReference(T* p) - { - return *p; - } -}; - /** * Make a TimerImpl from a class method pointer taking * a varying number of arguments. * - * \tparam MEM_PTR \deduced Class method function signature type. * \tparam OBJ_PTR \deduced Class type. + * \tparam U \deduced Class method function return type. + * \tparam V \deduced Class method function class type. + * \tparam Ts \deduced Class method function argument types. * \param [in] memPtr Class method to invoke when the timer expires. * \param [in] objPtr Object instance pointer. * \returns The TimerImpl. */ -template +template TimerImpl* -MakeTimerImpl(MEM_PTR memPtr, OBJ_PTR objPtr) +MakeTimerImpl(U (V::*memPtr)(Ts...), OBJ_PTR objPtr) { - NS_ASSERT(TypeTraits::IsPointerToMember); - return MakeTimerImpl(IntToType::PointerToMemberTraits::nArgs>(), - memPtr, - objPtr); -} - -/** - * Make a TimerImpl from a function pointer taking zero arguments. - * \copydetails MakeTimerImpl(MEM_PTR,OBJ_PTR) - */ -template -TimerImpl* -MakeTimerImpl(IntToType<0>, MEM_PTR memPtr, OBJ_PTR objPtr) -{ - struct MemFnTimerImplZero : public TimerImpl + struct MemFnTimerImpl : public TimerImplX&...> { - MemFnTimerImplZero(MEM_PTR memPtr, OBJ_PTR objPtr) + using MEM_PTR = U (V::*)(Ts...); + + MemFnTimerImpl(MEM_PTR memPtr, OBJ_PTR objPtr) : m_memPtr(memPtr), m_objPtr(objPtr) { } + void SetArguments(const std::remove_cvref_t&... args) override + { + m_arguments = std::tuple(args...); + } + EventId Schedule(const Time& delay) override { - return Simulator::Schedule(delay, m_memPtr, m_objPtr); + return std::apply( + [&, this](Ts... args) { + return Simulator::Schedule(delay, m_memPtr, m_objPtr, args...); + }, + m_arguments); } void Invoke() override { - (TimerImplMemberTraits::GetReference(m_objPtr).*m_memPtr)(); + std::apply([this](Ts... args) { ((*m_objPtr).*m_memPtr)(args...); }, m_arguments); } MEM_PTR m_memPtr; OBJ_PTR m_objPtr; - }* function = new MemFnTimerImplZero(memPtr, objPtr); - - return function; -} - -/** - * Make a TimerImpl from a function pointer taking one argument. - * \copydetails MakeTimerImpl(MEM_PTR,OBJ_PTR) - */ -template -TimerImpl* -MakeTimerImpl(IntToType<1>, MEM_PTR memPtr, OBJ_PTR objPtr) -{ - typedef typename TypeTraits::PointerToMemberTraits::Arg1Type T1; - typedef typename TimerTraits::ParameterType T1Parameter; - typedef typename TimerTraits::StoredType T1Stored; - - struct MemFnTimerImplOne : public TimerImplOne - { - MemFnTimerImplOne(MEM_PTR memPtr, OBJ_PTR objPtr) - : m_memPtr(memPtr), - m_objPtr(objPtr) - { - } - - void SetArguments(T1Parameter a1) override - { - m_a1 = a1; - } - - EventId Schedule(const Time& delay) override - { - return Simulator::Schedule(delay, m_memPtr, m_objPtr, m_a1); - } - - void Invoke() override - { - (TimerImplMemberTraits::GetReference(m_objPtr).*m_memPtr)(m_a1); - } - - MEM_PTR m_memPtr; - OBJ_PTR m_objPtr; - T1Stored m_a1; - }* function = new MemFnTimerImplOne(memPtr, objPtr); - - return function; -} - -/** - * Make a TimerImpl from a function pointer taking two arguments. - * \copydetails MakeTimerImpl(MEM_PTR,OBJ_PTR) - */ -template -TimerImpl* -MakeTimerImpl(IntToType<2>, MEM_PTR memPtr, OBJ_PTR objPtr) -{ - typedef typename TypeTraits::PointerToMemberTraits::Arg1Type T1; - typedef typename TimerTraits::ParameterType T1Parameter; - typedef typename TimerTraits::StoredType T1Stored; - typedef typename TypeTraits::PointerToMemberTraits::Arg2Type T2; - typedef typename TimerTraits::ParameterType T2Parameter; - typedef typename TimerTraits::StoredType T2Stored; - - struct MemFnTimerImplTwo : public TimerImplTwo - { - MemFnTimerImplTwo(MEM_PTR memPtr, OBJ_PTR objPtr) - : m_memPtr(memPtr), - m_objPtr(objPtr) - { - } - - void SetArguments(T1Parameter a1, T2Parameter a2) override - { - m_a1 = a1; - m_a2 = a2; - } - - EventId Schedule(const Time& delay) override - { - return Simulator::Schedule(delay, m_memPtr, m_objPtr, m_a1, m_a2); - } - - void Invoke() override - { - (TimerImplMemberTraits::GetReference(m_objPtr).*m_memPtr)(m_a1, m_a2); - } - - MEM_PTR m_memPtr; - OBJ_PTR m_objPtr; - T1Stored m_a1; - T2Stored m_a2; - }* function = new MemFnTimerImplTwo(memPtr, objPtr); - - return function; -} - -/** - * Make a TimerImpl from a function pointer taking three arguments. - * \copydetails MakeTimerImpl(MEM_PTR,OBJ_PTR) - */ -template -TimerImpl* -MakeTimerImpl(IntToType<3>, MEM_PTR memPtr, OBJ_PTR objPtr) -{ - typedef typename TypeTraits::PointerToMemberTraits::Arg1Type T1; - typedef typename TimerTraits::ParameterType T1Parameter; - typedef typename TimerTraits::StoredType T1Stored; - typedef typename TypeTraits::PointerToMemberTraits::Arg2Type T2; - typedef typename TimerTraits::ParameterType T2Parameter; - typedef typename TimerTraits::StoredType T2Stored; - typedef typename TypeTraits::PointerToMemberTraits::Arg3Type T3; - typedef typename TimerTraits::ParameterType T3Parameter; - typedef typename TimerTraits::StoredType T3Stored; - - struct MemFnTimerImplThree : public TimerImplThree - { - MemFnTimerImplThree(MEM_PTR memPtr, OBJ_PTR objPtr) - : m_memPtr(memPtr), - m_objPtr(objPtr) - { - } - - void SetArguments(T1Parameter a1, T2Parameter a2, T3Parameter a3) override - { - m_a1 = a1; - m_a2 = a2; - m_a3 = a3; - } - - EventId Schedule(const Time& delay) override - { - return Simulator::Schedule(delay, m_memPtr, m_objPtr, m_a1, m_a2, m_a3); - } - - void Invoke() override - { - (TimerImplMemberTraits::GetReference(m_objPtr).*m_memPtr)(m_a1, m_a2, m_a3); - } - - MEM_PTR m_memPtr; - OBJ_PTR m_objPtr; - T1Stored m_a1; - T2Stored m_a2; - T3Stored m_a3; - }* function = new MemFnTimerImplThree(memPtr, objPtr); - - return function; -} - -/** - * Make a TimerImpl from a function pointer taking four arguments. - * \copydetails MakeTimerImpl(MEM_PTR,OBJ_PTR) - */ -template -TimerImpl* -MakeTimerImpl(IntToType<4>, MEM_PTR memPtr, OBJ_PTR objPtr) -{ - typedef typename TypeTraits::PointerToMemberTraits::Arg1Type T1; - typedef typename TimerTraits::ParameterType T1Parameter; - typedef typename TimerTraits::StoredType T1Stored; - typedef typename TypeTraits::PointerToMemberTraits::Arg2Type T2; - typedef typename TimerTraits::ParameterType T2Parameter; - typedef typename TimerTraits::StoredType T2Stored; - typedef typename TypeTraits::PointerToMemberTraits::Arg3Type T3; - typedef typename TimerTraits::ParameterType T3Parameter; - typedef typename TimerTraits::StoredType T3Stored; - typedef typename TypeTraits::PointerToMemberTraits::Arg4Type T4; - typedef typename TimerTraits::ParameterType T4Parameter; - typedef typename TimerTraits::StoredType T4Stored; - - struct MemFnTimerImplFour - : public TimerImplFour - { - MemFnTimerImplFour(MEM_PTR memPtr, OBJ_PTR objPtr) - : m_memPtr(memPtr), - m_objPtr(objPtr) - { - } - - void SetArguments(T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4) override - { - m_a1 = a1; - m_a2 = a2; - m_a3 = a3; - m_a4 = a4; - } - - EventId Schedule(const Time& delay) override - { - return Simulator::Schedule(delay, m_memPtr, m_objPtr, m_a1, m_a2, m_a3, m_a4); - } - - void Invoke() override - { - (TimerImplMemberTraits::GetReference(m_objPtr).* - m_memPtr)(m_a1, m_a2, m_a3, m_a4); - } - - MEM_PTR m_memPtr; - OBJ_PTR m_objPtr; - T1Stored m_a1; - T2Stored m_a2; - T3Stored m_a3; - T4Stored m_a4; - }* function = new MemFnTimerImplFour(memPtr, objPtr); - - return function; -} - -/** - * Make a TimerImpl from a function pointer taking five arguments. - * \copydetails MakeTimerImpl(MEM_PTR,OBJ_PTR) - */ -template -TimerImpl* -MakeTimerImpl(IntToType<5>, MEM_PTR memPtr, OBJ_PTR objPtr) -{ - typedef typename TypeTraits::PointerToMemberTraits::Arg1Type T1; - typedef typename TimerTraits::ParameterType T1Parameter; - typedef typename TimerTraits::StoredType T1Stored; - typedef typename TypeTraits::PointerToMemberTraits::Arg2Type T2; - typedef typename TimerTraits::ParameterType T2Parameter; - typedef typename TimerTraits::StoredType T2Stored; - typedef typename TypeTraits::PointerToMemberTraits::Arg3Type T3; - typedef typename TimerTraits::ParameterType T3Parameter; - typedef typename TimerTraits::StoredType T3Stored; - typedef typename TypeTraits::PointerToMemberTraits::Arg4Type T4; - typedef typename TimerTraits::ParameterType T4Parameter; - typedef typename TimerTraits::StoredType T4Stored; - typedef typename TypeTraits::PointerToMemberTraits::Arg5Type T5; - typedef typename TimerTraits::ParameterType T5Parameter; - typedef typename TimerTraits::StoredType T5Stored; - - struct MemFnTimerImplFive - : public TimerImplFive - { - MemFnTimerImplFive(MEM_PTR memPtr, OBJ_PTR objPtr) - : m_memPtr(memPtr), - m_objPtr(objPtr) - { - } - - void SetArguments(T1Parameter a1, - T2Parameter a2, - T3Parameter a3, - T4Parameter a4, - T5Parameter a5) override - { - m_a1 = a1; - m_a2 = a2; - m_a3 = a3; - m_a4 = a4; - m_a5 = a5; - } - - EventId Schedule(const Time& delay) override - { - return Simulator::Schedule(delay, m_memPtr, m_objPtr, m_a1, m_a2, m_a3, m_a4, m_a5); - } - - void Invoke() override - { - (TimerImplMemberTraits::GetReference(m_objPtr).* - m_memPtr)(m_a1, m_a2, m_a3, m_a4, m_a5); - } - - MEM_PTR m_memPtr; - OBJ_PTR m_objPtr; - T1Stored m_a1; - T2Stored m_a2; - T3Stored m_a3; - T4Stored m_a4; - T5Stored m_a5; - }* function = new MemFnTimerImplFive(memPtr, objPtr); - - return function; -} - -/** - * Make a TimerImpl from a function pointer taking six arguments. - * \copydetails MakeTimerImpl(MEM_PTR,OBJ_PTR) - */ -template -TimerImpl* -MakeTimerImpl(IntToType<6>, MEM_PTR memPtr, OBJ_PTR objPtr) -{ - typedef typename TypeTraits::PointerToMemberTraits::Arg1Type T1; - typedef typename TimerTraits::ParameterType T1Parameter; - typedef typename TimerTraits::StoredType T1Stored; - typedef typename TypeTraits::PointerToMemberTraits::Arg2Type T2; - typedef typename TimerTraits::ParameterType T2Parameter; - typedef typename TimerTraits::StoredType T2Stored; - typedef typename TypeTraits::PointerToMemberTraits::Arg3Type T3; - typedef typename TimerTraits::ParameterType T3Parameter; - typedef typename TimerTraits::StoredType T3Stored; - typedef typename TypeTraits::PointerToMemberTraits::Arg4Type T4; - typedef typename TimerTraits::ParameterType T4Parameter; - typedef typename TimerTraits::StoredType T4Stored; - typedef typename TypeTraits::PointerToMemberTraits::Arg5Type T5; - typedef typename TimerTraits::ParameterType T5Parameter; - typedef typename TimerTraits::StoredType T5Stored; - typedef typename TypeTraits::PointerToMemberTraits::Arg6Type T6; - typedef typename TimerTraits::ParameterType T6Parameter; - typedef typename TimerTraits::StoredType T6Stored; - - struct MemFnTimerImplSix : public TimerImplSix - { - MemFnTimerImplSix(MEM_PTR memPtr, OBJ_PTR objPtr) - : m_memPtr(memPtr), - m_objPtr(objPtr) - { - } - - virtual void SetArguments(T1Parameter a1, - T2Parameter a2, - T3Parameter a3, - T4Parameter a4, - T5Parameter a5, - T6Parameter a6) - { - m_a1 = a1; - m_a2 = a2; - m_a3 = a3; - m_a4 = a4; - m_a5 = a5; - m_a6 = a6; - } - - virtual EventId Schedule(const Time& delay) - { - return Simulator::Schedule(delay, - m_memPtr, - m_objPtr, - m_a1, - m_a2, - m_a3, - m_a4, - m_a5, - m_a6); - } - - virtual void Invoke() - { - (TimerImplMemberTraits::GetReference(m_objPtr).* - m_memPtr)(m_a1, m_a2, m_a3, m_a4, m_a5, m_a6); - } - - MEM_PTR m_memPtr; - OBJ_PTR m_objPtr; - T1Stored m_a1; - T2Stored m_a2; - T3Stored m_a3; - T4Stored m_a4; - T5Stored m_a5; - T6Stored m_a6; - }* function = new MemFnTimerImplSix(memPtr, objPtr); + std::tuple...> m_arguments; + }* function = new MemFnTimerImpl(memPtr, objPtr); return function; } @@ -1080,108 +196,18 @@ MakeTimerImpl(IntToType<6>, MEM_PTR memPtr, OBJ_PTR objPtr) * Implementation of TimerImpl itself. ********************************************************************/ -template +template void -TimerImpl::SetArgs(T1 a1) +TimerImpl::SetArgs(Args... args) { - typedef TimerImplOne::ParameterType> TimerImplBase; + using TimerImplBase = TimerImplX&...>; auto impl = dynamic_cast(this); if (impl == nullptr) { NS_FATAL_ERROR("You tried to set Timer arguments incompatible with its function."); return; } - impl->SetArguments(a1); -} - -template -void -TimerImpl::SetArgs(T1 a1, T2 a2) -{ - typedef TimerImplTwo::ParameterType, - typename TimerTraits::ParameterType> - TimerImplBase; - auto impl = dynamic_cast(this); - if (impl == nullptr) - { - NS_FATAL_ERROR("You tried to set Timer arguments incompatible with its function."); - return; - } - impl->SetArguments(a1, a2); -} - -template -void -TimerImpl::SetArgs(T1 a1, T2 a2, T3 a3) -{ - typedef TimerImplThree::ParameterType, - typename TimerTraits::ParameterType, - typename TimerTraits::ParameterType> - TimerImplBase; - auto impl = dynamic_cast(this); - if (impl == nullptr) - { - NS_FATAL_ERROR("You tried to set Timer arguments incompatible with its function."); - return; - } - impl->SetArguments(a1, a2, a3); -} - -template -void -TimerImpl::SetArgs(T1 a1, T2 a2, T3 a3, T4 a4) -{ - typedef TimerImplFour::ParameterType, - typename TimerTraits::ParameterType, - typename TimerTraits::ParameterType, - typename TimerTraits::ParameterType> - TimerImplBase; - auto impl = dynamic_cast(this); - if (impl == nullptr) - { - NS_FATAL_ERROR("You tried to set Timer arguments incompatible with its function."); - return; - } - impl->SetArguments(a1, a2, a3, a4); -} - -template -void -TimerImpl::SetArgs(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) -{ - typedef TimerImplFive::ParameterType, - typename TimerTraits::ParameterType, - typename TimerTraits::ParameterType, - typename TimerTraits::ParameterType, - typename TimerTraits::ParameterType> - TimerImplBase; - auto impl = dynamic_cast(this); - if (impl == nullptr) - { - NS_FATAL_ERROR("You tried to set Timer arguments incompatible with its function."); - return; - } - impl->SetArguments(a1, a2, a3, a4, a5); -} - -template -void -TimerImpl::SetArgs(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6) -{ - typedef TimerImplSix::ParameterType, - typename TimerTraits::ParameterType, - typename TimerTraits::ParameterType, - typename TimerTraits::ParameterType, - typename TimerTraits::ParameterType, - typename TimerTraits::ParameterType> - TimerImplBase; - auto impl = dynamic_cast(this); - if (impl == 0) - { - NS_FATAL_ERROR("You tried to set Timer arguments incompatible with its function."); - return; - } - impl->SetArguments(a1, a2, a3, a4, a5, a6); + impl->SetArguments(args...); } } // namespace ns3