1 /** 2 Contains types that determine the semantics of predicates 3 */ 4 module ddash.functional.pred; 5 6 /// 7 unittest { 8 static struct S(alias pred) { 9 auto f(int a, int b) { 10 static if (isEq!pred) { 11 return pred(a, b); 12 } else static if (isLt!pred) { 13 return !pred(a, b) && !pred(b, a); 14 } else { 15 import std.functional: binaryFun; 16 return binaryFun!pred(a, b); 17 } 18 } 19 } 20 21 alias A = S!(eq!((a, b) => a == b)); 22 alias B = S!(lt!((a, b) => a < b)); 23 24 assert( A().f(1, 1)); 25 assert( B().f(1, 1)); 26 assert(!A().f(2, 1)); 27 assert(!B().f(2, 1)); 28 29 static bool feq(int a, int b) { return a == b; } 30 static bool flt(int a, int b) { return a < b; } 31 32 alias C = S!(eq!feq); 33 alias D = S!(lt!flt); 34 35 assert( C().f(1, 1)); 36 assert( D().f(1, 1)); 37 assert(!C().f(1, 2)); 38 assert(!D().f(1, 2)); 39 40 assert(S!"a == b"().f(1, 1)); 41 } 42 43 /** 44 Used to signify that `pred` is an equality predicate. 45 46 It must be a function over two arguments that returns a boolean if they are equal 47 */ 48 struct eq(alias pred) { 49 alias eq = pred; 50 static auto ref opCall(T, U)(auto ref T a, auto ref U b) { return pred(a, b); } 51 } 52 53 /// Is true if `pred` is an `eq` 54 template isEq(alias pred) { 55 static if (is(pred : eq!p, p...)) { 56 enum isEq = true; 57 } else { 58 enum isEq = false; 59 } 60 } 61 62 /** 63 Used to signify that `pred` is a less than predicate 64 65 It must be a function over two arguments that returns a boolean if arg1 < argb 66 */ 67 struct lt(alias pred) { 68 alias lt = pred; 69 static auto ref opCall(T, U)(auto ref T a, auto ref U b) { return pred(a, b); } 70 } 71 72 /// Is true if `pred` is an `lt` 73 template isLt(alias pred) { 74 static if (is(pred : lt!p, p...)) { 75 enum isLt = true; 76 } else { 77 enum isLt = false; 78 } 79 } 80 81 unittest { 82 alias plt = lt!((a, b) => a < b); 83 alias peq = eq!((a, b) => a == b); 84 85 static assert( isEq!peq); 86 static assert(!isEq!plt); 87 static assert( isLt!plt); 88 static assert(!isLt!peq); 89 90 assert( plt(1, 2)); 91 assert(!plt(1, 1)); 92 assert(!plt(2, 1)); 93 94 assert(!peq(2, 1)); 95 assert(!peq(1, 2)); 96 assert( peq(1, 1)); 97 }