1 module yu.memory.smartref; 2 3 import std.experimental.allocator; 4 5 public import yu.memory.scopedref; 6 public import yu.memory.sharedref; 7 public import yu.memory.allocator.smartgcalloctor; 8 import yu.traits; 9 10 alias SharedRef(T) = ISharedRef!(SmartGCAllocator, T,true); 11 alias WeakRef(T) = IWeakRef!(SmartGCAllocator, T,true); 12 alias ScopedRef(T) = IScopedRef!(SmartGCAllocator, T); 13 14 // alias 15 pragma(inline, true) auto makeSharedRef(T, Args...)(auto ref Args args) { 16 return SharedRef!(T)(SmartGCAllocator.instance.make!T(args)); 17 } 18 19 pragma(inline, true) auto makeScopedRef(T, Args...)(auto ref Args args) { 20 return ScopedRef!(T)(SmartGCAllocator.instance.make!T(args)); 21 } 22 23 pragma(inline, true) auto makeSharedRefWithDeleter(T, Args...)(auto ref Args args) { 24 static assert(args.length > 0); 25 static assert(is(typeof(args[0]) == void function(ref typeof(SmartGCAllocator.instance), Pointer!T) )); 26 return SharedRef!(T)(SmartGCAllocator.instance.make!T(args[1 .. $]), args[0]); 27 } 28 29 pragma(inline, true) auto makeScopedRefWithDeleter(T, Args...)(auto ref Args args) { 30 static assert(args.length > 0); 31 static assert(is(typeof(args[0]) == void function(ref typeof(SmartGCAllocator.instance), Pointer!T))); 32 return ScopedRef!(T)(SmartGCAllocator.instance.make!T(args[1 .. $]), args[0]); 33 } 34 35 // I 36 pragma(inline, true) auto makeISharedRef(T, Alloc, Args...)(auto ref Alloc alloc, auto ref Args args) { 37 Pointer!T value = alloc.make!T(args); 38 static if (stateSize!Alloc == 0) { 39 return ISharedRef!(Alloc, T)(value); 40 } else { 41 return ISharedRef!(Alloc, T)(alloc, value); 42 } 43 } 44 45 pragma(inline, true) auto makeIScopedRef(T, Alloc, Args...)(auto ref Alloc alloc, auto ref Args args) { 46 Pointer!T value = alloc.make!T(args); 47 static if (stateSize!Alloc == 0) { 48 return IScopedRef!(Alloc, T)(value); 49 } else { 50 return IScopedRef!(Alloc, T)(alloc, value); 51 } 52 } 53 54 pragma(inline, true) auto makeISharedRefWithDeleter(T, Alloc, Args...)( 55 auto ref Alloc alloc, auto ref Args args) { 56 static assert(args.length > 0); 57 static assert(is(typeof(args[0]) == void function(ref Alloc, Pointer!T))); 58 Pointer!T value = alloc.make!T(args[1 .. $]); 59 static if (stateSize!Alloc == 0) { 60 return ISharedRef!(Alloc, T)(value, args[0]); 61 } else { 62 return ISharedRef!(Alloc, T)(alloc, value, args[0]); 63 } 64 } 65 66 pragma(inline, true) auto makeIScopedRefWithDeleter(T, Alloc, Args...)( 67 auto ref Alloc alloc, auto ref Args args) { 68 static assert(args.length > 0); 69 static assert(is(typeof(args[0]) == void function(ref Alloc, Pointer!T))); 70 Pointer!T value = alloc.make!T(args[1 .. $]); 71 static if (stateSize!Alloc == 0) { 72 return IScopedRef!(Alloc, T)(value, args[0]); 73 } else { 74 return IScopedRef!(Alloc, T)(alloc, value, args[0]); 75 } 76 } 77 78 mixin template EnableSharedFromThisImpl(Alloc,T, bool Shread = true) 79 { 80 alias TWeakRef = IWeakRef!(Alloc,T,Shread); 81 alias TSharedRef = ISharedRef!(Alloc,T,Shread); 82 public: 83 pragma(inline,true) 84 final TSharedRef sharedFromThis() { return TSharedRef(__weakPointer); } 85 86 final void __InitializeFromSharedPointer(SHARED)(auto ref SHARED ptr) 87 if(is(SHARED == struct) && SHARED.isSharedRef && __traits(isSame, SHARED.Data, TWeakRef.Data)) 88 { 89 __weakPointer = ptr; 90 } 91 92 private TWeakRef __weakPointer; 93 } 94 95 version (unittest) { 96 import std.stdio; 97 import std.experimental.allocator; 98 import std.experimental.allocator.gc_allocator; 99 import std.exception; 100 101 void smartfreeSharedInt(ref typeof(SmartGCAllocator.instance) alloc, int* d) { 102 writeln("free the int"); 103 alloc.dispose(d); 104 } 105 106 void freeSharedInt(ref typeof(GCAllocator.instance) alloc, int* d) { 107 writeln("free the int"); 108 alloc.dispose(d); 109 } 110 111 class TestMyClass { 112 mixin EnableSharedFromThisImpl!(SmartGCAllocator,typeof(this)); 113 shared this(int t) { 114 i = t; 115 writeln("create TestMyClass i = ", i); 116 } 117 118 this(int t) { 119 i = t; 120 writeln("create TestMyClass i = ", i); 121 } 122 123 ~this() { 124 writeln("free TestMyClass i = ", i); 125 } 126 127 int i = 0; 128 } 129 } 130 131 132 unittest { 133 import std.stdio; 134 import std.experimental.allocator; 135 import std.experimental.allocator.gc_allocator; 136 import std.exception; 137 138 { 139 //auto malloc = 140 auto a = GCAllocator.instance.makeISharedRefWithDeleter!(int)(&freeSharedInt, 141 10); 142 assert(*a == 10); 143 auto c = a.castTo!(uint)(); 144 *c = uint.max; 145 uint t = cast(uint)(*a); 146 assert(t == uint.max); 147 auto b = GCAllocator.instance.makeISharedRef!int(100); 148 assert(*b == 100); 149 auto a1 = makeSharedRefWithDeleter!(int)(&smartfreeSharedInt, 10); 150 assert(*a1 == 10); 151 auto b1 = makeSharedRef!int(100); 152 assert(*b1 == 100); 153 154 } 155 writeln("Edit source/app.d to start your project."); 156 157 auto a = makeIScopedRefWithDeleter!(int)(GCAllocator.instance, &freeSharedInt); 158 auto a1 = makeScopedRefWithDeleter!(int)(&smartfreeSharedInt); 159 { 160 auto aclass = makeScopedRef!(TestMyClass)(10); 161 aclass.i = 500; 162 } 163 164 { 165 auto sclass = makeSharedRef!(shared TestMyClass)(100); 166 sclass.i = 1000; 167 168 auto sobj = sclass.castTo!(shared Object)(); 169 //auto nsared = sclass.castTo!(TestMyClass)(); , erro mast all sheref or not 170 171 auto t = makeSharedRef!(TestMyClass)(400); 172 t.i = 50; 173 auto th = t.sharedFromThis(); 174 auto tobj = th.castTo!(Object)(); 175 th.i = 30; 176 } 177 }