Skip to content

Commit 02f86de

Browse files
authored
Merge pull request #7 from Sympatron/cleanup
Some cleanup
2 parents 854b470 + fcb790e commit 02f86de

File tree

2 files changed

+81
-83
lines changed

2 files changed

+81
-83
lines changed

src/iter.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
use crate::{Address, Region};
2+
3+
/// Iterator producing block-region pairs, where each memory block maps to each
4+
/// region.
5+
pub struct OverlapIterator<'a, R, I>
6+
where
7+
R: Region,
8+
I: Iterator<Item = R>,
9+
{
10+
memory: &'a [u8],
11+
regions: I,
12+
base_address: Address,
13+
}
14+
15+
/// Trait allowing us to automatically add an `overlaps` function to all iterators over [`Region`]
16+
pub trait IterableByOverlaps<'a, R, I>
17+
where
18+
R: Region,
19+
I: Iterator<Item = R>,
20+
{
21+
/// Obtain an [`OverlapIterator`] over a subslice of `memory` that overlaps with the region in `self`
22+
fn overlaps(self, memory: &'a [u8], base_address: Address) -> OverlapIterator<R, I>;
23+
}
24+
25+
impl<'a, R, I> Iterator for OverlapIterator<'a, R, I>
26+
where
27+
R: Region,
28+
I: Iterator<Item = R>,
29+
{
30+
type Item = (&'a [u8], R, Address);
31+
32+
fn next(&mut self) -> Option<Self::Item> {
33+
while let Some(region) = self.regions.next() {
34+
// TODO: This might be possible to do in a smarter way?
35+
let mut block_range = (0..self.memory.len())
36+
.skip_while(|index| !region.contains(self.base_address + *index))
37+
.take_while(|index| region.contains(self.base_address + *index));
38+
if let Some(start) = block_range.next() {
39+
let end = block_range.last().unwrap_or(start) + 1;
40+
return Some((&self.memory[start..end], region, self.base_address + start));
41+
}
42+
}
43+
None
44+
}
45+
}
46+
47+
/// Blanket implementation for all types implementing [`Iterator`] over [`Regions`]
48+
impl<'a, R, I> IterableByOverlaps<'a, R, I> for I
49+
where
50+
R: Region,
51+
I: Iterator<Item = R>,
52+
{
53+
fn overlaps(self, memory: &'a [u8], base_address: Address) -> OverlapIterator<R, I> {
54+
OverlapIterator {
55+
memory,
56+
regions: self,
57+
base_address,
58+
}
59+
}
60+
}

src/lib.rs

Lines changed: 21 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,11 @@
1111
#![deny(missing_docs)]
1212
#![deny(unsafe_code)]
1313

14-
use core::ops::{Add, BitOr, Sub};
14+
use core::ops::{Add, Sub};
1515
use nb;
1616

17-
/// Trait to check if two entities are bitwise subset of another.
18-
pub trait BitSubset {
19-
/// Check that every '1' bit is a '1' on the right hand side.
20-
fn is_subset_of(&self, rhs: &Self) -> bool;
21-
}
22-
23-
/// Blanket implementation of [`BitSubset`] for all arrays of a type implementing [`BitOr`]
24-
impl<T: Copy + Eq + BitOr<Output = T>> BitSubset for [T] {
25-
fn is_subset_of(&self, rhs: &Self) -> bool {
26-
if self.len() > rhs.len() {
27-
false
28-
} else {
29-
self.iter().zip(rhs.iter()).all(|(a, b)| (*a | *b) == *b)
30-
}
31-
}
32-
}
17+
/// Currently contains [`OverlapIterator`]
18+
pub mod iter;
3319

3420
/// An address denotes the read/write address of a single word.
3521
#[derive(Default, Copy, Clone, Debug, PartialOrd, PartialEq, Eq, Ord)]
@@ -43,11 +29,26 @@ impl Add<usize> for Address {
4329
}
4430
}
4531

46-
impl Add<Address> for Address {
32+
impl Add<isize> for Address {
33+
type Output = Self;
34+
35+
fn add(self, rhs: isize) -> Self::Output {
36+
Address((self.0 as isize + rhs) as u32)
37+
}
38+
}
39+
impl Sub<usize> for Address {
4740
type Output = Self;
4841

49-
fn add(self, rhs: Address) -> Self::Output {
50-
Address(self.0 + rhs.0)
42+
fn sub(self, rhs: usize) -> Self::Output {
43+
Address(self.0 - rhs as u32)
44+
}
45+
}
46+
47+
impl Sub<isize> for Address {
48+
type Output = Self;
49+
50+
fn sub(self, rhs: isize) -> Self::Output {
51+
Address((self.0 as isize - rhs) as u32)
5152
}
5253
}
5354

@@ -65,69 +66,6 @@ pub trait Region {
6566
fn contains(&self, address: Address) -> bool;
6667
}
6768

68-
/// Iterator producing block-region pairs, where each memory block maps to each
69-
/// region.
70-
pub struct OverlapIterator<'a, R, I>
71-
where
72-
R: Region,
73-
I: Iterator<Item = R>,
74-
{
75-
memory: &'a [u8],
76-
regions: I,
77-
base_address: Address,
78-
}
79-
80-
/// Trait allowing us to automatically add an `overlaps` function to all iterators over [`Region`]
81-
pub trait IterableByOverlaps<'a, R, I>
82-
where
83-
R: Region,
84-
I: Iterator<Item = R>,
85-
{
86-
/// Obtain an [`OverlapIterator`] over a subslice of `memory` that overlaps with the region in `self`
87-
fn overlaps(self, memory: &'a [u8], base_address: Address) -> OverlapIterator<R, I>;
88-
}
89-
90-
impl<'a, R, I> Iterator for OverlapIterator<'a, R, I>
91-
where
92-
R: Region,
93-
I: Iterator<Item = R>,
94-
{
95-
type Item = (&'a [u8], R, Address);
96-
97-
fn next(&mut self) -> Option<Self::Item> {
98-
while let Some(region) = self.regions.next() {
99-
// TODO: This might be possible to do in a smarter way?
100-
let mut block_range = (0..self.memory.len())
101-
.skip_while(|index| !region.contains(self.base_address + Address(*index as u32)))
102-
.take_while(|index| region.contains(self.base_address + Address(*index as u32)));
103-
if let Some(start) = block_range.next() {
104-
let end = block_range.last().unwrap_or(start) + 1;
105-
return Some((
106-
&self.memory[start..end],
107-
region,
108-
self.base_address + Address(start as u32),
109-
));
110-
}
111-
}
112-
None
113-
}
114-
}
115-
116-
/// Blanket implementation for all types implementing [`Iterator`] over [`Regions`]
117-
impl<'a, R, I> IterableByOverlaps<'a, R, I> for I
118-
where
119-
R: Region,
120-
I: Iterator<Item = R>,
121-
{
122-
fn overlaps(self, memory: &'a [u8], base_address: Address) -> OverlapIterator<R, I> {
123-
OverlapIterator {
124-
memory,
125-
regions: self,
126-
base_address,
127-
}
128-
}
129-
}
130-
13169
/// Storage trait
13270
pub trait ReadWrite {
13371
/// An enumeration of storage errors

0 commit comments

Comments
 (0)