source: Sophya/trunk/SophyaLib/TArray/bitvector.cc@ 4059

Last change on this file since 4059 was 4055, checked in by cmv, 13 years ago

Vecteurs de bits, cmv 30/03/2012

File size: 6.5 KB
Line 
1#include "sopnamsp.h"
2#include "machdefs.h"
3#include <iostream>
4
5#include "bitvector.h"
6#include "pexceptions.h"
7#include "fiondblock.h"
8
9namespace SOPHYA {
10
11//! create a vecsize element vector than can handle AT LEAST nbits bits (set to 0)
12BitVector::BitVector(uint_8 nbits,uint_4 vecsize)
13: nbits_(nbits), vecsize_(vecsize)
14{
15 if(vecsize_==0) vecsize_ = 128;
16 bitpervec_ = vecsize_ * BitVec_BITPERWORD_;
17 nvector_ = nbits_ / bitpervec_ + 1;
18 for(uint_8 i=0;i<nvector_;i++) {
19 NDataBlock<BitVec_Type> V(vecsize_);
20 V = (BitVec_Type)0;
21 vv_.push_back(V);
22 }
23 nbits_ = nvector_ * bitpervec_;
24}
25
26//! copy constructor: data are shared
27BitVector::BitVector(BitVector const& bv)
28: nbits_(bv.nbits_), vecsize_(bv.vecsize_), bitpervec_(bv.bitpervec_), nvector_(bv.nvector_)
29{
30 if(nvector_==0) return;
31 // attention: partage de reference
32 for(uint_8 i=0;i<nvector_;i++) vv_.push_back(bv.vv_[i]);
33}
34
35//! default constructor
36BitVector::BitVector(void)
37: nbits_(0), vecsize_(0), bitpervec_(0), nvector_(0)
38{
39}
40
41//! destructor
42BitVector::~BitVector(void)
43{
44 delete_();
45}
46
47//! delete
48void BitVector::delete_(void)
49{
50 nbits_ = 0;
51 vecsize_ = 0;
52 bitpervec_ = 0;
53 nvector_ = 0;
54 vv_.resize(0);
55}
56
57//! extend bit vector to contain nbitsnew bits
58void BitVector::extend_(uint_8 nbitsnew)
59{
60 if(nbitsnew<=nbits_) return;
61 uint_8 nvectornew = nbitsnew / bitpervec_ + 1;
62 if(nvectornew<=nvector_) return;
63 for(uint_8 i=nvector_;i<nvectornew;i++) {
64 NDataBlock<BitVec_Type> V(vecsize_);
65 V = (BitVec_Type)0;
66 vv_.push_back(V);
67 }
68 nvector_ = vv_.size();
69 nbits_ = nvector_ * bitpervec_;
70}
71
72//! operator = : data are duplcated
73BitVector& BitVector::operator = (const BitVector& bv)
74{
75 if(this == &bv) return *this;
76
77 nbits_ = bv.nbits_;
78 vecsize_ = bv.vecsize_;
79 bitpervec_ = vecsize_ * BitVec_BITPERWORD_;
80 nvector_ = bv.nvector_;
81 vv_.resize(0);
82
83 if(nvector_!=0) {
84 for(uint_8 i=0;i<nvector_;i++) {
85 NDataBlock<BitVec_Type> V(bv.vv_[i],false); // copie des donnees
86 vv_.push_back(V);
87 }
88 }
89
90 return *this;
91}
92
93// set all bit vector to v
94BitVector& BitVector::operator = (bool v)
95{
96 if(nvector_==0) return *this;
97
98 BitVec_Type veltv = 0; if(v) veltv = ~veltv;
99 for(uint_8 i=0;i<nvector_;i++) vv_[i] = veltv;
100
101 return *this;
102}
103
104/*! make AND between 2 vectors
105\verbatim
106If (*this) has extra length:
107 putextra = -1 : put extra bits to false
108 = 0 : let extra bits to their value
109 = +1 : put extra bits to true
110\endverbatim
111*/
112BitVector& BitVector::AND(const BitVector& bv,int putextra)
113{
114 uint_8 nbits = (nbits_<=bv.nbits_) ? nbits_: bv.nbits_;
115 if(nbits==0) return *this;
116 for(uint_8 i=0;i<nbits;i++) {
117 BitVec_Type v = (*this)(i) & bv(i);
118 this->Set(i,(bool)v);
119 }
120 if(putextra!=0 && nbits_>nbits) {
121 bool v = (putextra>0) ? true: false;
122 for(uint_8 i=nbits;i<nbits_;i++) this->Set(i,v);
123 }
124 return *this;
125}
126
127/*! make OR between 2 vectors
128\verbatim
129If (*this) has extra length:
130 putextra = -1 : put extra bits to false
131 = 0 : let extra bits to their value
132 = +1 : put extra bits to true
133\endverbatim
134*/
135BitVector& BitVector::OR(const BitVector& bv,int putextra)
136{
137 uint_8 nbits = (nbits_<=bv.nbits_) ? nbits_: bv.nbits_;
138 if(nbits==0) return *this;
139 for(uint_8 i=0;i<nbits;i++) {
140 BitVec_Type v = (*this)(i) | bv(i);
141 this->Set(i,(bool)v);
142 }
143 if(putextra!=0 && nbits_>nbits) {
144 bool v = (putextra>0) ? true: false;
145 for(uint_8 i=nbits;i<nbits_;i++) this->Set(i,v);
146 }
147 return *this;
148}
149
150// negate all bits
151BitVector& BitVector::Negate(void)
152{
153 if(nvector_==0) return *this;
154 for(uint_8 i=0;i<nvector_;i++)
155 for(uint_8 j=0;j<vecsize_;j++) vv_[i](j) = ~(vv_[i](j));
156 return *this;
157}
158
159//! return bit k
160bool BitVector::operator() (uint_8 k) const
161{
162 if(k>=nbits_) throw(RangeCheckError("bool BitVector::operator(): indices out of range \n"));
163
164 uint_8 nv = k / bitpervec_; // numero du vecteur
165 k %= bitpervec_;
166 uint_8 iv = k / BitVec_BITPERWORD_; // numero de l'element du vecteur
167 k %= BitVec_BITPERWORD_; // numero de bit dans l'element du vecteur
168
169 return ( vv_[nv](iv) & (1ULL<<k) );
170}
171
172//! set bit k to v (with automatic extend)
173void BitVector::Set(uint_8 k,bool v)
174{
175 if(k>nbits_) extend_(k);
176
177 uint_8 nv = k / bitpervec_; // numero du vecteur
178 k %= bitpervec_;
179 uint_8 iv = k / BitVec_BITPERWORD_; // numero de l'element du vecteur
180 k %= BitVec_BITPERWORD_; // numero de bit dans l'element du vecteur
181
182 if(v) vv_[nv](iv) |= (1ULL<<k); else vv_[nv](iv) &= ~(1ULL<<k);
183}
184
185//! set bits [k1,k2] to v (no automatic extend)
186void BitVector::Set(uint_8 k1,uint_8 k2,bool v)
187{
188 if(k1>=nbits_) return;
189 if(k2<k1 || k2>=nbits_) k2 = nbits_ - 1;
190 for(uint_8 k=k1;k<=k2;k++) Set(k,v);
191}
192
193//! Return the number of bits with value v (true/false)
194uint_8 BitVector::NValues(bool v)
195{
196 uint_8 n = 0;
197 if(nbits_==0) return n;
198 for(uint_8 i=0;i<nbits_;i++) if((*this)(i)==v) n++;
199 return n;
200}
201
202//! print bit vector between [k1,k1+dk[, if dk=0 don't print elements, dk<0 print [k1,nbits[
203void BitVector::Print(uint_8 k1,int_8 dk)
204{
205 cout<<"BitVector::Print: nbits="<<nbits_<<" nvector="<<nvector_
206 <<" vecsize="<<vecsize_<<" bitpervec="<<bitpervec_<<" ("<<nbits_/8000000.<<" MB)"<<endl;
207 if(k1>=nbits_ || dk==0) return;
208 uint_8 k2 = k1 + dk;
209 if(k2>nbits_ || k2<=k1) k2 = nbits_;
210 if(k1!=0) cout<<"print ["<<k1<<","<<k2<<"["<<endl;
211 for(uint_8 k=k1;k<k2;k++) cout<<(*this)(k);
212 cout<<endl;
213}
214
215//-----------------------------------------------------
216DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
217void ObjFileIO<BitVector>::WriteSelf(POutPersist& s) const
218{
219 if (dobj == NULL) return;
220 s.Put(dobj->nbits_);
221 s.Put(dobj->vecsize_);
222 s.Put(dobj->bitpervec_);
223 s.Put(dobj->nvector_);
224 if(dobj->nvector_==0) return;
225 /* A REMPLACER par l'ecriture directe de vector< NDataBlock<uint_8> > */
226 for(uint_8 i=0;i<dobj->nvector_;i++) s << dobj->vv_[i];
227 return;
228}
229
230DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
231void ObjFileIO<BitVector>::ReadSelf(PInPersist& s)
232{
233 if (dobj == NULL) dobj = new BitVector;
234 else dobj->delete_();
235 s.Get(dobj->nbits_);
236 s.Get(dobj->vecsize_);
237 s.Get(dobj->bitpervec_);
238 s.Get(dobj->nvector_);
239 if(dobj->nvector_==0) return;
240 /* A REMPLACER par la lecture directe de vector< NDataBlock<uint_8> > */
241 for(uint_8 i=0;i<dobj->nvector_;i++) {
242 NDataBlock<BitVec_Type> V;
243 s >> V;
244 dobj->vv_.push_back(V);
245 }
246
247 return;
248}
249
250#ifdef __CXX_PRAGMA_TEMPLATES__
251#pragma define_template ObjFileIO<BitVector>
252#endif
253
254#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
255template class ObjFileIO<BitVector>;
256#endif
257
258} // FIN namespace SOPHYA
Note: See TracBrowser for help on using the repository browser.