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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8
9#ifndef TIMER_IMPL_H
10#define TIMER_IMPL_H
11
12#include "fatal-error.h"
13#include "simulator.h"
14
15#include <type_traits>
16
17/**
18 * \file
19 * \ingroup timer
20 * \ingroup timerimpl
21 * ns3::TimerImpl declaration and implementation.
22 */
23
24namespace ns3
25{
26
27namespace internal
28{
29
30/**
31 * \ingroup timer
32 * The timer implementation underlying Timer and Watchdog.
33 */
35{
36 public:
37 /** Destructor. */
38 virtual ~TimerImpl()
39 {
40 }
41
42 /**
43 * Set the arguments to be used when invoking the expire function.
44 *
45 * \tparam Args \deduced Type template parameter pack
46 * \param [in] args The arguments to pass to the invoked method
47 */
48 template <typename... Args>
49 void SetArgs(Args... args);
50
51 /**
52 * Schedule the callback for a future time.
53 *
54 * \param [in] delay The amount of time until the timer expires.
55 * \returns The scheduled EventId.
56 */
57 virtual EventId Schedule(const Time& delay) = 0;
58 /** Invoke the expire function. */
59 virtual void Invoke() = 0;
60};
61
62/********************************************************************
63 * Implementation of TimerImpl implementation functions.
64 ********************************************************************/
65
66/**
67 * \ingroup timer
68 * \defgroup timerimpl TimerImpl Implementation
69 * @{
70 */
71/** TimerImpl specialization class for varying numbers of arguments. */
72template <typename... Args>
73struct TimerImplX : public TimerImpl
74{
75 /**
76 * Bind the arguments to be used when the callback function is invoked.
77 *
78 * \param [in] args The arguments to pass to the invoked method.
79 */
80 virtual void SetArguments(Args... args) = 0;
81};
82
83/**
84 * Make a TimerImpl from a function pointer taking varying numbers of arguments.
85 *
86 * \tparam U \deduced Return type of the callback function.
87 * \tparam Ts \deduced Argument types of the callback function.
88 * \returns The TimerImpl.
89 */
90template <typename U, typename... Ts>
92MakeTimerImpl(U(fn)(Ts...))
93{
94 struct FnTimerImpl : public TimerImplX<const std::remove_cvref_t<Ts>&...>
95 {
96 FnTimerImpl(void (*fn)(Ts...))
97 : m_fn(fn)
98 {
99 }
100
101 void SetArguments(const std::remove_cvref_t<Ts>&... args) override
102 {
103 m_arguments = std::tuple(args...);
104 }
105
106 EventId Schedule(const Time& delay) override
107 {
108 return std::apply(
109 [&, this](Ts... args) { return Simulator::Schedule(delay, m_fn, args...); },
110 m_arguments);
111 }
112
113 void Invoke() override
114 {
115 std::apply([this](Ts... args) { (m_fn)(args...); }, m_arguments);
116 }
117
118 decltype(fn) m_fn;
119 std::tuple<std::remove_cvref_t<Ts>...> m_arguments;
120 }* function = new FnTimerImpl(fn);
121
122 return function;
123}
124
125/**
126 * Make a TimerImpl from a class method pointer taking
127 * a varying number of arguments.
128 *
129 * \tparam OBJ_PTR \deduced Class type.
130 * \tparam U \deduced Class method function return type.
131 * \tparam V \deduced Class method function class type.
132 * \tparam Ts \deduced Class method function argument types.
133 * \param [in] memPtr Class method to invoke when the timer expires.
134 * \param [in] objPtr Object instance pointer.
135 * \returns The TimerImpl.
136 */
137template <typename OBJ_PTR, typename U, typename V, typename... Ts>
138TimerImpl*
139MakeTimerImpl(U (V::*memPtr)(Ts...), OBJ_PTR objPtr)
140{
141 struct MemFnTimerImpl : public TimerImplX<const std::remove_cvref_t<Ts>&...>
142 {
143 MemFnTimerImpl(decltype(memPtr) memPtr, OBJ_PTR objPtr)
144 : m_memPtr(std::bind_front(memPtr, objPtr))
145 {
146 }
147
148 void SetArguments(const std::remove_cvref_t<Ts>&... args) override
149 {
150 m_arguments = std::tuple(args...);
151 }
152
153 EventId Schedule(const Time& delay) override
154 {
155 return std::apply(
156 [&, this](Ts... args) {
157 return Simulator::Schedule(delay, std::bind(m_memPtr, args...));
158 },
159 m_arguments);
160 }
161
162 void Invoke() override
163 {
164 std::apply(m_memPtr, m_arguments);
165 }
166
167 std::function<U(Ts...)> m_memPtr;
168 std::tuple<std::remove_cvref_t<Ts>...> m_arguments;
169 }* function = new MemFnTimerImpl(memPtr, objPtr);
170
171 return function;
172}
173
174/**@}*/ // \ingroup timer
175
176/********************************************************************
177 * Implementation of TimerImpl itself.
178 ********************************************************************/
179
180template <typename... Args>
181void
183{
184 using TimerImplBase = TimerImplX<const std::remove_cvref_t<Args>&...>;
185 auto impl = dynamic_cast<TimerImplBase*>(this);
186 if (impl == nullptr)
187 {
188 NS_FATAL_ERROR("You tried to set Timer arguments incompatible with its function.");
189 return;
190 }
191 impl->SetArguments(args...);
192}
193
194} // namespace internal
195
196} // namespace ns3
197
198#endif /* TIMER_IMPL_H */
An identifier for simulation events.
Definition event-id.h:45
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
The timer implementation underlying Timer and Watchdog.
Definition timer-impl.h:35
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:182
virtual ~TimerImpl()
Destructor.
Definition timer-impl.h:38
NS_FATAL_x macro definitions.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
TimerImpl * MakeTimerImpl(U(fn)(Ts...))
Make a TimerImpl from a function pointer taking varying numbers of arguments.
Definition timer-impl.h:92
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:74
virtual void SetArguments(Args... args)=0
Bind the arguments to be used when the callback function is invoked.