summaryrefslogtreecommitdiff
path: root/Runtime/mecanim/bitset.h
blob: 841e269dfe836c78f603eb09de078f2f971291c1 (plain)
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#pragma once


#include "Runtime/mecanim/defs.h"
#include "Runtime/mecanim/types.h"

namespace mecanim
{
	template <uint32_t Bits> class bitset
	{
	public:
		typedef uint32_t type;
		enum {
			digits = Bits,
			// parameters for packing bits into words
			Bitsperword = (int)(8 * sizeof(type)),	// bits in each word
			Words = (int)(Bits == 0	? 0 : (Bits - 1) / Bitsperword)
		};
		
		bitset(type value=0)
		{
			init(value);
		}

		bitset<Bits>& set()
		{	
			// set all bits true
			init((type)~0);
			return (*this);
		}

		bitset<Bits>& set(type pos, bool val = true)
		{	
			// set bit at _Pos to _Val
			if (pos < Bits)
			{
				if (val)
					mArray[pos / Bitsperword] |= (type)1 << pos % Bitsperword;
				else
					mArray[pos / Bitsperword] &= ~((type)1 << pos % Bitsperword);
			}
			return (*this);
		}

		bitset<Bits>& reset()
		{	
			// set all bits false
			init();
			return (*this);
		}

		bitset<Bits>& reset(type pos)
		{	
			// set bit at pos to false
			return set(pos, false);
		}

		bitset<Bits>& flip()
		{	
			// flip all bits
			for (int pos = Words; 0 <= pos; --pos)
			mArray[pos] = (type) ~mArray[pos];

			trim();
			return *this;
		}

		bitset<Bits>& flip(type pos)
		{	
			// flip bit at pos
			if (pos < Bits)
				mArray[pos / Bitsperword] ^= (type) 1 << pos % Bitsperword;
			return (*this);
		}

		size_t count() const
		{	
			// count number of set bits
			static char Bitsperhex[] = "\0\1\1\2\1\2\2\3\1\2\2\3\2\3\3\4";
			type val = 0;
			for (int pos = Words; 0 <= pos; --pos)
				for (type Wordval = mArray[pos]; Wordval != 0; Wordval >>= 4)
					val += Bitsperhex[Wordval & 0xF];
			return val;
		}

		type size() const
		{	
			// return size of bitset
			return (Bits);
		}

		bool test(uint32_t pos) const
		{	
			// test if bit at pos is set
			if (pos < Bits)
				return ((mArray[pos / Bitsperword] & ((type)1 << pos % Bitsperword)) != 0);
			return false;
		}

		bool any() const
		{	
			// test if any bits are set
			for (int pos = Words; 0 <= pos; --pos)
				if (mArray[pos] != 0)
					return true;
			return false;
		}

		bool none() const
		{	
			// test if no bits are set
			return !any();
		}

		bool operator==(const bitset<Bits>& right) const
		{	
			// test for bitset equality
			for (int pos = Words; 0 <= pos; --pos)
				if (mArray[pos] != right.word(pos))
					return false;
			return true;
		}

		type const& word(uint32_t pos)const
		{	
			// get word at pos
			return mArray[pos];
		}

		type& word(uint32_t pos)
		{	
			// get word at pos
			return mArray[pos];
		}
	protected:
		void init(type value = 0)
		{	
			// set all words to value
			for (int pos = Words; 0 <= pos; --pos)
				mArray[pos] = value;
			if (value != 0)
				trim();
		}

		void trim()
		{	
			// clear any trailing bits in last word
			if (Bits % Bitsperword != 0)
				mArray[Words] &= ((type)1 << Bits % Bitsperword) - 1;
		}

		type mArray[Words+1];
	};
}