digitalmars.D.learn - Different class template args to generate same template instance?
- "Nick Sabalausky" <a a.a> Nov 02 2009
- BCS <none anon.com> Nov 02 2009
- "Nick Sabalausky" <a a.a> Nov 02 2009
- downs <default_357-line yahoo.de> Nov 02 2009
- "Nick Sabalausky" <a a.a> Nov 02 2009
- "Nick Sabalausky" <a a.a> Nov 02 2009
I'd like to have a sub-class that's templated on a potentially-duplicated
name and an optional disambiguating type. To illustrate:
class Foo
{
}
/*
Three possible names/types are:
- sam, human
- zoe, human
- zoe, starship
*/
class SubFoo(char[] name, char[] type)
{
static if(name == "sam" && type == "human")
// create members specific to the only sam
else static if(name == "zoe" && type == "human")
// create members specific to the human zoe
static if(name == "zoe" && type == "starship")
// create members specific to the starship zoe
else
static assert(false, "Invalid name/type");
}
But unlike in that example, *most* of the names will only exist as one
possible type and will therefore be completely unambiguous just by
themselves. So, I would really like to be able to make the type optional and
just have a "static assert(false)" for any use of an ambiguous name that
isn't disambiguated by a type. Kind of like this:
class SubFoo(char[] name, char[] type="")
{
static if(name == "sam" && (type == "human" || type==""))
// create members specific to the only sam
else static if(name == "zoe" && type == "human")
// create members specific to the human zoe
static if(name == "zoe" && type == "starship")
// create members specific to the starship zoe
static if(name == "zoe" && type == "")
static assert(false, "zoe might be either the human or the starship,
please specify which one");
else
static assert(false, "Invalid name/type");
}
Problem is, that won't work because SubFoo!("sam") and SubFoo!("sam",
"human") are treated as different types. So...is there any trickery I could
do so that SubFoo!("sam") and SubFoo!("sam", "human") would resolve to the
same subclass of Foo?
I don't think any solution involving merging the name/type fields into
anything like "sam.human" would work because the valid names could be just
about any sequence of chars (this source file will be generated by a tool)
so any possible "disambiguated" string could potentially conflict with a
plain non-disambiguated name. Names being any sequence of chars also rules
out anything like "class SubFoo_sam_human : Foo", because name could be
something like "++. /&".
Nov 02 2009
Hello Nick,So...is there any trickery I could do so that SubFoo!("sam") and SubFoo!("sam", "human") would resolve to the same subclass of Foo?
Make a SubFoo!(char[] s) that does your logic and if it passesa alises to SubFoo!(s,"")
Nov 02 2009
"BCS" <none anon.com> wrote in message news:a6268ffc3898cc29d1f554dfe2 news.digitalmars.com...Hello Nick,So...is there any trickery I could do so that SubFoo!("sam") and SubFoo!("sam", "human") would resolve to the same subclass of Foo?
Make a SubFoo!(char[] s) that does your logic and if it passesa alises to SubFoo!(s,"")
I'm not sure I understand...?
Nov 02 2009
Nick Sabalausky wrote:"BCS" <none anon.com> wrote in message news:a6268ffc3898cc29d1f554dfe2 news.digitalmars.com...Hello Nick,So...is there any trickery I could do so that SubFoo!("sam") and SubFoo!("sam", "human") would resolve to the same subclass of Foo?
SubFoo!(s,"")
I'm not sure I understand...?
I think what he's trying to say is template SubFoo!(char[] name, char[] type) { static if (name == "sam" && (type == "human" || type == "")) alias _SubFoo!("sam", "human") SubFoo; /* etc */ }
Nov 02 2009
"downs" <default_357-line yahoo.de> wrote in message news:hcnjit$4na$1 digitalmars.com...Nick Sabalausky wrote:"BCS" <none anon.com> wrote in message news:a6268ffc3898cc29d1f554dfe2 news.digitalmars.com...Hello Nick,So...is there any trickery I could do so that SubFoo!("sam") and SubFoo!("sam", "human") would resolve to the same subclass of Foo?
to SubFoo!(s,"")
I'm not sure I understand...?
I think what he's trying to say is template SubFoo!(char[] name, char[] type) { static if (name == "sam" && (type == "human" || type == "")) alias _SubFoo!("sam", "human") SubFoo; /* etc */ }
Ahh! Thanks all, that works perfectly: ------------------------------------------------------------- module foo; class Foo { protected char[] _n="Plain Foo"; char[] n() { return _n.dup; } } template SubFoo(char[] name, char[] type="") { static if (name == "sam" && (type == "human" || type == "")) alias _SubFoo!(name, "human") SubFoo; else static if( (name == "zoe" && type == "human") || (name == "zoe" && type == "starship") ) alias _SubFoo!(name, type) SubFoo; else static if(name == "zoe" && type == "") static assert(false, "Name '"~name~"' is ambiguous"); else static assert(false, "Invalid name/type: '"~name~"' '"~type~"'"); } private class _SubFoo(char[] name, char[] type) : Foo { static if(name == "sam" && type == "human") this() { _n = "sam human"; } else static if(name == "zoe" && type == "human") this() { _n = "zoe human"; } else static if(name == "zoe" && type == "starship") this() { _n = "zoe starship"; } else static assert(false, "Invalid name/type: '"~name~"' '"~type~"'"); } ------------------------------------------------------------- module main; import tango.io.Stdout; import foo; void main() { auto f = new Foo(); auto s_ = new SubFoo!("sam"); auto sh = new SubFoo!("sam", "human"); auto zh = new SubFoo!("zoe", "human"); auto zs = new SubFoo!("zoe", "starship"); // ERROR: Name 'zoe' is ambiguous //auto z_ = new SubFoo!("zoe"); // ERROR: Invalid name/type 'dummy' 'dude' //auto d_ = new SubFoo!("dummy", "dude"); Stdout.formatln("f : {}", f.n); // OUT: f : Plain Foo Stdout.formatln("s_: {}", s_.n); // OUT: s_: sam human Stdout.formatln("sh: {}", sh.n); // OUT: sh: sam human Stdout.formatln("zh: {}", zh.n); // OUT: zh: zoe human Stdout.formatln("zs: {}", zs.n); // OUT: zs: zoe starship } -------------------------------------------------------------
Nov 02 2009
"Nick Sabalausky" <a a.a> wrote in message news:hcnlh7$msb$1 digitalmars.com..."downs" <default_357-line yahoo.de> wrote in message news:hcnjit$4na$1 digitalmars.com...Nick Sabalausky wrote:"BCS" <none anon.com> wrote in message news:a6268ffc3898cc29d1f554dfe2 news.digitalmars.com...Hello Nick,So...is there any trickery I could do so that SubFoo!("sam") and SubFoo!("sam", "human") would resolve to the same subclass of Foo?
to SubFoo!(s,"")
I'm not sure I understand...?
I think what he's trying to say is template SubFoo!(char[] name, char[] type) { static if (name == "sam" && (type == "human" || type == "")) alias _SubFoo!("sam", "human") SubFoo; /* etc */ }
Ahh! Thanks all, that works perfectly: ------------------------------------------------------------- module foo; class Foo { protected char[] _n="Plain Foo"; char[] n() { return _n.dup; } } template SubFoo(char[] name, char[] type="") { static if (name == "sam" && (type == "human" || type == "")) alias _SubFoo!(name, "human") SubFoo; else static if( (name == "zoe" && type == "human") || (name == "zoe" && type == "starship") ) alias _SubFoo!(name, type) SubFoo; else static if(name == "zoe" && type == "") static assert(false, "Name '"~name~"' is ambiguous"); else static assert(false, "Invalid name/type: '"~name~"' '"~type~"'"); } private class _SubFoo(char[] name, char[] type) : Foo { static if(name == "sam" && type == "human") this() { _n = "sam human"; } else static if(name == "zoe" && type == "human") this() { _n = "zoe human"; } else static if(name == "zoe" && type == "starship") this() { _n = "zoe starship"; } else static assert(false, "Invalid name/type: '"~name~"' '"~type~"'"); } ------------------------------------------------------------- module main; import tango.io.Stdout; import foo; void main() { auto f = new Foo(); auto s_ = new SubFoo!("sam"); auto sh = new SubFoo!("sam", "human"); auto zh = new SubFoo!("zoe", "human"); auto zs = new SubFoo!("zoe", "starship"); // ERROR: Name 'zoe' is ambiguous //auto z_ = new SubFoo!("zoe"); // ERROR: Invalid name/type 'dummy' 'dude' //auto d_ = new SubFoo!("dummy", "dude"); Stdout.formatln("f : {}", f.n); // OUT: f : Plain Foo Stdout.formatln("s_: {}", s_.n); // OUT: s_: sam human Stdout.formatln("sh: {}", sh.n); // OUT: sh: sam human Stdout.formatln("zh: {}", zh.n); // OUT: zh: zoe human Stdout.formatln("zs: {}", zs.n); // OUT: zs: zoe starship } -------------------------------------------------------------
Oops, just realized that main doesn't necessarily prove that the SubFoo!("sam") and SubFoo!("sam", "human") are the same types. But this passes fine, so all looks ok, thanks again! : static assert(is( SubFoo!("sam") == SubFoo!("sam", "human") ));
Nov 02 2009








"Nick Sabalausky" <a a.a>