LSSTApplications  1.1.2+25,10.0+13,10.0+132,10.0+133,10.0+224,10.0+41,10.0+8,10.0-1-g0f53050+14,10.0-1-g4b7b172+19,10.0-1-g61a5bae+98,10.0-1-g7408a83+3,10.0-1-gc1e0f5a+19,10.0-1-gdb4482e+14,10.0-11-g3947115+2,10.0-12-g8719d8b+2,10.0-15-ga3f480f+1,10.0-2-g4f67435,10.0-2-gcb4bc6c+26,10.0-28-gf7f57a9+1,10.0-3-g1bbe32c+14,10.0-3-g5b46d21,10.0-4-g027f45f+5,10.0-4-g86f66b5+2,10.0-4-gc4fccf3+24,10.0-40-g4349866+2,10.0-5-g766159b,10.0-5-gca2295e+25,10.0-6-g462a451+1
LSSTDataManagementBasePackage
Bitset.cc
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 
3 /*
4  * LSST Data Management System
5  * Copyright 2008, 2009, 2010 LSST Corporation.
6  *
7  * This product includes software developed by the
8  * LSST Project (http://www.lsst.org/).
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the LSST License Statement and
21  * the GNU General Public License along with this program. If not,
22  * see <http://www.lsstcorp.org/LegalNotices/>.
23  */
24 
25 
33 #include <climits>
34 
35 #include "lsst/ap/Bitset.h"
36 
37 using boost::uint8_t;
38 using boost::uint16_t;
39 using boost::uint32_t;
40 using boost::uint64_t;
41 
42 namespace lsst { namespace ap { namespace detail { namespace {
43 
44 #if LSST_AP_HAVE_BUILTIN_POPCOUNT
45 
46 inline int populationCount(uint64_t const val) {
47 # if ULLONG_MAX == 0xffffffffffffffff
48  return __builtin_popcountll(val);
49 # elif ULONG_MAX == 0xffffffffffffffff
50  return __builtin_popcountl(val);
51 # else
52 # error Unable to map between uint64_t and built-in integral types
53 # endif
54 }
55 
56 inline int populationCount(uint32_t const val) {
57 # if ULONG_MAX == 0xffffffff
58  return __builtin_popcountl(val);
59 # elif UINT_MAX == 0xffffffff
60  return __builtin_popcount(val);
61 # else
62 # error Unable to map between uint32_t and built-in integral types
63 # endif
64 }
65 
66 inline int populationCount(uint16_t const val) { return __builtin_popcount(val); }
67 inline int populationCount(uint8_t const val) { return __builtin_popcount(val); }
68 
69 #else
70 
71 uint64_t const sFreedMagic64[6] = {
72  UINT64_C(0x5555555555555555),
73  UINT64_C(0x3333333333333333),
74  UINT64_C(0x0F0F0F0F0F0F0F0F),
75  UINT64_C(0x00FF00FF00FF00FF),
76  UINT64_C(0x0000FFFF0000FFFF),
77  UINT64_C(0x00000000FFFFFFFF)
78 };
79 
80 uint32_t const sFreedMagic32[5] = {
81  0x55555555,
82  0x33333333,
83  0x0F0F0F0F,
84  0x00FF00FF,
85  0x0000FFFF
86 };
87 
88 // count bits with sideways addition using Freed's binary magic numbers
89 
90 inline int populationCount(uint64_t const val) {
91  uint64_t v = val;
92  v = ((v >> 1) & sFreedMagic64[0]) + (v & sFreedMagic64[0]);
93  v = ((v >> 2) & sFreedMagic64[1]) + (v & sFreedMagic64[1]);
94  v = ((v >> 4) & sFreedMagic64[2]) + (v & sFreedMagic64[2]);
95  v = ((v >> 8) & sFreedMagic64[3]) + (v & sFreedMagic64[3]);
96  v = ((v >> 16) & sFreedMagic64[4]) + (v & sFreedMagic64[4]);
97  v = ((v >> 32) & sFreedMagic64[5]) + (v & sFreedMagic64[5]);
98  return v;
99 }
100 
101 inline int populationCount(uint32_t const val) {
102  uint32_t v = val;
103  v = ((v >> 1) & sFreedMagic32[0]) + (v & sFreedMagic32[0]);
104  v = ((v >> 2) & sFreedMagic32[1]) + (v & sFreedMagic32[1]);
105  v = ((v >> 4) & sFreedMagic32[2]) + (v & sFreedMagic32[2]);
106  v = ((v >> 8) & sFreedMagic32[3]) + (v & sFreedMagic32[3]);
107  v = ((v >> 16) & sFreedMagic32[4]) + (v & sFreedMagic32[4]);
108  return v;
109 }
110 
111 inline int populationCount(uint16_t const val) {
112  uint32_t v = val;
113  v = ((v >> 1) & sFreedMagic32[0]) + (v & sFreedMagic32[0]);
114  v = ((v >> 2) & sFreedMagic32[1]) + (v & sFreedMagic32[1]);
115  v = ((v >> 4) & sFreedMagic32[2]) + (v & sFreedMagic32[2]);
116  v = ((v >> 8) & sFreedMagic32[3]) + (v & sFreedMagic32[3]);
117  return v;
118 }
119 
120 inline int populationCount(uint8_t const val) {
121  uint32_t v = val;
122  v = ((v >> 1) & sFreedMagic32[0]) + (v & sFreedMagic32[0]);
123  v = ((v >> 2) & sFreedMagic32[1]) + (v & sFreedMagic32[1]);
124  v = ((v >> 4) & sFreedMagic32[2]) + (v & sFreedMagic32[2]);
125  return v;
126 }
127 
128 #endif
129 
130 }}}} // end of namespace lsst::ap::detail::<anonymous>
131 
132 
148 template <typename WordT>
150  int * const indexes,
151  WordT * const words,
152  int const numBitsToSet,
153  int const numBits
154 ) {
155  assert(words != 0 && numBits > 0 && "null or empty bitset");
156  assert(indexes != 0 && numBitsToSet > 0 && "null or empty index array");
157 
158  bool const special = (numBits & (BitTraits<WordT>::BITS_PER_WORD - 1)) > 0;
159  WordT const last = ~(maskForBit<WordT>(numBits) - 1);
160  int const nwords = (numBits + (BitTraits<WordT>::BITS_PER_WORD - 1)) >>
162 
163  int zeroes = numBitsToSet;
164  int i;
165  for (i = 0; i < nwords - special && zeroes > 0; ++i) {
167  populationCount(static_cast<WordT>(words[i] & BitTraits<WordT>::WORD_MASK));
168  }
169  if (zeroes > 0 && special) {
171  populationCount(static_cast<WordT>((words[i] & BitTraits<WordT>::WORD_MASK) | last));
172  }
173  if (zeroes > 0) {
174  // didn't find enough zeroes
175  return false;
176  }
177 
178  zeroes = 0;
179  for (int i = 0; zeroes < numBitsToSet; ++i) {
180  WordT w = words[i] & BitTraits<WordT>::WORD_MASK;
181  if (w == BitTraits<WordT>::WORD_MASK) {
182  continue;
183  }
184  WordT mask = 1;
185  for (int j = 0; j < BitTraits<WordT>::BITS_PER_WORD; ++j, mask <<= 1) {
186  if ((w & mask) == 0) {
187  indexes[zeroes++] = (i << BitTraits<WordT>::BITS_PER_WORD_LOG2) + j;
188  w |= mask;
189  if (zeroes == numBitsToSet) {
190  break;
191  }
192  }
193  }
194  words[i] = w;
195  }
196 
197  return true;
198 }
199 
200 
211 template <typename WordT>
213  WordT * const words,
214  int const * const indexes,
215  int const numBitsToReset,
216  int const numBits
217 ) {
218  assert(words != 0 && numBits > 0 && "null or empty bitset");
219  assert(indexes != 0 && numBitsToReset >= 0 && "null or empty index array");
220 
221  for (int i = 0; i < numBitsToReset; ++i) {
222  int const j = indexes[i];
223  assert(j >= 0 && j < numBits);
224  words[wordForBit<WordT>(j)] &= ~ maskForBit<WordT>(j);
225  }
226 }
227 
228 // Explicit instantiations
230 #define INSTANTIATE(t) \
231  template bool lsst::ap::detail::setBits(int * const, t * const, int const, int const); \
232  template void lsst::ap::detail::resetBits(t * const, int const * const, int const, int const);
233 
234 INSTANTIATE(uint8_t)
235 INSTANTIATE(uint16_t)
236 INSTANTIATE(uint32_t)
237 INSTANTIATE(uint64_t)
238 
A class for manipulating a fixed set of bits at the individual bit level.
double w
Definition: CoaddPsf.cc:57
#define INSTANTIATE(TYPE)
Definition: ImagePca.cc:128
void resetBits(WordT *const words, int const *const indexes, int const numBitsToReset, int const numBits)
Definition: Bitset.cc:212
bool setBits(int *const indexes, WordT *const words, int const numBitsToSet, int const numBits)
Definition: Bitset.cc:149
ImageT val
Definition: CR.cc:154