#ifndef ICL_CLIPPED_CAST_H #define ICL_CLIPPED_CAST_H #include namespace icl{ /// clips a value into the range [tMin,tMax] \ingroup GENERAL template inline T clip(T tX, T tMin, T tMax){ return tX < tMin ? tMin : tX > tMax ? tMax : tX; } template inline bool is_float_type(){ return false; } /** \cond */ template<> inline bool is_float_type() { return true; } template<> inline bool is_float_type() { return true; } /** \endcond */ /// utility cast function wrapping the standard lib's numerical_limits template template inline D clipped_cast(S src){ if(is_float_type()){ //hopefully this is const enough for optimize this expresseion out return src < -std::numeric_limits::max() ? -std::numeric_limits::max() : src > std::numeric_limits::max() ? std::numeric_limits::max() : static_cast(src); }else{ return src < std::numeric_limits::min() ? std::numeric_limits::min() : src > std::numeric_limits::max() ? std::numeric_limits::max() : static_cast(src); } } /** \cond */ /// specializations for all buildin data types #define SPECIALISE_CLIPPED_CAST(T) template<> inline T clipped_cast(T t) { return t; } SPECIALISE_CLIPPED_CAST(int) SPECIALISE_CLIPPED_CAST(unsigned int) SPECIALISE_CLIPPED_CAST(char) SPECIALISE_CLIPPED_CAST(unsigned char) SPECIALISE_CLIPPED_CAST(short) SPECIALISE_CLIPPED_CAST(unsigned short) SPECIALISE_CLIPPED_CAST(long) SPECIALISE_CLIPPED_CAST(unsigned long) SPECIALISE_CLIPPED_CAST(bool) SPECIALISE_CLIPPED_CAST(float) SPECIALISE_CLIPPED_CAST(double) #undef SPECIALISE_CLIPPED_CAST /** \endcond */ } #endif