Skip to content
Snippets Groups Projects
Commit 0b3b1274 authored by Lasse Hinrichsen-Bischoff's avatar Lasse Hinrichsen-Bischoff
Browse files

Fix createbegin() iterators of VariableBlockVector

See issue #56.
parent 74a4964d
No related branches found
No related tags found
1 merge request!250Fix VariableBlockVector's CreateIterator
......@@ -406,61 +406,27 @@ namespace Dune {
{
public:
//! constructor
CreateIterator (VariableBlockVector& _v, int _i) : v(_v)
{
i = _i;
k = 0;
n = 0;
CreateIterator (VariableBlockVector& _v, int _i, bool _isEnd) :
v(_v),
i(_i),
isEnd(_isEnd) {}
~CreateIterator() {
// When the iterator gets destructed, we allocate the memory
// for the VariableBlockVector if
// 1. the current iterator was not created as enditarator
// 2. we're at the last block
// 3. the vector hasn't been initialized earlier
if (not isEnd && i==v.nblocks && not v.initialized)
v.allocate();
}
//! prefix increment
CreateIterator& operator++()
{
// we are at block i and the blocks size is known
// set the blocks size to current k
v.block[i].setsize(k);
// accumulate total size
n += k;
// go to next block
++i;
// reset block size
k = 0;
// if we are past the last block, finish off
if (i==v.nblocks)
{
// now we can allocate the big array in the base class of v
v.n = n;
if (n>0)
{
// allocate and construct objects
v.p = v.allocator_.allocate(n);
new (v.p)B[n];
}
else
{
v.n = 0;
v.p = nullptr;
}
// and we set the window pointer
if (v.nblocks>0)
{
v.block[0].setptr(v.p); // pointer tofirst block
for (size_type j=1; j<v.nblocks; ++j) // and the rest
v.block[j].setptr(v.block[j-1].getptr()+v.block[j-1].getsize());
}
// and the vector is ready
v.initialized = true;
//std::cout << "made vbvector with " << v.n << " components" << std::endl;
}
return *this;
}
......@@ -493,20 +459,19 @@ namespace Dune {
//! set size of current block
void setblocksize (size_type _k)
{
k = _k;
v.block[i].setsize(_k);
}
//! Access size of current block
size_type& operator*()
{
return k;
return v.block[i].getsize();
}
private:
VariableBlockVector& v; // my vector
size_type i; // current block to be defined
size_type k; // size of current block to be defined
size_type n; // total number of elements to be allocated
const bool isEnd; // flag if this object was created as the end iterator.
};
// CreateIterator wants to set all the arrays ...
......@@ -518,13 +483,13 @@ namespace Dune {
#ifdef DUNE_ISTL_WITH_CHECKING
if (initialized) DUNE_THROW(ISTLError,"no CreateIterator in initialized state");
#endif
return CreateIterator(*this,0);
return CreateIterator(*this,0, false);
}
//! get create iterator pointing to one after the last block
CreateIterator createend ()
{
return CreateIterator(*this,nblocks);
return CreateIterator(*this,nblocks, true);
}
......@@ -712,6 +677,38 @@ namespace Dune {
private:
void allocate() {
if (this->initialized)
DUNE_THROW(ISTLError, "Attempt to re-allocate already initialized VariableBlockVector");
// calculate space needed:
this->n=0;
for(size_type i = 0; i < nblocks; i++) {
this->n += block[i].size();
}
// now we can allocate the big array in the base class of v
if (this->n>0)
{
// allocate and construct objects
this->p = allocator_.allocate(this->n);
new (this->p)B[this->n];
}
else
{
this->p = nullptr;
}
// and we set the window pointers
this->block[0].setptr(this->p); // pointer to first block
for (size_type j=1; j<nblocks; ++j) // and the rest
block[j].setptr(block[j-1].getptr()+block[j-1].getsize());
// and the vector is ready
this->initialized = true;
}
size_type nblocks; // number of blocks in vector
window_type* block; // array of blocks pointing to the array in the base class
bool initialized; // true if vector has been initialized
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment