-
Notifications
You must be signed in to change notification settings - Fork 1
/
BooleanByte.cs
102 lines (94 loc) · 3.18 KB
/
BooleanByte.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
using System;
namespace BoolByte
{
/// <summary>
/// Wrapper for a single byte that can be addressed on a per-bit level.
/// </summary>
/// <remarks>
/// Useful for memory critical applications, such as tile data in a game, where large amounts of boolean values
/// need to be stored, without using an entire byte for each. This allows a single byte to contain 8 easily addressable
/// boolean values.
///
/// Copyright (c) 2014 Cyral
/// </remarks>
/// <example>
/// BooleanByte data = new BooleanByte();
/// data[2] = true; //Underlying byte now equals 0010000
/// data[7] = true; //Underlying byte now equals 0010001
/// bool foo = data[2]; //True
/// bool bar = data[1]; //False
/// </example>
/// <see cref="https://github.com/Cyral/BooleanByte/"/>
public struct BooleanByte
{
/// <summary>
/// Gets or sets the boolean value (bit) at the index
/// </summary>
/// <param name="index">The bit of the byte (0-7)</param>
/// <returns>The boolean value of the bit</returns>
public bool this[int index]
{
get
{
return GetBit(index);
}
set
{
SetBit(index, value);
}
}
/// <summary>
/// The raw underlying byte that is used for containg each bit
/// </summary>
public byte Raw
{
get { return data; }
set { data = value; }
}
private byte data; //Backing store
/// <summary>
/// Sets the boolean value to the specified index
/// </summary>
/// <param name="index">The bit of the byte to set (0-7)</param>
/// <param name="value">The boolean value to set the bit as</param>
public void SetBit(int index, bool value)
{
//Validation
if (index >= 8 && index < 0)
throw new ArgumentOutOfRangeException("Index must refer to a bit, 0-7.");
if (value)
{
//Left-shift 1, then bitwise OR
data = (byte)(data | (1 << index));
}
else
{
//Left-shift 1, then take complement, then bitwise AND
data = (byte)(data & ~(1 << index));
}
}
/// <summary>
/// Gets the bit at the specified index
/// </summary>
/// <param name="index">The bit of the byte to return (0-7)</param>
/// <returns>The boolean value of the bit</returns>
public bool GetBit(int index)
{
//Validation
if (index >= 8 && index < 0)
throw new ArgumentOutOfRangeException("Index must refer to a bit, 0-7.");
//Left-shift 1, then bitwise AND, then check for non-zero
return ((data & (1 << index)) != 0);
}
public override bool Equals(object obj)
{
if (obj is BooleanByte)
return data == ((BooleanByte)obj).data;
return false;
}
public override int GetHashCode()
{
return data.GetHashCode();
}
}
}