[m-rev.] diff: setting and testing individual bits of uint8s, uint16s and uint64s

Julien Fischer jfischer at opturion.com
Sat Apr 10 03:17:26 AEST 2021


This probably doesn't require review; it's very similar to the already
commited uint32 version.

-------------------------

Setting and testing individual bits of uint8s, uint16s and uint64s.

library/uint8.m:
library/uint16.m:
library/uint64.m:
     Add functions for setting, clearing, flipping and testing
     the individual bits of a uint8, uint16 and uint64 values.

NEWS:
     Announce the new functions.

tests/hard_coded/Mmakefile:
tests/hard_coded/bit_access_uint{8,16,64}.{m,exp}:
     Add a test case.

Julien.
-------------- next part --------------
diff --git a/NEWS b/NEWS
index 66f8243bb..c085c2254 100644
--- a/NEWS
+++ b/NEWS
@@ -296,6 +296,16 @@ Changes to the Mercury standard library
     - func `rotate_right/2`
     - func `unchecked_rotate_left/2`
     - func `unchecked_rotate_right/2`
+    - func `set_bit/2`
+    - func `unchecked_set_bit/2`
+    - func `clear_bit/2`
+    - func `unchecked_clear_bit/2`
+    - func `flip_bit/2`
+    - func `unchecked_flip_bit/2`
+    - func `bit_is_set/2`
+    - func `unchecked_bit_is_set/2`
+    - func `bit_is_clear/2`
+    - func `unchecked_bit_is_clear/2`
 
 ### Changes to the `uint32` module
 
@@ -324,6 +334,16 @@ Changes to the Mercury standard library
     - func `rotate_right/2`
     - func `unchecked_rotate_left/2`
     - func `unchecked_rotate_right/2`
+    - func `set_bit/2`
+    - func `unchecked_set_bit/2`
+    - func `clear_bit/2`
+    - func `unchecked_clear_bit/2`
+    - func `flip_bit/2`
+    - func `unchecked_flip_bit/2`
+    - func `bit_is_set/2`
+    - func `unchecked_bit_is_set/2`
+    - func `bit_is_clear/2`
+    - func `unchecked_bit_is_clear/2`
 
 ### Changes to the `uint8` module
 
@@ -333,6 +353,16 @@ Changes to the Mercury standard library
     - func `rotate_right/2`
     - func `unchecked_rotate_left/2`
     - func `unchecked_rotate_right/2`
+    - func `set_bit/2`
+    - func `unchecked_set_bit/2`
+    - func `clear_bit/2`
+    - func `unchecked_clear_bit/2`
+    - func `flip_bit/2`
+    - func `unchecked_flip_bit/2`
+    - func `bit_is_set/2`
+    - func `unchecked_bit_is_set/2`
+    - func `bit_is_clear/2`
+    - func `unchecked_bit_is_clear/2`
 
 ### Changes to the `varset` module
 
diff --git a/library/uint16.m b/library/uint16.m
index 06cd2ada7..32792500d 100644
--- a/library/uint16.m
+++ b/library/uint16.m
@@ -1,7 +1,7 @@
 %---------------------------------------------------------------------------%
 % vim: ts=4 sw=4 et ft=mercury
 %---------------------------------------------------------------------------%
-% Copyright (C) 2017-2018 The Mercury team.
+% Copyright (C) 2017-2021 The Mercury team.
 % This file is distributed under the terms specified in COPYING.LIB.
 %---------------------------------------------------------------------------%
 %
@@ -341,7 +341,7 @@
     % rotate_left(U, D) = N:
     %
     % N is the value obtained by rotating the binary representation of U
-    % left by D bits. Throws an exception if D is not in [0, 15].
+    % left by D bits. Throws an exception if D is not in the range [0, 15].
     %
 :- func rotate_left(uint16, uint) = uint16.
 
@@ -355,7 +355,7 @@
     % rotate_right(U, D) = N:
     %
     % N is the value obtained by rotating the binary representation of U
-    % right by D bits. Throws an exception if D is not in [0, 15].
+    % right by D bits. Throws an exception if D is not in the range [0, 15].
     %
 :- func rotate_right(uint16, uint) = uint16.
 
@@ -366,6 +366,66 @@
     %
 :- func unchecked_rotate_right(uint16, uint) = uint16.
 
+    % set_bit(U, I) = N:
+    % N is the value obtained by setting the I'th bit (the bit worth 2^I) of U
+    % to one. An exception is thrown if I is not in the range [0, 15].
+    %
+:- func set_bit(uint16, uint) = uint16.
+
+    % unchecked_set_bit(U, I) = N:
+    % As above, but the behaviour is undefined if I is not in the range
+    % [0, 15].
+    %
+:- func unchecked_set_bit(uint16, uint) = uint16.
+
+    % clear_bit(U, I) = N:
+    % N is the value obtained by setting the I'th bit (the bit worth 2^I) of U
+    % to zero. An exception is thrown if I is not in the range [0, 15].
+    %
+:- func clear_bit(uint16, uint) = uint16.
+
+    % unchecked_clear_bit(U, I) = N:
+    % As above, but the behaviour is undefined if I is not in the range
+    % [0, 15].
+    %
+:- func unchecked_clear_bit(uint16, uint) = uint16.
+
+    % flip_bit(U, I) = N:
+    % N is the value obtained by flipping the I'th bit (the bit worth 2^I) of
+    % U. An exception is thrown if I is not in the range [0, 15].
+    %
+:- func flip_bit(uint16, uint) = uint16.
+
+    % unchecked_flip_bit(U, I) = N:
+    % As above, but the behaviour is undefined if I is not in the range
+    % [0, 15].
+    %
+:- func unchecked_flip_bit(uint16, uint) = uint16.
+
+    % bit_is_set(U, I):
+    % True iff the I'th bit (the bit worth 2^I) of U is one.
+    % An exception is thrown if I is not in the range [0, 15].
+    %
+:- pred bit_is_set(uint16::in, uint::in) is semidet.
+
+    % unchecked_bit_is_set(U, I):
+    % As above, but the behaviour is undefined if I is not in the range
+    % [0, 15].
+    %
+:- pred unchecked_bit_is_set(uint16::in, uint::in) is semidet.
+
+    % bit_is_clear(U, I):
+    % True iff the I'th bit (the bit worth 2^I) of U is zero.
+    % An exception is thrown if I is not in the range [0, 15].
+    %
+:- pred bit_is_clear(uint16::in, uint::in) is semidet.
+
+    % unchecked_bit_is_clear(U, I):
+    % As above, but the behaviour is undefined if I is not in the range
+    % [0, 15].
+    %
+:- pred unchecked_bit_is_clear(uint16::in, uint::in) is semidet.
+
 %---------------------------------------------------------------------------%
 %
 % Limits.
@@ -859,6 +919,58 @@ rotate_right(X, N) =
 
 %---------------------------------------------------------------------------%
 
+set_bit(U, I) =
+    ( if I < 16u then
+        unchecked_set_bit(U, I)
+    else
+        func_error($pred, "bit index exceeds 15 bits")
+    ).
+
+unchecked_set_bit(U, I) =
+    U \/ (1u16 `unchecked_left_shift` cast_to_int(I)).
+
+clear_bit(U, I) =
+    ( if I < 16u then
+        unchecked_clear_bit(U, I)
+    else
+        func_error($pred, "bit index exceeds 15 bits")
+    ).
+
+unchecked_clear_bit(U, I) =
+    U /\ (\ (1u16 `unchecked_left_shift` cast_to_int(I))).
+
+flip_bit(U, I) =
+    ( if I < 16u then
+        unchecked_flip_bit(U, I)
+    else
+        func_error($pred, "bit index exceeds 15 bits")
+    ).
+
+unchecked_flip_bit(U, I) =
+    U `xor` (1u16 `unchecked_left_shift` cast_to_int(I)).
+
+bit_is_set(U, I) :-
+    ( if I < 16u then
+        unchecked_bit_is_set(U, I)
+    else
+        error($pred, "bit index exceeds 15 bits")
+    ).
+
+unchecked_bit_is_set(U, I) :-
+    U /\ (1u16 `unchecked_left_shift` cast_to_int(I)) \= 0u16.
+
+bit_is_clear(U, I) :-
+    ( if I < 16u then
+        unchecked_bit_is_clear(U, I)
+    else
+        error($pred, "bit index exceeds 15 bits")
+    ).
+
+unchecked_bit_is_clear(U, I) :-
+    U /\ (1u16 `unchecked_left_shift` cast_to_int(I)) = 0u16.
+
+%---------------------------------------------------------------------------%
+
 max_uint16 = 65_535_u16.
 
 %---------------------------------------------------------------------------%
