diff options
| author | Paul Stansifer <paul.stansifer@gmail.com> | 2012-07-26 16:16:28 -0700 |
|---|---|---|
| committer | Paul Stansifer <paul.stansifer@gmail.com> | 2012-07-26 16:16:28 -0700 |
| commit | 97422f0f0fdcbdd17a769fa9588e76b8bf8a5bdf (patch) | |
| tree | a91f89c585b54fccf34cd873d2488d2cb3c09909 /src/libcore | |
| parent | 8209b2e9b383b9e38a09b1ec79c7b5691aeb5d22 (diff) | |
| parent | 44631722ff234241cb7100103320a402fe4fdfa9 (diff) | |
Merge branch 'incoming' of github.com:mozilla/rust
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/arc.rs | 65 | ||||
| -rw-r--r-- | src/libcore/cmp.rs | 8 | ||||
| -rw-r--r-- | src/libcore/core.rc | 1 | ||||
| -rw-r--r-- | src/libcore/core.rs | 5 | ||||
| -rw-r--r-- | src/libcore/dlist.rs | 99 | ||||
| -rw-r--r-- | src/libcore/f32.rs | 18 | ||||
| -rw-r--r-- | src/libcore/f64.rs | 18 | ||||
| -rw-r--r-- | src/libcore/float.rs | 48 | ||||
| -rw-r--r-- | src/libcore/int-template.rs | 22 | ||||
| -rw-r--r-- | src/libcore/io.rs | 6 | ||||
| -rw-r--r-- | src/libcore/num.rs | 18 | ||||
| -rw-r--r-- | src/libcore/ops.rs | 66 | ||||
| -rw-r--r-- | src/libcore/pipes.rs | 108 | ||||
| -rw-r--r-- | src/libcore/uint-template.rs | 22 |
14 files changed, 271 insertions, 233 deletions
diff --git a/src/libcore/arc.rs b/src/libcore/arc.rs index 28f07264410..9c46df9731b 100644 --- a/src/libcore/arc.rs +++ b/src/libcore/arc.rs @@ -3,10 +3,9 @@ * share immutable data between tasks. */ -import comm::{port, chan, methods}; import sys::methods; -export arc, get, clone, shared_arc, get_arc; +export arc, get, clone; export exclusive, methods; @@ -122,49 +121,6 @@ impl methods<T: send> for exclusive<T> { } } -// Convenience code for sharing arcs between tasks - -type get_chan<T: const send> = chan<chan<arc<T>>>; - -// (terminate, get) -type shared_arc<T: const send> = (shared_arc_res, get_chan<T>); - -class shared_arc_res { - let c: comm::chan<()>; - new(c: comm::chan<()>) { self.c = c; } - drop { self.c.send(()); } -} - -fn shared_arc<T: send const>(-data: T) -> shared_arc<T> { - let a = arc::arc(data); - let p = port(); - let c = chan(p); - do task::spawn() |move a| { - let mut live = true; - let terminate = port(); - let get = port(); - - c.send((chan(terminate), chan(get))); - - while live { - alt comm::select2(terminate, get) { - either::left(()) { live = false; } - either::right(cc) { - comm::send(cc, arc::clone(&a)); - } - } - } - }; - let (terminate, get) = p.recv(); - (shared_arc_res(terminate), get) -} - -fn get_arc<T: send const>(c: get_chan<T>) -> arc::arc<T> { - let p = port(); - c.send(chan(p)); - p.recv() -} - #[cfg(test)] mod tests { import comm::*; @@ -197,25 +153,6 @@ mod tests { } #[test] - fn auto_share_arc() { - let v = ~[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - let (_res, arc_c) = shared_arc(v); - - let p = port(); - let c = chan(p); - - do task::spawn() { - let arc_v = get_arc(arc_c); - let v = *get(&arc_v); - assert v[2] == 3; - - c.send(()); - }; - - assert p.recv() == (); - } - - #[test] #[ignore] // this can probably infinite loop too. fn exclusive_arc() { let mut futures = ~[]; diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 1bdf3b9909a..d10b9603af0 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -1,10 +1,10 @@ /// Interfaces used for comparison. -iface ord { - fn lt(&&other: self) -> bool; +trait ord { + pure fn lt(&&other: self) -> bool; } -iface eq { - fn eq(&&other: self) -> bool; +trait eq { + pure fn eq(&&other: self) -> bool; } diff --git a/src/libcore/core.rc b/src/libcore/core.rc index d298ff15a9e..11e305e22e8 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -161,6 +161,7 @@ mod tuple; // Ubiquitous-utility-type modules +mod ops; mod cmp; mod num; mod hash; diff --git a/src/libcore/core.rs b/src/libcore/core.rs index 4738574fdb4..fdf53524188 100644 --- a/src/libcore/core.rs +++ b/src/libcore/core.rs @@ -30,6 +30,8 @@ import float::num; import f32::num; import f64::num; import num::num; +import ops::{const, copy, send, owned}; +import ops::{add, sub, mul, div, modulo, neg, bitops, index}; export path, option, some, none, unreachable; export extensions; @@ -42,6 +44,9 @@ export immutable_copyable_vector, iter_trait_extensions, vec_concat; export base_iter, copyable_iter, extended_iter; export tuple_ops, extended_tuple_ops; export ptr; +// The following exports are the core operators and kinds +export const, copy, send, owned; +export add, sub, mul, div, modulo, neg, bitops, index; // Export the log levels as global constants. Higher levels mean // more-verbosity. Error is the bottom level, default logging level is diff --git a/src/libcore/dlist.rs b/src/libcore/dlist.rs index 087194f721d..cd36d14816c 100644 --- a/src/libcore/dlist.rs +++ b/src/libcore/dlist.rs @@ -18,12 +18,28 @@ enum dlist_node<T> = @{ mut next: dlist_link<T> }; -// Needs to be an @-box so nodes can back-reference it. -enum dlist<T> = @{ - mut size: uint, - mut hd: dlist_link<T>, - mut tl: dlist_link<T> -}; +class dlist_root<T> { + let mut size: uint; + let mut hd: dlist_link<T>; + let mut tl: dlist_link<T>; + new() { + self.size = 0; self.hd = none; self.tl = none; + } + drop { + /* FIXME (#????) This doesn't work during task failure - the box + * annihilator might have killed some of our nodes already. This will + * be safe to uncomment when the box annihilator is safer. As is, + * this makes test_dlist_cyclic_link below crash the runtime. + // Empty the list. Not doing this explicitly would leave cyclic links + // around, not to be freed until cycle collection at task exit. + while self.hd.is_some() { + self.unlink(self.hd.get()); + } + */ + } +} + +type dlist<T> = @dlist_root<T>; impl private_methods<T> for dlist_node<T> { pure fn assert_links() { @@ -91,7 +107,7 @@ pure fn new_dlist_node<T>(+data: T) -> dlist_node<T> { /// Creates a new, empty dlist. pure fn new_dlist<T>() -> dlist<T> { - dlist(@{mut size: 0, mut hd: none, mut tl: none}) + @unchecked { dlist_root() } } /// Creates a new dlist with a single element @@ -118,7 +134,7 @@ fn concat<T>(lists: dlist<dlist<T>>) -> dlist<T> { result } -impl private_methods<T> for dlist<T> { +impl private_methods<T> for dlist_root<T> { pure fn new_link(-data: T) -> dlist_link<T> { some(dlist_node(@{data: data, mut linked: true, mut prev: none, mut next: none})) @@ -288,20 +304,6 @@ impl extensions<T> for dlist<T> { tl.map(|nobe| self.unlink(nobe)); tl } - /// Remove data from the head of the list. O(1). - fn pop() -> option<T> { - do option::map_consume(self.pop_n()) |nobe| { - let dlist_node(@{ data: x, _ }) <- nobe; - x - } - } - /// Remove data from the tail of the list. O(1). - fn pop_tail() -> option<T> { - do option::map_consume(self.pop_tail_n()) |nobe| { - let dlist_node(@{ data: x, _ }) <- nobe; - x - } - } /// Get the node at the list's head. O(1). pure fn peek_n() -> option<dlist_node<T>> { self.hd } /// Get the node at the list's tail. O(1). @@ -334,7 +336,7 @@ impl extensions<T> for dlist<T> { * to the other list's head. O(1). */ fn append(them: dlist<T>) { - if box::ptr_eq(*self, *them) { + if box::ptr_eq(self, them) { fail ~"Cannot append a dlist to itself!" } if them.len() > 0 { @@ -351,7 +353,7 @@ impl extensions<T> for dlist<T> { * list's tail to this list's head. O(1). */ fn prepend(them: dlist<T>) { - if box::ptr_eq(*self, *them) { + if box::ptr_eq(self, them) { fail ~"Cannot prepend a dlist to itself!" } if them.len() > 0 { @@ -366,15 +368,25 @@ impl extensions<T> for dlist<T> { /// Reverse the list's elements in place. O(n). fn reverse() { - let temp = new_dlist::<T>(); + do option::while_some(self.hd) |nobe| { + let next_nobe = nobe.next; + self.remove(nobe); + self.make_mine(nobe); + self.add_head(some(nobe)); + next_nobe + } + } + + /** + * Remove everything from the list. This is important because the cyclic + * links won't otherwise be automatically refcounted-collected. O(n). + */ + fn clear() { + // Cute as it would be to simply detach the list and proclaim "O(1)!", + // the GC would still be a hidden O(n). Better to be honest about it. while !self.is_empty() { - let nobe = self.pop_n().get(); - nobe.linked = true; // meh, kind of disorganised. - temp.add_head(some(nobe)); + let _ = self.pop_n(); } - self.hd = temp.hd; - self.tl = temp.tl; - self.size = temp.size; } /// Iterate over nodes. @@ -431,6 +443,10 @@ impl extensions<T> for dlist<T> { } impl extensions<T: copy> for dlist<T> { + /// Remove data from the head of the list. O(1). + fn pop() -> option<T> { self.pop_n().map (|nobe| nobe.data) } + /// Remove data from the tail of the list. O(1). + fn pop_tail() -> option<T> { self.pop_tail_n().map (|nobe| nobe.data) } /// Get data at the list's head. O(1). pure fn peek() -> option<T> { self.peek_n().map (|nobe| nobe.data) } /// Get data at the list's tail. O(1). @@ -596,6 +612,13 @@ mod tests { a.assert_consistent(); assert a.is_empty(); } #[test] + fn test_dlist_clear() { + let a = from_vec(~[5,4,3,2,1]); + a.clear(); + assert a.len() == 0; + a.assert_consistent(); + } + #[test] fn test_dlist_is_empty() { let empty = new_dlist::<int>(); let full1 = from_vec(~[1,2,3]); @@ -847,7 +870,7 @@ mod tests { l.assert_consistent(); assert l.is_empty(); } #[test] #[should_fail] #[ignore(cfg(windows))] - fn test_asymmetric_link() { + fn test_dlist_asymmetric_link() { let l = new_dlist::<int>(); let _one = l.push_n(1); let two = l.push_n(2); @@ -855,7 +878,7 @@ mod tests { l.assert_consistent(); } #[test] #[should_fail] #[ignore(cfg(windows))] - fn test_cyclic_list() { + fn test_dlist_cyclic_list() { let l = new_dlist::<int>(); let one = l.push_n(1); let _two = l.push_n(2); @@ -865,32 +888,32 @@ mod tests { l.assert_consistent(); } #[test] #[should_fail] #[ignore(cfg(windows))] - fn test_headless() { + fn test_dlist_headless() { new_dlist::<int>().head(); } #[test] #[should_fail] #[ignore(cfg(windows))] - fn test_insert_already_present_before() { + fn test_dlist_insert_already_present_before() { let l = new_dlist::<int>(); let one = l.push_n(1); let two = l.push_n(2); l.insert_n_before(two, one); } #[test] #[should_fail] #[ignore(cfg(windows))] - fn test_insert_already_present_after() { + fn test_dlist_insert_already_present_after() { let l = new_dlist::<int>(); let one = l.push_n(1); let two = l.push_n(2); l.insert_n_after(one, two); } #[test] #[should_fail] #[ignore(cfg(windows))] - fn test_insert_before_orphan() { + fn test_dlist_insert_before_orphan() { let l = new_dlist::<int>(); let one = new_dlist_node(1); let two = new_dlist_node(2); l.insert_n_before(one, two); } #[test] #[should_fail] #[ignore(cfg(windows))] - fn test_insert_after_orphan() { + fn test_dlist_insert_after_orphan() { let l = new_dlist::<int>(); let one = new_dlist_node(1); let two = new_dlist_node(2); diff --git a/src/libcore/f32.rs b/src/libcore/f32.rs index c72aa6e3aef..3e7bc0097f7 100644 --- a/src/libcore/f32.rs +++ b/src/libcore/f32.rs @@ -168,15 +168,15 @@ pure fn log2(n: f32) -> f32 { } impl num of num::num for f32 { - fn add(&&other: f32) -> f32 { ret self + other; } - fn sub(&&other: f32) -> f32 { ret self - other; } - fn mul(&&other: f32) -> f32 { ret self * other; } - fn div(&&other: f32) -> f32 { ret self / other; } - fn modulo(&&other: f32) -> f32 { ret self % other; } - fn neg() -> f32 { ret -self; } - - fn to_int() -> int { ret self as int; } - fn from_int(n: int) -> f32 { ret n as f32; } + pure fn add(&&other: f32) -> f32 { ret self + other; } + pure fn sub(&&other: f32) -> f32 { ret self - other; } + pure fn mul(&&other: f32) -> f32 { ret self * other; } + pure fn div(&&other: f32) -> f32 { ret self / other; } + pure fn modulo(&&other: f32) -> f32 { ret self % other; } + pure fn neg() -> f32 { ret -self; } + + pure fn to_int() -> int { ret self as int; } + pure fn from_int(n: int) -> f32 { ret n as f32; } } // diff --git a/src/libcore/f64.rs b/src/libcore/f64.rs index 40488d9f8f4..9e84c432bad 100644 --- a/src/libcore/f64.rs +++ b/src/libcore/f64.rs @@ -195,15 +195,15 @@ pure fn log2(n: f64) -> f64 { } impl num of num::num for f64 { - fn add(&&other: f64) -> f64 { ret self + other; } - fn sub(&&other: f64) -> f64 { ret self - other; } - fn mul(&&other: f64) -> f64 { ret self * other; } - fn div(&&other: f64) -> f64 { ret self / other; } - fn modulo(&&other: f64) -> f64 { ret self % other; } - fn neg() -> f64 { ret -self; } - - fn to_int() -> int { ret self as int; } - fn from_int(n: int) -> f64 { ret n as f64; } + pure fn add(&&other: f64) -> f64 { ret self + other; } + pure fn sub(&&other: f64) -> f64 { ret self - other; } + pure fn mul(&&other: f64) -> f64 { ret self * other; } + pure fn div(&&other: f64) -> f64 { ret self / other; } + pure fn modulo(&&other: f64) -> f64 { ret self % other; } + pure fn neg() -> f64 { ret -self; } + + pure fn to_int() -> int { ret self as int; } + pure fn from_int(n: int) -> f64 { ret n as f64; } } // diff --git a/src/libcore/float.rs b/src/libcore/float.rs index 0139c60873b..8b8cc4664dc 100644 --- a/src/libcore/float.rs +++ b/src/libcore/float.rs @@ -403,32 +403,32 @@ fn pow_with_uint(base: uint, pow: uint) -> float { ret total; } -fn is_positive(x: float) -> bool { f64::is_positive(x as f64) } -fn is_negative(x: float) -> bool { f64::is_negative(x as f64) } -fn is_nonpositive(x: float) -> bool { f64::is_nonpositive(x as f64) } -fn is_nonnegative(x: float) -> bool { f64::is_nonnegative(x as f64) } -fn is_zero(x: float) -> bool { f64::is_zero(x as f64) } -fn is_infinite(x: float) -> bool { f64::is_infinite(x as f64) } -fn is_finite(x: float) -> bool { f64::is_finite(x as f64) } -fn is_NaN(x: float) -> bool { f64::is_NaN(x as f64) } - -fn abs(x: float) -> float { f64::abs(x as f64) as float } -fn sqrt(x: float) -> float { f64::sqrt(x as f64) as float } -fn atan(x: float) -> float { f64::atan(x as f64) as float } -fn sin(x: float) -> float { f64::sin(x as f64) as float } -fn cos(x: float) -> float { f64::cos(x as f64) as float } -fn tan(x: float) -> float { f64::tan(x as f64) as float } +pure fn is_positive(x: float) -> bool { f64::is_positive(x as f64) } +pure fn is_negative(x: float) -> bool { f64::is_negative(x as f64) } +pure fn is_nonpositive(x: float) -> bool { f64::is_nonpositive(x as f64) } +pure fn is_nonnegative(x: float) -> bool { f64::is_nonnegative(x as f64) } +pure fn is_zero(x: float) -> bool { f64::is_zero(x as f64) } +pure fn is_infinite(x: float) -> bool { f64::is_infinite(x as f64) } +pure fn is_finite(x: float) -> bool { f64::is_finite(x as f64) } +pure fn is_NaN(x: float) -> bool { f64::is_NaN(x as f64) } + +pure fn abs(x: float) -> float { f64::abs(x as f64) as float } +pure fn sqrt(x: float) -> float { f64::sqrt(x as f64) as float } +pure fn atan(x: float) -> float { f64::atan(x as f64) as float } +pure fn sin(x: float) -> float { f64::sin(x as f64) as float } +pure fn cos(x: float) -> float { f64::cos(x as f64) as float } +pure fn tan(x: float) -> float { f64::tan(x as f64) as float } impl num of num::num for float { - fn add(&&other: float) -> float { ret self + other; } - fn sub(&&other: float) -> float { ret self - other; } - fn mul(&&other: float) -> float { ret self * other; } - fn div(&&other: float) -> float { ret self / other; } - fn modulo(&&other: float) -> float { ret self % other; } - fn neg() -> float { ret -self; } - - fn to_int() -> int { ret self as int; } - fn from_int(n: int) -> float { ret n as float; } + pure fn add(&&other: float) -> float { ret self + other; } + pure fn sub(&&other: float) -> float { ret self - other; } + pure fn mul(&&other: float) -> float { ret self * other; } + pure fn div(&&other: float) -> float { ret self / other; } + pure fn modulo(&&other: float) -> float { ret self % other; } + pure fn neg() -> float { ret -self; } + + pure fn to_int() -> int { ret self as int; } + pure fn from_int(n: int) -> float { ret n as float; } } #[test] diff --git a/src/libcore/int-template.rs b/src/libcore/int-template.rs index 02ce125e35c..2b950e4a797 100644 --- a/src/libcore/int-template.rs +++ b/src/libcore/int-template.rs @@ -112,27 +112,27 @@ fn to_str_bytes<U>(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U { fn str(i: T) -> ~str { ret to_str(i, 10u); } impl ord of ord for T { - fn lt(&&other: T) -> bool { + pure fn lt(&&other: T) -> bool { ret self < other; } } impl eq of eq for T { - fn eq(&&other: T) -> bool { + pure fn eq(&&other: T) -> bool { ret self == other; } } impl num of num::num for T { - fn add(&&other: T) -> T { ret self + other; } - fn sub(&&other: T) -> T { ret self - other; } - fn mul(&&other: T) -> T { ret self * other; } - fn div(&&other: T) -> T { ret self / other; } - fn modulo(&&other: T) -> T { ret self % other; } - fn neg() -> T { ret -self; } - - fn to_int() -> int { ret self as int; } - fn from_int(n: int) -> T { ret n as T; } + pure fn add(&&other: T) -> T { ret self + other; } + pure fn sub(&&other: T) -> T { ret self - other; } + pure fn mul(&&other: T) -> T { ret self * other; } + pure fn div(&&other: T) -> T { ret self / other; } + pure fn modulo(&&other: T) -> T { ret self % other; } + pure fn neg() -> T { ret -self; } + + pure fn to_int() -> int { ret self as int; } + pure fn from_int(n: int) -> T { ret n as T; } } impl times of iter::times for T { diff --git a/src/libcore/io.rs b/src/libcore/io.rs index 25d1b5e6680..3704f2b70da 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -687,7 +687,11 @@ fn seek_in_buf(offset: int, pos: uint, len: uint, whence: seek_style) -> fn read_whole_file_str(file: ~str) -> result<~str, ~str> { result::chain(read_whole_file(file), |bytes| { - result::ok(str::from_bytes(bytes)) + if str::is_utf8(bytes) { + result::ok(str::from_bytes(bytes)) + } else { + result::err(file + ~" is not UTF-8") + } }) } diff --git a/src/libcore/num.rs b/src/libcore/num.rs index 130b259c1df..03868527655 100644 --- a/src/libcore/num.rs +++ b/src/libcore/num.rs @@ -1,17 +1,17 @@ /// An interface for numbers. -iface num { +trait num { // FIXME: Cross-crate overloading doesn't work yet. (#2615) // FIXME: Interface inheritance. (#2616) - fn add(&&other: self) -> self; - fn sub(&&other: self) -> self; - fn mul(&&other: self) -> self; - fn div(&&other: self) -> self; - fn modulo(&&other: self) -> self; - fn neg() -> self; + pure fn add(&&other: self) -> self; + pure fn sub(&&other: self) -> self; + pure fn mul(&&other: self) -> self; + pure fn div(&&other: self) -> self; + pure fn modulo(&&other: self) -> self; + pure fn neg() -> self; - fn to_int() -> int; - fn from_int(n: int) -> self; // FIXME (#2376) Static functions. + pure fn to_int() -> int; + pure fn from_int(n: int) -> self; // FIXME (#2376) Static functions. // n.b. #2376 is for classes, not ifaces, but it could be generalized... } diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs new file mode 100644 index 00000000000..61efe704974 --- /dev/null +++ b/src/libcore/ops.rs @@ -0,0 +1,66 @@ +// Core operators and kinds. + +#[lang="const"] +trait const { + // Empty. +} + +#[lang="copy"] +trait copy { + // Empty. +} + +#[lang="send"] +trait send { + // Empty. +} + +#[lang="owned"] +trait owned { + // Empty. +} + +#[lang="add"] +trait add<RHS,Result> { + pure fn add(rhs: RHS) -> Result; +} + +#[lang="sub"] +trait sub<RHS,Result> { + pure fn sub(rhs: RHS) -> Result; +} + +#[lang="mul"] +trait mul<RHS,Result> { + pure fn mul(rhs: RHS) -> Result; +} + +#[lang="div"] +trait div<RHS,Result> { + pure fn div(rhs: RHS) -> Result; +} + +#[lang="modulo"] +trait modulo<RHS,Result> { + pure fn modulo(rhs: RHS) -> Result; +} + +#[lang="neg"] +trait neg<RHS,Result> { + pure fn neg(rhs: RHS) -> Result; +} + +#[lang="bitops"] +trait bitops<RHS,BitCount,Result> { + pure fn and(rhs: RHS) -> Result; + pure fn or(rhs: RHS) -> Result; + pure fn xor(rhs: RHS) -> Result; + pure fn shl(n: BitCount) -> Result; + pure fn shr(n: BitCount) -> Result; +} + +#[lang="index"] +trait index<Index,Result> { + pure fn index(index: Index) -> Result; +} + diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index 27cd8ef7caf..4ffa040250f 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -30,59 +30,6 @@ macro_rules! move { // places. Once there is unary move, it can be removed. fn move<T>(-x: T) -> T { x } -/** - -Some thoughts about fixed buffers. - -The idea is if a protocol is bounded, we will synthesize a record that -has a field for each state. Each of these states contains a packet for -the messages that are legal to be sent in that state. Then, instead of -allocating, the send code just finds a pointer to the right field and -uses that instead. - -Unforunately, this makes things kind of tricky. We need to be able to -find the buffer, which means we need to pass it around. This could -either be associated with the (send|recv)_packet classes, or with the -packet itself. We will also need some form of reference counting so we -can track who has the responsibility of freeing the buffer. - -We want to preserve the ability to do things like optimistic buffer -re-use, and skipping over to a new buffer when necessary. What I mean -is, suppose we had the typical stream protocol. It'd make sense to -amortize allocation costs by allocating a buffer with say 16 -messages. When the sender gets to the end of the buffer, it could -check if the receiver is done with the packet in slot 0. If so, it can -just reuse that one, checking if the receiver is done with the next -one in each case. If it is ever not done, it just allocates a new -buffer and skips over to that. - -Also, since protocols are in libcore, we have to do this in a way that -maintains backwards compatibility. - -buffer header and buffer. Cast as c_void when necessary. - -=== - -Okay, here are some new ideas. - -It'd be nice to keep the bounded/unbounded case as uniform as -possible. It leads to less code duplication, and less things that can -go sublty wrong. For the bounded case, we could either have a struct -with a bunch of unique pointers to pre-allocated packets, or we could -lay them out inline. Inline layout is better, if for no other reason -than that we don't have to allocate each packet -individually. Currently we pass unique packets around as unsafe -pointers, but they are actually unique pointers. We should instead use -real unsafe pointers. This makes freeing data and running destructors -trickier though. Thus, we should allocate all packets in parter of a -higher level buffer structure. Packets can maintain a pointer to their -buffer, and this is the part that gets freed. - -It might be helpful to have some idea of a semi-unique pointer (like -being partially pregnant, also like an ARC). - -*/ - enum state { empty, full, @@ -805,6 +752,12 @@ class port_set<T: send> : recv<T> { vec::push(self.ports, port) } + fn chan() -> chan<T> { + let (ch, po) = stream(); + self.add(po); + ch + } + fn try_recv() -> option<T> { let mut result = none; while result == none && self.ports.len() > 0 { @@ -869,3 +822,52 @@ impl chan<T: send> of channel<T> for shared_chan<T> { fn shared_chan<T:send>(+c: chan<T>) -> shared_chan<T> { arc::exclusive(c) } + +trait select2<T: send, U: send> { + fn try_select() -> either<option<T>, option<U>>; + fn select() -> either<T, U>; +} + +impl<T: send, U: send, Left: selectable recv<T>, Right: selectable recv<U>> + of select2<T, U> for (Left, Right) { + + fn select() -> either<T, U> { + alt self { + (lp, rp) { + alt select2i(lp, rp) { + left(()) { left (lp.recv()) } + right(()) { right(rp.recv()) } + } + } + } + } + + fn try_select() -> either<option<T>, option<U>> { + alt self { + (lp, rp) { + alt select2i(lp, rp) { + left(()) { left (lp.try_recv()) } + right(()) { right(rp.try_recv()) } + } + } + } + } +} + +#[cfg(test)] +mod test { + #[test] + fn test_select2() { + let (c1, p1) = pipes::stream(); + let (c2, p2) = pipes::stream(); + + c1.send("abc"); + + alt (p1, p2).select() { + right(_) { fail } + _ { } + } + + c2.send(123); + } +} diff --git a/src/libcore/uint-template.rs b/src/libcore/uint-template.rs index 75e17cd6a9b..9561ed4e65f 100644 --- a/src/libcore/uint-template.rs +++ b/src/libcore/uint-template.rs @@ -53,27 +53,27 @@ pure fn compl(i: T) -> T { } impl ord of ord for T { - fn lt(&&other: T) -> bool { + pure fn lt(&&other: T) -> bool { ret self < other; } } impl eq of eq for T { - fn eq(&&other: T) -> bool { + pure fn eq(&&other: T) -> bool { ret self == other; } } impl num of num::num for T { - fn add(&&other: T) -> T { ret self + other; } - fn sub(&&other: T) -> T { ret self - other; } - fn mul(&&other: T) -> T { ret self * other; } - fn div(&&other: T) -> T { ret self / other; } - fn modulo(&&other: T) -> T { ret self % other; } - fn neg() -> T { ret -self; } - - fn to_int() -> int { ret self as int; } - fn from_int(n: int) -> T { ret n as T; } + pure fn add(&&other: T) -> T { ret self + other; } + pure fn sub(&&other: T) -> T { ret self - other; } + pure fn mul(&&other: T) -> T { ret self * other; } + pure fn div(&&other: T) -> T { ret self / other; } + pure fn modulo(&&other: T) -> T { ret self % other; } + pure fn neg() -> T { ret -self; } + + pure fn to_int() -> int { ret self as int; } + pure fn from_int(n: int) -> T { ret n as T; } } /** |
