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