1 /* 2 * Copyright (C) 2023 Mai-Lapyst 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU Affero 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 Affero General Public License for more details. 13 * 14 * You should have received a copy of the GNU Affero General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 /** 19 * Module to provide callables for dlang. 20 * 21 * License: $(HTTP https://www.gnu.org/licenses/agpl-3.0.html, AGPL 3.0). 22 * Copyright: Copyright (C) 2023 Mai-Lapyst 23 * Authors: $(HTTP codeark.it/Mai-Lapyst, Mai-Lapyst) 24 */ 25 module ministd.callable; 26 27 /// A struct that makes holding any function and/or delegate a breeze! 28 struct Callable(RetT, ParamsT...) { 29 this(RetT function(ParamsT) fn) pure nothrow @nogc @safe { 30 () @trusted { this.fn = fn; }(); 31 this.kind = Kind.FN; 32 } 33 this(RetT delegate(ParamsT) dg) pure nothrow @nogc @safe { 34 () @trusted { this.dg = dg; }(); 35 this.kind = Kind.DG; 36 } 37 38 RetT opCall(ParamsT params) { 39 final switch (this.kind) { 40 case Kind.FN: return fn(params); 41 case Kind.DG: return dg(params); 42 case Kind.NO: throw new Exception("Called uninitialzed Callable!"); 43 } 44 } 45 46 private: 47 enum Kind { NO, FN, DG } 48 Kind kind = Kind.NO; 49 union { 50 RetT function(ParamsT) fn; 51 RetT delegate(ParamsT) dg; 52 } 53 } 54 55 unittest { 56 auto adder = Callable!(int, int, int)( (int a, int b) => a + b ); 57 assert( adder(12, 34) == (12 + 34) ); 58 }