codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
// Sample: sink all exceptions in one place and translate to return code // Author: Mateusz Loskot <mateusz at loskot dot net> #include <cassert> #include <exception> #include <iostream> #include <stdexcept> template <typename T> inline T const& handle_exception(char const* const who, T const& rc) { try { throw; } catch (int e) { std::cerr << who << " caught int: " << e << std::endl; } catch (char const* e) { std::cerr << who << " caught c-string: " << e << std::endl; } catch (std::exception const& e) { std::cerr << who << " caught std::exception: " << e.what() << std::endl; } return rc; } #define EXCEPTION_TRY() \ try { #define EXCEPTION_CATCH_AND_RETURN(success, failure) \ } catch (...) { \ return handle_exception(__FUNCTION__, failure); \ } \ return success; #define EXCEPTION_CATCH_AND_EXIT() \ } catch (...) { handle_exception(__FUNCTION__, false); return; } template <typename T> class number { public: // public ctor, may throw number(T value) : value_(value) { if (value != value) throw "value is NaN"; } // public save division, never throws, bool divide_s(double& result, T const& den) const { EXCEPTION_TRY() result = divide_(value_, den); EXCEPTION_CATCH_AND_RETURN(true, false) } private: T value_; // used internally by other private methods, allowed to throw double divide_(T const& num, T const& den) const { if (den > 0) { return num / den; } throw std::invalid_argument("denominator is zero"); } }; // C wrapper is not allowed to throw exceptions double divide_numbers(double num, double den) { EXCEPTION_TRY() number<double> n(num); double r = 0; n.divide_s(r, den); EXCEPTION_CATCH_AND_RETURN(true, false) } int main() { bool success(false); double result(0); // Using C++ interface { number<int> n(10); // no error logged success = n.divide_s(result, 2); assert(success); // error logged, flag returned success = n.divide_s(result, 0); assert(!success); } // Using C interface { // no error logged result = divide_numbers(10, 2); // error logged result = divide_numbers(10, 0); // error logged float nan = 0; result = divide_numbers(nan / 0, 10); } }
Private
[
?
]
Run code
Submit