[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