Bug 3012 - Use std::function to implement callbacks
Use std::function to implement callbacks
Status: RESOLVED MOVED
Product: ns-3
Classification: Unclassified
Component: core
ns-3-dev
PC All
: P5 enhancement
Assigned To: Peter Barnes
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2018-11-14 06:36 EST by Stefano Avallone
Modified: 2020-05-07 09:33 EDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Stefano Avallone 2018-11-14 06:36:54 EST
I spent some time to modernize the implementation of callbacks by using C++11 std::function. Here is the result:

https://github.com/stavallo/ns-3-dev-git/commits/callbacks

My goals were to:

- make the code in callback.h more readable and compact
- allow the creation of callbacks pointing to lambdas and objects returned by std::bind
- remove the limitation on 3 bound parameters

The overall design is mostly untouched. Instead of having a CallbackImpl<> class and 5 subclasses, we have a single CallbackImpl<> class that stores any kind of callable objects as a std::function. Given that std::function objects cannot be compared, I thought that CallbackImpl<> could also keep a vector of callback "components": the original function and every bound argument. Callbacks are compared by comparing such components one by one. Partial specialization of the CallbackComponent class enables to avoid the comparison of lambdas (not allowed by compilers) and always return false.

Still, it is possible to check when two callbacks point to the *same* lambda. The traced-callback test has been modified to show that this can be done by simply storing a CallbackBase object (slicing works because the implementation is kept).

I borrowed the changes to traced-callback.h from Alexander's patch attached to bug 2457. Apart from three nasty attempts at casting 0 to a Callback, no other changes are required. Changes to the tests are mainly additions to showcase what can be done with callbacks.

All the tests and examples run fine, I verified that there are no memory leaks and I also successfully scanned the python bindings.

The C++11 version of the patch compiles fine on MacOS and on Linux with g++ >= 5 (see below).

Given that this patch and others make use of variadic templates, I think it may be useful to switch to C++14 by default. We may then exploit:

- auto deduction of function return types
- generation of compile time integer sequences and other helpers such as enable_if_t, remove_pointer_t, etc.
- generic lambdas

The C++14 version of the patch ("core: Make use of C++14 features") exploits the first two features of the list above. C++14 is supported by clang 3.4 [1] and by g++ 4.9/5 [2]. From my tests, the C++14 version of my patch compiles fine even with g++ 4.9. Thus, if we switch to C++14, there is no need to increase the requirement on the minimum version of g++.


[1] https://clang.llvm.org/cxx_status.html
[2] https://gcc.gnu.org/projects/cxx-status.html#cxx14
Comment 1 natale.patriciello 2018-11-14 09:06:10 EST
Hi Stefano,

how does the patch compare with bug 2457? Is it a complete replacement?
Comment 2 Alexander Krotov 2018-11-14 09:21:22 EST
In reply to natale.patriciello from comment #1)
> Hi Stefano,
> 
> how does the patch compare with bug 2457? Is it a complete replacement?

It uses only part of the bug 2457 patch in the first commit:
https://github.com/stavallo/ns-3-dev-git/commit/79d5fb961945a1a10eaf7eec299e648216b20bb2

So it is not a complete replacement, it is an addition.

@Stefano Avallone: why not build on top of the whole bug 2457 patch?
Comment 3 Stefano Avallone 2018-11-14 09:23:00 EST
> how does the patch compare with bug 2457? Is it a complete replacement?

Good question. I should have mentioned first.

My patch:

- is a replacement for Alexander's changes to callback.h only (see also below)
- depends on Alexander's changes to trace-callback.h (which I borrowed without any change)
- is independent of the changes that Alexander made to other files

Concerning the changes to callback.h, Alexander only used variadic templates to simplify the definition of the three variants of MakeCallback and MakeNullCallback. So, I would say that his patch only achieves (partly) the first of the three goals I listed above.
Comment 4 Stefano Avallone 2018-11-14 09:30:04 EST
(In reply to Alexander Krotov from comment #2)
> It uses only part of the bug 2457 patch in the first commit:
> https://github.com/stavallo/ns-3-dev-git/commit/
> 79d5fb961945a1a10eaf7eec299e648216b20bb2
> 
> So it is not a complete replacement, it is an addition.

Correct.
 
> @Stefano Avallone: why not build on top of the whole bug 2457 patch?

For the moment, I chose not to depend on your patch, except for the piece I really needed. However, if your patch will be merged first (and soon, I hope!) I will rebase my patch on top of yours.
Comment 5 Stefano Avallone 2020-05-07 09:33:46 EDT
Moved to GitLab:

https://gitlab.com/nsnam/ns-3-dev/-/merge_requests/278