mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 18:31:55 -04:00
copy BitArray by reference
This commit is contained in:
parent
8933f78230
commit
bf6bb54c31
@ -518,3 +518,20 @@ operator >> (int shift) const {
|
||||
result >>= shift;
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::copy_on_write
|
||||
// Access: Private
|
||||
// Description: Called internally just before writing to the _array
|
||||
// member, this makes a new copy of _array if it appears
|
||||
// to be shared with any other objects--thus achieving
|
||||
// copy-on-write.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void BitArray::
|
||||
copy_on_write() {
|
||||
if (_array.get_ref_count() > 1) {
|
||||
PTA(MaskType) new_array;
|
||||
new_array.v() = _array.v();
|
||||
_array = new_array;
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ is_zero() const {
|
||||
}
|
||||
|
||||
// Start from the high end, since that's more likely to be nonzero.
|
||||
Array::const_reverse_iterator ai;
|
||||
Array::reverse_iterator ai;
|
||||
for (ai = _array.rbegin(); ai != _array.rend(); ++ai) {
|
||||
if ((*ai) != 0) {
|
||||
return false;
|
||||
@ -157,6 +157,7 @@ clear_range(int low_bit, int size) {
|
||||
void BitArray::
|
||||
invert_in_place() {
|
||||
_highest_bits = !_highest_bits;
|
||||
copy_on_write();
|
||||
Array::iterator ai;
|
||||
for (ai = _array.begin(); ai != _array.end(); ++ai) {
|
||||
(*ai) = ~(*ai);
|
||||
@ -328,6 +329,8 @@ void BitArray::
|
||||
operator &= (const BitArray &other) {
|
||||
size_t num_common_words = min(_array.size(), other._array.size());
|
||||
|
||||
copy_on_write();
|
||||
|
||||
// Consider the words that are on top of either array.
|
||||
if (other._array.size() < _array.size() && !other._highest_bits) {
|
||||
// The other array has fewer actual words, and the top n words of
|
||||
@ -365,6 +368,8 @@ void BitArray::
|
||||
operator |= (const BitArray &other) {
|
||||
size_t num_common_words = min(_array.size(), other._array.size());
|
||||
|
||||
copy_on_write();
|
||||
|
||||
// Consider the words that are on top of either array.
|
||||
if (other._array.size() < _array.size() && other._highest_bits) {
|
||||
// The other array has fewer actual words, and the top n words of
|
||||
@ -402,6 +407,8 @@ void BitArray::
|
||||
operator ^= (const BitArray &other) {
|
||||
size_t num_common_words = min(_array.size(), other._array.size());
|
||||
|
||||
copy_on_write();
|
||||
|
||||
// Consider the words that are on top of either array.
|
||||
if (other._array.size() < _array.size() && other._highest_bits) {
|
||||
// The other array has fewer actual words, and the top n words of
|
||||
@ -478,7 +485,7 @@ operator <<= (int shift) {
|
||||
for (ai = _array.begin(); ai != _array.end(); ++ai) {
|
||||
new_array.push_back(*ai);
|
||||
}
|
||||
_array.swap(new_array);
|
||||
_array = new_array;
|
||||
|
||||
} else {
|
||||
// Harder case--we have to shuffle bits between words.
|
||||
@ -508,7 +515,7 @@ operator <<= (int shift) {
|
||||
next_bits |= ~MaskType::lower_on(b);
|
||||
}
|
||||
new_array.push_back(next_bits);
|
||||
_array.swap(new_array);
|
||||
_array = new_array;
|
||||
}
|
||||
|
||||
normalize();
|
||||
@ -549,7 +556,7 @@ operator >>= (int shift) {
|
||||
for (ai = _array.begin() + w; ai != _array.end(); ++ai) {
|
||||
new_array.push_back(*ai);
|
||||
}
|
||||
_array.swap(new_array);
|
||||
_array = new_array;
|
||||
|
||||
} else {
|
||||
// Harder case--we have to shuffle bits between words.
|
||||
@ -576,7 +583,7 @@ operator >>= (int shift) {
|
||||
next_bits |= ~MaskType::lower_on(upshift_count);
|
||||
}
|
||||
new_array.push_back(next_bits);
|
||||
_array.swap(new_array);
|
||||
_array = new_array;
|
||||
}
|
||||
|
||||
normalize();
|
||||
@ -604,6 +611,8 @@ generate_hash(ChecksumHashGenerator &hashgen) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BitArray::
|
||||
ensure_has_word(int n) {
|
||||
copy_on_write();
|
||||
|
||||
if (_highest_bits) {
|
||||
while (n >= (int)_array.size()) {
|
||||
_array.push_back(MaskType::all_on());
|
||||
@ -625,12 +634,20 @@ ensure_has_word(int n) {
|
||||
void BitArray::
|
||||
normalize() {
|
||||
if (_highest_bits) {
|
||||
while (!_array.empty() && _array.back() == MaskType::all_on()) {
|
||||
if (!_array.empty() && _array.back() == MaskType::all_on()) {
|
||||
copy_on_write();
|
||||
_array.pop_back();
|
||||
while (!_array.empty() && _array.back() == MaskType::all_on()) {
|
||||
_array.pop_back();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (!_array.empty() && _array.back().is_zero()) {
|
||||
if (!_array.empty() && _array.back().is_zero()) {
|
||||
copy_on_write();
|
||||
_array.pop_back();
|
||||
while (!_array.empty() && _array.back().is_zero()) {
|
||||
_array.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "numeric_types.h"
|
||||
#include "typedObject.h"
|
||||
#include "indent.h"
|
||||
#include "pointerToArray.h"
|
||||
|
||||
#include "checksumHashGenerator.h"
|
||||
|
||||
@ -121,11 +122,12 @@ public:
|
||||
void generate_hash(ChecksumHashGenerator &hashgen) const;
|
||||
|
||||
private:
|
||||
INLINE void copy_on_write();
|
||||
void ensure_has_word(int n);
|
||||
void normalize();
|
||||
|
||||
private:
|
||||
typedef pvector<MaskType> Array;
|
||||
typedef PTA(MaskType) Array;
|
||||
Array _array;
|
||||
int _highest_bits; // Either 0 or 1.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user