1- use std:: { marker:: PhantomData , ops:: Deref } ;
1+ use std:: {
2+ any:: Any ,
3+ hash:: { Hash , Hasher } ,
4+ marker:: PhantomData ,
5+ ops:: Deref ,
6+ } ;
27
8+ use crate :: { DatabaseDyn , DerivedNodeId , ParamId , dependency:: NodeKind } ;
39use intern:: InternId ;
410
5- use crate :: { DatabaseDyn , DerivedNodeId , ParamId , dependency:: NodeKind } ;
11+ type MemoRefProjectorStep = for <' a > fn ( & ' a dyn Any ) -> & ' a dyn Any ;
12+
13+ const MAX_PROJECTOR_STEPS : usize = 4 ;
14+
15+ #[ inline( always) ]
16+ fn step_identity ( value : & dyn Any ) -> & dyn Any {
17+ value
18+ }
19+
20+ #[ inline( always) ]
21+ fn step_result_ok < T : ' static , E : ' static > ( value : & dyn Any ) -> & dyn Any {
22+ match value
23+ . downcast_ref :: < Result < T , E > > ( )
24+ . expect ( "MemoRef<Result<..>>: underlying value has unexpected type" )
25+ {
26+ Ok ( t) => t as & dyn Any ,
27+ Err ( _) => unreachable ! ( "Ok projection used only after Ok check" ) ,
28+ }
29+ }
30+
31+ #[ inline( always) ]
32+ fn step_option_some < T : ' static > ( value : & dyn Any ) -> & dyn Any {
33+ match value
34+ . downcast_ref :: < Option < T > > ( )
35+ . expect ( "MemoRef<Option<..>>: underlying value has unexpected type" )
36+ {
37+ Some ( t) => t as & dyn Any ,
38+ None => unreachable ! ( "Some projection used only after Some check" ) ,
39+ }
40+ }
41+
42+ #[ inline( always) ]
43+ fn step_tuple_0 < T0 : ' static , T1 : ' static > ( value : & dyn Any ) -> & dyn Any {
44+ let ( t0, _) = value
45+ . downcast_ref :: < ( T0 , T1 ) > ( )
46+ . expect ( "MemoRef<(..)>: underlying value has unexpected type" ) ;
47+ t0 as & dyn Any
48+ }
49+
50+ #[ inline( always) ]
51+ fn step_tuple_1 < T0 : ' static , T1 : ' static > ( value : & dyn Any ) -> & dyn Any {
52+ let ( _, t1) = value
53+ . downcast_ref :: < ( T0 , T1 ) > ( )
54+ . expect ( "MemoRef<(..)>: underlying value has unexpected type" ) ;
55+ t1 as & dyn Any
56+ }
657
758#[ derive( Debug ) ]
859pub struct MemoRef < T > {
960 pub ( crate ) db : * const dyn DatabaseDyn ,
1061 pub ( crate ) derived_node_id : DerivedNodeId ,
62+ projectors : [ MemoRefProjectorStep ; MAX_PROJECTOR_STEPS ] ,
63+ projectors_len : u8 ,
1164 phantom : PhantomData < T > ,
1265}
1366
@@ -27,12 +80,23 @@ impl<T> PartialEq for MemoRef<T> {
2780
2881impl < T > Eq for MemoRef < T > { }
2982
83+ #[ allow( clippy:: unnecessary_cast) ]
84+ impl < T > Hash for MemoRef < T > {
85+ fn hash < H : Hasher > ( & self , state : & mut H ) {
86+ let data_ptr = self . db as * const dyn DatabaseDyn as * const ( ) ;
87+ data_ptr. hash ( state) ;
88+ self . derived_node_id . hash ( state) ;
89+ }
90+ }
91+
3092#[ allow( clippy:: unnecessary_cast) ]
3193impl < T : ' static + Clone > MemoRef < T > {
3294 pub fn new ( db : & dyn DatabaseDyn , derived_node_id : DerivedNodeId ) -> Self {
3395 Self {
3496 db : db as * const _ as * const dyn DatabaseDyn ,
3597 derived_node_id,
98+ projectors : [ step_identity; MAX_PROJECTOR_STEPS ] ,
99+ projectors_len : 0 ,
36100 phantom : PhantomData ,
37101 }
38102 }
@@ -63,6 +127,83 @@ impl<T: 'static> Deref for MemoRef<T> {
63127 NodeKind :: Derived ( self . derived_node_id ) ,
64128 revision. time_updated ,
65129 ) ;
66- value. downcast_ref :: < T > ( ) . unwrap ( )
130+ let mut any_ref: & dyn Any = value;
131+ let len = self . projectors_len as usize ;
132+ for step in & self . projectors [ ..len] {
133+ any_ref = ( step) ( any_ref) ;
134+ }
135+ any_ref
136+ . downcast_ref :: < T > ( )
137+ . expect ( "MemoRef: projector chain produced unexpected type" )
138+ }
139+ }
140+
141+ impl < T : ' static , E : ' static + Clone > MemoRef < Result < T , E > > {
142+ pub fn try_ok ( self ) -> Result < MemoRef < T > , E > {
143+ match self . deref ( ) {
144+ Ok ( _) => {
145+ let mut next = MemoRef :: < T > {
146+ db : self . db ,
147+ derived_node_id : self . derived_node_id ,
148+ projectors : self . projectors ,
149+ projectors_len : self . projectors_len ,
150+ phantom : PhantomData ,
151+ } ;
152+ let idx = next. projectors_len as usize ;
153+ next. projectors [ idx] = step_result_ok :: < T , E > ;
154+ next. projectors_len += 1 ;
155+ Ok ( next)
156+ }
157+ Err ( err) => Err ( err. clone ( ) ) ,
158+ }
159+ }
160+ }
161+
162+ impl < T : ' static > MemoRef < Option < T > > {
163+ pub fn try_some ( self ) -> Option < MemoRef < T > > {
164+ match self . deref ( ) {
165+ Some ( _) => {
166+ let mut next = MemoRef :: < T > {
167+ db : self . db ,
168+ derived_node_id : self . derived_node_id ,
169+ projectors : self . projectors ,
170+ projectors_len : self . projectors_len ,
171+ phantom : PhantomData ,
172+ } ;
173+ let idx = next. projectors_len as usize ;
174+ next. projectors [ idx] = step_option_some :: < T > ;
175+ next. projectors_len += 1 ;
176+ Some ( next)
177+ }
178+ None => None ,
179+ }
180+ }
181+ }
182+
183+ impl < T0 : ' static , T1 : ' static > MemoRef < ( T0 , T1 ) > {
184+ pub fn split ( self ) -> ( MemoRef < T0 > , MemoRef < T1 > ) {
185+ let mut left = MemoRef :: < T0 > {
186+ db : self . db ,
187+ derived_node_id : self . derived_node_id ,
188+ projectors : self . projectors ,
189+ projectors_len : self . projectors_len ,
190+ phantom : PhantomData ,
191+ } ;
192+ let idx = left. projectors_len as usize ;
193+ left. projectors [ idx] = step_tuple_0 :: < T0 , T1 > ;
194+ left. projectors_len += 1 ;
195+
196+ let mut right = MemoRef :: < T1 > {
197+ db : self . db ,
198+ derived_node_id : self . derived_node_id ,
199+ projectors : self . projectors ,
200+ projectors_len : self . projectors_len ,
201+ phantom : PhantomData ,
202+ } ;
203+ let idx = right. projectors_len as usize ;
204+ right. projectors [ idx] = step_tuple_1 :: < T0 , T1 > ;
205+ right. projectors_len += 1 ;
206+
207+ ( left, right)
67208 }
68209}
0 commit comments