ADVlib is a simple library for C++ 14 when the C++ Standard Library is not an option or is not appropriate.
Most of the time, implementing callbacks is not a problem with C++ thanks to function and functional header. However, there are circumstances when function is not an option. For example:
- When the Standard Library is not available. It is in particular the case with AVR (and with IoT in general).
- When function is too complex to implement callbacks
Note: This library was previously called ADVcallback but I have renamed it since it contains more than just callbacks.
When using a C++ 11 (or later) compiler, the Standard Library is most of the time available, but not always. This is in particular a problem when developing for Arduino (and AVR in general). There are several reasons for that. One of them is that the Standard Library is heavy and it is not optimized for embedded systems with, for example, only 2048 bytes of RAM (as it is the case of the Arduino Uno).
There some partial implementations of the STL (Standard Template Library), a subset of the Standard Library. These implementations do implement algorithms and entities such as vector (most of the time, in a pre-C++11 way). But they lack C++ 11 entities such as unique_ptr.
When developing ADVi3++, I face these limitations many times and thus decided to create a minimal implementation of what I need.
Example of STL for embedded systems:
The template std::function
is a general-purpose polymorphic function wrapper. It can store plain functions, functors, lambda expressions, static members. It can also store pointers to members and pointers to data members. For example:
std::function<void()> display42 = []{ std::cout << 42 << cout::endl; }; display42();
However in the case of members, it is bind to the instance (the this
pointer). As a consequence, the signature of the function is changed. Let's assume we have defined the following class:
struct Num { explicit Num(int n): n_{n} {} int add(int i) { return n_ + i; } int n_ = 0; };
The signature of add` is the following:
int(Num::*)(int)
We declare a function initialized with the member function add
this way:
std::function<int(const Num&, int)> f{&Num::add};
And we call it this way:
Num n{0}; f(n, 1);
In other terms, the signature of the function
is std::function<int(const Num&, int)>
and we declare and use separately the instance.
Sometimes, this is not what we want. We want to declare at the same time both the instance and the member function, store them and calls them later. The function has to be polymorphic and store either a plain function, a functor, a static member or an instance member. For all these cases, the signature has to be the same. In this case:
std::function<int(int)>
This is possible to achieve with std::function
by using bind
and placeholders:
Num n{0}; std::function<int(int)> f2{std::bind(&Num::add, &n2, _1)}; f(1);
And this is exactly what I needed for callbacks inside ADVi3++. However, as you may have guessed, std::function is very heavy and complex. I wanted something similar but less complex. And this is why I implemented ADVcallback.
To make it clear that my callbacks are different from std::function, I have named them Callback
. All the entities are declared inside a namespace name andrivet
(and not std
).
Callbacks are used this way:
using MyCallback = Callback<int(int)>; Num n{0}; MyCallback callback{n, &Num::add}; callback(1); callback = MyCallback{[](int i){ return i; }}; callback(2); int b = 8; callback = MyCallback([b](int i){ return b + i; }}; callback(3);
The project contains unit tests for unique_ptr
, Callback
and `Crtp
(for compile-time polymorphism). They are located inside the tests
directory and give various example of how to use unique_ptr
, Callback
and Crtp
.
Copyright © 2018 Sebastien Andrivet
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.