November 04, 2005
Walter Bright wrote:
> "Dwight Freeney" <dt@apt.com> wrote in message
> news:dkcakt$1e1l$1@digitaldaemon.com...
> 
>>Also is there any way to send a string constant into a template or mixin?
> 
> 
> That's a bit problematical as the string constant would have to be encoded
> into the template instantiated name.

Couldn't you use a hash table, and encode the hash in the name, instead of the string itself? That would at least overcome the length problem.
The problem is with the linker, right?
You'd need to store the hash table, (which might not even be possible with the OBJ formats?) and then combine hash tables when a collision occurs.

I'm interested in this, to know whether using a constant array as a template value parameter is even theoretically feasible.
It should always be possible to convert a arbitrary-length array of constants (or constant structs) into an arbitrary-length string, so
this seems to be a fundamental restriction on template value parameters.

November 04, 2005
Don Clugston wrote:
> 
> I'm interested in this, to know whether using a constant array as a template value parameter is even theoretically feasible.

Strings are already valid template parameters in C++ and D, though it's just the address that ends up being a part of the signature.


Sean
November 04, 2005
Sean Kelly wrote:
> Don Clugston wrote:
> 
>>
>> I'm interested in this, to know whether using a constant array as a template value parameter is even theoretically feasible.
> 
> 
> Strings are already valid template parameters in C++ and D, though it's just the address that ends up being a part of the signature.
> 
> 
> Sean

Does not work for me. Not as a value parameter.
--------
template funcA(char [] a)
{
  const int funcA=1;
}

int main()
{
  return funcA!("does this work"));
}
----------
Error: integral type expected for value-parameter, not char[]
-------------
November 04, 2005
Don Clugston wrote:
> Sean Kelly wrote:
> 
>> Don Clugston wrote:
>>>
>>> I'm interested in this, to know whether using a constant array as a template value parameter is even theoretically feasible.
>>
>> Strings are already valid template parameters in C++ and D, though it's just the address that ends up being a part of the signature.
> 
> Does not work for me. Not as a value parameter.

Hrm...  This is how you do it in C++:

	#include <cstdio>

	template<char* c>
	void fn()
	{
	    printf( "%s\n", c );
	}
	
	char buf[] = "abc";
	
	int main()
	{
	    fn<buf>();
	}

I could have sworn I did this once in D, but this is the closest I can get:

	import std.c.stdio;
	
	template fn(alias c)
	{
	    void fn()
	    {
	        printf( "%.*s\n", c );
	    }
	}
	
	char[] buf = "abc";
	
	void main()
	{
	    fn!(buf)();
	}

I just remembered something doing this however.  Template parameters must have external linkage to avoid violating the one definition rule... and const values are static.


Sean
November 05, 2005
"Don Clugston" <dac@nospam.com.au> wrote in message news:dkf3i5$viu$1@digitaldaemon.com...
> Couldn't you use a hash table, and encode the hash in the name, instead
> of the string itself? That would at least overcome the length problem.
> The problem is with the linker, right?
> You'd need to store the hash table, (which might not even be possible
> with the OBJ formats?) and then combine hash tables when a collision
occurs.
>
> I'm interested in this, to know whether using a constant array as a
> template value parameter is even theoretically feasible.
> It should always be possible to convert a arbitrary-length array of
> constants (or constant structs) into an arbitrary-length string, so
> this seems to be a fundamental restriction on template value parameters.

One could convert the string to a hex representation and encode that into the identifier, but then one runs into the problem that the object file format can't deal with identifiers longer than a thousand characters or so. And yes, it does happen!


November 07, 2005
Walter Bright wrote:
> "Don Clugston" <dac@nospam.com.au> wrote in message
> news:dkf3i5$viu$1@digitaldaemon.com...
> 
>>Couldn't you use a hash table, and encode the hash in the name, instead
>>of the string itself? That would at least overcome the length problem.
>>The problem is with the linker, right?
>>You'd need to store the hash table, (which might not even be possible
>>with the OBJ formats?) and then combine hash tables when a collision
> 
> occurs.
> 
>>I'm interested in this, to know whether using a constant array as a
>>template value parameter is even theoretically feasible.
>>It should always be possible to convert a arbitrary-length array of
>>constants (or constant structs) into an arbitrary-length string, so
>>this seems to be a fundamental restriction on template value parameters.
> 
> 
> One could convert the string to a hex representation and encode that into
> the identifier, but then one runs into the problem that the object file
> format can't deal with identifiers longer than a thousand characters or so.
> And yes, it does happen!

What about something silly like
- convert all arrays into some canonical hex string form
- concatenate them using some separator
- calculate a hash like MD5 or whatever of the entire thing and use that?