diff --git a/library/uint64.m b/library/uint64.m
index d276018a3..c9bdb8116 100644
--- a/library/uint64.m
+++ b/library/uint64.m
@@ -313,7 +313,7 @@
     % rotate_left(U, D) = N:
     %
     % N is the value obtained by rotating the binary representation of U
-    % left by D bits. Throws an exception if D is not in [0, 63].
+    % left by D bits. Throws an exception if D is not in the range [0, 63].
     %
 :- func rotate_left(uint64, uint) = uint64.
 
@@ -327,7 +327,7 @@
     % rotate_right(U, D) = N:
     %
     % N is the value obtained by rotating the binary representation of U
-    % right by D bits. Throws an exception if D is not in [0, 63].
+    % right by D bits. Throws an exception if D is not in the range [0, 63].
     %
 :- func rotate_right(uint64, uint) = uint64.
 
@@ -338,6 +338,66 @@
     %
 :- func unchecked_rotate_right(uint64, uint) = uint64.
 
+    % set_bit(U, I) = N:
+    % N is the value obtained by setting the I'th bit (the bit worth 2^I) of U
+    % to one. An exception is thrown if I is not in the range [0, 63].
+    %
+:- func set_bit(uint64, uint) = uint64.
+
+    % unchecked_set_bit(U, I) = N:
+    % As above, but the behaviour is undefined if I is not in the range
+    % [0, 63].
+    %
+:- func unchecked_set_bit(uint64, uint) = uint64.
+
+    % clear_bit(U, I) = N:
+    % N is the value obtained by setting the I'th bit (the bit worth 2^I) of U
+    % to zero. An exception is thrown if I is not in the range [0, 63].
+    %
+:- func clear_bit(uint64, uint) = uint64.
+
+    % unchecked_clear_bit(U, I) = N:
+    % As above, but the behaviour is undefined if I is not in the range
+    % [0, 63].
+    %
+:- func unchecked_clear_bit(uint64, uint) = uint64.
+
+    % flip_bit(U, I) = N:
+    % N is the value obtained by flipping the I'th bit (the bit worth 2^I) of
+    % U. An exception is thrown if I is not in the range [0, 63].
+    %
+:- func flip_bit(uint64, uint) = uint64.
+
+    % unchecked_flip_bit(U, I) = N:
+    % As above, but the behaviour is undefined if I is not in the range
+    % [0, 63].
+    %
+:- func unchecked_flip_bit(uint64, uint) = uint64.
+
+    % bit_is_set(U, I):
+    % True iff the I'th bit (the bit worth 2^I) of U is one.
+    % An exception is thrown if I is not in the range [0, 63].
+    %
+:- pred bit_is_set(uint64::in, uint::in) is semidet.
+
+    % unchecked_bit_is_set(U, I):
+    % As above, but the behaviour is undefined if I is not in the range
+    % [0, 63].
+    %
+:- pred unchecked_bit_is_set(uint64::in, uint::in) is semidet.
+
+    % bit_is_clear(U, I):
+    % True iff the I'th bit (the bit worth 2^I) of U is zero.
+    % An exception is thrown if I is not in the range [0, 63].
+    %
+:- pred bit_is_clear(uint64::in, uint::in) is semidet.
+
+    % unchecked_bit_is_clear(U, I):
+    % As above, but the behaviour is undefined if I is not in the range
+    % [0, 63].
+    %
+:- pred unchecked_bit_is_clear(uint64::in, uint::in) is semidet.
+
 %---------------------------------------------------------------------------%
 %
 % Limits.
@@ -892,6 +952,58 @@ rotate_right(X, N) =
 
 %---------------------------------------------------------------------------%
 
+set_bit(U, I) =
+    ( if I < 64u then
+        unchecked_set_bit(U, I)
+    else
+        func_error($pred, "bit index exceeds 63 bits")
+    ).
+
+unchecked_set_bit(U, I) =
+    U \/ (1u64 `unchecked_left_shift` cast_to_int(I)).
+
+clear_bit(U, I) =
+    ( if I < 64u then
+        unchecked_clear_bit(U, I)
+    else
+        func_error($pred, "bit index exceeds 63 bits")
+    ).
+
+unchecked_clear_bit(U, I) =
+    U /\ (\ (1u64 `unchecked_left_shift` cast_to_int(I))).
+
+flip_bit(U, I) =
+    ( if I < 64u then
+        unchecked_flip_bit(U, I)
+    else
+        func_error($pred, "bit index exceeds 63 bits")
+    ).
+
+unchecked_flip_bit(U, I) =
+    U `xor` (1u64 `unchecked_left_shift` cast_to_int(I)).
+
+bit_is_set(U, I) :-
+    ( if I < 64u then
+        unchecked_bit_is_set(U, I)
+    else
+        error($pred, "bit index exceeds 63 bits")
+    ).
+
+unchecked_bit_is_set(U, I) :-
+    U /\ (1u64 `unchecked_left_shift` cast_to_int(I)) \= 0u64.
+
+bit_is_clear(U, I) :-
+    ( if I < 64u then
+        unchecked_bit_is_clear(U, I)
+    else
+        error($pred, "bit index exceeds 63 bits")
+    ).
+
+unchecked_bit_is_clear(U, I) :-
+    U /\ (1u64 `unchecked_left_shift` cast_to_int(I)) = 0u64.
+
+%---------------------------------------------------------------------------%
+
 max_uint64 = 18_446_744_073_709_551_615_u64.
 
 %---------------------------------------------------------------------------%
diff --git a/library/uint8.m b/library/uint8.m
index bb3279056..109b2efa1 100644
--- a/library/uint8.m
+++ b/library/uint8.m
@@ -1,7 +1,7 @@
 %---------------------------------------------------------------------------%
 % vim: ts=4 sw=4 et ft=mercury
 %---------------------------------------------------------------------------%
-% Copyright (C) 2017-2018 The Mercury team.
+% Copyright (C) 2017-2021 The Mercury team.
 % This file is distributed under the terms specified in COPYING.LIB.
 %---------------------------------------------------------------------------%
 %
@@ -294,7 +294,7 @@
     % rotate_left(U, D) = N:
     %
     % N is the value obtained by rotating the binary representation of U
-    % left by D bits. Throws an exception if D is not in [0, 7].
+    % left by D bits. Throws an exception if D is not in the range [0, 7].
     %
 :- func rotate_left(uint8, uint) = uint8.
 
@@ -308,7 +308,7 @@
     % rotate_right(U, D) = N:
     %
     % N is the value obtained by rotating the binary representation of U
-    % right by D bits. Throws an exception if D is not in [0, 7].
+    % right by D bits. Throws an exception if D is not in the range [0, 7].
     %
 :- func rotate_right(uint8, uint) = uint8.
 
@@ -319,6 +319,66 @@
     %
 :- func unchecked_rotate_right(uint8, uint) = uint8.
 
