Constrain function port from Arduino

14,790

Solution 1

Here a template-version, including a complete program to demonstrate the use (you should be able to copy and paste that):

#include <iostream>

template<class T>
const T& constrain(const T& x, const T& a, const T& b) {
    if(x < a) {
        return a;
    }
    else if(b < x) {
        return b;
    }
    else
        return x;
}

int main() {
    int value = 10;
    std::cout << constrain(value, 5, 20) << "\n"      // prints "10"
              << constrain(value, 15, 20) << "\n"     // prints "15"
              << constrain(value, 5, 9) << std::endl; // prints "9"
}

This can be used for any type that has an operator< (this includes all built-in numeric types, such as int and float).

Solution 2

For Arduino, constrain is not a function, it is a #define'd macro.

It is defined in Arduino.h within the Arduino IDE.

Arduino source code is released under an Open Source license, so you can read it :-)

It's definition is:

#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))

Which would continue to work in your port to stm32.

Of course, it is a macro, and so is simply a text replacement. Hence the parameters appear in your source code, so their is no new type information.

You may prefer to use functions rather than macros, but as your code is a port of existing code, it may be simpler to continue to use the macro. Then, if the original code is improved or changed, there should be less work to produce a new port.

A small issue about trying to use typed functions, or a template functions, rather than a macro, is it may cause confusion later. Using functions rather than the macro might create new warnings, errors or bugs to be introduced if you try to port any Arduino code. Specifically if the original code uses types or classes to constrain for which you have no matching function, there will be an error which clearly does not exist in the Arduino source. Or worse, a typed or templated function might trigger some C++ type conversions which do not happen in the macro version. You might leave a small 'gotcha' for yourself, or whoever takes on your code in the future.

Solution 3

Looking at Wikipedia under Clamping (graphics), it looks like you could have a type-independent template?

template<typename T>
T clamp(T Value, T Min, T Max)
{
  return (Value < Min)? Min : (Value > Max)? Max : Value;
}
Share:
14,790
SevenDays
Author by

SevenDays

iOS Developer

Updated on June 04, 2022

Comments

  • SevenDays
    SevenDays almost 2 years

    I'm now porting arduino code to stm32(c/c++). Please help me with this function:

    constrain(x, a, b)
    

    Returns

    x: if x is between a and b

    a: if x is less than a

    b: if x is greater than b

    Example

    sensVal = constrain(sensVal, 10, 150);
    
    // limits range of sensor values to between 10 and 150