1 /* Supporting different types and containers. 2 * Copyright (C) 2017 Marko Semet 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 */ 17 module structuresd.utils; 18 19 private 20 { 21 import std.algorithm.comparison; 22 import std.meta; 23 } 24 25 /** 26 * Check two function have same enough signature to convert T2 to T1. Result type is a bool. 27 * @tparam T1 Base function 28 * @tparam T2 Function to check 29 */ 30 public enum bool isSameFunction(alias T1, alias T2) = is(typeof(&T1) : typeof(&T2)); 31 32 /** 33 * Check function from two different containers to be equal. Result type is a boolean. 34 * BASE_T have to contain a member with the name NAME 35 * @tparam BASE_T base type 36 * @tparam TYPE_T container to check 37 * @tparam NAME name of the member 38 */ 39 template isSameContainerFunction(BASE_T, TYPE_T, string NAME) 40 { 41 static assert(__traits(hasMember, BASE_T, NAME)); 42 public enum bool isSameContainerFunction = __traits(hasMember, TYPE_T, NAME) && isSameFunction!(__traits(getMember, BASE_T, NAME), __traits(getMember, TYPE_T, NAME)); 43 } 44 45 /** 46 * Checks if an member has an attribute. 47 * @tparam ATTRIBUTE The attribute to check if exits. 48 * @tparam MEMBER The member to check. 49 */ 50 public template hasAttribute(ATTRIBUTE, alias MEMBER) 51 { 52 enum bool hasAttribute = Filter!(_hasAttribute!ATTRIBUTE, __traits(getAttributes, MEMBER)).length > 0; 53 } 54 private template _hasAttribute(ATTRIBUTE) 55 { 56 enum bool _hasAttribute(MEMBER) = is(ATTRIBUTE == MEMBER); 57 } 58 59 /** 60 * List all members with matching credentials. 61 * @tparam CHECKER The checker function 62 * @tparam TYPE The type to search in. 63 */ 64 public template membersWith(alias CHECKER, TYPE) 65 { 66 alias membersWith = Filter!(_membersWith!(CHECKER, TYPE), __traits(allMembers, TYPE)); 67 } 68 private template _membersWith(alias CHECKER, TYPE) 69 { 70 alias _membersWith(alias T) = CHECKER!(__traits(getMember, TYPE, T)); 71 } 72 73 /** 74 * Returns array type 75 * @tparam T The array to unpack 76 */ 77 public template arrayType(alias T = A[], A) 78 { 79 alias arrayType = A; 80 } 81 82 /** 83 * Returns the minimum. 84 * @tparam T Parameters of the function 85 * @return Type from the first parameter 86 */ 87 pragma(inline, true) 88 public T[0] min(T...)(T data) if(T.length > 0) 89 { 90 T[0] result = data[0]; 91 static foreach(i; data[1..$]) 92 { 93 result = result < i ? result : i; 94 } 95 return result; 96 } 97 98 /** 99 * Returns the maximum. 100 * @tparam T Parameters of the function 101 * @return Type from the first parameter 102 */ 103 pragma(inline, true) 104 public T[0] max(T...)(T data) 105 { 106 T[0] result = data[0]; 107 static foreach(i; data) 108 { 109 result = result > i ? result : i; 110 } 111 return result; 112 }