99 Authors: Luna Nielsen
1010*/
1111module numem.rc ;
12+ import numem.core.lifetime ;
1213import numem.core.hooks ;
14+ import numem.core.traits ;
1315import numem.lifetime;
1416
1517/**
16- A reference counted container.
18+ A semi-automatically reference counted value container.
1719*/
1820struct Rc (T) {
19- public :
21+ private :
2022@nogc :
21- mixin RcBase! T;
23+ alias RCT = __rc! T;
24+ RCT * rc;
25+
26+ pragma (inline, true )
27+ void __retain () @trusted {
28+ if (rc) {
29+ nu_atomic_add_32(rc.refs, 1 );
30+ }
31+ }
32+
33+ pragma (inline, true )
34+ void __release () @trusted {
35+ if (rc) {
36+ if (nu_atomic_sub_32(rc.refs, 1 ) == 1 ) {
37+ nogc_trydelete(rc.value);
38+ nu_free(rc);
39+
40+ }
41+ }
42+ this .rc = null ;
43+ }
44+
45+ public :
46+ alias value this ;
2247
2348 /**
24- Creates an reference counted object using given $(D value).
49+ Whether the RC value is valid.
50+ */
51+ @property bool isValid() inout nothrow @safe => rc ! is null ;
52+
53+ /**
54+ The value stored in the rc type.
55+ */
56+ @property ref inout (T) value() inout nothrow @safe => cast (inout (T))rc.value;
57+
58+ // / Destructor
59+ ~this () {
60+ this .__release();
61+ }
62+
63+ /**
64+ Creates an reference counted object using given $(D value),
65+ if value is given by reference, it is moved to the Rc.
2566
2667 Params:
2768 value = The value.
2869 */
29- this (T value) @trusted {
30- this .rc = nogc_new! __rc(1 , value);
70+ this (in inout (T) value) @trusted {
71+ RCT * rc = cast (RCT * )nu_malloc(RCT .sizeof);
72+ rc.value = cast (T)value;
73+ rc.refs = 1 ;
74+
75+ nu_atomic_store_ptr(cast (void ** )&this .rc, rc);
76+ }
77+
78+ /**
79+ Copy constructor
80+ */
81+ this (ref return scope inout (typeof (this )) rhs) @trusted {
82+ this .rc = cast (RCT * )rhs.rc;
83+ this .__retain();
3184 }
3285
3386 /**
@@ -46,76 +99,28 @@ public:
4699 this .__release();
47100 return this ;
48101 }
49- }
50-
51- /**
52- Automatically reference counted value.
53- */
54- struct Arc (T) {
55- public :
56- @nogc :
57- mixin RcBase! T;
58-
59- // / Destructor
60- ~this () {
61- this .__release();
62- }
63102
64103 /**
65- Creates an reference counted object using given $(D value).
66-
67- Params:
68- value = The value.
104+ Implements implicit cast for RC value validity.
69105 */
70- this (T value) @trusted {
71- this .rc = nogc_new! __rc(1 , value);
72- }
106+ T opCast (T : bool )() inout nothrow @safe => isValid();
73107
74108 /**
75- Copy constructor
109+ Implements base cast
76110 */
77- this (ref return scope inout (typeof (this )) rhs) inout @trusted {
78- this .rc = rhs.rc;
79- (cast (Arc! T)this ).__retain();
111+ ref T opCast (T : typeof (this ))() inout nothrow {
112+ return * (cast (T* )(cast (void ** )&rc.value));
80113 }
81114}
82115
83- // Base RefCounted.
84- private mixin template RcBase(T) {
116+ //
117+ // IMPLEMENTATION DETAILS
118+ //
85119private :
86- @nogc :
87- static struct __rc {
88- private :
89- @nogc :
90- uint refs;
91- T value;
92- }
93-
94- __rc* rc;
95120
96- pragma (inline, true )
97- void __retain () @trusted nothrow {
98- if (rc) {
99- nu_atomic_add_32(rc.refs, 1 );
100- }
101- }
102-
103- pragma (inline, true )
104- void __release () @trusted nothrow {
105- if (rc) {
106- if (nu_atomic_sub_32(rc.refs, 1 ) == 1 ) {
107- nogc_delete(rc.value);
108- nu_free(rc);
109- }
110- }
111- this .rc = null ;
112- }
113-
114- public :
115- alias value this ;
116-
117- /**
118- The value stored in the rc type.
119- */
120- @property T value() @safe => rc ? rc.value : T.init;
121+ struct __rc (T) {
122+ private :
123+ @nogc :
124+ uint refs;
125+ T value;
121126}
0 commit comments