@@ -6,7 +6,7 @@ const assert = std.debug.assert;
6
6
const expect = std .testing .expect ;
7
7
const expectEqual = std .testing .expectEqual ;
8
8
9
- pub const SelfType = @OpaqueType ( );
9
+ pub const SelfType = @Type ( .Opaque );
10
10
11
11
fn makeSelfPtr (ptr : anytype ) * SelfType {
12
12
if (comptime ! trait .isSingleItemPtr (@TypeOf (ptr ))) {
@@ -43,16 +43,21 @@ pub const Storage = struct {
43
43
erased_ptr : * SelfType ,
44
44
ImplType : type ,
45
45
46
- pub fn init ( args : anytype ) ! Comptime {
47
- if ( args . len != 1 ) {
48
- @compileError ( "Comptime storage expected a 1-tuple in initialization." );
49
- }
46
+ fn makeInit ( comptime TInterface : type ) type {
47
+ return struct {
48
+ fn init ( obj : anytype ) ! TInterface {
49
+ const ImplType = PtrChildOrSelf ( @TypeOf ( obj ));
50
50
51
- var obj = args [ 0 ] ;
51
+ comptime var obj_holder = obj ;
52
52
53
- return Comptime {
54
- .erased_ptr = makeSelfPtr (& obj ),
55
- .ImplType = @TypeOf (args [0 ]),
53
+ return TInterface {
54
+ .vtable_ptr = & comptime makeVTable (TInterface .VTable , ImplType ),
55
+ .storage = Comptime {
56
+ .erased_ptr = makeSelfPtr (& obj_holder ),
57
+ .ImplType = @TypeOf (obj ),
58
+ },
59
+ };
60
+ }
56
61
};
57
62
}
58
63
@@ -66,13 +71,16 @@ pub const Storage = struct {
66
71
pub const NonOwning = struct {
67
72
erased_ptr : * SelfType ,
68
73
69
- pub fn init (args : anytype ) ! NonOwning {
70
- if (args .len != 1 ) {
71
- @compileError ("NonOwning storage expected a 1-tuple in initialization." );
72
- }
73
-
74
- return NonOwning {
75
- .erased_ptr = makeSelfPtr (args [0 ]),
74
+ fn makeInit (comptime TInterface : type ) type {
75
+ return struct {
76
+ fn init (ptr : anytype ) ! TInterface {
77
+ return TInterface {
78
+ .vtable_ptr = & comptime makeVTable (TInterface .VTable , PtrChildOrSelf (@TypeOf (ptr ))),
79
+ .storage = NonOwning {
80
+ .erased_ptr = makeSelfPtr (ptr ),
81
+ },
82
+ };
83
+ }
76
84
};
77
85
}
78
86
@@ -87,19 +95,22 @@ pub const Storage = struct {
87
95
allocator : * mem.Allocator ,
88
96
mem : []u8 ,
89
97
90
- pub fn init (args : anytype ) ! Owning {
91
- if (args .len != 2 ) {
92
- @compileError ("Owning storage expected a 2-tuple in initialization." );
93
- }
94
-
95
- const AllocT = @TypeOf (args [0 ]);
98
+ fn makeInit (comptime TInterface : type ) type {
99
+ return struct {
100
+ fn init (obj : anytype , allocator : * std.mem.Allocator ) ! TInterface {
101
+ const AllocT = @TypeOf (obj );
96
102
97
- var obj = try args [ 1 ] .create (AllocT );
98
- obj .* = args [ 0 ] ;
103
+ var ptr = try allocator .create (AllocT );
104
+ ptr .* = obj ;
99
105
100
- return Owning {
101
- .allocator = args [1 ],
102
- .mem = std .mem .asBytes (obj )[0.. ],
106
+ return TInterface {
107
+ .vtable_ptr = & comptime makeVTable (TInterface .VTable , PtrChildOrSelf (AllocT )),
108
+ .storage = Owning {
109
+ .allocator = allocator ,
110
+ .mem = std .mem .asBytes (ptr )[0.. ],
111
+ },
112
+ };
113
+ }
103
114
};
104
115
}
105
116
@@ -119,23 +130,28 @@ pub const Storage = struct {
119
130
120
131
mem : [size ]u8 ,
121
132
122
- pub fn init (args : anytype ) ! Self {
123
- if (args .len != 1 ) {
124
- @compileError ("Inline storage expected a 1-tuple in initialization." );
125
- }
126
-
127
- const ImplSize = @sizeOf (@TypeOf (args [0 ]));
128
-
129
- if (ImplSize > size ) {
130
- @compileError ("Type does not fit in inline storage." );
131
- }
132
-
133
- var self : Self = undefined ;
134
-
135
- if (ImplSize > 0 ) {
136
- std .mem .copy (u8 , self .mem [0.. ], @ptrCast ([* ]const u8 , & args [0 ])[0.. ImplSize ]);
137
- }
138
- return self ;
133
+ fn makeInit (comptime TInterface : type ) type {
134
+ return struct {
135
+ fn init (value : anytype ) ! TInterface {
136
+ const ImplSize = @sizeOf (@TypeOf (value ));
137
+
138
+ if (ImplSize > size ) {
139
+ @compileError ("Type does not fit in inline storage." );
140
+ }
141
+
142
+ var self = Self {
143
+ .mem = undefined ,
144
+ };
145
+ if (ImplSize > 0 ) {
146
+ std .mem .copy (u8 , self .mem [0.. ], @ptrCast ([* ]const u8 , & args [0 ])[0.. ImplSize ]);
147
+ }
148
+
149
+ return TInterface {
150
+ .vtable_ptr = & comptime makeVTable (TInterface .VTable , PtrChildOrSelf (@TypeOf (value ))),
151
+ .storage = self ,
152
+ };
153
+ }
154
+ };
139
155
}
140
156
141
157
pub fn getSelfPtr (self : * Self ) * SelfType {
@@ -426,15 +442,10 @@ pub fn Interface(comptime VTableT: type, comptime StorageT: type) type {
426
442
storage : StorageT ,
427
443
428
444
const Self = @This ();
445
+ const VTable = VTableT ;
446
+ const Storage = StorageT ;
429
447
430
- pub fn init (args : anytype ) ! Self {
431
- const ImplType = PtrChildOrSelf (@TypeOf (args .@"0" ));
432
-
433
- return Self {
434
- .vtable_ptr = & comptime makeVTable (VTableT , ImplType ),
435
- .storage = try StorageT .init (args ),
436
- };
437
- }
448
+ pub const init = StorageT .makeInit (Self ).init ;
438
449
439
450
pub fn initWithVTable (vtable_ptr : * const VTableT , args : anytype ) ! Self {
440
451
return .{
0 commit comments