coherence/lang/lang_spec.hpp

00001 /*
00002 * lang_spec.hpp
00003 *
00004 * Copyright 2001-2008 by Oracle. 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     };
00036 
00037 /**
00038 * @internal
00039 *
00040 * Definition of class alias, used in Exceptions.
00041 */
00042 template<class T> class Alias
00043     {
00044     public:
00045         typedef typename T::alias alias;
00046     };
00047 
00048 /**
00049 * @internal
00050 *
00051 * Terminal Alias.
00052 */
00053 template<> class Alias<Void<> >
00054     {
00055     public:
00056         typedef Void<> alias;
00057     };
00058 
00059 /**
00060 * @internal
00061 *
00062 * Object Alias.
00063 */
00064 template<> class Alias<Object>
00065     {
00066     public:
00067         typedef Void<Object> alias;
00068     };
00069 
00070 
00071 /**
00072 * @internal
00073 *
00074 * Definition of individual link in chain of implemented interfaces.
00075 *
00076 * @see implements
00077 *
00078 * @author mf 2008.07.14
00079 */
00080 template<class I, class NEXT> class COH_EXPORT_SPEC interface_link
00081     : public virtual I, public virtual NEXT
00082     {
00083     };
00084 
00085 /**
00086 * @internal
00087 *
00088 * Terminal interface_link
00089 */
00090 template<class IGNORE> class COH_EXPORT_SPEC interface_link<void, IGNORE>
00091     {
00092     };
00093 
00094 
00095 /**
00096 * The implements template specifies a list of interfaces which a class or
00097 * interface specification derives from.  Each interface will be virtually
00098 * inheirted by specified class or interface. Up to sixteen interfaces are
00099 * supported, in the case where more are required, they can be specified using
00100 * an interface_link<I> chain.  i.e.
00101 *
00102 * @code
00103 * implements<I1, ..., I15, interface_link<I16, interface_link<I17> > >
00104 * @endcode
00105 *
00106 * @see abstract_spec
00107 * @see class_spec
00108 * @see cloneable_spec
00109 * @see throwable_spec
00110 * @see interface_spec
00111 *
00112 * @author mf 2008.07.14
00113 */
00114 template<class I1  = void,
00115          class I2  = void,
00116          class I3  = void,
00117          class I4  = void,
00118          class I5  = void,
00119          class I6  = void,
00120          class I7  = void,
00121          class I8  = void,
00122          class I9  = void,
00123          class I10 = void,
00124          class I11 = void,
00125          class I12 = void,
00126          class I13 = void,
00127          class I14 = void,
00128          class I15 = void,
00129          class I16 = void>
00130 class COH_EXPORT_SPEC implements
00131     {
00132     public:
00133         typedef interface_link<I1,
00134                 interface_link<I2,
00135                 interface_link<I3,
00136                 interface_link<I4,
00137                 interface_link<I5,
00138                 interface_link<I6,
00139                 interface_link<I7,
00140                 interface_link<I8,
00141                 interface_link<I9,
00142                 interface_link<I10,
00143                 interface_link<I11,
00144                 interface_link<I12,
00145                 interface_link<I13,
00146                 interface_link<I14,
00147                 interface_link<I15,
00148                 interface_link<I16,
00149                 void > > > > > > > > > > > > > > > >
00150         implements_chain;
00151     };
00152 
00153 /**
00154 * The extends template indicates the parent class in a class specification.
00155 *
00156 * @see abstract_spec
00157 * @see class_spec
00158 * @see cloneable_spec
00159 * @see throwable_spec
00160 *
00161 * @author mf 2008.07.14
00162 */
00163 template<class P = Void<>, class A = typename Alias<P>::alias >
00164 class COH_EXPORT_SPEC extends
00165     {
00166     public:
00167         /**
00168         * Marker for the actual inherited parent class.
00169         */
00170         typedef P inherited;
00171 
00172         /**
00173         * The purpose of this definition is to cause a compilation error if
00174         * an attempt is made to instantiate the extends template by supplying
00175         * an interface.
00176         */
00177         typedef typename P::super grand;
00178 
00179         /**
00180         * Alias type used in throwables.
00181         */
00182         typedef A alias;
00183     };
00184 
00185 /**
00186 * @internal
00187 *
00188 * Terminal definition in extension hierarchy.
00189 */
00190 template<> class COH_EXPORT_SPEC extends<Void<>, Void<> >
00191     {
00192     public:
00193         typedef Void<> inherited;
00194         typedef Void<> alias;
00195     };
00196 
00197 // ----- helper macros used in the creation of specs ------------------------
00198 
00199 /**
00200 * The COH_LIST macros create a coma seperated list of names, which each name
00201 * is the same except for a numeric suffix.
00202 */
00203 #define COH_LIST1(A)                 A##1
00204 #define COH_LIST2(A)  COH_LIST1 (A), A##2
00205 #define COH_LIST3(A)  COH_LIST2 (A), A##3
00206 #define COH_LIST4(A)  COH_LIST3 (A), A##4
00207 #define COH_LIST5(A)  COH_LIST4 (A), A##5
00208 #define COH_LIST6(A)  COH_LIST5 (A), A##6
00209 #define COH_LIST7(A)  COH_LIST6 (A), A##7
00210 #define COH_LIST8(A)  COH_LIST7 (A), A##8
00211 #define COH_LIST9(A)  COH_LIST8 (A), A##9
00212 #define COH_LIST10(A) COH_LIST9 (A), A##10
00213 #define COH_LIST11(A) COH_LIST10(A), A##11
00214 #define COH_LIST12(A) COH_LIST11(A), A##12
00215 #define COH_LIST13(A) COH_LIST12(A), A##13
00216 #define COH_LIST14(A) COH_LIST13(A), A##14
00217 #define COH_LIST15(A) COH_LIST14(A), A##15
00218 #define COH_LIST16(A) COH_LIST15(A), A##16
00219 
00220 /**
00221 * The COH_ARG_LIST macros create a comma seperated list of argument
00222 * declarationsnames, which each argument name is the same except for a numeric
00223 * suffix.
00224 */
00225 #define COH_ARG_LIST1(A)                     const A##1&  a1
00226 #define COH_ARG_LIST2(A)  COH_ARG_LIST1 (A), const A##2&  a2
00227 #define COH_ARG_LIST3(A)  COH_ARG_LIST2 (A), const A##3&  a3
00228 #define COH_ARG_LIST4(A)  COH_ARG_LIST3 (A), const A##4&  a4
00229 #define COH_ARG_LIST5(A)  COH_ARG_LIST4 (A), const A##5&  a5
00230 #define COH_ARG_LIST6(A)  COH_ARG_LIST5 (A), const A##6&  a6
00231 #define COH_ARG_LIST7(A)  COH_ARG_LIST6 (A), const A##7&  a7
00232 #define COH_ARG_LIST8(A)  COH_ARG_LIST7 (A), const A##8&  a8
00233 #define COH_ARG_LIST9(A)  COH_ARG_LIST8 (A), const A##9&  a9
00234 #define COH_ARG_LIST10(A) COH_ARG_LIST9 (A), const A##10& a10
00235 #define COH_ARG_LIST11(A) COH_ARG_LIST10(A), const A##11& a11
00236 #define COH_ARG_LIST12(A) COH_ARG_LIST11(A), const A##12& a12
00237 #define COH_ARG_LIST13(A) COH_ARG_LIST12(A), const A##13& a13
00238 #define COH_ARG_LIST14(A) COH_ARG_LIST13(A), const A##14& a14
00239 #define COH_ARG_LIST15(A) COH_ARG_LIST14(A), const A##15& a15
00240 #define COH_ARG_LIST16(A) COH_ARG_LIST15(A), const A##16& a16
00241 
00242 /**
00243 * Declare a set of templated copy constructors.
00244 *
00245 * @param CLASS the class of which the constors are declared
00246 */
00247 #define COH_DECLARE_PROXY_CONSTRUCTORS(CLASS) \
00248     CLASS(); \
00249     CLASS(const CLASS&); \
00250     virtual ~CLASS(); \
00251     template<COH_LIST1 (class A)> CLASS(COH_ARG_LIST1 (A)); \
00252     template<COH_LIST2 (class A)> CLASS(COH_ARG_LIST2 (A)); \
00253     template<COH_LIST3 (class A)> CLASS(COH_ARG_LIST3 (A)); \
00254     template<COH_LIST4 (class A)> CLASS(COH_ARG_LIST4 (A)); \
00255     template<COH_LIST5 (class A)> CLASS(COH_ARG_LIST5 (A)); \
00256     template<COH_LIST6 (class A)> CLASS(COH_ARG_LIST6 (A)); \
00257     template<COH_LIST7 (class A)> CLASS(COH_ARG_LIST7 (A)); \
00258     template<COH_LIST8 (class A)> CLASS(COH_ARG_LIST8 (A)); \
00259     template<COH_LIST9 (class A)> CLASS(COH_ARG_LIST9 (A)); \
00260     template<COH_LIST10(class A)> CLASS(COH_ARG_LIST10(A)); \
00261     template<COH_LIST11(class A)> CLASS(COH_ARG_LIST11(A)); \
00262     template<COH_LIST12(class A)> CLASS(COH_ARG_LIST12(A)); \
00263     template<COH_LIST13(class A)> CLASS(COH_ARG_LIST13(A)); \
00264     template<COH_LIST14(class A)> CLASS(COH_ARG_LIST14(A)); \
00265     template<COH_LIST15(class A)> CLASS(COH_ARG_LIST15(A)); \
00266     template<COH_LIST16(class A)> CLASS(COH_ARG_LIST16(A))
00267 
00268 /**
00269 * Generate the prefix for a template definition, sutiable for passing to
00270 * another macro.
00271 */
00272 #define COH_TEMPLATE_DECLARE3(T1, T2, T3) \
00273     template<class T1, class T2, class T3>
00274 #define COH_TEMPLATE_DECLARE4(T1, T2, T3, T4) \
00275     template<class T1, class T2, class T3, class T4>
00276 
00277 /**
00278 * Generate the prefix for a template class external method declaration,
00279 * sutiable for passing to another macro.
00280 */
00281 #define COH_TEMPLATE_DEFINE3(T1, T2, T3)  <T1, T2, T3>
00282 #define COH_TEMPLATE_DEFINE4(T1, T2, T3, T4)  <T1, T2, T3, T4>
00283 
00284 /**
00285 * Define implementations for the constructors declared.
00286 *
00287 * @param DECLARE the class's template prefix
00288 * @param DEFINE  the class's template parameters
00289 * @param CLASS   the class on which to generate the methods
00290 * @param SUPER   the parent class of CLASS
00291 */
00292 #define COH_DEFINE_PROXY_CONSTRUCTORS(DECLARE, DEFINE, CLASS, SUPER) \
00293     DECLARE CLASS DEFINE::CLASS() : SUPER() {} \
00294     DECLARE CLASS DEFINE::CLASS(const CLASS& that) : SUPER(that) {} \
00295     DECLARE CLASS DEFINE::~CLASS() {} \
00296     DECLARE template<COH_LIST1(class A)> \
00297         CLASS DEFINE::CLASS(COH_ARG_LIST1 (A)) : SUPER(COH_LIST1(a)) {} \
00298     DECLARE template<COH_LIST2(class A)> \
00299         CLASS DEFINE::CLASS(COH_ARG_LIST2 (A)) : SUPER(COH_LIST2(a)) {} \
00300     DECLARE template<COH_LIST3(class A)> \
00301         CLASS DEFINE::CLASS(COH_ARG_LIST3 (A)) : SUPER(COH_LIST3(a)) {} \
00302     DECLARE template<COH_LIST4(class A)> \
00303         CLASS DEFINE::CLASS(COH_ARG_LIST4 (A)) : SUPER(COH_LIST4(a)) {} \
00304     DECLARE template<COH_LIST5(class A)> \
00305         CLASS DEFINE::CLASS(COH_ARG_LIST5 (A)) : SUPER(COH_LIST5(a)) {} \
00306     DECLARE template<COH_LIST6(class A)> \
00307         CLASS DEFINE::CLASS(COH_ARG_LIST6 (A)) : SUPER(COH_LIST6(a)) {} \
00308     DECLARE template<COH_LIST7(class A)> \
00309         CLASS DEFINE::CLASS(COH_ARG_LIST7 (A)) : SUPER(COH_LIST7(a)) {} \
00310     DECLARE template<COH_LIST8(class A)> \
00311         CLASS DEFINE::CLASS(COH_ARG_LIST8 (A)) : SUPER(COH_LIST8(a)) {} \
00312     DECLARE template<COH_LIST9(class A)> \
00313         CLASS DEFINE::CLASS(COH_ARG_LIST9 (A)) : SUPER(COH_LIST9(a)) {} \
00314     DECLARE template<COH_LIST10(class A)> \
00315         CLASS DEFINE::CLASS(COH_ARG_LIST10(A)) : SUPER(COH_LIST10(a)) {} \
00316     DECLARE template<COH_LIST11(class A)> \
00317         CLASS DEFINE::CLASS(COH_ARG_LIST11(A)) : SUPER(COH_LIST11(a)) {} \
00318     DECLARE template<COH_LIST12(class A)> \
00319         CLASS DEFINE::CLASS(COH_ARG_LIST12(A)) : SUPER(COH_LIST12(a)) {} \
00320     DECLARE template<COH_LIST13(class A)> \
00321         CLASS DEFINE::CLASS(COH_ARG_LIST13(A)) : SUPER(COH_LIST13(a)) {} \
00322     DECLARE template<COH_LIST14(class A)> \
00323         CLASS DEFINE::CLASS(COH_ARG_LIST14(A)) : SUPER(COH_LIST14(a)) {} \
00324     DECLARE template<COH_LIST15(class A)> \
00325         CLASS DEFINE::CLASS(COH_ARG_LIST15(A)) : SUPER(COH_LIST15(a)) {} \
00326     DECLARE template<COH_LIST16(class A)> \
00327         CLASS DEFINE::CLASS(COH_ARG_LIST16(A)) : SUPER(COH_LIST16(a)) {}
00328 
00329 /**
00330 * Declare and define factory "create" methods.
00331 *
00332 * @param RETURN    the return type from the factory
00333 * @param FUNCTION  the function to be called to produce the the RETURN
00334 */
00335 #define COH_DEFINE_CREATE_METHODS(RETURN, FUNCTION) \
00336     static RETURN create() \
00337         {return FUNCTION();} \
00338     template<COH_LIST1 (class A)> static RETURN create(COH_ARG_LIST1(A)) \
00339         {return FUNCTION(COH_LIST1(a));} \
00340     template<COH_LIST2 (class A)> static RETURN create(COH_ARG_LIST2(A)) \
00341         {return FUNCTION(COH_LIST2(a));} \
00342     template<COH_LIST3 (class A)> static RETURN create(COH_ARG_LIST3(A)) \
00343         {return FUNCTION(COH_LIST3(a));} \
00344     template<COH_LIST4 (class A)> static RETURN create(COH_ARG_LIST4(A)) \
00345         {return FUNCTION(COH_LIST4(a));} \
00346     template<COH_LIST5 (class A)> static RETURN create(COH_ARG_LIST5(A)) \
00347         {return FUNCTION(COH_LIST5(a));} \
00348     template<COH_LIST6 (class A)> static RETURN create(COH_ARG_LIST6(A)) \
00349         {return FUNCTION(COH_LIST6(a));} \
00350     template<COH_LIST7 (class A)> static RETURN create(COH_ARG_LIST7(A)) \
00351         {return FUNCTION(COH_LIST7(a));} \
00352     template<COH_LIST8 (class A)> static RETURN create(COH_ARG_LIST8(A)) \
00353         {return FUNCTION(COH_LIST8(a));} \
00354     template<COH_LIST9 (class A)> static RETURN create(COH_ARG_LIST9(A)) \
00355         {return FUNCTION(COH_LIST9(a));} \
00356     template<COH_LIST10(class A)> static RETURN create(COH_ARG_LIST10(A)) \
00357         {return FUNCTION(COH_LIST10(a));} \
00358     template<COH_LIST11(class A)> static RETURN create(COH_ARG_LIST11(A)) \
00359         {return FUNCTION(COH_LIST11(a));} \
00360     template<COH_LIST12(class A)> static RETURN create(COH_ARG_LIST12(A)) \
00361         {return FUNCTION(COH_LIST12(a));} \
00362     template<COH_LIST13(class A)> static RETURN create(COH_ARG_LIST13(A)) \
00363         {return FUNCTION(COH_LIST13(a));} \
00364     template<COH_LIST14(class A)> static RETURN create(COH_ARG_LIST14(A)) \
00365         {return FUNCTION(COH_LIST14(a));} \
00366     template<COH_LIST15(class A)> static RETURN create(COH_ARG_LIST15(A)) \
00367         {return FUNCTION(COH_LIST15(a));} \
00368     template<COH_LIST16(class A)> static RETURN create(COH_ARG_LIST16(A)) \
00369         {return FUNCTION(COH_LIST16(a));}
00370 
00371 
00372 /**
00373 * The factory class auto-generates static create methods for a class,
00374 * corresponding to the class's constructors.  The factory must be made a
00375 * friend of the defined class so that it may access the protected constructors.
00376 *
00377 * The factory is used by class specifications to provide the class with static
00378 * create methods.  i.e. the result of using a class_spec when defining class
00379 * Foo will result in Foo having auto-generated static create methods.  Direct
00380 * use of the factory for class instantation is not supported.
00381 *
00382 * The factory supports constructors from zero to sixteen parameters. To help
00383 * the template system it is best (though not required) that there are not
00384 * multiple constructors with the same number of parameters. Classes wishing to
00385 * provide custom create methods may simply define them in their class, and
00386 * these will override and hide the factory auto-generated versions.
00387 *
00388 * @see class_spec
00389 * @see cloneable_spec
00390 * @see throwable_spec
00391 *
00392 * @author mf 2008.07.14
00393 */
00394 template<class T> class COH_EXPORT_SPEC factory
00395     {
00396     template<class, class, class> friend class class_spec;
00397 
00398     protected:
00399         /**
00400         * Generate a set of static "create" methods matching the signatures of
00401         * class T's constructors.
00402         *
00403         * NOTE: Compilation errors referencing this line likely indicate that
00404         *       the parameters supplied by the caller to the create method did
00405         *       not match one of the constructors.
00406         */
00407         COH_DEFINE_CREATE_METHODS(T*, new T)
00408     };
00409 
00410 COH_CLOSE_NAMESPACE2
00411 
00412 #endif // COH_LANG_SPEC_HPP
Copyright (c) 2000-2008 Oracle. All rights reserved.