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 FnTimerImpl(void (*fn)(Ts...))
108 : m_fn(fn)
109 {
110 }
111
112 void SetArguments(const std::remove_cvref_t<Ts>&... args) override
113 {
114 m_arguments = std::tuple(args...);
115 }
116
117 EventId Schedule(const Time& delay) override
118 {
119 return std::apply(
120 [&, this](Ts... args) { return Simulator::Schedule(delay, m_fn, args...); },
121 m_arguments);
122 }
123
124 void Invoke() override
125 {
126 std::apply([this](Ts... args) { (m_fn)(args...); }, m_arguments);
127 }
128
129 decltype(fn) m_fn;
130 std::tuple<std::remove_cvref_t<Ts>...> m_arguments;
131 }* function = new FnTimerImpl(fn);
132
133 return function;
134}
135
136/**
137 * Make a TimerImpl from a class method pointer taking
138 * a varying number of arguments.
139 *
140 * \tparam OBJ_PTR \deduced Class type.
141 * \tparam U \deduced Class method function return type.
142 * \tparam V \deduced Class method function class type.
143 * \tparam Ts \deduced Class method function argument types.
144 * \param [in] memPtr Class method to invoke when the timer expires.
145 * \param [in] objPtr Object instance pointer.
146 * \returns The TimerImpl.
147 */
148template <typename OBJ_PTR, typename U, typename V, typename... Ts>
149TimerImpl*
150MakeTimerImpl(U (V::*memPtr)(Ts...), OBJ_PTR objPtr)
151{
152 struct MemFnTimerImpl : public TimerImplX<const std::remove_cvref_t<Ts>&...>
153 {
154 MemFnTimerImpl(decltype(memPtr) memPtr, OBJ_PTR objPtr)
155 : m_memPtr(std::bind_front(memPtr, objPtr))
156 {
157 }
158
159 void SetArguments(const std::remove_cvref_t<Ts>&... args) override
160 {
161 m_arguments = std::tuple(args...);
162 }
163
164 EventId Schedule(const Time& delay) override
165 {
166 return std::apply(
167 [&, this](Ts... args) {
168 return Simulator::Schedule(delay, std::bind(m_memPtr, args...));
169 },
170 m_arguments);
171 }
172
173 void Invoke() override
174 {
175 std::apply(m_memPtr, m_arguments);
176 }
177
178 std::function<U(Ts...)> m_memPtr;
179 std::tuple<std::remove_cvref_t<Ts>...> m_arguments;
180 }* function = new MemFnTimerImpl(memPtr, objPtr);
181
182 return function;
183}
184
185/**@}*/ // \ingroup timer
186
187/********************************************************************
188 * Implementation of TimerImpl itself.
189 ********************************************************************/
190
191template <typename... Args>
192void
194{
195 using TimerImplBase = TimerImplX<const std::remove_cvref_t<Args>&...>;
196 auto impl = dynamic_cast<TimerImplBase*>(this);
197 if (impl == nullptr)
198 {
199 NS_FATAL_ERROR("You tried to set Timer arguments incompatible with its function.");
200 return;
201 }
202 impl->SetArguments(args...);
203}
204
205} // namespace internal
206
207} // namespace ns3
208
209#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:193
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.