Oracle Coherence for C++ API
Release 3.7.1.0
E22845-01
00001 /* 00002 * TypedMethod.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_TYPED_METHOD_HPP 00017 #define COH_TYPED_METHOD_HPP 00018 00019 #include "coherence/lang/compatibility.hpp" 00020 00021 #include "coherence/lang/BoxHandle.hpp" 00022 #include "coherence/lang/IllegalArgumentException.hpp" 00023 #include "coherence/lang/Method.hpp" 00024 #include "coherence/lang/SystemClassLoader.hpp" 00025 #include "coherence/lang/class_spec.hpp" 00026 00027 #include "coherence/lang/Boolean.hpp" 00028 #include "coherence/lang/Octet.hpp" 00029 #include "coherence/lang/Character16.hpp" 00030 #include "coherence/lang/Integer16.hpp" 00031 #include "coherence/lang/Integer32.hpp" 00032 #include "coherence/lang/Integer64.hpp" 00033 #include "coherence/lang/Size32.hpp" 00034 #include "coherence/lang/Size64.hpp" 00035 #include "coherence/lang/Float32.hpp" 00036 #include "coherence/lang/Float64.hpp" 00037 #include "coherence/lang/String.hpp" 00038 00039 00040 COH_OPEN_NAMESPACE2(coherence,lang) 00041 00042 namespace 00043 { 00044 // ----- internal helpers ----------------------------------------------- 00045 00046 // the following templates are used by TypedMethod to produce specialized 00047 // variants of methods in order to account for "void" parameters 00048 00049 /** 00050 * @internal 00051 */ 00052 template<class A> Method::ClassView coh_getMethodArgumentType() 00053 { 00054 return SystemClassLoader::getInstance()->loadByType(typeid(typename A::ValueType)); 00055 } 00056 00057 /** 00058 * @internal 00059 */ 00060 template<> Method::ClassView coh_getMethodArgumentType<void>() 00061 { 00062 return NULL; 00063 } 00064 00065 /** 00066 * @internal 00067 */ 00068 template<class H> int32_t coh_getMethodModifiers() 00069 { 00070 return Method::modifier_instance | 00071 (constness<typename H::ValueType>::applied 00072 ? Method::modifier_const 00073 : Method::modifier_mutable); 00074 } 00075 00076 /** 00077 * @internal 00078 */ 00079 template<> int32_t coh_getMethodModifiers<void>() 00080 { 00081 return Method::modifier_static; 00082 } 00083 00084 /** 00085 * @internal 00086 */ 00087 template<class H, class P, class R, class A1, class A2, class A3, class A4, 00088 class A5, class A6, class A7, class A8> 00089 class coh_invoker 00090 { 00091 public: 00092 static Object::Holder invoke(Object::Holder oh, P p, ObjectArray::View va) 00093 { 00094 COH_ENSURE_PARAM_RELATION(va->length, ==, 3); 00095 return R((*cast<H>(oh).*(p))(cast<A1>(va[0]), cast<A2>(va[1]), 00096 cast<A3>(va[2]), cast<A4>(va[3]), cast<A5>(va[4]), 00097 cast<A6>(va[5]), cast<A7>(va[6]), cast<A8>(va[7]))); 00098 } 00099 }; 00100 } 00101 00102 /** 00103 * TypedMethod provides a template based implementation for building Methods 00104 * which delegate to member function pointers. 00105 * 00106 * Rather then making direct use of this class it is recommended to utilize 00107 * the following helper macros. For each of these methods there are nine 00108 * variants suffixed 0..8 which indicate the number of arguments the method 00109 * takes. 00110 * 00111 * - COH_CONSTRUCTOR defines a Method representing a constructor 00112 * - COH_METHOD defines a Method representing an instance method 00113 * - COH_STATIC_METHOD defines a Method representing a static method 00114 * - COH_MANAGED_METHOD defines a Method representing an instance on a 00115 * Managed<> class 00116 * 00117 * - COH_OVERLOADED_CONSTRUCTOR defines an overloaded constructor 00118 * - COH_OVERLOADED_METHOD defines an overloaded instance method 00119 * - COH_OVERLOADED_STATIC_METHOD defines an overloaded static method 00120 * 00121 * Additionally the following macros will create setter and getter Methods 00122 * for a "property". 00123 * 00124 * - COH_PROPERTY defines setter/getter for a object property 00125 * - COH_BOX_PROPERTY defines a setter/getter for a value type property 00126 * - COH_MANAGED_PROPERTY defines a setter/getter for a value type on a 00127 * Managed<> class 00128 * 00129 * These macros output Method objects which can then be registered with 00130 * their corresponding Class object. This registration can either be 00131 * performed as part of the Class registration, or it can be done in multiple 00132 * COH_REGISTER_METHOD blocks, allowing the Method definition to reside 00133 * next to the actual method implementation. 00134 * 00135 * @code 00136 * // Person.hpp 00137 * class Person 00138 * : public class_spec<Person> 00139 * { 00140 * friend class factory<Person>; 00141 * 00142 * protected: 00143 * Person(String::View vsName = String::null_string, int32_t nAge = 0); 00144 * 00145 * public: 00146 * virtual void setName(String::View vsName); 00147 * virtual String::View getName() const; 00148 * 00149 * virtual void setAge(int32_t nAge); 00150 * virtual int32_t getAge() const; 00151 * ... 00152 * }; 00153 * @endcode 00154 * 00155 * @code 00156 * // Person.cpp - using single class registration block 00157 * 00158 * COH_REGISTER_CLASS(TypedClass<Person>::create() 00159 * ->declare(COH_CONSTRUCTOR2(Person, String::View, BoxHandle<const Integer32>)) 00160 * ->declare(COH_PROPERTY(Person, Name, String::View)) 00161 * ->declare(COH_BOX_PROPERTY(Person, Age, Integer32::View)); 00162 * @endcode 00163 * 00164 * @code 00165 * // Person.cpp - using multi method registration blocks 00166 * 00167 * COH_REGISTER_TYPED_CLASS(Person); 00168 * 00169 * Person::Person(String::View vsName, int32_t nAge) 00170 * { 00171 * ... 00172 * } 00173 * COH_REGISTER_METHOD(Person, COH_CONSTRUCTOR2(Person, String::View, BoxHandle<const Integer32>)); 00174 * 00175 * void Person::setName(String::View vsName) 00176 * { 00177 * ... 00178 * } 00179 * COH_REGISTER_METHOD(Person, COH_METHOD1(void, Person::Handle, setName, String::View)); 00180 * 00181 * String::View Person::getName() const 00182 * { 00183 * ... 00184 * } 00185 * COH_REGISTER_METHOD(Person, COH_METHOD0(String::View, Person::View, getName)); 00186 * 00187 * void Person::setAge(int32_t nAge) 00188 * { 00189 * ... 00190 * } 00191 * COH_REGISTER_METHOD(Person, COH_METHOD1(void, Person::Handle, setName, BoxHandle<const Integer32>)); 00192 * 00193 * int32_t Person::getAge() const 00194 * { 00195 * ... 00196 * } 00197 * COH_REGISTER_METHOD(Person, COH_METHOD0(BoxHandle<const Integer32>, Person::View, getName)); 00198 * @endcode 00199 * 00200 * @author mf 2011.02.28 00201 * 00202 * @since Coherence 3.7.1 00203 */ 00204 template<class P, class R, class C, class H, P M, 00205 class A1 = void, class A2 = void, class A3 = void, class A4 = void, 00206 class A5 = void, class A6 = void, class A7 = void, class A8 = void> 00207 class TypedMethod 00208 : public class_spec<TypedMethod<P, R, C, H, M, A1, A2, A3, A4, A5, A6, A7, A8>, 00209 extends<Method> > 00210 { 00211 friend class factory<TypedMethod<P, R, C, H, M, A1, A2, A3, A4, A5, A6, A7, A8> >; 00212 00213 // ----- constructors --------------------------------------------------- 00214 00215 protected: 00216 /** 00217 * Construct a TypedMethod. 00218 * 00219 * @param vsName the method name 00220 */ 00221 TypedMethod(String::View vsName) 00222 : class_spec<TypedMethod<P, R, C, H, M, A1, A2, A3, A4, A5, A6, A7, A8>, 00223 extends<Method> >(vsName) 00224 { 00225 } 00226 00227 00228 // ----- Method interface ----------------------------------------------- 00229 00230 public: 00231 /** 00232 * {@inheritDoc} 00233 */ 00234 virtual int32_t getModifiers() const 00235 { 00236 return coh_getMethodModifiers<H>(); 00237 } 00238 00239 /** 00240 * {@inheritDoc} 00241 */ 00242 virtual ObjectArray::View getParameterTypes() const 00243 { 00244 ObjectArray::Handle ha = 00245 typeid(A1) == typeid(void) ? ObjectArray::create(0) 00246 : typeid(A2) == typeid(void) ? ObjectArray::create(1) 00247 : typeid(A3) == typeid(void) ? ObjectArray::create(2) 00248 : typeid(A4) == typeid(void) ? ObjectArray::create(3) 00249 : typeid(A5) == typeid(void) ? ObjectArray::create(4) 00250 : typeid(A6) == typeid(void) ? ObjectArray::create(5) 00251 : typeid(A7) == typeid(void) ? ObjectArray::create(6) 00252 : typeid(A8) == typeid(void) ? ObjectArray::create(7) 00253 : ObjectArray::create(8); 00254 00255 switch (ha->length) 00256 { 00257 case 8: 00258 ha[7] = coh_getMethodArgumentType<A8>(); 00259 case 7: 00260 ha[6] = coh_getMethodArgumentType<A7>(); 00261 case 6: 00262 ha[5] = coh_getMethodArgumentType<A6>(); 00263 case 5: 00264 ha[4] = coh_getMethodArgumentType<A5>(); 00265 case 4: 00266 ha[3] = coh_getMethodArgumentType<A4>(); 00267 case 3: 00268 ha[2] = coh_getMethodArgumentType<A3>(); 00269 case 2: 00270 ha[1] = coh_getMethodArgumentType<A2>(); 00271 case 1: 00272 ha[0] = coh_getMethodArgumentType<A1>(); 00273 case 0: 00274 break; 00275 default: 00276 coh_throw_illegal_state("unsupported method parameter count"); 00277 } 00278 00279 return ha; 00280 } 00281 00282 /** 00283 * {@inheritDoc} 00284 */ 00285 virtual Method::ClassView getReturnType() const 00286 { 00287 return coh_getMethodArgumentType<R>(); 00288 } 00289 00290 /** 00291 * {@inheritDoc} 00292 */ 00293 virtual Method::ClassView getDeclaringClass() const 00294 { 00295 return SystemClassLoader::getInstance()->loadByType(typeid(C)); 00296 } 00297 00298 /** 00299 * {@inheritDoc} 00300 */ 00301 virtual Object::Holder invoke(Object::Holder oh, ObjectArray::View vaArgs) const 00302 { 00303 if (typeid(H) == typeid(void) && oh != NULL && 00304 !instanceof<typename C::View>(oh)) 00305 { 00306 coh_throw_illegal_argument("oh must be NULL or of correct type"); 00307 } 00308 return coh_invoker<H, P, R, A1, A2, A3, A4, A5, A6, A7, A8>::invoke(oh, M, vaArgs); 00309 } 00310 }; 00311 00312 // ----- coh_invoker specializations ---------------------------------------- 00313 00314 namespace 00315 { 00316 // the following macros create specialized variants of the coh_invoker in 00317 // order to support 1-7 parameters 00318 #define COH_INVOKER(N, HH, RR, AA1, AA2, AA3, AA4, AA5, AA6, AA7, AA8, EXEC) \ 00319 class coh_invoker<HH, P, RR, AA1, AA2, AA3, AA4, AA5, AA6, AA7, AA8> \ 00320 { \ 00321 public: \ 00322 static Object::Holder invoke(Object::Holder oh, P p, ObjectArray::View va) \ 00323 { \ 00324 if (!(N == 0 && va == NULL)) \ 00325 { \ 00326 COH_ENSURE_PARAM_RELATION(va->length, ==, N); \ 00327 } \ 00328 Object::Holder ohSunProWantsItToGetUsed = oh; \ 00329 Object::Holder r; \ 00330 EXEC; \ 00331 return r; \ 00332 } \ 00333 } 00334 00335 #define COH_A0 00336 #define COH_A1 COH_A0, class A1 00337 #define COH_A2 COH_A1, class A2 00338 #define COH_A3 COH_A2, class A3 00339 #define COH_A4 COH_A3, class A4 00340 #define COH_A5 COH_A4, class A5 00341 #define COH_A6 COH_A5, class A6 00342 #define COH_A7 COH_A6, class A7 00343 00344 #define COH_DEF_METHOD_TEMPLATE(N, RT) template<class H, class P, class RT COH_A##N> 00345 #define COH_DEF_METHOD_TEMPLATE_VOID(N) template<class H, class P COH_A##N> 00346 #define COH_DEF_STATIC_METHOD_TEMPLATE(N, RT) template<class P, class RT COH_A##N> 00347 #define COH_DEF_STATIC_METHOD_TEMPLATE_VOID(N) template<class P COH_A##N> 00348 00349 #define COH_DEF_ARGS0 00350 #define COH_DEF_ARGS1 COH_DEF_ARGS0 cast<A1>(va[0]) 00351 #define COH_DEF_ARGS2 COH_DEF_ARGS1, cast<A2>(va[1]) 00352 #define COH_DEF_ARGS3 COH_DEF_ARGS2, cast<A3>(va[2]) 00353 #define COH_DEF_ARGS4 COH_DEF_ARGS3, cast<A4>(va[3]) 00354 #define COH_DEF_ARGS5 COH_DEF_ARGS4, cast<A5>(va[4]) 00355 #define COH_DEF_ARGS6 COH_DEF_ARGS5, cast<A6>(va[5]) 00356 #define COH_DEF_ARGS7 COH_DEF_ARGS6, cast<A7>(va[6]) 00357 00358 #define COH_INSTANCE_METHOD *cast<H>(oh).*(p) 00359 #define COH_STATIC_METHOD *(p) 00360 00361 #define COH_DEF_EXEC(N, MS, RS) RS((MS)(COH_DEF_ARGS##N)); 00362 00363 #define COH_DEF_INVOKER0(RT, HH, MS, RS) COH_INVOKER(0, HH, RT, void, void, void, void, void, void, void, void, COH_DEF_EXEC(0, MS, RS)) 00364 #define COH_DEF_INVOKER1(RT, HH, MS, RS) COH_INVOKER(1, HH, RT, A1, void, void, void, void, void, void, void, COH_DEF_EXEC(1, MS, RS)) 00365 #define COH_DEF_INVOKER2(RT, HH, MS, RS) COH_INVOKER(2, HH, RT, A1, A2, void, void, void, void, void, void, COH_DEF_EXEC(2, MS, RS)) 00366 #define COH_DEF_INVOKER3(RT, HH, MS, RS) COH_INVOKER(3, HH, RT, A1, A2, A3, void, void, void, void, void, COH_DEF_EXEC(3, MS, RS)) 00367 #define COH_DEF_INVOKER4(RT, HH, MS, RS) COH_INVOKER(4, HH, RT, A1, A2, A3, A4, void, void, void, void, COH_DEF_EXEC(4, MS, RS)) 00368 #define COH_DEF_INVOKER5(RT, HH, MS, RS) COH_INVOKER(5, HH, RT, A1, A2, A3, A4, A5, void, void, void, COH_DEF_EXEC(5, MS, RS)) 00369 #define COH_DEF_INVOKER6(RT, HH, MS, RS) COH_INVOKER(6, HH, RT, A1, A2, A3, A4, A5, A6, void, void, COH_DEF_EXEC(6, MS, RS)) 00370 #define COH_DEF_INVOKER7(RT, HH, MS, RS) COH_INVOKER(7, HH, RT, A1, A2, A3, A4, A5, A6, A7, void, COH_DEF_EXEC(7, MS, RS)) 00371 00372 #define COH_DEF_METHOD(N) \ 00373 COH_DEF_METHOD_TEMPLATE(N, R) COH_DEF_INVOKER##N(R, H, COH_INSTANCE_METHOD, r = R); \ 00374 COH_DEF_METHOD_TEMPLATE_VOID(N) COH_DEF_INVOKER##N(void, H, COH_INSTANCE_METHOD, ;); \ 00375 COH_DEF_STATIC_METHOD_TEMPLATE(N, R) COH_DEF_INVOKER##N(R, void, COH_STATIC_METHOD, r = R); \ 00376 COH_DEF_STATIC_METHOD_TEMPLATE_VOID(N) COH_DEF_INVOKER##N(void, void, COH_STATIC_METHOD, ;) 00377 00378 COH_DEF_METHOD(0); 00379 COH_DEF_METHOD(1); 00380 COH_DEF_METHOD(2); 00381 COH_DEF_METHOD(3); 00382 COH_DEF_METHOD(4); 00383 COH_DEF_METHOD(5); 00384 COH_DEF_METHOD(6); 00385 COH_DEF_METHOD(7); 00386 00387 #undef COH_DEF_METHOD 00388 #undef COH_DEF_INVOKER0 00389 #undef COH_DEF_INVOKER1 00390 #undef COH_DEF_INVOKER2 00391 #undef COH_DEF_INVOKER3 00392 #undef COH_DEF_INVOKER4 00393 #undef COH_DEF_INVOKER5 00394 #undef COH_DEF_INVOKER6 00395 #undef COH_DEF_INVOKER7 00396 #undef COH_DEF_EXEC 00397 #undef COH_STATIC_METHOD 00398 #undef COH_INSTANCE_METHOD 00399 00400 #undef COH_DEF_ARGS0 00401 #undef COH_DEF_ARGS1 00402 #undef COH_DEF_ARGS2 00403 #undef COH_DEF_ARGS3 00404 #undef COH_DEF_ARGS4 00405 #undef COH_DEF_ARGS5 00406 #undef COH_DEF_ARGS6 00407 #undef COH_DEF_ARGS7 00408 00409 #undef COH_DEF_METHOD_TEMPLATE 00410 #undef COH_DEF_METHOD_TEMPLATE_VOID 00411 #undef COH_DEF_STATIC_METHOD_TEMPLATE 00412 #undef COH_DEF_STATIC_METHOD_TEMPLATE_VOID 00413 00414 #undef COH_A0 00415 #undef COH_A1 00416 #undef COH_A2 00417 #undef COH_A3 00418 #undef COH_A4 00419 #undef COH_A5 00420 #undef COH_A6 00421 #undef COH_A7 00422 00423 #undef COH_INVOKER 00424 00425 /** 00426 * @internal 00427 */ 00428 template<class C, class H> 00429 class coh_type_info 00430 { 00431 public: typedef H type; 00432 }; 00433 00434 /** 00435 * @internal 00436 */ 00437 template<class C> 00438 class coh_type_info<C, BoxHandle<C> > 00439 { 00440 public: typedef typename C::BoxedType type; 00441 }; 00442 00443 /** 00444 * @internal 00445 */ 00446 template<class C> 00447 class coh_type_info<C, BoxHandle<const C> > 00448 { 00449 public: typedef typename C::BoxedType type; 00450 }; 00451 00452 // for compilers (SunPro) which have trouble with the above partial 00453 // specializations we provide more specific versions 00454 #define COH_BOX_TYPE_INFO(T) \ 00455 template<> \ 00456 class coh_type_info<T, BoxHandle<T> > \ 00457 { \ 00458 public: typedef T::BoxedType type; \ 00459 }; \ 00460 template<> \ 00461 class coh_type_info<const T, BoxHandle<const T> > \ 00462 { \ 00463 public: typedef T::BoxedType type; \ 00464 } 00465 00466 COH_BOX_TYPE_INFO(Boolean); 00467 COH_BOX_TYPE_INFO(Octet); 00468 COH_BOX_TYPE_INFO(Character16); 00469 COH_BOX_TYPE_INFO(Integer16); 00470 COH_BOX_TYPE_INFO(Integer32); 00471 COH_BOX_TYPE_INFO(Integer64); 00472 COH_BOX_TYPE_INFO(Size32); 00473 COH_BOX_TYPE_INFO(Size64); 00474 COH_BOX_TYPE_INFO(Float32); 00475 COH_BOX_TYPE_INFO(Float64); 00476 COH_BOX_TYPE_INFO(String); 00477 00478 /** 00479 * @internal 00480 */ 00481 template<class H> 00482 class coh_handle_info 00483 { 00484 public: typedef typename coh_type_info<typename H::ValueType, H>::type type; 00485 }; 00486 00487 /** 00488 * @internal 00489 */ 00490 template<> 00491 class coh_handle_info<void> 00492 { 00493 public: typedef void type; 00494 }; 00495 } 00496 00497 // the following templates will compute a function pointer signature, similar 00498 // what the non-standard __typeof__ operator would do 00499 00500 /** 00501 * @internal 00502 */ 00503 template<int N, class R, class C, class H, class A1 = void, class A2 = void, 00504 class A3 = void, class A4 = void, class A5 = void, 00505 class A6 = void, class A7 = void, class A8 = void> 00506 class coh_signature_info \ 00507 { \ 00508 public: typedef void signature; 00509 }; 00510 00511 #define COH_SIG_INFON(N, RS, CS, HS, AS, TS) \ 00512 template<class R, class C, class A1, class A2, \ 00513 class A3, class A4, class A5, \ 00514 class A6, class A7, class A8> \ 00515 class coh_signature_info<N, R, C, HS, A1, A2, A3, A4, A5, A6, A7, A8> \ 00516 { \ 00517 public: typedef typename coh_handle_info<RS>::type (CS signature)AS TS \ 00518 } 00519 00520 00521 #define COH_ARG_TYPE0 00522 #define COH_ARG_TYPE1 COH_ARG_TYPE0 typename coh_handle_info<A1>::type 00523 #define COH_ARG_TYPE2 COH_ARG_TYPE1, typename coh_handle_info<A2>::type 00524 #define COH_ARG_TYPE3 COH_ARG_TYPE2, typename coh_handle_info<A3>::type 00525 #define COH_ARG_TYPE4 COH_ARG_TYPE3, typename coh_handle_info<A4>::type 00526 #define COH_ARG_TYPE5 COH_ARG_TYPE4, typename coh_handle_info<A5>::type 00527 #define COH_ARG_TYPE6 COH_ARG_TYPE5, typename coh_handle_info<A6>::type 00528 #define COH_ARG_TYPE7 COH_ARG_TYPE6, typename coh_handle_info<A7>::type 00529 #define COH_ARG_TYPE8 COH_ARG_TYPE7, typename coh_handle_info<A8>::type 00530 00531 #define COH_SIG_INFO(N) \ 00532 COH_SIG_INFON(N, R, *, void ,(COH_ARG_TYPE##N), ;); \ 00533 COH_SIG_INFON(N, R, C::*, typename C::Handle,(COH_ARG_TYPE##N), ;); \ 00534 COH_SIG_INFON(N, R, C::*, typename C::View ,(COH_ARG_TYPE##N), const;) 00535 00536 COH_SIG_INFO(0); 00537 COH_SIG_INFO(1); 00538 COH_SIG_INFO(2); 00539 COH_SIG_INFO(3); 00540 COH_SIG_INFO(4); 00541 COH_SIG_INFO(5); 00542 COH_SIG_INFO(6); 00543 COH_SIG_INFO(7); 00544 COH_SIG_INFO(8); 00545 00546 #undef COH_SIG_INFO 00547 #undef COH_SIG_INFON 00548 #undef COH_ARG_TYPE0 00549 #undef COH_ARG_TYPE1 00550 #undef COH_ARG_TYPE2 00551 #undef COH_ARG_TYPE3 00552 #undef COH_ARG_TYPE4 00553 #undef COH_ARG_TYPE5 00554 #undef COH_ARG_TYPE6 00555 #undef COH_ARG_TYPE7 00556 #undef COH_ARG_TYPE8 00557 00558 COH_CLOSE_NAMESPACE2 00559 00560 00561 // ----- helper macros ------------------------------------------------------ 00562 00563 /** 00564 * Declare an overloaded static Method based on a description of its signature. 00565 * 00566 * This OVERLOADED macro is only necessary when a class or interface declares 00567 * multiple methods of the same name, otherwise the COH_DECLARE_STATIC_METHOD 00568 * is a better choice of macros. An additional use case for this macro variant 00569 * is to handle the case where defining a static Method for a Managed<T> class 00570 * where the method is not actually declared on T, but on some super class of T. 00571 * 00572 * For both R, and A1..A8 the value should be a handle type, for instance 00573 * String::View or Map::Handle. If the underlying method returns a value 00574 * type instead, then a BoxHandle<> needs to be supplied for the corresponding 00575 * Object type. For instance BoxHandle<const Integer32> in place of int32_t. 00576 * 00577 * @param S the method signature 00578 * @param R the method return type 00579 * @param C the target class to call on 00580 * @param M the method name 00581 * @param A1..A8 the argument types 00582 */ 00583 #define COH_OVERLOADED_STATIC_METHOD8(S, R, C, M, A1, A2, A3, A4, A5, A6, A7, A8) \ 00584 coherence::lang::TypedMethod<S, \ 00585 R, C, void, &C::M, A1, A2, A3, A4, A5, A6, A7, A8>::create(#M) 00586 #define COH_OVERLOADED_STATIC_METHOD7(S, R, C, M, A1, A2, A3, A4, A5, A6, A7) \ 00587 COH_OVERLOADED_STATIC_METHOD8(S, R, C, M, A1, A2, A3, A4, A5, A6, A7, void) 00588 #define COH_OVERLOADED_STATIC_METHOD6(S, R, C, M, A1, A2, A3, A4, A5, A6) \ 00589 COH_OVERLOADED_STATIC_METHOD7(S, R, C, M, A1, A2, A3, A4, A5, A6, void) 00590 #define COH_OVERLOADED_STATIC_METHOD5(S, R, C, M, A1, A2, A3, A4, A5) \ 00591 COH_OVERLOADED_STATIC_METHOD6(S, R, C, M, A1, A2, A3, A4, A5, void) 00592 #define COH_OVERLOADED_STATIC_METHOD4(S, R, C, M, A1, A2, A3, A4) \ 00593 COH_OVERLOADED_STATIC_METHOD5(S, R, C, M, A1, A2, A3, A4, void) 00594 #define COH_OVERLOADED_STATIC_METHOD3(S, R, C, M, A1, A2, A3) \ 00595 COH_OVERLOADED_STATIC_METHOD4(S, R, C, M, A1, A2, A3, void) 00596 #define COH_OVERLOADED_STATIC_METHOD2(S, R, C, M, A1, A2) \ 00597 COH_OVERLOADED_STATIC_METHOD3(S, R, C, M, A1, A2, void) 00598 #define COH_OVERLOADED_STATIC_METHOD1(S, R, C, M, A) \ 00599 COH_OVERLOADED_STATIC_METHOD2(S, R, C, M, A, void) 00600 #define COH_OVERLOADED_STATIC_METHOD0(S, R, C, M) \ 00601 COH_OVERLOADED_STATIC_METHOD1(S, R, C, M, void) 00602 00603 /** 00604 * Declare a static Method based on a description of its signature. 00605 * 00606 * For both R, and A1..A8 the value should be a handle type, for instance 00607 * String::View or Map::Handle. If the underlying method returns a value 00608 * type instead, then a BoxHandle<> needs to be supplied for the corresponding 00609 * Object type. For instance BoxHandle<const Integer32> in place of in32_t. 00610 * 00611 * @param R the method return type 00612 * @param H the target handle type to call on 00613 * @param M the method name 00614 * @param A1..A8 the argument types 00615 */ 00616 #define COH_STATIC_METHOD(N, R, C, M, A1, A2, A3, A4, A5, A6, A7, A8) \ 00617 coherence::lang::TypedMethod<coh_signature_info<N, R, C, void, A1, A2, \ 00618 A3, A4, A5, A6, A7, A8>::signature, R, C, void, \ 00619 &C::M, A1, A2, A3, A4, A5, A6, A7, A8>::create(#M) 00620 #define COH_STATIC_METHOD8(R, C, M, A1, A2, A3, A4, A5, A6, A7, A8) \ 00621 COH_STATIC_METHOD(8, R, C, M, A1, A2, A3, A4, A5, A6, A7, A8) 00622 #define COH_STATIC_METHOD7(R, C, M, A1, A2, A3, A4, A5, A6, A7) \ 00623 COH_STATIC_METHOD(7, R, C, M, A1, A2, A3, A4, A5, A6, A7, void) 00624 #define COH_STATIC_METHOD6(R, C, M, A1, A2, A3, A4, A5, A6) \ 00625 COH_STATIC_METHOD(6, R, C, M, A1, A2, A3, A4, A5, A6, void, void) 00626 #define COH_STATIC_METHOD5(R, C, M, A1, A2, A3, A4, A5) \ 00627 COH_STATIC_METHOD(5, R, C, M, A1, A2, A3, A4, A5, void, void, void) 00628 #define COH_STATIC_METHOD4(R, C, M, A1, A2, A3, A4) \ 00629 COH_STATIC_METHOD(4, R, C, M, A1, A2, A3, A4, void, void, void, void) 00630 #define COH_STATIC_METHOD3(R, C, M, A1, A2, A3) \ 00631 COH_STATIC_METHOD(3, R, C, M, A1, A2, A3, void, void, void, void, void) 00632 #define COH_STATIC_METHOD2(R, C, M, A1, A2) \ 00633 COH_STATIC_METHOD(2, R, C, M, A1, A2, void, void, void, void, void, void) 00634 #define COH_STATIC_METHOD1(R, C, M, A) \ 00635 COH_STATIC_METHOD(1, R, C, M, A, void, void, void, void, void, void, void) 00636 #define COH_STATIC_METHOD0(R, C, M) \ 00637 COH_STATIC_METHOD(0, R, C, M, void, void, void, void, void, void, void, void) 00638 00639 /** 00640 * Declare a constructor Method based on a description of its signature. 00641 * 00642 * For both R, and A1..A8 the value should be a handle type, for instance 00643 * String::View or Map::Handle. If the underlying method returns a value 00644 * type instead, then a BoxHandle<> needs to be supplied for the corresponding 00645 * Object type. For instance BoxHandle<const Integer32> in place of in32_t. 00646 * 00647 * @param R the method return type 00648 * @param H the target handle type to call on 00649 * @param M the method name 00650 * @param A1..A8 the argument types 00651 */ 00652 #define COH_CONSTRUCTOR8(C, A1, A2, A3, A4, A5, A6, A7, A8) \ 00653 COH_OVERLOADED_STATIC_METHOD8(C::Handle (*)(const A1&, const A2&, \ 00654 const A3&, const A4&, const A5&, const A6&, const A7&, const A8&), \ 00655 C::Handle, C, create, A1, A2, A3, A4, A5, A6, A7, A8) 00656 #define COH_CONSTRUCTOR7(C, A1, A2, A3, A4, A5, A6, A7) \ 00657 COH_OVERLOADED_STATIC_METHOD7(C::Handle (*)(const A1&, const A2&, \ 00658 const A3&, const A4&, const A5&, const A6&, const A7&), \ 00659 C::Handle, C, create, A1, A2, A3, A4, A5, A6, A7) 00660 #define COH_CONSTRUCTOR6(C, A1, A2, A3, A4, A5, A6) \ 00661 COH_OVERLOADED_STATIC_METHOD6(C::Handle (*)(const A1&, const A2&, \ 00662 const A3&, const A4&, const A5&, const A6&), \ 00663 C::Handle, C, create, A1, A2, A3, A4, A5, A6) 00664 #define COH_CONSTRUCTOR5(C, A1, A2, A3, A4, A5) \ 00665 COH_OVERLOADED_STATIC_METHOD5(C::Handle (*)(const A1&, const A2&, \ 00666 const A3&, const A4&, const A5&), \ 00667 C::Handle, C, create, A1, A2, A3, A4, A5) 00668 #define COH_CONSTRUCTOR4(C, A1, A2, A3, A4) \ 00669 COH_OVERLOADED_STATIC_METHOD4(C::Handle (*)(const A1&, const A2&, \ 00670 const A3&, const A4&), \ 00671 C::Handle, C, create, A1, A2, A3, A4) 00672 #define COH_CONSTRUCTOR3(C, A1, A2, A3) \ 00673 COH_OVERLOADED_STATIC_METHOD3(C::Handle (*)(const A1&, const A2&, \ 00674 const A3&), \ 00675 C::Handle, C, create, A1, A2, A3) 00676 #define COH_CONSTRUCTOR2(C, A1, A2) \ 00677 COH_OVERLOADED_STATIC_METHOD2(C::Handle (*)(const A1&, const A2&), \ 00678 C::Handle, C, create, A1, A2) 00679 #define COH_CONSTRUCTOR1(C, A1) \ 00680 COH_OVERLOADED_STATIC_METHOD1(C::Handle (*)(const A1&), \ 00681 C::Handle, C, create, A1) 00682 #define COH_CONSTRUCTOR0(C) \ 00683 COH_OVERLOADED_STATIC_METHOD1(C::Handle (*)(), C::Handle, C, create) 00684 00685 /** 00686 * Declare an overloaded Method based on a description of its signature. 00687 * 00688 * This OVERLOADED macro is only necessary when a class or interface declares 00689 * multiple methods of the same name, otherwise the COH_DECLARE_METHOD is 00690 * a better choice of macros. 00691 * 00692 * For both R, and A1..A8 the value should be a handle type, for instance 00693 * String::View or Map::Handle. If the underlying method returns a value 00694 * type instead, then a BoxHandle<> needs to be supplied for the corresponding 00695 * Object type. For instance BoxHandle<const Integer32> in place of int32_t. 00696 * 00697 * @param S the method signature 00698 * @param R the method return type 00699 * @param H the target handle type to call on 00700 * @param M the method name 00701 * @param A1..A8 the argument types 00702 */ 00703 #define COH_OVERLOADED_METHOD8(S, R, H, M, A1, A2, A3, A4, A5, A6, A7, A8) \ 00704 coherence::lang::TypedMethod<S, \ 00705 R, H::ValueType, H, &H::ValueType::M, A1, A2, A3, A4, A5, A6, A7, A8>::create(#M) 00706 #define COH_OVERLOADED_METHOD7(S, R, H, M, A1, A2, A3, A4, A5, A6, A7) \ 00707 COH_OVERLOADED_METHOD8(S, R, H, M, A1, A2, A3, A4, A5, A6, A7, void) 00708 #define COH_OVERLOADED_METHOD6(S, R, H, M, A1, A2, A3, A4, A5, A6) \ 00709 COH_OVERLOADED_METHOD7(S, R, H, M, A1, A2, A3, A4, A5, A6, void) 00710 #define COH_OVERLOADED_METHOD5(S, R, H, M, A1, A2, A3, A4, A5) \ 00711 COH_OVERLOADED_METHOD6(S, R, H, M, A1, A2, A3, A4, A5, void) 00712 #define COH_OVERLOADED_METHOD4(S, R, H, M, A1, A2, A3, A4) \ 00713 COH_OVERLOADED_METHOD5(S, R, H, M, A1, A2, A3, A4, void) 00714 #define COH_OVERLOADED_METHOD3(S, R, H, M, A1, A2, A3) \ 00715 COH_OVERLOADED_METHOD4(S, R, H, M, A1, A2, A3, void) 00716 #define COH_OVERLOADED_METHOD2(S, R, H, M, A1, A2) \ 00717 COH_OVERLOADED_METHOD3(S, R, H, M, A1, A2, void) 00718 #define COH_OVERLOADED_METHOD1(S, R, H, M, A) \ 00719 COH_OVERLOADED_METHOD2(S, R, H, M, A, void) 00720 #define COH_OVERLOADED_METHOD0(S, R, H, M) \ 00721 COH_OVERLOADED_METHOD1(S, R, H, M, void) 00722 00723 /** 00724 * Declare a Method based on a description of its signature. 00725 * 00726 * For both R, and A1..A8 the value should be a handle type, for instance 00727 * String::View or Map::Handle. If the underlying method returns a value 00728 * type instead, then a BoxHandle<> needs to be supplied for the corresponding 00729 * Object type. For instance BoxHandle<const Integer32> in place of in32_t. 00730 * 00731 * @param R the method return type 00732 * @param H the target handle type to call on 00733 * @param M the method name 00734 * @param A1..A8 the argument types 00735 */ 00736 #define COH_METHOD(N, R, H, M, A1, A2, A3, A4, A5, A6, A7, A8) \ 00737 coherence::lang::TypedMethod<coh_signature_info<N, R, H::ValueType, H, A1, A2, \ 00738 A3, A4, A5, A6, A7, A8>::signature, R, H::ValueType, H, \ 00739 &H::ValueType::M, A1, A2, A3, A4, A5, A6, A7, A8>::create(#M) 00740 #define COH_METHOD8(R, H, M, A1, A2, A3, A4, A5, A6, A7, A8) \ 00741 COH_METHOD(8, R, H, M, A1, A2, A3, A4, A5, A6, A7, A8) 00742 #define COH_METHOD7(R, H, M, A1, A2, A3, A4, A5, A6, A7) \ 00743 COH_METHOD(7, R, H, M, A1, A2, A3, A4, A5, A6, A7, void) 00744 #define COH_METHOD6(R, H, M, A1, A2, A3, A4, A5, A6) \ 00745 COH_METHOD(6, R, H, M, A1, A2, A3, A4, A5, A6, void, void) 00746 #define COH_METHOD5(R, H, M, A1, A2, A3, A4, A5) \ 00747 COH_METHOD(5, R, H, M, A1, A2, A3, A4, A5, void, void, void) 00748 #define COH_METHOD4(R, H, M, A1, A2, A3, A4) \ 00749 COH_METHOD(4, R, H, M, A1, A2, A3, A4, void, void, void, void) 00750 #define COH_METHOD3(R, H, M, A1, A2, A3) \ 00751 COH_METHOD(3, R, H, M, A1, A2, A3, void, void, void, void, void) 00752 #define COH_METHOD2(R, H, M, A1, A2) \ 00753 COH_METHOD(2, R, H, M, A1, A2, void, void, void, void, void, void) 00754 #define COH_METHOD1(R, H, M, A) \ 00755 COH_METHOD(1, R, H, M, A, void, void, void, void, void, void, void) 00756 #define COH_METHOD0(R, H, M) \ 00757 COH_METHOD(0, R, H, M, void, void, void, void, void, void, void, void) 00758 00759 /** 00760 * Declare a Method for a Managed<> class based on a description of its 00761 * signature. 00762 * 00763 * For both R, and A1..A8 the value should be a handle type, for instance 00764 * String::View or Map::Handle. If the underlying method returns a value 00765 * type instead, then a BoxHandle<> needs to be supplied for the corresponding 00766 * Object type. For instance BoxHandle<const Integer32> in place of in32_t. 00767 * 00768 * @param S the method signature 00769 * @param R the method return type 00770 * @param H the target handle type to call on 00771 * @param M the method name 00772 * @param A1..A8 the argument types 00773 */ 00774 #define COH_MANAGED_METHOD8(S, R, H, M, A1, A2, A3, A4, A5, A6, A7, A8) \ 00775 coherence::lang::TypedMethod<S, R, H::ValueType, H, \ 00776 &H::ValueType::BoxedType::M, A1, A2, A3, A4, A5, A6, A7, A8>::create(#M) 00777 #define COH_MANAGED_METHOD7(S, R, H, M, A1, A2, A3, A4, A5, A6, A7) \ 00778 COH_MANAGED_METHOD8(S, R, H, M, A1, A2, A3, A4, A5, A6, A7, void) 00779 #define COH_MANAGED_METHOD6(S, R, H, M, A1, A2, A3, A4, A5, A6) \ 00780 COH_MANAGED_METHOD7(S, R, H, M, A1, A2, A3, A4, A5, A6, void) 00781 #define COH_MANAGED_METHOD5(S, R, H, M, A1, A2, A3, A4, A5) \ 00782 COH_MANAGED_METHOD6(S, R, H, M, A1, A2, A3, A4, A5, void) 00783 #define COH_MANAGED_METHOD4(S, R, H, M, A1, A2, A3, A4) \ 00784 COH_MANAGED_METHOD5(S, R, H, M, A1, A2, A3, A4, void) 00785 #define COH_MANAGED_METHOD3(S, R, H, M, A1, A2, A3) \ 00786 COH_MANAGED_METHOD4(S, R, H, M, A1, A2, A3, void) 00787 #define COH_MANAGED_METHOD2(S, R, H, M, A1, A2) \ 00788 COH_MANAGED_METHOD3(S, R, H, M, A1, A2, void) 00789 #define COH_MANAGED_METHOD1(S, R, H, M, A) \ 00790 COH_MANAGED_METHOD2(S, R, H, M, A, void) 00791 #define COH_MANAGED_METHOD0(S, R, H, M) \ 00792 COH_MANAGED_METHOD1(S, R, H, M, void) 00793 00794 /** 00795 * Helper macro for creating getter and setter methods for a property. 00796 * 00797 * @param C the class to call the method on, i.e. Address 00798 * @param P the property to access, i.e. State 00799 * @param V the return object type, i.e. String::View 00800 */ 00801 #define COH_PROPERTY(C, P, V) \ 00802 COH_METHOD0(V, C::View, get##P)) \ 00803 ->declare(COH_METHOD1(void, C::Handle, set##P, V) 00804 00805 /** 00806 * Helper macro for creating getter and setter methods for a boxable property. 00807 * 00808 * @param C the class to call the method on, i.e. Address 00809 * @param P the property to access, i.e. State 00810 * @param V the return object type, i.e. String::View 00811 */ 00812 #define COH_BOX_PROPERTY(C, P, V) \ 00813 COH_METHOD0(coherence::lang::BoxHandle<V::ValueType >, C::View, get##P)) \ 00814 ->declare(COH_METHOD1(void, C::Handle, set##P, coherence::lang::BoxHandle<V::ValueType >) 00815 00816 /** 00817 * Helper macro for creating getter and setter methods for a boxable property 00818 * on a Managed<> object. 00819 * 00820 * @param C the class to call the method on, i.e. Address 00821 * @param P the property to access, i.e. Zip 00822 * @param V the return object type, i.e. Integer32::View 00823 */ 00824 #define COH_MANAGED_PROPERTY(C, P, V) \ 00825 COH_MANAGED_METHOD0(V::ValueType::BoxedType (C::*)() const, coherence::lang::BoxHandle<V::ValueType >, coherence::lang::Managed<C >::View, get##P)) \ 00826 ->declare(COH_MANAGED_METHOD1(void (C::*)(V::ValueType::BoxedType), void, coherence::lang::Managed<C >::Handle, set##P, coherence::lang::BoxHandle<V::ValueType >) 00827 00828 #endif // COH_TYPED_METHOD_HPP