Skip to content

Instantly share code, notes, and snippets.

@seliopou
Created November 6, 2018 08:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seliopou/043d93eb6a3f2e40c26b16244aaabf88 to your computer and use it in GitHub Desktop.
Save seliopou/043d93eb6a3f2e40c26b16244aaabf88 to your computer and use it in GitHub Desktop.
module String = StringLabels
type t = Bytes.t
external unsafe_get_64 : Bytes.t -> int -> int64 = "%caml_string_get64u"
external unsafe_set_64 : Bytes.t -> int -> int64 -> unit = "%caml_string_set64u"
let pp_hum fmt t =
Printf.fprintf fmt "x%.16Lx" (unsafe_get_64 t 0);
Printf.fprintf fmt "x%.16Lx" (unsafe_get_64 t 8);
Printf.fprintf fmt "x%.16Lx" (unsafe_get_64 t 16);
Printf.fprintf fmt "x%.16Lx" (unsafe_get_64 t 24);
;;
let create cs =
let t = Bytes.make 32 '\000' in
String.iter cs ~f:(fun char ->
let code = Char.code char in
let word = (code lsr 6) lsl 3 in
unsafe_set_64 t word Int64.(logor (unsafe_get_64 t word) (shift_left 1L code)));
Printf.printf "create: %a\n%!" pp_hum t;
t
let member t char =
let code = Char.code char in
let word = (code lsr 6) lsl 3 in
Int64.((logand (unsafe_get_64 t word) (shift_left 1L code)) <> 0L)
let union u v =
let t = Bytes.make 32 '\000' in
unsafe_set_64 t 0 Int64.(logor (unsafe_get_64 u 0 ) (unsafe_get_64 v 0 ));
unsafe_set_64 t 8 Int64.(logor (unsafe_get_64 u 8 ) (unsafe_get_64 v 8 ));
unsafe_set_64 t 16 Int64.(logor (unsafe_get_64 u 16) (unsafe_get_64 v 16));
unsafe_set_64 t 24 Int64.(logor (unsafe_get_64 u 24) (unsafe_get_64 v 24));
t
let difference u v =
let t = Bytes.make 32 '\000' in
unsafe_set_64 t 0 Int64.(logand (unsafe_get_64 u 0 ) (lognot (unsafe_get_64 v 0 )));
unsafe_set_64 t 8 Int64.(logand (unsafe_get_64 u 8 ) (lognot (unsafe_get_64 v 8 )));
unsafe_set_64 t 16 Int64.(logand (unsafe_get_64 u 16) (lognot (unsafe_get_64 v 16)));
unsafe_set_64 t 24 Int64.(logand (unsafe_get_64 u 24) (lognot (unsafe_get_64 v 24)));
t
let negate t =
Printf.printf "before: %a\n%!" pp_hum t;
let u = Bytes.make 32 '\000' in
unsafe_set_64 u 0 Int64.(lognot (unsafe_get_64 t 0 ));
unsafe_set_64 u 8 Int64.(lognot (unsafe_get_64 t 8 ));
unsafe_set_64 u 16 Int64.(lognot (unsafe_get_64 t 16));
unsafe_set_64 u 24 Int64.(lognot (unsafe_get_64 t 24));
Printf.printf "after : %a\n%!" pp_hum u;
u
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment