123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- // Copyright (c) 2012 Cygnus Software
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy of
- // this software and associated documentation files (the "Software"), to deal in
- // the Software without restriction, including without limitation the rights to use,
- // copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
- // Software, and to permit persons to whom the Software is furnished to do so,
- // subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in all
- // copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- // For more details see the original blog post at:
- // http://randomascii.wordpress.com/2012/04/21/exceptional-floating-point/
- #ifdef _WIN32
- #include <float.h> // For _clearfp and _controlfp_s
- //#define ENABLE_FP_EXCEPTIONS 1
- // Declare an object of this type in a scope in order to suppress
- // all floating-point exceptions temporarily. The old exception
- // state will be reset at the end.
- // From http://randomascii.wordpress.com/2012/04/21/exceptional-floating-point/
- class FPExceptionDisabler
- {
- public:
- FPExceptionDisabler()
- {
- // Retrieve the current state of the exception flags. This
- // must be done before changing them.
- _controlfp_s(&mOldValues, 0, 0);
- // Set all of the exception flags, which suppresses FP
- // exceptions on the x87 and SSE units. _MCW_EM is a bit
- // mask representing all available exception masks.
- _controlfp_s(0, _MCW_EM, _MCW_EM);
- }
- ~FPExceptionDisabler()
- {
- // Clear any pending FP exceptions. This must be done
- // prior to enabling FP exceptions since otherwise there
- // may be a 'deferred crash' as soon the exceptions are
- // enabled.
- _clearfp();
- // Reset (possibly enabling) the exception status.
- _controlfp_s(0, mOldValues, _MCW_EM);
- }
- private:
- unsigned int mOldValues;
- // Make the copy constructor and assignment operator private
- // and unimplemented to prohibit copying.
- FPExceptionDisabler(const FPExceptionDisabler&);
- FPExceptionDisabler& operator=(const FPExceptionDisabler&);
- };
- // Declare an object of this type in a scope in order to enable a
- // specified set of floating-point exceptions temporarily. The old
- // exception state will be reset at the end.
- // This class can be nested.
- // From http://randomascii.wordpress.com/2012/04/21/exceptional-floating-point/
- class FPExceptionEnabler
- {
- public:
- // Overflow, divide-by-zero, and invalid-operation are the FP
- // exceptions most frequently associated with bugs.
- FPExceptionEnabler(unsigned int enableBits = _EM_OVERFLOW |
- _EM_ZERODIVIDE | _EM_INVALID)
- {
- // Retrieve the current state of the exception flags. This
- // must be done before changing them.
- _controlfp_s(&mOldValues, 0, 0);
- // Make sure no non-exception flags have been specified,
- // to avoid accidental changing of rounding modes, etc.
- enableBits &= _MCW_EM;
- // Clear any pending FP exceptions. This must be done
- // prior to enabling FP exceptions since otherwise there
- // may be a 'deferred crash' as soon the exceptions are
- // enabled. _MCW_EM is a bit
- // mask representing all available exception masks.
- _clearfp();
- // Zero out the specified bits, leaving other bits alone.
- _controlfp_s(0, ~enableBits, enableBits);
- }
- ~FPExceptionEnabler()
- {
- // Reset the exception state.
- _controlfp_s(0, mOldValues, _MCW_EM);
- }
- private:
- unsigned int mOldValues;
- // Make the copy constructor and assignment operator private
- // and unimplemented to prohibit copying.
- FPExceptionEnabler(const FPExceptionEnabler&);
- FPExceptionEnabler& operator=(const FPExceptionEnabler&);
- };
- #endif
|