@@ -623,18 +623,16 @@ impl Type {
623
623
624
624
/// If this type is a class template specialization, return its
625
625
/// template arguments. Otherwise, return None.
626
- pub fn template_args ( & self ) -> Option < TypeTemplateArgIterator > {
627
- let n = unsafe { clang_Type_getNumTemplateArguments ( self . x ) } ;
628
- if n >= 0 {
629
- Some ( TypeTemplateArgIterator {
630
- x : self . x ,
631
- length : n as u32 ,
632
- index : 0 ,
633
- } )
634
- } else {
635
- debug_assert_eq ! ( n, -1 ) ;
636
- None
637
- }
626
+ pub fn template_args ( & self ) -> Option < Box < ExactSizeIterator < Item = Type > > > {
627
+ let x = self . x ;
628
+ let f_len = || unsafe { clang_Type_getNumTemplateArguments ( x) } ;
629
+ let f = move |i| {
630
+ Type {
631
+ x : unsafe { clang_Type_getTemplateArgumentAsType ( x, i) } ,
632
+ }
633
+ } ;
634
+
635
+ ffi_call_index_iterator_check_positive ( f_len, f)
638
636
}
639
637
640
638
/// Given that this type is a pointer type, return the type that it points
@@ -717,35 +715,6 @@ impl Type {
717
715
}
718
716
}
719
717
720
- /// An iterator for a type's template arguments.
721
- pub struct TypeTemplateArgIterator {
722
- x : CXType ,
723
- length : u32 ,
724
- index : u32 ,
725
- }
726
-
727
- impl Iterator for TypeTemplateArgIterator {
728
- type Item = Type ;
729
- fn next ( & mut self ) -> Option < Type > {
730
- if self . index < self . length {
731
- let idx = self . index as c_int ;
732
- self . index += 1 ;
733
- Some ( Type {
734
- x : unsafe { clang_Type_getTemplateArgumentAsType ( self . x , idx) } ,
735
- } )
736
- } else {
737
- None
738
- }
739
- }
740
- }
741
-
742
- impl ExactSizeIterator for TypeTemplateArgIterator {
743
- fn len ( & self ) -> usize {
744
- assert ! ( self . index <= self . length) ;
745
- ( self . length - self . index ) as usize
746
- }
747
- }
748
-
749
718
/// A `SourceLocation` is a file, line, column, and byte offset location for
750
719
/// some source text.
751
720
pub struct SourceLocation {
@@ -801,12 +770,16 @@ impl Comment {
801
770
}
802
771
803
772
/// Get this comment's children comment
804
- pub fn get_children ( & self ) -> CommentChildrenIterator {
805
- CommentChildrenIterator {
806
- parent : self . x ,
807
- length : unsafe { clang_Comment_getNumChildren ( self . x ) } ,
808
- index : 0 ,
809
- }
773
+ pub fn get_children ( & self ) -> Box < ExactSizeIterator < Item = Comment > > {
774
+ let x = self . x ;
775
+ let f_len = || unsafe { clang_Comment_getNumChildren ( x) } ;
776
+ let f = move |i| {
777
+ Comment {
778
+ x : unsafe { clang_Comment_getChild ( x, i) } ,
779
+ }
780
+ } ;
781
+
782
+ ffi_call_index_iterator ( f_len, f)
810
783
}
811
784
812
785
/// Given that this comment is the start or end of an HTML tag, get its tag
@@ -816,34 +789,18 @@ impl Comment {
816
789
}
817
790
818
791
/// Given that this comment is an HTML start tag, get its attributes.
819
- pub fn get_tag_attrs ( & self ) -> CommentAttributesIterator {
820
- CommentAttributesIterator {
821
- x : self . x ,
822
- length : unsafe { clang_HTMLStartTag_getNumAttrs ( self . x ) } ,
823
- index : 0 ,
824
- }
825
- }
826
- }
827
-
828
- /// An iterator for a comment's children
829
- pub struct CommentChildrenIterator {
830
- parent : CXComment ,
831
- length : c_uint ,
832
- index : c_uint ,
833
- }
792
+ pub fn get_tag_attrs ( & self )
793
+ -> Box < ExactSizeIterator < Item = CommentAttribute > > {
794
+ let x = self . x ;
795
+ let f_len = || unsafe { clang_HTMLStartTag_getNumAttrs ( x) } ;
796
+ let f = move |i| {
797
+ CommentAttribute {
798
+ name : unsafe { clang_HTMLStartTag_getAttrName ( x, i) . into ( ) } ,
799
+ value : unsafe { clang_HTMLStartTag_getAttrValue ( x, i) . into ( ) } ,
800
+ }
801
+ } ;
834
802
835
- impl Iterator for CommentChildrenIterator {
836
- type Item = Comment ;
837
- fn next ( & mut self ) -> Option < Comment > {
838
- if self . index < self . length {
839
- let idx = self . index ;
840
- self . index += 1 ;
841
- Some ( Comment {
842
- x : unsafe { clang_Comment_getChild ( self . parent , idx) } ,
843
- } )
844
- } else {
845
- None
846
- }
803
+ ffi_call_index_iterator ( f_len, f)
847
804
}
848
805
}
849
806
@@ -855,33 +812,6 @@ pub struct CommentAttribute {
855
812
pub value : String ,
856
813
}
857
814
858
- /// An iterator for a comment's attributes
859
- pub struct CommentAttributesIterator {
860
- x : CXComment ,
861
- length : c_uint ,
862
- index : c_uint ,
863
- }
864
-
865
- impl Iterator for CommentAttributesIterator {
866
- type Item = CommentAttribute ;
867
- fn next ( & mut self ) -> Option < CommentAttribute > {
868
- if self . index < self . length {
869
- let idx = self . index ;
870
- self . index += 1 ;
871
- Some ( CommentAttribute {
872
- name : unsafe {
873
- clang_HTMLStartTag_getAttrName ( self . x , idx) . into ( )
874
- } ,
875
- value : unsafe {
876
- clang_HTMLStartTag_getAttrValue ( self . x , idx) . into ( )
877
- } ,
878
- } )
879
- } else {
880
- None
881
- }
882
- }
883
- }
884
-
885
815
/// A source file.
886
816
pub struct File {
887
817
x : CXFile ,
@@ -1172,3 +1102,36 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> Enum_CXVisitorResult {
1172
1102
pub fn extract_clang_version ( ) -> String {
1173
1103
unsafe { clang_getClangVersion ( ) . into ( ) }
1174
1104
}
1105
+
1106
+ /// Provide a boxed iterator for foreign function call
1107
+ /// Iterate over 0..f_len() and map using f
1108
+ /// This function can be used with c_uint index
1109
+ fn ffi_call_index_iterator < ' a , FLen , F , T >
1110
+ ( f_len : FLen ,
1111
+ f : F )
1112
+ -> Box < ExactSizeIterator < Item = T > + ' a >
1113
+ where F : Fn ( c_uint ) -> T + ' a ,
1114
+ FLen : Fn ( ) -> c_uint ,
1115
+ {
1116
+ Box :: new ( ( 0 ..f_len ( ) ) . map ( f) )
1117
+ }
1118
+
1119
+ /// Provide an option boxed iterator for foreign function call
1120
+ /// Iterate over 0..f_len() and map using f
1121
+ /// This function can be used with c_int index and only
1122
+ /// returns an iterator if f_len() is positive.
1123
+ fn ffi_call_index_iterator_check_positive < ' a , FLen , F , T >
1124
+ ( f_len : FLen ,
1125
+ f : F )
1126
+ -> Option < Box < ExactSizeIterator < Item = T > + ' a > >
1127
+ where F : Fn ( c_int ) -> T + ' a ,
1128
+ FLen : Fn ( ) -> c_int ,
1129
+ {
1130
+ let len = f_len ( ) ;
1131
+ if len >= 0 {
1132
+ Some ( Box :: new ( ( 0 ..len) . map ( f) ) )
1133
+ } else {
1134
+ assert_eq ! ( len, -1 ) ; // only expect -1 as invalid
1135
+ None
1136
+ }
1137
+ }
0 commit comments