+    % set_bit(U, I) = N:
+    % N is the value obtained by setting the I'th bit (the bit worth 2^I) of U
+    % to one. An exception is thrown if I is not in the range [0, 7].
+    %
+:- func set_bit(uint8, uint) = uint8.
+
+    % unchecked_set_bit(U, I) = N:
+    % As above, but the behaviour is undefined if I is not in the range
+    % [0, 7].
+    %
+:- func unchecked_set_bit(uint8, uint) = uint8.
+
+    % clear_bit(U, I) = N:
+    % N is the value obtained by setting the I'th bit (the bit worth 2^I) of U
+    % to zero. An exception is thrown if I is not in the range [0, 7].
+    %
+:- func clear_bit(uint8, uint) = uint8.
+
+    % unchecked_clear_bit(U, I) = N:
+    % As above, but the behaviour is undefined if I is not in the range
+    % [0, 7].
+    %
+:- func unchecked_clear_bit(uint8, uint) = uint8.
+
+    % flip_bit(U, I) = N:
+    % N is the value obtained by flipping the I'th bit (the bit worth 2^I) of
+    % U. An exception is thrown if I is not in the range [0, 7].
+    %
+:- func flip_bit(uint8, uint) = uint8.
+
+    % unchecked_flip_bit(U, I) = N:
+    % As above, but the behaviour is undefined if I is not in the range
+    % [0, 7].
+    %
+:- func unchecked_flip_bit(uint8, uint) = uint8.
+
+    % bit_is_set(U, I):
+    % True iff the I'th bit (the bit worth 2^I) of U is one.
+    % An exception is thrown if I is not in the range [0, 7].
+    %
+:- pred bit_is_set(uint8::in, uint::in) is semidet.
+
+    % unchecked_bit_is_set(U, I):
+    % As above, but the behaviour is undefined if I is not in the range
+    % [0, 7].
+    %
+:- pred unchecked_bit_is_set(uint8::in, uint::in) is semidet.
+
+    % bit_is_clear(U, I):
+    % True iff the I'th bit (the bit worth 2^I) of U is zero.
+    % An exception is thrown if I is not in the range [0, 7].
+    %
+:- pred bit_is_clear(uint8::in, uint::in) is semidet.
+
+    % unchecked_bit_is_clear(U, I):
+    % As above, but the behaviour is undefined if I is not in the range
+    % [0, 7].
+    %
+:- pred unchecked_bit_is_clear(uint8::in, uint::in) is semidet.
+
 %---------------------------------------------------------------------------%
 %
 % Limits.
@@ -872,6 +932,58 @@ rotate_right(X, N) =
 
 %---------------------------------------------------------------------------%
 
+set_bit(U, I) =
+    ( if I < 8u then
+        unchecked_set_bit(U, I)
+    else
+        func_error($pred, "bit index exceeds 7 bits")
+    ).
+
+unchecked_set_bit(U, I) =
+    U \/ (1u8 `unchecked_left_shift` cast_to_int(I)).
+
+clear_bit(U, I) =
+    ( if I < 8u then
+        unchecked_clear_bit(U, I)
+    else
+        func_error($pred, "bit index exceeds 7 bits")
+    ).
+
+unchecked_clear_bit(U, I) =
+    U /\ (\ (1u8 `unchecked_left_shift` cast_to_int(I))).
+
+flip_bit(U, I) =
+    ( if I < 8u then
+        unchecked_flip_bit(U, I)
+    else
+        func_error($pred, "bit index exceeds 7 bits")
+    ).
+
+unchecked_flip_bit(U, I) =
+    U `xor` (1u8 `unchecked_left_shift` cast_to_int(I)).
+
+bit_is_set(U, I) :-
+    ( if I < 8u then
+        unchecked_bit_is_set(U, I)
+    else
+        error($pred, "bit index exceeds 7 bits")
+    ).
+
+unchecked_bit_is_set(U, I) :-
+    U /\ (1u8 `unchecked_left_shift` cast_to_int(I)) \= 0u8.
+
+bit_is_clear(U, I) :-
+    ( if I < 8u then
+        unchecked_bit_is_clear(U, I)
+    else
+        error($pred, "bit index exceeds 7 bits")
+    ).
+
+unchecked_bit_is_clear(U, I) :-
+    U /\ (1u8 `unchecked_left_shift` cast_to_int(I)) = 0u8.
+
+%---------------------------------------------------------------------------%
+
 max_uint8 = 255_u8.
 
 %---------------------------------------------------------------------------%
diff --git a/tests/hard_coded/Mmakefile b/tests/hard_coded/Mmakefile
index d12ce07af..3d9947225 100644
--- a/tests/hard_coded/Mmakefile
+++ b/tests/hard_coded/Mmakefile
@@ -746,7 +746,10 @@ ifeq "$(findstring profdeep,$(GRADE))" ""
 		arith_uint32 \
 		arith_uint64 \
 		arith_uint8 \
+		bit_access_uint16 \
 		bit_access_uint32 \
+		bit_access_uint64 \
+		bit_access_uint8 \
 		bitmap_bytes \
 		bitmap_empty \
 		bitmap_test \
