www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - autoptr (ref counted pointers)

reply vit <vit vit.vit> writes:
Hello,
I implemented reference counted pointers supporting:
- weak pointers (optional).
- aliasing.
- atomic/non-atomic counters.
- multithread ref counted pointers .
- arrays.
- destructors with attributes
- pure, const, immutable and shared support.
- limited dip1000 and  safe support.
- intrusive pointers
- unique pointers

Api is inspired with std::shared_ptr
Implementation is inspired by clang std::shared_ptr.

git: https://github.com/submada/autoptr
doc: https://submada.github.io/autoptr/
dub: https://code.dlang.org/packages/autoptr

Examples:
```d

import autoptr.shared_ptr;


///
pure nothrow  nogc unittest{

     static class Foo{
         int i;

         this(int i)pure nothrow  safe  nogc{
             this.i = i;
         }
     }

     static class Bar : Foo{
         double d;

         this(int i, double d)pure nothrow  safe  nogc{
             super(i);
             this.d = d;
         }
     }

     //implicit qualifier cast
     {
         SharedPtr!(const Foo) foo =  SharedPtr!Foo.make(42);
         assert(foo.get.i == 42);
         assert(foo.useCount == 1);

         const SharedPtr!Foo foo2 = foo;
         assert(foo2.get.i == 42);
         assert(foo.useCount == 2);

     }

     //polymorphic classes:
     {
         SharedPtr!Foo foo = SharedPtr!Bar.make(42, 3.14);
         assert(foo != null);
         assert(foo.useCount == 1);
         assert(foo.get.i == 42);

         //dynamic cast:
         {
             SharedPtr!Bar bar = dynCast!Bar(foo);
             assert(foo.useCount == 2);

             assert(bar.get.i == 42);
             assert(bar.get.d == 3.14);
         }

     }

     //aliasing:
     {
         SharedPtr!Foo foo = SharedPtr!Bar.make(42, 3.14);
         assert(foo.useCount == 1);

         auto x = SharedPtr!int(foo, &foo.get.i);
         assert(foo.useCount == 2);
         assert(x.useCount == 2);

         assert(*x == 42);
     }

     //weak references:
     {
         auto x = SharedPtr!double.make(3.14);
         assert(x.useCount == 1);
         assert(x.weakCount == 0);

         auto w = x.weak();  //weak pointer
         assert(x.useCount == 1);
         assert(x.weakCount == 1);
         assert(*w.lock == 3.14);

         SharedPtr!double.WeakType w2 = x;
         assert(x.useCount == 1);
         assert(x.weakCount == 2);

         assert(w2.expired == false);
         x = null;
         assert(w2.expired == true);
     }

     //dynamic array
     {
         import std.algorithm : all;

         {
             auto arr = SharedPtr!(long[]).make(10, -1);

             assert(arr.length == 10);
             assert(arr.get.all!(x => x == -1));
         }

         {
             auto arr = SharedPtr!(long[]).make(8);
             assert(arr.length == 8);
             assert(arr.get.all!(x => x == long.init));
         }
     }

     //static array
     {
         import std.algorithm : all;

         {
             auto arr = SharedPtr!(long[4]).make(-1);
             assert(arr.get[].all!(x => x == -1));

         }

         {
             long[4] tmp = [0, 1, 2, 3];
             auto arr = SharedPtr!(long[4]).make(tmp);
             assert(arr.get[] == tmp[]);
         }
     }

}

///
pure nothrow  safe  nogc unittest{
     //make SharedPtr object
     static struct Foo{
         int i;

         this(int i)pure nothrow  safe  nogc{
             this.i = i;
         }
     }

     {
         auto foo = SharedPtr!Foo.make(42);
         auto foo2 = SharedPtr!Foo.make!Mallocator(42);  
//explicit stateless allocator
     }

     {
         import std.experimental.allocator : make, dispose;

         static void deleter(long* x)pure nothrow  trusted  nogc{
             Mallocator.instance.dispose(x);
         }
         long* element = Mallocator.instance.make!long;

         auto x = SharedPtr!long.make(element, &deleter);
     }

     {
         auto arr = SharedPtr!(long[]).make(10); //dynamic array 
with length 10
         assert(arr.length == 10);
     }
}

///
nothrow unittest{
     //alloc SharedPtr object
     import std.experimental.allocator : make, dispose, 
allocatorObject;

     auto allocator = allocatorObject(Mallocator.instance);

     {
         auto x = SharedPtr!long.alloc(allocator, 42);
     }

     {
         static void deleter(long* x)pure nothrow  trusted  nogc{
             Mallocator.instance.dispose(x);
         }
         long* element = Mallocator.instance.make!long;
         auto x = SharedPtr!long.alloc(allocator, element, 
&deleter);
     }

     {
         auto arr = SharedPtr!(long[]).alloc(allocator, 10); 
//dynamic array with length 10
         assert(arr.length == 10);
     }

}
```
Nov 12 2021
parent Salih Dincer <salihdb hotmail.com> writes:
On Friday, 12 November 2021 at 14:32:42 UTC, vit wrote:
 Hello,
 I implemented reference counted pointers supporting:
 - weak pointers (optional).
 - aliasing.
 - atomic/non-atomic counters.
 - multithread ref counted pointers .
 - arrays.
 - destructors with attributes
 - pure, const, immutable and shared support.
 - limited dip1000 and  safe support.
 - intrusive pointers
 - unique pointers

 Api is inspired with std::shared_ptr
 Implementation is inspired by clang std::shared_ptr.

 git: https://github.com/submada/autoptr
 doc: https://submada.github.io/autoptr/
 dub: https://code.dlang.org/packages/autoptr
Nicely done! There are over 1000 lines of test code, line 2590 starts unittests. Thank you...
Nov 13 2021