1 /** 2 * Copyright: © 2014-2015 Anton Gushcha 3 * License: Subject to the terms of the Boost 1.0 license as specified in LICENSE file 4 * Authors: Anton Gushcha <ncrashed@gmail.com> 5 * 6 * Template satisfy checks - extension of std.typecons (allSatisfy); 7 */ 8 module stribog.meta.satisfy; 9 10 public import std.typetuple : allSatisfy, anySatisfy; 11 12 import std.conv : text; 13 14 import stribog.meta.base; 15 16 /** 17 * Same as std.typetuple.allSatisfy, but passes $(B i) arguments to the first template. 18 */ 19 template allSatisfyN(size_t i, alias F, T...) 20 { 21 static assert(T.length % i == 0, text("Invalid count of arguments, expected ", i, " but got ", T.length)); 22 23 static if (T.length < i) 24 { 25 enum allSatisfyN = true; 26 } 27 else static if (T.length == i) 28 { 29 static if(__traits(compiles, F(T[0 .. i]))) { 30 enum allSatisfyN = F(T[0 .. i]); 31 } 32 else { 33 enum allSatisfyN = F!(T[0 .. i]); 34 } 35 } 36 else 37 { 38 static if(!F!(T[0 .. i])) 39 enum allSatisfyN = false; 40 else 41 enum allSatisfyN = allSatisfyN!(i, F, T[i .. $]); 42 } 43 } 44 /// Example 45 unittest 46 { 47 template Test(T...) 48 { 49 enum Test = is(typeof(T[0]) == string) && is(typeof(T[1]) == bool); 50 } 51 52 static assert(allSatisfyN!(2, Test, "42", true, "108", false)); 53 } 54 55 /// alias to allSatisfyN for 2 arguments 56 alias allSatisfy2(alias F, T...) = allSatisfyN!(2, F, T); 57 /// alias to allSatisfyN for 3 arguments 58 alias allSatisfy3(alias F, T...) = allSatisfyN!(3, F, T); 59 /// alias to allSatisfyN for 4 arguments 60 alias allSatisfy4(alias F, T...) = allSatisfyN!(4, F, T); 61 /// alias to allSatisfyN for 5 arguments 62 alias allSatisfy5(alias F, T...) = allSatisfyN!(5, F, T); 63 /// alias to allSatisfyN for 6 arguments 64 alias allSatisfy6(alias F, T...) = allSatisfyN!(6, F, T); 65 /// alias to allSatisfyN for 7 arguments 66 alias allSatisfy7(alias F, T...) = allSatisfyN!(7, F, T); 67 /// alias to allSatisfyN for 8 arguments 68 alias allSatisfy8(alias F, T...) = allSatisfyN!(8, F, T); 69 /// alias to allSatisfyN for 9 arguments 70 alias allSatisfy9(alias F, T...) = allSatisfyN!(9, F, T); 71 72 /** 73 * Same as std.typetuple anySatisfy, but passes $(B i) arguments to $(B F). 74 */ 75 template anySatisfyN(size_t i, alias F, T...) 76 { 77 static assert(T.length % i == 0, text("Invalid count of arguments, expected ", i, " but got ", T.length)); 78 79 static if (T.length < i) 80 { 81 enum anySatisfyN = true; 82 } 83 else static if (T.length == i) 84 { 85 static if(__traits(compiles, F(T[0 .. i]))) { 86 enum anySatisfyN = F(T[0 .. i]); 87 } 88 else { 89 enum anySatisfyN = F!(T[0 .. i]); 90 } 91 } 92 else 93 { 94 static if(F!(T[0 .. i])) 95 enum anySatisfyN = true; 96 else 97 enum anySatisfyN = anySatisfyN!(i, F, T[i .. $]); 98 } 99 } 100 /// Example 101 unittest 102 { 103 template Test(int a, int b, int c) { 104 enum Test = a + b == c; 105 } 106 107 static assert(!anySatisfyN!(3, Test, 1, 1, 3, 5, 8, 11)); 108 static assert( anySatisfyN!(3, Test, 1, 1, 2, 5, 8, 11)); 109 } 110 111 /// alias of anySatisfyN for 2 arguments 112 alias anySatisfy2(alias F, T...) = anySatisfyN!(2, F, T); 113 /// alias of anySatisfyN for 3 arguments 114 alias anySatisfy3(alias F, T...) = anySatisfyN!(3, F, T); 115 /// alias of anySatisfyN for 4 arguments 116 alias anySatisfy4(alias F, T...) = anySatisfyN!(4, F, T); 117 /// alias of anySatisfyN for 5 arguments 118 alias anySatisfy5(alias F, T...) = anySatisfyN!(5, F, T); 119 /// alias of anySatisfyN for 6 arguments 120 alias anySatisfy6(alias F, T...) = anySatisfyN!(6, F, T); 121 /// alias of anySatisfyN for 7 arguments 122 alias anySatisfy7(alias F, T...) = anySatisfyN!(7, F, T); 123 /// alias of anySatisfyN for 8 arguments 124 alias anySatisfy8(alias F, T...) = anySatisfyN!(8, F, T); 125 /// alias of anySatisfyN for 9 arguments 126 alias anySatisfy9(alias F, T...) = anySatisfyN!(9, F, T);