Re: A module comprehensive template-specialization

2010-06-28 Thread Rory McGuire
On Mon, 28 Jun 2010 11:09:13 +0200, Matthias Walter  
 wrote:



On 06/28/2010 09:49 AM, Justin Spahr-Summers wrote:

On Sun, 27 Jun 2010 18:51:35 +0200, Matthias Walter
 wrote:


Hi list,

I tried to write a traits class comparable to iterator_traits in C++  
STL
or graph_traits in Boost Graph Library in D 2.0, but failed to do so  
via

template specialization which is put into different modules. Putting
everything into one module interferes with extensibility. I tried the
following:

== Module a ==
| module a;
|
| template Base (T)
| {
|   alias T Base;
| }

== Module b ==
| module b;
|
| import a;
|
| template Base(T: T*)
| {
|   alias Base !(T) Base;
| }

== Main module ==
|
|  import a, b;
|
| int main(char[][] args)
| {
|   alias Base !(int*) foo;
|
|   return 0;
| }

The error message is:
"bug.d(8): Error: template instance ambiguous template declaration
b.Base(T : T*) and a.Base(T)"

Can I handle this in another way (like making the template a  
conditional

one)?

best regards
Matthias Walter


I believe this is intended behavior, as it prevents template hijacking
and the like. Using alias to import the two templates into the same
scope might help, though I'm not sure exactly how it should be done.


I tried to do so in some variants but did not succeed unfortunately. If
you have a precise idea, please let me know!



On another note, though, have you looked at __traits() and std.traits?


I looked at them but didn't find them helpful for this precise problem.
The whole reason for doing this is to make it possible to make another
existing class model the concept (i.e. have some aliases / typedefs
done) of my library class without editing any of them. As I mentioned in
my other response, a prominent example for Boost Graph
Library is the LEDA graph class, which can be enabled to be used by BGL
by more or less just specializing the graph_traits template. I'd like to
have this kind of technique available, too.

Any further suggestions?


I haven't looked at the boost stuff you mention but is it possible that  
using alias this, solves a similar or the same problem?
TDPL addresses the use of aliasing to bring multiple declarations into the  
same scope/module but it only uses actual functions not templates.


Re: A module comprehensive template-specialization

2010-06-28 Thread Matthias Walter
On 06/28/2010 09:49 AM, Justin Spahr-Summers wrote:
> On Sun, 27 Jun 2010 18:51:35 +0200, Matthias Walter 
>  wrote:
>>
>> Hi list,
>>
>> I tried to write a traits class comparable to iterator_traits in C++ STL
>> or graph_traits in Boost Graph Library in D 2.0, but failed to do so via
>> template specialization which is put into different modules. Putting
>> everything into one module interferes with extensibility. I tried the
>> following:
>>
>> == Module a ==
>> | module a;
>> |
>> | template Base (T)
>> | {
>> |   alias T Base;
>> | }
>>
>> == Module b ==
>> | module b;
>> |
>> | import a;
>> |
>> | template Base(T: T*)
>> | {
>> |   alias Base !(T) Base;
>> | }
>>
>> == Main module ==
>> |
>> |  import a, b;
>> |
>> | int main(char[][] args)
>> | {
>> |   alias Base !(int*) foo;
>> |
>> |   return 0;
>> | }
>>
>> The error message is:
>> "bug.d(8): Error: template instance ambiguous template declaration
>> b.Base(T : T*) and a.Base(T)"
>>
>> Can I handle this in another way (like making the template a conditional
>> one)?
>>
>> best regards
>> Matthias Walter
> 
> I believe this is intended behavior, as it prevents template hijacking 
> and the like. Using alias to import the two templates into the same 
> scope might help, though I'm not sure exactly how it should be done.

I tried to do so in some variants but did not succeed unfortunately. If
you have a precise idea, please let me know!

> 
> On another note, though, have you looked at __traits() and std.traits?

I looked at them but didn't find them helpful for this precise problem.
The whole reason for doing this is to make it possible to make another
existing class model the concept (i.e. have some aliases / typedefs
done) of my library class without editing any of them. As I mentioned in
my other response, a prominent example for Boost Graph
Library is the LEDA graph class, which can be enabled to be used by BGL
by more or less just specializing the graph_traits template. I'd like to
have this kind of technique available, too.

Any further suggestions?


Re: A module comprehensive template-specialization

