Skip to content

Commit 9fce674

Browse files
committed
Add API doc-strings, improve docs and README
1 parent 103cc6a commit 9fce674

File tree

4 files changed

+186
-47
lines changed

4 files changed

+186
-47
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010

1111
## Documentation
1212

13-
A Julia package for bit and register operations. This is mainly intended
14-
for Julia code that needs to talk to hardware (with a register-based
15-
memory model) or work with intricate binary data formats.
13+
BitOperations is a Julia package for bit and register operations. It is mainly
14+
intended for Julia code that needs to communicate with hardware (e.g. with a
15+
register-based memory model) or work with intricate binary data formats.
1616

1717
* [Documentation for stable version](https://oschulz.github.io/BitOperations.jl/stable)
1818
* [Documentation for development version](https://oschulz.github.io/BitOperations.jl/dev)

docs/src/index.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,24 @@
11
# BitOperations.jl
2+
3+
BitOperations is a Julia package for bit and register operations. It is mainly
4+
intended for Julia code that needs to communicate with hardware (e.g. with a
5+
register-based memory model) or work with intricate binary data formats.
6+
7+
While bit-manipulation operations are typically easy to implement on-the-fly,
8+
using a set of library functions (as provided by this package) improves code
9+
readability and reduces the potential for errors.
10+
11+
BitOperations.jl conventions:
12+
13+
* Bit indices start at zero: `bmask(Int, 0) == 0x01`, `bmask(Int, 1) == 0x02`.
14+
15+
16+
## Provided functions
17+
18+
Basic bit operations:
19+
20+
[`bsizeof`](@ref), [`bmask`](@ref), [`lsbmask`](@ref), [`msbmask`](@ref), [`bget`](@ref), [`bset`](@ref), [`bclear`](@ref), [`bflip`](@ref), [`lsbget`](@ref), [`msbget`](@ref)
21+
22+
Zigzag encoding/decoding (Google Protocol Buffers compatible):
23+
24+
[`zigzagenc`](@ref), [`zigzagdec`](@ref)

src/bitops.jl

Lines changed: 145 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,203 @@
11
# This file is a part of BitOperations.jl, licensed under the MIT License (MIT).
22

33

4-
export BitCount
4+
"""
5+
BitOperations.BitCount = Union{Signed, Unsigned}
6+
7+
A number of bits or the index of a bit.
8+
"""
59
const BitCount = Union{Signed, Unsigned}
610

7-
function bsizeof end
8-
export bsizeof
911

10-
function bmask end
11-
export bmask
1212

13-
function lsbmask end
14-
export lsbmask
15-
16-
function msbmask end
17-
export msbmask
18-
19-
function bget end
20-
export bget
21-
22-
function bset end
23-
export bset
24-
25-
function bclear end
26-
export bclear
13+
@inline fbc(::Type{T}, x) where {T} = x%unsigned(T)
14+
@inline fbc(::Type{T}, bits::UnitRange{U}) where {T,U} = fbc(T, bits.start):fbc(T, bits.stop)
2715

28-
function bflip end
29-
export bflip
3016

31-
function lsbget end
32-
export lsbget
33-
34-
function msbget end
35-
export msbget
17+
function bsizeof end
18+
export bsizeof
3619

20+
"""
21+
bsizeof(x)
3722
38-
@inline fbc(::Type{T}, x) where {T} = x%unsigned(T)
39-
@inline fbc(::Type{T}, bits::UnitRange{U}) where {T,U} = fbc(T, bits.start):fbc(T, bits.stop)
23+
Returns the data size of x in bits.
24+
"""
25+
@inline bsizeof(x) = sizeof(x) << 3
4026

4127

42-
@inline bsizeof(x) = sizeof(x) << 3
28+
function bmask end
29+
export bmask
4330

31+
"""
32+
bmask(::Type{T}, bit::Integer)::T where {T<:Integer}
4433
34+
Generates a bit mask of type `T` with bit `bit` set to one.
35+
"""
4536
@inline bmask(::Type{T}, bit::BitCount) where {T<:Integer} = one(T) << fbc(T, bit)
4637

47-
@inline bmask(::Type{T}, bits::UnitRange{U}) where {T<:Integer,U<:BitCount} = begin
38+
"""
39+
bmask(::Type{T}, bits::UnitRange{<:Integer})::T where {T<:Integer}
40+
41+
Generates a bit mask of type `T` with bit-range `bits` set to one.
42+
"""
43+
@inline bmask(::Type{T}, bits::UnitRange{<:BitCount}) where {T<:Integer} = begin
4844
fbits = fbc(T, bits)
4945
#@assert fbits.stop >= fbits.start "Bitmask range of fbits can't be reverse"
5046
((one(T) << (fbits.stop - fbits.start + 1)) - one(T)) << fbits.start
5147
end
5248

5349

54-
@inline lsbmask(::Type{T}) where {T<:Integer} = one(T)
50+
function lsbmask end
51+
export lsbmask
5552

56-
@inline msbmask(::Type{T}) where {T<:Integer} = one(T) << fbc(T, bsizeof(T) - 1)
53+
"""
54+
lsbmask(::Type{T})::T where {T<:Integer}
55+
56+
Generates a bit mask with only the least significant bit set.
57+
"""
58+
@inline lsbmask(::Type{T}) where {T<:Integer} = one(T)
5759

60+
"""
61+
lsbmask(::Type{T}, nbits::Integer)::T where {T<:Integer}
5862
63+
Generates a bit mask with only the `nbits` least significant bits set.
64+
"""
5965
@inline lsbmask(::Type{T}, nbits::BitCount) where {T<:Integer} = ~(~zero(T) << fbc(T, nbits))
6066

67+
68+
function msbmask end
69+
export msbmask
70+
71+
"""
72+
msbmask(::Type{T})::T where {T<:Integer}
73+
74+
Generates a bit mask with only the most significant bit set.
75+
"""
76+
@inline msbmask(::Type{T}) where {T<:Integer} = one(T) << fbc(T, bsizeof(T) - 1)
77+
78+
"""
79+
msbmask(::Type{T}, nbits::Integer)::T where {T<:Integer}
80+
81+
Generates a bit mask with only the `nbits` most significant bits set.
82+
"""
6183
@inline msbmask(::Type{T}, nbits::BitCount) where {T<:Integer} = ~(~zero(T) >>> fbc(T, nbits))
6284

6385

64-
@inline bget(x::T, bit::BitCount) where {T<:Integer} = x & bmask(typeof(x), fbc(T, bit)) != zero(typeof(x))
86+
function bget end
87+
export bget
6588

66-
@inline bset(x::T, bit::BitCount, y::Bool) where {T<:Integer} = y ? bset(x, fbc(T, bit)) : bclear(x, fbc(T, bit))
67-
@inline bset(x::T, bit::BitCount) where {T<:Integer} = x | bmask(typeof(x), fbc(T, bit))
89+
"""
90+
bget(x::T, bit::Integer)::Bool where {T<:Integer}
6891
69-
@inline bclear(x::T, bit::BitCount) where {T<:Integer} = x & ~bmask(typeof(x), fbc(T, bit))
92+
Get the value of bit `bit` of x.
93+
"""
94+
@inline bget(x::T, bit::BitCount) where {T<:Integer} = x & bmask(typeof(x), fbc(T, bit)) != zero(typeof(x))
7095

96+
"""
97+
bget(x::T, bits::UnitRange{<:Integer})::T where {T<:Integer}
7198
72-
@inline bget(x::T, bits::UnitRange{U}) where {T<:Integer,U<:BitCount} = begin
99+
Get the value of the bit range `bits` of x.
100+
"""
101+
@inline bget(x::T, bits::UnitRange{<:BitCount}) where {T<:Integer} = begin
73102
fbits = fbc(T, bits)
74103
(x & bmask(typeof(x), fbits)) >>> fbits.start
75104
end
76105

77-
@inline bset(x::T, bits::UnitRange{U}, y::Integer) where {T<:Integer,U<:BitCount} = begin
106+
107+
function bset end
108+
export bset
109+
110+
"""
111+
bset(x::T, bit::Integer)::T where {T<:Integer}
112+
113+
Returns a modified copy of x, with bit `bit` set (to one).
114+
"""
115+
@inline bset(x::T, bit::BitCount) where {T<:Integer} = x | bmask(typeof(x), fbc(T, bit))
116+
117+
"""
118+
bset(x::T, bit::Integer, y::Bool)::T where {T<:Integer}
119+
120+
Returns a modified copy of x, with bit `bit` set to `y`.
121+
"""
122+
@inline bset(x::T, bit::BitCount, y::Bool) where {T<:Integer} = y ? bset(x, fbc(T, bit)) : bclear(x, fbc(T, bit))
123+
124+
"""
125+
bset(x::T, bits::UnitRange{<:Integer}, y::Integer)::T where {T<:Integer}
126+
127+
Returns a modified copy of x, with bit range `bits` set to `y`.
128+
"""
129+
@inline bset(x::T, bits::UnitRange{<:BitCount}, y::Integer) where {T<:Integer} = begin
78130
fbits = fbc(T, bits)
79131
local bm = bmask(typeof(x), fbits)
80132
(x & ~bm) | ((convert(typeof(x), y) << fbits.start) & bm)
81133
end
82134

83135

136+
function bclear end
137+
export bclear
138+
139+
"""
140+
bclear(x::T, bit::Integer)::T where {T<:Integer}
141+
142+
Returns a modified copy of x, with bit `bit` cleared (set to zero).
143+
"""
144+
@inline bclear(x::T, bit::BitCount) where {T<:Integer} = x & ~bmask(typeof(x), fbc(T, bit))
145+
146+
147+
148+
function bflip end
149+
export bflip
150+
151+
"""
152+
bflip(x::T, bit::Integer)::T where {T<:Integer}
153+
154+
Returns a modified copy of x, with bit `bit` flipped.
155+
"""
84156
@inline bflip(x::T, bit::BitCount) where {T<:Integer} = xor(x, bmask(typeof(x), fbc(T, bit)))
85157

86-
@inline bflip(x::T, bits::UnitRange{U}) where {T<:Integer,U<:BitCount} = xor(x, bmask(typeof(x), fbc(T, bits)))
158+
"""
159+
bflip(x::T, bits::UnitRange{<:Integer})::T where {T<:Integer}
160+
161+
Returns a modified copy of x, with all bits in bit range `bits` flipped.
162+
"""
163+
@inline bflip(x::T, bits::UnitRange{<:BitCount}) where {T<:Integer} = xor(x, bmask(typeof(x), fbc(T, bits)))
164+
165+
166+
function lsbget end
167+
export lsbget
87168

169+
"""
170+
lsbget(x::Integer)::Bool
88171
172+
Returns the value of the least significant bit of x.
173+
"""
89174
@inline lsbget(x::T) where {T<:Integer} =
90175
x & lsbmask(typeof(x)) != zero(typeof(x))
91176

92-
@inline msbget(x::T) where {T<:Integer} =
93-
x & msbmask(typeof(x)) != zero(typeof(x))
94-
177+
"""
178+
lsbget(x::T)::T where {T <: Integer}
95179
180+
Returns the value of the `nbits` least significant bits of x.
181+
"""
96182
@inline lsbget(x::T, nbits::BitCount) where {T<:Integer} =
97183
x & lsbmask(typeof(x), fbc(T, nbits))
98184

185+
186+
function msbget end
187+
export msbget
188+
189+
"""
190+
msbget(x::T)::Bool where {T<:Integer}
191+
192+
Returns the value of the most significant bit of x.
193+
"""
194+
@inline msbget(x::T) where {T<:Integer} =
195+
x & msbmask(typeof(x)) != zero(typeof(x))
196+
197+
"""
198+
msbget(x::T)::T where {T<:Integer}
199+
200+
Returns the value of the `nbits` most significant bits of x.
201+
"""
99202
@inline msbget(x::T, nbits::BitCount) where {T<:Integer} =
100203
x >>> (bsizeof(x) - fbc(T, nbits))

src/zigzagzenc.jl

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
11
# This file is a part of BitOperations.jl, licensed under the MIT License (MIT).
22

3-
export zigzagenc
4-
export zigzagdec
3+
"""
4+
zigzagenc(x::Signed)::Unsigned
55
6+
Zigzag-encode x, Google Protocol Buffers compatible.
7+
"""
8+
function zigzagenc end
9+
export zigzagenc
610

711
@inline zigzagenc(x::Signed) = unsigned(xor((x << 1), (x >> (8 * sizeof(x) - 1))))
812

13+
14+
"""
15+
zigzagdec(x::Unsigned)::Signed
16+
17+
Zigzag-decode x, Google Protocol Buffers compatible.
18+
"""
19+
function zigzagdec end
20+
export zigzagdec
21+
922
@inline zigzagdec(x::Unsigned) = signed(xor((x >>> 1), (-(x & 1))))

0 commit comments

Comments
 (0)