Concepts vs template constraints - the practical approach

Denis Shelomovskij verylonglogin.reg at gmail.com
Sun Nov 20 11:31:38 PST 2011


Your example, a bit improved:
---
// In std.concept, e.g.
template verify(alias concept, T) {
     //static assert(isConcept!concept, concept.stringof ~ " is not a 
concept"); //the test for particular concept's concepts can be added
     mixin concept!T;
}

template verify(alias concept) {
     mixin verify!(concept, typeof(this));
}

template satisfy(alias concept, T) {
     enum satisfy = __traits(compiles, verify!(concept, T));
}

// User code
template myConcept(A) {
     static assert(is(A.type), "Error 1: !is(A.type)");
     static assert(A.len >= 0, "Error 2: A.len < 0");
     static assert(is(typeof(A.init[0]) == A.type), "Error 3: 
typeof(A.init[0]) != A.type");
}

struct MyClass(T,int R) {
     alias T type;
     enum len = R;

     T[R] value;

     T opIndex(int idx) {
         return value[idx];
     }

     mixin verify!myConcept;
}

void myFunction(A)(A arr) {
     mixin verify!(myConcept, A);
}

void myOverlodedFunction(A)(A arr) if(satisfy!(myConcept, A)) {
     // Do something
}

void myOverlodedFunction(A)(int i, A arr) if(satisfy!(myConcept, A)) {
     // Do something
}

void myOverlodedFunction(T...)(T) {
     static assert(0, "Error: here should be some user-defined error 
message(s) based on T");
}

unittest {
     MyClass!(int,4) x;
     myFunction(x);
     //myFunction(1); //Error: static assert  "Error 1: !is(A.type)"
     myOverlodedFunction(x);
     myOverlodedFunction(3, x);
     //myOverlodedFunction(3, 2); //Error: static assert  "Error: here 
should be..."
}
---


More information about the Digitalmars-d mailing list