@@ -121,6 +121,110 @@ public override void MarshalToManaged(MarshalContext ctx)
121121 ctx . ReturnVarName ) ;
122122 }
123123 }
124+
125+ [ TypeMap ( "std::optional" , GeneratorKindID = GeneratorKind . CLI_ID ) ]
126+ public class Optional : TypeMap
127+ {
128+ public override bool IsIgnored
129+ {
130+ get
131+ {
132+ var finalType = Type . GetFinalPointee ( ) ?? Type ;
133+ if ( finalType is not TemplateSpecializationType type )
134+ {
135+ var injectedClassNameType = ( InjectedClassNameType ) finalType ;
136+ type = ( TemplateSpecializationType ) injectedClassNameType . InjectedSpecializationType . Type ;
137+ }
138+ var checker = new TypeIgnoreChecker ( TypeMapDatabase ) ;
139+ type . Arguments [ 0 ] . Type . Visit ( checker ) ;
140+
141+ return checker . IsIgnored ;
142+ }
143+ }
144+
145+ public override Type SignatureType ( TypePrinterContext ctx )
146+ {
147+ return new CustomType ( $ "System::Nullable<{ ctx . GetTemplateParameterList ( ) } >") ;
148+ }
149+
150+ public override void MarshalToNative ( MarshalContext ctx )
151+ {
152+ var desugared = Type . Desugar ( ) ;
153+ var templateType = desugared as TemplateSpecializationType ;
154+ var type = templateType ! . Arguments [ 0 ] . Type ;
155+ var isPointerToPrimitive = type . Type . IsPointerToPrimitiveType ( ) ;
156+ var managedType = isPointerToPrimitive
157+ ? new CILType ( typeof ( nint ) )
158+ : type . Type ;
159+
160+ var paramName = ctx . Parameter ? . Name ?? ctx . ArgName ;
161+
162+ ctx . Before . WriteLineIndent ( "if (!{0}.HasValue)" , paramName ) ;
163+ ctx . Before . WriteOpenBraceAndIndent ( ) ;
164+ {
165+ ctx . Before . WriteLine ( "{0} = std::nullopt;" , ctx . ReturnVarName ) ;
166+ ctx . Before . WriteLine ( "return;" ) ;
167+ ctx . Before . UnindentAndWriteCloseBrace ( ) ;
168+ }
169+
170+ var param = new Parameter
171+ {
172+ Name = paramName + ".Value" ,
173+ QualifiedType = type
174+ } ;
175+
176+ var elementCtx = new MarshalContext ( ctx . Context , ctx . Indentation )
177+ {
178+ Parameter = param ,
179+ ArgName = param . Name ,
180+ } ;
181+
182+ var marshal = new CLIMarshalManagedToNativePrinter ( elementCtx ) ;
183+ type . Type . Visit ( marshal ) ;
184+
185+ if ( ! string . IsNullOrWhiteSpace ( marshal . Context . Before ) )
186+ ctx . Before . Write ( marshal . Context . Before ) ;
187+
188+ if ( isPointerToPrimitive )
189+ ctx . Return . Write ( "{0}.ToPointer()" , marshal . Context . Return ) ;
190+ else
191+ ctx . Return . Write ( marshal . Context . Return ) ;
192+ }
193+
194+ public override void MarshalToManaged ( MarshalContext ctx )
195+ {
196+ var desugared = Type . Desugar ( ) ;
197+ var templateType = desugared as TemplateSpecializationType ;
198+ var type = templateType ! . Arguments [ 0 ] . Type ;
199+ var isPointerToPrimitive = type . Type . IsPointerToPrimitiveType ( ) ;
200+ var managedType = isPointerToPrimitive
201+ ? new CILType ( typeof ( nint ) )
202+ : type . Type ;
203+
204+ ctx . Before . WriteLineIndent ( "if (!{0}.has_value())" , ctx . ArgName ) ;
205+ {
206+ ctx . Before . WriteLine ( "return {};" ) ;
207+ ctx . Before . Unindent ( ) ;
208+ }
209+
210+ var elementCtx = new MarshalContext ( ctx . Context , ctx . Indentation )
211+ {
212+ ReturnVarName = ctx . ReturnVarName + ".value()" ,
213+ ReturnType = type
214+ } ;
215+
216+ var marshal = new CLIMarshalNativeToManagedPrinter ( elementCtx ) ;
217+ type . Type . Visit ( marshal ) ;
218+
219+ if ( ! string . IsNullOrWhiteSpace ( marshal . Context . Before ) )
220+ ctx . Before . Write ( marshal . Context . Before ) ;
221+
222+ if ( isPointerToPrimitive )
223+ ctx . Return . Write ( "{0}({1})" , managedType , marshal . Context . Return ) ;
224+ else
225+ ctx . Return . Write ( marshal . Context . Return ) ;
226+ }
227+ }
124228
125229 [ TypeMap ( "std::vector" , GeneratorKindID = GeneratorKind . CLI_ID ) ]
126230 public class Vector : TypeMap
@@ -159,8 +263,7 @@ public override void MarshalToNative(MarshalContext ctx)
159263 ? new CILType ( typeof ( System . IntPtr ) )
160264 : type . Type ;
161265
162- var entryString = ( ctx . Parameter != null ) ? ctx . Parameter . Name
163- : ctx . ArgName ;
266+ var entryString = ctx . Parameter ? . Name ?? ctx . ArgName ;
164267
165268 var tmpVarName = "_tmp" + entryString ;
166269
@@ -314,7 +417,7 @@ public override void MarshalToNative(MarshalContext ctx)
314417 [ TypeMap ( "std::nullptr_t" , GeneratorKindID = GeneratorKind . CLI_ID ) ]
315418 public class NullPtr : TypeMap
316419 {
317- public override bool DoesMarshalling { get { return false ; } }
420+ public override bool DoesMarshalling => false ;
318421
319422 public override void CLITypeReference ( CLITypeReferenceCollector collector ,
320423 ASTRecord < Declaration > loc )
0 commit comments