On 11/20/2011 11:36 AM, Norbert Nemec wrote:
Hi Ali,

indeed, defining individual named sub-concepts makes the thing somewhat
more readable.

However, my approach with individual static assertions was very
intentional:

Collecting individual requirements as an AND expression of booleans does
not allow any helpful error message. If just one of the requirements is
not met, there is just one failure of the global assertion.

dmd 2.056 with the code that I've tried, does provide which individual requirement is not met:

deneme.d(54697): Error: no property 'len' for type 'YourClass'
deneme.d(54709): Error: template instance deneme.hasNonNegativeLength!(YourClass) error instantiating
deneme.d(54727):        instantiated from here: matchesMyConcept!(YourClass)

I had also toyed with boolean wrappers for the "__traits(compiles,...)"
construct. It does work, but still it feels way more hacky than anything
I would want to use at the foundation of a general library.

Agreed.


Greetings,
Norbert

Ali




On 20.11.2011 19:47, Ali Çehreli wrote:

On 11/20/2011 08:41 AM, Norbert Nemec wrote:
> Hi there,
>
> back in the discussions about C++-"concepts" it was argued that
> D-template-parameter constraints allow you to achieve the same goal.

Have a look at std.range.hasLength, std.range.isInputRange, and friends.
[...]
Here is something:

template hasType(T)
{
enum bool hasType = is(T.type);
}

template hasNonNegativeLength(T)
{
enum bool hasNonNegativeLength = T.len >= 0;
}

template firstElementSameType(T)
{
enum bool firstElementSameType = is(typeof(T.init[0]) == T.type);
}

template matchesMyConcept(T)
{
enum bool matchesMyConcept = (hasType!T &&
hasNonNegativeLength!T &&
firstElementSameType!T);
}


Reply via email to