00001 /* 00002 * Copyright (c) 2000, 2020, Oracle and/or its affiliates. 00003 * 00004 * Licensed under the Universal Permissive License v 1.0 as shown at 00005 * http://oss.oracle.com/licenses/upl. 00006 */ 00007 #ifndef COH_THROWABLE_SPEC_HPP 00008 #define COH_THROWABLE_SPEC_HPP 00009 00010 #include "coherence/lang/compatibility.hpp" 00011 00012 #include "coherence/lang/class_spec.hpp" 00013 #include "coherence/lang/lang_spec.hpp" 00014 #include "coherence/lang/TypedHandle.hpp" 00015 #include "coherence/lang/TypedHolder.hpp" 00016 00017 #include <stdexcept> 00018 00019 COH_OPEN_NAMESPACE2(coherence,lang) 00020 00021 class Exception; 00022 00023 // ----- local helpers ------------------------------------------------------ 00024 00025 /** 00026 * Return an empty std::exception derivative. 00027 * 00028 * @return an empty exception. 00029 */ 00030 template<class E> inline E coh_get_default_exception() 00031 { 00032 return E(""); 00033 } 00034 00035 /** 00036 * Return an empty std::exception derivative. 00037 * @internal 00038 * 00039 * @return an empty exception. 00040 */ 00041 template<> inline std::exception coh_get_default_exception<std::exception>() 00042 { 00043 return std::exception(); 00044 } 00045 00046 /** 00047 * Return an empty std::exception derivative. 00048 * @internal 00049 * 00050 * @return an empty exception. 00051 */ 00052 template<> inline std::bad_cast coh_get_default_exception<std::bad_cast>() 00053 { 00054 return std::bad_cast(); 00055 } 00056 00057 /** 00058 * Return an empty std::exception derivative. 00059 * @internal 00060 * 00061 * @return an empty exception. 00062 */ 00063 template<> inline std::bad_typeid coh_get_default_exception<std::bad_typeid>() 00064 { 00065 return std::bad_typeid(); 00066 } 00067 00068 /** 00069 * Return an empty std::exception derivative. 00070 * @internal 00071 * 00072 * @return an empty exception. 00073 */ 00074 template<> inline std::bad_alloc coh_get_default_exception<std::bad_alloc>() 00075 { 00076 return std::bad_alloc(); 00077 } 00078 00079 /** 00080 * @internal 00081 */ 00082 template<> class Alias<Exception> 00083 { 00084 public: 00085 typedef std::exception alias; 00086 }; 00087 00088 /** 00089 * Helper for defining a throwable managed class. 00090 * 00091 * It addition to the features auto-generated by the class_spec<> helper template 00092 * throwable_spec<> auto-generates an implementation of "raise() const" 00093 * which (re)throws the exception as a View. 00094 * 00095 * A normal throwable class definition would be: 00096 * @code 00097 * class MyException 00098 * : public throwable_spec<MyException, 00099 * extends<SomeOtherException, std::exception> > 00100 * { 00101 * // add support for auto-generated static create methods 00102 * friend class factory<MyException>; 00103 * 00104 * protected: 00105 * // Constructors are defined as protected, and access via 00106 * // auto-generated create methods, with matching signatures 00107 * MyException(String::View vsMessage = String::null_string, 00108 * Exception::View vCause = NULL) 00109 * : super(vsMessage, vCause) 00110 * { 00111 * } 00112 * }; 00113 * @endcode 00114 * 00115 * The extends template class for throwables is used to define an alias 00116 * exception in the std::exception hierarchy, via a second template parameter. 00117 * When thrown the resulting throwable can be caught by its View type hierarchy 00118 * or by its std::exception hierarchy. This parameter is optional and defaults 00119 * to the alias type of the parent exception. 00120 * 00121 * @see Exception 00122 * @see extends 00123 * @see implements 00124 * 00125 * @author mf 2008.07.14 00126 */ 00127 template<class T, 00128 class E, 00129 class I = implements<>, 00130 class H = typename E::inherited::hierarchy > 00131 class throwable_spec 00132 : public class_spec<T, E, I> 00133 { 00134 // ----- typedefs ------------------------------------------------------- 00135 00136 public: 00137 /** 00138 * Specification definition 00139 */ 00140 typedef throwable_spec this_spec; 00141 00142 /** 00143 * Definition T's parent class 00144 */ 00145 typedef throwable_spec super; 00146 00147 /** 00148 * Definition of the spec's parent class 00149 */ 00150 typedef class_spec<T, E, I> super_spec; 00151 00152 /** 00153 * Alias into std::exception hierarchy 00154 */ 00155 typedef typename E::alias alias; 00156 00157 /** 00158 * View definition 00159 */ 00160 typedef typename class_spec<T, E, I>::View View; 00161 00162 // ----- nested type: hierarchy ----------------------------------------- 00163 00164 public: 00165 /** 00166 * The hierarchy class wraps the Coherence C++ Exception classes in a 00167 * object that preserves their hierarchical structure. 00168 */ 00169 class hierarchy 00170 : public View, public H 00171 { 00172 // ----- constructors --------------------------------------- 00173 00174 public: 00175 /** 00176 * Default constructor 00177 */ 00178 hierarchy() 00179 { 00180 } 00181 00182 /** 00183 * Copy constructor 00184 */ 00185 hierarchy(const hierarchy& that) 00186 : View(that), H(that) 00187 { 00188 } 00189 00190 /** 00191 * Create a new hierarchy based on a View. 00192 */ 00193 explicit hierarchy(const View& vE) 00194 : View(vE), H(vE) 00195 { 00196 } 00197 }; 00198 00199 00200 // ----- nested class: bridge ------------------------------------------- 00201 00202 public: 00203 /** 00204 * bridge joins two hierarchy types into a single type. 00205 * 00206 * The intended usage is to merge support for std exceptions into the 00207 * coherence exception hierarchy. 00208 * 00209 * @author mf 2008.05.15 00210 */ 00211 class bridge 00212 : public hierarchy, public alias 00213 { 00214 // ----- constructors --------------------------------------- 00215 00216 public: 00217 /** 00218 * Construct a bridge with a specific object. 00219 * 00220 * @param vEx A view to the object this bridge should contain 00221 */ 00222 bridge(const View &vEx) 00223 : hierarchy(vEx), alias(coh_get_default_exception<alias>()) 00224 { 00225 } 00226 00227 /** 00228 * Copy constructor. 00229 * 00230 * @param that The hierarchyBase to copy. 00231 */ 00232 bridge(const bridge& that) 00233 : hierarchy(that), alias(that) 00234 { 00235 } 00236 00237 /** 00238 * Destructor. 00239 */ 00240 virtual ~bridge() throw() 00241 { 00242 } 00243 00244 00245 // ----- std::exception interface --------------------------- 00246 00247 public: 00248 /** 00249 * Returns a C-style character string describing the general 00250 * cause of the current error. 00251 * 00252 * Note: The memory for the returned array is managed by the 00253 * referenced Exception and is only valid for the 00254 * lifetime of the Exception. 00255 * 00256 * @return the C-style character string describing the general 00257 * cause of the current error. 00258 */ 00259 virtual const char* what() const throw() 00260 { 00261 return ((View)(*this)) 00262 ->getDescription()->getCString(); 00263 } 00264 }; 00265 00266 // ----- constructors --------------------------------------------------- 00267 00268 protected: 00269 /** 00270 * Generate a set of proxy constructors matching the signatures of the 00271 * parent class's constructors. 00272 * 00273 * NOTE: Compilation errors referencing this line likely indicate that 00274 * class being defined by this spec makes calls a "super" 00275 * constructor supplying a set of parameters for which there is 00276 * no exact match on the parent class. 00277 */ 00278 COH_DEFINE_PROXY_CONSTRUCTORS(throwable_spec) 00279 00280 public: 00281 /** 00282 * @inheritDoc 00283 */ 00284 virtual void raise() const 00285 { 00286 throw bridge(static_cast<const T*>(this)); 00287 } 00288 }; 00289 00290 COH_CLOSE_NAMESPACE2 00291 00292 #endif // COH_THROWABLE_SPEC_HPP