1 /** 2 * Betterc: Frequently used primitives suitable for use in the BetterC D subset. 3 * inspired by https://theartofmachinery.com/2018/05/27/cpp_classes_in_betterc.html 4 * 5 * Copyright: Maxim Freck, 2018. 6 * Authors: Maxim Freck <maxim@freck.pp.ru> 7 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 8 */ 9 module betterc.cppclass; 10 11 import std.traits: ReturnType; 12 13 /******* 14 * Returns `true` if `T` is destructible with T.destructor() method. 15 * In other words tests whether `T` contains `void destructor()` method. 16 * Please note: the parent destructor must be called explicitly. 17 */ 18 enum bool isDestructable(T) = is(ReturnType!((T r) => r.destructor) == void); 19 20 /******* 21 * Creates an instance of T inside the malloc'd memory and calls its constructor. 22 * 23 * Params: 24 * Args... = Constructor arguments 25 * 26 * Returns: an instance of a class of type T 27 */ 28 T cnew(T, Args...)(auto ref Args args) 29 { 30 import core.stdc.stdlib: malloc; 31 import core.stdc.string: memcpy; 32 33 static immutable model = new T(); 34 enum kTSize = __traits(classInstanceSize, T); 35 auto instance = cast(T)malloc(kTSize); 36 memcpy(cast(void*)instance, cast(void*)model, kTSize); 37 instance.__ctor(args); 38 39 return instance; 40 } 41 42 /******* 43 * Calls the destructor of a previously malloc'd class and frees its memory 44 * 45 * Params: 46 * instance = Class instance 47 */ 48 void cdelete(T)(T instance) 49 { 50 import core.stdc.stdlib: free; 51 52 // __xdtor() is non-virtual and non-@nogc 53 // so let's just use destructor() method 54 // before freing object's memory 55 static if(isDestructable!T) instance.destructor(); 56 57 free(cast(void*)instance); 58 } 59