Re: Is There a Better Way To Do This?
Angus Leeming wrote: Richard Heck <[EMAIL PROTECTED]> writes: This is very boring: CommandInfo const * InsetCommandParams::findInfo( InsetCode code, std::string const & cmdName) { switch (code) { case BIBITEM_CODE: return InsetBibitem::findInfo(cmdName); case BIBTEX_CODE: return InsetBibtex::findInfo(cmdName); case CITE_CODE: return InsetCitation::findInfo(cmdName); case FLOAT_LIST_CODE: return InsetFloatList::findInfo(cmdName); case HFILL_CODE: return InsetHFill::findInfo(cmdName); What you're really implementing here is the Factory Pattern. One way to implement a factory, as you're doing here, is using a giant switch. Another way to do it is to register the content of the case statement in some map. Something like (I probably get the function pointer syntax wrong): class InsetCommandParams { typedef CommandInfo const * (FindInfoFn *)(std::string); static std::map InsetCommandParams.RegisterFindInfo(BIBITEM_CODE, InsetBibitem::findInfo); } } }; Then your InsetCommandParams::findInfo just calls into the map: CommandInfo const * InsetCommandParams::findInfo( InsetCode code, std::string const & cmdName) { return findInfoFactory[code](cmdName); } Thanks very much. This really helps me understand this "registration" thing. Possibly I'll try to implement this at some point, or just put a FIXME suggesting someone else do it This is one place where c#'s reflection tool is a real win. Don't know C#, but it's at points like this that I miss Perl: sub findInfo { $insetCode = shift; $InsetType = getInsetName($insetCode); no strict refs; return $InsetType::findInfo(); } Couldn't possibly be simpler. And in languages like Ruby, you can do even better, since types are objects. rh -- == Richard G Heck, Jr Professor of Philosophy Brown University http://frege.brown.edu/heck/ == Get my public key from http://sks.keyserver.penguin.de Hash: 0x1DE91F1E66FFBDEC Learn how to sign your email using Thunderbird and GnuPG at: http://dudu.dyn.2-h.org/nist/gpg-enigmail-howto
Re: Is There a Better Way To Do This?
Angus Leeming wrote: Richard Heck <[EMAIL PROTECTED]> writes: This is very boring: CommandInfo const * InsetCommandParams::findInfo( InsetCode code, std::string const & cmdName) { switch (code) { case BIBITEM_CODE: return InsetBibitem::findInfo(cmdName); case BIBTEX_CODE: return InsetBibtex::findInfo(cmdName); case CITE_CODE: return InsetCitation::findInfo(cmdName); case FLOAT_LIST_CODE: return InsetFloatList::findInfo(cmdName); case HFILL_CODE: return InsetHFill::findInfo(cmdName); What you're really implementing here is the Factory Pattern. One way to implement a factory, as you're doing here, is using a giant switch. Another way to do it is to register the content of the case statement in some map. Something like (I probably get the function pointer syntax wrong): class InsetCommandParams { typedef CommandInfo const * (FindInfoFn *)(std::string); static std::map InsetCommandParams.RegisterFindInfo(BIBITEM_CODE, InsetBibitem::findInfo); } } }; Then your InsetCommandParams::findInfo just calls into the map: CommandInfo const * InsetCommandParams::findInfo( InsetCode code, std::string const & cmdName) { return findInfoFactory[code](cmdName); } Thanks very much. This really helps me understand this "registration" thing. Possibly I'll try to implement this at some point, or just put a FIXME suggesting someone else do it This is one place where c#'s reflection tool is a real win. Don't know C#, but it's at points like this that I miss Perl: sub findInfo { $insetCode = shift; $InsetType = getInsetName($insetCode); no strict refs; return $InsetType::findInfo(); } Couldn't possibly be simpler. And in languages like Ruby, and I think also Python, you can do even better, since types are objects. rh -- == Richard G Heck, Jr Professor of Philosophy Brown University http://frege.brown.edu/heck/ == Get my public key from http://sks.keyserver.penguin.de Hash: 0x1DE91F1E66FFBDEC Learn how to sign your email using Thunderbird and GnuPG at: http://dudu.dyn.2-h.org/nist/gpg-enigmail-howto
Re: Is There a Better Way To Do This?
Richard Heck <[EMAIL PROTECTED]> writes: > > > This is very boring: > > CommandInfo const * InsetCommandParams::findInfo( > InsetCode code, std::string const & cmdName) > { > switch (code) { > case BIBITEM_CODE: > return InsetBibitem::findInfo(cmdName); > case BIBTEX_CODE: > return InsetBibtex::findInfo(cmdName); > case CITE_CODE: > return InsetCitation::findInfo(cmdName); > case FLOAT_LIST_CODE: > return InsetFloatList::findInfo(cmdName); > case HFILL_CODE: > return InsetHFill::findInfo(cmdName); What you're really implementing here is the Factory Pattern. One way to implement a factory, as you're doing here, is using a giant switch. Another way to do it is to register the content of the case statement in some map. Something like (I probably get the function pointer syntax wrong): class InsetCommandParams { typedef CommandInfo const * (FindInfoFn *)(std::string); static std::map
Re: Is There a Better Way To Do This?
Andre Poenitz wrote: On Wed, Oct 24, 2007 at 01:37:06PM -0400, Richard Heck wrote: Andre Poenitz wrote: On Wed, Oct 24, 2007 at 12:26:17PM -0400, Richard Heck wrote: Andre Poenitz wrote: Call a 'register' function from a constructor of a static dummy object. This is sometimes troublesome with shared objects/older compiler, though. Can you sketch this in pseudo code, perhaps? This is beyond my C++ experience. static struct FooInsetInitializer { FooInsetInitializer() { callSomeRegistrationFunction(); } } dummy; Thanks but sorry, this by itself doesn't mean much to me. I need help---or a reference---on which all this registration business is about, and how it will help me when I'm trying to call static methods of a class. Is the idea that the registration function might pass pointers to the static methods it wants called in various cases? If so, I think I vaguely understand this. But then: When and how do the InsetFooInitializer's themselves get called? They get call on application startup. All global static objects are initialized, for non-POD types this means calling the default constructor. Ahh, right. But actually I think the code is fine as it is now. This isn't critical, to be sure. Now the other issue Richard
Re: Is There a Better Way To Do This?
On Wed, Oct 24, 2007 at 01:37:06PM -0400, Richard Heck wrote: > Andre Poenitz wrote: > >On Wed, Oct 24, 2007 at 12:26:17PM -0400, Richard Heck wrote: > > > >>Andre Poenitz wrote: > >> > >>>Call a 'register' function from a constructor of a static dummy object. > >>>This is sometimes troublesome with shared objects/older compiler, > >>>though. > >>> > >>> > >>Can you sketch this in pseudo code, perhaps? This is beyond my C++ > >>experience. > >> > > > >static struct FooInsetInitializer { > > FooInsetInitializer() { callSomeRegistrationFunction(); } > >} dummy; > > > > Thanks but sorry, this by itself doesn't mean much to me. I need > help---or a reference---on which all this registration business is > about, and how it will help me when I'm trying to call static methods of > a class. Is the idea that the registration function might pass pointers > to the static methods it wants called in various cases? If so, I think I > vaguely understand this. But then: When and how do the > InsetFooInitializer's themselves get called? They get call on application startup. All global static objects are initialized, for non-POD types this means calling the default constructor. But actually I think the code is fine as it is now. Andre'
Re: Is There a Better Way To Do This?
Andre Poenitz wrote: On Wed, Oct 24, 2007 at 12:26:17PM -0400, Richard Heck wrote: Andre Poenitz wrote: Call a 'register' function from a constructor of a static dummy object. This is sometimes troublesome with shared objects/older compiler, though. Can you sketch this in pseudo code, perhaps? This is beyond my C++ experience. static struct FooInsetInitializer { FooInsetInitializer() { callSomeRegistrationFunction(); } } dummy; Thanks but sorry, this by itself doesn't mean much to me. I need help---or a reference---on which all this registration business is about, and how it will help me when I'm trying to call static methods of a class. Is the idea that the registration function might pass pointers to the static methods it wants called in various cases? If so, I think I vaguely understand this. But then: When and how do the InsetFooInitializer's themselves get called? Richard rh
Re: Is There a Better Way To Do This?
On Wed, Oct 24, 2007 at 12:26:17PM -0400, Richard Heck wrote: > Andre Poenitz wrote: > >Call a 'register' function from a constructor of a static dummy object. > >This is sometimes troublesome with shared objects/older compiler, > >though. > > > Can you sketch this in pseudo code, perhaps? This is beyond my C++ > experience. static struct FooInsetInitializer { FooInsetInitializer() { callSomeRegistrationFunction(); } } dummy; Andre'
Re: Is There a Better Way To Do This?
Andre Poenitz wrote: Call a 'register' function from a constructor of a static dummy object. This is sometimes troublesome with shared objects/older compiler, though. Can you sketch this in pseudo code, perhaps? This is beyond my C++ experience. rh
Re: Is There a Better Way To Do This?
Andre Poenitz wrote: In any case, it wouln't help with the typos (Compati_a_ble( I wrote that message while compiling rh
Re: Is There a Better Way To Do This?
Andre Poenitz wrote: > Call a 'register' function from a constructor of a static dummy object. > This is sometimes troublesome with shared objects/older compiler, > though. > > In any case, it wouln't help with the typos (Compati_a_ble( For these problems I'd recommend using the other static dummy object with all English words and correct spelling of them. A/
Re: Is There a Better Way To Do This?
On Tue, Oct 23, 2007 at 10:05:10PM -0400, Richard Heck wrote: > > This is very boring: > > CommandInfo const * InsetCommandParams::findInfo( >InsetCode code, std::string const & cmdName) > { >switch (code) { >case BIBITEM_CODE: >return InsetBibitem::findInfo(cmdName); >case BIBTEX_CODE: >return InsetBibtex::findInfo(cmdName); >case CITE_CODE: >return InsetCitation::findInfo(cmdName); >case FLOAT_LIST_CODE: >return InsetFloatList::findInfo(cmdName); >case HFILL_CODE: >return InsetHFill::findInfo(cmdName); >case HYPERLINK_CODE: >return InsetHyperlink::findInfo(cmdName); >case INCLUDE_CODE: >return InsetInclude::findInfo(cmdName); >case INDEX_CODE: >return InsetIndex::findInfo(cmdName); >case INDEX_PRINT_CODE: >return InsetPrintIndex::findInfo(cmdName); >case LABEL_CODE: >return InsetLabel::findInfo(cmdName); >case NOMENCL_CODE: >return InsetNomencl::findInfo(cmdName); >case NOMENCL_PRINT_CODE: >return InsetPrintNomencl::findInfo(cmdName); >case REF_CODE: >return InsetRef::findInfo(cmdName); >case TOC_CODE: >return InsetTOC::findInfo(cmdName); >default: >BOOST_ASSERT(false); >} >return 0; > } > > > std::string InsetCommandParams::getDefaultCmd(InsetCode code) { >switch (code) { >case BIBITEM_CODE: >return InsetBibitem::defaultCommand(); >case BIBTEX_CODE: >return InsetBibtex::defaultCommand(); >case CITE_CODE: >return InsetCitation::defaultCommand(); >case FLOAT_LIST_CODE: >return InsetFloatList::defaultCommand(); >case HFILL_CODE: >return InsetHFill::defaultCommand(); >case HYPERLINK_CODE: >return InsetHyperlink::defaultCommand(); >case INCLUDE_CODE: >return InsetInclude::defaultCommand(); >case INDEX_CODE: >return InsetIndex::defaultCommand(); >case INDEX_PRINT_CODE: >return InsetPrintIndex::defaultCommand(); >case LABEL_CODE: >return InsetLabel::defaultCommand(); >case NOMENCL_CODE: >return InsetNomencl::defaultCommand(); >case NOMENCL_PRINT_CODE: >return InsetPrintNomencl::defaultCommand(); >case REF_CODE: >return InsetRef::defaultCommand(); >case TOC_CODE: >return InsetTOC::defaultCommand(); >default: >BOOST_ASSERT(false); >} >return string(); //silence the warning > } > > > static bool InsetCommandParams::isCompatibleCommand( >InsetCode code, std::string const & s) > { >switch (code) { >case BIBITEM_CODE: >return InsetBibitem::isCompatiableCommand(s); >case BIBTEX_CODE: >return InsetBibtex::isCompatiableCommand(s); >case CITE_CODE: >return InsetCitation::isCompatiableCommand(s); >case FLOAT_LIST_CODE: >return InsetFloatList::isCompatiableCommand(s); >case HFILL_CODE: >return InsetHFill::isCompatiableCommand(s); >case HYPERLINK_CODE: >return InsetHyperlink::isCompatiableCommand(s); >case INCLUDE_CODE: >return InsetInclude::isCompatiableCommand(s); >case INDEX_CODE: >return InsetIndex::isCompatiableCommand(s); >case INDEX_PRINT_CODE: >return InsetPrintIndex::isCompatiableCommand(s); >case LABEL_CODE: >return InsetLabel::isCompatiableCommand(s); >case NOMENCL_CODE: >return InsetNomencl::isCompatiableCommand(s); >case NOMENCL_PRINT_CODE: >return InsetPrintNomencl::isCompatiableCommand(s); >case REF_CODE: >return InsetRef::isCompatiableCommand(s); >case TOC_CODE: >return InsetTOC::isCompatiableCommand(s); >default: >BOOST_ASSERT(false); >} >return false; //silence the warning > } > > So tell me: The fact that C++ is strongly typed and not really object > oriented makes it impossible to do this neatly? There are such nice ways > to do it in both Perl and Python...right Bo? Call a 'register' function from a constructor of a static dummy object. This is sometimes troublesome with shared objects/older compiler, though. In any case, it wouln't help with the typos (Compati_a_ble( Andre'