On Wednesday, 29 July 2015 at 20:41:02 UTC, Tofu Ninja wrote:
On Wednesday, 29 July 2015 at 20:26:53 UTC, Tofu Ninja wrote:
If you write:

@satisfies!(isInputRange, MyRange) struct MyRange { ... }

the UDA can check it self, it really works as expected. Which is why I suggested a way to get whatever the UDA is attached to automatically in my other post.

A UDA can reference the thing it's being attached to with no problems.
For example, this works 100% as expected right now...

@UDA!testS struct testS // UDA fails to instantiate because testS is not an inputRange!
{
        
}

template UDA(alias a)
{
        import std.range;
        static assert(isInputRange!a);
}

The only thing that would be needed to make this a nice solution is some syntax sugar to automatically get whatever the UDA is attached to, which is why I suggested this:

template UDA(alias a = __UDA_ATTACHMENT__) { ... }

You still wouldn't get a better error message here than with:

struct MyRange {
    ...
    static assert(isInputRange!MyRange);
}

It's less typing, but you still wouldn't know why the static assertion failed. Now, if we make Adam's idiom in my aforementioned pull request the go-to thing, then this would be good:

@satisfies!(checkInputRange, MyRange) struct MyRange { ... }

There's still the problem of having two names for each constraint: checkInputRange and isInputRange. But... we could also establish the convention of checkXXX and use string mixins to turn this:

@satifies!(isInputRange, MyRange)

into (which works cos I just tried it):

template satisfies(alias Constraint, R) {
    enum check = "check" ~ Constraint.stringof[2..$-3] ~ "!(R)";
    enum assert_ = "static assert("~ check ~ ");";
    mixin(assert_); //mixes in "static assert(checkInputRange!R)"
}


@satisfies!(isInputRange, Zeroes)
struct Zeroes {
    enum empty = false;
    void popFront() {}
    @property int front() { return 0; }
}


Now, _this_ I could go for.

Atila

Reply via email to