@@ -653,18 +653,18 @@ impl Type {
653
653
654
654
/// If this type is a class template specialization, return its
655
655
/// template arguments. Otherwise, return None.
656
- pub fn template_args ( & self ) -> Option < TypeTemplateArgIterator > {
657
- let n = unsafe { clang_Type_getNumTemplateArguments ( self . x ) } ;
658
- if n >= 0 {
659
- Some ( TypeTemplateArgIterator {
660
- x : self . x ,
661
- length : n as u32 ,
662
- index : 0 ,
663
- } )
664
- } else {
665
- debug_assert_eq ! ( n , - 1 ) ;
666
- None
667
- }
656
+ pub fn template_args < ' a >
657
+ ( & ' a self )
658
+ -> Option < Box < ExactSizeIterator < Item = Type > + ' a > > {
659
+ let f_len =
660
+ move || unsafe { clang_Type_getNumTemplateArguments ( self . x ) } ;
661
+ let f = move |i| {
662
+ Type {
663
+ x : unsafe { clang_Type_getTemplateArgumentAsType ( self . x , i ) } ,
664
+ }
665
+ } ;
666
+
667
+ ffi_call_index_iterator_check_positive ( f_len , f )
668
668
}
669
669
670
670
/// Given that this type is a pointer type, return the type that it points
@@ -761,35 +761,6 @@ impl Type {
761
761
}
762
762
}
763
763
764
- /// An iterator for a type's template arguments.
765
- pub struct TypeTemplateArgIterator {
766
- x : CXType ,
767
- length : u32 ,
768
- index : u32 ,
769
- }
770
-
771
- impl Iterator for TypeTemplateArgIterator {
772
- type Item = Type ;
773
- fn next ( & mut self ) -> Option < Type > {
774
- if self . index < self . length {
775
- let idx = self . index as c_int ;
776
- self . index += 1 ;
777
- Some ( Type {
778
- x : unsafe { clang_Type_getTemplateArgumentAsType ( self . x , idx) } ,
779
- } )
780
- } else {
781
- None
782
- }
783
- }
784
- }
785
-
786
- impl ExactSizeIterator for TypeTemplateArgIterator {
787
- fn len ( & self ) -> usize {
788
- assert ! ( self . index <= self . length) ;
789
- ( self . length - self . index ) as usize
790
- }
791
- }
792
-
793
764
/// A `SourceLocation` is a file, line, column, and byte offset location for
794
765
/// some source text.
795
766
pub struct SourceLocation {
@@ -845,12 +816,16 @@ impl Comment {
845
816
}
846
817
847
818
/// Get this comment's children comment
848
- pub fn get_children ( & self ) -> CommentChildrenIterator {
849
- CommentChildrenIterator {
850
- parent : self . x ,
851
- length : unsafe { clang_Comment_getNumChildren ( self . x ) } ,
852
- index : 0 ,
853
- }
819
+ pub fn get_children < ' a > ( & ' a self )
820
+ -> Box < ExactSizeIterator < Item = Comment > + ' a > {
821
+ let f_len = move || unsafe { clang_Comment_getNumChildren ( self . x ) } ;
822
+ let f = move |i| {
823
+ Comment {
824
+ x : unsafe { clang_Comment_getChild ( self . x , i) } ,
825
+ }
826
+ } ;
827
+
828
+ ffi_call_index_iterator ( f_len, f)
854
829
}
855
830
856
831
/// Given that this comment is the start or end of an HTML tag, get its tag
@@ -860,34 +835,22 @@ impl Comment {
860
835
}
861
836
862
837
/// Given that this comment is an HTML start tag, get its attributes.
863
- pub fn get_tag_attrs ( & self ) -> CommentAttributesIterator {
864
- CommentAttributesIterator {
865
- x : self . x ,
866
- length : unsafe { clang_HTMLStartTag_getNumAttrs ( self . x ) } ,
867
- index : 0 ,
868
- }
869
- }
870
- }
871
-
872
- /// An iterator for a comment's children
873
- pub struct CommentChildrenIterator {
874
- parent : CXComment ,
875
- length : c_uint ,
876
- index : c_uint ,
877
- }
838
+ pub fn get_tag_attrs < ' a >
839
+ ( & ' a self )
840
+ -> Box < ExactSizeIterator < Item = CommentAttribute > + ' a > {
841
+ let f_len = move || unsafe { clang_HTMLStartTag_getNumAttrs ( self . x ) } ;
842
+ let f = move |i| {
843
+ CommentAttribute {
844
+ name : unsafe {
845
+ clang_HTMLStartTag_getAttrName ( self . x , i) . into ( )
846
+ } ,
847
+ value : unsafe {
848
+ clang_HTMLStartTag_getAttrValue ( self . x , i) . into ( )
849
+ } ,
850
+ }
851
+ } ;
878
852
879
- impl Iterator for CommentChildrenIterator {
880
- type Item = Comment ;
881
- fn next ( & mut self ) -> Option < Comment > {
882
- if self . index < self . length {
883
- let idx = self . index ;
884
- self . index += 1 ;
885
- Some ( Comment {
886
- x : unsafe { clang_Comment_getChild ( self . parent , idx) } ,
887
- } )
888
- } else {
889
- None
890
- }
853
+ ffi_call_index_iterator ( f_len, f)
891
854
}
892
855
}
893
856
@@ -899,33 +862,6 @@ pub struct CommentAttribute {
899
862
pub value : String ,
900
863
}
901
864
902
- /// An iterator for a comment's attributes
903
- pub struct CommentAttributesIterator {
904
- x : CXComment ,
905
- length : c_uint ,
906
- index : c_uint ,
907
- }
908
-
909
- impl Iterator for CommentAttributesIterator {
910
- type Item = CommentAttribute ;
911
- fn next ( & mut self ) -> Option < CommentAttribute > {
912
- if self . index < self . length {
913
- let idx = self . index ;
914
- self . index += 1 ;
915
- Some ( CommentAttribute {
916
- name : unsafe {
917
- clang_HTMLStartTag_getAttrName ( self . x , idx) . into ( )
918
- } ,
919
- value : unsafe {
920
- clang_HTMLStartTag_getAttrValue ( self . x , idx) . into ( )
921
- } ,
922
- } )
923
- } else {
924
- None
925
- }
926
- }
927
- }
928
-
929
865
/// A source file.
930
866
pub struct File {
931
867
x : CXFile ,
@@ -1343,3 +1279,36 @@ impl Drop for EvalResult {
1343
1279
unsafe { clang_EvalResult_dispose ( self . x ) } ;
1344
1280
}
1345
1281
}
1282
+
1283
+ /// Provide a boxed iterator for foreign function call
1284
+ /// Iterate over 0..f_len() and map using f
1285
+ /// This function can be used with c_uint index
1286
+ fn ffi_call_index_iterator < ' a , FLen , F , T >
1287
+ ( f_len : FLen ,
1288
+ f : F )
1289
+ -> Box < ExactSizeIterator < Item = T > + ' a >
1290
+ where FLen : Fn ( ) -> c_uint + ' a ,
1291
+ F : Fn ( c_uint ) -> T + ' a ,
1292
+ {
1293
+ Box :: new ( ( 0 ..f_len ( ) ) . map ( f) )
1294
+ }
1295
+
1296
+ /// Provide an option boxed iterator for foreign function call
1297
+ /// Iterate over 0..f_len() and map using f
1298
+ /// This function can be used with c_int index and only
1299
+ /// returns an iterator if f_len() is positive.
1300
+ fn ffi_call_index_iterator_check_positive < ' a , FLen , F , T >
1301
+ ( f_len : FLen ,
1302
+ f : F )
1303
+ -> Option < Box < ExactSizeIterator < Item = T > + ' a > >
1304
+ where FLen : Fn ( ) -> c_int + ' a ,
1305
+ F : Fn ( c_int ) -> T + ' a ,
1306
+ {
1307
+ let len = f_len ( ) ;
1308
+ if len >= 0 {
1309
+ Some ( Box :: new ( ( 0 ..len) . map ( f) ) )
1310
+ } else {
1311
+ assert_eq ! ( len, -1 ) ; // only expect -1 as invalid
1312
+ None
1313
+ }
1314
+ }
0 commit comments