// // SPDX-License-Identifier: BSD-3-Clause // Copyright Contributors to the OpenEXR Project. // //--------------------------------------------------------------------------- // // halfFunction -- a class for fast evaluation // of half --> T functions // // The constructor for a halfFunction object, // // halfFunction (function, // domainMin, domainMax, // defaultValue, // posInfValue, negInfValue, // nanValue); // // evaluates the function for all finite half values in the interval // [domainMin, domainMax], and stores the results in a lookup table. // For finite half values that are not in [domainMin, domainMax], the // constructor stores defaultValue in the table. For positive infinity, // negative infinity and NANs, posInfValue, negInfValue and nanValue // are stored in the table. // // The tabulated function can then be evaluated quickly for arbitrary // half values by calling the the halfFunction object's operator() // method. // // Example: // // #include // #include // // halfFunction hsin (sin); // // halfFunction hsqrt (sqrt, // function // 0, HALF_MAX, // domain // half::qNan(), // sqrt(x) for x < 0 // half::posInf(), // sqrt(+inf) // half::qNan(), // sqrt(-inf) // half::qNan()); // sqrt(nan) // // half x = hsin (1); // half y = hsqrt (3.5); // //--------------------------------------------------------------------------- #ifndef _HALF_FUNCTION_H_ #define _HALF_FUNCTION_H_ /// @cond Doxygen_Suppress #include "half.h" #include "ImathConfig.h" #ifndef IMATH_HAVE_LARGE_STACK # include // need this for memset #else #endif #include template class halfFunction { public: //------------ // Constructor //------------ template halfFunction (Function f, half domainMin = -HALF_MAX, half domainMax = HALF_MAX, T defaultValue = 0, T posInfValue = 0, T negInfValue = 0, T nanValue = 0); #ifndef IMATH_HAVE_LARGE_STACK ~halfFunction() { delete[] _lut; } halfFunction (const halfFunction&) = delete; halfFunction& operator= (const halfFunction&) = delete; halfFunction (halfFunction&&) = delete; halfFunction& operator= (halfFunction&&) = delete; #endif //----------- // Evaluation //----------- T operator() (half x) const; private: #ifdef IMATH_HAVE_LARGE_STACK T _lut[1 << 16]; #else T* _lut; #endif }; //--------------- // Implementation //--------------- template template halfFunction::halfFunction (Function f, half domainMin, half domainMax, T defaultValue, T posInfValue, T negInfValue, T nanValue) { #ifndef IMATH_HAVE_LARGE_STACK _lut = new T[1 << 16]; #endif for (int i = 0; i < (1 << 16); i++) { half x; x.setBits (i); if (x.isNan()) _lut[i] = nanValue; else if (x.isInfinity()) _lut[i] = x.isNegative() ? negInfValue : posInfValue; else if (x < domainMin || x > domainMax) _lut[i] = defaultValue; else _lut[i] = f (x); } } template inline T halfFunction::operator() (half x) const { return _lut[x.bits()]; } /// @endcond #endif