July 02, 2008
"Jarrett Billingsley" <kb3ctd2@yahoo.com> wrote in message news:g4g3hd$ckq$1@digitalmars.com...
> "Steven Schveighoffer" <schveiguy@yahoo.com> wrote in message news:g4g2fg$a4l$1@digitalmars.com...
>
>>
>> In that case, this should work, but generates extra code (which should be inlined):
>>
>> public void Foo(T: char)(T arg)  {Foo_dwc!(T)(arg); }
>> public void Foo(T: wchar)(T arg) {Foo_dwc!(T)(arg); }
>> public void Foo(T: dchar)(T arg) {Foo_dwc!(T)(arg); }
>>
>> private void Foo_dwc(T)(T arg) {  }
>>
>> void main(char[][] args)
>> {
>> Foo('a');
>> }
>
> It does.  :)

I can't decide if this is better of worse. Leaning towards worse ;)

char[] Bar(char[] retType, char[] publicName, char[] privateName,
                char[] argsDecl, char[] argsCall, char[][] types)
{
    char[] ret;
    foreach(char[] type; types)
    {
        ret ~= "public "~retType~" "~publicName~"(T:"~type~")("~argsDecl~")
{"~privateName~"!(T)("~argsCall~");}";
    }
    return ret;
}

mixin(Bar("void", "Foo", "Foo_dwc", "T arg", "arg", ["char", "wchar", "dchar"]));

void main(char[][] args)
{
    Foo('a');
}


July 02, 2008
"Nick Sabalausky" <a@a.a> wrote in message news:g4g69h$j7v$1@digitalmars.com...
>
> I can't decide if this is better of worse. Leaning towards worse ;)
>
> char[] Bar(char[] retType, char[] publicName, char[] privateName,
>                char[] argsDecl, char[] argsCall, char[][] types)
> {
>    char[] ret;
>    foreach(char[] type; types)
>    {
>        ret ~= "public "~retType~" "~publicName~"(T:"~type~")("~argsDecl~")
> {"~privateName~"!(T)("~argsCall~");}";
>    }
>    return ret;
> }
>
> mixin(Bar("void", "Foo", "Foo_dwc", "T arg", "arg", ["char", "wchar", "dchar"]));
>
> void main(char[][] args)
> {
>    Foo('a');
> }

Now it's just getting silly.

template MakeFunctions(RetType, char[] PublicName,
    char[] PrivateName, Types...)
{
    static if(Types.length == 0)
        const char[] MakeFunctions = "";
    else
        const char[] MakeFunctions =
    "public " ~ RetType.stringof ~ " " ~ PublicName ~ "(T : " ~
        Types[0].stringof ~ ")(T arg)\n"
    "{\n"
    "   return " ~ PrivateName ~ "(arg);\n"
    "}\n"
    ~ MakeFunctions!(RetType, PublicName, PrivateName, Types[1 .. $]);
}

public template NameOfFunc(alias f)
{
    // weirdness in dmdfe.
    const char[] NameOfFunc = (&f).stringof[2 .. $];
}

private template BarImpl(char[] PublicName, alias PrivateFunc, Types...)
{
    alias typeof(&PrivateFunc!(Types[0])) FuncType;
    alias ReturnTypeOf!(FuncType) RetType;

    const ret = MakeFunctions!(RetType, PublicName,
        NameOfFunc!(PrivateFunc!(Types[0])), Types);
}

public template Bar(char[] PublicName, alias PrivateFunc, Types...)
{
    static assert(Types.length > 0, "must have at least one type");
    const Bar = BarImpl!(PublicName, PrivateFunc, Types).ret;
}

mixin(Bar!("Foo", Foo_dwc, char, wchar, dchar));

Template-foo to the rescue, you can extract the return type directly from the alias to the private function.  :)


July 02, 2008
Reply to Jarrett,

> It can't deduce the template function on line 9 simply because it
> doesn't think that Foo is a template function.
> 

Should a bug report be filed?


