From 2f0a61fab7f72e6a4b273015358ce6e3cdea2c47 Mon Sep 17 00:00:00 2001
From: Jeremy Yallop <yallop@gmail.com>
Date: Mon, 22 May 2017 11:34:28 +0100
Subject: [PATCH 1/3] Add a name to the opam file to ease pinning.

---
 opam | 1 +
 1 file changed, 1 insertion(+)

diff --git a/opam b/opam
index 2b61fea..e76cc1f 100644
--- a/opam
+++ b/opam
@@ -1,4 +1,5 @@
 opam-version: "1.2"
+name: "usane"
 maintainer: "Hannes Mehnert <hannes@mehnert.org>"
 authors: ["Hannes Mehnert <hannes@mehnert.org>"]
 homepage: "https://github.com/hannesm/usane"

From c22d356267092d9ce2ab21cadfef1b3ab91e742d Mon Sep 17 00:00:00 2001
From: Jeremy Yallop <yallop@gmail.com>
Date: Mon, 22 May 2017 11:48:22 +0100
Subject: [PATCH 2/3] Add Uint*.zero.

---
 src/usane.ml  |  8 ++++++++
 src/usane.mli | 16 ++++++++++++++--
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/src/usane.ml b/src/usane.ml
index 6002694..1108ca4 100644
--- a/src/usane.ml
+++ b/src/usane.ml
@@ -16,6 +16,8 @@ module Uint8 = struct
   external mul : t -> t -> t * bool = "caml__uint8_mul_overflow"
   external sub : t -> t -> t * bool = "caml__uint8_sub_overflow"
 
+  let zero = 0
+
   let pred t = sub t 1
 
   let succ t = add t 1
@@ -54,6 +56,8 @@ module Uint16 = struct
   external mul : t -> t -> t * bool = "caml__uint16_mul_overflow"
   external sub : t -> t -> t * bool = "caml__uint16_sub_overflow"
 
+  let zero = 0
+
   let pred t = sub t 1
 
   let succ t = add t 1
@@ -100,6 +104,8 @@ module Uint32 = struct
   external mul : t -> t -> t * bool = "caml_uint32_mul_overflow"
   external sub : t -> t -> t * bool = "caml_uint32_sub_overflow"
 
+  let zero = 0l
+
   let pred t = sub t 1l
 
   let succ t = add t 1l
@@ -144,6 +150,8 @@ module Uint64 = struct
   external mul : t -> t -> t * bool = "caml_uint64_mul_overflow"
   external sub : t -> t -> t * bool = "caml_uint64_sub_overflow"
 
+  let zero = 0L
+
   let pred t = sub t 1L
 
   let succ t = add t 1L
diff --git a/src/usane.mli b/src/usane.mli
index 42b4eb8..21c5deb 100644
--- a/src/usane.mli
+++ b/src/usane.mli
@@ -24,7 +24,7 @@
 module Uint8 : sig
 
   (** Type of an unsigned 8 bit integer.  It is represented as an [int]*)
-  type t = int
+  type t = private int
 
   (** [pp ppf u] prints the unsigned 8bit integer in hex encoding. *)
   val pp : Format.formatter -> t -> unit
@@ -55,6 +55,9 @@ module Uint8 : sig
       is [true], otherwise it is [false]. *)
   val pred : t -> t * bool
 
