136. Generic Range Clamping

#include <iostream>
#include <iomanip>

// Function Template Definition
template <typename T>
T clamp_value(T val, T min, T max) {
    if (val < min) {
        return min;
    } else if (val > max) {
        return max;
    } else {
        return val;
    }
}

int main() {
    int N;
    if (!(std::cin >> N)) return 0;

    for (int i = 0; i < N; ++i) {
        char type_code;
        std::cin >> type_code;

        if (type_code == 'i') {
            int val, min, max;
            std::cin >> val >> min >> max;
            
            // Implicit template instantiation for int
            std::cout << "Result: " << clamp_value(val, min, max) << std::endl;
            
        } else if (type_code == 'f') {
            float val, min, max;
            std::cin >> val >> min >> max;
            
            // Implicit template instantiation for float
            // Formatting output to show 1 decimal place (e.g. 10.0)
            std::cout << "Result: " << std::fixed << std::setprecision(1) 
                      << clamp_value(val, min, max) << std::endl;
        }
    }
    return 0;
}

Explanation & Logic Summary: 

Legacy C code often uses preprocessor macros like #define CLAMP(x, low, high) ... to limit values. This is dangerous because macros are not type-safe and can cause "double evaluation" (e.g., if x is i++).

The solution uses a C++ Function Template:

  • template <typename T> tells the compiler that T is a placeholder for a data type.
  • When clamp_value is called with integers, the compiler generates a version of the function where T is int.
  • When called with floats, it generates a separate version where T is float.
  • The logic val < min ? min : (val > max ? max : val) is applied generically to any type that supports comparison operators.

Firmware Relevance & Real-World Context:

  • Actuator Limits: Servo motors often accept pulse widths between 1000us and 2000us. Sending 3000us might strip the gears. A clamp function ensures commands stay within physical hardware limits.
  • PID Controllers: The output of a PID control loop (often float) must be clamped to the range of the DAC or PWM register (often uint16_t or uint8_t) before conversion.
  • Type Safety: Using templates ensures that you don't accidentally compare a signed integer to an unsigned limit in a way that causes wrap-around bugs.

 

 

 

 

 

Loading...

Input

4 i 100 0 255 i 300 0 255 f 12.5 0.0 10.0 f -5.0 -10.0 0.0

Expected Output

Result: 100 Result: 255 Result: 10.0 Result: -5.0