Skip to content

implement Ord, TotalEq and TotalOrd for char #6064

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions src/libcore/char.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

//! Utilities for manipulating the char type

use cmp::Ord;
use option::{None, Option, Some};
use str;
use u32;
Expand Down Expand Up @@ -243,26 +244,26 @@ 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 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]
fn test_is_lowercase() {
assert!(is_lowercase('a'));
Expand Down
4 changes: 4 additions & 0 deletions src/libcore/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 }

Expand Down Expand Up @@ -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
Expand Down
92 changes: 37 additions & 55 deletions src/libstd/rope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
}
}
}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);

}

Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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],
Expand All @@ -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;
Expand All @@ -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)
}
};
}
Expand All @@ -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,
Expand All @@ -1202,28 +1188,28 @@ 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,
}
}

pub fn empty() -> T {
T {
leaf_iterator: leaf_iterator::empty(),
leaf: option::None,
leaf: None,
leaf_byte_pos: 0u,
}
}

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
}
}
}
Expand All @@ -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;
Expand All @@ -1249,20 +1235,20 @@ 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,
(*it).leaf_byte_pos + aleaf.byte_offset);
let ch = range.ch;
let next = range.next;
(*it).leaf_byte_pos = next - aleaf.byte_offset;
return option::Some(ch)
return Some(ch)
}
}
}
Expand All @@ -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 {
Expand Down Expand Up @@ -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; }
Expand Down Expand Up @@ -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
}
}

Expand Down