+  (** [zero] is [Uint8.of_int 0] *)
+  val zero : t
+
   (** [compare t t'] is
       {ul
       {- [-1] if [t] is smaller than [t'],}
@@ -88,7 +91,7 @@ end
 module Uint16 : sig
 
   (** Type of an unsigned 16 bit integer.  It is represented as an [int]*)
-  type t = int
+  type t = private int
 
   (** [pp ppf u] prints the unsigned 16bit integer in hex encoding. *)
   val pp : Format.formatter -> t -> unit
@@ -119,6 +122,9 @@ module Uint16 : sig
       is [true], otherwise it is [false]. *)
   val pred : t -> t * bool
 
+  (** [zero] is [Uint16.of_int 0] *)
+  val zero : t
+
   (** [compare t t'] is
       {ul
       {- [-1] if [t] is smaller than [t'],}
@@ -188,6 +194,9 @@ module Uint32 : sig
       is [true], otherwise it is [false]. *)
   val pred : t -> t * bool
 
+  (** [zero] is [Uint32.of_int 0] *)
+  val zero : t
+
   (** [compare t t'] is
       {ul
       {- [-1] if [t] is smaller than [t'],}
@@ -257,6 +266,9 @@ module Uint64 : sig
       is [true], otherwise it is [false]. *)
   val pred : t -> t * bool
 
+  (** [zero] is [Uint64.of_int 0] *)
+  val zero : t
+
   (** [compare t t'] is
       {ul
       {- [-1] if [t] is smaller than [t'],}

From 52f91d2f1f6e44c08ba5658f73d8daec19d82ff6 Mon Sep 17 00:00:00 2001
From: Jeremy Yallop <yallop@gmail.com>
Date: Mon, 22 May 2017 11:56:40 +0100
Subject: [PATCH 3/3] Update Uint8, Uint16 tests for private types.

---
 test/test.ml | 156 +++++++++++++++++++++++++--------------------------
 1 file changed, 78 insertions(+), 78 deletions(-)

diff --git a/test/test.ml b/test/test.ml
index 5d649b0..eb0fcdf 100644
--- a/test/test.ml
+++ b/test/test.ml
@@ -19,15 +19,15 @@ module Uint8_test = struct
   let of_int_r () =
     for _i = 0 to 1000 do
       let r = r8 () in
-      Alcotest.check uint8 "random" r (Uint8.of_int r)
+      Alcotest.(check int) "random" r (Uint8.of_int r :> int)
     done
 
   let int_bound () =
-    Alcotest.check uint8 "int 0 ok" 0 (Uint8.of_int 0) ;
+    Alcotest.(check int) "int 0 ok" 0 (Uint8.zero :> int) ;
     Alcotest.check_raises "smaller 0 raises"
       (Invalid_argument "out of range")
       (fun () -> ignore (Uint8.of_int (-1))) ;
-    Alcotest.check uint8 "int 2 ^ 8 - 1 ok" 0xFF (Uint8.of_int 0xFF) ;
+    Alcotest.(check int) "int 2 ^ 8 - 1 ok" 0xFF (Uint8.of_int 0xFF :> int) ;
     Alcotest.check_raises "greater 2 ^ 8 - 1 raises"
       (Invalid_argument "out of range")
       (fun () -> ignore (Uint8.of_int (0x100)))
@@ -42,16 +42,16 @@ module Uint8_test = struct
 
   let add_int_overflow () =
     Alcotest.(check (pair uint8 bool) "add 0xFF 1 overflows"
-                (0, true)
-                Uint8.(add (of_int 0xFF) 1)) ;
+                (Uint8.zero, true)
+                Uint8.(add (of_int 0xFF) (Uint8.of_int 1))) ;
     Alcotest.(check (pair uint8 bool) "succ 0xFF overflows"
-                (0, true)
+                (Uint8.zero, true)
                 Uint8.(succ (of_int 0xFF))) ;
     Alcotest.(check (pair uint8 bool) "add 0x80 0x80 overflows"
-                (0, true)
+                (Uint8.zero, true)
                 Uint8.(add (of_int 0x80) (of_int 0x80))) ;
     Alcotest.(check (pair uint8 bool) "add 0x80 0x7F no overflow"
-                (0xFF, false)
+                (Uint8.of_int 0xFF, false)
                 Uint8.(add (of_int 0x80) (of_int 0x7F)))
 
   let mul_ints () =
@@ -68,26 +68,26 @@ module Uint8_test = struct
 
   let mul_int_overflow () =
     Alcotest.(check (pair uint8 bool) "mul 0xFF 2 overflows"
-                (0xFE, true)
-                Uint8.(mul (of_int 0xFF) 2)) ;
+                (Uint8.of_int 0xFE, true)
+                Uint8.(mul (of_int 0xFF) (Uint8.of_int 2))) ;
     Alcotest.(check (pair uint8 bool) "mul 0x3F 2 no overflow"
-                (0x7E, false)
-                Uint8.(mul (of_int 0x3F) 2)) ;
+                (Uint8.of_int 0x7E, false)
+                Uint8.(mul (of_int 0x3F) (Uint8.of_int 2))) ;
     Alcotest.(check (pair uint8 bool) "mul 0x3F 4 no overflow"
-                (0xFC, false)
-                Uint8.(mul (of_int 0x3F) 4)) ;
+                (Uint8.of_int 0xFC, false)
+                Uint8.(mul (of_int 0x3F) (Uint8.of_int 4))) ;
     Alcotest.(check (pair uint8 bool) "mul 0x7F 2 no overflow"
-                (0xFE, false)
-                Uint8.(mul (of_int 0x7F) 2)) ;
+                (Uint8.of_int 0xFE, false)
+                Uint8.(mul (of_int 0x7F) (Uint8.of_int 2))) ;
     Alcotest.(check (pair uint8 bool) "mul 0x80 2 overflows"
-                (0, true)
-                Uint8.(mul (of_int 0x80) 2)) ;
+                (Uint8.zero, true)
+                Uint8.(mul (of_int 0x80) (Uint8.of_int 2))) ;
     Alcotest.(check (pair uint8 bool) "mul 0x40 4 overflows"
-                (0, true)
-                Uint8.(mul (of_int 0x40) 4)) ;
+                (Uint8.zero, true)
+                Uint8.(mul (of_int 0x40) (Uint8.of_int 4))) ;
     Alcotest.(check (pair uint8 bool) "mul 0x40 2 no overflow"
-                (0x80, false)
-                Uint8.(mul (of_int 0x40) 2))
+                (Uint8.of_int 0x80, false)
+                Uint8.(mul (of_int 0x40) (Uint8.of_int 2)))
 
   let sub_ints () =
     for _i = 0 to 1000 do
@@ -101,33 +101,33 @@ module Uint8_test = struct
 
   let sub_int_underflow () =
     Alcotest.(check (pair uint8 bool) "sub 0 1 underflows"
-                (0xFF, true)
-                Uint8.(sub 0 1)) ;
+                (Uint8.of_int 0xFF, true)
+                Uint8.(sub zero (of_int 1))) ;
     Alcotest.(check (pair uint8 bool) "pred 0 underflows"
-                (0xFF, true)
-                Uint8.(pred 0)) ;
+                (Uint8.of_int 0xFF, true)
+                Uint8.(pred zero)) ;
     Alcotest.(check (pair uint8 bool) "sub 0x80 0x81 underflows"
-                (0xFF, true)
+                (Uint8.of_int 0xFF, true)
                 Uint8.(sub (of_int 0x80) (of_int 0x81))) ;
     Alcotest.(check (pair uint8 bool) "sub 0x80 0x7F is 1"
-                (1, false)
+                (Uint8.of_int 1, false)
                 Uint8.(sub (of_int 0x80) (of_int 0x7F)))
 
   let compare_works () =
     Alcotest.check Alcotest.int "compare 0xFF 0xFF is 0"
       0 Uint8.(compare (of_int 0xFF) (of_int 0xFF)) ;
     Alcotest.check Alcotest.int "compare 0 0 is 0"
-      0 Uint8.(compare 0 0) ;
+      0 Uint8.(compare zero zero) ;
     Alcotest.check Alcotest.int "compare 1 1 is 0"
-      0 Uint8.(compare 1 1) ;
+      0 Uint8.(compare (of_int 1) (of_int 1)) ;
     Alcotest.check Alcotest.int "compare 0 1 is -1"
-      (-1) Uint8.(compare 0 1) ;
+      (-1) Uint8.(compare (of_int 0) (of_int 1)) ;
     Alcotest.check Alcotest.int "compare 1 0 is 1"
-      1 Uint8.(compare 1 0) ;
+      1 Uint8.(compare (of_int 1) (of_int 0)) ;
     Alcotest.check Alcotest.int "compare 0xFF 0 is 1"
-      1 Uint8.(compare (of_int 0xFF) 0) ;
+      1 Uint8.(compare (of_int 0xFF) zero) ;
     Alcotest.check Alcotest.int "compare 0 0xFF is -1"
-      (-1) Uint8.(compare 0 (of_int 0xFF)) ;
+      (-1) Uint8.(compare zero (of_int 0xFF)) ;
     Alcotest.check Alcotest.int "compare 0xFF 0xFE is 1"
       1 Uint8.(compare (of_int 0xFF) (of_int 0xFE)) ;
     Alcotest.check Alcotest.int "compare 0xFE 0xFF is -1"
@@ -139,13 +139,13 @@ module Uint8_test = struct
 
   let succ_pred_at_bound () =
     Alcotest.(check (pair uint8 bool) "succ 0x7F is 0x80"
-                (0x80, false) Uint8.(succ (of_int 0x7F))) ;
+                (Uint8.of_int 0x80, false) Uint8.(succ (of_int 0x7F))) ;
     Alcotest.(check (pair uint8 bool) "succ 0x80 is 0x81"
-                (0x81, false) Uint8.(succ (of_int 0x80))) ;
+                (Uint8.of_int 0x81, false) Uint8.(succ (of_int 0x80))) ;
     Alcotest.(check (pair uint8 bool) "pred 0x80 is 0x7F"
-                (0x7F, false) Uint8.(pred (of_int 0x80))) ;
+                (Uint8.of_int 0x7F, false) Uint8.(pred (of_int 0x80))) ;
     Alcotest.(check (pair uint8 bool) "pred 0x81 is 0x80"
-                (0x80, false) Uint8.(pred (of_int 0x81)))
+                (Uint8.of_int 0x80, false) Uint8.(pred (of_int 0x81)))
 
   let tests = [
     "random of_int", `Slow, of_int_r ;
@@ -180,15 +180,15 @@ module Uint16_test = struct
   let of_int_r () =
     for _i = 0 to 1000 do
       let r = r16 () in
-      Alcotest.check uint16 "random" r (Uint16.of_int r)
+      Alcotest.(check int) "random" r (Uint16.of_int r :> int)
     done
 
   let int_bound () =
-    Alcotest.check uint16 "int 0 ok" 0 (Uint16.of_int 0) ;
+    Alcotest.(check int) "int 0 ok" 0 (Uint16.zero :> int) ;
     Alcotest.check_raises "smaller 0 raises"
       (Invalid_argument "out of range")
       (fun () -> ignore (Uint16.of_int (-1))) ;
-    Alcotest.check uint16 "int 2 ^ 16 - 1 ok" 0xFFFF (Uint16.of_int 0xFFFF) ;
+    Alcotest.(check int) "int 2 ^ 16 - 1 ok" 0xFFFF (Uint16.of_int 0xFFFF :> int) ;
     Alcotest.check_raises "greater 2 ^ 16 - 1 raises"
       (Invalid_argument "out of range")
       (fun () -> ignore (Uint16.of_int (0x10000)))
@@ -203,16 +203,16 @@ module Uint16_test = struct
 
   let add_int_overflow () =
     Alcotest.(check (pair uint16 bool) "add 0xFFFF 1 overflows"
-                (0, true)
-                Uint16.(add (of_int 0xFFFF) 1)) ;
+                (Uint16.zero, true)
+                Uint16.(add (of_int 0xFFFF) (of_int 1))) ;
     Alcotest.(check (pair uint16 bool) "succ 0xFFFF overflows"
-                (0, true)
+                (Uint16.zero, true)
                 Uint16.(succ (of_int 0xFFFF))) ;
     Alcotest.(check (pair uint16 bool) "add 0x8000 0x8000 overflows"
-                (0, true)
+                (Uint16.zero, true)
                 Uint16.(add (of_int 0x8000) (of_int 0x8000))) ;
     Alcotest.(check (pair uint16 bool) "add 0x8000 0x7FFF no overflow"
-                (0xFFFF, false)
+                (Uint16.of_int 0xFFFF, false)
                 Uint16.(add (of_int 0x8000) (of_int 0x7FFF)))
 
   let mul_ints () =
@@ -229,26 +229,26 @@ module Uint16_test = struct
 
   let mul_int_overflow () =
     Alcotest.(check (pair uint16 bool) "mul 0xFFFF 2 overflows"
-                (0xFFFE, true)
-                Uint16.(mul (of_int 0xFFFF) 2)) ;
+                (Uint16.of_int 0xFFFE, true)
+                Uint16.(mul (of_int 0xFFFF) (Uint16.of_int 2))) ;
     Alcotest.(check (pair uint16 bool) "mul 0x3FFF 2 no overflow"
-                (0x7FFE, false)
-                Uint16.(mul (of_int 0x3FFF) 2)) ;
+                (Uint16.of_int 0x7FFE, false)
+                Uint16.(mul (of_int 0x3FFF) (Uint16.of_int 2))) ;
     Alcotest.(check (pair uint16 bool) "mul 0x3FFF 4 no overflow"
-                (0xFFFC, false)
-                Uint16.(mul (of_int 0x3FFF) 4)) ;
+                (Uint16.of_int 0xFFFC, false)
+                Uint16.(mul (of_int 0x3FFF) (Uint16.of_int 4))) ;
     Alcotest.(check (pair uint16 bool) "mul 0x7FFF 2 no overflow"
-                (0xFFFE, false)
-                Uint16.(mul (of_int 0x7FFF) 2)) ;
+                (Uint16.of_int 0xFFFE, false)
+                Uint16.(mul (of_int 0x7FFF) (Uint16.of_int 2))) ;
     Alcotest.(check (pair uint16 bool) "mul 0x8000 2 overflows"
-                (0, true)
-                Uint16.(mul (of_int 0x8000) 2)) ;
+                (Uint16.zero, true)
+                Uint16.(mul (of_int 0x8000) (Uint16.of_int 2))) ;
     Alcotest.(check (pair uint16 bool) "mul 0x4000 4 overflows"
-                (0, true)
-                Uint16.(mul (of_int 0x4000) 4)) ;
+                (Uint16.zero, true)
+                Uint16.(mul (of_int 0x4000) (Uint16.of_int 4))) ;
     Alcotest.(check (pair uint16 bool) "mul 0x4000 2 no overflow"
-                (0x8000, false)
-                Uint16.(mul (of_int 0x4000) 2))
+                (Uint16.of_int 0x8000, false)
+                Uint16.(mul (of_int 0x4000) (Uint16.of_int 2)))
 
   let sub_ints () =
     for _i = 0 to 1000 do
@@ -262,33 +262,33 @@ module Uint16_test = struct
 
   let sub_int_underflow () =
     Alcotest.(check (pair uint16 bool) "sub 0 1 underflows"
-                (0xFFFF, true)
-                Uint16.(sub 0 1)) ;
+                (Uint16.of_int 0xFFFF, true)
+                Uint16.(sub zero (of_int 1))) ;
     Alcotest.(check (pair uint16 bool) "pred 0 underflows"
-                (0xFFFF, true)
-                Uint16.(pred 0)) ;
+                (Uint16.of_int 0xFFFF, true)
+                Uint16.(pred zero)) ;
     Alcotest.(check (pair uint16 bool) "sub 0x8000 0x8001 underflows"
-                (0xFFFF, true)
+                (Uint16.of_int 0xFFFF, true)
                 Uint16.(sub (of_int 0x8000) (of_int 0x8001))) ;
     Alcotest.(check (pair uint16 bool) "sub 0x8000 0x7FFF is 1"
-                (1, false)
+                (Uint16.of_int 1, false)
                 Uint16.(sub (of_int 0x8000) (of_int 0x7FFF)))
 
   let compare_works () =
     Alcotest.check Alcotest.int "compare 0xFFFF 0xFFFF is 0"
       0 Uint16.(compare (of_int 0xFFFF) (of_int 0xFFFF)) ;
     Alcotest.check Alcotest.int "compare 0 0 is 0"
-      0 Uint16.(compare 0 0) ;
+      0 Uint16.(compare zero zero) ;
     Alcotest.check Alcotest.int "compare 1 1 is 0"
-      0 Uint16.(compare 1 1) ;
+      0 Uint16.(compare (of_int 1) (of_int 1)) ;
     Alcotest.check Alcotest.int "compare 0 1 is -1"
-      (-1) Uint16.(compare 0 1) ;
+      (-1) Uint16.(compare (of_int 0) (of_int 1)) ;
     Alcotest.check Alcotest.int "compare 1 0 is 1"
-      1 Uint16.(compare 1 0) ;
+      1 Uint16.(compare (of_int 1) (of_int 0)) ;
     Alcotest.check Alcotest.int "compare 0xFFFF 0 is 1"
-      1 Uint16.(compare (of_int 0xFFFF) 0) ;
+      1 Uint16.(compare (of_int 0xFFFF) zero) ;
     Alcotest.check Alcotest.int "compare 0 0xFFFF is -1"
-      (-1) Uint16.(compare 0 (of_int 0xFFFF)) ;
+      (-1) Uint16.(compare zero (of_int 0xFFFF)) ;
     Alcotest.check Alcotest.int "compare 0xFFFF 0xFFFE is 1"
       1 Uint16.(compare (of_int 0xFFFF) (of_int 0xFFFE)) ;
     Alcotest.check Alcotest.int "compare 0xFFFE 0xFFFF is -1"
@@ -300,13 +300,13 @@ module Uint16_test = struct
 
   let succ_pred_at_bound () =
     Alcotest.(check (pair uint16 bool) "succ 0x7FFF is 0x8000"
-                (0x8000, false) Uint16.(succ (of_int 0x7FFF))) ;
+                (Uint16.of_int 0x8000, false) Uint16.(succ (of_int 0x7FFF))) ;
     Alcotest.(check (pair uint16 bool) "succ 0x8000 is 0x8001"
-                (0x8001, false) Uint16.(succ (of_int 0x8000))) ;
+                (Uint16.of_int 0x8001, false) Uint16.(succ (of_int 0x8000))) ;
     Alcotest.(check (pair uint16 bool) "pred 0x8000 is 0x7FFF"
-                (0x7FFF, false) Uint16.(pred (of_int 0x8000))) ;
+                (Uint16.of_int 0x7FFF, false) Uint16.(pred (of_int 0x8000))) ;
     Alcotest.(check (pair uint16 bool) "pred 0x8001 is 0x8000"
-                (0x8000, false) Uint16.(pred (of_int 0x8001)))
+                (Uint16.of_int 0x8000, false) Uint16.(pred (of_int 0x8001)))
 
   let tests = [
     "random of_int", `Slow, of_int_r ;
@@ -345,7 +345,7 @@ module Uint32_test = struct
     done
 
   let int_bound () =
-    Alcotest.check uint32 "int 0 ok" 0l (Uint32.of_int 0) ;
+    Alcotest.check uint32 "int 0 ok" 0l Uint32.zero ;
     Alcotest.check_raises "smaller 0 raises"
       (Invalid_argument "out of range")
       (fun () -> ignore (Uint32.of_int (-1))) ;
@@ -514,7 +514,7 @@ module Uint64_test = struct
     done
 
   let int_bound () =
-    Alcotest.check uint64 "int 0 ok" 0L (Uint64.of_int 0) ;
+    Alcotest.check uint64 "int 0 ok" 0L Uint64.zero ;
     Alcotest.check_raises "smaller 0 raises"
       (Invalid_argument "out of range")
       (fun () -> ignore (Uint64.of_int (-1)))