www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Partial specialisation: howto? (in the right news group this time.

reply div0 <div0 users.sourceforge.net> writes:
-----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
parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
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
parent reply div0 <div0 users.sourceforge.net> writes:
-----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
next sibling parent reply Jason House <jason.james.house gmail.com> writes:
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
parent div0 <div0 users.sourceforge.net> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Jason House wrote:
 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.
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-----
May 17 2009
prev sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
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