November 30, 2005
Not everyone might realise just how revolutionary DMD 0.140 is for template metaprogramming.

I submitted this to pragma's DDL "D Dynamic Libraries", used to dynamically link to .obj files. In this example, we want to be able to call the function
uint add(uint, uint)
which was defined in test.testmodule.obj.
To do this, we need to know the mangled function name, which depends on the module name and the types of the parameters. Then we need to do a cast to a function pointer of the right type. But the new templates can do all the work for us.

THIS LINE:
----------------
auto add = mymodule.load!(uint, "test.testmodule.add", uint, uint)();
----------------
COMPILES TO:
----------------
uint function(uint a,uint b) add = cast(uint function(uint a,uint b)) mymodule.LoadExport("_D4test10testmodule3addFkkZk");
----------------
Full name mangling occurs at compile time.

Source available in the DDL forum at www.dsource.org. The code is not too obscure (much better than anything at Boost).

It currently only works for fundamental types and pointers. There's not enough compile-time or even run-time type info to do function pointers, for example. Some compile-time type info would be real nice...

This would be impossible to do in C++. Even to come close would be a nightmare.


PS: This code could also be used in the DLL example in the D docs at d/dll.html

The code :
-----------------
   alias void function(void*) MyDLL_Initialize_fp;
	FARPROC fp;
	MyDLL_Initialize_fp mydll_initialize;

	HMODULE h = LoadLibraryA("mydll.dll");

	fp = GetProcAddress(h, "D5mydll16MyDLL_InitializeFPvZv");
	if (fp == null)
	{   printf("error loading symbol MyDLL_Initialize()\n");
	    return 1;
	}

	mydll_initialize = cast(MyDLL_Initialize_fp) fp;
	(*mydll_initialize)(std.gc.getGCHandle());
-----------------

can be replaced with:
-------------
      auto mydll = LoadDModule("mydll.dll");
      auto init  = mydll.GetProc!(void, "mydll.MyDLL_Initialize", void *)();
      init(std.gc.getGCHandle());
------------

November 30, 2005
he he. I came for a little group snoop, and this is the first post I looked at, and ...

> This would be impossible to do in C++. Even to come close would be a nightmare.

... au contraire, mon ami. Can one pronounce "hubris"? <g>

