Skip to content

Commit 2aaaff4

Browse files
authored
Switch to the new iterator idiom in all rules (#548)
I also deleted the old PtrValueIter because it assumed that the inputs were random access iterators. This assumption is wrong for weaker iterator categories, for example bidirectional, see tests/unit/vector_iter_range_ctor.cpp: ```cpp // the iterator of map is bidirectional std::map<int, int> m; // the iterator of vector is random access, the the arguments (m.begin(), m.end()) // are bidirectional where PtrValueIter does not work std::vector<std::pair<int, int>> v6(m.begin(), m.end()); ```
1 parent d3f3288 commit 2aaaff4

20 files changed

Lines changed: 436 additions & 240 deletions

‎docs/src/runtime/iterators.md‎

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,6 @@ for x in v.as_pointer() as Ptr<i32> {
2727
}
2828
```
2929

30-
`PtrValueIter` yields copies of the elements instead of pointers to them; rule
31-
bodies use it to feed a range of C memory to Rust iterator adaptors:
32-
33-
```rust
34-
// std::accumulate(first, last, init)
35-
let count = (last - first) as usize;
36-
PtrValueIter::new(&first, count).fold(init, |acc, x| acc + x)
37-
```
3830

3931
## Stable iterators
4032

‎libcc2rs/src/rc.rs‎

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,43 +1229,6 @@ impl<T> Iterator for Ptr<T> {
12291229
}
12301230
}
12311231

1232-
// Ptr iterator that yields values instead of pointers.
1233-
// It's more efficient and it's useful to implement idiomatic iterator patterns
1234-
pub struct PtrValueIter<T> {
1235-
ptr: Ptr<T>,
1236-
n: usize,
1237-
}
1238-
1239-
impl<T> PtrValueIter<T> {
1240-
pub fn new(ptr: &Ptr<T>, n: usize) -> Self {
1241-
Self {
1242-
ptr: ptr.clone(),
1243-
n,
1244-
}
1245-
}
1246-
}
1247-
1248-
impl<T: Clone + ByteRepr> Iterator for PtrValueIter<T> {
1249-
type Item = T;
1250-
1251-
fn next(&mut self) -> Option<Self::Item> {
1252-
if self.n > 0 {
1253-
let value = self.ptr.read();
1254-
self.ptr += 1;
1255-
self.n -= 1;
1256-
Some(value)
1257-
} else {
1258-
None
1259-
}
1260-
}
1261-
1262-
fn size_hint(&self) -> (usize, Option<usize>) {
1263-
(self.n, Some(self.n))
1264-
}
1265-
}
1266-
1267-
impl<T: Clone + ByteRepr> ExactSizeIterator for PtrValueIter<T> {}
1268-
12691232
impl<T> Sub for Ptr<T> {
12701233
type Output = isize;
12711234
fn sub(self, other: Self) -> Self::Output {

‎rules/algorithm/src.cpp‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,8 @@ void f12(T1 first, T1 last, const T2 &value) {
4040
return std::fill(first, last, value);
4141
}
4242

43-
std::ostream_iterator<char> f13(std::string::iterator a0,
44-
std::string::iterator a1,
45-
std::ostream_iterator<char> a2) {
43+
template <typename T1>
44+
std::ostream_iterator<char> f13(T1 a0, T1 a1, std::ostream_iterator<char> a2) {
4645
return std::copy(a0, a1, a2);
4746
}
4847

‎rules/algorithm/tgt_refcount.rs‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,14 @@ fn f12<T1: CppInputIterator<T2>, T2: Clone + ByteRepr>(a0: T1, a1: T1, a2: T2) {
122122
}
123123
}
124124

125-
fn f13(a0: Ptr<i8>, a1: Ptr<i8>, a2: &mut ::std::fs::File) -> ::std::fs::File {
126-
a0.with_slice(a1.get_offset() - a0.get_offset(), |__s| {
127-
CChar::with_u8_slice(__s, |__b| a2.write_all(__b))
128-
});
125+
fn f13<T1: CppInputIterator<i8>>(a0: T1, a1: T1, a2: &mut ::std::fs::File) -> ::std::fs::File {
126+
let mut __bytes: Vec<u8> = Vec::new();
127+
let mut __it = a0;
128+
while __it != a1 {
129+
__bytes.push(__it.iter_deref().read() as u8);
130+
__it.iter_inc();
131+
}
132+
a2.write_all(&__bytes);
129133
a2.try_clone().unwrap()
130134
}
131135

‎rules/algorithm/tgt_unsafe.rs‎

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,18 @@ unsafe fn f12<T1: UnsafeCppInputIterator<T2>, T2: Clone>(a0: T1, a1: T1, a2: T2)
112112
}
113113
}
114114

115-
unsafe fn f13(
116-
a0: *const libc::c_char,
117-
a1: *const libc::c_char,
115+
unsafe fn f13<T1: UnsafeCppInputIterator<libc::c_char>>(
116+
a0: T1,
117+
a1: T1,
118118
a2: &mut ::std::fs::File,
119119
) -> ::std::fs::File {
120-
let __start = a0 as *const u8;
121-
let __end = a1 as *const u8;
122-
let __len = __end.offset_from(__start) as usize;
123-
a2.write_all(::std::slice::from_raw_parts(__start, __len));
120+
let mut __bytes: Vec<u8> = Vec::new();
121+
let mut __it = a0;
122+
while __it != a1 {
123+
__bytes.push(*__it.iter_deref() as u8);
124+
__it.iter_inc();
125+
}
126+
a2.write_all(&__bytes);
124127
a2.try_clone().unwrap()
125128
}
126129

‎rules/iterator_category/shim.rs‎

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -338,14 +338,6 @@ macro_rules! random_access_iterator {
338338
Vec($ptr),
339339
}
340340

341-
impl<T> $name<T> {
342-
pub fn vec_ptr(&self) -> $ptr {
343-
match self {
344-
Self::Vec(p) => p.clone(),
345-
}
346-
}
347-
}
348-
349341
impl<T> Default for $name<T> {
350342
fn default() -> Self {
351343
Self::Vec($null)
@@ -354,7 +346,9 @@ macro_rules! random_access_iterator {
354346

355347
impl<T> Clone for $name<T> {
356348
fn clone(&self) -> Self {
357-
Self::Vec(self.vec_ptr())
349+
match self {
350+
Self::Vec(p) => Self::Vec(p.clone()),
351+
}
358352
}
359353
}
360354

@@ -442,6 +436,14 @@ random_access_iterator!(
442436
Ptr::null()
443437
);
444438

439+
impl<T> RandomAccessIterator<T> {
440+
pub fn index(&self) -> usize {
441+
match self {
442+
Self::Vec(p) => p.get_offset(),
443+
}
444+
}
445+
}
446+
445447
random_access_iterator!(
446448
UnsafeRandomAccessIterator,
447449
*mut T,

‎rules/string/src.cpp‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#include <string>
77

88
using t1 = std::string;
9-
using t2 = std::string::iterator;
109
typedef std::string::size_type t3;
1110

1211
std::string f1(const std::string &s, std::size_t pos, std::size_t count) {
@@ -57,10 +56,6 @@ bool f18(const std::string &a, const char *b) { return a == b; }
5756

5857
std::size_t f19(const std::string &s) { return s.length(); }
5958

60-
std::string::iterator f20(std::string::iterator it, std::size_t n) {
61-
return it + n;
62-
}
63-
6459
std::string &f21(std::string &s, std::size_t n, char c) {
6560
return s.append(n, c);
6661
}

‎rules/string/tgt_refcount.rs‎

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@ fn t1() -> Vec<i8> {
99
vec![0]
1010
}
1111

12-
fn t2() -> Ptr<i8> {
13-
Ptr::null()
14-
}
15-
1612
fn f1(a0: Vec<i8>, a1: usize, a2: usize) -> Vec<i8> {
1713
let mut __tmp1 =
1814
a0[(a1) as usize..::std::cmp::min((a1 + a2) as usize, a0.len().saturating_sub(1))].to_vec();
@@ -62,8 +58,8 @@ fn f11(a0: Ptr<i8>) -> Ptr<i8> {
6258
a0
6359
}
6460

65-
fn f12(a0: Ptr<i8>) -> Ptr<i8> {
66-
a0
61+
fn f12(a0: Ptr<i8>) -> RandomAccessIterator<i8> {
62+
RandomAccessIterator::Vec(a0)
6763
}
6864

6965
fn f14(a0: Ptr<Vec<i8>>, a1: usize, a2: usize, a3: Ptr<i8>, a4: usize) -> Ptr<Vec<i8>> {
@@ -80,8 +76,8 @@ fn f14(a0: Ptr<Vec<i8>>, a1: usize, a2: usize, a3: Ptr<i8>, a4: usize) -> Ptr<Ve
8076
a0
8177
}
8278

83-
fn f15(a0: Ptr<i8>) -> Ptr<i8> {
84-
a0.to_last()
79+
fn f15(a0: Ptr<i8>) -> RandomAccessIterator<i8> {
80+
RandomAccessIterator::Vec(a0.to_last())
8581
}
8682

8783
fn f16(a0: Vec<i8>, a1: Ptr<i8>) -> usize {
@@ -106,10 +102,6 @@ fn f18(a0: Vec<i8>, a1: Ptr<i8>) -> bool {
106102
a1.with_c_str(|__s| a0[..a0.len().saturating_sub(1)] == *__s)
107103
}
108104

109-
fn f20(a0: Ptr<i8>, a1: usize) -> Ptr<i8> {
110-
a0.offset(a1 as isize)
111-
}
112-
113105
// TODO: This should return a0
114106
fn f21(a0: &mut Vec<i8>, a1: usize, a2: i8) -> Vec<i8> {
115107
a0.pop();

‎rules/string/tgt_unsafe.rs‎

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
// Copyright (c) 2022-present INESC-ID.
22
// Distributed under the MIT license that can be found in the LICENSE file.
33

4+
use libcc2rs::*;
5+
46
fn t1() -> Vec<libc::c_char> {
57
vec![0]
68
}
79

8-
fn t2() -> *mut libc::c_char {
9-
::std::ptr::null_mut()
10-
}
11-
1210
fn t3() -> usize {
1311
0_usize
1412
}
@@ -80,8 +78,8 @@ unsafe fn f10(a0: *const libc::c_char) -> Vec<libc::c_char> {
8078
unsafe fn f11(a0: Vec<libc::c_char>) -> *const libc::c_char {
8179
a0.as_ptr()
8280
}
83-
unsafe fn f12(a0: &mut Vec<libc::c_char>) -> *mut libc::c_char {
84-
a0.as_mut_ptr()
81+
unsafe fn f12(a0: &mut Vec<libc::c_char>) -> UnsafeRandomAccessIterator<libc::c_char> {
82+
UnsafeRandomAccessIterator::Vec(a0.as_mut_ptr())
8583
}
8684
unsafe fn f13(a0: &mut Vec<libc::c_char>, a1: usize) {
8785
a0.pop();
@@ -100,8 +98,8 @@ unsafe fn f14(
10098
::std::slice::from_raw_parts(a3, a4 as usize).to_vec(),
10199
);
102100
}
103-
unsafe fn f15(a0: &mut Vec<libc::c_char>) -> *mut libc::c_char {
104-
a0.as_mut_ptr().add(a0.len() - 1)
101+
unsafe fn f15(a0: &mut Vec<libc::c_char>) -> UnsafeRandomAccessIterator<libc::c_char> {
102+
UnsafeRandomAccessIterator::Vec(a0.as_mut_ptr().add(a0.len() - 1))
105103
}
106104
unsafe fn f16(a0: Vec<libc::c_char>, a1: *const libc::c_char) -> usize {
107105
match a0.iter().rposition(|&c| {
@@ -134,9 +132,6 @@ unsafe fn f18(a0: Vec<libc::c_char>, a1: *const libc::c_char) -> bool {
134132
unsafe fn f19(a0: Vec<libc::c_char>) -> usize {
135133
(a0.len() - 1)
136134
}
137-
unsafe fn f20(a0: *mut libc::c_char, a1: usize) -> *mut libc::c_char {
138-
a0.add(a1 as usize)
139-
}
140135
unsafe fn f21(a0: &mut Vec<libc::c_char>, a1: usize, a2: libc::c_char) {
141136
a0.splice(
142137
a0.len() - 1..a0.len() - 1,

‎rules/vector/src.cpp‎

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -136,18 +136,13 @@ void f80(std::vector<T1, T2> &o, const T1 &value) {
136136
return o.push_back(value);
137137
}
138138

139-
template <typename T1, typename T2 = std::allocator<T1>>
140-
std::vector<T1, T2> f90(const T1 *first, const T1 *last) {
141-
return std::vector<T1, T2>(first, last);
142-
}
143-
144139
template <typename T1, typename T2 = std::allocator<T1>>
145140
std::vector<T1, T2> f91(const std::initializer_list<T1> &a0) {
146141
return std::vector<T1, T2>(a0);
147142
}
148143

149144
template <typename T1, typename T2 = std::allocator<T1>, typename T3>
150-
std::vector<T1, T2> f92(T3 *first, T3 *last) {
145+
std::vector<T1, T2> f92(T3 first, T3 last) {
151146
return std::vector<T1, T2>(first, last);
152147
}
153148

@@ -181,10 +176,10 @@ const T1 &f99(const std::vector<T1, T2> &o) {
181176
return o.back();
182177
}
183178

184-
template <typename T1, typename T2 = std::allocator<T1>>
179+
template <typename T1, typename T2 = std::allocator<T1>, typename T3>
185180
typename std::vector<T1, T2>::iterator
186181
f101(std::vector<T1, T2> &o, typename std::vector<T1, T2>::const_iterator pos,
187-
const T1 *first, const T1 *last) {
182+
T3 first, T3 last) {
188183
return o.insert(pos, first, last);
189184
}
190185

@@ -231,3 +226,17 @@ auto f114(std::vector<T1, T2> &o, Init<T1, Args> &&...args)
231226
-> decltype(o.emplace_back(std::forward<Args>(args)...)) {
232227
return o.emplace_back(std::forward<Args>(args)...);
233228
}
229+
230+
template <typename T1, typename T2 = std::allocator<T1>>
231+
typename std::vector<T1, T2>::iterator
232+
f115(std::vector<T1, T2> &o, typename std::vector<T1, T2>::const_iterator pos,
233+
std::size_t n, const T1 &value) {
234+
return o.insert(pos, n, value);
235+
}
236+
237+
template <typename T1, typename T2 = std::allocator<T1>>
238+
typename std::vector<T1, T2>::iterator
239+
f116(std::vector<T1, T2> &o, typename std::vector<T1, T2>::const_iterator pos,
240+
std::initializer_list<T1> l) {
241+
return o.insert(pos, l);
242+
}

0 commit comments

Comments
 (0)