1 module des.math.basic.traits;
2 
3 import std.traits;
4 /* for debug
5     static assert( isAssignable!(Unqual!T,Unqual!T) );
6     static assert( is( typeof(T.init + T.init) == T ) );
7     static assert( is( typeof(T.init - T.init) == T ) );
8     static assert( is( typeof( cast(T)(T.init * 0.5) ) ) );
9     static assert( is( typeof( cast(T)(T.init / 0.5) ) ) );
10  */
11 
12 ///
13 template isComplex(T)
14 {
15     alias Unqual!T UT;
16     enum isComplex = is( UT == cfloat ) ||
17                      is( UT == cdouble ) ||
18                      is( UT == creal );
19 }
20 
21 ///
22 template isImaginary(T)
23 {
24     alias Unqual!T UT;
25     enum isImaginary = is( UT == ifloat ) ||
26                        is( UT == idouble ) ||
27                        is( UT == ireal );
28 }
29 
30 unittest
31 {
32     static assert( isComplex!(typeof(4+3i)) );
33     static assert( isImaginary!(typeof(3i)) );
34 }
35 
36 ///
37 template hasBasicMathOp(T)
38 {
39     enum hasBasicMathOp =
40         isAssignable!(Unqual!T,T) &&
41         is( typeof(T.init + T.init) == T ) &&
42         is( typeof(T.init - T.init) == T ) &&
43         is( typeof( (T.init * 0.5) ) : T ) &&
44         is( typeof( (T.init / 0.5) ) : T );
45 }
46 
47 ///
48 unittest
49 {
50     static assert( !hasBasicMathOp!int );
51     static assert(  hasBasicMathOp!float );
52     static assert(  hasBasicMathOp!double );
53     static assert(  hasBasicMathOp!real );
54     static assert(  hasBasicMathOp!cfloat );
55     static assert( !hasBasicMathOp!char );
56     static assert( !hasBasicMathOp!string );
57 
58     struct TTest
59     {
60         float x,y;
61         auto opBinary(string op)( in TTest v ) const 
62             if( op=="+" || op=="-" )
63         { return TTest(x+v.x,y+v.y); }
64         auto opBinary(string op)( double v ) const 
65             if( op=="*" || op=="/" )
66         { return TTest(x*v,y*v); }
67     }
68 
69     static assert(  hasBasicMathOp!TTest );
70 
71     struct FTest
72     {
73         float x,y;
74         auto opAdd( in TTest v ) const { return TTest(x+v.x,y+v.y); }
75     }
76 
77     static assert( !hasBasicMathOp!FTest );
78 }