guaranteed not to exceed 32 characters, and practically guaranteed to be unique, unless someone really really really tries to break it :)


xs0
November 09, 2005
Sean Kelly wrote:
> Don Clugston wrote:
> 
>> Sean Kelly wrote:
>>
>>> Don Clugston wrote:
>>>
>>>>
>>>> I'm interested in this, to know whether using a constant array as a template value parameter is even theoretically feasible.
>>>
>>>
>>> Strings are already valid template parameters in C++ and D, though it's just the address that ends up being a part of the signature.
>>
>>
>> Does not work for me. Not as a value parameter.
> 
> 
> Hrm...  This is how you do it in C++:
> 
>     #include <cstdio>
> 
>     template<char* c>
>     void fn()
>     {
>         printf( "%s\n", c );
>     }
>         char buf[] = "abc";
>         int main()
>     {
>         fn<buf>();
>     }
> 
> I could have sworn I did this once in D, but this is the closest I can get:
> 
>     import std.c.stdio;
>         template fn(alias c)
>     {
>         void fn()
>         {
>             printf( "%.*s\n", c );
>         }
>     }
>         char[] buf = "abc";
>         void main()
>     {
>         fn!(buf)();
>     }
> 
> I just remembered something doing this however.  Template parameters must have external linkage to avoid violating the one definition rule... and const values are static.
> 
> 
> Sean

As I already posted to this ng, I found that is possible to do it with alias parameters.
You wrap the constant inside a template (so basically you are doing the name mangling manually). In contrast to the C++ version, it's completely
evaluated at compile time (you're not recieving a pointer to a static string, you're recieving the string literal itself).

{{ Now, use static if on the contents of the string literal. Suppose that string is a definition of a regular expression. You can compile a lexer, just like Boost::Spirit, except that since you're using a string there are absolutely no syntax restrictions.... Use a mixin and get access to local variables in the function that called the template...
you have a primitive compiler compiler...
 I have to stop, my mind is starting to explode. }}

But anyway, this is how you can do strings.
------------------------------

template fn(alias c)
{
   void fn()
   {
      printf( c!() ~ \n );   // look mum, no %
   }
}

template buf()
{
   const char[] buf = "abc";
}

int main()
{
   fn!(buf)();
   return 0;
}
November 09, 2005
Don Clugston wrote:
> 
> As I already posted to this ng, I found that is possible to do it with alias parameters.

Oops, I missed that post.

> But anyway, this is how you can do strings.
> ------------------------------
> 
> template fn(alias c)
> {
>    void fn()
>    {
>       printf( c!() ~ \n );   // look mum, no %
>    }
> }
> 
> template buf()
> {
>    const char[] buf = "abc";
> }
> 
> int main()
> {
>    fn!(buf)();
>    return 0;
> }

So an alias to a template is evaluated at compile-time?  Makes sense I suppose, though it wouldn't have occurred to me right off.  I feel like we're tricking the compielr by doing this, but it works so I won't complain :)  I suppose doing something like Spirit would require writing a compile-time regexp parser?  Probably a lot less awkward than it would be in C++.


Sean
November 10, 2005
Sean Kelly wrote:
> Don Clugston wrote:
> 
>>
>> As I already posted to this ng, I found that is possible to do it with alias parameters.
> 
> 
> Oops, I missed that post.
> 
>> But anyway, this is how you can do strings.
>> ------------------------------
>>
>> template fn(alias c)
>> {
>>    void fn()
>>    {
>>       printf( c!() ~ \n );   // look mum, no %
>>    }
>> }
>>
>> template buf()
>> {
>>    const char[] buf = "abc";
>> }
>>
>> int main()
>> {
>>    fn!(buf)();
>>    return 0;
>> }
> 
> 
> So an alias to a template is evaluated at compile-time?  Makes sense I suppose, though it wouldn't have occurred to me right off.  I feel like we're tricking the compielr by doing this, but it works so I won't complain :) 

I think it's no different to template template parameters in C++.
The important difference, though, is that any compile-time constant can be in a D template.

 I suppose doing something like Spirit would require writing
> a compile-time regexp parser?  Probably a lot less awkward than it would be in C++.

Yes, I think so. Since Spirit is kind of a "flagship product" of C++ templates, it would be great to have a "proof of concept" to show that such a thing is possible in D.

When I started looking a D a few months ago, I thought that D templates were a lot less powerful than C++, because they don't yet have implicit instantiation; but that D had enough other appealing features to compensate for that deficiency. It was a shock to discover that rather, D templates are fundamentally much more powerful than C++ templates.
(This is not the impression you get from the docs. I'd like to construct some convincing examples).
1 2
Next ›   Last »