Oracle Coherence for C++ API
Release 3.7.1.0
E22845-01
00001 /* 00002 * lang_spec.hpp 00003 * 00004 * Copyright (c) 2000, 2011, 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_LANG_SPEC_HPP 00017 #define COH_LANG_SPEC_HPP 00018 00019 #include "coherence/lang/compatibility.hpp" 00020 00021 #include "coherence/lang/TypedHandle.hpp" 00022 #include "coherence/lang/TypedHolder.hpp" 00023 00024 COH_OPEN_NAMESPACE2(coherence,lang) 00025 00026 class Object; 00027 00028 /** 00029 * @internal 00030 * 00031 * Definition of terminal class identifier. 00032 */ 00033 template<class T = void> class COH_EXPORT_SPEC Void 00034 { 00035 protected: 00036 virtual ~Void() 00037 {} 00038 00039 public: 00040 /** 00041 * @internal 00042 * 00043 * Perform an optimistic cast from this type to the specified 00044 * type. This method is for use by the cast<T> operator. 00045 * 00046 * As this is an optimistic test it may produce false negatives, but 00047 * not false positives. A negative result should be followed up with a 00048 * dynamic_cast. 00049 * 00050 * @param pInfo the type to cast to 00051 * 00052 * @return NULL on failure, else the cast'd value represented as a 00053 * void* which is suitable for direct casting to the 00054 * corresponding type. 00055 */ 00056 virtual void* _cast(const std::type_info* /*pInfo*/) const 00057 { 00058 return NULL; 00059 } 00060 }; 00061 00062 /** 00063 * @internal 00064 * 00065 * Definition of class alias, used in Exceptions. 00066 */ 00067 template<class T> class Alias 00068 { 00069 public: 00070 typedef typename T::alias alias; 00071 }; 00072 00073 /** 00074 * @internal 00075 * 00076 * Terminal Alias. 00077 */ 00078 template<> class Alias<Void<> > 00079 { 00080 public: 00081 typedef Void<> alias; 00082 }; 00083 00084 /** 00085 * @internal 00086 * 00087 * Object Alias. 00088 */ 00089 template<> class Alias<Object> 00090 { 00091 public: 00092 typedef Void<Object> alias; 00093 }; 00094 00095 00096 /** 00097 * @internal 00098 * 00099 * Definition of individual link in chain of implemented interfaces. 00100 * 00101 * @see implements 00102 * 00103 * @author mf 2008.07.14 00104 */ 00105 template<class I, class N> class COH_EXPORT_SPEC interface_link 00106 : public virtual I, public virtual N 00107 { 00108 public: 00109 /** 00110 * @internal 00111 * 00112 * Perform an optimistic cast from this type to the specified 00113 * type. Unlike the virtual _cast which is part of class_specs, 00114 * _icast handles interfaces, and is called only by _cast and thus 00115 * doesn't need to be virtual. 00116 * 00117 * As this is an optimistic test it may produce false negatives, but 00118 * not false positives. A negative result should be followed up with a 00119 * dynamic_cast. 00120 * 00121 * @param pInfo the type to cast to 00122 * 00123 * @return NULL on failure, else the cast'd value represented as a 00124 * void* which is suitable for direct casting to the 00125 * corresponding type. 00126 */ 00127 void* _icast(const std::type_info* pInfo) const 00128 { 00129 // Perform an optimistic cast, walking across the interface links 00130 // comparing type_infos by address. This is a shallow traversal 00131 // avoiding nested interfaces. 00132 static const std::type_info* pInfoThis = &typeid(I); 00133 return pInfoThis == pInfo 00134 ? (void*) static_cast<const I*>(this) 00135 : N::_icast(pInfo); 00136 } 00137 }; 00138 00139 /** 00140 * @internal 00141 * 00142 * Terminal interface_link 00143 */ 00144 template<class I> class COH_EXPORT_SPEC interface_link<void, I> 00145 { 00146 public: 00147 void* _icast(const std::type_info* /*pInfo*/) const 00148 { 00149 return NULL; 00150 } 00151 }; 00152 00153 00154 /** 00155 * The implements template specifies a list of interfaces which a class or 00156 * interface specification derives from. Each interface will be virtually 00157 * inherited by specified class or interface. Up to sixteen interfaces are 00158 * supported, in the case where more are required, they can be specified using 00159 * an interface_link<I> chain. i.e. 00160 * 00161 * @code 00162 * implements<I1, ..., I15, interface_link<I16, interface_link<I17> > > 00163 * @endcode 00164 * 00165 * @see abstract_spec 00166 * @see class_spec 00167 * @see cloneable_spec 00168 * @see throwable_spec 00169 * @see interface_spec 00170 * 00171 * @author mf 2008.07.14 00172 */ 00173 template<class I1 = void, 00174 class I2 = void, 00175 class I3 = void, 00176 class I4 = void, 00177 class I5 = void, 00178 class I6 = void, 00179 class I7 = void, 00180 class I8 = void, 00181 class I9 = void, 00182 class I10 = void, 00183 class I11 = void, 00184 class I12 = void, 00185 class I13 = void, 00186 class I14 = void, 00187 class I15 = void, 00188 class I16 = void> 00189 class COH_EXPORT_SPEC implements 00190 { 00191 public: 00192 typedef interface_link<I1, 00193 interface_link<I2, 00194 interface_link<I3, 00195 interface_link<I4, 00196 interface_link<I5, 00197 interface_link<I6, 00198 interface_link<I7, 00199 interface_link<I8, 00200 interface_link<I9, 00201 interface_link<I10, 00202 interface_link<I11, 00203 interface_link<I12, 00204 interface_link<I13, 00205 interface_link<I14, 00206 interface_link<I15, 00207 interface_link<I16, 00208 void > > > > > > > > > > > > > > > > 00209 implements_chain; 00210 00211 typedef I1 interface_1; 00212 typedef I2 interface_2; 00213 typedef I3 interface_3; 00214 typedef I4 interface_4; 00215 typedef I5 interface_5; 00216 typedef I6 interface_6; 00217 typedef I7 interface_7; 00218 typedef I8 interface_8; 00219 typedef I9 interface_9; 00220 typedef I10 interface_10; 00221 typedef I11 interface_11; 00222 typedef I12 interface_12; 00223 typedef I13 interface_13; 00224 typedef I14 interface_14; 00225 typedef I15 interface_15; 00226 typedef I16 interface_16; 00227 }; 00228 00229 /** 00230 * The extends template indicates the parent class in a class specification. 00231 * 00232 * @see abstract_spec 00233 * @see class_spec 00234 * @see cloneable_spec 00235 * @see throwable_spec 00236 * 00237 * @author mf 2008.07.14 00238 */ 00239 template<class P = Void<>, class A = typename Alias<P>::alias > 00240 class COH_EXPORT_SPEC extends 00241 { 00242 public: 00243 /** 00244 * Marker for the actual inherited parent class. 00245 */ 00246 typedef P inherited; 00247 00248 /** 00249 * The literal inherited class. 00250 */ 00251 typedef P inherited_literal; 00252 00253 /** 00254 * The purpose of this definition is to cause a compilation error if 00255 * an attempt is made to instantiate the extends template by supplying 00256 * an interface. 00257 */ 00258 typedef typename P::super grand; 00259 00260 /** 00261 * Alias type used in throwables. 00262 */ 00263 typedef A alias; 00264 }; 00265 00266 /** 00267 * @internal 00268 * 00269 * Terminal definition in extension hierarchy. 00270 */ 00271 template<> class COH_EXPORT_SPEC extends<Void<>, Void<> > 00272 { 00273 public: 00274 typedef Void<> inherited; 00275 typedef Void<> inherited_literal; 00276 typedef Void<> alias; 00277 }; 00278 00279 // ----- helper macros used in the creation of specs ------------------------ 00280 00281 /** 00282 * The COH_LIST macros create a comma separated list of names, which each name 00283 * is the same except for a numeric suffix. 00284 */ 00285 #define COH_LIST1(A) A##1 00286 #define COH_LIST2(A) COH_LIST1 (A), A##2 00287 #define COH_LIST3(A) COH_LIST2 (A), A##3 00288 #define COH_LIST4(A) COH_LIST3 (A), A##4 00289 #define COH_LIST5(A) COH_LIST4 (A), A##5 00290 #define COH_LIST6(A) COH_LIST5 (A), A##6 00291 #define COH_LIST7(A) COH_LIST6 (A), A##7 00292 #define COH_LIST8(A) COH_LIST7 (A), A##8 00293 #define COH_LIST9(A) COH_LIST8 (A), A##9 00294 #define COH_LIST10(A) COH_LIST9 (A), A##10 00295 #define COH_LIST11(A) COH_LIST10(A), A##11 00296 #define COH_LIST12(A) COH_LIST11(A), A##12 00297 #define COH_LIST13(A) COH_LIST12(A), A##13 00298 #define COH_LIST14(A) COH_LIST13(A), A##14 00299 #define COH_LIST15(A) COH_LIST14(A), A##15 00300 #define COH_LIST16(A) COH_LIST15(A), A##16 00301 00302 /** 00303 * The COH_ARG_LIST macros create a comma separated list of argument 00304 * declarations names, which each argument name is the same except for a 00305 * numeric suffix. 00306 */ 00307 #define COH_ARG_LIST1(A) A##1& a1 00308 #define COH_ARG_LIST2(A) COH_ARG_LIST1 (A), A##2& a2 00309 #define COH_ARG_LIST3(A) COH_ARG_LIST2 (A), A##3& a3 00310 #define COH_ARG_LIST4(A) COH_ARG_LIST3 (A), A##4& a4 00311 #define COH_ARG_LIST5(A) COH_ARG_LIST4 (A), A##5& a5 00312 #define COH_ARG_LIST6(A) COH_ARG_LIST5 (A), A##6& a6 00313 #define COH_ARG_LIST7(A) COH_ARG_LIST6 (A), A##7& a7 00314 #define COH_ARG_LIST8(A) COH_ARG_LIST7 (A), A##8& a8 00315 #define COH_ARG_LIST9(A) COH_ARG_LIST8 (A), A##9& a9 00316 #define COH_ARG_LIST10(A) COH_ARG_LIST9 (A), A##10& a10 00317 #define COH_ARG_LIST11(A) COH_ARG_LIST10(A), A##11& a11 00318 #define COH_ARG_LIST12(A) COH_ARG_LIST11(A), A##12& a12 00319 #define COH_ARG_LIST13(A) COH_ARG_LIST12(A), A##13& a13 00320 #define COH_ARG_LIST14(A) COH_ARG_LIST13(A), A##14& a14 00321 #define COH_ARG_LIST15(A) COH_ARG_LIST14(A), A##15& a15 00322 #define COH_ARG_LIST16(A) COH_ARG_LIST15(A), A##16& a16 00323 00324 /** 00325 * Define a proxy constructor with N arguments. 00326 */ 00327 #define COH_DEFINE_PROXY_CONSTRUCTOR(SPEC, N) \ 00328 template<COH_LIST##N (class A)> SPEC(COH_ARG_LIST##N (A)) \ 00329 : super_spec(COH_LIST##N (a)) {} \ 00330 template<COH_LIST##N (class A)> SPEC(COH_ARG_LIST##N (const A)) \ 00331 : super_spec(COH_LIST##N (a)) {} 00332 00333 /** 00334 * Define a set of templated copy constructors. 00335 * 00336 * @param SPEC the class of which the constructors are declared 00337 */ 00338 #define COH_DEFINE_PROXY_CONSTRUCTORS(SPEC) \ 00339 SPEC() : super_spec() {} \ 00340 SPEC(const SPEC& that) : super_spec(that) {} \ 00341 COH_DEFINE_PROXY_CONSTRUCTOR(SPEC, 1) \ 00342 COH_DEFINE_PROXY_CONSTRUCTOR(SPEC, 2) \ 00343 COH_DEFINE_PROXY_CONSTRUCTOR(SPEC, 3) \ 00344 COH_DEFINE_PROXY_CONSTRUCTOR(SPEC, 4) \ 00345 COH_DEFINE_PROXY_CONSTRUCTOR(SPEC, 5) \ 00346 COH_DEFINE_PROXY_CONSTRUCTOR(SPEC, 6) \ 00347 COH_DEFINE_PROXY_CONSTRUCTOR(SPEC, 7) \ 00348 COH_DEFINE_PROXY_CONSTRUCTOR(SPEC, 8) \ 00349 COH_DEFINE_PROXY_CONSTRUCTOR(SPEC, 9) \ 00350 COH_DEFINE_PROXY_CONSTRUCTOR(SPEC, 10) \ 00351 COH_DEFINE_PROXY_CONSTRUCTOR(SPEC, 11) \ 00352 COH_DEFINE_PROXY_CONSTRUCTOR(SPEC, 12) \ 00353 COH_DEFINE_PROXY_CONSTRUCTOR(SPEC, 13) \ 00354 COH_DEFINE_PROXY_CONSTRUCTOR(SPEC, 14) \ 00355 COH_DEFINE_PROXY_CONSTRUCTOR(SPEC, 15) \ 00356 COH_DEFINE_PROXY_CONSTRUCTOR(SPEC, 16) 00357 00358 /** 00359 * Define a factory create method with N arguments. 00360 */ 00361 #define COH_DEFINE_PROXY_CREATE_METHOD(RETURN, FUNCTION, N) \ 00362 template<COH_LIST##N (class A)> static RETURN create(COH_ARG_LIST##N (A)) \ 00363 {return FUNCTION(COH_LIST##N(a));} \ 00364 template<COH_LIST##N (class A)> static RETURN create(COH_ARG_LIST##N (const A)) \ 00365 {return FUNCTION(COH_LIST##N(a));} 00366 00367 /** 00368 * Define factory "create" methods. 00369 * 00370 * @param RETURN the return type from the factory 00371 * @param FUNCTION the function to be called to produce the the RETURN 00372 */ 00373 #define COH_DEFINE_CREATE_METHODS(RETURN, FUNCTION) \ 00374 static RETURN create() {return FUNCTION();} \ 00375 COH_DEFINE_PROXY_CREATE_METHOD(RETURN, FUNCTION, 1) \ 00376 COH_DEFINE_PROXY_CREATE_METHOD(RETURN, FUNCTION, 2) \ 00377 COH_DEFINE_PROXY_CREATE_METHOD(RETURN, FUNCTION, 3) \ 00378 COH_DEFINE_PROXY_CREATE_METHOD(RETURN, FUNCTION, 4) \ 00379 COH_DEFINE_PROXY_CREATE_METHOD(RETURN, FUNCTION, 5) \ 00380 COH_DEFINE_PROXY_CREATE_METHOD(RETURN, FUNCTION, 6) \ 00381 COH_DEFINE_PROXY_CREATE_METHOD(RETURN, FUNCTION, 7) \ 00382 COH_DEFINE_PROXY_CREATE_METHOD(RETURN, FUNCTION, 8) \ 00383 COH_DEFINE_PROXY_CREATE_METHOD(RETURN, FUNCTION, 9) \ 00384 COH_DEFINE_PROXY_CREATE_METHOD(RETURN, FUNCTION, 10) \ 00385 COH_DEFINE_PROXY_CREATE_METHOD(RETURN, FUNCTION, 11) \ 00386 COH_DEFINE_PROXY_CREATE_METHOD(RETURN, FUNCTION, 12) \ 00387 COH_DEFINE_PROXY_CREATE_METHOD(RETURN, FUNCTION, 13) \ 00388 COH_DEFINE_PROXY_CREATE_METHOD(RETURN, FUNCTION, 14) \ 00389 COH_DEFINE_PROXY_CREATE_METHOD(RETURN, FUNCTION, 15) \ 00390 COH_DEFINE_PROXY_CREATE_METHOD(RETURN, FUNCTION, 16) 00391 00392 /** 00393 * The factory class auto-generates static create methods for a class, 00394 * corresponding to the class's constructors. The factory must be made a 00395 * friend of the defined class so that it may access the protected constructors. 00396 * 00397 * The factory is used by class specifications to provide the class with static 00398 * create methods. i.e. the result of using a class_spec when defining class 00399 * Foo will result in Foo having auto-generated static create methods. Direct 00400 * use of the factory for class instantiation is not supported. 00401 * 00402 * The factory supports constructors from zero to sixteen parameters. To help 00403 * the template system it is best (though not required) that there are not 00404 * multiple constructors with the same number of parameters. Classes wishing to 00405 * provide custom create methods may simply define them in their class, and 00406 * these will override and hide the factory auto-generated versions. 00407 * 00408 * @see class_spec 00409 * @see cloneable_spec 00410 * @see throwable_spec 00411 * 00412 * @author mf 2008.07.14 00413 */ 00414 template<class T> class COH_EXPORT_SPEC factory 00415 { 00416 template<class, class, class> friend class class_spec; 00417 00418 protected: 00419 /** 00420 * Generate a set of static "create" methods matching the signatures of 00421 * class T's constructors. 00422 * 00423 * NOTE: Compilation errors referencing this line likely indicate that 00424 * the parameters supplied by the caller to the create method did 00425 * not match one of the constructors. 00426 */ 00427 COH_DEFINE_CREATE_METHODS(T*, new T) 00428 }; 00429 00430 COH_CLOSE_NAMESPACE2 00431 00432 #endif // COH_LANG_SPEC_HPP