00001 #ifndef CLASSLIB_MULTIMETHOD_H
00002 # define CLASSLIB_MULTIMETHOD_H
00003
00004
00005
00006 # include "classlib/utils/XTypeInfo.h"
00007 # include "classlib/utils/PODVector.h"
00008 # include "classlib/utils/Macros.h"
00009
00010 namespace lat {
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 # define MULTIMETHOD_ARGS_1_0(V1) V1
00051 # define MULTIMETHOD_ARGS_1_1(V1,A1) V1, A1
00052 # define MULTIMETHOD_ARGS_1_2(V1,A1,A2) V1, A1, A2
00053 # define MULTIMETHOD_ARGS_2_0(V1,V2) V1, V2
00054 # define MULTIMETHOD_ARGS_2_1(V1,V2,A1) V1, V2, A1
00055 # define MULTIMETHOD_ARGS_2_2(V1,V2,A1,A2) V1, V2, A1, A2
00056 # define MULTIMETHOD_ARGS_3_0(V1,V2,V3) V1, V2, V3
00057 # define MULTIMETHOD_ARGS_3_1(V1,V2,V3,A1) V1, V2, V3, A1
00058 # define MULTIMETHOD_ARGS_3_2(V1,V2,V3,A1,A2) V1, V2, V3, A1, A2
00059
00060 # define MULTIMETHOD_DECLARE(ext,rettype,name,nvirt,nnonvirt,args) \
00061 ext lat::MultiMethod::Definition name ## Def; \
00062 typedef lat::MultiMethod_##nvirt##_##nnonvirt< \
00063 rettype, MULTIMETHOD_ARGS_##nvirt##_##nnonvirt args \
00064 > name##Type; \
00065 ext name##Type name
00066
00067 # define MULTIMETHOD_DEFINE(scope,name) \
00068 lat::MultiMethod::Definition scope name ## Def = \
00069 { #name, 0, false, false, 0, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0, 0 }; \
00070 scope name ## Type scope name (&name ##Def)
00071
00072 # define MMM_SYM(pre,line,post) CLASSLIB_name3(pre,line,post)
00073 # define MMM_DECLARE(ret,name,proto) ret mmm_##name proto
00074 # define MMM_DECLARE_STUB(mscope,scope,name,proto,regsym) \
00075 static lat::MultiMethodMember< mscope name##Type,proto, \
00076 &scope mmm_##name, &mscope name##Def> regsym
00077 # define MMM_DEFUN_METHOD(ret,mscope,scope,name,proto) \
00078 MMM_DECLARE_STUB(mscope,scope,name,ret (*) proto, \
00079 MMM_SYM(name,Init,__LINE__)); \
00080 ret scope mmm_##name proto
00081 # define MMM_DEFUN_FUNC(ret,mscope,name,proto) \
00082 ret mmm_##name proto; \
00083 MMM_DECLARE_STUB(mscope,::,name,ret (*) proto, \
00084 MMM_SYM(name,Init,__LINE__)); \
00085 ret mmm_##name proto
00086
00087
00088
00089
00090
00091
00092
00154 class MultiMethod : protected XTypeInfo::Monitor
00155 {
00156 public:
00157 struct Definition;
00158 #if ! HAVE_BROKEN_CLASS_ACCESS
00159 protected:
00160 #endif
00161 struct Score;
00162 #if ! HAVE_BROKEN_CLASS_ACCESS
00163 private:
00164 #endif
00165 struct Member;
00166 struct ScoreHunk;
00167 struct EntryHunk;
00168 struct Entry;
00169
00170 friend struct Definition;
00171 friend struct Member;
00172 friend struct ScoreHunk;
00173 friend struct EntryHunk;
00174 friend struct Entry;
00175 public:
00181 typedef void (*MemberFunction) (void);
00182
00195 struct Definition
00196 {
00199 const char *m_name;
00200
00203 STDC::size_t m_key;
00204
00207 bool m_hooked;
00208
00212 bool m_dirty;
00213
00217 STDC::size_t m_generation;
00218
00220 STDC::size_t m_formals;
00221
00225 XTypeInfo::ClassDef **m_formalTypes;
00226
00227
00230 PODVector<Member>::Data m_family;
00231
00233 STDC::size_t m_familyMaxSize;
00234
00236 STDC::size_t m_familyMaxCapacity;
00237
00247 ScoreHunk *m_scoreHunks;
00248
00251 EntryHunk *m_entryHunks;
00252
00256 Entry *m_freeEntries;
00257
00258 void extend (MemberFunction function,
00259 XTypeInfo::ClassDef **formalTypes);
00260 void remove (MemberFunction function);
00261 };
00262
00263 #if ! HAVE_BROKEN_CLASS_ACCESS
00264 protected:
00265 #endif
00266
00285 struct Score
00286 {
00294 unsigned short m_distance;
00295
00298 unsigned short m_index;
00299 };
00300
00301 MultiMethod (void);
00302 ~MultiMethod (void);
00303
00304 void initialise (Definition *data,
00305 STDC::size_t formals,
00306 XTypeInfo::ClassDef **formalTypes);
00307
00308 MemberFunction dispatch (XTypeInfo **actualTypes,
00309 Score **candidates,
00310 Score *best) const;
00311
00312 #if ! HAVE_BROKEN_CLASS_ACCESS
00313 private:
00314 #endif
00315
00321 enum { INITIAL_FAMILY_SIZE = 32 };
00322
00324 enum { SCORE_HUNK_SIZE = 64 };
00325
00327 enum { ENTRY_HUNK_SIZE = 32 };
00328
00331 enum { LAST_SCORE = USHRT_MAX };
00332
00336 enum { INFINITE_DISTANCE = USHRT_MAX };
00337
00339 struct Member
00340 {
00342 MemberFunction m_function;
00346 XTypeInfo::ClassDef **m_formalTypes;
00347 };
00348
00350 struct ScoreHunk
00351 {
00352 ScoreHunk *m_next;
00353 Score *m_scores;
00354 Score *m_free;
00355 STDC::size_t m_capacity;
00356 };
00357
00359 struct EntryHunk
00360 {
00361 EntryHunk *m_next;
00362 Entry *m_entries;
00363 Entry *m_free;
00364 STDC::size_t m_capacity;
00365 };
00366
00385 struct Entry
00386 {
00391 Entry *m_next;
00392
00395 STDC::size_t m_key;
00396
00398 STDC::size_t m_formal;
00399
00403 STDC::size_t m_generation;
00404
00416 Score *m_scores;
00417 };
00418
00419
00420 static XTypeInfo::ExtensionKey
00421 extensionKey (void);
00422 static STDC::size_t methodKey (void);
00423
00424
00425 ScoreHunk * createScoreHunk (STDC::size_t min) const;
00426 void freeScoreHunks (void) const;
00427 Score * allocateScores (STDC::size_t n) const;
00428
00429 EntryHunk * createEntryHunk (void) const;
00430 void freeEntryHunks (void) const;
00431 Entry * allocateEntry (void) const;
00432 void freeEntry (Entry *item) const;
00433
00434
00435 STDC::size_t relatedFormal (const XTypeInfo *type) const;
00436 static Entry * findTypeEntries (const XTypeInfo *type,
00437 Entry *&previous,
00438 STDC::size_t key,
00439 STDC::size_t formal
00440 = STDC::size_t(-1));
00441
00442 void typePrepare (STDC::size_t formal,
00443 XTypeInfo *type) const;
00444 bool typeClean (STDC::size_t formal,
00445 XTypeInfo *type) const;
00446 virtual void typeHook (XTypeInfo *type);
00447 virtual void typeUnhook (XTypeInfo *type);
00448
00449 static bool orderScores (const Score &x, const Score &y);
00450 void cleanScores (const XTypeInfo *type) const;
00451 void buildScores (const XTypeInfo *type) const;
00452 void newGeneration (void) const;
00453 void regenerate (const XTypeInfo *type) const;
00454
00455
00456 void noViableAlt (XTypeInfo **actuals) const;
00457 void ambiguity (XTypeInfo **actuals,
00458 Score **candidates,
00459 Score *best) const;
00460
00461
00462 Definition *m_data;
00463
00464
00465 MultiMethod (const MultiMethod &);
00466 MultiMethod &operator= (const MultiMethod &);
00467 };
00468
00472
00473
00474
00475
00476
00477
00478 template <class R, class V1>
00479 class MultiMethod_1_0 : public MultiMethod
00480 {
00481 public:
00482 static const int NVIRT = 1;
00483 static const int NNONVIRT = 0;
00484 typedef R RTYPE;
00485 typedef V1 VTYPE1;
00486
00487 MultiMethod_1_0 (Definition *def);
00488 R operator() (V1 *v1);
00489
00490 private:
00491 XTypeInfo::ClassDef *m_formals [1];
00492 };
00493
00494 template <class R, class V1, class T1>
00495 class MultiMethod_1_1 : public MultiMethod
00496 {
00497 public:
00498 static const int NVIRT = 1;
00499 static const int NNONVIRT = 1;
00500 typedef R RTYPE;
00501 typedef V1 VTYPE1;
00502 typedef T1 NONVTYPE1;
00503
00504 MultiMethod_1_1 (Definition *def);
00505 R operator() (V1 *v1, T1 t1);
00506
00507 private:
00508 XTypeInfo::ClassDef *m_formals [1];
00509 };
00510
00511 template <class R, class V1, class T1, class T2>
00512 class MultiMethod_1_2 : public MultiMethod
00513 {
00514 public:
00515 static const int NVIRT = 1;
00516 static const int NNONVIRT = 2;
00517 typedef R RTYPE;
00518 typedef V1 VTYPE1;
00519 typedef T1 NONVTYPE1;
00520 typedef T2 NONVTYPE2;
00521
00522 MultiMethod_1_2 (Definition *def);
00523 R operator() (V1 *v1, T1 t1, T2 t2);
00524
00525 private:
00526 XTypeInfo::ClassDef *m_formals [1];
00527 };
00528
00532 template <class R, class V1, class V2>
00533 class MultiMethod_2_0 : public MultiMethod
00534 {
00535 public:
00536 static const int NVIRT = 2;
00537 static const int NNONVIRT = 0;
00538 typedef R RTYPE;
00539 typedef V1 VTYPE1;
00540 typedef V2 VTYPE2;
00541
00542 MultiMethod_2_0 (Definition *def);
00543 R operator() (V1 *v1, V2 *v2);
00544
00545 private:
00546 XTypeInfo::ClassDef *m_formals [2];
00547 };
00548
00549 template <class R, class V1, class V2, class T1>
00550 class MultiMethod_2_1 : public MultiMethod
00551 {
00552 public:
00553 static const int NVIRT = 2;
00554 static const int NNONVIRT = 1;
00555 typedef R RTYPE;
00556 typedef V1 VTYPE1;
00557 typedef V2 VTYPE2;
00558 typedef T1 NONVTYPE1;
00559
00560 MultiMethod_2_1 (Definition *def);
00561 R operator() (V1 *v1, V2 *v2, T1 t1);
00562
00563 private:
00564 XTypeInfo::ClassDef *m_formals [2];
00565 };
00566
00567 template <class R, class V1, class V2, class T1, class T2>
00568 class MultiMethod_2_2 : public MultiMethod
00569 {
00570 public:
00571 static const int NVIRT = 2;
00572 static const int NNONVIRT = 2;
00573 typedef R RTYPE;
00574 typedef V1 VTYPE1;
00575 typedef V2 VTYPE2;
00576 typedef T1 NONVTYPE1;
00577 typedef T2 NONVTYPE2;
00578
00579 MultiMethod_2_2 (Definition *def);
00580 R operator() (V1 *v1, V2 *v2, T1 t1, T2 t2);
00581
00582 private:
00583 XTypeInfo::ClassDef *m_formals [2];
00584 };
00585
00589 template <class R, class V1, class V2, class V3>
00590 class MultiMethod_3_0 : public MultiMethod
00591 {
00592 public:
00593 static const int NVIRT = 3;
00594 static const int NNONVIRT = 0;
00595 typedef R RTYPE;
00596 typedef V1 VTYPE1;
00597 typedef V2 VTYPE2;
00598 typedef V3 VTYPE3;
00599
00600 MultiMethod_3_0 (Definition *def);
00601 R operator() (V1 *v1, V2 *v2, V3 *v3);
00602
00603 private:
00604 XTypeInfo::ClassDef *m_formals [3];
00605 };
00606
00607 template <class R, class V1, class V2, class V3, class T1>
00608 class MultiMethod_3_1 : public MultiMethod
00609 {
00610 public:
00611 static const int NVIRT = 3;
00612 static const int NNONVIRT = 1;
00613 typedef R RTYPE;
00614 typedef V1 VTYPE1;
00615 typedef V2 VTYPE2;
00616 typedef V3 VTYPE3;
00617 typedef T1 NONVTYPE1;
00618
00619 MultiMethod_3_1 (Definition *def);
00620 R operator() (V1 *v1, V2 *v2, V3 *v3, T1 t1);
00621
00622 private:
00623 XTypeInfo::ClassDef *m_formals [3];
00624 };
00625
00626 template <class R, class V1, class V2, class V3, class T1, class T2>
00627 class MultiMethod_3_2 : public MultiMethod
00628 {
00629 public:
00630 static const int NVIRT = 3;
00631 static const int NNONVIRT = 2;
00632 typedef R RTYPE;
00633 typedef V1 VTYPE1;
00634 typedef V2 VTYPE2;
00635 typedef V3 VTYPE3;
00636 typedef T1 NONVTYPE1;
00637 typedef T2 NONVTYPE2;
00638
00639 MultiMethod_3_2 (Definition *def);
00640 R operator() (V1 *v1, V2 *v2, V3 *v3, T1 t1, T2 t2);
00641
00642 private:
00643 XTypeInfo::ClassDef *m_formals [3];
00644 };
00645
00649
00662 template <int NV, int NNV, class M, class R, class P> class MultiMethodCarrier {};
00663
00695 template <class M, class P, P F, MultiMethod::Definition *D>
00696 struct MultiMethodMember {
00697 typedef MultiMethodCarrier<M::NVIRT, M::NNONVIRT, M, typename M::RTYPE, P> Carrier;
00698 MultiMethodMember (void) { MultiMethodStub ((Carrier *)0)->init(D,F); }
00699 ~MultiMethodMember (void) { MultiMethodStub ((Carrier *)0)->reset(D); }
00700 };
00701
00703
00704
00705 template <class M, class V1>
00706 struct MultiMethodMemberStub_1_0 {
00707 typedef typename M::RTYPE (*F) (V1 *);
00708 static F s_f;
00709 static void init (MultiMethod::Definition *d, F f)
00710 { static XTypeInfo::ClassDef *actuals [M::NVIRT] = { xtypedata(V1) };
00711 s_f = f; d->extend ((MultiMethod::MemberFunction) &stub, actuals); }
00712 static void reset (MultiMethod::Definition *d)
00713 { d->remove ((MultiMethod::MemberFunction) &stub); }
00714 static typename M::RTYPE stub (typename M::VTYPE1 *v1)
00715 { return s_f (dynamic_cast<V1 *> (v1)); }
00716 };
00717
00718 template <class M, class V1>
00719 struct MultiMethodMemberStub_1_1 {
00720 typedef typename M::RTYPE (*F) (V1 *, typename M::NONVTYPE1);
00721 static F s_f;
00722 static void init (MultiMethod::Definition *d, F f)
00723 { static XTypeInfo::ClassDef *actuals [M::NVIRT] = { xtypedata(V1) };
00724 s_f = f; d->extend ((MultiMethod::MemberFunction) &stub, actuals); }
00725 static void reset (MultiMethod::Definition *d)
00726 { d->remove ((MultiMethod::MemberFunction) &stub); }
00727 static typename M::RTYPE stub (typename M::VTYPE1 *v1,
00728 typename M::NONVTYPE1 a1)
00729 { return s_f (dynamic_cast<V1 *> (v1), a1); }
00730 };
00731
00732 template <class M, class V1>
00733 struct MultiMethodMemberStub_1_2 {
00734 typedef typename M::RTYPE (*F) (V1 *, typename M::NONVTYPE1,
00735 typename M::NONVTYPE2);
00736 static F s_f;
00737 static void init (MultiMethod::Definition *d, F f)
00738 { static XTypeInfo::ClassDef *actuals [M::NVIRT] = { xtypedata(V1) };
00739 s_f = f; d->extend ((MultiMethod::MemberFunction) &stub, actuals); }
00740 static void reset (MultiMethod::Definition *d)
00741 { d->remove ((MultiMethod::MemberFunction) &stub); }
00742 static typename M::RTYPE stub (typename M::VTYPE1 *v1,
00743 typename M::NONVTYPE1 a1,
00744 typename M::NONVTYPE2 a2)
00745 { return s_f (dynamic_cast<V1 *> (v1), a1, a2); }
00746 };
00747
00749 template <class M, class V1, class V2>
00750 struct MultiMethodMemberStub_2_0 {
00751 typedef typename M::RTYPE (*F) (V1 *, V2 *);
00752 static F s_f;
00753 static void init (MultiMethod::Definition *d, F f)
00754 { static XTypeInfo::ClassDef *actuals [M::NVIRT]
00755 = { xtypedata(V1), xtypedata(V2) };
00756 s_f = f; d->extend ((MultiMethod::MemberFunction) &stub, actuals); }
00757 static void reset (MultiMethod::Definition *d)
00758 { d->remove ((MultiMethod::MemberFunction) &stub); }
00759 static typename M::RTYPE stub (typename M::VTYPE1 *v1,
00760 typename M::VTYPE2 *v2)
00761 { return s_f (dynamic_cast<V1 *> (v1), dynamic_cast<V2 *> (v2)); }
00762 };
00763
00764 template <class M, class V1, class V2>
00765 struct MultiMethodMemberStub_2_1 {
00766 typedef typename M::RTYPE (*F) (V1 *, V2 *, typename M::NONVTYPE1);
00767 static F s_f;
00768 static void init (MultiMethod::Definition *d, F f)
00769 { static XTypeInfo::ClassDef *actuals [M::NVIRT]
00770 = { xtypedata(V1), xtypedata(V2) };
00771 s_f = f; d->extend ((MultiMethod::MemberFunction) &stub, actuals); }
00772 static void reset (MultiMethod::Definition *d)
00773 { d->remove ((MultiMethod::MemberFunction) &stub); }
00774 static typename M::RTYPE stub (typename M::VTYPE1 *v1,
00775 typename M::VTYPE2 *v2,
00776 typename M::NONVTYPE1 a1)
00777 { return s_f (dynamic_cast<V1 *> (v1), dynamic_cast<V2 *> (v2), a1); }
00778 };
00779
00780 template <class M, class V1, class V2>
00781 struct MultiMethodMemberStub_2_2 {
00782 typedef typename M::RTYPE (*F) (V1 *, V2 *, typename M::NONVTYPE1,
00783 typename M::NONVTYPE2);
00784 static F s_f;
00785 static void init (MultiMethod::Definition *d, F f)
00786 { static XTypeInfo::ClassDef *actuals [M::NVIRT]
00787 = { xtypedata(V1), xtypedata(V2) };
00788 s_f = f; d->extend ((MultiMethod::MemberFunction) &stub, actuals); }
00789 static void reset (MultiMethod::Definition *d)
00790 { d->remove ((MultiMethod::MemberFunction) &stub); }
00791 static typename M::RTYPE stub (typename M::VTYPE1 *v1,
00792 typename M::VTYPE2 *v2,
00793 typename M::NONVTYPE1 a1,
00794 typename M::NONVTYPE2 a2)
00795 { return s_f (dynamic_cast<V1 *> (v1), dynamic_cast<V2 *> (v2),
00796 a1, a2); }
00797 };
00798
00800 template <class M, class V1, class V2, class V3>
00801 struct MultiMethodMemberStub_3_0 {
00802 typedef typename M::RTYPE (*F) (V1 *, V2 *, V3 *);
00803 static F s_f;
00804 static void init (MultiMethod::Definition *d, F f)
00805 { static XTypeInfo::ClassDef *actuals [M::NVIRT]
00806 = { xtypedata(V1), xtypedata(V2), xtypedata(V3) };
00807 s_f = f; d->extend ((MultiMethod::MemberFunction) &stub, actuals); }
00808 static void reset (MultiMethod::Definition *d)
00809 { d->remove ((MultiMethod::MemberFunction) &stub); }
00810 static typename M::RTYPE stub (typename M::VTYPE1 *v1,
00811 typename M::VTYPE2 *v2,
00812 typename M::VTYPE3 *v3)
00813 { return s_f (dynamic_cast<V1 *> (v1), dynamic_cast<V2 *> (v2),
00814 dynamic_cast<V3 *> (v3)); }
00815 };
00816
00817 template <class M, class V1, class V2, class V3>
00818 struct MultiMethodMemberStub_3_1 {
00819 typedef typename M::RTYPE (*F) (V1 *, V2 *, V3 *, typename M::NONVTYPE1);
00820 static F s_f;
00821 static void init (MultiMethod::Definition *d, F f)
00822 { static XTypeInfo::ClassDef *actuals [M::NVIRT]
00823 = { xtypedata(V1), xtypedata(V2), xtypedata(V3) };
00824 s_f = f; d->extend ((MultiMethod::MemberFunction) &stub, actuals); }
00825 static void reset (MultiMethod::Definition *d)
00826 { d->remove ((MultiMethod::MemberFunction) &stub); }
00827 static typename M::RTYPE stub (typename M::VTYPE1 *v1,
00828 typename M::VTYPE2 *v2,
00829 typename M::VTYPE3 *v3,
00830 typename M::NONVTYPE1 a1)
00831 { return s_f (dynamic_cast<V1 *> (v1), dynamic_cast<V2 *> (v2),
00832 dynamic_cast<V3 *> (v3), a1); }
00833 };
00834
00835 template <class M, class V1, class V2, class V3>
00836 struct MultiMethodMemberStub_3_2 {
00837 typedef typename M::RTYPE (*F) (V1 *, V2 *, V3 *, typename M::NONVTYPE1,
00838 typename M::NONVTYPE2);
00839 static F s_f;
00840 static void init (MultiMethod::Definition *d, F f)
00841 { static XTypeInfo::ClassDef *actuals [M::NVIRT]
00842 = { xtypedata(V1), xtypedata(V2), xtypedata(V3) };
00843 s_f = f; d->extend ((MultiMethod::MemberFunction) &stub, actuals); }
00844 static void reset (MultiMethod::Definition *d)
00845 { d->remove ((MultiMethod::MemberFunction) &stub); }
00846 static typename M::RTYPE stub (typename M::VTYPE1 *v1,
00847 typename M::VTYPE2 *v2,
00848 typename M::VTYPE3 *v3,
00849 typename M::NONVTYPE1 a1,
00850 typename M::NONVTYPE2 a2)
00851 { return s_f (dynamic_cast<V1 *> (v1), dynamic_cast<V2 *> (v2),
00852 dynamic_cast<V3 *> (v3), a1, a2); }
00853 };
00854
00856 template <class M, class V1>
00857 typename MultiMethodMemberStub_1_0<M,V1>::F
00858 MultiMethodMemberStub_1_0<M,V1>::s_f = 0;
00859 template <class M, class V1>
00860 typename MultiMethodMemberStub_1_1<M,V1>::F
00861 MultiMethodMemberStub_1_1<M,V1>::s_f = 0;
00862 template <class M, class V1>
00863 typename MultiMethodMemberStub_1_2<M,V1>::F
00864 MultiMethodMemberStub_1_2<M,V1>::s_f = 0;
00865
00866 template <class M, class V1, class V2>
00867 typename MultiMethodMemberStub_2_0<M,V1,V2>::F
00868 MultiMethodMemberStub_2_0<M,V1,V2>::s_f = 0;
00869 template <class M, class V1, class V2>
00870 typename MultiMethodMemberStub_2_1<M,V1,V2>::F
00871 MultiMethodMemberStub_2_1<M,V1,V2>::s_f = 0;
00872 template <class M, class V1, class V2>
00873 typename MultiMethodMemberStub_2_2<M,V1,V2>::F
00874 MultiMethodMemberStub_2_2<M,V1,V2>::s_f = 0;
00875
00876 template <class M, class V1, class V2, class V3>
00877 typename MultiMethodMemberStub_3_0<M,V1,V2,V3>::F
00878 MultiMethodMemberStub_3_0<M,V1,V2,V3>::s_f = 0;
00879 template <class M, class V1, class V2, class V3>
00880 typename MultiMethodMemberStub_3_1<M,V1,V2,V3>::F
00881 MultiMethodMemberStub_3_1<M,V1,V2,V3>::s_f = 0;
00882 template <class M, class V1, class V2, class V3>
00883 typename MultiMethodMemberStub_3_2<M,V1,V2,V3>::F
00884 MultiMethodMemberStub_3_2<M,V1,V2,V3>::s_f = 0;
00885
00886
00887
00888
00889 template <class R, class V1>
00890 inline
00891 MultiMethod_1_0<R,V1>::MultiMethod_1_0 (Definition *def)
00892 {
00893 m_formals [0] = xtypedata (V1);
00894 initialise (def, 1, m_formals);
00895 }
00896
00897 template <class R, class V1>
00898 inline R
00899 MultiMethod_1_0<R,V1>::operator() (V1 *v1)
00900 {
00901 XTypeInfo *actuals [1] = { xtypeid (*v1) };
00902 Score *candidates [1];
00903 Score best [1];
00904 MemberFunction match;
00905
00906 match = dispatch (actuals, candidates, best);
00907 return (*reinterpret_cast<R (*) (V1 *)> (match))
00908 (v1);
00909 }
00910
00912
00913 template <class R, class V1, class T1>
00914 inline
00915 MultiMethod_1_1<R,V1,T1>::MultiMethod_1_1 (Definition *def)
00916 {
00917 m_formals [0] = xtypedata (V1);
00918 initialise (def, 1, m_formals);
00919 }
00920
00921 template <class R, class V1, class T1>
00922 inline R
00923 MultiMethod_1_1<R,V1,T1>::operator() (V1 *v1, T1 t1)
00924 {
00925 XTypeInfo *actuals [1] = { xtypeid (*v1) };
00926 Score *candidates [1];
00927 Score best [1];
00928 MemberFunction match;
00929
00930 match = dispatch (actuals, candidates, best);
00931 return (*reinterpret_cast<R (*) (V1 *, T1)> (match))
00932 (v1, t1);
00933 }
00934
00936 template <class R, class V1, class T1, class T2>
00937 inline
00938 MultiMethod_1_2<R,V1,T1,T2>::MultiMethod_1_2 (Definition *def)
00939 {
00940 m_formals [0] = xtypedata (V1);
00941 initialise (def, 1, m_formals);
00942 }
00943
00944 template <class R, class V1, class T1, class T2>
00945 inline R
00946 MultiMethod_1_2<R,V1,T1,T2>::operator() (V1 *v1, T1 t1, T2 t2)
00947 {
00948 XTypeInfo *actuals [1] = { xtypeid (*v1) };
00949 Score *candidates [1];
00950 Score best [1];
00951 MemberFunction match;
00952
00953 match = dispatch (actuals, candidates, best);
00954 return (*reinterpret_cast<R (*) (V1 *, T1, T2)> (match))
00955 (v1, t1, t2);
00956 }
00957
00961 template <class R, class V1, class V2>
00962 inline
00963 MultiMethod_2_0<R,V1,V2>::MultiMethod_2_0 (Definition *def)
00964 {
00965 m_formals [0] = xtypedata (V1);
00966 m_formals [1] = xtypedata (V2);
00967 initialise (def, 2, m_formals);
00968 }
00969
00970 template <class R, class V1, class V2>
00971 inline R
00972 MultiMethod_2_0<R,V1,V2>::operator() (V1 *v1, V2 *v2)
00973 {
00974 XTypeInfo *actuals [2] = { xtypeid (*v1), xtypeid (*v2) };
00975 Score *candidates [2];
00976 Score best [2];
00977 MemberFunction match;
00978
00979 match = dispatch (actuals, candidates, best);
00980 return (*reinterpret_cast<R (*) (V1 *, V2 *)> (match))
00981 (v1, v2);
00982 }
00983
00985 template <class R, class V1, class V2, class T1>
00986 inline
00987 MultiMethod_2_1<R,V1,V2,T1>::MultiMethod_2_1 (Definition *def)
00988 {
00989 m_formals [0] = xtypedata (V1);
00990 m_formals [1] = xtypedata (V2);
00991 initialise (def, 2, m_formals);
00992 }
00993
00994 template <class R, class V1, class V2, class T1>
00995 inline R
00996 MultiMethod_2_1<R,V1,V2,T1>::operator() (V1 *v1, V2 *v2, T1 t1)
00997 {
00998 XTypeInfo *actuals [2] = { xtypeid (*v1), xtypeid (*v2) };
00999 Score *candidates [2];
01000 Score best [2];
01001 MemberFunction match;
01002
01003 match = dispatch (actuals, candidates, best);
01004 return (*reinterpret_cast<R (*) (V1 *, V2 *, T1)> (match))
01005 (v1, v2, t1);
01006 }
01007
01009 template <class R, class V1, class V2, class T1, class T2>
01010 inline
01011 MultiMethod_2_2<R,V1,V2,T1,T2>::MultiMethod_2_2 (Definition *def)
01012 {
01013 m_formals [0] = xtypedata (V1);
01014 m_formals [1] = xtypedata (V2);
01015 initialise (def, 2, m_formals);
01016 }
01017
01018 template <class R, class V1, class V2, class T1, class T2>
01019 inline R
01020 MultiMethod_2_2<R,V1,V2,T1,T2>::operator() (V1 *v1, V2 *v2, T1 t1, T2 t2)
01021 {
01022 XTypeInfo *actuals [2] = { xtypeid (*v1), xtypeid (*v2) };
01023 Score *candidates [2];
01024 Score best [2];
01025 MemberFunction match;
01026
01027 match = dispatch (actuals, candidates, best);
01028 return (*reinterpret_cast<R (*) (V1 *, V2 *, T1, T2)> (match))
01029 (v1, v2, t1, t2);
01030 }
01031
01035 template <class R, class V1, class V2, class V3>
01036 inline
01037 MultiMethod_3_0<R,V1,V2,V3>::MultiMethod_3_0 (Definition *def)
01038 {
01039 m_formals [0] = xtypedata (V1);
01040 m_formals [1] = xtypedata (V2);
01041 m_formals [3] = xtypedata (V3);
01042 initialise (def, 3, m_formals);
01043 }
01044
01045 template <class R, class V1, class V2, class V3>
01046 inline R
01047 MultiMethod_3_0<R,V1,V2,V3>::operator() (V1 *v1, V2 *v2, V3 *v3)
01048 {
01049 XTypeInfo *actuals [3] = { xtypeid (*v1), xtypeid (*v2), xtypeid (*v3) };
01050 Score *candidates [3];
01051 Score best [3];
01052 MemberFunction match;
01053
01054 match = dispatch (actuals, candidates, best);
01055 return (*reinterpret_cast<R (*) (V1 *, V2 *, V3 *)> (match))
01056 (v1, v2, v3);
01057 }
01058
01060 template <class R, class V1, class V2, class V3, class T1>
01061 inline
01062 MultiMethod_3_1<R,V1,V2,V3,T1>::MultiMethod_3_1 (Definition *def)
01063 {
01064 m_formals [0] = xtypedata (V1);
01065 m_formals [1] = xtypedata (V2);
01066 m_formals [3] = xtypedata (V3);
01067 initialise (def, 3, m_formals);
01068 }
01069
01070 template <class R, class V1, class V2, class V3, class T1>
01071 inline R
01072 MultiMethod_3_1<R,V1,V2,V3,T1>::operator() (V1 *v1, V2 *v2, V3 *v3, T1 t1)
01073 {
01074 XTypeInfo *actuals [3] = { xtypeid (*v1), xtypeid (*v2), xtypeid (*v3) };
01075 Score *candidates [3];
01076 Score best [3];
01077 MemberFunction match;
01078
01079 match = dispatch (actuals, candidates, best);
01080 return (*reinterpret_cast<R (*) (V1 *, V2 *, V3 *, T1)> (match))
01081 (v1, v2, v3, t1);
01082 }
01083
01085 template <class R, class V1, class V2, class V3, class T1, class T2>
01086 inline
01087 MultiMethod_3_2<R,V1,V2,V3,T1,T2>::MultiMethod_3_2 (Definition *def)
01088 {
01089 m_formals [0] = xtypedata (V1);
01090 m_formals [1] = xtypedata (V2);
01091 m_formals [3] = xtypedata (V3);
01092 initialise (def, 3, m_formals);
01093 }
01094
01095 template <class R, class V1, class V2, class V3, class T1, class T2>
01096 inline R
01097 MultiMethod_3_2<R,V1,V2,V3,T1,T2>::operator() (V1 *v1, V2 *v2, V3 *v3, T1 t1, T2 t2)
01098 {
01099 XTypeInfo *actuals [3] = { xtypeid (*v1), xtypeid (*v2), xtypeid (*v3) };
01100 Score *candidates [3];
01101 Score best [3];
01102 MemberFunction match;
01103
01104 match = dispatch (actuals, candidates, best);
01105 return (*reinterpret_cast<R (*) (V1 *, V2 *, V3 *, T1, T2)> (match))
01106 (v1, v2, v3, t1, t2);
01107 }
01108
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133 template <class M, class R, class V1>
01134 inline MultiMethodMemberStub_1_0<M,V1> *
01135 MultiMethodStub (MultiMethodCarrier<1,0,M,R, R (*) (V1*)> *)
01136 { return 0; }
01137
01138 template <class M, class R, class V1, class A1>
01139 inline MultiMethodMemberStub_1_1<M,V1> *
01140 MultiMethodStub (MultiMethodCarrier<1,1,M,R, R (*) (V1 *, A1)> *)
01141 { (void) static_cast<A1 **> ((typename M::NONVTYPE1 **) 0); return 0; }
01142
01143 template <class M, class R, class V1, class A1, class A2>
01144 inline MultiMethodMemberStub_1_2<M,V1> *
01145 MultiMethodStub (MultiMethodCarrier<1,2,M,R, R (*) (V1 *, A1, A2)> *)
01146 { (void) static_cast<A1 **> ((typename M::NONVTYPE1 **) 0);
01147 (void) static_cast<A2 **> ((typename M::NONVTYPE2 **) 0); return 0; }
01148
01150 template <class M, class R, class V1, class V2>
01151 inline MultiMethodMemberStub_2_0<M,V1,V2> *
01152 MultiMethodStub (MultiMethodCarrier<2,0,M,R, R (*) (V1 *, V2 *)> *)
01153 { return 0; }
01154
01155 template <class M, class R, class V1, class V2, class A1>
01156 inline MultiMethodMemberStub_2_1<M,V1,V2> *
01157 MultiMethodStub (MultiMethodCarrier<2,1,M,R, R (*) (V1 *, V2 *, A1)> *)
01158 { (void) static_cast<A1 **> ((typename M::NONVTYPE1 **) 0); return 0; }
01159
01160 template <class M, class R, class V1, class V2, class A1, class A2>
01161 inline MultiMethodMemberStub_2_2<M,V1,V2> *
01162 MultiMethodStub (MultiMethodCarrier<2,2,M,R, R (*) (V1 *, V2 *, A1, A2)> *)
01163 { (void) static_cast<A1 **> ((typename M::NONVTYPE1 **) 0);
01164 (void) static_cast<A2 **> ((typename M::NONVTYPE2 **) 0); return 0; }
01165
01167 template <class M, class R, class V1, class V2, class V3>
01168 inline MultiMethodMemberStub_3_0<M,V1,V2,V3> *
01169 MultiMethodStub (MultiMethodCarrier<3,0,M,R, R (*) (V1 *, V2 *, V3 *)> *)
01170 { return 0; }
01171
01172 template <class M, class R, class V1, class V2, class V3, class A1>
01173 inline MultiMethodMemberStub_3_1<M,V1,V2,V3> *
01174 MultiMethodStub (MultiMethodCarrier<3,1,M,R, R (*) (V1 *, V2 *, V3 *, A1)> *)
01175 { (void) static_cast<A1 **> ((typename M::NONVTYPE1 **) 0); return 0; }
01176
01177 template <class M, class R, class V1, class V2, class V3, class A1, class A2>
01178 inline MultiMethodMemberStub_3_2<M,V1,V2,V3> *
01179 MultiMethodStub (MultiMethodCarrier<3,2,M,R, R (*) (V1 *, V2 *, V3 *, A1, A2)> *)
01180 { (void) static_cast<A1 **> ((typename M::NONVTYPE1 **) 0);
01181 (void) static_cast<A2 **> ((typename M::NONVTYPE2 **) 0); return 0; }
01182
01183 }
01184 #endif // CLASSLIB_MULTIMETHOD_H