In embedded C/C++ programming is quite common to write for loops of this type:
...
for(int16_t i=0; i<5; i++)
{
if(true == unlockSIM(simPinNumber))
return true;
wait_ms(1000);
}
return false;
...
or like this while() loop:
bool CGps::waitGpsFix(int8_t fixVal)
{
int16_t iRunStatus=0, iFixStatus=0;
_timeWaitGpsFix = CSysTick::instance().set(TIME_TO_WAIT_GPS);
while(1)
{
bool bRet = _pGsm->GPSstatus(&iRunStatus, &iFixStatus);
if( (true == bRet) && (1 == iRunStatus) && (iFixStatus >= fixVal) )
return true;
if(CSysTick::instance().isElapsed(_timeWaitGpsFix))
return false;
wait_ms(500);
}
return false;
}
//---------------------------------------------------------------------------
is there any well known good pattern useful to don't write each time so many lines but just a function or method call?
For the for loop, you could use a function template that accepts the function (must return a boolean) and return when succeeded. For the while loop, things get more complicated, but I guess that lambdas could be used as true and false conditions.
For loop:
#include <iostream>
template<int retries, int wait_time, typename FUNC, typename ...Args>
bool retry(FUNC& f, Args &&... args)
{
for (int i = 0; i < retries; ++i)
{
if (f(std::forward<Args>(args)...)) return true;
if (i < retries - 1)
{
std::cout << "waiting " << wait_time << "\n";
}
}
return false;
}
bool func(int i)
{
return (i > 0);
}
bool func2(int i, int j)
{
return (i > j);
}
int main()
{
bool result = retry<5, 500>(func, 0);
std::cout << result << "\n";
result = retry<5, 500>(func, 1);
std::cout << result << "\n";
result = retry<5, 500>(func2, 1, 2);
std::cout << result << "\n";
result = retry<5, 500>(func2, 1, 0);
std::cout << result << "\n";
}
See example in coliru
This is simple enough with the execute-around idiom, which executes a given piece of code in an environment/set of circumstances controlled by the function the piece of code is passed in to. Here, we'll simply be calling the piece of code in a loop once every n milliseconds, either for a set amount of time, or for a set number of times.
Since you're working in an embedded environment and seem to be using a set of timing mechanisms different from that provided by <chrono> and <thread>, I've tried to adjust my answer so you can use the methods you seem to have access to to do the same thing. These are the functions I've used in my solution:
// similar functions to what you seem to have access to
namespace timing{
// interval defined as some arbitrary type
interval getInterval(int msCount);
bool intervalElapsed(interval i);
void await(interval i);
}
A note on the await function there--it takes an interval, and pauses execution until the interval has passed. It seems like the closest you can get to this might be simply waiting for the total number of milliseconds instead, though that strategy will introduce a certain amount of drift in your timings. If you can tolerate that (and given you're using it, it seems you can), then great.
The retry-for variant would look like this, given the above function signatures:
template <typename Func>
bool pollRetries(
int retryLimit,
int msInterval,
Func func){
for(int i = 0; i < retryLimit; ++i){
auto interval = timing::getInterval(msInterval);
if (func()){return true;}
timing::await(interval);
}
return false;
}
and the retry-while would look like this:
template <typename Func>
bool pollDuration(
int msLimit,
int msInterval,
Func func){
auto limit = timing::getInterval(msLimit);
while(!timing::intervalElapsed(limit)){
auto interval = timing::getInterval(msInterval);
if (func()){return true;}
timing::await(interval);
}
return false;
}
Live demo on Coliru
Both functions take a single functor which will be called with no arguments, and which returns either a boolean or something convertible to a boolean value. If the evaluation ever returns true, the loop will exit and the function will return true. Otherwise it'll return false at the end of the retry count or period.
Your sample code would convert to this:
retry for loop:
return pollRetries(5,1000,[simPinNumber](){
return unlockSIM(simPinNumber);
});
retry while loop:
return pollDuration(TIME_TO_WAIT_GPS, 500, [fixVal, this](){
int16_t
iRunStatus = 0,
iFixStatus = 0;
bool bRet = this->_pGsm->GPSstatus(&iRunStatus, &iFixStatus);
return bRet && (1 == iRunStatus) && (iFixStatus >= fixVal);
});
You can pass either functors or function pointers into these methods and the execution will occur, so you can also simply directly pass in lambdas to be executed. A few notes about that:
Lambdas without a capture group can be converted to function pointers with the unary + operator, allowing the template to use the function pointer instantiation of the template rather than one based off the lambda. You might want to do this because:
Every lambda in every function has an anonymous type. Passing the lambda into the template function will result in an additional template instantiation which might increase binary size.
You can also mitigate the above problem by defining your own functor class for uses that share a set of persistent state.
You might try making the timing functions into variadic templates per #stefaanv's solution. If you went this route, you could remove the capture groups from your lambdas and pass that information in manually, which would allow you to convert the lambdas into function pointers as though they were stateless.
Were most of these retry loops for a single class you could simply define the retry mechanisms as member function templates, and then subject yourself to member function pointers, thereby passing state around using the called object. I'd not recommend this though, as member function pointers are a bit of a pain to deal with, and you could get the same result by making a stateless lambda take a reference to the object, and passing in *this to the call. You'd also have to define all the bits of code as their own functions, rather than simply defining them within the function where they were used.
Related
The full context of this problem is unfortunately too involved to explain, but suffice to say it involves some complicated template metaprogramming and I find myself having to do some funny things. I've tried to boil down an issue I've encountered into a minimal example, so the question may seem awkward. If it's possible to do this I'd be interested to know how, if not I'd be interested in hearing possible alternatives.
I'd like to create a function that takes as input a lambda function that may return void or something else. If it does return void, I'd like to convert it into an identical lambda that, instead of returning void, returns true.
template <typename InputFuncType>
auto function_converter(InputFuncType lambda_func)
{
// I also need to figure out how to deduce the return type of lambda_func
// might be something like this.
if constexpr (std::is_same<std::result_of<InputFuncType>::type, void>::value)
{
// Current best guess. Note that in the context of the converter, I don't explicitly know
// lambda_func's input type, so I'm not sure how to do something like this.
return [](InputFuncType::input_args_t... args) {lambda_func(args); return true;};
}
return lambda_func;
}
// target usage
const auto lam1 = [](int a) {return;};
const auto lam2 = function_converter(lam1);
int x = 4;
lam1(x); // returns void
const bool y2 = lam2(x); // returns true
I'm using c++17.
A little redundant, I suppose, but the following wrapper should works
template <typename InputFuncType>
auto function_converter (InputFuncType lf)
{
return [=](auto && ... args)
{
using RT = decltype(lf(std::forward<decltype(args)>(args)...));
if constexpr ( true == std::is_same_v<void, RT> )
{
lf(std::forward<decltype(args)>(args)...);
return true;
}
else
return lf(std::forward<decltype(args)>(args)...);
};
}
Substantially, the idea is transfer the check, about the returned type, inside the internal lambda.
I have been making various functions that will compute the sigma in a range of very specific functions. I am now trying to write a sigma function that you would input a lambda or a function and it would then calculate the sum of its outputs within a range. I have the iteration code done fine but now need to figure out how to input a lambda and call it inside that function.
here is my current code:
int sigma(int start, int end, ? function) {
if (start == end) {
return function(start);
}
else {
return function(start) + sigma(start + 1, end, function);
}
}
PS if anyone could help me make this not use recursion that would be amazing
You can make this function into a function-template:
template<typename Fn>
int sigma(int start, int end, Fn function) {
// ...
}
and then call it with a lambda:
auto lam = [](int) { return 42; };
std::cout << sigma(1, 5, lam);
To avoid the rescursion, the body could simply be:
int sum = 0;
for (int i = start; i <= end; ++i)
sum += function(i);
return sum;
You need the type for your parameter. So ask yourself what is this parameter supposed to be? Based upon your definition of sigma(), you appear to be expecting a function-like object that is invoked with an int parameter and returns an int. That is, a std::function<int(int)>. Your function's declaration might end up looking like the following.
int sigma(int start, int end, std::function<int(int)> & function);
If you want to handle functions with other signatures, then a function template might be more appropriate. See std::function vs template for a discussion.
I have a function that acts as a "function dispatch." This function contains a variable named next_func, which is initialized to the first function to load. Then, inside an infinite loop, the next_func is set to the return value of itself.
My question is, besides using auto, what type does next_func need to be? Here's some conceptual code (using auto) to give an idea of what I'm looking for:
void FunctionDispatch()
{
auto next_menu = first_menu;
while (next_menu != app_exit)
{
next_menu = next_menu();
}
}
auto first_menu()
{
auto return_menu = first_menu; // Set to itself for 'auto', but I don't want to have to do this
std::cout << "2 or 3? ";
unsigned input = 0;
std::cin >> input;
switch (input)
{
case 2:
return_menu = second_menu;
break;
case 3:
return_menu = third_menu;
break;
default:
break;
}
return return_menu;
}
I like using auto for trivial types, but I don't really like relying on it because I don't know how to address the type I'm wanting, which is why I'm wondering what auto actually is here and how to explicitly declare the variables and function return types (probably using type aliases since that's most sensible).
Something to note:
All functions that FunctionDispath() can call take no parameters and return function pointers to other functions that take in no parameters and return the same type of function pointers.
I'd prefer an answer that explains both what the full type would be with no type aliases and how to use a type alias here.
First off, cool! This reminds me of middleware frameworks, or coroutines with tasks and event loops.
Doing this with straight-up function pointers will result in an infinitely recursive type, as many have mentioned. But if each task is a callable object, then you don't need recursive types as a forward reference will do. You can inherit std::function to make it easy:
struct task : std::function<task()> {
using std::function<task()>::function;
};
Then you can assign functions to it. You can also bind arguments with std::bind, or even use the default constructor to make an empty function with no target:
task n_hellos(int count) {
if (count) {
std::cout << "hello\n";
return std::bind(n_hellos, count-1);
}
return task();
}
You can cast an std::function to bool to see if it is empty, allowing for a terminal case. The event loop below quits when the next task is empty:
int main() {
task current_task = std::bind(n_hellos, 5);
while (current_task) {
current_task = current_task();
}
} // prints "hello" five times
Demo: https://godbolt.org/z/dHaSWC
As shown in the following code, one of several atomic routines is called in the function messagePassing.
Which one to use is determined before diving into the nested loops.
In the current implementation, several while loops are used for sake of runtime performance.
I want to avoid repeating myself (repeating the shared operations in the nested loops) for sake of readability and maintainability, and achieve something like messagePassingCleanButSlower.
Is there a approach which does not sacrifice runtime performance?
I need to deal with two scenarios.
In the first one, the atomic routines are small and only involve 3 plus/minus operations, thus I guess they will be inlined.
In the second one, the atomic routines are big (about 200 lines) and hence unlikely to be inlined.
#include <vector>
template<typename Uint, typename Real>
class Graph {
public:
void messagePassing(Uint nit, Uint type);
void messagePassingCleanButSlower(Uint nit, Uint type);
private:
struct Vertex {}; // Details are hidden since they are distracting.
std::vector< Vertex > vertices;
void atomicMessagePassingType1(Vertex &v);
void atomicMessagePassingType2(Vertex &v);
void atomicMessagePassingType3(Vertex &v);
// ...
// may have other types
};
template<typename Uint, typename Real>
void
Graph<Uint, Real>::
messagePassing(Uint nit, Uint type)
{
Uint count = 0; // round counter
if (type == 1) {
while (count < nit) {
++count;
// many operations
for (auto &v : vertices) {
// many other operations
atomicMessagePassingType1(v);
}
}
}
else if (type == 2) {
while (count < nit) {
++count;
// many operations
for (auto &v : vertices) {
// many other operations
atomicMessagePassingType2(v);
}
}
}
else {
while (count < nit) {
++count;
// many operations
for (auto &v : vertices) {
// many other operations
atomicMessagePassingType3(v);
}
}
}
}
template<typename Uint, typename Real>
void
Graph<Uint, Real>::
messagePassingCleanButSlower(Uint nit, Uint type)
{
Uint count = 0; // round counter
while (count < nit) {
++count;
// many operations
for (auto &v : vertices) {
// many other operations
if (type == 1) {
atomicMessagePassingType1(v);
}
else if (type == 2) {
atomicMessagePassingType2(v);
}
else {
atomicMessagePassingType3(v);
}
}
}
}
See the benchmarks here:
http://quick-bench.com/rMsSb0Fg4I0WNFX8QbKugCe3hkc
For 1. I have setup a test scenario where the operations in atomicMessagePassingTypeX are really short (only an optimization barrier). I chose roughly 100 elements for vertices and 100 iterations of the outer while. These conditions are going to be different for your actual code, so whether my benchmark results apply to your case, you must verify by benchmarking your own code.
The four test cases are: Your two variants, the one with a function pointer mentioned in the other answers and one where the function pointer is called through a dispatching lambda, like this:
template<typename Uint, typename Real>
void
Graph<Uint, Real>::
messagePassingLambda(Uint nit, Uint type)
{
using ftype = decltype(&Graph::atomicMessagePassingType1);
auto lambda = [&](ftype what_to_call) {
Uint count = 0; // round counter
while (count < nit) {
++count;
// many operations
for (auto &v : vertices) {
// many other operations
(this->*what_to_call)(v);
}
}
};
if(type == 1) lambda(&Graph::atomicMessagePassingType1);
else if(type == 2) lambda(&Graph::atomicMessagePassingType2);
else lambda(&Graph::atomicMessagePassingType3);
}
Try all combinations of GCC 9.1/Clang 8.0 and O2/O3. You will see that at O3 both compilers give roughly the same performance for your "slow" variant, in the case of GCC, it is actually the best. The compiler does hoist the if/else statements out of at least the inner loops and then, for some reason that is not completely clear to me, GCC does reorder the instructions in the inner loop differently than it does for the first variant, resulting in it being even a slightly bit faster.
The function pointer variant is consistently slowest.
The lambda variant is effectively equal to your first variant in performance. I guess it is clear why they are essentially the same if the the lambda is inlined.
If it is not inlined, then there might be a significant performance penalty due to the indirect call of what_to_call. This can be avoided by forcing a different type with appropriate direct call at each call site of lambda:
With C++14 or later you can make a generic lambda:
auto lambda = [&](auto what_to_call) {
adjust the call form (this->*what_to_call)(v); to what_to_call(); and call it with another lambda:
lambda([&](){ atomicMessagePassingType1(v); });
which will force the compiler to instantiate one function per dispatch and that should remove any potential indirect calls.
With C++11 you cannot make a generic lambda or variable template and so you would need to write an actual function template taking the secondary lambda as argument.
You can use a function pointer to make the decision before entering the loop, like so:
template<typename Uint, typename Real>
void
Graph<Uint, Real>::
messagePassingV2(Uint nit, bool isType1)
{
void (Graph::* aMPT_Ptr)(Vertex &); // Thanks to #uneven_mark for the corerct
if (isType1)
aMPT_Ptr = &Graph<Uint, Real>::atomicMessagePassingType1; // syntax here
else
aMPT_Ptr = &Graph<Uint, Real>::atomicMessagePassingType2;
Uint count = 0; // round counter
while (count < nit) {
++count;
for (auto& v : vertices) {
(this->*aMPT_Ptr)(v); // Again, thanks to #uneven_mark for the syntax!
}
}
}
The one thing that remains as a potential issue is what happens if either of the functions 'assigned' to the pointer is inlined. I'm thinking that, as there is code taking the address of these functions, then the compiler will probably prevent any inlining.
There are a couple ways.
1) Bool param. This really just moves the if/else into the function... but that's a good thing when you use the function[s] in multiple places, and a bad thing if you're trying to move the test out of the loop. OTOH, speculative execution should mitigate that.
2) Member function pointers. Nasty syntax in the raw, but 'auto' can burry all that for us.
#include <functional>
#include <iostream>
class Foo
{
public:
void bar() { std::cout << "bar\n"; }
void baz() { std::cout << "baz\n"; }
};
void callOneABunch(Foo& foo, bool callBar)
{
auto whichToCall = callBar ? &Foo::bar : &Foo::baz;
// without the auto, this would be "void(Foo::*)()"
// typedef void(Foo::*TypedefNameGoesHereWeirdRight)();
for (int i = 0; i < 4; ++i)
{
std::invoke(whichToCall, foo); // C++17
(foo.*whichToCall)(); // ugly, several have recommended wrapping it in a macro
Foo* foop = &foo;
(foop->*whichToCall)(); // yep, still ugly
}
}
int main() {
Foo myFoo;
callOneABunch(myFoo, true);
}
You can also take a swing at this with std::function or std::bind, but after arguing with fuction for a bit, I fell back on the bare syntax.
Since C++ 17 one can write an if block that will get executed exactly once like this:
#include <iostream>
int main() {
for (unsigned i = 0; i < 10; ++i) {
if (static bool do_once = true; do_once) { // Enter only once
std::cout << "hello one-shot" << std::endl;
// Possibly much more code
do_once = false;
}
}
}
I know I might be overthinking this, and there are other ways to solve this, but still - is it possible to write this somehow like this, so there is no need of the do_once = false at the end?
if (DO_ONCE) {
// Do stuff
}
I'm thinking a helper function, do_once(), containing the static bool do_once, but what if I wanted to use that same function in different places? Might this be the time and place for a #define? I hope not.
Use std::exchange:
if (static bool do_once = true; std::exchange(do_once, false))
You can make it shorter reversing the truth value:
if (static bool do_once; !std::exchange(do_once, true))
But if you are using this a lot, don't be fancy and create a wrapper instead:
struct Once {
bool b = true;
explicit operator bool() { return std::exchange(b, false); }
};
And use it like:
if (static Once once; once)
The variable is not supposed to be referenced outside the condition, so the name does not buy us much. Taking inspiration from other languages like Python which give a special meaning to the _ identifier, we may write:
if (static Once _; _)
Further improvements: take advantage of the BSS section (#Deduplicator), avoid the memory write when we have already run (#ShadowRanger), and give a branch prediction hint if you are going to test many times (e.g. like in the question):
// GCC, Clang, icc only; use [[likely]] in C++20 instead
#define likely(x) __builtin_expect(!!(x), 1)
struct Once {
bool b = false;
explicit operator bool()
{
if (likely(b))
return false;
b = true;
return true;
}
};
Maybe not the most elegant solution and you don't see any actual if, but the standard library actually covers this case:, see std::call_once.
#include <mutex>
std::once_flag flag;
for (int i = 0; i < 10; ++i)
std::call_once(flag, [](){ std::puts("once\n"); });
The advantage here is that this is thread safe.
C++ does have a builtin control flow primitive that consists of "(before-block; condition; after-block)" already:
for (static bool b = true; b; b = false)
Or hackier, but shorter:
for (static bool b; !b; b = !b)
However, I think any of the techniques presented here should be used with care, as they are not (yet?) very common.
In C++17 you can write
if (static int i; i == 0 && (i = 1)){
in order to avoid playing around with i in the loop body. i starts with 0 (guaranteed by the standard), and the expression after the ; sets i to 1 the first time it is evaluated.
Note that in C++11 you could achieve the same with a lambda function
if ([]{static int i; return i == 0 && (i = 1);}()){
which also carries a slight advantage in that i is not leaked into the loop body.
static bool once = [] {
std::cout << "Hello one-shot\n";
return false;
}();
This solution is thread safe (unlike many of the other suggestions).
You could wrap the one-time action in the constructor of a static object that you instantiate in place of the conditional.
Example:
#include <iostream>
#include <functional>
struct do_once {
do_once(std::function<void(void)> fun) {
fun();
}
};
int main()
{
for (int i = 0; i < 3; ++i) {
static do_once action([](){ std::cout << "once\n"; });
std::cout << "Hello World\n";
}
}
Or you may indeed stick with a macro, that may look something like this:
#include <iostream>
#define DO_ONCE(exp) \
do { \
static bool used_before = false; \
if (used_before) break; \
used_before = true; \
{ exp; } \
} while(0)
int main()
{
for (int i = 0; i < 3; ++i) {
DO_ONCE(std::cout << "once\n");
std::cout << "Hello World\n";
}
}
Like #damon said, you can avoid using std::exchange by using a decrementing integer, but you have to remember that negative values resolve to true. The way to use this would be:
if (static int n_times = 3; n_times && n_times--)
{
std::cout << "Hello world x3" << std::endl;
}
Translating this to #Acorn's fancy wrapper would look like this:
struct n_times {
int n;
n_times(int number) {
n = number;
};
explicit operator bool() {
return n && n--;
};
};
...
if(static n_times _(2); _)
{
std::cout << "Hello world twice" << std::endl;
}
While using std::exchange as suggested by #Acorn is probably the most idiomatic way, an exchange operation is not necessarily cheap. Although of course static initialization is guaranteed to be thread-safe (unless you tell your compiler not to do it), so any considerations about performance are somewhat futile anyway in presence of the static keyword.
If you are concerned about micro-optimization (as people using C++ often are), you could as well scratch bool and use int instead, which will allow you to use post-decrement (or rather, increment, as unlike bool decrementing an int will not saturate to zero...):
if(static int do_once = 0; !do_once++)
It used to be that bool had increment/decrement operators, but they were deprecated long ago (C++11? not sure?) and are to be removed altogether in C++17. Nevertheless you can decrement an int just fine, and it will of course work as a Boolean condition.
Bonus: You can implement do_twice or do_thrice similarly...
Based on #Bathsheba's great answer for this - just made it even simpler.
In C++ 17, you can simply do:
if (static int i; !i++) {
cout << "Execute once";
}
(In previous versions, just declare int i outside the block. Also works in C :) ).
In simple words: you declare i, which takes default value of zero (0).
Zero is falsey, therefore we use exclamation mark (!) operator to negate it.
We then take into account the increment property of the <ID>++ operator, which first gets processed (assigned, etc) and then incremented.
Therefore, in this block, i will be initialized and have the value 0 only once, when block gets executed, and then the value will increase. We simply use the ! operator to negate it.