implement Ord, TotalEq and TotalOrd for char

Closes #6063
This commit is contained in:
Daniel Micay 2013-04-25 13:55:39 -04:00
parent 1d53babd2f
commit 6d589f88f7
3 changed files with 57 additions and 70 deletions

View File

@ -10,6 +10,7 @@
//! Utilities for manipulating the char type
use cmp::Ord;
use option::{None, Option, Some};
use str;
use u32;
@ -243,24 +244,24 @@ pub fn len_utf8_bytes(c: char) -> uint {
else { fail!(~"invalid character!") }
}
/**
* Compare two chars
*
* # Return value
*
* -1 if a < b, 0 if a == b, +1 if a > b
*/
#[inline(always)]
pub fn cmp(a: char, b: char) -> int {
return if b > a { -1 }
else if b < a { 1 }
else { 0 }
#[cfg(notest)]
impl Eq for char {
#[inline(always)]
fn eq(&self, other: &char) -> bool { (*self) == (*other) }
#[inline(always)]
fn ne(&self, other: &char) -> bool { (*self) != (*other) }
}
#[cfg(notest)]
impl Eq for char {
fn eq(&self, other: &char) -> bool { (*self) == (*other) }
fn ne(&self, other: &char) -> bool { (*self) != (*other) }
impl Ord for char {
#[inline(always)]
fn lt(&self, other: &char) -> bool { *self < *other }
#[inline(always)]
fn le(&self, other: &char) -> bool { *self <= *other }
#[inline(always)]
fn gt(&self, other: &char) -> bool { *self > *other }
#[inline(always)]
fn ge(&self, other: &char) -> bool { *self >= *other }
}
#[test]

View File

@ -64,6 +64,8 @@ totaleq_impl!(i64)
totaleq_impl!(int)
totaleq_impl!(uint)
totaleq_impl!(char)
#[deriving(Clone, Eq)]
pub enum Ordering { Less = -1, Equal = 0, Greater = 1 }
@ -116,6 +118,8 @@ totalord_impl!(i64)
totalord_impl!(int)
totalord_impl!(uint)
totalord_impl!(char)
pub fn cmp2<A:TotalOrd,B:TotalOrd>(
a1: &A, b1: &B,
a2: &A, b2: &B) -> Ordering

View File

@ -33,11 +33,7 @@
* * access to a character by index is logarithmic (linear in strings);
*/
use core::option;
use core::prelude::*;
use core::str;
use core::uint;
use core::vec;
/// The type of ropes.
pub type Rope = node::Root;
@ -215,8 +211,8 @@ pub fn bal(rope:Rope) -> Rope {
match (rope) {
node::Empty => return rope,
node::Content(x) => match (node::bal(x)) {
option::None => rope,
option::Some(y) => node::Content(y)
None => rope,
Some(y) => node::Content(y)
}
}
}
@ -558,13 +554,7 @@ pub fn char_at(rope: Rope, pos: uint) -> char {
pub mod node {
use rope::node;
use core::cast;
use core::char;
use core::option;
use core::prelude::*;
use core::str;
use core::uint;
use core::vec;
/// Implementation of type `rope`
pub enum Root {
@ -835,8 +825,8 @@ pub mod node {
let mut it = leaf_iterator::start(node);
loop {
match leaf_iterator::next(&mut it) {
option::None => break,
option::Some(x) => {
None => break,
Some(x) => {
//FIXME (#2744): Replace with memcpy or something similar
let local_buf: ~[u8] = cast::transmute(*x.content);
let mut i = x.byte_offset;
@ -885,24 +875,24 @@ pub mod node {
*
* # Return value
*
* * `option::None` if no transformation happened
* * `option::Some(x)` otherwise, in which case `x` has the same contents
* * `None` if no transformation happened
* * `Some(x)` otherwise, in which case `x` has the same contents
* as `node` bot lower height and/or fragmentation.
*/
pub fn bal(node: @Node) -> Option<@Node> {
if height(node) < hint_max_node_height { return option::None; }
if height(node) < hint_max_node_height { return None; }
//1. Gather all leaves as a forest
let mut forest = ~[];
let mut it = leaf_iterator::start(node);
loop {
match leaf_iterator::next(&mut it) {
option::None => break,
option::Some(x) => forest.push(@Leaf(x))
None => break,
Some(x) => forest.push(@Leaf(x))
}
}
//2. Rebuild tree from forest
let root = @*tree_from_forest_destructive(forest);
return option::Some(root);
return Some(root);
}
@ -1061,14 +1051,14 @@ pub mod node {
while result == 0 {
match (char_iterator::next(&mut ita), char_iterator::next(&mut itb))
{
(option::None, option::None) => break,
(option::Some(chara), option::Some(charb)) => {
result = char::cmp(chara, charb);
(None, None) => break,
(Some(chara), Some(charb)) => {
result = chara.cmp(&charb) as int;
}
(option::Some(_), _) => {
(Some(_), _) => {
result = 1;
}
(_, option::Some(_)) => {
(_, Some(_)) => {
result = -1;
}
}
@ -1145,9 +1135,7 @@ pub mod node {
pub mod leaf_iterator {
use rope::node::{Concat, Leaf, Node, height};
use core::option;
use core::prelude::*;
use core::vec;
pub struct T {
stack: ~[@Node],
@ -1168,7 +1156,7 @@ pub mod node {
}
pub fn next(it: &mut T) -> Option<Leaf> {
if it.stackpos < 0 { return option::None; }
if it.stackpos < 0 { return None; }
loop {
let current = it.stack[it.stackpos];
it.stackpos -= 1;
@ -1179,7 +1167,7 @@ pub mod node {
it.stackpos += 1;
it.stack[it.stackpos] = x.left;
}
Leaf(x) => return option::Some(x)
Leaf(x) => return Some(x)
}
};
}
@ -1189,9 +1177,7 @@ pub mod node {
use rope::node::{Leaf, Node};
use rope::node::leaf_iterator;
use core::option;
use core::prelude::*;
use core::str;
pub struct T {
leaf_iterator: leaf_iterator::T,
@ -1202,7 +1188,7 @@ pub mod node {
pub fn start(node: @Node) -> T {
T {
leaf_iterator: leaf_iterator::start(node),
leaf: option::None,
leaf: None,
leaf_byte_pos: 0u,
}
}
@ -1210,7 +1196,7 @@ pub mod node {
pub fn empty() -> T {
T {
leaf_iterator: leaf_iterator::empty(),
leaf: option::None,
leaf: None,
leaf_byte_pos: 0u,
}
}
@ -1218,12 +1204,12 @@ pub mod node {
pub fn next(it: &mut T) -> Option<char> {
loop {
match get_current_or_next_leaf(it) {
option::None => return option::None,
option::Some(_) => {
None => return None,
Some(_) => {
let next_char = get_next_char_in_leaf(it);
match next_char {
option::None => loop,
option::Some(_) => return next_char
None => loop,
Some(_) => return next_char
}
}
}
@ -1232,12 +1218,12 @@ pub mod node {
pub fn get_current_or_next_leaf(it: &mut T) -> Option<Leaf> {
match it.leaf {
option::Some(_) => return it.leaf,
option::None => {
Some(_) => return it.leaf,
None => {
let next = leaf_iterator::next(&mut it.leaf_iterator);
match next {
option::None => return option::None,
option::Some(_) => {
None => return None,
Some(_) => {
it.leaf = next;
it.leaf_byte_pos = 0u;
return next;
@ -1249,12 +1235,12 @@ pub mod node {
pub fn get_next_char_in_leaf(it: &mut T) -> Option<char> {
match copy it.leaf {
option::None => return option::None,
option::Some(aleaf) => {
None => return None,
Some(aleaf) => {
if it.leaf_byte_pos >= aleaf.byte_len {
//We are actually past the end of the leaf
it.leaf = option::None;
return option::None
it.leaf = None;
return None
} else {
let range =
str::char_range_at(*aleaf.content,
@ -1262,7 +1248,7 @@ pub mod node {
let ch = range.ch;
let next = range.next;
(*it).leaf_byte_pos = next - aleaf.byte_offset;
return option::Some(ch)
return Some(ch)
}
}
}
@ -1273,11 +1259,7 @@ pub mod node {
#[cfg(test)]
mod tests {
use rope::*;
use core::option;
use core::str;
use core::uint;
use core::vec;
use core::prelude::*;
//Utility function, used for sanity check
fn rope_to_string(r: Rope) -> ~str {
@ -1341,11 +1323,11 @@ mod tests {
let mut equal = true;
while equal {
match (node::char_iterator::next(&mut rope_iter)) {
option::None => {
None => {
if string_iter < string_len {
equal = false;
} break; }
option::Some(c) => {
Some(c) => {
let range = str::char_range_at(*sample, string_iter);
string_iter = range.next;
if range.ch != c { equal = false; break; }
@ -1373,8 +1355,8 @@ mod tests {
let mut it = iterator::char::start(r);
loop {
match (node::char_iterator::next(&mut it)) {
option::None => break,
option::Some(_) => len += 1u
None => break,
Some(_) => len += 1u
}
}