Core: Bits now have multibit operations

git-svn-id: svn://ultimatepp.org/upp/trunk@11093 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2017-05-16 11:06:14 +00:00
parent 2f14e205c3
commit e8324d029a
4 changed files with 81 additions and 5 deletions

View file

@ -101,6 +101,7 @@ file
Obsolete.h,
Vcont.h,
BiCont.h,
Other.h,
Vcont.hpp,
Vcont.cpp,
Index.h,
@ -112,7 +113,6 @@ file
InVector.hpp,
InMap.hpp,
Tuple.h,
Other.h,
Function readonly separator,
Function.h,
CallbackNP.i highlight cpp,

View file

@ -129,6 +129,10 @@ public:
bool Get(int i) const { ASSERT(i >= 0 && alloc >= 0); int q = i >> 5;
return q < alloc ? bp[q] & (1 << (i & 31)) : false; }
bool operator[](int i) const { return Get(i); }
void Set(int i, dword bits, int count);
void Set64(int i, uint64 bits, int count);
void SetN(int i, int count, bool b = true);
void Reserve(int nbits);
void Shrink();
@ -147,9 +151,6 @@ public:
Bits(Bits&& b) { alloc = b.alloc; bp = b.bp; b.bp = NULL; }
void operator=(Bits&& b) { if(this != &b) { Clear(); alloc = b.alloc; bp = b.bp; b.bp = NULL; } }
#ifdef DEPRECATED
void Set(int i, bool b, int count) { while(count--) Set(i++, b); }
#endif
};
//# System dependent

View file

@ -782,3 +782,78 @@ BiArray<T>::BiArray(std::initializer_list<T> init)
}
#endif
inline
void Bits::Set(int i, dword bits, int count)
{
ASSERT(i >= 0 && alloc >= 0 && count >= 0 && count <= 32);
if(!count) // note: this also avoids problem with (dword)-1 >> 32 being undefined
return;
int q = i >> 5;
i &= 31;
if(q >= alloc)
Expand(q);
if(i == 0 && count == 32) {
bp[q] = bits;
return;
}
dword mask = (dword)-1 >> (32 - count); // does not work for count == 0
bits &= mask;
bp[q] = (bp[q] & ~(mask << i)) | (bits << i);
if(i + count <= 32)
return;
if(++q >= alloc)
Expand(q);
i = 32 - i;
bp[q] = (bp[q] & ~(mask >> i)) | (bits >> i);
}
inline
void Bits::Set64(int i, uint64 bits, int count)
{
if(count > 32) {
Set(i, LODWORD(bits), 32);
Set(i + 32, HIDWORD(bits), count - 32);
}
else
Set(i, LODWORD(bits), count);
}
inline
void Bits::SetN(int i, int count, bool b)
{
ASSERT(i >= 0 && alloc >= 0);
if(!count) // note: this also avoids problem with (dword)-1 >> 32 being undefined
return;
dword bits = (dword)0 - b;
int q = i >> 5;
i &= 31;
if(q >= alloc)
Expand(q);
int n = min(32 - i, count); // number of bits to dword boundary (or count if smaller)
dword mask = (dword)-1 >> (32 - n);
bp[q] = (bp[q] & ~(mask << i)) | ((bits & mask) << i);
count -= n;
if(!count)
return;
int dw_count = count >> 5;
if(++q + dw_count >= alloc)
Expand(q + dw_count);
while(dw_count) {
bp[q++] = bits;
dw_count--;
}
count = count & 31; // remaining bits to set
if(!count)
return;
if(q >= alloc)
Expand(q);
mask = (dword)-1 >> (32 - count);
bp[q] = (bp[q] & ~mask) | (bits & mask);
}

View file

@ -39,7 +39,7 @@ Bits RichEdit::SpellParagraph(const RichPara& para)
while(s < end && IsLetter(*s) || s + 1 < end && *s == '\'' && IsLetter(s[1]))
s++;
if(!SpellWord(q, int(s - q), lang[q - text]))
e.Set(int(q - text), true, int(s - q));
e.SetN(int(q - text), int(s - q));
}
else
s++;