Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
bitset.cpp
Go to the documentation of this file.
1
29#define _RWSTD_LIB_SRC
30
31#include <bitset>
32#include <string.h> // for memmove(), memset(), strlen()
33#include <rw/_traits.h> // for char_traits<wchar_t>
34
35#include <rw/_defs.h>
36
37#include <stdio.h>
38
40
41#if 2 == _RWSTD_LONG_SIZE
42static const int __rw_wbasebits = 1;
43static const _RWSTD_SIZE_T __rw_wbasemask = 15;
44#elif 4 == _RWSTD_LONG_SIZE
45static const int __rw_wbasebits = 2;
46static const _RWSTD_SIZE_T __rw_wbasemask = 31;
47#elif 8 == _RWSTD_LONG_SIZE
48static const int __rw_wbasebits = 3;
49static const _RWSTD_SIZE_T __rw_wbasemask = 63;
50#else // assume 16 == sizeof (long)
51static const int __rw_wbasebits = 4;
52static const _RWSTD_SIZE_T __rw_wbasemask = 127;
53#endif // _RWSTD_LONG_SIZE
54
55// overloads of __rw_bitset() implement:
56//
57// 23.3.5.1 bitset constructors [lib.bitset.cons]
58//
59// bitset<N>::
60// bitset(basic_string<charT, Traits, Allocator>& str,
61// typename basic_string<charT, Traits, Allocator>::size_type pos,
62// typename basic_string<charT, Traits, Allocator>::size_type n);
63//
64// -5- Effects: Determines the effective length rlen of the initializing
65// string as the smaller of n and str.size() - pos.
66// The function then throws invalid_argument if any of the rlen
67// characters in str beginning at position pos is other than 0 or 1.
68// Otherwise, the function constructs an object of class bitset<N>,
69// initializing the first M bit positions to values determined from
70// the corresponding characters in the string str. M is the smaller
71// of N and rlen.
72// -6- An element of the constructed string has value zero if
73// the corresponding character in str, beginning at position pos,
74// is 0. Otherwise, the element has the value one. Character
75// position pos + M - 1 corresponds to bit position zero.
76// Subsequent decreasing character positions correspond to
77// increasing bit positions.
78// -7- If M < N, remaining bit positions are initialized to zero.
79
81__rw_bitset (unsigned long *bits, _RWSTD_SIZE_T maxbits,
82 const char *str, _RWSTD_SIZE_T slen,
83 const _STD::char_traits<char>*, char b0, char b1,
84 _RWSTD_SIZE_T pos, _RWSTD_SIZE_T n,
85 const char *file, const char *fun)
86{
87 if (_RWSTD_SIZE_MAX == slen)
88 slen = strlen (str);
89
90 // verify that `pos' is a valid offset into `str'
93
94 // compute the number of characters in `str' past the offset `pos'
95 const _RWSTD_SIZE_T nchars = n < (slen - pos) ? n : slen - pos;
96
97 // compute the number of bits to initialize from `str'
98 const _RWSTD_SIZE_T nbits = nchars < maxbits ? nchars : maxbits;
99
100 str += pos;
101
102 // compute the number of non-zero bytes occupied by `bits'
103 _RWSTD_SIZE_T nbytes = ((maxbits | 1) >> 3) + (0 != (maxbits & 7));
104
105 // round the number up to a multiple of sizeof(long)
106 nbytes = ( (nbytes >> __rw_wbasebits)
107 + (0 != (nbytes & (__rw_wbasemask >> 3)))) << __rw_wbasebits;
108
109 memset (bits, 0, nbytes);
110
111 // set all bits but also check any extra characters as required
112 for (_RWSTD_SIZE_T i = 0; i != nchars; ++i) {
113
114 if (b1 == str [i]) {
115 if (i < nbits) {
116 const _RWSTD_SIZE_T bitno = nbits - i - 1;
117
118 // efficiently compute the value of the expression below
119 // (i.e., without relying on slow division and modulo)
120 // bits [bitno / wordbits] |= 1UL << bitno % wordbits;
121 bits [bitno >> (3 + __rw_wbasebits)]
122 |= 1UL << (bitno & __rw_wbasemask);
123 }
124 }
125 else {
126 // verify that the character is valid
127 _RWSTD_REQUIRES (b0 == str [i],
129 }
130 }
131}
132
133
134#ifndef _RWSTD_NO_WCHAR_T
135
137__rw_bitset (unsigned long *bits, _RWSTD_SIZE_T maxbits,
138 const wchar_t *str, _RWSTD_SIZE_T slen,
139 const _STD::char_traits<wchar_t>*, wchar_t b0, wchar_t b1,
140 _RWSTD_SIZE_T pos, _RWSTD_SIZE_T n,
141 const char *file, const char *fun)
142{
143 if (_RWSTD_SIZE_MAX == slen)
144 slen = _STD::char_traits<wchar_t>::length (str);
145
146 // verify that `pos' is a valid offset into `str'
149
150 // compute the number of characters in `str' past the offset `pos'
151 const _RWSTD_SIZE_T nchars = n < (slen - pos) ? n : slen - pos;
152
153 // compute the number of bits to initialize from `str'
154 const _RWSTD_SIZE_T nbits = nchars < maxbits ? nchars : maxbits;
155
156 str += pos;
157
158 // compute the number of non-zero bytes occupied by `bits'
159 _RWSTD_SIZE_T nbytes = ((maxbits | 1) >> 3) + (0 != (maxbits & 7));
160
161 // round the number up to a multiple of sizeof(long)
162 nbytes = ( (nbytes >> __rw_wbasebits)
163 + (0 != (nbytes & (__rw_wbasemask >> 3)))) << __rw_wbasebits;
164
165 memset (bits, 0, nbytes);
166
167 // set all bits but also check any extra characters as required
168 for (_RWSTD_SIZE_T i = 0; i != nchars; ++i) {
169
170 if (b1 == str [i]) {
171 if (i < nbits) {
172 const _RWSTD_SIZE_T bitno = nbits - i - 1;
173 bits [bitno >> (3 + __rw_wbasebits)]
174 |= 1UL << (bitno & __rw_wbasemask);
175 }
176 }
177 else {
178 // verify that the character is valid
179 _RWSTD_REQUIRES (b0 == str [i],
181 }
182 }
183}
184
185#endif // _RWSTD_NO_WCHAR_T
186
187
188// table of bitcounts in each of the 256 values
189// a byte can take on for efficient counting of bits
190static const unsigned char
191__rw_bitcounts [256] = {
192 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
193 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
194 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
195 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
196 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
197 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
198 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
199 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
200 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
201 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
202 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
203 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
204 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
205 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
206 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
207 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
208};
209
210
211// count the number of 1 bits in bitset `bits' of `size' elements
212_RWSTD_EXPORT _RWSTD_SIZE_T
213__rw_bit_count (const unsigned long *bits,
214 _RWSTD_SIZE_T size) _THROWS (())
215{
216 _RWSTD_ASSERT (0 != bits);
217
218 _RWSTD_SIZE_T sum = 0;
219
220 typedef unsigned char UChar;
221
222 const UChar* pbyte = _RWSTD_REINTERPRET_CAST (const UChar*, bits);
223 const UChar* const pend = pbyte + size * sizeof (unsigned long);
224
225 for ( ; pbyte != pend; ++pbyte)
226 sum += __rw_bitcounts [*pbyte];
227
228 return sum;
229}
230
231
232// shift bitset `bits' of `size' elements left by `n' positions
233_RWSTD_EXPORT void
234__rw_shl (unsigned long *bits,
235 _RWSTD_SIZE_T size, _RWSTD_SIZE_T n) _THROWS (())
236{
237 const _RWSTD_SIZE_T wordbits = sizeof *bits * _RWSTD_CHAR_BIT;
238
239 if (n >= size * wordbits) {
240 memset (bits, 0, size * sizeof *bits);
241 return;
242 }
243
244 if (!n)
245 return;
246
247 const _RWSTD_SIZE_T shlw = n / wordbits; // word shift left
248 const _RWSTD_SIZE_T shlb = n % wordbits; // bit shift left
249
250 if (shlb) {
251 const _RWSTD_SIZE_T shrb = wordbits - shlb; // bit shift right
252
253 // shift one word at a time, spanning word boundaries
254 for (_RWSTD_SIZE_T i = size - 1; i > shlw; --i)
255 bits [i] = bits [i - shlw] << shlb
256 | bits [i - shlw - 1] >> shrb;
257
258 // shift the last word
259 bits [shlw] = bits [0] << shlb;
260 }
261 else {
262 // no shifting necessary, just copy
263 memmove (bits + shlw, bits, (size - shlw) * sizeof *bits);
264 }
265
266 // fill remainder with zeros
267 memset (bits, 0, shlw * sizeof *bits);
268}
269
270
271// shift bitset `bits' of `size' elements right by `n' positions
272_RWSTD_EXPORT void
273__rw_shr (unsigned long *bits,
274 _RWSTD_SIZE_T size, _RWSTD_SIZE_T n) _THROWS (())
275{
276 const _RWSTD_SIZE_T wordbits = sizeof *bits * _RWSTD_CHAR_BIT;
277
278 if (n >= size * wordbits) {
279 memset (bits, 0, size * sizeof *bits);
280 return;
281 }
282
283 if (!n)
284 return;
285
286 const _RWSTD_SIZE_T shrw = n / wordbits; // word shift right
287 const _RWSTD_SIZE_T shrb = n % wordbits; // bit shift right
288
289 // max word index
290 const _RWSTD_SIZE_T maxw = size - shrw - 1;
291
292 if (shrb) {
293 const _RWSTD_SIZE_T shlb = wordbits - shrb; // bit shift left
294
295 // shift one word at a time, spanning word boundaries
296 for (_RWSTD_SIZE_T i = 0; i < maxw; ++i)
297 bits [i] = bits [i + shrw] >> shrb
298 | bits [i + shrw + 1] << shlb;
299
300 // shift the last word
301 bits [maxw] = bits [size - 1] >> shrb;
302 }
303 else {
304 // no shifting necessary, just copy
305 memmove (bits, bits + shrw, (maxw + 1) * sizeof *bits);
306 }
307
308 // fill remainder with zeros
309 memset (bits + (maxw + 1), 0, (size - (maxw + 1)) * sizeof *bits);
310}
311
312
313} // namespace __rw
#define i
Definition 17.names.cpp:126
#define nchars
Definition 17.names.cpp:502
#define b1
Definition 17.names.cpp:226
#define fun
Definition 17.names.cpp:471
#define slen
Definition 17.names.cpp:545
#define pend
Definition 17.names.cpp:523
#define n
Definition 17.names.cpp:130
#define pos
Definition 17.names.cpp:518
#define _THROWS()
#define _RWSTD_REQUIRES(pred, args)
Definition _defs.h:1132
#define _RWSTD_EXPORT
Definition _defs.h:485
#define _RWSTD_REINTERPRET_CAST(T, x)
Definition _defs.h:535
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _RWSTD_ASSERT(ignore)
Definition _defs.h:1108
#define _RWSTD_SPECIALIZED_FUNCTION
Definition _defs.h:556
#define _RWSTD_ERROR_INVALID_ARGUMENT
Definition _error.h:91
#define _RWSTD_ERROR_OUT_OF_RANGE
Definition _error.h:93
const char * str
Definition exec.cpp:170
unsigned char UChar
Definition collate.cpp:122