summaryrefslogtreecommitdiff
path: root/src/cxpp11_common.hpp
diff options
context:
space:
mode:
authorIvan Shapovalov <intelfx@intelfx.name>2016-10-22 05:14:19 +0300
committerIvan Shapovalov <intelfx@intelfx.name>2016-10-22 08:45:25 +0300
commitb98af44fcf89b9946e1de438b1f5527e6bf28905 (patch)
treefbd5ec2ab1e418830b88e5de42279845911ea0da /src/cxpp11_common.hpp
parent5d03d48f7aaf38d3b28bad612638d2d9db8ebee0 (diff)
treewide: use C++ exceptions properly
Since the codebase is designed around proper C++ idioms such as RAII, it makes sense to only use C++ exceptions internally instead of mixing exceptions and error codes. The exceptions are now caught at top level to preserve compatibility with the existing error code-based API. Note that we deliberately do not catch C++ runtime errors (such as `std::bad_alloc`) nor logic errors (aka failed assertions) because no actual handling can ever happen for such errors. However, in the C interface we do catch _all_ exceptions (...) and convert them into a wild-card error code.
Diffstat (limited to 'src/cxpp11_common.hpp')
-rw-r--r--src/cxpp11_common.hpp87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/cxpp11_common.hpp b/src/cxpp11_common.hpp
new file mode 100644
index 00000000..c164ec1d
--- /dev/null
+++ b/src/cxpp11_common.hpp
@@ -0,0 +1,87 @@
+#ifndef CLBLAST_CXPP11_COMMON_H_
+#define CLBLAST_CXPP11_COMMON_H_
+
+// C++
+#include <string> // std::string
+#include <stdexcept> // std::runtime_error
+
+namespace clblast {
+// =================================================================================================
+
+// Basic exception class: represents an error happened inside our code
+// (as opposed to an error in C++ runtime)
+template <typename Base>
+class Error : public Base {
+ public:
+ using Base::Base;
+};
+
+// =================================================================================================
+
+// Represents a generic device-specific runtime error (returned by an OpenCL or CUDA API function)
+class DeviceError : public Error<std::runtime_error> {
+ public:
+ using Error<std::runtime_error>::Error;
+
+ static std::string TrimCallString(const char *where) {
+ const char *paren = strchr(where, '(');
+ if (paren) {
+ return std::string(where, paren);
+ } else {
+ return std::string(where);
+ }
+ }
+};
+
+// =================================================================================================
+
+// Represents a generic runtime error (aka environmental problem)
+class RuntimeError : public Error<std::runtime_error> {
+ public:
+ explicit RuntimeError(const std::string &reason):
+ Error("Run-time error: " + reason) {
+ }
+};
+
+// =================================================================================================
+
+// Represents a generic logic error (aka failed assertion)
+class LogicError : public Error<std::logic_error> {
+ public:
+ explicit LogicError(const std::string &reason):
+ Error("Internal logic error: " + reason) {
+ }
+};
+
+// =================================================================================================
+
+// Internal exception base class with a status field and a subclass-specific "details" field
+// which can be used to recreate an exception
+template <typename Base, typename Status>
+class ErrorCode : public Base {
+ public:
+ ErrorCode(Status status, const std::string &details, const std::string &reason):
+ Base(reason),
+ status_(status),
+ details_(details) {
+ }
+
+ Status status() const {
+ return status_;
+ }
+
+ const std::string& details() const {
+ return details_;
+ }
+
+ private:
+ const Status status_;
+ const std::string details_;
+};
+
+// =================================================================================================
+
+} // namespace clblast
+
+// CLBLAST_CXPP11_COMMON_H_
+#endif