I've just completed an intial version of just such a library, called dl_call(), and we're currently having a discussion within the editorial panel of "The C++ Source" (http://www.artima.com/cppsource/index.html) on my idea of doing a series of articles describing proposing this to the C++ standards committee, and the ensuing acceptance/rejection.

(For anyone that's downloaded STLSoft 1.8.9, please ignore the nascent form of dl_call() in the WinSTL sub-project. The full version is considerably more full featured. It'll be part of the PlatformSTL sub-project, once I've ported the code to support UNIX as well as Windows.)


Notwithstanding my slight bubble-pricking above, I don't doubt for a second that D's got a lot more welly in it since last I played in anger, and am looking forward to playing with it in a big way next year.

Cheers

Matthew


November 30, 2005
Matthew wrote:
> he he. I came for a little group snoop, and this is the first post I looked
> at, and ...
> 
>>This would be impossible to do in C++. Even to come close would be a
>>nightmare.
> 
> ... au contraire, mon ami. Can one pronounce "hubris"? <g>
> 
> I've just completed an intial version of just such a library, called
> dl_call(),

I'm impressed, and rather intrigued - how do you parse a C++ string at compile time? And convert the string length to a text integer? I'd really like to see the code.

Certainly, it would have been a nightmare for *me* to do it in C++. Doing it in D was very straightforward (two nights work).

Hmmm, I'll have to try a bit harder.

and we're currently having a discussion within the editorial
> panel of "The C++ Source" (http://www.artima.com/cppsource/index.html) on my idea of doing a series of articles describing proposing this to the C++ standards committee, and the ensuing acceptance/rejection.

I'll look out for that.
> 
> Notwithstanding my slight bubble-pricking above, I don't doubt for a second that D's got a lot more welly in it since last I played in anger, and am looking forward to playing with it in a big way next year.

Definitely. I look forward to seeing the results, too.
November 30, 2005
Don Clugston wrote:
> Not everyone might realise just how revolutionary DMD 0.140 is for template metaprogramming.
> 
> I submitted this to pragma's DDL "D Dynamic Libraries", used to dynamically link to .obj files. In this example, we want to be able to call the function
> uint add(uint, uint)
> which was defined in test.testmodule.obj.
> To do this, we need to know the mangled function name, which depends on the module name and the types of the parameters. Then we need to do a cast to a function pointer of the right type. But the new templates can do all the work for us.
> 
> THIS LINE:
> ----------------
> auto add = mymodule.load!(uint, "test.testmodule.add", uint, uint)();
> ----------------
> COMPILES TO:
> ----------------
> uint function(uint a,uint b) add = cast(uint function(uint a,uint b)) mymodule.LoadExport("_D4test10testmodule3addFkkZk");
> ----------------
> Full name mangling occurs at compile time.
> 
> Source available in the DDL forum at www.dsource.org. The code is not too obscure (much better than anything at Boost).

Not too obsure? The code is looking great and very understandable.

> 
> It currently only works for fundamental types and pointers. There's not enough compile-time or even run-time type info to do function pointers, for example. Some compile-time type info would be real nice...
> 
> This would be impossible to do in C++. Even to come close would be a nightmare.
> 
> 
> PS: This code could also be used in the DLL example in the D docs at d/dll.html
> 

...
November 30, 2005
In article <dmke9m$ott$1@digitaldaemon.com>, Don Clugston says...
>
>Matthew wrote:
>> he he. I came for a little group snoop, and this is the first post I looked at, and ...
>> 
>>>This would be impossible to do in C++. Even to come close would be a nightmare.
>> 
>> ... au contraire, mon ami. Can one pronounce "hubris"? <g>
>> 
>> I've just completed an intial version of just such a library, called
>> dl_call(),
>
>I'm impressed, and rather intrigued - how do you parse a C++ string at compile time? And convert the string length to a text integer? I'd really like to see the code.
>
>Certainly, it would have been a nightmare for *me* to do it in C++. Doing it in D was very straightforward (two nights work).
>
>Hmmm, I'll have to try a bit harder.

Don, here's something I've given some thought: are you familiar with XSLT/XPATH 2.0?

As XSL is a *template* language, it is most directly supported by the support that XPATH brings to the table.  The 2.0 specification, especially for strings, is the bare-minimum needed to do nearly any kind of parsing or processing one could imagine (although some productions take some serious coding to work).

http://www.w3schools.com/xpath/xpath_functions.asp#string

Maybe the string portion of the spec (described at URL above) might point you in the right direction for a more comprehensive/complete compile-time facility.  I think slicing already covers most of these, leaving case-switching, search-and-replace, and the like; I think these all boil down into combinations of compare-and-slice and concat.

Some kind of easy iteration (recursive template that takes args like for-each) would be a huge plus too.

The really, really hard part?  The second argument to tokenize() is a regular-expression.  Teach D how to do that at compile-time, and there's not much left.


- EricAnderton at yahoo
November 30, 2005
Don Clugston wrote:
> Matthew wrote:
>> he he. I came for a little group snoop, and this is the first post I looked
>> at, and ...
>>
>>> This would be impossible to do in C++. Even to come close would be a
>>> nightmare.
>>
>> ... au contraire, mon ami. Can one pronounce "hubris"? <g>
>>
>> I've just completed an intial version of just such a library, called
>> dl_call(),
> 
> I'm impressed, and rather intrigued - how do you parse a C++ string at compile time? And convert the string length to a text integer? I'd really like to see the code.

Same here.  I think it would be possible to cobble something bearable together using a combination of macro and template language, but the result would look a lot more like input for Spirit than pure string manipulation.  The real nasty part here is that I don't think there's any way to split strings at compile-time in C++, so everything would likely have to be assembled from common substrings (perhaps even one per letter).


Sean
December 01, 2005
"Don Clugston" <dac@nospam.com.au> wrote in message news:dmk465$fq3$1@digitaldaemon.com...
> THIS LINE:
> ----------------
> auto add = mymodule.load!(uint, "test.testmodule.add", uint, uint)();
> ----------------
> COMPILES TO:
> ----------------
> uint function(uint a,uint b) add = cast(uint function(uint a,uint b))
> mymodule.LoadExport("_D4test10testmodule3addFkkZk");
> ----------------
> Full name mangling occurs at compile time.

This is pretty incredible. I had no idea this could be done <g>.

> It currently only works for fundamental types and pointers. There's not enough compile-time or even run-time type info to do function pointers, for example. Some compile-time type info would be real nice...

What's missing from function pointers? Note that the name demangler (std.demangle) can demangle function pointers, so the information must be complete.


December 01, 2005
"Matthew" <matthew@stlsoft.com> wrote in message news:dmk89b$jhi$1@digitaldaemon.com...
> > This would be impossible to do in C++. Even to come close would be a nightmare.
>
> ... au contraire, mon ami. Can one pronounce "hubris"? <g>
>
> I've just completed an intial version of just such a library, called dl_call(), and we're currently having a discussion within the editorial panel of "The C++ Source" (http://www.artima.com/cppsource/index.html) on
my
> idea of doing a series of articles describing proposing this to the C++ standards committee, and the ensuing acceptance/rejection.

A comparitive review would be fun. Want to go for it?


December 01, 2005
Walter Bright wrote:
> "Don Clugston" <dac@nospam.com.au> wrote in message
> news:dmk465$fq3$1@digitaldaemon.com...
> 
>>THIS LINE:
>>----------------
>>auto add = mymodule.load!(uint, "test.testmodule.add", uint, uint)();
>>----------------
>>COMPILES TO:
>>----------------
>>uint function(uint a,uint b) add = cast(uint function(uint a,uint b))
>>mymodule.LoadExport("_D4test10testmodule3addFkkZk");
>>----------------
>>Full name mangling occurs at compile time.
> 
> This is pretty incredible. I had no idea this could be done <g>.

And it's not even ugly. That's a very primitive use of template string value parameters. Despite Matthew's comment, I do think we're crossing into unexplored territory.

>>It currently only works for fundamental types and pointers. There's not
>>enough compile-time or even run-time type info to do function pointers,
>>for example. Some compile-time type info would be real nice...
> 
> What's missing from function pointers? Note that the name demangler
> (std.demangle) can demangle function pointers, so the information must be
> complete.

All the mangling information is present in a mangled string, but I don't know any way to find out what the function arguments are.
Suppose T is a function pointer type.

R function (P1, P2, P3)

What are R, P1, P2, P3 ? You can work out what R is, using
is(T R : function)
which gives you the type of the return value.
In C++, you can find out what P1, P2, P3 are, by using implicit template instantiation. But in D, I don't even know how I can work out how many parameters there are. (Maybe there is, and I've just missed it).

Even the runtime typeinfo structure seems to be incomplete.
Example:

writefln(typeid(int *), "  ", typeid(int function(char *, creal)));

prints:
int *    int()*

yet from std.demangle, it looks as though even inout vs out parameters are distinguished in the mangled name.

Musing...

Now, a simple-to-implement way of doing this, and ensuring that all presnt and future types are covered, would be to include a __mangletypeof() function or property, valid for any type, which converts a type to a const char[], using exactly the same mangling algorithm which is used by the linker for individual types.
So that std.demangle(__mangletypeof(int)) would return "int".

Note: if there was some kind of __demangletypeof() as well, we would have well-supported typelists by the backdoor -- mangle the types, perform string manipulations on them, and demangle when you're done. But perhaps this is all far, far too much rope...

Could also be done from a library, if we had implicit function template instantiation. But I'm guessing that's not coming any time soon.

December 01, 2005
In article <dmmhfc$2m8p$1@digitaldaemon.com>, Don Clugston says...
>
>Walter Bright wrote:
>> "Don Clugston" <dac@nospam.com.au> wrote in message news:dmk465$fq3$1@digitaldaemon.com...
>> 
>>>THIS LINE:
>>>----------------
>>>auto add = mymodule.load!(uint, "test.testmodule.add", uint, uint)();
>>>----------------
>>>COMPILES TO:
>>>----------------
>>>uint function(uint a,uint b) add = cast(uint function(uint a,uint b))
>>>mymodule.LoadExport("_D4test10testmodule3addFkkZk");
>>>----------------
>>>Full name mangling occurs at compile time.
>> 
>> This is pretty incredible. I had no idea this could be done <g>.
>
>And it's not even ugly. That's a very primitive use of template string value parameters. Despite Matthew's comment, I do think we're crossing into unexplored territory.
>
>>>It currently only works for fundamental types and pointers. There's not enough compile-time or even run-time type info to do function pointers, for example. Some compile-time type info would be real nice...
>> 
>> What's missing from function pointers? Note that the name demangler (std.demangle) can demangle function pointers, so the information must be complete.
>
>All the mangling information is present in a mangled string, but I don't
>know any way to find out what the function arguments are.
>Suppose T is a function pointer type.
>
>R function (P1, P2, P3)
>
>What are R, P1, P2, P3 ? You can work out what R is, using
>is(T R : function)
>which gives you the type of the return value.
>In C++, you can find out what P1, P2, P3 are, by using implicit template
>instantiation. But in D, I don't even know how I can work out how many
>parameters there are. (Maybe there is, and I've just missed it).
>
>Even the runtime typeinfo structure seems to be incomplete. Example:
>
>writefln(typeid(int *), "  ", typeid(int function(char *, creal)));
>
>prints:
>int *    int()*
>
>yet from std.demangle, it looks as though even inout vs out parameters are distinguished in the mangled name.
>
>Musing...
>
>Now, a simple-to-implement way of doing this, and ensuring that all
>presnt and future types are covered, would be to include a
>__mangletypeof() function or property, valid for any type, which
>converts a type to a const char[], using exactly the same mangling
>algorithm which is used by the linker for individual types.
>So that std.demangle(__mangletypeof(int)) would return "int".
>
>Note: if there was some kind of __demangletypeof() as well, we would have well-supported typelists by the backdoor -- mangle the types, perform string manipulations on them, and demangle when you're done. But perhaps this is all far, far too much rope...
>
>Could also be done from a library, if we had implicit function template instantiation. But I'm guessing that's not coming any time soon.
>

Yes, I feel like walter gave me a christmas present. Ive been wanting this from c++ for ages. We have something pretty awesome here. As far as Im concerned anyone whos not using D is missing out...


« First   ‹ Prev
1 2 3
Top | Discussion index | About this forum | D home