| ... | @@ -3014,6 +3014,7 @@ fn ReverseIterator(comptime T: type) type { | ... | @@ -3014,6 +3014,7 @@ fn ReverseIterator(comptime T: type) type { |
| 3014 | @compileError("expected slice or pointer to array, found '" ++ @typeName(T) ++ "'"); | 3014 | @compileError("expected slice or pointer to array, found '" ++ @typeName(T) ++ "'"); |
| 3015 | }; | 3015 | }; |
| 3016 | const Element = std.meta.Elem(Pointer); | 3016 | const Element = std.meta.Elem(Pointer); |
| | 3017 | const ElementPointer = @TypeOf(&@as(Pointer, undefined)[0]); |
| 3017 | return struct { | 3018 | return struct { |
| 3018 | ptr: Pointer, | 3019 | ptr: Pointer, |
| 3019 | index: usize, | 3020 | index: usize, |
| ... | @@ -3022,6 +3023,11 @@ fn ReverseIterator(comptime T: type) type { | ... | @@ -3022,6 +3023,11 @@ fn ReverseIterator(comptime T: type) type { |
| 3022 | self.index -= 1; | 3023 | self.index -= 1; |
| 3023 | return self.ptr[self.index]; | 3024 | return self.ptr[self.index]; |
| 3024 | } | 3025 | } |
| | 3026 | pub fn nextPtr(self: *@This()) ?ElementPointer { |
| | 3027 | if (self.index == 0) return null; |
| | 3028 | self.index -= 1; |
| | 3029 | return &self.ptr[self.index]; |
| | 3030 | } |
| 3025 | }; | 3031 | }; |
| 3026 | } | 3032 | } |
| 3027 | | 3033 | |
| ... | @@ -3051,6 +3057,18 @@ test "reverseIterator" { | ... | @@ -3051,6 +3057,18 @@ test "reverseIterator" { |
| 3051 | try testing.expectEqual(@as(?i32, 7), it.next()); | 3057 | try testing.expectEqual(@as(?i32, 7), it.next()); |
| 3052 | try testing.expectEqual(@as(?i32, 3), it.next()); | 3058 | try testing.expectEqual(@as(?i32, 3), it.next()); |
| 3053 | try testing.expectEqual(@as(?i32, null), it.next()); | 3059 | try testing.expectEqual(@as(?i32, null), it.next()); |
| | 3060 | |
| | 3061 | it = reverseIterator(slice); |
| | 3062 | try testing.expect(trait.isConstPtr(@TypeOf(it.nextPtr().?))); |
| | 3063 | try testing.expectEqual(@as(?i32, 7), it.nextPtr().?.*); |
| | 3064 | try testing.expectEqual(@as(?i32, 3), it.nextPtr().?.*); |
| | 3065 | try testing.expectEqual(@as(?*const i32, null), it.nextPtr()); |
| | 3066 | |
| | 3067 | var mut_slice: []i32 = &array; |
| | 3068 | var mut_it = reverseIterator(mut_slice); |
| | 3069 | mut_it.nextPtr().?.* += 1; |
| | 3070 | mut_it.nextPtr().?.* += 2; |
| | 3071 | try testing.expectEqual([2]i32{ 5, 8 }, array); |
| 3054 | } | 3072 | } |
| 3055 | { | 3073 | { |
| 3056 | var array = [2]i32{ 3, 7 }; | 3074 | var array = [2]i32{ 3, 7 }; |
| ... | @@ -3059,6 +3077,18 @@ test "reverseIterator" { | ... | @@ -3059,6 +3077,18 @@ test "reverseIterator" { |
| 3059 | try testing.expectEqual(@as(?i32, 7), it.next()); | 3077 | try testing.expectEqual(@as(?i32, 7), it.next()); |
| 3060 | try testing.expectEqual(@as(?i32, 3), it.next()); | 3078 | try testing.expectEqual(@as(?i32, 3), it.next()); |
| 3061 | try testing.expectEqual(@as(?i32, null), it.next()); | 3079 | try testing.expectEqual(@as(?i32, null), it.next()); |
| | 3080 | |
| | 3081 | it = reverseIterator(ptr_to_array); |
| | 3082 | try testing.expect(trait.isConstPtr(@TypeOf(it.nextPtr().?))); |
| | 3083 | try testing.expectEqual(@as(?i32, 7), it.nextPtr().?.*); |
| | 3084 | try testing.expectEqual(@as(?i32, 3), it.nextPtr().?.*); |
| | 3085 | try testing.expectEqual(@as(?*const i32, null), it.nextPtr()); |
| | 3086 | |
| | 3087 | var mut_ptr_to_array: *[2]i32 = &array; |
| | 3088 | var mut_it = reverseIterator(mut_ptr_to_array); |
| | 3089 | mut_it.nextPtr().?.* += 1; |
| | 3090 | mut_it.nextPtr().?.* += 2; |
| | 3091 | try testing.expectEqual([2]i32{ 5, 8 }, array); |
| 3062 | } | 3092 | } |
| 3063 | } | 3093 | } |
| 3064 | | 3094 | |