1 /**********************************************************\ 2 | | 3 | hprose | 4 | | 5 | Official WebSite: http://www.hprose.com/ | 6 | http://www.hprose.org/ | 7 | | 8 \**********************************************************/ 9 10 /**********************************************************\ 11 * * 12 * hprose/io/common.d * 13 * * 14 * hprose common library for D. * 15 * * 16 * LastModified: Jul 15, 2015 * 17 * Author: Ma Bingyao <andot@hprose.com> * 18 * * 19 \**********************************************************/ 20 21 module hprose.io.common; 22 @safe: 23 24 import std.stdio; 25 import std.traits; 26 import std.typecons; 27 import std.typetuple; 28 29 template make(T) 30 if (is(T == struct) || is(T == class)) { 31 T make(Args...)(Args arguments) 32 if (is(T == struct) && __traits(compiles, T(arguments))) { 33 return T(arguments); 34 } 35 36 T make(Args...)(Args arguments) 37 if (is(T == class) && __traits(compiles, new T(arguments))) { 38 return new T(arguments); 39 } 40 } 41 42 template isSerializable(T) { 43 alias U = Unqual!T; 44 static if (is(U == typeof(null)) || 45 isBasicType!U || 46 isSomeString!U || 47 is(U == struct)) { 48 enum isSerializable = true; 49 } 50 else static if (is(U == class) && !isAbstractClass!U 51 && __traits(compiles, { new U; })) { 52 enum isSerializable = true; 53 } 54 else static if (isArray!U) { 55 enum isSerializable = isSerializable!(ForeachType!U); 56 } 57 else static if (isAssociativeArray!U) { 58 enum isSerializable = isSerializable!(KeyType!U) && isSerializable!(ValueType!U); 59 } 60 else { 61 enum isSerializable = false; 62 } 63 } 64 65 template isSerializableField(T) if (is(T == struct) || is(T == class)) { 66 template isSerializableField(string M) { 67 static if (__traits(hasMember, T, M) && is(typeof(__traits(getMember, T, M)))) { 68 alias U = typeof(__traits(getMember, T, M)); 69 enum isSerializableField = isAssignable!U && isSerializable!U && 70 !__traits(compiles, { mixin("(T)." ~ M ~ " = (U).init;"); }) && 71 __traits(compiles, { mixin("const T x = T.init; U y = x." ~ M ~ ";"); }); 72 } 73 else { 74 enum isSerializableField = false; 75 } 76 } 77 } 78 79 template getSerializableFields(T) if (is(T == struct) || is(T == class)) { 80 enum allMembers = __traits(allMembers, T); 81 static if (allMembers.length > 0) { 82 enum getSerializableFields = tuple(Filter!(isSerializableField!T, allMembers)); 83 } 84 else { 85 static assert(0, T.stringof ~ " has no fields"); 86 } 87 } 88 89 private { 90 91 struct MyStruct { int a; }; 92 93 class MyClass { int a; this(int a) {}; this() {}; }; 94 95 } 96 97 unittest { 98 assert(getSerializableFields!(MyStruct) == tuple("a")); 99 assert(getSerializableFields!(MyClass) == tuple("a")); 100 }