Re: [rust-dev] Can Rust allow a bitwise equality test?

2013-07-19 Thread Thiez
I think something along these lines should do:

fn bitwise_compareT(a: T, b: T) - bool {
  use std::{ptr,sys,cast,uint};
  let size = sys::size_of::T();
  unsafe {
let a: u8 = cast::transmute(a);
let b: u8 = cast::transmute(b);
for uint::range(0,size) |n| {
  if *ptr::offset(a,n) != *ptr::offset(b,n){
return false
  }
}
  }
  true
}

Note that it won't work for strings and vectors. It could be slightly more
efficient by comparing in larger chunks than u8, but LLVM will probably
figure that out.

On Fri, Jul 19, 2013 at 3:06 AM, David Piepgrass qwertie...@gmail.comwrote:


  I think at the least we should offer a #[deriving(Basics)] for use on
 public
  types so that people aren't forced to memorize Eq Ord TotalOrd TotalEq
  IterBytes Clone (unless we can find a silly SFINAE-esque acronym...
  http://www.wordsmith.org/anagram/anagram.cgi?anagram=eottic ).

 Plenty of types can't actually be ordered, and in *many* cases not all
 fields should be considered for equality/ordering and they may or may
 not be listed in the order the comparison should try.

 The only two that rarely require any extra consideration are
 `Clone`/`DeepClone`, since they should be on almost every type without
 a destructor.


 I just had a random thought.

 I once implemented a data structure for .NET called a VList (
 http://www.codeproject.com/Articles/26171/VList-data-structures-in-C)
 which provided a SmartSelect pseudo-LINQ method. If you had a list of
 numbers, you could ensure they are all positive like this:

 list.SmartSelect(x = Math.Max(x, 1))

 The reason it's called SmartSelect is that it returns a changed list only
 if the select operation *changes* any of the values (and even then it may
 still be able to re-use the tail of the list). The tricky part is detecting
 when there has been any changes. Ideally I would have liked to simply do a
 bitwise equality test because it would be very fast and requires no special
 support from the data type, but .NET doesn't have a bitwise equality test.
 So I ended up having to use a test that always requires dynamic method
 invocation, which I have heard is fantastically slow in the general case of
 structs that don't implement IEquatableT.

 I wonder if Rust could, in the general case, allow my bitwise equality
 test. I realize that bitwise equality isn't real equality, but in this
 case it's good enough. For instance if the selector changes -0.0 to +0.0,
 which is value-equal but bitwise-different, the effect is fairly
 harmless--a partially new list is allocated instead of re-using the old
 list.

 Of course, if the list contains references (~T, @T), the bitwise test
 should compare the references themselves, without dereferencing.

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Can Rust allow a bitwise equality test?

2013-07-19 Thread Simon Sapin

Le 19/07/2013 10:17, Thiez a écrit :

I think something along these lines should do:

fn bitwise_compareT(a: T, b: T) - bool {
   use std::{ptr,sys,cast,uint};
   let size = sys::size_of::T();
   unsafe {
 let a: u8 = cast::transmute(a);
 let b: u8 = cast::transmute(b);
 for uint::range(0,size) |n| {
   if *ptr::offset(a,n) != *ptr::offset(b,n){
 return false
   }
 }
   }
   true
}

Note that it won't work for strings and vectors. It could be slightly
more efficient by comparing in larger chunks than u8, but LLVM will
probably figure that out.


There’s code in libstd that uses libc::memcpm instead of an explicit loop:

https://github.com/mozilla/rust/blob/06fec5243b/src/libstd/vec.rs#L2091

Cheers,
--
Simon Sapin
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev