A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
traced-value.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005,2006,2007 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8#ifndef TRACED_VALUE_H
9#define TRACED_VALUE_H
10
11#include "boolean.h"
12#include "double.h"
13#include "enum.h"
14#include "integer.h"
15#include "traced-callback.h"
16#include "uinteger.h"
17
18/**
19 * @file
20 * @ingroup tracing
21 * ns3::TracedValue declaration and template implementation.
22 */
23
24/**
25 * Logging macro for TracedValue.
26 *
27 * No NS_LOG_... here. When logging is needed use something like
28 * @code
29 * #define TRACED_VALUE_DEBUG(x) \
30 * std::cout << __FILE__ << ":" << __FUNCTION__ \
31 * << "(" << __LINE__ << ") " \
32 * << x << std::endl
33 * @endcode
34 */
35#define TRACED_VALUE_DEBUG(x)
36
37namespace ns3
38{
39
40/**
41 * @ingroup core
42 * @defgroup tracing Tracing
43 * @brief Publish/subscribe tools to collect and report changes to any
44 * values used by the various model components.
45 *
46 * Additional callback function signatures defined elsewhere:
47 * - TracedValueCallback::Time
48 * - TracedValueCallback::SequenceNumber32
49 * - TracedValueCallback::LrWpanMacState
50 * - TracedValueCallback::LrWpanPhyEnumeration
51 */
52
53/**
54 * @ingroup tracing
55 *
56 * @brief TracedValue Callback function types.
57 */
58namespace TracedValueCallback
59{
60
61/**
62 * @name TracedValueCallback Signatures for POD.
63 * @{
64 */
65/**
66 * TracedValue Callback signature for POD.
67 * @{
68 * @param [in] oldValue original value of the traced variable
69 * @param [in] newValue new value of the traced variable
70 */
71typedef void (*Bool)(bool oldValue, bool newValue);
72typedef void (*Int8)(int8_t oldValue, int8_t newValue);
73typedef void (*Uint8)(uint8_t oldValue, uint8_t newValue);
74typedef void (*Int16)(int16_t oldValue, int16_t newValue);
75typedef void (*Uint16)(uint16_t oldValue, uint16_t newValue);
76typedef void (*Int32)(int32_t oldValue, int32_t newValue);
77typedef void (*Uint32)(uint32_t oldValue, uint32_t newValue);
78typedef void (*Int64)(int64_t oldValue, int64_t newValue);
79typedef void (*Uint64)(uint64_t oldValue, uint64_t newValue);
80typedef void (*Double)(double oldValue, double newValue);
81/**@}*/
82/** TracedValue Callback signature for void. */
83typedef void (*Void)();
84/**@}*/
85
86} // namespace TracedValueCallback
87
88/**
89 * @ingroup tracing
90 *
91 * @brief Trace classes with value semantics
92 *
93 * If you want to trace the change of value of a class or
94 * primitive type which have value semantics (they _must_
95 * support operator !=), you can wrap them in an instance of
96 * this template. This instance will behave just like
97 * the original class (if it did not export any special method),
98 * and will define Connect/DisconnectWithoutContext methods to work
99 * with MakeTraceSourceAccessor.
100 *
101 * @tparam T \explicit The type of the underlying value being traced.
102 */
103template <typename T>
105{
106 public:
107 /** Default constructor. */
109 : m_v()
110 {
111 }
112
113 /**
114 * Copy constructor.
115 * @param [in] o The value to copy.
116 */
118 : m_v(o.m_v)
119 {
120 }
121
122 /**
123 * Construct from an explicit variable.
124 * @param [in] v The variable to trace.
125 */
126 TracedValue(const T& v)
127 : m_v(v)
128 {
129 }
130
131 /**
132 * Cast to the underlying type.
133 * @returns The underlying value.
134 */
135 operator T() const
136 {
137 return m_v;
138 }
139
140 /**
141 * Assignment.
142 * @param [in] o The value to assign to this instance.
143 * @return This TracedValue.
144 */
146 {
147 TRACED_VALUE_DEBUG("x=");
148 Set(o.m_v);
149 return *this;
150 }
151
152 /**
153 * Copy from a TracedValue of a compatible type.
154 * @tparam U \deduced The underlying type of the other TracedValue.
155 * @param [in] other The other TracedValuet to copy.
156 */
157 template <typename U>
159 : m_v(other.Get())
160 {
161 }
162
163 /**
164 * Copy from a variable type compatible with this underlying type.
165 * @tparam U \deduced Type of the other variable.
166 * @param [in] other The other variable to copy.
167 */
168 template <typename U>
169 TracedValue(const U& other)
170 : m_v((T)other)
171 {
172 }
173
174 /**
175 * Connect a Callback (without context.)
176 *
177 * @param [in] cb The callback to connect.
178 */
180 {
182 }
183
184 /**
185 * Connect a Callback with a context string.
186 *
187 * The context string will be provided as the first argument to the
188 * Callback function.
189 *
190 * @param [in] cb The Callback to connect to the target trace source.
191 * @param [in] path The context to bind to the user callback.
192 */
193 void Connect(const CallbackBase& cb, std::string path)
194 {
195 m_cb.Connect(cb, path);
196 }
197
198 /**
199 * Disconnect a Callback which was connected without context.
200 *
201 * @param [in] cb The Callback to disconnect.
202 */
207
208 /**
209 * Disconnect a Callback which was connected with context.
210 *
211 * @param [in] cb The Callback to disconnect.
212 * @param [in] path The context to bind to the user callback.
213 */
214 void Disconnect(const CallbackBase& cb, std::string path)
215 {
216 m_cb.Disconnect(cb, path);
217 }
218
219 /**
220 * Set the value of the underlying variable.
221 *
222 * If the new value differs from the old, the Callback will be invoked.
223 * @param [in] v The new value.
224 */
225 void Set(const T& v)
226 {
227 if (m_v != v)
228 {
229 m_cb(m_v, v);
230 m_v = v;
231 }
232 }
233
234 /**
235 * Get the underlying value.
236 * @returns The value.
237 */
238 T Get() const
239 {
240 return m_v;
241 }
242
243 /**
244 * Pre/post- increment/decrement operator.
245 *
246 * This invokes the Callback.
247 * @returns This TracedValue.
248 */
249 /**@{*/
251 {
252 TRACED_VALUE_DEBUG("++x");
253 T tmp = Get();
254 ++tmp;
255 Set(tmp);
256 return *this;
257 }
258
260 {
261 TRACED_VALUE_DEBUG("--x");
262 T tmp = Get();
263 --tmp;
264 Set(tmp);
265 return *this;
266 }
267
269 {
270 TRACED_VALUE_DEBUG("x++");
271 TracedValue old(*this);
272 T tmp = Get();
273 tmp++;
274 Set(tmp);
275 return old;
276 }
277
279 {
280 TRACED_VALUE_DEBUG("x--");
281 TracedValue old(*this);
282 T tmp = Get();
283 tmp--;
284 Set(tmp);
285 return old;
286 }
287
288 /**@}*/
289
290 private:
291 /** The underlying value. */
293 /** The connected Callback. */
295};
296
297/********************************************************************
298 Operator implementations for TracedValue
299 ********************************************************************/
300
301/**
302 * @ingroup tracing
303 */
304/**@{*/
305/**
306 * Output streamer for TracedValue.
307 *
308 * The underlying value will be written to the stream.
309 *
310 * @tparam T \deduced The underlying type of the TracedValue.
311 * @param [in,out] os The output stream.
312 * @param [in] rhs The TracedValue to stream.
313 * @returns The stream.
314 */
315template <typename T>
316std::ostream&
317operator<<(std::ostream& os, const TracedValue<T>& rhs)
318{
319 return os << rhs.Get();
320}
321
322/**
323 * Boolean operator for TracedValue.
324 * @tparam T \deduced The underlying type held by the left-hand argument.
325 * @tparam U \deduced The underlying type held by the right-hand argument.
326 * @param [in] lhs The left-hand argument.
327 * @param [in] rhs The right-hand argument.
328 * @returns The Boolean result of comparing the underlying values.
329 */
330template <typename T, typename U>
331bool
333{
334 TRACED_VALUE_DEBUG("x==x");
335 return lhs.Get() == rhs.Get();
336}
337
338/** @copydoc operator==(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
339template <typename T, typename U>
340bool
341operator==(const TracedValue<T>& lhs, const U& rhs)
342{
343 TRACED_VALUE_DEBUG("x==");
344 return lhs.Get() == rhs;
345}
346
347/** @copydoc operator==(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
348template <typename T, typename U>
349bool
350operator==(const U& lhs, const TracedValue<T>& rhs)
351{
352 TRACED_VALUE_DEBUG("==x");
353 return lhs == rhs.Get();
354}
355
356/** @copydoc operator==(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
357template <typename T, typename U>
358bool
360{
361 TRACED_VALUE_DEBUG("x!=x");
362 return lhs.Get() != rhs.Get();
363}
364
365/** @copydoc operator==(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
366template <typename T, typename U>
367bool
368operator!=(const TracedValue<T>& lhs, const U& rhs)
369{
370 TRACED_VALUE_DEBUG("x!=");
371 return lhs.Get() != rhs;
372}
373
374/** @copydoc operator==(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
375template <typename T, typename U>
376bool
377operator!=(const U& lhs, const TracedValue<T>& rhs)
378{
379 TRACED_VALUE_DEBUG("!=x");
380 return lhs != rhs.Get();
381}
382
383/** @copydoc operator==(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
384template <typename T, typename U>
385bool
386operator<=(const TracedValue<T>& lhs, const TracedValue<U>& rhs)
387{
388 TRACED_VALUE_DEBUG("x<=x");
389 return lhs.Get() <= rhs.Get();
390}
391
392/** @copydoc operator==(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
393template <typename T, typename U>
394bool
395operator<=(const TracedValue<T>& lhs, const U& rhs)
396{
397 TRACED_VALUE_DEBUG("x<=");
398 return lhs.Get() <= rhs;
399}
400
401/** @copydoc operator==(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
402template <typename T, typename U>
403bool
404operator<=(const U& lhs, const TracedValue<T>& rhs)
405{
406 TRACED_VALUE_DEBUG("<=x");
407 return lhs <= rhs.Get();
408}
409
410/** @copydoc operator==(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
411template <typename T, typename U>
412bool
414{
415 TRACED_VALUE_DEBUG("x>=x");
416 return lhs.Get() >= rhs.Get();
417}
418
419/** @copydoc operator==(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
420template <typename T, typename U>
421bool
422operator>=(const TracedValue<T>& lhs, const U& rhs)
423{
424 TRACED_VALUE_DEBUG("x>=");
425 return lhs.Get() >= rhs;
426}
427
428/** @copydoc operator==(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
429template <typename T, typename U>
430bool
431operator>=(const U& lhs, const TracedValue<T>& rhs)
432{
433 TRACED_VALUE_DEBUG(">=x");
434 return lhs >= rhs.Get();
435}
436
437/** @copydoc operator==(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
438template <typename T, typename U>
439bool
440operator<(const TracedValue<T>& lhs, const TracedValue<U>& rhs)
441{
442 TRACED_VALUE_DEBUG("x<x");
443 return lhs.Get() < rhs.Get();
444}
445
446/** @copydoc operator==(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
447template <typename T, typename U>
448bool
449operator<(const TracedValue<T>& lhs, const U& rhs)
450{
451 TRACED_VALUE_DEBUG("x<");
452 return lhs.Get() < rhs;
453}
454
455/** @copydoc operator==(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
456template <typename T, typename U>
457bool
458operator<(const U& lhs, const TracedValue<T>& rhs)
459{
460 TRACED_VALUE_DEBUG("<x");
461 return lhs < rhs.Get();
462}
463
464/** @copydoc operator==(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
465template <typename T, typename U>
466bool
468{
469 TRACED_VALUE_DEBUG("x>x");
470 return lhs.Get() > rhs.Get();
471}
472
473/** @copydoc operator==(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
474template <typename T, typename U>
475bool
476operator>(const TracedValue<T>& lhs, const U& rhs)
477{
478 TRACED_VALUE_DEBUG("x>");
479 return lhs.Get() > rhs;
480}
481
482/** @copydoc operator==(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
483template <typename T, typename U>
484bool
485operator>(const U& lhs, const TracedValue<T>& rhs)
486{
487 TRACED_VALUE_DEBUG(">x");
488 return lhs > rhs.Get();
489}
490
491/**
492 * Infix arithmetic operator for TracedValue.
493 *
494 * This returns the arithmetic result in a new TracedValue,
495 * which has no Callback connected.
496 *
497 * @tparam T \deduced The underlying type held by the left-hand argument.
498 * @tparam U \deduced The underlying type held by the right-hand argument.
499 * @param [in] lhs The left-hand argument.
500 * @param [in] rhs The right-hand argument.
501 * @returns The result of doing the operator on
502 * the underlying values.
503 */
504// clang-format off
505// Clang-format guard needed for version 18 only
506template <typename T, typename U>
507auto
509 -> TracedValue<decltype(lhs.Get() + rhs.Get())>
510// clang-format on
511{
512 TRACED_VALUE_DEBUG("x+x");
513 return TracedValue<decltype(lhs.Get() + rhs.Get())>(lhs.Get() + rhs.Get());
514}
515
516/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
517template <typename T, typename U>
518auto
519operator+(const TracedValue<T>& lhs, const U& rhs) -> TracedValue<decltype(lhs.Get() + rhs)>
520{
521 TRACED_VALUE_DEBUG("x+");
522 return TracedValue<decltype(lhs.Get() + rhs)>(lhs.Get() + rhs);
523}
524
525/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
526template <typename T, typename U>
527auto
528operator+(const U& lhs, const TracedValue<T>& rhs) -> TracedValue<decltype(lhs + rhs.Get())>
529{
530 TRACED_VALUE_DEBUG("+x");
531 return TracedValue<decltype(lhs + rhs.Get())>(lhs + rhs.Get());
532}
533
534/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
535// clang-format off
536// Clang-format guard needed for version 18 only
537template <typename T, typename U>
538auto
540 -> TracedValue<decltype(lhs.Get() - rhs.Get())>
541// clang-format on
542{
543 TRACED_VALUE_DEBUG("x-x");
544 return TracedValue<decltype(lhs.Get() - rhs.Get())>(lhs.Get() - rhs.Get());
545}
546
547/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
548template <typename T, typename U>
549auto
550operator-(const TracedValue<T>& lhs, const U& rhs) -> TracedValue<decltype(lhs.Get() - rhs)>
551{
552 TRACED_VALUE_DEBUG("x-");
553 return TracedValue<decltype(lhs.Get() - rhs)>(lhs.Get() - rhs);
554}
555
556/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
557template <typename T, typename U>
558auto
559operator-(const U& lhs, const TracedValue<T>& rhs) -> TracedValue<decltype(lhs - rhs.Get())>
560{
561 TRACED_VALUE_DEBUG("-x");
562 return TracedValue<decltype(lhs - rhs.Get())>(lhs - rhs.Get());
563}
564
565/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
566// clang-format off
567// Clang-format guard needed for version 18 only
568template <typename T, typename U>
569auto
571 -> TracedValue<decltype(lhs.Get() * rhs.Get())>
572// clang-format on
573{
574 TRACED_VALUE_DEBUG("x*x");
575 return TracedValue<decltype(lhs.Get() * rhs.Get())>(lhs.Get() * rhs.Get());
576}
577
578/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
579template <typename T, typename U>
580auto
581operator*(const TracedValue<T>& lhs, const U& rhs) -> TracedValue<decltype(lhs.Get() * rhs)>
582{
583 TRACED_VALUE_DEBUG("x*");
584 return TracedValue<decltype(lhs.Get() * rhs)>(lhs.Get() * rhs);
585}
586
587/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
588template <typename T, typename U>
589auto
590operator*(const U& lhs, const TracedValue<T>& rhs) -> TracedValue<decltype(lhs + rhs.Get())>
591{
592 TRACED_VALUE_DEBUG("*x");
593 return TracedValue<decltype(lhs + rhs.Get())>(lhs * rhs.Get());
594}
595
596/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
597// clang-format off
598// Clang-format guard needed for version 18 only
599template <typename T, typename U>
600auto
602 -> TracedValue<decltype(lhs.Get() / rhs.Get())>
603// clang-format on
604{
605 TRACED_VALUE_DEBUG("x/x");
606 return TracedValue<decltype(lhs.Get() / rhs.Get())>(lhs.Get() / rhs.Get());
607}
608
609/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
610template <typename T, typename U>
611auto
612operator/(const TracedValue<T>& lhs, const U& rhs) -> TracedValue<decltype(lhs.Get() / rhs)>
613{
614 TRACED_VALUE_DEBUG("x/");
615 return TracedValue<decltype(lhs.Get() / rhs)>(lhs.Get() / rhs);
616}
617
618/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
619template <typename T, typename U>
620auto
621operator/(const U& lhs, const TracedValue<T>& rhs) -> TracedValue<decltype(lhs / rhs.Get())>
622{
623 TRACED_VALUE_DEBUG("/x");
624 return TracedValue<decltype(lhs / rhs.Get())>(lhs / rhs.Get());
625}
626
627/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
628// clang-format off
629// Clang-format guard needed for version 18 only
630template <typename T, typename U>
631auto
633 -> TracedValue<decltype(lhs.Get() % rhs.Get())>
634// clang-format on
635{
636 TRACED_VALUE_DEBUG("x%x");
637 return TracedValue<decltype(lhs.Get() % rhs.Get())>(lhs.Get() % rhs.Get());
638}
639
640/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
641template <typename T, typename U>
642auto
643operator%(const TracedValue<T>& lhs, const U& rhs) -> TracedValue<decltype(lhs.Get() % rhs)>
644{
645 TRACED_VALUE_DEBUG("x%");
646 return TracedValue<decltype(lhs.Get() % rhs)>(lhs.Get() % rhs);
647}
648
649/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
650template <typename T, typename U>
651auto
652operator%(const U& lhs, const TracedValue<T>& rhs) -> TracedValue<decltype(lhs % rhs.Get())>
653{
654 TRACED_VALUE_DEBUG("%x");
655 return TracedValue<decltype(lhs % rhs.Get())>(lhs % rhs.Get());
656}
657
658/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
659// clang-format off
660// Clang-format guard needed for version 18 only
661template <typename T, typename U>
662auto
664 -> TracedValue<decltype(lhs.Get() ^ rhs.Get())>
665// clang-format on
666{
667 TRACED_VALUE_DEBUG("x^x");
668 return TracedValue<decltype(lhs.Get() ^ rhs.Get())>(lhs.Get() ^ rhs.Get());
669}
670
671/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
672template <typename T, typename U>
673auto
674operator^(const TracedValue<T>& lhs, const U& rhs) -> TracedValue<decltype(lhs.Get() ^ rhs)>
675{
676 TRACED_VALUE_DEBUG("x^");
677 return TracedValue<decltype(lhs.Get() ^ rhs)>(lhs.Get() ^ rhs);
678}
679
680/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
681template <typename T, typename U>
682auto
683operator^(const U& lhs, const TracedValue<T>& rhs) -> TracedValue<decltype(lhs ^ rhs.Get())>
684{
685 TRACED_VALUE_DEBUG("^x");
686 return TracedValue<decltype(lhs ^ rhs.Get())>(lhs ^ rhs.Get());
687}
688
689/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
690// clang-format off
691// Clang-format guard needed for version 18 only
692template <typename T, typename U>
693auto
695 -> TracedValue<decltype(lhs.Get() | rhs.Get())>
696// clang-format on
697{
698 TRACED_VALUE_DEBUG("x|x");
699 return TracedValue<decltype(lhs.Get() | rhs.Get())>(lhs.Get() | rhs.Get());
700}
701
702/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
703template <typename T, typename U>
704auto
705operator|(const TracedValue<T>& lhs, const U& rhs) -> TracedValue<decltype(lhs.Get() | rhs)>
706{
707 TRACED_VALUE_DEBUG("x|");
708 return TracedValue<decltype(lhs.Get() | rhs)>(lhs.Get() | rhs);
709}
710
711/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
712template <typename T, typename U>
713auto
714operator|(const U& lhs, const TracedValue<T>& rhs) -> TracedValue<decltype(lhs | rhs.Get())>
715{
716 TRACED_VALUE_DEBUG("|x");
717 return TracedValue<decltype(lhs | rhs.Get())>(lhs | rhs.Get());
718}
719
720/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
721// clang-format off
722// Clang-format guard needed for version 18 only
723template <typename T, typename U>
724auto
726 -> TracedValue<decltype(lhs.Get() & rhs.Get())>
727// clang-format on
728{
729 TRACED_VALUE_DEBUG("x&x");
730 return TracedValue<decltype(lhs.Get() & rhs.Get())>(lhs.Get() & rhs.Get());
731}
732
733/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
734template <typename T, typename U>
735auto
736operator&(const TracedValue<T>& lhs, const U& rhs) -> TracedValue<decltype(lhs.Get() & rhs)>
737{
738 TRACED_VALUE_DEBUG("x&");
739 return TracedValue<decltype(lhs.Get() & rhs)>(lhs.Get() & rhs);
740}
741
742/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
743template <typename T, typename U>
744auto
745operator&(const U& lhs, const TracedValue<T>& rhs) -> TracedValue<decltype(lhs & rhs.Get())>
746{
747 TRACED_VALUE_DEBUG("&x");
748 return TracedValue<decltype(lhs & rhs.Get())>(lhs & rhs.Get());
749}
750
751/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
752// clang-format off
753// Clang-format guard needed for version 18 only
754template <typename T, typename U>
755auto
756operator<<(const TracedValue<T>& lhs, const TracedValue<U>& rhs)
757 -> TracedValue<decltype(lhs.Get() << rhs.Get())>
758// clang-format on
759{
760 TRACED_VALUE_DEBUG("x<<x");
761 return TracedValue<decltype(lhs.Get() << rhs.Get())>(lhs.Get() << rhs.Get());
762}
763
764/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
765template <typename T, typename U>
766auto
767operator<<(const TracedValue<T>& lhs, const U& rhs) -> TracedValue<decltype(lhs.Get() << rhs)>
768{
769 TRACED_VALUE_DEBUG("x<<");
770 return TracedValue<decltype(lhs.Get() << rhs)>(lhs.Get() << rhs);
771}
772
773/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
774template <typename T, typename U>
775auto
776operator<<(const U& lhs, const TracedValue<T>& rhs) -> TracedValue<decltype(lhs << rhs.Get())>
777{
778 TRACED_VALUE_DEBUG("<<x");
779 return TracedValue<decltype(lhs << rhs.Get())>(lhs << rhs.Get());
780}
781
782/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
783// clang-format off
784// Clang-format guard needed for version 18 only
785template <typename T, typename U>
786auto
788 -> TracedValue<decltype(lhs.Get() >> rhs.Get())>
789// clang-format on
790{
791 TRACED_VALUE_DEBUG("x>>x");
792 return TracedValue<decltype(lhs.Get() >> rhs.Get())>(lhs.Get() >> rhs.Get());
793}
794
795/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
796template <typename T, typename U>
797auto
798operator>>(const TracedValue<T>& lhs, const U& rhs) -> TracedValue<decltype(lhs.Get() >> rhs)>
799{
800 TRACED_VALUE_DEBUG("x>>");
801 return TracedValue<decltype(lhs.Get() >> rhs)>(lhs.Get() >> rhs);
802}
803
804/** @copydoc operator+(const TracedValue<T>&lhs,const TracedValue<U>&rhs) */
805template <typename T, typename U>
806auto
807operator>>(const U& lhs, const TracedValue<T>& rhs) -> TracedValue<decltype(lhs >> rhs.Get())>
808{
809 TRACED_VALUE_DEBUG(">>x");
810 return TracedValue<decltype(lhs >> rhs.Get())>(lhs >> rhs.Get());
811}
812
813/**
814 * Operator assignment for TracedValue.
815 *
816 * The result of the arithmetic operation on the underlying values
817 * is assigned to the \c lhs TracedValue. If the new value
818 * is different, the Callback will be invoked.
819 *
820 * @tparam T \deduced The underlying type held by the left-hand argument.
821 * @tparam U \deduced The underlying type held by the right-hand argument.
822 * @param [in] lhs The left-hand argument.
823 * @param [in] rhs The right-hand argument.
824 * @returns The result of doing the operator on
825 * the underlying values.
826 */
827template <typename T, typename U>
828TracedValue<T>&
829operator+=(TracedValue<T>& lhs, const U& rhs)
830{
831 TRACED_VALUE_DEBUG("x+=");
832 T tmp = lhs.Get();
833 tmp += rhs;
834 lhs.Set(tmp);
835 return lhs;
836}
837
838/** @copydoc operator+=(TracedValue<T>&lhs,const U&rhs) */
839template <typename T, typename U>
840TracedValue<T>&
841operator-=(TracedValue<T>& lhs, const U& rhs)
842{
843 TRACED_VALUE_DEBUG("x-=");
844 T tmp = lhs.Get();
845 tmp -= rhs;
846 lhs.Set(tmp);
847 return lhs;
848}
849
850/** @copydoc operator+=(TracedValue<T>&lhs,const U&rhs) */
851template <typename T, typename U>
852TracedValue<T>&
853operator*=(TracedValue<T>& lhs, const U& rhs)
854{
855 TRACED_VALUE_DEBUG("x*=");
856 T tmp = lhs.Get();
857 tmp *= rhs;
858 lhs.Set(tmp);
859 return lhs;
860}
861
862/** @copydoc operator+=(TracedValue<T>&lhs,const U&rhs) */
863template <typename T, typename U>
864TracedValue<T>&
865operator/=(TracedValue<T>& lhs, const U& rhs)
866{
867 TRACED_VALUE_DEBUG("x/=");
868 T tmp = lhs.Get();
869 tmp /= rhs;
870 lhs.Set(tmp);
871 return lhs;
872}
873
874/** @copydoc operator+=(TracedValue<T>&lhs,const U&rhs) */
875template <typename T, typename U>
876TracedValue<T>&
877operator%=(TracedValue<T>& lhs, const U& rhs)
878{
879 TRACED_VALUE_DEBUG("x%=");
880 T tmp = lhs.Get();
881 tmp %= rhs;
882 lhs.Set(tmp);
883 return lhs;
884}
885
886/** @copydoc operator+=(TracedValue<T>&lhs,const U&rhs) */
887template <typename T, typename U>
888TracedValue<T>&
889operator<<=(TracedValue<T>& lhs, const U& rhs)
890{
891 TRACED_VALUE_DEBUG("x<<=");
892 T tmp = lhs.Get();
893 tmp <<= rhs;
894 lhs.Set(tmp);
895 return lhs;
896}
897
898/** @copydoc operator+=(TracedValue<T>&lhs,const U&rhs) */
899template <typename T, typename U>
900TracedValue<T>&
901operator>>=(TracedValue<T>& lhs, const U& rhs)
902{
903 TRACED_VALUE_DEBUG("x>>=");
904 T tmp = lhs.Get();
905 tmp >>= rhs;
906 lhs.Set(tmp);
907 return lhs;
908}
909
910/** @copydoc operator+=(TracedValue<T>&lhs,const U&rhs) */
911template <typename T, typename U>
912TracedValue<T>&
913operator&=(TracedValue<T>& lhs, const U& rhs)
914{
915 TRACED_VALUE_DEBUG("x&=");
916 T tmp = lhs.Get();
917 tmp &= rhs;
918 lhs.Set(tmp);
919 return lhs;
920}
921
922/** @copydoc operator+=(TracedValue<T>&lhs,const U&rhs) */
923template <typename T, typename U>
924TracedValue<T>&
925operator|=(TracedValue<T>& lhs, const U& rhs)
926{
927 TRACED_VALUE_DEBUG("x|=");
928 T tmp = lhs.Get();
929 tmp |= rhs;
930 lhs.Set(tmp);
931 return lhs;
932}
933
934/** @copydoc operator+=(TracedValue<T>&lhs,const U&rhs) */
935template <typename T, typename U>
936TracedValue<T>&
937operator^=(TracedValue<T>& lhs, const U& rhs)
938{
939 TRACED_VALUE_DEBUG("x^=");
940 T tmp = lhs.Get();
941 tmp ^= rhs;
942 lhs.Set(tmp);
943 return lhs;
944}
945
946/**
947 * Unary arithmetic operator for TracedValue.
948 *
949 * @tparam T \deduced The underlying type held by the TracedValue.
950 * @param [in] lhs The TracedValue.
951 * @returns The result of doing the operator on
952 * the underlying values.
953 */
954template <typename T>
955TracedValue<T>
957{
958 TRACED_VALUE_DEBUG("(+x)");
959 return TracedValue<T>(+lhs.Get());
960}
961
962/** @copydoc operator+(const TracedValue<T>&lhs) */
963template <typename T>
964TracedValue<T>
966{
967 TRACED_VALUE_DEBUG("(-x)");
968 return TracedValue<T>(-lhs.Get());
969}
970
971/** @copydoc operator+(const TracedValue<T>&lhs) */
972template <typename T>
973TracedValue<T>
975{
976 TRACED_VALUE_DEBUG("(~x)");
977 return TracedValue<T>(~lhs.Get());
978}
979
980/** @copydoc operator+(const TracedValue<T>&lhs) */
981template <typename T>
982TracedValue<T>
984{
985 TRACED_VALUE_DEBUG("(!x)");
986 return TracedValue<T>(!lhs.Get());
987}
988
989/**@}*/ // \ingroup tracing
990
991} // namespace ns3
992
993#endif /* TRACED_VALUE_H */
ns3::BooleanValue attribute value declarations.
Base class for Callback class.
Definition callback.h:344
Forward calls to a chain of Callback.
void Disconnect(const CallbackBase &callback, std::string path)
Remove from the chain a Callback which was connected with a context.
void ConnectWithoutContext(const CallbackBase &callback)
Append a Callback to the chain (without a context).
void DisconnectWithoutContext(const CallbackBase &callback)
Remove from the chain a Callback which was connected without a context.
void Connect(const CallbackBase &callback, std::string path)
Append a Callback to the chain with a context.
Trace classes with value semantics.
TracedValue(const T &v)
Construct from an explicit variable.
TracedValue & operator++()
Pre/post- increment/decrement operator.
void DisconnectWithoutContext(const CallbackBase &cb)
Disconnect a Callback which was connected without context.
TracedCallback< T, T > m_cb
The connected Callback.
T m_v
The underlying value.
TracedValue & operator--()
Pre/post- increment/decrement operator.
void Connect(const CallbackBase &cb, std::string path)
Connect a Callback with a context string.
void Disconnect(const CallbackBase &cb, std::string path)
Disconnect a Callback which was connected with context.
TracedValue operator--(int)
Pre/post- increment/decrement operator.
TracedValue & operator=(const TracedValue &o)
Assignment.
TracedValue(const TracedValue &o)
Copy constructor.
void ConnectWithoutContext(const CallbackBase &cb)
Connect a Callback (without context.)
T Get() const
Get the underlying value.
TracedValue()
Default constructor.
TracedValue(const U &other)
Copy from a variable type compatible with this underlying type.
void Set(const T &v)
Set the value of the underlying variable.
TracedValue operator++(int)
Pre/post- increment/decrement operator.
TracedValue(const TracedValue< U > &other)
Copy from a TracedValue of a compatible type.
ns3::DoubleValue attribute value declarations and template implementations.
ns3::EnumValue attribute value declarations.
int64x64_t operator/(const int64x64_t &lhs, const int64x64_t &rhs)
Division operator.
Definition int64x64.h:121
bool operator>=(const int64x64_t &lhs, const int64x64_t &rhs)
Greater or equal operator.
Definition int64x64.h:162
bool operator<=(const int64x64_t &lhs, const int64x64_t &rhs)
Less or equal operator.
Definition int64x64.h:149
int64x64_t operator-(const int64x64_t &lhs, const int64x64_t &rhs)
Subtraction operator.
Definition int64x64.h:91
int64x64_t operator+(const int64x64_t &lhs, const int64x64_t &rhs)
Addition operator.
Definition int64x64.h:76
int64x64_t operator*(const int64x64_t &lhs, const int64x64_t &rhs)
Multiplication operator.
Definition int64x64.h:106
bool operator>(const Length &left, const Length &right)
Check if left has a value greater than right.
Definition length.cc:410
TracedValue< T > & operator/=(TracedValue< T > &lhs, const U &rhs)
Operator assignment for TracedValue.
TracedValue< T > & operator|=(TracedValue< T > &lhs, const U &rhs)
Operator assignment for TracedValue.
TracedValue< T > operator!(const TracedValue< T > &lhs)
Unary arithmetic operator for TracedValue.
TracedValue< T > & operator%=(TracedValue< T > &lhs, const U &rhs)
Operator assignment for TracedValue.
auto operator^(const TracedValue< T > &lhs, const TracedValue< U > &rhs) -> TracedValue< decltype(lhs.Get() ^ rhs.Get())>
Infix arithmetic operator for TracedValue.
auto operator|(const TracedValue< T > &lhs, const TracedValue< U > &rhs) -> TracedValue< decltype(lhs.Get()|rhs.Get())>
Infix arithmetic operator for TracedValue.
TracedValue< T > & operator^=(TracedValue< T > &lhs, const U &rhs)
Operator assignment for TracedValue.
TracedValue< T > & operator*=(TracedValue< T > &lhs, const U &rhs)
Operator assignment for TracedValue.
TracedValue< T > & operator<<=(TracedValue< T > &lhs, const U &rhs)
Operator assignment for TracedValue.
TracedValue< T > operator~(const TracedValue< T > &lhs)
Unary arithmetic operator for TracedValue.
TracedValue< T > & operator>>=(TracedValue< T > &lhs, const U &rhs)
Operator assignment for TracedValue.
TracedValue< T > & operator&=(TracedValue< T > &lhs, const U &rhs)
Operator assignment for TracedValue.
auto operator&(const TracedValue< T > &lhs, const TracedValue< U > &rhs) -> TracedValue< decltype(lhs.Get() &rhs.Get())>
Infix arithmetic operator for TracedValue.
ns3::IntegerValue attribute value declarations and template implementations.
void(* Uint16)(uint16_t oldValue, uint16_t newValue)
TracedValue Callback signature for POD.
void(* Bool)(bool oldValue, bool newValue)
TracedValue Callback signature for POD.
void(* Int8)(int8_t oldValue, int8_t newValue)
TracedValue Callback signature for POD.
void(* Void)()
TracedValue Callback signature for void.
void(* Int16)(int16_t oldValue, int16_t newValue)
TracedValue Callback signature for POD.
void(* Uint8)(uint8_t oldValue, uint8_t newValue)
TracedValue Callback signature for POD.
void(* Int64)(int64_t oldValue, int64_t newValue)
TracedValue Callback signature for POD.
void(* Uint32)(uint32_t oldValue, uint32_t newValue)
TracedValue Callback signature for POD.
void(* Uint64)(uint64_t oldValue, uint64_t newValue)
TracedValue Callback signature for POD.
void(* Int32)(int32_t oldValue, int32_t newValue)
TracedValue Callback signature for POD.
void(* Double)(double oldValue, double newValue)
TracedValue Callback signature for POD.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool operator!=(Callback< R, Args... > a, Callback< R, Args... > b)
Inequality test.
Definition callback.h:658
Time operator%(const Time &lhs, const Time &rhs)
Remainder (modulus) from the quotient of two Times.
Definition nstime.h:1146
bool operator==(const EventId &a, const EventId &b)
Definition event-id.h:155
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
Time & operator+=(Time &lhs, const Time &rhs)
Compound addition assignment for Time.
Definition nstime.h:1192
std::istream & operator>>(std::istream &is, Angles &a)
Definition angles.cc:172
bool operator<(const EventId &a, const EventId &b)
Definition event-id.h:168
Time & operator-=(Time &lhs, const Time &rhs)
Compound subtraction assignment for Time.
Definition nstime.h:1205
ns3::TracedCallback declaration and template implementation.
#define TRACED_VALUE_DEBUG(x)
Logging macro for TracedValue.
ns3::UintegerValue attribute value declarations and template implementations.