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..."
}
---