diff --git a/tests/hard_coded/bit_access_uint16.exp b/tests/hard_coded/bit_access_uint16.exp
index e69de29bb..292a12c4b 100644
--- a/tests/hard_coded/bit_access_uint16.exp
+++ b/tests/hard_coded/bit_access_uint16.exp
@@ -0,0 +1,123 @@
+*** Test operation 'set_bit' ***
+
+set_bit(0000000000000000, 0 ) = 0000000000000001
+set_bit(0000000000000000, 1 ) = 0000000000000010
+set_bit(0000000000000000, 2 ) = 0000000000000100
+set_bit(0000000000000000, 7 ) = 0000000010000000
+set_bit(0000000000000000, 15) = 1000000000000000
+set_bit(0000000000000000, 16) = <<exception>>
+set_bit(1111111111111111, 0 ) = 1111111111111111
+set_bit(1111111111111111, 1 ) = 1111111111111111
+set_bit(1111111111111111, 2 ) = 1111111111111111
+set_bit(1111111111111111, 7 ) = 1111111111111111
+set_bit(1111111111111111, 15) = 1111111111111111
+set_bit(1111111111111111, 16) = <<exception>>
+
+*** Test operation 'clear_bit' ***
+
+clear_bit(0000000000000000, 0 ) = 0000000000000000
+clear_bit(0000000000000000, 1 ) = 0000000000000000
+clear_bit(0000000000000000, 2 ) = 0000000000000000
+clear_bit(0000000000000000, 7 ) = 0000000000000000
+clear_bit(0000000000000000, 15) = 0000000000000000
+clear_bit(0000000000000000, 16) = <<exception>>
+clear_bit(1111111111111111, 0 ) = 1111111111111110
+clear_bit(1111111111111111, 1 ) = 1111111111111101
+clear_bit(1111111111111111, 2 ) = 1111111111111011
+clear_bit(1111111111111111, 7 ) = 1111111101111111
+clear_bit(1111111111111111, 15) = 0111111111111111
+clear_bit(1111111111111111, 16) = <<exception>>
+
+*** Test operation 'flip_bit' ***
+
+flip_bit(0000000000000000, 0 ) = 0000000000000001
+flip_bit(0000000000000000, 1 ) = 0000000000000010
+flip_bit(0000000000000000, 2 ) = 0000000000000100
+flip_bit(0000000000000000, 7 ) = 0000000010000000
+flip_bit(0000000000000000, 15) = 1000000000000000
+flip_bit(0000000000000000, 16) = <<exception>>
+flip_bit(1111111111111111, 0 ) = 1111111111111110
+flip_bit(1111111111111111, 1 ) = 1111111111111101
+flip_bit(1111111111111111, 2 ) = 1111111111111011
+flip_bit(1111111111111111, 7 ) = 1111111101111111
+flip_bit(1111111111111111, 15) = 0111111111111111
+flip_bit(1111111111111111, 16) = <<exception>>
+
+*** Test operation 'bit_is_set' ***
+
+bit_is_set(0000000000000000, 0 ) ==> false
+bit_is_set(0000000000000000, 1 ) ==> false
+bit_is_set(0000000000000000, 2 ) ==> false
+bit_is_set(0000000000000000, 7 ) ==> false
+bit_is_set(0000000000000000, 15) ==> false
+bit_is_set(0000000000000000, 16) ==> <<exception>>
+bit_is_set(0000000000000001, 0 ) ==> true
+bit_is_set(0000000000000001, 1 ) ==> false
+bit_is_set(0000000000000001, 2 ) ==> false
+bit_is_set(0000000000000001, 7 ) ==> false
+bit_is_set(0000000000000001, 15) ==> false
+bit_is_set(0000000000000001, 16) ==> <<exception>>
+bit_is_set(0000000000000010, 0 ) ==> false
+bit_is_set(0000000000000010, 1 ) ==> true
+bit_is_set(0000000000000010, 2 ) ==> false
+bit_is_set(0000000000000010, 7 ) ==> false
+bit_is_set(0000000000000010, 15) ==> false
+bit_is_set(0000000000000010, 16) ==> <<exception>>
+bit_is_set(0000000011111111, 0 ) ==> true
+bit_is_set(0000000011111111, 1 ) ==> true
+bit_is_set(0000000011111111, 2 ) ==> true
+bit_is_set(0000000011111111, 7 ) ==> true
+bit_is_set(0000000011111111, 15) ==> false
+bit_is_set(0000000011111111, 16) ==> <<exception>>
+bit_is_set(0111111111111111, 0 ) ==> true
+bit_is_set(0111111111111111, 1 ) ==> true
+bit_is_set(0111111111111111, 2 ) ==> true
+bit_is_set(0111111111111111, 7 ) ==> true
+bit_is_set(0111111111111111, 15) ==> false
+bit_is_set(0111111111111111, 16) ==> <<exception>>
+bit_is_set(1111111111111111, 0 ) ==> true
+bit_is_set(1111111111111111, 1 ) ==> true
+bit_is_set(1111111111111111, 2 ) ==> true
+bit_is_set(1111111111111111, 7 ) ==> true
+bit_is_set(1111111111111111, 15) ==> true
+bit_is_set(1111111111111111, 16) ==> <<exception>>
+
+*** Test operation 'bit_is_clear' ***
+
+bit_is_clear(0000000000000000, 0 ) ==> true
+bit_is_clear(0000000000000000, 1 ) ==> true
+bit_is_clear(0000000000000000, 2 ) ==> true
+bit_is_clear(0000000000000000, 7 ) ==> true
+bit_is_clear(0000000000000000, 15) ==> true
+bit_is_clear(0000000000000000, 16) ==> <<exception>>
+bit_is_clear(0000000000000001, 0 ) ==> false
+bit_is_clear(0000000000000001, 1 ) ==> true
+bit_is_clear(0000000000000001, 2 ) ==> true
+bit_is_clear(0000000000000001, 7 ) ==> true
+bit_is_clear(0000000000000001, 15) ==> true
+bit_is_clear(0000000000000001, 16) ==> <<exception>>
+bit_is_clear(0000000000000010, 0 ) ==> true
+bit_is_clear(0000000000000010, 1 ) ==> false
+bit_is_clear(0000000000000010, 2 ) ==> true
+bit_is_clear(0000000000000010, 7 ) ==> true
+bit_is_clear(0000000000000010, 15) ==> true
+bit_is_clear(0000000000000010, 16) ==> <<exception>>
+bit_is_clear(0000000011111111, 0 ) ==> false
+bit_is_clear(0000000011111111, 1 ) ==> false
+bit_is_clear(0000000011111111, 2 ) ==> false
+bit_is_clear(0000000011111111, 7 ) ==> false
+bit_is_clear(0000000011111111, 15) ==> true
+bit_is_clear(0000000011111111, 16) ==> <<exception>>
+bit_is_clear(0111111111111111, 0 ) ==> false
+bit_is_clear(0111111111111111, 1 ) ==> false
+bit_is_clear(0111111111111111, 2 ) ==> false
+bit_is_clear(0111111111111111, 7 ) ==> false
+bit_is_clear(0111111111111111, 15) ==> true
+bit_is_clear(0111111111111111, 16) ==> <<exception>>
+bit_is_clear(1111111111111111, 0 ) ==> false
+bit_is_clear(1111111111111111, 1 ) ==> false
+bit_is_clear(1111111111111111, 2 ) ==> false
+bit_is_clear(1111111111111111, 7 ) ==> false
+bit_is_clear(1111111111111111, 15) ==> false
+bit_is_clear(1111111111111111, 16) ==> <<exception>>
+
diff --git a/tests/hard_coded/bit_access_uint16.m b/tests/hard_coded/bit_access_uint16.m
index e69de29bb..006e1c1c4 100644
--- a/tests/hard_coded/bit_access_uint16.m
+++ b/tests/hard_coded/bit_access_uint16.m
@@ -0,0 +1,173 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
+%---------------------------------------------------------------------------%
+
+% Test look ups and setting of individual bits for uint16s.
+
+:- module bit_access_uint16.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is cc_multi.
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module uint16.
+
+:- import_module exception.
+:- import_module list.
+:- import_module string.
+
+%---------------------------------------------------------------------------%
+
+main(!IO) :-
+    run_modify_test(uint16.set_bit, "set_bit", !IO),
+    io.nl(!IO),
+    run_modify_test(uint16.clear_bit, "clear_bit", !IO),
+    io.nl(!IO),
+    run_modify_test(uint16.flip_bit, "flip_bit", !IO),
+    io.nl(!IO),
+    run_value_test(uint16.bit_is_set, "bit_is_set", !IO),
+    io.nl(!IO),
+    run_value_test(uint16.bit_is_clear, "bit_is_clear", !IO),
+    io.nl(!IO).
+
+%---------------------------------------------------------------------------%
+
+:- pred run_modify_test((func(uint16, uint) = uint16)::in, string::in,
+    io::di, io::uo) is cc_multi.
+
+run_modify_test(Func, Desc, !IO) :-
+    io.format("*** Test operation '%s' ***\n\n", [s(Desc)], !IO),
+    list.foldl(run_modify_on_input(Func, Desc), modify_numbers, !IO).
+
+:- pred run_modify_on_input((func(uint16, uint) = uint16)::in, string::in,
+    uint16::in, io::di, io::uo) is cc_multi.
+
+run_modify_on_input(Func, Desc, U, !IO) :-
+    list.foldl(run_modify_on_input_at_index(Func, Desc, U), bit_indexes, !IO).
+
+:- pred run_modify_on_input_at_index((func(uint16, uint) = uint16)::in, string::in,
+    uint16::in, uint::in, io::di, io::uo) is cc_multi.
+
+run_modify_on_input_at_index(Func, Desc, U, I, !IO) :-
+    ( try []
+        Result0 = Func(U, I)
+    then
+        ResultStr = to_binary_string_lz(Result0)
+    catch_any _ ->
+        ResultStr = "<<exception>>"
+    ),
+    io.format("%s(%s, %-2u) = %s\n",
+        [s(Desc),
+        s(to_binary_string_lz(U)),
+        u(I),
+        s(ResultStr)], !IO).
+
+%---------------------------------------------------------------------------%
+
+:- pred run_value_test(pred(uint16, uint)::in(pred(in, in) is semidet),
+    string::in, io::di, io::uo) is cc_multi.
+
+run_value_test(Pred, Desc, !IO) :-
+    io.format("*** Test operation '%s' ***\n\n", [s(Desc)], !IO),
+    list.foldl(run_value_on_input(Pred, Desc), test_numbers, !IO).
+
+:- pred run_value_on_input(pred(uint16, uint)::in(pred(in, in) is semidet),
+    string::in, uint16::in, io::di, io::uo) is cc_multi.
+
+run_value_on_input(Pred, Desc, U, !IO) :-
+    list.foldl(run_value_on_input_at_index(Pred, Desc, U), bit_indexes, !IO).
+
+:- pred run_value_on_input_at_index(pred(uint16, uint)::in(pred(in, in) is semidet),
+    string::in, uint16::in, uint::in, io::di, io::uo) is cc_multi.
+
+run_value_on_input_at_index(Pred, Desc, U, I, !IO) :-
+    ( try []
+        Pred(U, I)
+    then
+        ResultStr = "true"
+    else
+        ResultStr = "false"
+    catch_any _ ->
+        ResultStr = "<<exception>>"
+    ),
+    io.format("%s(%s, %-2u) ==> %s\n",
+        [s(Desc),
+        s(to_binary_string_lz(U)),
+        u(I),
+        s(ResultStr)], !IO).
+
+%---------------------------------------------------------------------------%
+
+:- func modify_numbers = list(uint16).
+
+modify_numbers = [
+   0_u16,
+   65_535_u16
+].
+
+:- func test_numbers = list(uint16).
+
+test_numbers = [
+    0_u16,
+    1_u16,
+    2_u16,
+    255_u16,
+    32767_u16,
+    65_535_u16
+].
+
+:- func bit_indexes = list(uint).
+
+bit_indexes = [
+   0_u,
+   1_u,
+   2_u,
+   7_u,
+   15_u,
+   16_u
+].
+
+%---------------------------------------------------------------------------%
+
+:- func to_binary_string_lz(uint16::in) = (string::uo) is det.
+
+:- pragma foreign_proc("C",
+    to_binary_string_lz(U::in) = (S::uo),
+    [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+    int i = 16;
+
+    MR_allocate_aligned_string_msg(S, 16, MR_ALLOC_ID);
+    S[16] = '\\0';
+    while (i > 0) {
+        i--;
+        S[i] = (U & 1) ? '1' : '0';
+        U = U >> 1;
+    }
+").
+
+:- pragma foreign_proc("C#",
+    to_binary_string_lz(U::in) = (S::uo),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    S = System.Convert.ToString(U, 2).PadLeft(16, '0');
+").
+
+:- pragma foreign_proc("Java",
+    to_binary_string_lz(U::in) = (S::uo),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    S = java.lang.String.format(""%16s"",
+        java.lang.Integer.toBinaryString(U & 0xffff)).replace(' ', '0');
+").
+
+%---------------------------------------------------------------------------%
+:- end_module bit_access_uint16.
+%---------------------------------------------------------------------------%
+
diff --git a/tests/hard_coded/bit_access_uint64.exp b/tests/hard_coded/bit_access_uint64.exp
index e69de29bb..7bb3036a8 100644
--- a/tests/hard_coded/bit_access_uint64.exp
+++ b/tests/hard_coded/bit_access_uint64.exp
@@ -0,0 +1,135 @@
+*** Test operation 'set_bit' ***
+
+set_bit(0000000000000000000000000000000000000000000000000000000000000000, 0 ) = 0000000000000000000000000000000000000000000000000000000000000001
+set_bit(0000000000000000000000000000000000000000000000000000000000000000, 1 ) = 0000000000000000000000000000000000000000000000000000000000000010
+set_bit(0000000000000000000000000000000000000000000000000000000000000000, 2 ) = 0000000000000000000000000000000000000000000000000000000000000100
+set_bit(0000000000000000000000000000000000000000000000000000000000000000, 31) = 0000000000000000000000000000000010000000000000000000000000000000
+set_bit(0000000000000000000000000000000000000000000000000000000000000000, 63) = 1000000000000000000000000000000000000000000000000000000000000000
+set_bit(0000000000000000000000000000000000000000000000000000000000000000, 64) = <<exception>>
+set_bit(1111111111111111111111111111111111111111111111111111111111111111, 0 ) = 1111111111111111111111111111111111111111111111111111111111111111
+set_bit(1111111111111111111111111111111111111111111111111111111111111111, 1 ) = 1111111111111111111111111111111111111111111111111111111111111111
+set_bit(1111111111111111111111111111111111111111111111111111111111111111, 2 ) = 1111111111111111111111111111111111111111111111111111111111111111
+set_bit(1111111111111111111111111111111111111111111111111111111111111111, 31) = 1111111111111111111111111111111111111111111111111111111111111111
+set_bit(1111111111111111111111111111111111111111111111111111111111111111, 63) = 1111111111111111111111111111111111111111111111111111111111111111
+set_bit(1111111111111111111111111111111111111111111111111111111111111111, 64) = <<exception>>
+
+*** Test operation 'clear_bit' ***
+
+clear_bit(0000000000000000000000000000000000000000000000000000000000000000, 0 ) = 0000000000000000000000000000000000000000000000000000000000000000
+clear_bit(0000000000000000000000000000000000000000000000000000000000000000, 1 ) = 0000000000000000000000000000000000000000000000000000000000000000
+clear_bit(0000000000000000000000000000000000000000000000000000000000000000, 2 ) = 0000000000000000000000000000000000000000000000000000000000000000
+clear_bit(0000000000000000000000000000000000000000000000000000000000000000, 31) = 0000000000000000000000000000000000000000000000000000000000000000
+clear_bit(0000000000000000000000000000000000000000000000000000000000000000, 63) = 0000000000000000000000000000000000000000000000000000000000000000
+clear_bit(0000000000000000000000000000000000000000000000000000000000000000, 64) = <<exception>>
+clear_bit(1111111111111111111111111111111111111111111111111111111111111111, 0 ) = 1111111111111111111111111111111111111111111111111111111111111110
+clear_bit(1111111111111111111111111111111111111111111111111111111111111111, 1 ) = 1111111111111111111111111111111111111111111111111111111111111101
+clear_bit(1111111111111111111111111111111111111111111111111111111111111111, 2 ) = 1111111111111111111111111111111111111111111111111111111111111011
+clear_bit(1111111111111111111111111111111111111111111111111111111111111111, 31) = 1111111111111111111111111111111101111111111111111111111111111111
+clear_bit(1111111111111111111111111111111111111111111111111111111111111111, 63) = 0111111111111111111111111111111111111111111111111111111111111111
+clear_bit(1111111111111111111111111111111111111111111111111111111111111111, 64) = <<exception>>
+
+*** Test operation 'flip_bit' ***
+
+flip_bit(0000000000000000000000000000000000000000000000000000000000000000, 0 ) = 0000000000000000000000000000000000000000000000000000000000000001
+flip_bit(0000000000000000000000000000000000000000000000000000000000000000, 1 ) = 0000000000000000000000000000000000000000000000000000000000000010
+flip_bit(0000000000000000000000000000000000000000000000000000000000000000, 2 ) = 0000000000000000000000000000000000000000000000000000000000000100
+flip_bit(0000000000000000000000000000000000000000000000000000000000000000, 31) = 0000000000000000000000000000000010000000000000000000000000000000
+flip_bit(0000000000000000000000000000000000000000000000000000000000000000, 63) = 1000000000000000000000000000000000000000000000000000000000000000
+flip_bit(0000000000000000000000000000000000000000000000000000000000000000, 64) = <<exception>>
+flip_bit(1111111111111111111111111111111111111111111111111111111111111111, 0 ) = 1111111111111111111111111111111111111111111111111111111111111110
+flip_bit(1111111111111111111111111111111111111111111111111111111111111111, 1 ) = 1111111111111111111111111111111111111111111111111111111111111101
+flip_bit(1111111111111111111111111111111111111111111111111111111111111111, 2 ) = 1111111111111111111111111111111111111111111111111111111111111011
+flip_bit(1111111111111111111111111111111111111111111111111111111111111111, 31) = 1111111111111111111111111111111101111111111111111111111111111111
+flip_bit(1111111111111111111111111111111111111111111111111111111111111111, 63) = 0111111111111111111111111111111111111111111111111111111111111111
+flip_bit(1111111111111111111111111111111111111111111111111111111111111111, 64) = <<exception>>
+
+*** Test operation 'bit_is_set' ***
+
+bit_is_set(0000000000000000000000000000000000000000000000000000000000000000, 0 ) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000000000000, 1 ) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000000000000, 2 ) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000000000000, 31) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000000000000, 63) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000000000000, 64) ==> <<exception>>
+bit_is_set(0000000000000000000000000000000000000000000000000000000000000001, 0 ) ==> true
+bit_is_set(0000000000000000000000000000000000000000000000000000000000000001, 1 ) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000000000001, 2 ) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000000000001, 31) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000000000001, 63) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000000000001, 64) ==> <<exception>>
+bit_is_set(0000000000000000000000000000000000000000000000000000000000000010, 0 ) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000000000010, 1 ) ==> true
+bit_is_set(0000000000000000000000000000000000000000000000000000000000000010, 2 ) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000000000010, 31) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000000000010, 63) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000000000010, 64) ==> <<exception>>
+bit_is_set(0000000000000000000000000000000000000000000000000000000000001000, 0 ) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000000001000, 1 ) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000000001000, 2 ) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000000001000, 31) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000000001000, 63) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000000001000, 64) ==> <<exception>>
+bit_is_set(0000000000000000000000000000000000000000000000000000000011111111, 0 ) ==> true
+bit_is_set(0000000000000000000000000000000000000000000000000000000011111111, 1 ) ==> true
+bit_is_set(0000000000000000000000000000000000000000000000000000000011111111, 2 ) ==> true
+bit_is_set(0000000000000000000000000000000000000000000000000000000011111111, 31) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000011111111, 63) ==> false
+bit_is_set(0000000000000000000000000000000000000000000000000000000011111111, 64) ==> <<exception>>
+bit_is_set(0000000000000000000000000000000011111111111111111111111111111111, 0 ) ==> true
+bit_is_set(0000000000000000000000000000000011111111111111111111111111111111, 1 ) ==> true
+bit_is_set(0000000000000000000000000000000011111111111111111111111111111111, 2 ) ==> true
+bit_is_set(0000000000000000000000000000000011111111111111111111111111111111, 31) ==> true
+bit_is_set(0000000000000000000000000000000011111111111111111111111111111111, 63) ==> false
+bit_is_set(0000000000000000000000000000000011111111111111111111111111111111, 64) ==> <<exception>>
+bit_is_set(1111111111111111111111111111111111111111111111111111111111111111, 0 ) ==> true
+bit_is_set(1111111111111111111111111111111111111111111111111111111111111111, 1 ) ==> true
+bit_is_set(1111111111111111111111111111111111111111111111111111111111111111, 2 ) ==> true
+bit_is_set(1111111111111111111111111111111111111111111111111111111111111111, 31) ==> true
+bit_is_set(1111111111111111111111111111111111111111111111111111111111111111, 63) ==> true
+bit_is_set(1111111111111111111111111111111111111111111111111111111111111111, 64) ==> <<exception>>
+
+*** Test operation 'bit_is_clear' ***
+
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000000000, 0 ) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000000000, 1 ) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000000000, 2 ) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000000000, 31) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000000000, 63) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000000000, 64) ==> <<exception>>
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000000001, 0 ) ==> false
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000000001, 1 ) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000000001, 2 ) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000000001, 31) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000000001, 63) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000000001, 64) ==> <<exception>>
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000000010, 0 ) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000000010, 1 ) ==> false
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000000010, 2 ) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000000010, 31) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000000010, 63) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000000010, 64) ==> <<exception>>
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000001000, 0 ) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000001000, 1 ) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000001000, 2 ) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000001000, 31) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000001000, 63) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000000001000, 64) ==> <<exception>>
+bit_is_clear(0000000000000000000000000000000000000000000000000000000011111111, 0 ) ==> false
+bit_is_clear(0000000000000000000000000000000000000000000000000000000011111111, 1 ) ==> false
+bit_is_clear(0000000000000000000000000000000000000000000000000000000011111111, 2 ) ==> false
+bit_is_clear(0000000000000000000000000000000000000000000000000000000011111111, 31) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000011111111, 63) ==> true
+bit_is_clear(0000000000000000000000000000000000000000000000000000000011111111, 64) ==> <<exception>>
+bit_is_clear(0000000000000000000000000000000011111111111111111111111111111111, 0 ) ==> false
+bit_is_clear(0000000000000000000000000000000011111111111111111111111111111111, 1 ) ==> false
+bit_is_clear(0000000000000000000000000000000011111111111111111111111111111111, 2 ) ==> false
+bit_is_clear(0000000000000000000000000000000011111111111111111111111111111111, 31) ==> false
+bit_is_clear(0000000000000000000000000000000011111111111111111111111111111111, 63) ==> true
+bit_is_clear(0000000000000000000000000000000011111111111111111111111111111111, 64) ==> <<exception>>
+bit_is_clear(1111111111111111111111111111111111111111111111111111111111111111, 0 ) ==> false
+bit_is_clear(1111111111111111111111111111111111111111111111111111111111111111, 1 ) ==> false
+bit_is_clear(1111111111111111111111111111111111111111111111111111111111111111, 2 ) ==> false
+bit_is_clear(1111111111111111111111111111111111111111111111111111111111111111, 31) ==> false
+bit_is_clear(1111111111111111111111111111111111111111111111111111111111111111, 63) ==> false
+bit_is_clear(1111111111111111111111111111111111111111111111111111111111111111, 64) ==> <<exception>>
+
diff --git a/tests/hard_coded/bit_access_uint64.m b/tests/hard_coded/bit_access_uint64.m
index e69de29bb..3ff93ccf9 100644
--- a/tests/hard_coded/bit_access_uint64.m
+++ b/tests/hard_coded/bit_access_uint64.m
@@ -0,0 +1,174 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
+%---------------------------------------------------------------------------%
+
+% Test look ups and setting of individual bits for uint64s.
+
+:- module bit_access_uint64.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is cc_multi.
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module uint64.
+
+:- import_module exception.
+:- import_module list.
+:- import_module string.
+
+%---------------------------------------------------------------------------%
+
+main(!IO) :-
+    run_modify_test(uint64.set_bit, "set_bit", !IO),
+    io.nl(!IO),
+    run_modify_test(uint64.clear_bit, "clear_bit", !IO),
+    io.nl(!IO),
+    run_modify_test(uint64.flip_bit, "flip_bit", !IO),
+    io.nl(!IO),
+    run_value_test(uint64.bit_is_set, "bit_is_set", !IO),
+    io.nl(!IO),
+    run_value_test(uint64.bit_is_clear, "bit_is_clear", !IO),
+    io.nl(!IO).
+
+%---------------------------------------------------------------------------%
+
+:- pred run_modify_test((func(uint64, uint) = uint64)::in, string::in,
+    io::di, io::uo) is cc_multi.
+
+run_modify_test(Func, Desc, !IO) :-
+    io.format("*** Test operation '%s' ***\n\n", [s(Desc)], !IO),
+    list.foldl(run_modify_on_input(Func, Desc), modify_numbers, !IO).
+
+:- pred run_modify_on_input((func(uint64, uint) = uint64)::in, string::in,
+    uint64::in, io::di, io::uo) is cc_multi.
+
+run_modify_on_input(Func, Desc, U, !IO) :-
+    list.foldl(run_modify_on_input_at_index(Func, Desc, U), bit_indexes, !IO).
+
+:- pred run_modify_on_input_at_index((func(uint64, uint) = uint64)::in, string::in,
+    uint64::in, uint::in, io::di, io::uo) is cc_multi.
+
+run_modify_on_input_at_index(Func, Desc, U, I, !IO) :-
+    ( try []
+        Result0 = Func(U, I)
+    then
+        ResultStr = to_binary_string_lz(Result0)
+    catch_any _ ->
+        ResultStr = "<<exception>>"
+    ),
+    io.format("%s(%s, %-2u) = %s\n",
+        [s(Desc),
+        s(to_binary_string_lz(U)),
+        u(I),
+        s(ResultStr)], !IO).
+
+%---------------------------------------------------------------------------%
+
+:- pred run_value_test(pred(uint64, uint)::in(pred(in, in) is semidet),
+    string::in, io::di, io::uo) is cc_multi.
+
+run_value_test(Pred, Desc, !IO) :-
+    io.format("*** Test operation '%s' ***\n\n", [s(Desc)], !IO),
+    list.foldl(run_value_on_input(Pred, Desc), test_numbers, !IO).
+
+:- pred run_value_on_input(pred(uint64, uint)::in(pred(in, in) is semidet),
+    string::in, uint64::in, io::di, io::uo) is cc_multi.
+
+run_value_on_input(Pred, Desc, U, !IO) :-
+    list.foldl(run_value_on_input_at_index(Pred, Desc, U), bit_indexes, !IO).
+
+:- pred run_value_on_input_at_index(pred(uint64, uint)::in(pred(in, in) is semidet),
+    string::in, uint64::in, uint::in, io::di, io::uo) is cc_multi.
+
+run_value_on_input_at_index(Pred, Desc, U, I, !IO) :-
+    ( try []
+        Pred(U, I)
+    then
+        ResultStr = "true"
+    else
+        ResultStr = "false"
+    catch_any _ ->
+        ResultStr = "<<exception>>"
+    ),
+    io.format("%s(%s, %-2u) ==> %s\n",
+        [s(Desc),
+        s(to_binary_string_lz(U)),
+        u(I),
+        s(ResultStr)], !IO).
+
+%---------------------------------------------------------------------------%
+
+:- func modify_numbers = list(uint64).
+
+modify_numbers = [
+   0_u64,
+   18_446_744_073_709_551_615_u64
+].
+
+:- func test_numbers = list(uint64).
+
+test_numbers = [
+    0_u64,
+    1_u64,
+    2_u64,
+    8_u64,
+    255_u64,
+    4_294_967_295_u64,
+    18_446_744_073_709_551_615_u64
+].
+
+:- func bit_indexes = list(uint).
+
+bit_indexes = [
+   0_u,
+   1_u,
+   2_u,
+   31_u,
+   63_u,
+   64_u
+].
+
+%---------------------------------------------------------------------------%
+
+:- func to_binary_string_lz(uint64::in) = (string::uo) is det.
+
+:- pragma foreign_proc("C",
+    to_binary_string_lz(U::in) = (S::uo),
+    [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+    int i = 64;
+
+    MR_allocate_aligned_string_msg(S, 64, MR_ALLOC_ID);
+    S[64] = '\\0';
+    while (i > 0) {
+        i--;
+        S[i] = (U & 1) ? '1' : '0';
+        U = U >> 1;
+    }
+").
+
+:- pragma foreign_proc("C#",
+    to_binary_string_lz(U::in) = (S::uo),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    S = System.Convert.ToString((long)U, 2).PadLeft(64, '0');
+").
+
+:- pragma foreign_proc("Java",
+    to_binary_string_lz(U::in) = (S::uo),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    S = java.lang.String.format(""%64s"",
+        java.lang.Long.toBinaryString(U)).replace(' ', '0');
+").
+
+%---------------------------------------------------------------------------%
+:- end_module bit_access_uint64.
+%---------------------------------------------------------------------------%
+
diff --git a/tests/hard_coded/bit_access_uint8.exp b/tests/hard_coded/bit_access_uint8.exp
index e69de29bb..ebcbe67ce 100644
--- a/tests/hard_coded/bit_access_uint8.exp
+++ b/tests/hard_coded/bit_access_uint8.exp
@@ -0,0 +1,177 @@
+*** Test operation 'set_bit' ***
+
+set_bit(00000000, 0) = 00000001
+set_bit(00000000, 1) = 00000010
+set_bit(00000000, 2) = 00000100
+set_bit(00000000, 3) = 00001000
+set_bit(00000000, 4) = 00010000
+set_bit(00000000, 5) = 00100000
+set_bit(00000000, 6) = 01000000
+set_bit(00000000, 7) = 10000000
+set_bit(00000000, 8) = <<exception>>
+set_bit(11111111, 0) = 11111111
+set_bit(11111111, 1) = 11111111
+set_bit(11111111, 2) = 11111111
+set_bit(11111111, 3) = 11111111
+set_bit(11111111, 4) = 11111111
+set_bit(11111111, 5) = 11111111
+set_bit(11111111, 6) = 11111111
+set_bit(11111111, 7) = 11111111
+set_bit(11111111, 8) = <<exception>>
+
+*** Test operation 'clear_bit' ***
+
+clear_bit(00000000, 0) = 00000000
+clear_bit(00000000, 1) = 00000000
+clear_bit(00000000, 2) = 00000000
+clear_bit(00000000, 3) = 00000000
+clear_bit(00000000, 4) = 00000000
+clear_bit(00000000, 5) = 00000000
+clear_bit(00000000, 6) = 00000000
+clear_bit(00000000, 7) = 00000000
+clear_bit(00000000, 8) = <<exception>>
+clear_bit(11111111, 0) = 11111110
+clear_bit(11111111, 1) = 11111101
+clear_bit(11111111, 2) = 11111011
+clear_bit(11111111, 3) = 11110111
+clear_bit(11111111, 4) = 11101111
+clear_bit(11111111, 5) = 11011111
+clear_bit(11111111, 6) = 10111111
+clear_bit(11111111, 7) = 01111111
+clear_bit(11111111, 8) = <<exception>>
+
+*** Test operation 'flip_bit' ***
+
+flip_bit(00000000, 0) = 00000001
+flip_bit(00000000, 1) = 00000010
+flip_bit(00000000, 2) = 00000100
+flip_bit(00000000, 3) = 00001000
+flip_bit(00000000, 4) = 00010000
+flip_bit(00000000, 5) = 00100000
+flip_bit(00000000, 6) = 01000000
+flip_bit(00000000, 7) = 10000000
+flip_bit(00000000, 8) = <<exception>>
+flip_bit(11111111, 0) = 11111110
+flip_bit(11111111, 1) = 11111101
+flip_bit(11111111, 2) = 11111011
+flip_bit(11111111, 3) = 11110111
+flip_bit(11111111, 4) = 11101111
+flip_bit(11111111, 5) = 11011111
+flip_bit(11111111, 6) = 10111111
+flip_bit(11111111, 7) = 01111111
+flip_bit(11111111, 8) = <<exception>>
+
+*** Test operation 'bit_is_set' ***
+
+bit_is_set(00000000, 0) ==> false
+bit_is_set(00000000, 1) ==> false
+bit_is_set(00000000, 2) ==> false
+bit_is_set(00000000, 3) ==> false
+bit_is_set(00000000, 4) ==> false
+bit_is_set(00000000, 5) ==> false
+bit_is_set(00000000, 6) ==> false
+bit_is_set(00000000, 7) ==> false
+bit_is_set(00000000, 8) ==> <<exception>>
+bit_is_set(00000001, 0) ==> true
+bit_is_set(00000001, 1) ==> false
+bit_is_set(00000001, 2) ==> false
+bit_is_set(00000001, 3) ==> false
+bit_is_set(00000001, 4) ==> false
+bit_is_set(00000001, 5) ==> false
+bit_is_set(00000001, 6) ==> false
+bit_is_set(00000001, 7) ==> false
+bit_is_set(00000001, 8) ==> <<exception>>
+bit_is_set(00000010, 0) ==> false
+bit_is_set(00000010, 1) ==> true
+bit_is_set(00000010, 2) ==> false
+bit_is_set(00000010, 3) ==> false
+bit_is_set(00000010, 4) ==> false
+bit_is_set(00000010, 5) ==> false
+bit_is_set(00000010, 6) ==> false
+bit_is_set(00000010, 7) ==> false
+bit_is_set(00000010, 8) ==> <<exception>>
+bit_is_set(00001000, 0) ==> false
+bit_is_set(00001000, 1) ==> false
+bit_is_set(00001000, 2) ==> false
+bit_is_set(00001000, 3) ==> true
+bit_is_set(00001000, 4) ==> false
+bit_is_set(00001000, 5) ==> false
+bit_is_set(00001000, 6) ==> false
+bit_is_set(00001000, 7) ==> false
+bit_is_set(00001000, 8) ==> <<exception>>
+bit_is_set(01111111, 0) ==> true
+bit_is_set(01111111, 1) ==> true
+bit_is_set(01111111, 2) ==> true
+bit_is_set(01111111, 3) ==> true
+bit_is_set(01111111, 4) ==> true
+bit_is_set(01111111, 5) ==> true
+bit_is_set(01111111, 6) ==> true
+bit_is_set(01111111, 7) ==> false
+bit_is_set(01111111, 8) ==> <<exception>>
+bit_is_set(11111111, 0) ==> true
+bit_is_set(11111111, 1) ==> true
+bit_is_set(11111111, 2) ==> true
+bit_is_set(11111111, 3) ==> true
+bit_is_set(11111111, 4) ==> true
+bit_is_set(11111111, 5) ==> true
+bit_is_set(11111111, 6) ==> true
+bit_is_set(11111111, 7) ==> true
+bit_is_set(11111111, 8) ==> <<exception>>
+
+*** Test operation 'bit_is_clear' ***
+
+bit_is_clear(00000000, 0) ==> true
+bit_is_clear(00000000, 1) ==> true
+bit_is_clear(00000000, 2) ==> true
+bit_is_clear(00000000, 3) ==> true
+bit_is_clear(00000000, 4) ==> true
+bit_is_clear(00000000, 5) ==> true
+bit_is_clear(00000000, 6) ==> true
+bit_is_clear(00000000, 7) ==> true
+bit_is_clear(00000000, 8) ==> <<exception>>
+bit_is_clear(00000001, 0) ==> false
+bit_is_clear(00000001, 1) ==> true
+bit_is_clear(00000001, 2) ==> true
+bit_is_clear(00000001, 3) ==> true
+bit_is_clear(00000001, 4) ==> true
+bit_is_clear(00000001, 5) ==> true
+bit_is_clear(00000001, 6) ==> true
+bit_is_clear(00000001, 7) ==> true
+bit_is_clear(00000001, 8) ==> <<exception>>
+bit_is_clear(00000010, 0) ==> true
+bit_is_clear(00000010, 1) ==> false
+bit_is_clear(00000010, 2) ==> true
+bit_is_clear(00000010, 3) ==> true
+bit_is_clear(00000010, 4) ==> true
+bit_is_clear(00000010, 5) ==> true
+bit_is_clear(00000010, 6) ==> true
+bit_is_clear(00000010, 7) ==> true
+bit_is_clear(00000010, 8) ==> <<exception>>
+bit_is_clear(00001000, 0) ==> true
+bit_is_clear(00001000, 1) ==> true
+bit_is_clear(00001000, 2) ==> true
+bit_is_clear(00001000, 3) ==> false
+bit_is_clear(00001000, 4) ==> true
+bit_is_clear(00001000, 5) ==> true
+bit_is_clear(00001000, 6) ==> true
+bit_is_clear(00001000, 7) ==> true
+bit_is_clear(00001000, 8) ==> <<exception>>
+bit_is_clear(01111111, 0) ==> false
+bit_is_clear(01111111, 1) ==> false
+bit_is_clear(01111111, 2) ==> false
+bit_is_clear(01111111, 3) ==> false
+bit_is_clear(01111111, 4) ==> false
+bit_is_clear(01111111, 5) ==> false
+bit_is_clear(01111111, 6) ==> false
+bit_is_clear(01111111, 7) ==> true
+bit_is_clear(01111111, 8) ==> <<exception>>
+bit_is_clear(11111111, 0) ==> false
+bit_is_clear(11111111, 1) ==> false
+bit_is_clear(11111111, 2) ==> false
+bit_is_clear(11111111, 3) ==> false
+bit_is_clear(11111111, 4) ==> false
+bit_is_clear(11111111, 5) ==> false
+bit_is_clear(11111111, 6) ==> false
+bit_is_clear(11111111, 7) ==> false
+bit_is_clear(11111111, 8) ==> <<exception>>
+
diff --git a/tests/hard_coded/bit_access_uint8.m b/tests/hard_coded/bit_access_uint8.m
index e69de29bb..0c64304c1 100644
--- a/tests/hard_coded/bit_access_uint8.m
+++ b/tests/hard_coded/bit_access_uint8.m
@@ -0,0 +1,177 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
+%---------------------------------------------------------------------------%
+
+% Test look ups and setting of individual bits for uint8s.
+
+:- module bit_access_uint8.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is cc_multi.
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module uint8.
+
+:- import_module exception.
+:- import_module list.
+:- import_module string.
+
+%---------------------------------------------------------------------------%
+
+main(!IO) :-
+    run_modify_test(uint8.set_bit, "set_bit", !IO),
+    io.nl(!IO),
+    run_modify_test(uint8.clear_bit, "clear_bit", !IO),
+    io.nl(!IO),
+    run_modify_test(uint8.flip_bit, "flip_bit", !IO),
+    io.nl(!IO),
+    run_value_test(uint8.bit_is_set, "bit_is_set", !IO),
+    io.nl(!IO),
+    run_value_test(uint8.bit_is_clear, "bit_is_clear", !IO),
+    io.nl(!IO).
+
+%---------------------------------------------------------------------------%
+
+:- pred run_modify_test((func(uint8, uint) = uint8)::in, string::in,
+    io::di, io::uo) is cc_multi.
+
+run_modify_test(Func, Desc, !IO) :-
+    io.format("*** Test operation '%s' ***\n\n", [s(Desc)], !IO),
+    list.foldl(run_modify_on_input(Func, Desc), modify_numbers, !IO).
+
+:- pred run_modify_on_input((func(uint8, uint) = uint8)::in, string::in,
+    uint8::in, io::di, io::uo) is cc_multi.
+
+run_modify_on_input(Func, Desc, U, !IO) :-
+    list.foldl(run_modify_on_input_at_index(Func, Desc, U), bit_indexes, !IO).
+
+:- pred run_modify_on_input_at_index((func(uint8, uint) = uint8)::in, string::in,
+    uint8::in, uint::in, io::di, io::uo) is cc_multi.
+
+run_modify_on_input_at_index(Func, Desc, U, I, !IO) :-
+    ( try []
+        Result0 = Func(U, I)
+    then
+        ResultStr = to_binary_string_lz(Result0)
+    catch_any _ ->
+        ResultStr = "<<exception>>"
+    ),
+    io.format("%s(%s, %u) = %s\n",
+        [s(Desc),
+        s(to_binary_string_lz(U)),
+        u(I),
+        s(ResultStr)], !IO).
+
+%---------------------------------------------------------------------------%
+
+:- pred run_value_test(pred(uint8, uint)::in(pred(in, in) is semidet),
+    string::in, io::di, io::uo) is cc_multi.
+
+run_value_test(Pred, Desc, !IO) :-
+    io.format("*** Test operation '%s' ***\n\n", [s(Desc)], !IO),
+    list.foldl(run_value_on_input(Pred, Desc), test_numbers, !IO).
+
+:- pred run_value_on_input(pred(uint8, uint)::in(pred(in, in) is semidet),
+    string::in, uint8::in, io::di, io::uo) is cc_multi.
+
+run_value_on_input(Pred, Desc, U, !IO) :-
+    list.foldl(run_value_on_input_at_index(Pred, Desc, U), bit_indexes, !IO).
+
+:- pred run_value_on_input_at_index(pred(uint8, uint)::in(pred(in, in) is semidet),
+    string::in, uint8::in, uint::in, io::di, io::uo) is cc_multi.
+
+run_value_on_input_at_index(Pred, Desc, U, I, !IO) :-
+    ( try []
+        Pred(U, I)
+    then
+        ResultStr = "true"
+    else
+        ResultStr = "false"
+    catch_any _ ->
+        ResultStr = "<<exception>>"
+    ),
+    io.format("%s(%s, %u) ==> %s\n",
+        [s(Desc),
+        s(to_binary_string_lz(U)),
+        u(I),
+        s(ResultStr)], !IO).
+
+%---------------------------------------------------------------------------%
+
+:- func modify_numbers = list(uint8).
+
+modify_numbers = [
+   0_u8,
+   255_u8
+].
+
+:- func test_numbers = list(uint8).
+
+test_numbers = [
+    0_u8,
+    1_u8,
+    2_u8,
+    8_u8,
+    127_u8,
+    255_u8
+].
+
+:- func bit_indexes = list(uint).
+
+bit_indexes = [
+   0_u,
+   1_u,
+   2_u,
+   3_u,
+   4_u,
+   5_u,
+   6_u,
+   7_u,
+   8_u
+].
+
+%---------------------------------------------------------------------------%
+
+:- func to_binary_string_lz(uint8::in) = (string::uo) is det.
+
+:- pragma foreign_proc("C",
+    to_binary_string_lz(U::in) = (S::uo),
+    [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+    int i = 8;
+
+    MR_allocate_aligned_string_msg(S, 8, MR_ALLOC_ID);
+    S[8] = '\\0';
+    while (i > 0) {
+        i--;
+        S[i] = (U & 1) ? '1' : '0';
+        U = U >> 1;
+    }
+").
+
+:- pragma foreign_proc("C#",
+    to_binary_string_lz(U::in) = (S::uo),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    S = System.Convert.ToString(U, 2).PadLeft(8, '0');
+").
+
+:- pragma foreign_proc("Java",
+    to_binary_string_lz(U::in) = (S::uo),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    S = java.lang.String.format(""%8s"",
+        java.lang.Integer.toBinaryString(U & 0xff)).replace(' ', '0');
+").
+
+
+%---------------------------------------------------------------------------%
+:- end_module bit_access_uint8.
+%---------------------------------------------------------------------------%
+


More information about the reviews mailing list