1 /// Flag enum to string conversion, flag get/sets, and mask interactions. 2 module tern.state; 3 4 import tern.traits; 5 6 public: 7 static: 8 pure: 9 /** 10 * Generates a string representation of a value based on its flag members. 11 * 12 * Params: 13 * val = The value for which to generate the string representation. 14 * 15 * Returns: 16 * A string representing the flag members set in the value. 17 */ 18 string toString(T)(T val) 19 { 20 foreach (string member; Children!T) 21 { 22 if (val.hasFlag(__traits(getMember, T, member))) 23 { 24 string str; 25 foreach (m; Children!T) 26 { 27 if (val.hasFlag(__traits(getMember, T, m))) 28 str ~= m~" | "; 29 } 30 return str[0 .. $-3]; 31 } 32 } 33 return Children!T[0]; 34 } 35 36 @nogc: 37 /** 38 * Checks if a value has a specific flag set. 39 * 40 * Params: 41 * value = The value to check for the flag. 42 * flag = The flag to check within the value. 43 * 44 * Returns: 45 * A boolean indicating whether the flag is set in the value. 46 */ 47 bool hasFlag(T)(T value, T flag) 48 { 49 return (value & flag) != 0; 50 } 51 52 /** 53 * Checks if a value's masked portion matches a specific flag. 54 * 55 * Params: 56 * value = The value to check for the flag match. 57 * mask = The mask to apply to the value. 58 * flag = The flag to match within the masked value. 59 * 60 * Returns: 61 * A boolean indicating whether the flag matches the masked value. 62 */ 63 bool hasFlagMasked(T)(T value, T mask, T flag) 64 { 65 return (value & mask) == flag; 66 } 67 68 /** 69 * Sets or clears a flag in a value based on the provided state. 70 * 71 * Params: 72 * value = Reference to the value where the flag will be modified. 73 * flag = The flag to set or clear. 74 * state = A boolean indicating whether to set or clear the flag. 75 */ 76 void setFlag(T)(ref T value, T flag, bool state) 77 { 78 value = cast(T)(state ? (value | flag) : (value & ~flag)); 79 } 80 81 /** 82 * Toggles a flag in a value. 83 * 84 * Params: 85 * value = Reference to the value where the flag will be toggled. 86 * flag = The flag to toggle. 87 */ 88 void toggleFlag(T)(ref T value, T flag) 89 { 90 value = cast(T)(value ^ flag); 91 } 92 93 /** 94 * Sets a flag in a masked value based on the provided state. 95 * 96 * Params: 97 * value = Reference to the value where the flag will be modified. 98 * mask = The mask to apply to the value. 99 * flag = The flag to set or clear. 100 * state = A boolean indicating whether to set or clear the flag. 101 */ 102 void setFlagMasked(T)(ref T value, T mask, T flag, bool state) 103 { 104 value = cast(T)(state ? (value & mask) | flag : (value & mask) & ~flag); 105 } 106 107 /** 108 * Toggles a flag within a masked value. 109 * 110 * Params: 111 * value = Reference to the value where the flag will be toggled. 112 * mask = The mask to apply to the value. 113 * flag = The flag to toggle within the masked value. 114 */ 115 void toggleFlagMasked(T)(ref T value, T mask, T flag) 116 { 117 value = cast(T)((value & mask) ^ flag); 118 } 119 120 /** 121 * Clears a mask from the provided value. 122 * 123 * Params: 124 * value = The value from which the mask will be cleared. 125 * mask = The mask to clear from the value. 126 * 127 * Returns: 128 * The value after clearing the specified mask. 129 */ 130 T clearMask(T)(T value, T mask) 131 { 132 return cast(T)(value & ~mask); 133 }