1 /** 2 * Miscellaneous types. 3 */ 4 module asynchronous.types; 5 6 import std.algorithm; 7 import std.container.array; 8 import std.exception; 9 import std.traits; 10 11 struct Coroutine 12 { 13 } 14 15 template UNSPECIFIED(E) 16 if (is(E == enum)) 17 { 18 E UNSPECIFIED() 19 { 20 return cast(E) 0; 21 } 22 } 23 24 /** 25 * This operation was cancelled. 26 */ 27 class CancelledException : Exception 28 { 29 this(string message = null, string file = __FILE__, size_t line = __LINE__, 30 Throwable next = null) @safe pure nothrow 31 { 32 super(message, file, line, next); 33 } 34 } 35 36 /** 37 * This operation is not allowed in this state. 38 */ 39 class InvalidStateException : Exception 40 { 41 this(string message = null, string file = __FILE__, size_t line = __LINE__, 42 Throwable next = null) @safe pure nothrow 43 { 44 super(message, file, line, next); 45 } 46 } 47 48 /** 49 * This operation exceeded the given deadline. 50 */ 51 class TimeoutException : Exception 52 { 53 this(string message = null, string file = __FILE__, size_t line = __LINE__, 54 Throwable next = null) @safe pure nothrow 55 { 56 super(message, file, line, next); 57 } 58 } 59 60 /** 61 * This operation is not implemented. 62 */ 63 class NotImplementedException : Exception 64 { 65 this(string message = null, string file = __FILE__, size_t line = __LINE__, 66 Throwable next = null) @safe pure nothrow 67 { 68 super(message, file, line, next); 69 } 70 } 71 72 class ResourcePool(T, TArgs...) 73 if (is(T == class)) 74 { 75 private size_t inUseCount; 76 private Array!bool inUseFlags; 77 private Array!T resources; 78 79 private TArgs tArgs; 80 81 this(TArgs tArgs) 82 { 83 this.tArgs = tArgs; 84 } 85 86 T acquire(TResetArgs...)(TResetArgs tResetArgs) 87 out (result) 88 { 89 assert(result !is null); 90 } 91 body 92 { 93 auto count = inUseFlags[].countUntil!"!a"; 94 T result = null; 95 96 if (count >= 0) 97 { 98 inUseFlags[count] = true; 99 result = resources[count]; 100 } 101 else 102 { 103 inUseFlags.insertBack(true); 104 result = new T(tArgs); 105 resources.insertBack(result); 106 } 107 108 static if (hasMember!(T, "reset")) 109 result.reset(tResetArgs); 110 111 ++inUseCount; 112 return result; 113 } 114 115 void release(T t) 116 { 117 auto count = resources[].countUntil!(a => a is t); 118 119 enforce(count >= 0, "Cannot release non-acquired resource"); 120 121 static if (hasMember!(T, "reset")) 122 resources[count].reset; 123 124 inUseFlags[count] = false; 125 --inUseCount; 126 } 127 128 bool empty() 129 { 130 return inUseCount == 0; 131 } 132 133 override string toString() const 134 { 135 import std.format : format; 136 137 return "%s(length: %s, capacity: %s)".format(typeid(this), 138 inUseCount, inUseFlags.length); 139 } 140 }