diff options
author | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2012-05-28 04:39:18 +0000 |
---|---|---|
committer | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2012-05-28 04:39:18 +0000 |
commit | f278315081b24b59bf73e9613e552e3519200a71 (patch) | |
tree | cdfe0e8d00e2c3e8002284c4541429f91cb66e68 /sca-cpp/trunk/kernel/monad.hpp | |
parent | c3eb9d1e20e1f8a7a101854d6a883692cac4e8d0 (diff) |
Improve error reporting with a reason code. Improve debug and audit logging. Fix test scripts to cleanup state from previous builds and correctly report test errors.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1343138 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
-rw-r--r-- | sca-cpp/trunk/kernel/monad.hpp | 102 |
1 files changed, 67 insertions, 35 deletions
diff --git a/sca-cpp/trunk/kernel/monad.hpp b/sca-cpp/trunk/kernel/monad.hpp index b1bef7996c..657a809c1c 100644 --- a/sca-cpp/trunk/kernel/monad.hpp +++ b/sca-cpp/trunk/kernel/monad.hpp @@ -203,59 +203,63 @@ template<typename R, typename V> const maybe<R> operator>>(const maybe<V>& m, co * To get the value in the monad, just cast it to the value type. * To get the failure in the monad, cast it to the failure type. */ -template<typename V, typename F = string> class failable { +template<typename V, typename F = string, typename C = int> class failable { public: - failable() : hasv(false) { + failable() : hasv(false), c(-1) { } - failable(const V& v) : hasv(true), v(v) { + failable(const V& v) : hasv(true), v(v), c(-1) { } - failable(const failable<V, F>& m) : hasv(m.hasv), v(m.v), f(m.f) { + failable(const failable<V, F, C>& m) : hasv(m.hasv), v(m.v), f(m.f), c(m.c) { } - const failable<V, F>& operator=(const failable<V, F>& m) { + const failable<V, F, C>& operator=(const failable<V, F, C>& m) { if (&m == this) return *this; hasv = m.hasv; v = m.v; f = m.f; + c = m.c; return *this; } - const bool operator!=(const failable<V, F>& m) const { + const bool operator!=(const failable<V, F, C>& m) const { return !this->operator==(m); } - const bool operator==(const failable<V, F>& m) const { + const bool operator==(const failable<V, F, C>& m) const { if (this == &m) return true; if (!hasv) - return !m.hasv && f == m.f; + return !m.hasv && f == m.f && c == m.c; return m.hasv && v == m.v; } private: - failable(const bool hasv, const F& f) : hasv(hasv), f(f) { + failable(const bool hasv, const F& f, const C& c) : hasv(hasv), f(f), c(c) { } - template<typename A, typename B> friend const bool hasContent(const failable<A, B>& m); - template<typename A, typename B> friend const A content(const failable<A, B>& m); - template<typename A, typename B> friend const B reason(const failable<A, B>& m); - template<typename A, typename B> friend const failable<A, B> mkfailure(const B& f, const bool log); - template<typename A> friend const failable<A, string> mkfailure(); + template<typename A, typename B, typename R> friend const bool hasContent(const failable<A, B, R>& m); + template<typename A, typename B, typename R> friend const A content(const failable<A, B, R>& m); + template<typename A, typename B, typename R> friend const B reason(const failable<A, B, R>& m); + template<typename A, typename B, typename R> friend const R rcode(const failable<A, B, R>& m); + template<typename A, typename B, typename R> friend const failable<A, B, R> mkfailure(const B& f, const R& c, const bool log); + template<typename A, typename B> friend const failable<A, B> mkfailure(const B& f, const int c, const bool log); + template<typename A> friend const failable<A> mkfailure(); bool hasv; V v; F f; + C c; }; /** * Write a failable monad to a stream. */ -template<typename V, typename F> ostream& operator<<(ostream& out, const failable<V, F>& m) { +template<typename V, typename F, typename C> ostream& operator<<(ostream& out, const failable<V, F, C>& m) { if (!hasContent(m)) { - out << reason(m); + out << reason(m) << " : " << rcode(m); return out; } out << content(m); @@ -265,18 +269,18 @@ template<typename V, typename F> ostream& operator<<(ostream& out, const failabl /** * Returns a failable monad with a success value in it. */ -template<typename V, typename F> const failable<V, F> mksuccess(const V& v) { - return failable<V, F>(v); +template<typename V, typename F, typename C> const failable<V, F, C> mksuccess(const V& v) { + return failable<V, F, C>(v); } -template<typename V, typename F> const lambda<failable<V, F>(const V)> success() { - return mksuccess<V, F>; +template<typename V, typename F, typename C> const lambda<failable<V, F, C>(const V)> success() { + return mksuccess<V, F, C>; } /** * Returns a failable monad with a failure in it. */ -template<typename V, typename F> const failable<V, F> mkfailure(const F& f, const bool log = true) { +template<typename V, typename F, typename C> const failable<V, F, C> mkfailure(const F& f, const C& c, const bool log = true) { #ifdef WANT_MAINTAINER_LOG if (!log) debug(f, "failable::mkfailure"); @@ -285,57 +289,85 @@ template<typename V, typename F> const failable<V, F> mkfailure(const F& f, cons ostringstream os; os << f; if (length(str(os)) != 0) - cfailure << "failable::mkfailure" << ": " << f << endl; + cfailure << "failable::mkfailure" << ": " << f << " : " << c << endl; } - return failable<V, F>(false, f); + return failable<V, F, C>(false, f, c); } -template<typename V> const failable<V> mkfailure(const char* f, const bool log = true) { - return mkfailure<V, string>(string(f), log); +template<typename V, typename F> const failable<V, F> mkfailure(const F& f, const int c = -1, const bool log = true) { +#ifdef WANT_MAINTAINER_LOG + if (!log) + debug(f, c, "failable::mkfailure"); +#endif + if (log) { + ostringstream os; + os << f; + if (length(str(os)) != 0) + cfailure << "failable::mkfailure: " << str(os) << " : " << c << endl; + } + return failable<V, F>(false, f, c); +} + +template<typename V> const failable<V> mkfailure(const char* f, const int c = -1, const bool log = true) { + return mkfailure<V, string>(string(f), c, log); } template<typename V> const failable<V> mkfailure() { - return failable<V, string>(false, string()); + return failable<V, string>(false, string(), -1); +} + +template<typename V, typename F, typename C> const lambda<failable<V, F, C>(const V)> failure() { + return mkfailure<V, F, C>; } -template<typename V, typename F> const lambda<failable<V, F>(const V)> failure() { - return mkfailure<V, F>; +/** + * Convert a failable of a given type to a failable of another type. + */ +template<typename V, typename F, typename C, typename X> const failable<V, F, C> mkfailure(const failable<X, F, C>& f, const bool log = true) { + return mkfailure<V, F, C>(reason(f), rcode(f), log); } /** * Returns true if the monad contains a content. */ -template<typename V, typename F> const bool hasContent(const failable<V, F>& m) { +template<typename V, typename F, typename C> const bool hasContent(const failable<V, F, C>& m) { return m.hasv; } /** * Returns the content of a failable monad. */ -template<typename V, typename F> const V content(const failable<V, F>& m) { +template<typename V, typename F, typename C> const V content(const failable<V, F, C>& m) { return m.v; } /** * Returns the reason for failure of a failable monad. */ -template<typename V, typename F> const F reason(const failable<V, F>& m) { +template<typename V, typename F, typename C> const F reason(const failable<V, F, C>& m) { return m.f; } /** + * Returns the reason code for failure of a failable monad. + */ +template<typename V, typename F, typename C> const C rcode(const failable<V, F, C>& m) { + return m.c; +} + +/** * Bind a function to a failable monad. Passes the success value in the monad to the function * if present, or does nothing if there's no value and a failure instead. */ -template<typename R, typename FR, typename V, typename FV> -const failable<R, FR> operator>>(const failable<V, FV>& m, const lambda<failable<R, FR>(const V)>& f) { +template<typename R, typename FR, typename XR, typename V, typename FV, typename XV> +const failable<R, FR, XR> operator>>(const failable<V, FV, XV>& m, const lambda<failable<R, FR, XR>(const V)>& f) { if (!hasContent(m)) return m; return f(content(m)); } -template<typename R, typename FR, typename V, typename FV> -const failable<R, FR> operator>>(const failable<V, FV>& m, const failable<R, FR> (* const f)(const V)) { +template<typename R, typename FR, typename XR, typename V, typename FV, typename XV> +const failable<R, FR, XR> operator>>(const failable<V, FV, XV>& m, const failable<R, FR, XR> (* const f)(const V)) { if (!hasContent(m)) return m; return f(content(m)); |