2010-06-28 Thread Matthias Walter
On 06/28/2010 05:32 AM, Simen kjaeraas wrote:
> Matthias Walter  wrote:
> 
>> Can I handle this in another way (like making the template a conditional
>> one)?
> 
> Template constraints[1] sounds like what you want.
> 
> Basically, you want the following:
> 
> == Module a ==
> | module a;
> |
> | template Base (T) if (!is(T t : t*))
> | {
> |   alias T Base;
> | }
> 
> == Module b ==
> | module b;
> |
> | import a;
> |
> | template Base(T) if (is(T t : t*))
> | {
> |   alias Base !(T) Base;
> | }
> 
> == Main module ==
> |
> |  import a, b;
> |
> | int main(char[][] args)
> | {
> |   alias Base !(int*) foo;
> |
> |   return 0;
> | }
> 
> Not tested, ymmv.
> 
> [1]: http://digitalmars.com/d/2.0/template.html#Constraint
> 

The problem with constraints arises when I want to make an existing
class (who's code I cannot modify) match a Concept, in which case I
would just add another template specialization for this class. Here I
would have to add further conditions to the template constraints, which
would also mean to modify a library. A prominent example for Boost Graph
Library is the LEDA graph class, which can be enabled to be used by BGL
by more or less just specializing the graph_traits template.

Any further ideas?


Re: A module comprehensive template-specialization

2010-06-28 Thread Justin Spahr-Summers
On Sun, 27 Jun 2010 18:51:35 +0200, Matthias Walter 
 wrote:
> 
> Hi list,
> 
> I tried to write a traits class comparable to iterator_traits in C++ STL
> or graph_traits in Boost Graph Library in D 2.0, but failed to do so via
> template specialization which is put into different modules. Putting
> everything into one module interferes with extensibility. I tried the
> following:
> 
> == Module a ==
> | module a;
> |
> | template Base (T)
> | {
> |   alias T Base;
> | }
> 
> == Module b ==
> | module b;
> |
> | import a;
> |
> | template Base(T: T*)
> | {
> |   alias Base !(T) Base;
> | }
> 
> == Main module ==
> |
> |  import a, b;
> |
> | int main(char[][] args)
> | {
> |   alias Base !(int*) foo;
> |
> |   return 0;
> | }
> 
> The error message is:
> "bug.d(8): Error: template instance ambiguous template declaration
> b.Base(T : T*) and a.Base(T)"
> 
> Can I handle this in another way (like making the template a conditional
> one)?
> 
> best regards
> Matthias Walter

I believe this is intended behavior, as it prevents template hijacking 
and the like. Using alias to import the two templates into the same 
scope might help, though I'm not sure exactly how it should be done.

On another note, though, have you looked at __traits() and std.traits?


Re: A module comprehensive template-specialization

2010-06-27 Thread Simen kjaeraas

Matthias Walter  wrote:


Can I handle this in another way (like making the template a conditional
one)?


Template constraints[1] sounds like what you want.

Basically, you want the following:

== Module a ==
| module a;
|
| template Base (T) if (!is(T t : t*))
| {
|   alias T Base;
| }

== Module b ==
| module b;
|
| import a;
|
| template Base(T) if (is(T t : t*))
| {
|   alias Base !(T) Base;
| }

== Main module ==
|
|  import a, b;
|
| int main(char[][] args)
| {
|   alias Base !(int*) foo;
|
|   return 0;
| }

Not tested, ymmv.

[1]: http://digitalmars.com/d/2.0/template.html#Constraint

--
Simen


A module comprehensive template-specialization

2010-06-27 Thread Matthias Walter
Hi list,

I tried to write a traits class comparable to iterator_traits in C++ STL
or graph_traits in Boost Graph Library in D 2.0, but failed to do so via
template specialization which is put into different modules. Putting
everything into one module interferes with extensibility. I tried the
following:

== Module a ==
| module a;
|
| template Base (T)
| {
|   alias T Base;
| }

== Module b ==
| module b;
|
| import a;
|
| template Base(T: T*)
| {
|   alias Base !(T) Base;
| }

== Main module ==
|
|  import a, b;
|
| int main(char[][] args)
| {
|   alias Base !(int*) foo;
|
|   return 0;
| }

The error message is:
"bug.d(8): Error: template instance ambiguous template declaration
b.Base(T : T*) and a.Base(T)"

Can I handle this in another way (like making the template a conditional
one)?

best regards
Matthias Walter