www.digitalmars.com         C & C++   DMDScript  

c++ - Fast Template Visitor Library

reply Anand Krishnamoorthi <anand.shankar.k gmail.com> writes:
Hi,

I've been working on a `Visitor' generation library.
The main advantages being aimed for are:

1) N number of arguments and return type ( templatized )
2) Prevent coupling between classes
3) Easy to add new classes
4) Not having to declare a Visitor interface with visit methods
5) Efficient dispatch: equivalent to a virtual function call
( normally a visitor requires 2 virt calls; acyclic visitor
requires a dynamic cast )
6) Add new visit methods at runtime

One drawback includes having to register each visit method.
But this is also allows runtime flexibility.

A visitor can be created as a singleton if needed.

The code has been developed using VC++ 8.0.
The implementation techniques include assigning tags to classes
on the fly, building virtual table internally, creating thunk
functions, a cast policy etc.

Cvisitor.h contains the library.
test1.cpp contains an example for a Shape heirarchy.

Please feel free to discuss the code.
Comments and suggestions are welcome.

Thanks,
Anand.
begin 644 CVisitor.h

M"B-I;F-L=61E(#QS=&1D968N:#X-"B-I;F-L=61E(#P =F5C=&]R(#X-"B-I
M;F-L=61E(#P
M(#X-

M('L <F5T=7)N('-T871I8U]C87-T/"!$97)V*B`^*"!B("D[('T-" T*?3L-
M" T*=&5M<&QA=&4\('1Y<&5N86UE($)A<V4L('1E;7!L871E/"!C;&%S<R`^
M(&-L87-S($-A<W10;VQI8WD /2!$969A=6QT0V%S=%!O;&EC>2` / T*8VQA


M"G1E;7!L871E/"!T>7!E;F%M92!$97)V(#X-"G-T<G5C="!.97=486< >PT*



M"G!U8FQI8SH-" T*=&5M<&QA=&4\('1Y<&5N86UE($1E<G8 / T*<W1R=6-T

M97)V(#XZ.G-?;F5W7W1A9U\N=&%G7SL ?0T*?3L-" T*<')I=F%T93H-" T*
M=&5M<&QA=&4\('1Y<&5N86UE($9U;F, / T*8VQA<W, 5E1A8FQE('L-"G!U
M8FQI8SH-" T*5E1A8FQE*"!&=6YC(&1E9B`I(#H 9&5F875L=%\H(&1E9B`I
M('L 861D/"!"87-E(#XH(&1E9F%U;'1?("D[('T-" T*=&5M<&QA=&4\('1Y

M<W0 <VEZ95]T(&EN9&5X(#T
M:68H('9T86)L95\N<VEZ92 I(#P
M>F5?="!C;W5N="`](&EN9&5X("L ,2`M('9T86)L95\N<VEZ92 I.PT*"0EV
M=&%B;&5?+FEN<V5R="  =G1A8FQE7RYE;F0H*2P 8V]U;G0L(&1E9F%U;'1?


M*3L-" EI9B  :6YD97  /CT =G1A8FQE7RYS:7IE*"D *0T*"0EI;F1E>"`]
M($1I<W!A=&-H.CI486<\($)A<V4 /B I.PT*"7)E='5R;B!V=&%B;&5?6R!I

M($9U;F, /B!486)L93L-" E486)L92!V=&%B;&5?.PT*"49U;F, 9&5F875L

M(%)E="`]('9O:60L(`T*"71Y<&5N86UE($$Q(#T =F]I9"P-" ET>7!E;F%M

M($$T(#T

M961E9B!2970 *%9I<VET;W(Z.BI&=6YC*2  0F%S92HL($$Q+"!!,BP 03,L


M<&5N86UE($1E<G8L(%)E="`H5FES:71O<D1E<G8Z.BIF=6YC*2  1&5R=BHL
M($$Q+"!!,BP 03,L($$T+"!!-2P 038I(#X-"E)E="!T:'5N:R  0F%S92H 
M8BP 03$ 83$L($$R(&$R+"!!,R!A,RP 030 830L($$U(&$U+"!!-B!A-B`I

M:&ES*2T^*F9U;F, *2`H($-A<W10;VQI8WD\($1E<G8 /CHZ0V%S="  8B`I



M871E/"!T>7!E;F%M92!6:7-I=&]R1&5R=BP ='EP96YA;64 1&5R=BP 4F5T
M("A6:7-I=&]R1&5R=CHZ*F9U;F,I*"!$97)V*BP 03$L($$R+"!!,RP 030L
M($$U+"!!-BD / T*5FES:71O<B8 861D*"D-"GL-" EV=&%B;&5?+F%D9#P 
M1&5R=B`^*"`F5FES:71O<CHZ=&AU;FL\(%9I<VET;W)$97)V+"!$97)V+"!F

M*2  0F%S92H 8BP 03$ 83$L($$R(&$R+"!!,R!A,RP 030 830L($$U(&$U

M("D *2`H(&(L(&$Q+"!A,BP 83,L(&$T+"!A-2P 838 *3L-"GT-" T*?3L-



M($$R+"!!,RP 030L($$U+"!V;VED(#X >PT*<')I=F%T93H-" ET>7!E9&5F
M(%)E="`H5FES:71O<CHZ*D9U;F,I*"!"87-E*BP 03$L($$R+"!!,RP 030L

M. T*=&5M<&QA=&4\('1Y<&5N86UE(%9I<VET;W)$97)V+"!T>7!E;F%M92!$
M97)V+"!2970 *%9I<VET;W)$97)V.CHJ9G5N8RDH($1E<G8J+"!!,2P 03(L


M=&EC7V-A<W0\(%9I<VET;W)$97)V*B`^*"!T:&ES*2T^*F9U;F, *2`H($-A
M<W10;VQI8WD\($1E<G8 /CHZ0V%S="  8B`I+"!A,2P 83(L(&$S+"!A-"P 


M971U<FX *G1H:7,[('T-" T*=&5M<&QA=&4\('1Y<&5N86UE(%9I<VET;W)$
M97)V+"!T>7!E;F%M92!$97)V+"!2970 *%9I<VET;W)$97)V.CHJ9G5N8RDH

M*0T*>PT*"79T86)L95\N861D/"!$97)V(#XH("96:7-I=&]R.CIT:'5N:SP 


M($$S(&$S+"!!-"!A-"P 034 834 *0T*>PT*"7)E='5R;B`H('1H:7,M/BIV
M=&%B;&5?+F=E="  8B`I("D *"!B+"!A,2P 83(L(&$S+"!A-"P 834 *3L-
M"GT-" T*?3L-" T*=&5M<&QA=&4\(`T*"71Y<&5N86UE(%)E="`L(`T*"71Y
M<&5N86UE($$Q+`T*"71Y<&5N86UE($$R+`T*"71Y<&5N86UE($$S+`T*"71Y

M($$T+"!V;VED+"!V;VED(#X >PT*<')I=F%T93H-" ET>7!E9&5F(%)E="`H
M5FES:71O<CHZ*D9U;F,I*"!"87-E*BP 03$L($$R+"!!,RP 030 *3L-" E6

M93P ='EP96YA;64 5FES:71O<D1E<G8L('1Y<&5N86UE($1E<G8L(%)E="`H
M5FES:71O<D1E<G8Z.BIF=6YC*2  1&5R=BHL($$Q+"!!,BP 03,L($$T("D 
M/ T*4F5T('1H=6YK*"!"87-E*B!B+"!!,2!A,2P 03( 83(L($$S(&$S+"!!

M*B`^*"!T:&ES*2T^*F9U;F, *2`H($-A<W10;VQI8WD\($1E<G8 /CHZ0V%S

M<VET;W(H($9U;F, 9&5F("D .B!V=&%B;&5?*"!D968 *2![('T-" T*5FES

M93P ='EP96YA;64 5FES:71O<D1E<G8L('1Y<&5N86UE($1E<G8L(%)E="`H
M5FES:71O<D1E<G8Z.BIF=6YC*2  1&5R=BHL($$Q+"!!,BP 03,L($$T("D 
M/ T*5FES:71O<B8 861D*"D-"GL-" EV=&%B;&5?+F%D9#P 1&5R=B`^*"`F
M5FES:71O<CHZ=&AU;FL\(%9I<VET;W)$97)V+"!$97)V+"!F=6YC/B`I.PT*

M8BP 03$ 83$L($$R(&$R+"!!,R!A,RP 030 830 *0T*>PT*"7)E='5R;B`H
M('1H:7,M/BIV=&%B;&5?+F=E="  8B`I("D *"!B+"!A,2P 83(L(&$S+"!A


M"CX-"F-L87-S(%9I<VET;W(\(%)E="P 03$L($$R+"!!,RP =F]I9"P =F]I

M.BI&=6YC*2  0F%S92HL($$Q+"!!,BP 03, *3L-" E65&%B;&4\($9U;F, 

M5FES:71O<D1E<G8L('1Y<&5N86UE($1E<G8L(%)E="`H5FES:71O<D1E<G8Z

M<V4J(&(L($$Q(&$Q+"!!,B!A,BP 03, 83, *0T*>PT*"7)E='5R;B`H('-T

M87-T4&]L:6-Y/"!$97)V(#XZ.D-A<W0H(&( *2P 83$L(&$R+"!A,R`I.PT*

M*"!D968 *2![('T-" T*5FES:71O<B8 ;W9E<G)I9&4H*2![(')E='5R;B`J

M<&5N86UE($1E<G8L(%)E="`H5FES:71O<D1E<G8Z.BIF=6YC*2  1&5R=BHL

M861D/"!$97)V(#XH("96:7-I=&]R.CIT:'5N:SP 5FES:71O<D1E<G8L($1E

M871O<B I*"!"87-E*B!B+"!!,2!A,2P 03( 83(L($$S(&$S("D-"GL-" ER
M971U<FX *"!T:&ES+3XJ=G1A8FQE7RYG970H(&( *2`I("  8BP 83$L(&$R


M<VET;W(\(%)E="P 03$L($$R+"!V;VED+"!V;VED+"!V;VED+"!V;VED(#X 
M>PT*<')I=F%T93H-" ET>7!E9&5F(%)E="`H5FES:71O<CHZ*D9U;F,I*"!"

M<')O=&5C=&5D. T*=&5M<&QA=&4\('1Y<&5N86UE(%9I<VET;W)$97)V+"!T
M>7!E;F%M92!$97)V+"!2970 *%9I<VET;W)$97)V.CHJ9G5N8RDH($1E<G8J


M*"!T:&ES*2T^*F9U;F, *2`H($-A<W10;VQI8WD\($1E<G8 /CHZ0V%S="  

M(&1E9B`I(#H
M:61E*"D >R!R971U<FX *G1H:7,[('T-" T*=&5M<&QA=&4\('1Y<&5N86UE
M(%9I<VET;W)$97)V+"!T>7!E;F%M92!$97)V+"!2970 *%9I<VET;W)$97)V

M>PT*"79T86)L95\N861D/"!$97)V(#XH("96:7-I=&]R.CIT:'5N:SP 5FES


M>PT*"7)E='5R;B`H('1H:7,M/BIV=&%B;&5?+F=E="  8B`I("D *"!B+"!A
M,2P 83( *3L-"GT-" T*?3L-" T*=&5M<&QA=&4\(`T*"71Y<&5N86UE(%)E

M+"!V;VED+"!V;VED+"!V;VED+"!V;VED+"!V;VED(#X >PT*<')I=F%T93H-
M" ET>7!E9&5F(%)E="`H5FES:71O<CHZ*D9U;F,I*"!"87-E*BP 03$ *3L-

M;&%T93P ='EP96YA;64 5FES:71O<D1E<G8L('1Y<&5N86UE($1E<G8L(%)E
M="`H5FES:71O<D1E<G8Z.BIF=6YC*2  1&5R=BHL($$Q("D / T*4F5T('1H

M<W0\(%9I<VET;W)$97)V*B`^*"!T:&ES*2T^*F9U;F, *2`H($-A<W10;VQI

M"E9I<VET;W(H($9U;F, 9&5F("D .B!V=&%B;&5?*"!D968 *2![('T-" T*

M;&%T93P ='EP96YA;64 5FES:71O<D1E<G8L('1Y<&5N86UE($1E<G8L(%)E
M="`H5FES:71O<D1E<G8Z.BIF=6YC*2  1&5R=BHL($$Q("D / T*5FES:71O
M<B8 861D*"D-"GL-" EV=&%B;&5?+F%D9#P 1&5R=B`^*"`F5FES:71O<CHZ
M=&AU;FL\(%9I<VET;W)$97)V+"!$97)V+"!F=6YC/B`I.PT*"7)E='5R;B`J

M*0T*>PT*"7)E='5R;B`H('1H:7,M/BIV=&%B;&5?+F=E="  8B`I("D *"!B



M*%9I<VET;W(Z.BI&=6YC*2  0F%S92H *3L-" E65&%B;&4\($9U;F, /B!V

M:71O<D1E<G8L('1Y<&5N86UE($1E<G8L(%)E="`H5FES:71O<D1E<G8Z.BIF

M='5R;B`H('-T871I8U]C87-T/"!6:7-I=&]R1&5R=BH /B  =&AI<RDM/BIF


M968 *2![('T-" T*5FES:71O<B8 ;W9E<G)I9&4H*2![(')E='5R;B`J=&AI

M86UE($1E<G8L(%)E="`H5FES:71O<D1E<G8Z.BIF=6YC*2  1&5R=BH *2`^



M("D-"GL-" ER971U<FX *"!T:&ES+3XJ=G1A8FQE7RYG970H(&( *2`I("  

M92P =&5M<&QA=&4\(&-L87-S(#X
M7W0 1&ES<&%T8V \($)A<V4L($-A<W10;VQI8WD /CHZ<U]T86=?(#T ,#L-
M" T*=&5M<&QA=&4\('1Y<&5N86UE($)A<V4L('1E;7!L871E/"!C;&%S<R`^
M(&-L87-S($-A<W10;VQI8WD / T*=&5M<&QA=&4\('1Y<&5N86UE($1E<G8 
M/ T*='EP96YA;64 1&ES<&%T8V \($)A<V4L($-A<W10;VQI8WD /CHZ=&5M
M<&QA=&4 3F5W5&%G/"!$97)V(#X-"G1Y<&5N86UE($1I<W!A=&-H/"!"87-E


`
end
begin 644 test1.cpp

M"B-I;F-L=61E(#QV96-T
M(&$ :&5L<&5R(&-L87-S('1O(&%S<VEG;B!R:6=H="!T86< 9F]R(&$ 8VQA
M<W,-"B\O(&5A8V  8VQA<W, :6X =&AE(&AE:7)A<F-H>2!N965D<R!T;R!H

M87-E(&-L87-S(&QI<W0-"G1E;7!L871E/"!T>7!E;F%M92!"87-E+"!T>7!E


M8BT^7U]S971?=&%G*"!$:7-P871C:#P 0F%S92`^.CI486<\($1E<G8 /B I
M("D[(`T*?0T*?3L-" T*8VQA<W, 4VAA<&4 .B!486=G960\(%-H87!E+"!3

M;W0 8VQA<W, :6X =&AE(&AE:7)A<F-H>0T*+R\ ;F5E9', =&\ <')O=FED





M;"!^0W5R=F4H*2![?0T*?3L-" T*+R\ 86X 97AA;7!L92!F;W( ;75L=&EP
M;&4 :6YH97)I=&%N8V4Z($-U<G9E(&ES(&%N;W1H97( <&]L>6UO<G!H:6, 
M8F%S90T*8VQA<W, 0VER8VQE(#H <'5B;&EC($-U<G9E("P <'5B;&EC(%-H




M5&%G9V5D/"!3:&%P92P 4F5C="`^('L-"G!U8FQI8SH-"E)E8W0H*2![?0T*


M=&AI<R!T>7!E('1O(&)E(&]F(&9O<FT-"B\O('-T9#HZ;W-T<F5A;28 =FES

M=6UE;G0 :7, ;F]T('-P96-I9FEE9`T*='EP961E9B!$:7-P871C:#P 4VAA
M<&4 /CHZ5FES:71O<CP <W1D.CIO<W1R96%M)BP <W1D.CIO<W1R96%M)B`^



M+R!I;7!L96UE;G0 82!D969A=6QT(&UE=&AO9`T*+R\ 8V%L;&5D(&9O<B!A
M(&YO;6%T8V  ='EP90T*<W1D.CIO<W1R96%M)B!D968H(%-H87!E*BP <W1D
M.CIO<W1R96%M)B!O=70 *2![(&]U=#P\(&YA;65?/#P *RMC;W5N=&5R7SP\
M("(Z('5N:&%N9&QE9"!3:&%P92(\/"!S=&0Z.F5N9&P[(')E='5R;B!O=70[

M8W0H(%)E8W0J+"!S=&0Z.F]S=')E86TF(&]U="`I('L ;W5T/#P ;F%M95\\
M/"`K*V-O=6YT97)?/#P (CH 4F5C="(\/"!S=&0Z.F5N9&P[(')E='5R;B!O

M*"`F4')I;G1E<D)A<V4Z.G1H=6YK/"!0<FEN=&5R+"!3:&%P92P )E!R:6YT
M97(Z.F1E9B`^("D +R\ 8V]N<W1R=6-T;W( ;75S="!P87-S('1H92!D969A




M;G1A:6YS(&)O=& -" EA9&0\(%!R:6YT97(L(%)E8W0L("90<FEN=&5R.CIP


M8W1E9#H-" EC;VYS="!C:&%R*B!N86UE7SL +R\ ;F]T('1H870 =&AE<V4 
M='=O(&UE;6)E<G, :&ED92!T:&4 ;65M8F5R<R!I;B!T:&4 8F%S92!C;&%S

M96UE;G0 =FES:70 9F]R(&-I<F-L90T*<W1D.CIO<W1R96%M)B!P<FEN=%]C
M:7(H($-I<F-L92H 8RP <W1D.CIO<W1R96%M)B!O=70 *2![(&]U=#P\(&YA
M;65?/#P *RMC;W5N=&5R7SP\("(Z($-I<F-L92`Z("(\/"!C+3YR861I=7,H
M*3P\('-T9#HZ96YD;#L <F5T=7)N(&]U=#L
M=&5R,B I(#H

M<FEN=&5R,BP 0VER8VQE+"`F4')I;G1E<C(Z.G!R:6YT7V-I<CXH*3L-"GT-
M" T*?3L-" T*='EP961E9B!S=&0Z.G9E8W1O<CP 4VAA<&4J(#X 4VAA<&56

M86-H(%-H87!E* T*=F]I9"!P<F]C97-S*"!0<FEN=&5R*B!P+"!3:&%P958J

M87!E<RT^8F5G:6XH*3L :71R("$]('-H87!E<RT^96YD*"D[("LK:71R("D 
M>PT*"0DH*G`I("  *FET<BP <W1D.CIC;W5T("D[("\O('1H:7, :7, <V5M

M+R!A9&0 82!N97< 8VQA<W, ;VX =&AE(&9L>0T*=F]I9"!E>&%M<&QE7V%D
M9%]N97=?8VQA<W-?86YD7W5P9&%T95]V:7-I=&]R*"!3:&%P958J('-H87!E




M=&AA="!I<R!L87EO=70 8V]M<&%T:6)L>2!W:71H(%!R:6YT97(-" DO+R!T
M:&ES(&ES(&IU<W0 <V\ =&AA="!W92!C86X =7!D871E('1H92!E>&ES=&EN


M<')I;G1?<W$H(%-Q=6%R92HL('-T9#HZ;W-T<F5A;28 ;W5T("D >R!O=70\
M/"!N86UE7SP\("LK8V]U;G1E<E\\/"`B.B!3<75A<F4B/#P <W1D.CIE;F1L


M(#XH
M" T*"7-H87!E<RYP=7-H7V)A8VLH(&YE=R!296-T*"D *3L-" ES:&%P97,N
M<'5S:%]B86-K*"!N97< 0VER8VQE*"`S+C$T,35F("D *3L-" T*"5!R:6YT

M=&0Z.F-O=70\/")<;EQN7&XM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM



M/2!0<FEN=&5R,B I.PT*"65X86UP;&5?861D7VYE=U]C;&%S<U]A;F1?=7!D


`
end
Apr 24 2007
parent Anand Krishnamoorthi <anand.shankar.k gmail.com> writes:
I'll test it in Digital Mars C++, G++ soon and post the results.

Anand.
Apr 24 2007