July 02, 2008
"Jarrett Billingsley" <kb3ctd2@yahoo.com> wrote in message news:g4g81l$n9b$1@digitalmars.com...
> "Nick Sabalausky" <a@a.a> wrote in message news:g4g69h$j7v$1@digitalmars.com...
>>
>> I can't decide if this is better of worse. Leaning towards worse ;)
>>
>> char[] Bar(char[] retType, char[] publicName, char[] privateName,
>>                char[] argsDecl, char[] argsCall, char[][] types)
>> {
>>    char[] ret;
>>    foreach(char[] type; types)
>>    {
>>        ret ~= "public "~retType~"
>> "~publicName~"(T:"~type~")("~argsDecl~")
>> {"~privateName~"!(T)("~argsCall~");}";
>>    }
>>    return ret;
>> }
>>
>> mixin(Bar("void", "Foo", "Foo_dwc", "T arg", "arg", ["char", "wchar",
>> "dchar"]));
>>
>> void main(char[][] args)
>> {
>>    Foo('a');
>> }
>
> Now it's just getting silly.
>
> template MakeFunctions(RetType, char[] PublicName,
>    char[] PrivateName, Types...)
> {
>    static if(Types.length == 0)
>        const char[] MakeFunctions = "";
>    else
>        const char[] MakeFunctions =
>    "public " ~ RetType.stringof ~ " " ~ PublicName ~ "(T : " ~
>        Types[0].stringof ~ ")(T arg)\n"
>    "{\n"
>    "   return " ~ PrivateName ~ "(arg);\n"
>    "}\n"
>    ~ MakeFunctions!(RetType, PublicName, PrivateName, Types[1 .. $]);
> }
>
> public template NameOfFunc(alias f)
> {
>    // weirdness in dmdfe.
>    const char[] NameOfFunc = (&f).stringof[2 .. $];
> }
>
> private template BarImpl(char[] PublicName, alias PrivateFunc, Types...)
> {
>    alias typeof(&PrivateFunc!(Types[0])) FuncType;
>    alias ReturnTypeOf!(FuncType) RetType;
>
>    const ret = MakeFunctions!(RetType, PublicName,
>        NameOfFunc!(PrivateFunc!(Types[0])), Types);
> }
>
> public template Bar(char[] PublicName, alias PrivateFunc, Types...)
> {
>    static assert(Types.length > 0, "must have at least one type");
>    const Bar = BarImpl!(PublicName, PrivateFunc, Types).ret;
> }
>
> mixin(Bar!("Foo", Foo_dwc, char, wchar, dchar));
>
> Template-foo to the rescue, you can extract the return type directly from the alias to the private function.  :)
>
>

I turned that into a working compileable source file (attached, test5.d), and made notes of a few bits of weirdness that I noticed when getting it to compile.

I do actually like the end result though. Put it into a utility module, and it's a nicely DRY approach to the original problem that works around D1's lack of template constraints. (I'm a DRY junkie.)

I have a few other utility mixins I've been using. When I wrote them, I was having trouble getting template mixins to work without using the "CTFE that returns char[] and takes all-char[] paramaters" approach you saw in my original version of Bar. Studying that code above, I think I understand D's templates well enough now to maybe improve some of those other utility mixins I have.



July 02, 2008
"BCS" <ao@pathlink.com> wrote in message news:55391cb32ec1c8caaa3f5f7077a6@news.digitalmars.com...
> Reply to Jarrett,
>
>> It can't deduce the template function on line 9 simply because it doesn't think that Foo is a template function.
>>
>
> Should a bug report be filed?
>
>

Sure, if you think it'll get any response.


July 02, 2008
Reply to Jarrett,

> "BCS" <ao@pathlink.com> wrote in message
> news:55391cb32ec1c8caaa3f5f7077a6@news.digitalmars.com...
> 
>> Reply to Jarrett,
>> 
>>> It can't deduce the template function on line 9 simply because it
>>> doesn't think that Foo is a template function.
>>> 
>> Should a bug report be filed?
>> 
> Sure, if you think it'll get any response.
> 

No need to add a new bug. (and Walter seems to like the idea.)

http://d.puremagic.com/issues/show_bug.cgi?id=1807


1 2
Next ›   Last »