1 /// Utilities not related to IRC. 2 module irc.util; 3 4 import core.exception : OutOfMemoryError; 5 import core.stdc.stdlib : malloc, free; 6 7 import std.algorithm; 8 import std.array; 9 import std.conv : emplace; 10 import std.exception; 11 import std.range; 12 import std.traits; 13 14 auto values(Elems...)(auto ref Elems elems) if(is(CommonType!Elems)) 15 { 16 alias CommonType!Elems ElemType; 17 18 static struct StaticArray 19 { 20 ElemType[Elems.length] data = void; 21 size_t i = 0; 22 23 bool empty() const 24 { 25 return i == data.length; 26 } 27 28 ElemType front() const pure 29 { 30 return data[i]; 31 } 32 33 void popFront() pure 34 { 35 ++i; 36 } 37 38 enum length = data.length; 39 } 40 41 StaticArray arr; 42 43 foreach(i, ref elem; elems) 44 arr.data[i] = elem; 45 46 return arr; 47 } 48 49 unittest 50 { 51 assert( 52 values("one", "two", "three") 53 .joiner(" ") 54 .array() == "one two three"); 55 } 56 57 auto castRange(T, R)(R range) 58 { 59 static struct Casted 60 { 61 R r; 62 63 T front() 64 { 65 return cast(T)r.front; 66 } 67 68 alias r this; 69 } 70 71 return Casted(range); 72 } 73 74 T* alloc(T)() 75 { 76 import core.exception : onOutOfMemoryError; 77 78 if(auto p = malloc(T.sizeof)) 79 { 80 auto block = p[0 .. T.sizeof]; 81 return emplace!T(block); 82 } 83 else 84 { 85 onOutOfMemoryError(); 86 assert(false); 87 } 88 } 89 90 void dealloc(void* p) 91 { 92 free(p); 93 } 94 95 mixin template ExceptionConstructor() 96 { 97 @safe pure nothrow 98 this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) 99 { 100 super(msg, file, line, next); 101 } 102 } 103 104 mixin template ExceptionConstructor(string defaultMessage) 105 { 106 @safe pure nothrow 107 this(string msg = defaultMessage, string file = __FILE__, size_t line = __LINE__, Throwable next = null) 108 { 109 super(msg, file, line, next); 110 } 111 }