1 module cerealed.traits; 2 3 import cerealed.cereal; 4 import cerealed.cerealiser; 5 import cerealed.decerealiser; 6 7 8 void checkCereal(T)() { 9 ubyte b; 10 auto cereal = T.init; 11 cereal.grainUByte(b); 12 uint val; 13 cereal.grainBits(val, 3); 14 CerealType type = cereal.type; 15 // can't check grainClass because it calls grainClassImpl, 16 // which uses the template constraint isCereal 17 // Class class_; 18 // cereal.grainClass(class_); 19 } 20 21 enum isCereal(T) = is(typeof(checkCereal!T)); 22 23 void checkCerealiser(T)() { 24 checkCereal!T; 25 static assert(T.type == CerealType.WriteBytes); 26 } 27 28 enum isCerealiser(T) = is(typeof(checkCerealiser!T)); 29 30 void checkDecerealiser(T)() { 31 checkCereal!T; 32 static assert(T.type == CerealType.ReadBytes); 33 auto dec = T(); 34 ulong bl = dec.bytesLeft; 35 } 36 37 enum isDecerealiser(T) = is(typeof(checkDecerealiser!T)); 38 39 40 bool hasFunc(T, string funcName)() { 41 if(!__ctfe) { 42 auto obj = T.init; 43 auto enc = Cerealiser(); 44 mixin("obj." ~ funcName ~ "(enc);"); 45 auto dec = Decerealiser(); 46 mixin("obj." ~ funcName ~ "(dec);"); 47 } 48 return true; 49 } 50 51 enum hasAccept(T) = hasFunc!(T, "accept"); 52 enum hasPostBlit(T) = hasFunc!(T, "postBlit"); 53 enum hasPreBlit(T) = hasFunc!(T, "preBlit"); 54 55 unittest { 56 struct Accept { 57 void accept(C)(auto ref C cereal) if(isCereal!C) { } 58 } 59 60 static assert(hasAccept!Accept); 61 } 62 63 mixin template assertHas(T, string funcName) { 64 static assert(hasFunc!(T, funcName)); 65 } 66 67 mixin template assertHasPostBlit(T) { mixin assertHas!(T, "postBlit"); } 68 mixin template assertHasPreBlit(T) { mixin assertHas!(T, "preBlit"); } 69 mixin template assertHasAccept(T) { mixin assertHas!(T, "accept"); } 70 71 private class Class { ubyte ub; }