import std.range; static assert(isInputRange!(uint[])); // true static assert(isInputRange!string); // true static assert(!isInputRange!void); // false
template isInputRange(R) { enum bool isInputRange = is(typeof( (inout int = 0) { R r = void; // can define a range object if (r.empty) {} // can test for empty r.popFront(); // can invoke popFront() auto h = r.front; // can get the front of the range })); }
// struct CInterface { string method1(); bool method2(); } // / struct A {} static assert(isExpose!(A, CInterface));
// template factorial(uint n) { // - private template inner(ulong acc, uint n) { // static if static if(n == 0) enum inner = acc; // else enum inner = inner!(acc * n, n-1 ); // } // 1 enum factorial = inner!(1, n); } static assert(factorial!5 == 120);
template test(T...) {} alias a1 = test!(ulong, float, double); // alias a2 = test!("hi!", 23+42, [true, false], float); //
// , template isExpose(Type, Interfaces...) { // , 1 private template isExposeSingle(Interface) { } // , 1 enum isExpose = allSatisfy!(isExposeSingle, Interfaces); }
template allSatisfy(alias F, T...) { static if (T.length == 0) { enum allSatisfy = true; } else static if (T.length == 1) { enum allSatisfy = F!(T[0]); } else { enum allSatisfy = allSatisfy!(F, T[ 0 .. $/2]) && allSatisfy!(F, T[$/2 .. $ ]); // // enum allSatisfy = F!(T[0]) && allSatisfy!(F, T[1 .. $ ]); } }
// template List(T...) { // alias List = T; }
template getMembers(T) { // List alias getMembers = List!(__traits(allMembers, T)); }
template staticReplicate(TS...) { // is(T) true, T static if(is(TS[0])) alias T = TS[0]; else // enum T = TS[0]; enum n = TS[1]; static if(n > 0) { alias staticReplicate = List!(T, staticReplicate!(T, n-1)); } else { alias staticReplicate = List!(); } } /// Example unittest { template isBool(T) { enum isBool = is(T == bool); } static assert(allSatisfy!(isBool, staticReplicate!(bool, 2))); static assert([staticReplicate!("42", 3)] == ["42", "42", "42"]); }
template staticMap2(alias F, T...) { static assert(T.length % 2 == 0); static if (T.length < 2) { alias staticMap2 = List!(); } else static if (T.length == 2) { alias staticMap2 = List!(F!(T[0], T[1])); } else { alias staticMap2 = List!(F!(T[0], T[1]), staticMap2!(F, T[2 .. $])); } } /// Example unittest { template Test(T...) { enum Test = T[0] && T[1]; } static assert([staticMap2!(Test, true, true, true, false)] == [true, false]); }
template staticFold(alias F, T...) { static if(T.length == 0) // invalid input { alias staticFold = List!(); } else static if(T.length == 1) { static if(is(T[0])) alias staticFold = T[0]; else enum staticFold = T[0]; } else { alias staticFold = staticFold!(F, F!(T[0], T[1]), T[2 .. $]); } }
template StrictList(T...) { alias expand = T; }
// StrictList, template staticRobin(SF...) { // private template minimum(T...) { enum length = T[1].expand.length; enum minimum = T[0] > length ? length : T[0]; } // enum minLength = staticFold!(minimum, size_t.max, SF); // , , private template robin(ulong i) { // i private template takeByIndex(alias T) { // , static if(is(T.expand[i])) alias takeByIndex = T.expand[i]; else enum takeByIndex = T.expand[i]; } static if(i >= minLength) { alias robin = List!(); } else { // staticMap!(takeByIndex, SF) i- alias robin = List!(staticMap!(takeByIndex, SF), robin!(i+1)); } } // alias staticRobin = robin!0; } /// Example unittest { alias test = staticRobin!(StrictList!(int, int, int), StrictList!(float, float)); static assert(is(test == List!(int, float, int, float))); alias test2 = staticRobin!(StrictList!(1, 2), StrictList!(3, 4, 5), StrictList!(6, 7)); static assert([test2]== [1, 3, 6, 2, 4, 7]); }
alias intMembers = StrictList!(getMembers!Interface); alias intTypes = StrictList!(staticReplicate!(Interface, intMembers.expand.length)); alias pairs = staticMap2!(bindType, staticRobin!(intTypes, intMembers)); private template bindType(Base, string T) { alias bindType = List!(typeof(mixin(Base.stringof ~ "." ~ T)), T); }
template checkMember(MemberType, string MemberName) { static if(hasMember!(Type, MemberName)) { enum checkMember = is(typeof(mixin(Type.stringof ~ "." ~ MemberName)) == MemberType); } else { enum checkMember = false; } } enum isExposeSingle = allSatisfy2!(checkMember, pairs);
template isExpose(Type, Interfaces...) { private template getMembers(T) { alias getMembers = List!(__traits(allMembers, T)); } private template isExposeSingle(Interface) { alias intMembers = StrictList!(getMembers!Interface); alias intTypes = StrictList!(staticReplicate!(Interface, intMembers.expand.length)); alias pairs = staticMap2!(bindType, staticRobin!(intTypes, intMembers)); private template bindType(Base, string T) { alias bindType = List!(typeof(mixin(Base.stringof ~ "." ~ T)), T); } template checkMember(MemberType, string MemberName) { static if(hasMember!(Type, MemberName)) { enum checkMember = is(typeof(mixin(Type.stringof ~ "." ~ MemberName)) == MemberType); } else { enum checkMember = false; } } enum isExposeSingle = allSatisfy2!(checkMember, pairs); } enum isExpose = allSatisfy!(isExposeSingle, Interfaces); }
struct CITest1 { string a; string meth1(); bool meth2(); } struct CITest2 { bool delegate(string) meth3(); } struct CITest3 { bool meth1(); } struct Test1 { string meth1() {return "";} bool meth2() {return true;} string a; bool delegate(string) meth3() { return (string) {return true;}; }; } static assert(isExpose!(Test1, CITest1, CITest2)); static assert(!isExpose!(Test1, CITest3));
Source: https://habr.com/ru/post/227015/
All Articles