-
Notifications
You must be signed in to change notification settings - Fork 208
Description
Both C++ and Java define a bitset type, so I propose that the standard
library also have a module implementing a bitset type. My first draft
for a public API for that module is as follows.
The module name is STDLIB_BITSETS.
The module exports one constant, BITS_KIND, to be used as a KIND
value in addressing bits in the bitset. This will initially be
INT32.
The module exports one derived type, BITSETS, with a plural name so
that users can name their scalar realizations as BITSET. The type
will contain two private components: BITS a scalar integer of kind
BITS_KIND giving the number of bits in a bitset entity, and a rank
one allocatable integer array BLOCK of private kind BLOCK_KIND,
that will be INT32, to be used in holding the bit values. The type
has an ASSIGNMENT(=) operation defined.
BITSETS will have the following procedures: ALL, AND, AND_NOT,
ANY_BIT, BIT_COUNT, BITS, CLEAR, EOR, EQUIV, EXTRACT,
FLIP, INIT, INPUT, MAX_SET_BIT, NONE, OR, OUTPUT,
PRINT_BITSET, READ_BITSET, SET, TEST, and VALUE. Some of
these procedures will be overloaded:
interface clear
module procedure clear_bit, clear_range
end interface clear
interface flip
module procedure flip_bit, flip_range
end interface flip
interface init
module procedure init_copy, init_zero
end interface init
interface set
module procedure set_bit, set_range
end interface set
interface print_bitset
module procedure print_bitset_string, print_bitset_unit
end interface print_bitset
interface read_bitset
module procedure read_bitset_string, read_bitset_unit
end interface read_bitset
The API for the individual procedures is listed below. The following
aspects of the API may be controversial:
-
How the range is defined for
CLEAR_RANGE,FLIP_RANGE, and
SET_RANGE. I have roughly followed Java's bitset here. -
That the first argument is modified in
AND,AND_NOT,EOR, and
OR. That is how it is done in the Java bitset, but I can see
having a function that returns the result rather than a subroutine
that modifies the first argument. -
That the I/O procedures
INPUT,OUTPUT,PRINT_BITSET, and
READ_BITSEThaveSTATUSflags. -
That the procedures often ignore user specification of positions
outside the range 0 toBITS-1. An alternative is to make the
procedures impure and invokingERROR STOP. Another option is to
add aSTATUSargument, but I am reluctant to do that for a simple
user error. -
The names of some of the procedures could be more similar to the
names of Fortran's bit intrinsics.
subroutine init_copy(set, aset, bits)
: Creates the bitset SET, of size BITS if present, otherwise of the
size of ASET. All bits in the range of ASET are copied from ASET. If
BITS is present and larger than the size of ASET then all additional
bits are zero.
subroutine init_zero(set, bits)
: Creates the bitset, SET, of size BITS, with all bits initialized to
zero. BITS must be non-negative.
elemental function all_bits( set )
: Returns .TRUE. if all bits in SET are 1, .FALSE. otherwise.
elemental subroutine and(set1, set2)
: Sets the bits in SET1 to the bitwise AND of the original bits in
SET1 and SET2. If SET1 has fewer bits than SET2 then the
additional bits in SET2 are ignored. If SET1 has more bits than
SET2, then the absent SET2 bits are treated as if present with
zero value.
elemental subroutine and_not(set1, set2)
: Sets the bits in SET1 to the bitwise and of the original bits in
SET1 with the bitwise negation of SET2. If SET1 has fewer bits
than SET2 then the additional bits in SET2 are ignored. If SET1
has more bits, then the absent SET2 bits are treated as if present
with zero value.
elemental function any_bit(set)
: Returns .TRUE. if any bit in SET is 1, .FALSE. otherwise
elemental function bit_count(set)
: Returns the number of non-zero bits in SET.
elemental function bits(set)
: Returns the number of bit positions in SET.
elemental subroutine clear_bit(set, pos)
: Sets to zero the POS position in SET. If POS is less than zero
or greater than BITS(SET)-1 it is ignored.
pure subroutine clear_range(set, start_pos, stop_pos)
: Sets to zero all bits from the START_POS to STOP_POS positions in
SET. If STOP_POS < START_POS then no bits are modified. Positions
outside the range 0 to BITS(SET)-1 are ignored.
elemental subroutine eor(set1, set2)
: Sets the bits in SET1 to the bitwise EOR of the original bits in
SET1 and SET2. If SET1 has fewer bits than SET2 then the
additional bits in SET2 are ignored. If SET1 has more bits than
SET2, then the absent SET2 bits are treated as if present with
zero value.
elemental function equiv(set1, set2)
: Returns .TRUE. if all bits in SET1 and SET2 have the same
value, .FALSE. otherwise. If the sets differ in size a value true
will be returned if and only if the sets are equivalent in the
overlapping range, and all bits outside the overlapping range are
zero.
pure function extract(set, start_pos, stop_pos)
: Creates a new bitset from a range, START_POS to STOP_POS, in
bitset SET.
elemental subroutine flip_bit(set, pos)
: Flips the value at the POS position in SET, provided the
position is valid. If POS is less than 0 or greater than
BITS(SET)-1, then no value is changed.
pure subroutine flip_range(set, start_pos, stop_pos)
: Flips all valid bits from the START_POS to STOP_POS positions in
SET. If STOP_POS < START_POS no bits are flipped. Positions less
than 0 or greater than BITS(SET)-1 are ignored.
subroutine input(unit, set, status)
: Reads the components of the bitset, SET, from the logical unit,
UNIT, assuming that the components were written using OUTPUT.
elemental function max_set_bit( set )
: Returns the maximum position with a set bit. If no bit is set
returns -1.
elemental function none(set)
: Returns .TRUE. if none of the bits in SET have the value 1.
elemental subroutine or(set1, set2)
: Sets the bits in SET1 to the bitwise OR of the original bits in
SET1 and SET2. If SET1 has fewer bits than SET2 then the
additional bits in SET2 are ignored. If SET1 has more bits than
SET2, then the absent SET2 bits are treated as if present with
zero value.
subroutine output(unit, set, status)
: Writes the components of the bitset, SET, to the logical unit,
UNIT, in a unformatted sequence compatible with INPUT.
subroutine print_bitset_string(string, set)
: Writes a BITSETS literal to the allocatable default character
STRING, representing the individual bit values in the bitsets,
SET.
subroutine print_bitset_unit(unit, set, status, advance)
: Writes a bitsets literal to the logical unit, UNIT, representing
the individual bit values in the bitsets, SET. If STATUS is not
present and an error occurs then processing stops with an error
message. If STATUS is present then it has the error code SUCCESS
if no error occurs, has the value ALLOC_FAULT if failure is due to
the allocation of a temporary and, has the value WRITE_FAULT if an
error occurs in the write to the unit. By default or if ADVANCE is
present with the value 'YES', advancing output is used. If ADVANCE
is present with the value 'NO', then the current record is not
advanced by the write.
subroutine read_bitset_string(string, set, status)
: Uses the bitsets literal in the default character STRING, to
define the bitset, SET. The literal may be preceded by an an
arbitrary sequence of blank characters. If STATUS is not present
then an error results in the sending an error message to ERROR_UNIT
and the termination of the program. If STATUS is present then it has
the error code SUCCESS if no error occurs, the value
INVALID_STRING if the sequence of characters after an initial
sequence of blanks is not a BITSETS literal, the value
INVALID_ARRAY_SIZE if the literal's bit size is too large to be
represented by the bit size integer kind, the value ALLOC_FAULT if
allocation of SET failed for the specified BITSIZE, or
INVALID_INTEGER if the HEX literal constant is too large to be
represented by a bit size binary integer. If STATUS is present with
the value SUCCESS then SET is defined, otherwise it is not
defined.
subroutine read_bitset_unit(unit, set, status)
: Uses the bitsets literal at the current position in the formatted
file with logical unit, UNIT, to define the bitset, SET. The
literal may be preceded by an an arbitrary sequence of blank
characters. If STATUS is not present then an error results in the
sending an error message to ERROR_UNIT and the termination of the
program. If STATUS is present then it has the error code SUCCESS
if no error occurs, the value INVALID_STRING if the sequence of
characters after an initial sequence of blanks is not a BITSETS
literal, the value INVALID_ARRAY_SIZE if the literal's bitsize is
too large to be represented by the bitsize integer kind, the value
ALLOC_FAULT if allocation of SET failed for the specified bitsize,
or INVALID_INTEGER if the HEX literal constant is too large to be
represented by a bitsize binary integer. If STATUS is present with
the value SUCCESS then SET is defined, otherwise it is not
defined.
elemental subroutine set_bit(set, pos)
: Sets the value at the POS position in SET, provided the position
is valid. If the position is less than 0 or greater than BITS(SET)-1
then SET is unchanged.
pure subroutine set_range(set, start_pos, stop_pos)
: Sets all valid bits to 1 from the START_POS to the STOP_POS
positions in SET. If STOP_POS < START_POS no bits are
changed. Positions outside the range 0 to BITS(SET)-1 are ignored.
elemental function test(set, pos)
: Returns .TRUE. if the POS position is set, .FALSE.
otherwise. If POS is negative or greater than BITS(SET) - 1 the
result is .FALSE..
elemental function value(set, pos)
: Returns 1 if the POS position is set, 0 otherwise. If POS is
negative or greater than BITS(SET) - 1 the result is 0.