MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Bitmask.hpp
1 /*
2  Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #ifndef NDB_BITMASK_H
19 #define NDB_BITMASK_H
20 
21 #include <ndb_global.h>
22 
23 #ifdef HAVE__BITSCANFORWARD
24 #include <intrin.h>
25 #endif
26 
31 class BitmaskImpl {
32 public:
33  STATIC_CONST( NotFound = (unsigned)-1 );
34 
38  static bool get(unsigned size, const Uint32 data[], unsigned n);
39 
43  static void set(unsigned size, Uint32 data[], unsigned n, bool value);
44 
48  static void set(unsigned size, Uint32 data[], unsigned n);
49 
53  static void set(unsigned size, Uint32 data[]);
54 
58  static void setRange(unsigned size, Uint32 data[], unsigned start,
59  unsigned len);
60 
64  static void assign(unsigned size, Uint32 dst[], const Uint32 src[]);
65 
69  static void clear(unsigned size, Uint32 data[], unsigned n);
70 
74  static void clear(unsigned size, Uint32 data[]);
75 
79  static void clear_range(unsigned size, Uint32 data[], unsigned start, unsigned last);
80 
81  static Uint32 getWord(unsigned size, Uint32 data[], unsigned word_pos);
82  static void setWord(unsigned size, Uint32 data[],
83  unsigned word_pos, Uint32 new_word);
88  static bool isclear(unsigned size, const Uint32 data[]);
89 
93  static unsigned count(unsigned size, const Uint32 data[]);
94 
99  static unsigned ffs(Uint32 x);
100 
105  static unsigned find_first(unsigned size, const Uint32 data[]);
106 
111  static unsigned find_next(unsigned size, const Uint32 data[], unsigned n);
112 
117  static unsigned find(unsigned size, const Uint32 data[], unsigned n);
118 
122  static bool equal(unsigned size, const Uint32 data[], const Uint32 data2[]);
123 
127  static void bitOR(unsigned size, Uint32 data[], const Uint32 data2[]);
128 
132  static void bitAND(unsigned size, Uint32 data[], const Uint32 data2[]);
133 
137  static void bitANDC(unsigned size, Uint32 data[], const Uint32 data2[]);
138 
142  static void bitXOR(unsigned size, Uint32 data[], const Uint32 data2[]);
143 
147  static void bitXORC(unsigned size, Uint32 data[], const Uint32 data2[]);
148 
152  static void bitNOT(unsigned size, Uint32 data[]);
153 
157  static bool contains(unsigned size, Uint32 data[], const Uint32 data2[]);
158 
162  static bool overlaps(unsigned size, Uint32 data[], const Uint32 data2[]);
163 
167  static Uint32 getField(unsigned size, const Uint32 data[],
168  unsigned pos, unsigned len);
169 
174  static void setField(unsigned size, Uint32 data[],
175  unsigned pos, unsigned len, Uint32 val);
176 
177 
182  static void getField(unsigned size, const Uint32 data[],
183  unsigned pos, unsigned len, Uint32 dst[]);
184 
188  static void setField(unsigned size, Uint32 data[],
189  unsigned pos, unsigned len, const Uint32 src[]);
190 
196  static void copyField(Uint32 dst[], unsigned destPos,
197  const Uint32 src[], unsigned srcPos, unsigned len);
198 
202  static char* getText(unsigned size, const Uint32 data[], char* buf);
203 
204  /* Fast bit counting (16 instructions on x86_64, gcc -O3). */
205  static inline Uint32 count_bits(Uint32 x);
206 
210  static Uint32 toArray(Uint8* dst, Uint32 len,
211  unsigned size, const Uint32 data[]);
212 private:
213  static void getFieldImpl(const Uint32 data[], unsigned, unsigned, Uint32 []);
214  static void setFieldImpl(Uint32 data[], unsigned, unsigned, const Uint32 []);
215 };
216 
217 inline bool
218 BitmaskImpl::get(unsigned size, const Uint32 data[], unsigned n)
219 {
220  assert(n < (size << 5));
221  return (data[n >> 5] & (1 << (n & 31))) != 0;
222 }
223 
224 inline void
225 BitmaskImpl::set(unsigned size, Uint32 data[], unsigned n, bool value)
226 {
227  value ? set(size, data, n) : clear(size, data, n);
228 }
229 
230 inline void
231 BitmaskImpl::set(unsigned size, Uint32 data[], unsigned n)
232 {
233  assert(n < (size << 5));
234  data[n >> 5] |= (1 << (n & 31));
235 }
236 
237 inline void
238 BitmaskImpl::set(unsigned size, Uint32 data[])
239 {
240  for (unsigned i = 0; i < size; i++) {
241  data[i] = ~0;
242  }
243 }
244 
245 inline void
246 BitmaskImpl::setRange(unsigned size, Uint32 data[],
247  unsigned start, unsigned len)
248 {
249  Uint32 last = start + len - 1;
250  Uint32 *ptr = data + (start >> 5);
251  Uint32 *end = data + (last >> 5);
252  assert(start <= last);
253  assert(last < (size << 5));
254 
255  Uint32 tmp_word = ~(Uint32)0 << (start & 31);
256 
257  if (ptr < end)
258  {
259  * ptr ++ |= tmp_word;
260 
261  for(; ptr < end; )
262  {
263  * ptr ++ = ~(Uint32)0;
264  }
265 
266  tmp_word = ~(Uint32)0;
267  }
268 
269  tmp_word &= ~(~(Uint32)0 << (last & 31));
270 
271  * ptr |= tmp_word;
272 }
273 
274 inline void
275 BitmaskImpl::assign(unsigned size, Uint32 dst[], const Uint32 src[])
276 {
277  for (unsigned i = 0; i < size; i++) {
278  dst[i] = src[i];
279  }
280 }
281 
282 inline void
283 BitmaskImpl::clear(unsigned size, Uint32 data[], unsigned n)
284 {
285  assert(n < (size << 5));
286  data[n >> 5] &= ~(1 << (n & 31));
287 }
288 
289 inline void
290 BitmaskImpl::clear(unsigned size, Uint32 data[])
291 {
292  for (unsigned i = 0; i < size; i++) {
293  data[i] = 0;
294  }
295 }
296 
297 inline void
298 BitmaskImpl::clear_range(unsigned size, Uint32 data[],
299  unsigned start, unsigned last)
300 {
301  Uint32 *ptr = data + (start >> 5);
302  Uint32 *end = data + (last >> 5);
303  assert(start <= last);
304  assert(last < (size << 5));
305 
306  Uint32 tmp_word = ~(Uint32)0 << (start & 31);
307 
308  if (ptr < end)
309  {
310  * ptr ++ &= ~tmp_word;
311 
312  for(; ptr < end; )
313  {
314  * ptr ++ = 0;
315  }
316 
317  tmp_word = ~(Uint32)0;
318  }
319 
320  tmp_word &= ~(~(Uint32)0 << (last & 31));
321 
322  * ptr &= ~tmp_word;
323 }
324 
325 inline
326 Uint32
327 BitmaskImpl::getWord(unsigned size, Uint32 data[], unsigned word_pos)
328 {
329  return data[word_pos];
330 }
331 
332 inline void
333 BitmaskImpl::setWord(unsigned size, Uint32 data[],
334  unsigned word_pos, Uint32 new_word)
335 {
336  data[word_pos] = new_word;
337  return;
338 }
339 
340 inline bool
341 BitmaskImpl::isclear(unsigned size, const Uint32 data[])
342 {
343  for (unsigned i = 0; i < size; i++) {
344  if (data[i] != 0)
345  return false;
346  }
347  return true;
348 }
349 
350 inline unsigned
351 BitmaskImpl::count(unsigned size, const Uint32 data[])
352 {
353  unsigned cnt = 0;
354  for (unsigned i = 0; i < size; i++) {
355  cnt += count_bits(data[i]);
356  }
357  return cnt;
358 }
359 
364 inline
365 Uint32
367 {
368 #if defined(__GNUC__) && (defined(__x86_64__) || defined (__i386__))
369  asm("bsf %1,%0"
370  : "=r" (x)
371  : "rm" (x));
372  return x;
373 #elif defined HAVE___BUILTIN_FFS
374 
377  return __builtin_ffs(x) - 1;
378 #elif defined HAVE__BITSCANFORWARD
379  unsigned long r;
380  unsigned char res = _BitScanForward(&r, (unsigned long)x);
381  assert(res > 0);
382  return (Uint32)r;
383 #elif defined HAVE_FFS
384  return ::ffs(x) - 1;
385 #else
386  int b = 0;
387  if (!(x & 0xffff))
388  {
389  x >>= 16;
390  b += 16;
391  }
392  if (!(x & 0xff))
393  {
394  x >>= 8;
395  b += 8;
396  }
397  if (!(x & 0xf))
398  {
399  x >>= 4;
400  b += 4;
401  }
402  if (!(x & 3))
403  {
404  x >>= 2;
405  b += 2;
406  }
407  if (!(x & 1))
408  {
409  x >>= 1;
410  b += 1;
411  }
412  return b;
413 #endif
414 }
415 
416 inline unsigned
417 BitmaskImpl::find_first(unsigned size, const Uint32 data[])
418 {
419  Uint32 n = 0;
420  while (n < (size << 5))
421  {
422  Uint32 val = data[n >> 5];
423  if (val)
424  {
425  return n + ffs(val);
426  }
427  n += 32;
428  }
429  return NotFound;
430 }
431 
432 inline unsigned
433 BitmaskImpl::find_next(unsigned size, const Uint32 data[], unsigned n)
434 {
435  Uint32 val = data[n >> 5];
436  Uint32 b = n & 31;
437  if (b)
438  {
439  val >>= b;
440  if (val)
441  {
442  return n + ffs(val);
443  }
444  n += 32 - b;
445  }
446 
447  while (n < (size << 5))
448  {
449  val = data[n >> 5];
450  if (val)
451  {
452  return n + ffs(val);
453  }
454  n += 32;
455  }
456  return NotFound;
457 }
458 
459 inline unsigned
460 BitmaskImpl::find(unsigned size, const Uint32 data[], unsigned n)
461 {
462  return find_next(size, data, n);
463 }
464 
465 inline bool
466 BitmaskImpl::equal(unsigned size, const Uint32 data[], const Uint32 data2[])
467 {
468  for (unsigned i = 0; i < size; i++) {
469  if (data[i] != data2[i])
470  return false;
471  }
472  return true;
473 }
474 
475 inline void
476 BitmaskImpl::bitOR(unsigned size, Uint32 data[], const Uint32 data2[])
477 {
478  for (unsigned i = 0; i < size; i++) {
479  data[i] |= data2[i];
480  }
481 }
482 
483 inline void
484 BitmaskImpl::bitAND(unsigned size, Uint32 data[], const Uint32 data2[])
485 {
486  for (unsigned i = 0; i < size; i++) {
487  data[i] &= data2[i];
488  }
489 }
490 
491 inline void
492 BitmaskImpl::bitANDC(unsigned size, Uint32 data[], const Uint32 data2[])
493 {
494  for (unsigned i = 0; i < size; i++) {
495  data[i] &= ~data2[i];
496  }
497 }
498 
499 inline void
500 BitmaskImpl::bitXOR(unsigned size, Uint32 data[], const Uint32 data2[])
501 {
502  for (unsigned i = 0; i < size; i++) {
503  data[i] ^= data2[i];
504  }
505 }
506 
507 inline void
508 BitmaskImpl::bitXORC(unsigned size, Uint32 data[], const Uint32 data2[])
509 {
510  for (unsigned i = 0; i < size; i++) {
511  data[i] ^= ~data2[i];
512  }
513 }
514 
515 inline void
516 BitmaskImpl::bitNOT(unsigned size, Uint32 data[])
517 {
518  for (unsigned i = 0; i < size; i++) {
519  data[i] = ~data[i];
520  }
521 }
522 
523 inline bool
524 BitmaskImpl::contains(unsigned size, Uint32 data[], const Uint32 data2[])
525 {
526  for (unsigned int i = 0; i < size; i++)
527  if ((data[i] & data2[i]) != data2[i])
528  return false;
529  return true;
530 }
531 
532 inline bool
533 BitmaskImpl::overlaps(unsigned size, Uint32 data[], const Uint32 data2[])
534 {
535  for (unsigned int i = 0; i < size; i++)
536  if ((data[i] & data2[i]) != 0)
537  return true;
538  return false;
539 }
540 
541 inline Uint32
542 BitmaskImpl::getField(unsigned size, const Uint32 data[],
543  unsigned pos, unsigned len)
544 {
545  Uint32 val = 0;
546  for (unsigned i = 0; i < len; i++)
547  val |= get(size, data, pos + i) << i;
548  return val;
549 }
550 
551 inline void
552 BitmaskImpl::setField(unsigned size, Uint32 data[],
553  unsigned pos, unsigned len, Uint32 val)
554 {
555  for (unsigned i = 0; i < len; i++)
556  set(size, data, pos + i, val & (1 << i));
557 }
558 
559 inline char *
560 BitmaskImpl::getText(unsigned size, const Uint32 data[], char* buf)
561 {
562  char * org = buf;
563  const char* const hex = "0123456789abcdef";
564  for (int i = (size-1); i >= 0; i--) {
565  Uint32 x = data[i];
566  for (unsigned j = 0; j < 8; j++) {
567  buf[7-j] = hex[x & 0xf];
568  x >>= 4;
569  }
570  buf += 8;
571  }
572  *buf = 0;
573  return org;
574 }
575 
576 inline
577 Uint32
578 BitmaskImpl::count_bits(Uint32 x)
579 {
580  x= x - ((x>>1) & 0x55555555);
581  x= (x & 0x33333333) + ((x>>2) & 0x33333333);
582  x= (x + (x>>4)) & 0x0f0f0f0f;
583  x= (x*0x01010101) >> 24;
584  return x;
585 }
586 
587 inline
588 Uint32
589 BitmaskImpl::toArray(Uint8* dst, Uint32 len,
590  unsigned size, const Uint32 * data)
591 {
592  assert(len >= size * 32);
593  assert(32 * size <= 256); // Uint8
594  Uint8 * save = dst;
595  for (Uint32 i = 0; i<size; i++)
596  {
597  Uint32 val = * data++;
598  Uint32 bit = 0;
599  while (val)
600  {
601  if (val & (1 << bit))
602  {
603  * dst++ = 32 * i + bit;
604  val &= ~(1U << bit);
605  }
606  bit ++;
607  }
608  }
609  return (Uint32)(dst - save);
610 }
611 
618 template <unsigned size>
619 struct BitmaskPOD {
620 public:
624  struct Data {
625  Uint32 data[size];
626 #if 0
627  Data & operator=(const BitmaskPOD<size> & src) {
628  src.copyto(size, data);
629  return *this;
630  }
631 #endif
632  };
633 
634  Data rep;
635 public:
636  STATIC_CONST( Size = size );
637  STATIC_CONST( NotFound = BitmaskImpl::NotFound );
638  STATIC_CONST( TextLength = size * 8 );
639 
640  Uint32 getSizeInWords() const { return Size;}
641 
642  unsigned max_size() const { return (size * 32) - 1; }
643 
647  void assign(const typename BitmaskPOD<size>::Data & src);
648 
652  static void assign(Uint32 dst[], const Uint32 src[]);
653  static void assign(Uint32 dst[], const BitmaskPOD<size> & src);
654  void assign(const BitmaskPOD<size> & src);
655 
659  void copyto(unsigned sz, Uint32 dst[]) const;
660 
664  void assign(unsigned sz, const Uint32 src[]);
665 
672  static bool get(const Uint32 data[], unsigned n);
673  bool get(unsigned n) const;
674 
678  static void set(Uint32 data[], unsigned n, bool value);
679  void set(unsigned n, bool value);
680 
684  static void set(Uint32 data[], unsigned n);
685  void set(unsigned n);
686 
690  static void set(Uint32 data[]);
691  void set();
692 
696  static void setRange(Uint32 data[], Uint32 pos, Uint32 len);
697  void setRange(Uint32 pos, Uint32 len);
698 
702  static void clear(Uint32 data[], unsigned n);
703  void clear(unsigned n);
704 
708  static void clear(Uint32 data[]);
709  void clear();
710 
714  Uint32 getWord(unsigned word_pos);
715  void setWord(unsigned word_pos, Uint32 new_word);
716 
721  static bool isclear(const Uint32 data[]);
722  bool isclear() const;
723 
727  static unsigned count(const Uint32 data[]);
728  unsigned count() const;
729 
734  static unsigned find_first(const Uint32 data[]);
735  unsigned find_first() const;
736 
741  static unsigned find_next(const Uint32 data[], unsigned n);
742  unsigned find_next(unsigned n) const;
743 
748  static unsigned find(const Uint32 data[], unsigned n);
749  unsigned find(unsigned n) const;
750 
754  static bool equal(const Uint32 data[], const Uint32 data2[]);
755  bool equal(const BitmaskPOD<size>& mask2) const;
756 
760  static void bitOR(Uint32 data[], const Uint32 data2[]);
761  BitmaskPOD<size>& bitOR(const BitmaskPOD<size>& mask2);
762 
766  static void bitAND(Uint32 data[], const Uint32 data2[]);
768 
772  static void bitANDC(Uint32 data[], const Uint32 data2[]);
774 
778  static void bitXOR(Uint32 data[], const Uint32 data2[]);
780 
784  static void bitXORC(Uint32 data[], const Uint32 data2[]);
786 
790  static void bitNOT(Uint32 data[]);
792 
796  static bool contains(Uint32 data[], const Uint32 data2[]);
797  bool contains(BitmaskPOD<size> that);
798 
802  static bool overlaps(Uint32 data[], const Uint32 data2[]);
803  bool overlaps(BitmaskPOD<size> that);
804 
808  static char* getText(const Uint32 data[], char* buf);
809  char* getText(char* buf) const;
810 
811  static Uint32 toArray(Uint8 * dst, Uint32 len, const Uint32 data[]);
812  Uint32 toArray(Uint8 * dst, Uint32 len) const;
813 };
814 
815 template <unsigned size>
816 inline void
817 BitmaskPOD<size>::assign(Uint32 dst[], const Uint32 src[])
818 {
819  BitmaskImpl::assign(size, dst, src);
820 }
821 
822 template <unsigned size>
823 inline void
824 BitmaskPOD<size>::assign(Uint32 dst[], const BitmaskPOD<size> & src)
825 {
826  BitmaskImpl::assign(size, dst, src.rep.data);
827 }
828 
829 template <unsigned size>
830 inline void
832 {
833  BitmaskPOD<size>::assign(rep.data, src.data);
834 }
835 
836 template <unsigned size>
837 inline void
839 {
840  BitmaskPOD<size>::assign(rep.data, src.rep.data);
841 }
842 
843 template <unsigned size>
844 inline void
845 BitmaskPOD<size>::copyto(unsigned sz, Uint32 dst[]) const
846 {
847  BitmaskImpl::assign(sz, dst, rep.data);
848 }
849 
850 template <unsigned size>
851 inline void
852 BitmaskPOD<size>::assign(unsigned sz, const Uint32 src[])
853 {
854  BitmaskImpl::assign(sz, rep.data, src);
855 }
856 
857 template <unsigned size>
858 inline bool
859 BitmaskPOD<size>::get(const Uint32 data[], unsigned n)
860 {
861  return BitmaskImpl::get(size, data, n);
862 }
863 
864 template <unsigned size>
865 inline bool
866 BitmaskPOD<size>::get(unsigned n) const
867 {
868  return BitmaskPOD<size>::get(rep.data, n);
869 }
870 
871 template <unsigned size>
872 inline void
873 BitmaskPOD<size>::set(Uint32 data[], unsigned n, bool value)
874 {
875  BitmaskImpl::set(size, data, n, value);
876 }
877 
878 template <unsigned size>
879 inline void
880 BitmaskPOD<size>::set(unsigned n, bool value)
881 {
882  BitmaskPOD<size>::set(rep.data, n, value);
883 }
884 
885 template <unsigned size>
886 inline void
887 BitmaskPOD<size>::set(Uint32 data[], unsigned n)
888 {
889  BitmaskImpl::set(size, data, n);
890 }
891 
892 template <unsigned size>
893 inline void
894 BitmaskPOD<size>::set(unsigned n)
895 {
896  BitmaskPOD<size>::set(rep.data, n);
897 }
898 
899 template <unsigned size>
900 inline void
901 BitmaskPOD<size>::set(Uint32 data[])
902 {
903  BitmaskImpl::set(size, data);
904 }
905 
906 template <unsigned size>
907 inline void
909 {
910  BitmaskPOD<size>::set(rep.data);
911 }
912 
913 template <unsigned size>
914 inline void
915 BitmaskPOD<size>::setRange(Uint32 data[], Uint32 pos, Uint32 len)
916 {
917  BitmaskImpl::setRange(size, data, pos, len);
918 }
919 
920 
921 template <unsigned size>
922 inline void
923 BitmaskPOD<size>::setRange(Uint32 pos, Uint32 len)
924 {
925  BitmaskPOD<size>::setRange(rep.data, pos, len);
926 }
927 
928 template <unsigned size>
929 inline void
930 BitmaskPOD<size>::clear(Uint32 data[], unsigned n)
931 {
932  BitmaskImpl::clear(size, data, n);
933 }
934 
935 template <unsigned size>
936 inline void
937 BitmaskPOD<size>::clear(unsigned n)
938 {
939  BitmaskPOD<size>::clear(rep.data, n);
940 }
941 
942 template <unsigned size>
943 inline void
945 {
946  BitmaskImpl::clear(size, data);
947 }
948 
949 template <unsigned size>
950 inline void
952 {
953  BitmaskPOD<size>::clear(rep.data);
954 }
955 
956 template <unsigned size>
957 inline Uint32
958 BitmaskPOD<size>::getWord(unsigned word_pos)
959 {
960  return BitmaskImpl::getWord(size, rep.data, word_pos);
961 }
962 
963 template <unsigned size>
964 inline void
965 BitmaskPOD<size>::setWord(unsigned word_pos, Uint32 new_word)
966 {
967  BitmaskImpl::setWord(size, rep.data, word_pos, new_word);
968 }
969 
970 template <unsigned size>
971 inline bool
972 BitmaskPOD<size>::isclear(const Uint32 data[])
973 {
974  return BitmaskImpl::isclear(size, data);
975 }
976 
977 template <unsigned size>
978 inline bool
980 {
981  return BitmaskPOD<size>::isclear(rep.data);
982 }
983 
984 template <unsigned size>
985 inline unsigned
986 BitmaskPOD<size>::count(const Uint32 data[])
987 {
988  return BitmaskImpl::count(size, data);
989 }
990 
991 template <unsigned size>
992 inline unsigned
994 {
995  return BitmaskPOD<size>::count(rep.data);
996 }
997 
998 template <unsigned size>
999 inline unsigned
1000 BitmaskPOD<size>::find_first(const Uint32 data[])
1001 {
1002  return BitmaskImpl::find_first(size, data);
1003 }
1004 
1005 template <unsigned size>
1006 inline unsigned
1008 {
1009  return BitmaskPOD<size>::find_first(rep.data);
1010 }
1011 
1012 template <unsigned size>
1013 inline unsigned
1014 BitmaskPOD<size>::find_next(const Uint32 data[], unsigned n)
1015 {
1016  return BitmaskImpl::find_next(size, data, n);
1017 }
1018 
1019 template <unsigned size>
1020 inline unsigned
1021 BitmaskPOD<size>::find_next(unsigned n) const
1022 {
1023  return BitmaskPOD<size>::find_next(rep.data, n);
1024 }
1025 
1026 template <unsigned size>
1027 inline unsigned
1028 BitmaskPOD<size>::find(const Uint32 data[], unsigned n)
1029 {
1030  return find_next(data, n);
1031 }
1032 
1033 template <unsigned size>
1034 inline unsigned
1035 BitmaskPOD<size>::find(unsigned n) const
1036 {
1037  return find_next(n);
1038 }
1039 
1040 template <unsigned size>
1041 inline bool
1042 BitmaskPOD<size>::equal(const Uint32 data[], const Uint32 data2[])
1043 {
1044  return BitmaskImpl::equal(size, data, data2);
1045 }
1046 
1047 template <unsigned size>
1048 inline bool
1049 BitmaskPOD<size>::equal(const BitmaskPOD<size>& mask2) const
1050 {
1051  return BitmaskPOD<size>::equal(rep.data, mask2.rep.data);
1052 }
1053 
1054 template <unsigned size>
1055 inline void
1056 BitmaskPOD<size>::bitOR(Uint32 data[], const Uint32 data2[])
1057 {
1058  BitmaskImpl::bitOR(size,data, data2);
1059 }
1060 
1061 template <unsigned size>
1062 inline BitmaskPOD<size>&
1064 {
1065  BitmaskPOD<size>::bitOR(rep.data, mask2.rep.data);
1066  return *this;
1067 }
1068 
1069 template <unsigned size>
1070 inline void
1071 BitmaskPOD<size>::bitAND(Uint32 data[], const Uint32 data2[])
1072 {
1073  BitmaskImpl::bitAND(size,data, data2);
1074 }
1075 
1076 template <unsigned size>
1077 inline BitmaskPOD<size>&
1079 {
1080  BitmaskPOD<size>::bitAND(rep.data, mask2.rep.data);
1081  return *this;
1082 }
1083 
1084 template <unsigned size>
1085 inline void
1086 BitmaskPOD<size>::bitANDC(Uint32 data[], const Uint32 data2[])
1087 {
1088  BitmaskImpl::bitANDC(size,data, data2);
1089 }
1090 
1091 template <unsigned size>
1092 inline BitmaskPOD<size>&
1094 {
1095  BitmaskPOD<size>::bitANDC(rep.data, mask2.rep.data);
1096  return *this;
1097 }
1098 
1099 template <unsigned size>
1100 inline void
1101 BitmaskPOD<size>::bitXOR(Uint32 data[], const Uint32 data2[])
1102 {
1103  BitmaskImpl::bitXOR(size,data, data2);
1104 }
1105 
1106 template <unsigned size>
1107 inline BitmaskPOD<size>&
1109 {
1110  BitmaskPOD<size>::bitXOR(rep.data, mask2.rep.data);
1111  return *this;
1112 }
1113 
1114 template <unsigned size>
1115 inline void
1116 BitmaskPOD<size>::bitXORC(Uint32 data[], const Uint32 data2[])
1117 {
1118  BitmaskImpl::bitXORC(size,data, data2);
1119 }
1120 
1121 template <unsigned size>
1122 inline BitmaskPOD<size>&
1124 {
1125  BitmaskPOD<size>::bitXORC(rep.data, mask2.rep.data);
1126  return *this;
1127 }
1128 
1129 template <unsigned size>
1130 inline void
1132 {
1133  BitmaskImpl::bitNOT(size,data);
1134 }
1135 
1136 template <unsigned size>
1137 inline BitmaskPOD<size>&
1139 {
1140  BitmaskPOD<size>::bitNOT(rep.data);
1141  return *this;
1142 }
1143 
1144 template <unsigned size>
1145 inline char *
1146 BitmaskPOD<size>::getText(const Uint32 data[], char* buf)
1147 {
1148  return BitmaskImpl::getText(size, data, buf);
1149 }
1150 
1151 template <unsigned size>
1152 inline char *
1153 BitmaskPOD<size>::getText(char* buf) const
1154 {
1155  return BitmaskPOD<size>::getText(rep.data, buf);
1156 }
1157 
1158 template <unsigned size>
1159 inline bool
1160 BitmaskPOD<size>::contains(Uint32 data[], const Uint32 data2[])
1161 {
1162  return BitmaskImpl::contains(size, data, data2);
1163 }
1164 
1165 template <unsigned size>
1166 inline bool
1168 {
1169  return BitmaskPOD<size>::contains(this->rep.data, that.rep.data);
1170 }
1171 
1172 template <unsigned size>
1173 inline bool
1174 BitmaskPOD<size>::overlaps(Uint32 data[], const Uint32 data2[])
1175 {
1176  return BitmaskImpl::overlaps(size, data, data2);
1177 }
1178 
1179 template <unsigned size>
1180 inline bool
1182 {
1183  return BitmaskPOD<size>::overlaps(this->rep.data, that.rep.data);
1184 }
1185 
1186 template <unsigned size>
1187 inline
1188 Uint32
1189 BitmaskPOD<size>::toArray(Uint8* dst, Uint32 len, const Uint32 data[])
1190 {
1191  return BitmaskImpl::toArray(dst, len, size, data);
1192 }
1193 
1194 template <unsigned size>
1195 inline
1196 Uint32
1197 BitmaskPOD<size>::toArray(Uint8* dst, Uint32 len) const
1198 {
1199  return BitmaskImpl::toArray(dst, len, size, this->rep.data);
1200 }
1201 
1202 template <unsigned size>
1203 class Bitmask : public BitmaskPOD<size> {
1204 public:
1205  Bitmask() { this->clear();}
1206 
1207  template<unsigned sz2> Bitmask& operator=(const Bitmask<sz2>& src){
1208  if (size >= sz2)
1209  {
1210  for (unsigned i = 0; i < sz2; i++)
1211  {
1212  this->rep.data[i] = src.rep.data[i];
1213  }
1214  }
1215  else
1216  {
1217  assert(src.find(32*size+1) == BitmaskImpl::NotFound);
1218  for (unsigned i = 0; i < size; i++)
1219  {
1220  this->rep.data[i] = src.rep.data[i];
1221  }
1222  }
1223  return * this;
1224  }
1225 
1226  template<unsigned sz2> Bitmask& operator=(const BitmaskPOD<sz2>& src){
1227  if (size >= sz2)
1228  {
1229  for (unsigned i = 0; i < sz2; i++)
1230  {
1231  this->rep.data[i] = src.rep.data[i];
1232  }
1233  }
1234  else
1235  {
1236  assert(src.find(32*size+1) == BitmaskImpl::NotFound);
1237  for (unsigned i = 0; i < size; i++)
1238  {
1239  this->rep.data[i] = src.rep.data[i];
1240  }
1241  }
1242  return * this;
1243  }
1244 };
1245 
1246 inline void
1247 BitmaskImpl::getField(unsigned size, const Uint32 src[],
1248  unsigned pos, unsigned len, Uint32 dst[])
1249 {
1250  assert(pos + len <= (size << 5));
1251  assert (len != 0);
1252  if (len == 0)
1253  return;
1254 
1255  src += (pos >> 5);
1256  Uint32 offset = pos & 31;
1257  * dst = (* src >> offset) & (len >= 32 ? ~0 : (1 << len) - 1);
1258 
1259  if(offset + len <= 32)
1260  {
1261  return;
1262  }
1263  Uint32 used = (32 - offset);
1264  assert(len > used);
1265  getFieldImpl(src+1, used & 31, len-used, dst+(used >> 5));
1266 }
1267 
1268 inline void
1269 BitmaskImpl::setField(unsigned size, Uint32 dst[],
1270  unsigned pos, unsigned len, const Uint32 src[])
1271 {
1272  assert(pos + len <= (size << 5));
1273  assert(len != 0);
1274  if (len == 0)
1275  return;
1276 
1277  dst += (pos >> 5);
1278  Uint32 offset = pos & 31;
1279  Uint32 mask = (len >= 32 ? ~0 : (1 << len) - 1) << offset;
1280 
1281  * dst = (* dst & ~mask) | ((*src << offset) & mask);
1282 
1283  if(offset + len <= 32)
1284  {
1285  return;
1286  }
1287  Uint32 used = (32 - offset);
1288  assert(len > used);
1289  setFieldImpl(dst+1, used & 31, len-used, src+(used >> 5));
1290 }
1291 
1292 /* Three way min utiltiy for copyField below */
1293 inline unsigned minLength(unsigned a, unsigned b, unsigned c)
1294 {
1295  return (a < b ?
1296  (a < c ? a : c) :
1297  (b < c ? b : c ));
1298 }
1299 
1300 inline void
1301 BitmaskImpl::copyField(Uint32 _dst[], unsigned dstPos,
1302  const Uint32 _src[], unsigned srcPos, unsigned len)
1303 {
1304  /* Algorithm
1305  * While (len > 0)
1306  * - Find the longest bit length we can copy from one 32-bit word
1307  * to another (which is the miniumum of remaining length,
1308  * space in current src word and space in current dest word)
1309  * - Extract that many bits from src, and shift them to the correct
1310  * position to insert into dest
1311  * - Mask out the to-be-written words from dest (and any irrelevant
1312  * words in src) and or them together
1313  * - Move onto next chunk
1314  */
1315  while (len > 0)
1316  {
1317  const Uint32* src= _src + (srcPos >> 5);
1318  Uint32* dst= _dst + (dstPos >> 5);
1319  unsigned srcOffset= srcPos & 31;
1320  unsigned dstOffset= dstPos & 31;
1321  unsigned srcBitsInWord= 32 - srcOffset;
1322  unsigned dstBitsInWord= 32 - dstOffset;
1323 
1324  /* How many bits can we copy at once? */
1325  unsigned bits= minLength(dstBitsInWord, srcBitsInWord, len);
1326 
1327  /* Create mask for affected bits in dest */
1328  Uint32 destMask= (~(Uint32)0 >> (32-bits) << dstOffset);
1329 
1330  /* Grab source data and shift to dest offset */
1331  Uint32 data= ((*src) >> srcOffset) << dstOffset;
1332 
1333  /* Mask out affected bits in dest and irrelevant bits in source
1334  * and combine
1335  */
1336  *dst= (*dst & ~destMask) | (data & destMask);
1337 
1338  srcPos+= bits;
1339  dstPos+= bits;
1340  len-= bits;
1341  }
1342 
1343  return;
1344 }
1345 
1346 #endif