A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
timer-impl.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007 INRIA
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18 */
19
20#ifndef TIMER_IMPL_H
21#define TIMER_IMPL_H
22
23#include "fatal-error.h"
24#include "simulator.h"
25
26#include <type_traits>
27
28/**
29 * \file
30 * \ingroup timer
31 * \ingroup timerimpl
32 * ns3::TimerImpl declaration and implementation.
33 */
34
35namespace ns3
36{
37
38namespace internal
39{
40
41/**
42 * \ingroup timer
43 * The timer implementation underlying Timer and Watchdog.
44 */
46{
47 public:
48 /** Destructor. */
49 virtual ~TimerImpl()
50 {
51 }
52
53 /**
54 * Set the arguments to be used when invoking the expire function.
55 *
56 * \tparam Args \deduced Type template parameter pack
57 * \param [in] args The arguments to pass to the invoked method
58 */
59 template <typename... Args>
60 void SetArgs(Args... args);
61
62 /**
63 * Schedule the callback for a future time.
64 *
65 * \param [in] delay The amount of time until the timer expires.
66 * \returns The scheduled EventId.
67 */
68 virtual EventId Schedule(const Time& delay) = 0;
69 /** Invoke the expire function. */
70 virtual void Invoke() = 0;
71};
72
73/********************************************************************
74 * Implementation of TimerImpl implementation functions.
75 ********************************************************************/
76
77/**
78 * \ingroup timer
79 * \defgroup timerimpl TimerImpl Implementation
80 * @{
81 */
82/** TimerImpl specialization class for varying numbers of arguments. */
83template <typename... Args>
84struct TimerImplX : public TimerImpl
85{
86 /**
87 * Bind the arguments to be used when the callback function is invoked.
88 *
89 * \param [in] args The arguments to pass to the invoked method.
90 */
91 virtual void SetArguments(Args... args) = 0;
92};
93
94/**
95 * Make a TimerImpl from a function pointer taking varying numbers of arguments.
96 *
97 * \tparam U \deduced Return type of the callback function.
98 * \tparam Ts \deduced Argument types of the callback function.
99 * \returns The TimerImpl.
100 */
101template <typename U, typename... Ts>
103MakeTimerImpl(U(fn)(Ts...))
104{
105 struct FnTimerImpl : public TimerImplX<const std::remove_cvref_t<Ts>&...>
106 {
107 using FN = U (*)(Ts...);
108
109 FnTimerImpl(void (*fn)(Ts...))
110 : m_fn(fn)
111 {
112 }
113
114 void SetArguments(const std::remove_cvref_t<Ts>&... args) override
115 {
116 m_arguments = std::tuple(args...);
117 }
118
119 EventId Schedule(const Time& delay) override
120 {
121 return std::apply(
122 [&, this](Ts... args) { return Simulator::Schedule(delay, m_fn, args...); },
123 m_arguments);
124 }
125
126 void Invoke() override
127 {
128 std::apply([this](Ts... args) { (m_fn)(args...); }, m_arguments);
129 }
130
131 FN m_fn;
132 std::tuple<std::remove_cvref_t<Ts>...> m_arguments;
133 }* function = new FnTimerImpl(fn);
134
135 return function;
136}
137
138/**
139 * Make a TimerImpl from a class method pointer taking
140 * a varying number of arguments.
141 *
142 * \tparam OBJ_PTR \deduced Class type.
143 * \tparam U \deduced Class method function return type.
144 * \tparam V \deduced Class method function class type.
145 * \tparam Ts \deduced Class method function argument types.
146 * \param [in] memPtr Class method to invoke when the timer expires.
147 * \param [in] objPtr Object instance pointer.
148 * \returns The TimerImpl.
149 */
150template <typename OBJ_PTR, typename U, typename V, typename... Ts>
151TimerImpl*
152MakeTimerImpl(U (V::*memPtr)(Ts...), OBJ_PTR objPtr)
153{
154 struct MemFnTimerImpl : public TimerImplX<const std::remove_cvref_t<Ts>&...>
155 {
156 using MEM_PTR = U (V::*)(Ts...);
157
158 MemFnTimerImpl(MEM_PTR memPtr, OBJ_PTR objPtr)
159 : m_memPtr(memPtr),
160 m_objPtr(objPtr)
161 {
162 }
163
164 void SetArguments(const std::remove_cvref_t<Ts>&... args) override
165 {
166 m_arguments = std::tuple(args...);
167 }
168
169 EventId Schedule(const Time& delay) override
170 {
171 return std::apply(
172 [&, this](Ts... args) {
173 return Simulator::Schedule(delay, m_memPtr, m_objPtr, args...);
174 },
175 m_arguments);
176 }
177
178 void Invoke() override
179 {
180 std::apply([this](Ts... args) { ((*m_objPtr).*m_memPtr)(args...); }, m_arguments);
181 }
182
183 MEM_PTR m_memPtr;
184 OBJ_PTR m_objPtr;
185 std::tuple<std::remove_cvref_t<Ts>...> m_arguments;
186 }* function = new MemFnTimerImpl(memPtr, objPtr);
187
188 return function;
189}
190
191/**@}*/ // \ingroup timer
192
193/********************************************************************
194 * Implementation of TimerImpl itself.
195 ********************************************************************/
196
197template <typename... Args>
198void
200{
201 using TimerImplBase = TimerImplX<const std::remove_cvref_t<Args>&...>;
202 auto impl = dynamic_cast<TimerImplBase*>(this);
203 if (impl == nullptr)
204 {
205 NS_FATAL_ERROR("You tried to set Timer arguments incompatible with its function.");
206 return;
207 }
208 impl->SetArguments(args...);
209}
210
211} // namespace internal
212
213} // namespace ns3
214
215#endif /* TIMER_IMPL_H */
An identifier for simulation events.
Definition: event-id.h:55
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
The timer implementation underlying Timer and Watchdog.
Definition: timer-impl.h:46
virtual void Invoke()=0
Invoke the expire function.
virtual EventId Schedule(const Time &delay)=0
Schedule the callback for a future time.
void SetArgs(Args... args)
Set the arguments to be used when invoking the expire function.
Definition: timer-impl.h:199
virtual ~TimerImpl()
Destructor.
Definition: timer-impl.h:49
NS_FATAL_x macro definitions.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
TimerImpl * MakeTimerImpl(U(fn)(Ts...))
Make a TimerImpl from a function pointer taking varying numbers of arguments.
Definition: timer-impl.h:103
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::Simulator declaration.
TimerImpl specialization class for varying numbers of arguments.
Definition: timer-impl.h:85
virtual void SetArguments(Args... args)=0
Bind the arguments to be used when the callback function is invoked.