mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-07 11:45:31 -05:00
export more functions in CCBitField including any-width fields
This commit is contained in:
parent
e54b5f32e6
commit
b71cfc4568
2 changed files with 90 additions and 5 deletions
|
|
@ -25,12 +25,35 @@ module type BITFIELD = sig
|
||||||
(** Number of bits of the field *)
|
(** Number of bits of the field *)
|
||||||
|
|
||||||
val bool : unit -> bool field
|
val bool : unit -> bool field
|
||||||
(** New field of type bool *)
|
(** New field of type boo
|
||||||
|
@raise TooManyFields if there is no room *)
|
||||||
|
|
||||||
val int2 : unit -> int field
|
val int2 : unit -> int field
|
||||||
(** New field of type 2-bits int *)
|
(** New field of type 2-bits int
|
||||||
|
@raise TooManyFields if there is no room *)
|
||||||
|
|
||||||
|
val int3 : unit -> int field
|
||||||
|
(** New field for 3-bits int
|
||||||
|
@raise TooManyFields if there is no room *)
|
||||||
|
|
||||||
|
val int : width:int -> int field
|
||||||
|
(** New field for [width] bits.
|
||||||
|
@raise TooManyFields if there is no room *)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
let rec all_bits_ acc w =
|
||||||
|
if w=0 then acc
|
||||||
|
else
|
||||||
|
let acc = acc lor (1 lsl w-1) in
|
||||||
|
all_bits_ acc (w-1)
|
||||||
|
|
||||||
|
(*$T
|
||||||
|
all_bits_ 0 1 = 1
|
||||||
|
all_bits_ 0 2 = 3
|
||||||
|
all_bits_ 0 3 = 7
|
||||||
|
all_bits_ 0 4 = 15
|
||||||
|
*)
|
||||||
|
|
||||||
module Make(X : EMPTY) : BITFIELD = struct
|
module Make(X : EMPTY) : BITFIELD = struct
|
||||||
type t = int
|
type t = int
|
||||||
|
|
||||||
|
|
@ -78,4 +101,37 @@ module Make(X : EMPTY) : BITFIELD = struct
|
||||||
x lor (v lsl n)
|
x lor (v lsl n)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let int3 () =
|
||||||
|
let n = !width_ in
|
||||||
|
width_ := n+3;
|
||||||
|
if !width_ > max_width then raise TooManyFields;
|
||||||
|
let mask = 7 lsl n in
|
||||||
|
{
|
||||||
|
start=n;
|
||||||
|
width=3;
|
||||||
|
get=(fun x -> (x land mask) lsr n);
|
||||||
|
set=(fun v x ->
|
||||||
|
assert (x >= 0 && x < 8);
|
||||||
|
let x = x land (lnot mask) in
|
||||||
|
x lor (v lsl n)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let int ~width:w =
|
||||||
|
let n = !width_ in
|
||||||
|
width_ := n+w;
|
||||||
|
if !width_ > max_width then raise TooManyFields;
|
||||||
|
let mask_unshifted = all_bits_ 0 w in
|
||||||
|
let mask = mask_unshifted lsl n in
|
||||||
|
{
|
||||||
|
start=n;
|
||||||
|
width=w;
|
||||||
|
get=(fun x -> (x land mask) lsr n);
|
||||||
|
set=(fun v x ->
|
||||||
|
assert (x >= 0 && x <= mask_unshifted);
|
||||||
|
let x = x land (lnot mask) in
|
||||||
|
x lor (v lsl n)
|
||||||
|
)
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@
|
||||||
{b status: experimental}
|
{b status: experimental}
|
||||||
@since NEXT_RELEASE *)
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
exception TooManyFields
|
||||||
|
(** Raised when too many fields are packed into one bitfield *)
|
||||||
|
|
||||||
module type EMPTY = sig end
|
module type EMPTY = sig end
|
||||||
|
|
||||||
(** {2 Bitfield Signature} *)
|
(** {2 Bitfield Signature} *)
|
||||||
|
|
@ -29,10 +32,20 @@ module type BITFIELD = sig
|
||||||
(** Number of bits of the field *)
|
(** Number of bits of the field *)
|
||||||
|
|
||||||
val bool : unit -> bool field
|
val bool : unit -> bool field
|
||||||
(** New field of type bool *)
|
(** New field of type boo
|
||||||
|
@raise TooManyFields if there is no room *)
|
||||||
|
|
||||||
val int2 : unit -> int field
|
val int2 : unit -> int field
|
||||||
(** New field of type 2-bits int *)
|
(** New field of type 2-bits int
|
||||||
|
@raise TooManyFields if there is no room *)
|
||||||
|
|
||||||
|
val int3 : unit -> int field
|
||||||
|
(** New field for 3-bits int
|
||||||
|
@raise TooManyFields if there is no room *)
|
||||||
|
|
||||||
|
val int : width:int -> int field
|
||||||
|
(** New field for [width] bits.
|
||||||
|
@raise TooManyFields if there is no room *)
|
||||||
end
|
end
|
||||||
|
|
||||||
(** Create a new bitfield type *)
|
(** Create a new bitfield type *)
|
||||||
|
|
@ -44,8 +57,10 @@ module Make(X : EMPTY) : BITFIELD
|
||||||
let x = B.bool () in
|
let x = B.bool () in
|
||||||
let y = B.int2 () in
|
let y = B.int2 () in
|
||||||
let z = B.bool () in
|
let z = B.bool () in
|
||||||
|
let u = B.int 4 in
|
||||||
|
|
||||||
assert_equal 2 (B.width y) ;
|
assert_equal 2 (B.width y) ;
|
||||||
|
assert_equal 4 (B.width u) ;
|
||||||
|
|
||||||
let f = B.empty
|
let f = B.empty
|
||||||
|> B.set y 3
|
|> B.set y 3
|
||||||
|
|
@ -56,8 +71,22 @@ module Make(X : EMPTY) : BITFIELD
|
||||||
|
|
||||||
assert_equal false (B.get x f) ;
|
assert_equal false (B.get x f) ;
|
||||||
assert_equal 3 (B.get y f) ;
|
assert_equal 3 (B.get y f) ;
|
||||||
assert_equal (B.get z f);
|
assert_equal true (B.get z f);
|
||||||
|
|
||||||
|
let f' = B.set u 13 f in
|
||||||
|
|
||||||
|
assert_equal false (B.get x f') ;
|
||||||
|
assert_equal 3 (B.get y f') ;
|
||||||
|
assert_equal true (B.get z f');
|
||||||
|
assert_equal 13 (B.get u f');
|
||||||
|
|
||||||
()
|
()
|
||||||
*)
|
*)
|
||||||
|
|
||||||
|
|
||||||
|
(**/**)
|
||||||
|
|
||||||
|
val all_bits_ : int -> int -> int
|
||||||
|
(** Undocumented, do not use. Exposed for testing purpose *)
|
||||||
|
|
||||||
|
(**/**)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue