A static assertion that a type satisfies a given template constraint. It can be used as a UDA or in a static assert to make sure that a type conforms to the compile-time interface the user expects it to. The difference between using models and a simple static assert with the template contraint is that models will instantiate the failing code when the constraint is not satisfied, yielding compiler error messages to aid the user.

The template contraint predicate must start with the word is (e.g. isInputRange) and an associated template function with the "is" replaced by "check" should exist (e.g. checkInputRange) and be defined in the same module.

template models(alias T, alias P, A...)


1 enum isFoo(T) = is(typeof(checkFoo!T));
4 template isBar(T, U)
5 {
6     enum isBar = is(typeof(checkBar!(T, U)));
7 }
9 @models!(Foo, isFoo) //as a UDA
10 struct Foo
11 {
12     void foo() {}
13     static assert(models!(Foo, isFoo)); //as a static assert
14 }
16 @models!(Bar, isBar, byte) //as a UDA
17 struct Bar
18 {
19     byte bar;
20     static assert(models!(Bar, isBar, byte)); //as a static assert
21 }
23 // can't assert that, e.g. !models!(Bar, isFoo) -
24 // the whole point of `models` is that it doesn't compile
25 // when the template constraint is not satisfied
26 static assert(!__traits(compiles, models!(Bar, isFoo)));
27 static assert(!__traits(compiles, models!(Foo, isBar, byte)));