GetFEM++  5.3
dal_bit_vector.cc
1 /*===========================================================================
2 
3  Copyright (C) 1995-2017 Yves Renard
4 
5  This file is a part of GetFEM++
6 
7  GetFEM++ is free software; you can redistribute it and/or modify it
8  under the terms of the GNU Lesser General Public License as published
9  by the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version along with the GCC Runtime Library
11  Exception either version 3.1 or (at your option) any later version.
12  This program is distributed in the hope that it will be useful, but
13  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15  License and GCC Runtime Library Exception for more details.
16  You should have received a copy of the GNU Lesser General Public License
17  along with this program; if not, write to the Free Software Foundation,
18  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19 
20 ===========================================================================*/
21 
22 
23 #include "getfem/dal_bit_vector.h"
24 
25 namespace dal {
26 
27  bit_reference& bit_reference::operator = (bool x) {
28  if (x) { if (!(*p & mask)) { *p |= mask; bv->change_for_true(ind); } }
29  else { if (*p & mask) { *p &= ~mask; bv->change_for_false(ind); } }
30  return *this;
31  }
32 
33  bit_iterator::bit_iterator(bit_vector &b, size_type i) : p(b, i / WD_BIT)
34  { ind = i; bv = &b, mask = bit_support(1) << (i & WD_MASK); }
35 
36  bit_iterator& bit_iterator::operator+=(difference_type i){
37  ind+=i; mask = bit_support(1) << (ind & WD_MASK);
38  p=bit_container::iterator(*bv, ind/WD_BIT);
39  return *this;
40  }
41 
42  bit_const_iterator::bit_const_iterator(const bit_vector &b, size_type i)
43  : p(b, i / WD_BIT)
44  { ind = i; bv = &b, mask = bit_support(1) << (i & WD_MASK); }
45 
46  bit_const_iterator& bit_const_iterator::operator+=(difference_type i) {
47  ind += i; mask = bit_support(1) << (ind & WD_MASK);
48  p = bit_container::const_iterator(*bv, ind/WD_BIT);
49  return *this;
50  }
51 
52  void bit_vector::fill_false(size_type i1, size_type i2) {
53  size_type f = i1 / WD_BIT, r = i1 & (WD_BIT-1), l = i2 / WD_BIT;
54  (*((bit_container *)(this)))[l];
55  if (r != 0) f++;
56  l++;
57  if (f < l) std::fill(dal::bit_container::begin()+f,
58  dal::bit_container::begin()+l, 0);
59  ilast_false = i2;
60  }
61 
62  void bit_vector::swap(bit_vector &da) {
63  ((bit_container *)(this))->swap(da);
64  std::swap(ifirst_true, da.ifirst_true);
65  std::swap(ifirst_false, da.ifirst_false);
66  std::swap(ilast_true, da.ilast_true);
67  std::swap(ilast_false, da.ilast_false);
68  std::swap(icard, da.icard);
69  std::swap(icard_valid, da.icard_valid);
70  }
71 
72  bit_vector::size_type bit_vector::card(void) const {
73  if (!icard_valid) {
74 // bit_container::const_iterator itb = bit_container::begin()
75 // + ifirst_true/WD_BIT, ite = bit_container::end();
76 // bit_support x;
77  icard = 0;
78 // for (; itb != ite; ++itb) {
79 // if ((x = *itb)) // fast count of the nb of bits
80 // // of an integer (faster than shifts)
81 // do icard++; while ((x &= x-1));
82 // }
83 // icard_valid = true;
84 
85  const_iterator itb = begin(), ite = end();
86  icard = 0;
87  while (itb != ite) { if (*itb) ++icard; ++itb; }
88  icard_valid = true;
89  }
90  return icard;
91  }
92 
93  bit_vector::size_type bit_vector::first_true(void) const {
94  assert(ifirst_true <= ilast_true);
95  const_iterator itx = begin(), ite = end(); itx += ifirst_true;
96  while (itx != ite && !*itx ) { ++itx; ++(ifirst_true); }
97  if (is_in(ifirst_true)) return ifirst_true;
98  else { ifirst_true = ilast_true = 0; return size_type(-1); }
99  }
100 
101  bit_vector::size_type bit_vector::first_false(void) const {
102  const_iterator itx = begin(), ite = end(); itx += ifirst_false;
103  while (itx != ite && *itx) { ++itx; ++(ifirst_false); }
104  if (!is_in(ifirst_false)) return ifirst_false;
105  else { ifirst_false = ilast_false = size()-1; return size_type(-1); }
106  }
107 
108  bit_vector::size_type bit_vector::last_true(void) const {
109  const_iterator itb = begin(), itx = itb; itx += ilast_true;
110  while (itx != itb && !*itx) { --itx; --(ilast_true); }
111  if (is_in(ilast_true)) return ilast_true;
112  else return size_type(-1);
113  }
114 
115  bit_vector::size_type bit_vector::last_false(void) const {
116  const_iterator itb = begin(), itx = itb; itx += ilast_false;
117  while (itx != itb && *itx) { --itx; --(ilast_false); }
118  return ilast_false;
119  }
120 
121  bit_vector &bit_vector::setminus(const bit_vector& b) {
122  for (bv_visitor i(b); !i.finished(); ++i) del(i);
123  return *this;
124  }
125 
126  bit_vector &bit_vector::operator |=(const bit_vector &bv) {
127  for (bv_visitor i(bv); !i.finished(); ++i) add(i);
128  return *this;
129  }
130 
131  bit_vector &bit_vector::operator &=(const bit_vector &bv) {
132  bit_container::iterator it1b = bit_container::begin();
133  bit_container::iterator it1e = bit_container::end();
134  bit_container::const_iterator it2b = bv.bit_container::begin();
135  bit_container::const_iterator it2e = bv.bit_container::end();
136 
137  while (it1b != it1e && it2b != it2e) { *it1b++ &= *it2b++; }
138  while (it1b != it1e) { *it1b++ = 0; }
139  icard_valid = false;
140  ifirst_true = std::max(ifirst_true, bv.ifirst_true);
141  ilast_true = std::min(ilast_true, bv.ilast_true);
142  if (ifirst_true > ilast_true) clear();
143  else {
144  ilast_false = std::min(size()-1, std::max(ilast_false,bv.ilast_false));
145  ifirst_false = std::min(ifirst_false, bv.ifirst_false);
146  }
147  return *this;
148  }
149 
150  bool bit_vector::operator ==(const bit_vector &bv) const {
151  bit_container::const_iterator it1b = bit_container::begin();
152  bit_container::const_iterator it1e = bit_container::end();
153  bit_container::const_iterator it2b = bv.bit_container::begin();
154  bit_container::const_iterator it2e = bv.bit_container::end();
155 
156  while (it1b!=it1e && it2b!=it2e) if (*it1b++ != *it2b++) return false;
157  while (it1b != it1e) if (*it1b++ != 0) return false;
158  while (it2b != it2e) if (*it2b++ != 0) return false;
159  return true;
160  }
161 
162  void bit_vector::add(size_type i, size_type nb) {
163  if (nb)
164  { add(i+nb-1); std::fill(this->begin()+i, this->begin()+(i+nb), true); }
165  }
166 
167  void bit_vector::sup(size_type i, size_type nb) {
168  if (nb)
169  { del(i+nb-1); std::fill(this->begin()+i, this->begin()+(i+nb), false); }
170  }
171 
172  void bit_vector::del(size_type i, size_type nb) {
173  if (nb)
174  { del(i+nb-1); std::fill(this->begin()+i, this->begin()+(i+nb), false); }
175  }
176 
177  bool bit_vector::contains(const dal::bit_vector& other) const {
178  for (dal::bv_visitor i(other); !i.finished(); ++i)
179  if (!this->is_in(i)) return false;
180  return true;
181  }
182 
183  std::ostream &operator <<(std::ostream &o, const bit_vector &s) {
184  bool first = true;
185  o << "[";
186  for (bv_visitor i(s); !i.finished(); ++i) {
187  if (!first) o << " ";
188  o << bit_vector::size_type(i);
189  first = false;
190  }
191  o << "]";
192  return o;
193  }
194 
195  bool bv_visitor::operator++() {
196  while (1) {
197  size_type ind_b = (ind&(~WD_MASK));
198  while (v) {
199  ++ind; v >>= 1;
200  if (v&1) return true;
201  }
202  ind = ind_b + WD_BIT;
203  if (ind >= ilast) return false;
204  v = *(++it);
205  if (v&1) return true;
206  }
207  }
208 
209  const_bv_iterator<bv_iterable> bv_iterable::begin() const{
210  return const_bv_iterator<bv_iterable>(this, v_.first_true());
211  }
212  const_bv_iterator<bv_iterable> bv_iterable::end() const{
213  return const_bv_iterator<bv_iterable>(this, v_.last_true() + 1);
214  }
215 
216  const_bv_iterator<bv_iterable_c> bv_iterable_c::begin() const{
217  return const_bv_iterator<bv_iterable_c>(this, v_.first_true());
218  }
219  const_bv_iterator<bv_iterable_c> bv_iterable_c::end() const{
220  return const_bv_iterator<bv_iterable_c>(this, v_.last_true() + 1);
221  }
222 }
223 
Provide a dynamic bit container.
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:49
Dynamic Array Library.
void clear(L &l)
clear (fill with zeros) a vector or matrix.
Definition: gmm_blas.h:59
void add(const L1 &l1, L2 &l2)
*/
Definition: gmm_blas.h:1268