digitalmars.D.learn - Partial specialisation: howto? (in the right news group this time.
- div0 (53/53) May 16 2009 -----BEGIN PGP SIGNED MESSAGE-----
- Simen Kjaeraas (22/22) May 16 2009 div0 wrote:
- div0 (17/50) May 17 2009 -----BEGIN PGP SIGNED MESSAGE-----
- Jason House (7/17) May 17 2009 It's nearly impossible to answer your question without knowing what you'...
- div0 (18/38) May 17 2009 -----BEGIN PGP SIGNED MESSAGE-----
- Simen Kjaeraas (19/22) May 17 2009 I would believe this to work:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi Everybody, Please have a look at the appended sucky code. Obv. the createHandlerCode function is a pain in the back side for extending this system; I want multiple different partially specialised implementations. So whats the syntax for doing partial specialisation? Damed if I can work it out. ================== enum EHandlerType { eMsgRangeHdlr, eMsgHdlr, eCmdIdHdlr } template createHandlerCode(T ...) { string format() { static if(T[0]._type == EHandlerType.eMsgRangeHdlr) return createMessageRangeHandler!(T).format(); else static if(T[0]._type == EHandlerType.eMsgHdlr) return createMessageHandler!(T).format(); else static if(T[0]._type == EHandlerType.eCmdIdHdlr) return createCommandIdHandler!(T).format(); else static assert(false, "handler type not handled"); } } struct msgRangeHdlr(uint msgIdFirst, uint msgIdLast, string responseMethod) { invariant EHandlerType _type = EHandlerType.eMsgRangeHdlr; invariant string _msgIdFirst = std.metastrings.ToString!(msgIdFirst); invariant string _msgIdLast = std.metastrings.ToString!(msgIdLast); invariant string _responseMethod = responseMethod; } struct msgHdlr(uint msgId, string responseMethod) { invariant EHandlerType _type = EHandlerType.eMsgHdlr; invariant string _msgId = std.metastrings.ToString!(msgId); invariant string _responseMethod = responseMethod; } struct cmdIdHdlr(uint cmdId, string responseMethod) { invariant EHandlerType _type = EHandlerType.eCmdIdHdlr; invariant string _cmdId = std.metastrings.ToString!(cmdId); invariant string _responseMethod = responseMethod; } - -- My enormous talent is exceeded only by my outrageous laziness. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFKD1t9T9LetA9XoXwRAgKDAJ9BFJ+d5qLpPSjZn5SN9C0g1hh6HgCgrFWr c5752+efFTIYG9/2pY4Vp5Y= =W6lL -----END PGP SIGNATURE-----
May 16 2009
div0 wrote: It seems I might know how to do this after all. As is mentioned under template constraints[1], templates can be specialized by trailing the parameter list with a condition: template createHandlerCode( T... ) if ( T[0]._type == EHandlerType.eMsgRangeHdlr ) { string format( ) { return createMessageRangeHandler!( T ).format(); } } template createHandlerCode( T... ) if ( T[0]._type == EHandlerType.eMsgHdlr ) { string format( ) { return createMessageHandler!( T ).format(); } } template createHandlerCode( T... ) if ( T[0]._type == EHandlerType.eCmdIdHdlr ) { string format( ) { return createCommandIdHandler!( T ).format(); } } This code is D2-only and untested, so there is certainly a possibility it will not work for you. [1]: http://www.digitalmars.com/d/2.0/template.html#Constraint -- Simen
May 16 2009
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Thanks Simen, That's nicer than the chained static ifs. Is there anyway to get rid of the enum though? Using the enum is a pain as it means you have to edit that import anytime you need to create a specialistion. Simen Kjaeraas wrote:div0 wrote: It seems I might know how to do this after all. As is mentioned under template constraints[1], templates can be specialized by trailing the parameter list with a condition: template createHandlerCode( T... ) if ( T[0]._type == EHandlerType.eMsgRangeHdlr ) { string format( ) { return createMessageRangeHandler!( T ).format(); } } template createHandlerCode( T... ) if ( T[0]._type == EHandlerType.eMsgHdlr ) { string format( ) { return createMessageHandler!( T ).format(); } } template createHandlerCode( T... ) if ( T[0]._type == EHandlerType.eCmdIdHdlr ) { string format( ) { return createCommandIdHandler!( T ).format(); } } This code is D2-only and untested, so there is certainly a possibility it will not work for you. [1]: http://www.digitalmars.com/d/2.0/template.html#Constraint -- Simen- -- My enormous talent is exceeded only by my outrageous laziness. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFKD80yT9LetA9XoXwRAjwYAJ94ZdQT/+UP6iTP/Vgplf2M02zpXgCfSYpD GgdBnsafroFNvffhEFqeuVY= =Wbhe -----END PGP SIGNATURE-----
May 17 2009
div0 wrote:-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Thanks Simen, That's nicer than the chained static ifs. Is there anyway to get rid of the enum though? Using the enum is a pain as it means you have to edit that import anytime you need to create a specialistion.It's nearly impossible to answer your question without knowing what you're trying to achieve. For example, you're specializing on T... which means there are more template arguments. Is there anything differentiating the cases in those? Another candidate is a class hierarchy (or use of an interface) where createHandlerCode is defined in the base definition, and each inheriting class overrides the method.
May 17 2009
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Jason House wrote:div0 wrote:I've just reread it and realised I deleted too much stuff for anybody to get what I was after. doh. But as per usual, I thought of a much easier way to do it about 10 minutes after I asked the question. Thanks for your responses though! :) - -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFKEEglT9LetA9XoXwRAt+wAJ9tdu/LdSan1W4+YPNtFRs9BcCATgCfTBIQ M+um8KGHgwngYTkQIvv1OGA= =tXiu -----END PGP SIGNATURE----------BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Thanks Simen, That's nicer than the chained static ifs. Is there anyway to get rid of the enum though? Using the enum is a pain as it means you have to edit that import anytime you need to create a specialistion.It's nearly impossible to answer your question without knowing what you're trying to achieve. For example, you're specializing on T... which means there are more template arguments. Is there anything differentiating the cases in those? Another candidate is a class hierarchy (or use of an interface) where createHandlerCode is defined in the base definition, and each inheriting class overrides the method.
May 17 2009
div0 wrote:Thanks Simen, That's nicer than the chained static ifs. Is there anyway to get rid of the enum though?I would believe this to work: template createHandlerCode( T... ) if ( is( T == msgRangeHdlr ) ) { string format( ) { return createMessageRangeHandler!(T).format(); } } template createHandlerCode( T... ) if ( is( T == msgHdlr ) ) { string format( ) { return createMessageHandler!(T).format(); } } template createHandlerCode( T... ) if ( is( T == cmdIdHdlr ) ) { string format( ) { return createCommandIdHandler!(T).format(); } } -- Simen
May 17 2009