Skip to content
Snippets Groups Projects
Commit 64820a54 authored by Markus Blatt's avatar Markus Blatt
Browse files

Bugfixes with fixed code redundancy.

It seems like I finally found the bug in the
poolallocator. Unfortunately I cannot recall what it was.

Still the static memory pool in the pool allocator seems to prevent
the destructor of sllist from being called sometimes. This is annoying!

[[Imported from SVN: r2079]]
parent b9b4a526
No related branches found
No related tags found
No related merge requests found
......@@ -6,17 +6,47 @@
#include "alignment.hh"
#include "helpertemplates.hh"
#include <typeinfo>
#include "lcm.hh"
//#include<typeinfo>
#include <iostream>
template<std::size_t size, typename T>
int testPool();
//forward declarations.
namespace Dune
{
template<typename T, std::size_t size>
class Pool;
template<typename T, std::size_t s>
class PoolAllocator;
}
namespace std
{
template<class T, std::size_t S>
inline ostream& operator<<(ostream& os, Dune::Pool<T,S>& pool)
{
os<<"pool="<<&pool<<" allocated_="<<pool.allocated_;
return os;
}
template<class T, std::size_t S>
inline ostream& operator<<(ostream& os, Dune::PoolAllocator<T,S>& pool)
{
os<<pool.memoryPool_<<std::endl;
return os;
}
}
namespace Dune
{
/**
* @file
* This file implements the class ArrayList which behaves like
......@@ -51,6 +81,8 @@ namespace Dune
{
friend int ::testPool<s,T>();
friend std::ostream& std::operator<<<>(std::ostream&,Pool<T,s>&);
private:
/** @brief Reference to next free element. */
......@@ -65,13 +97,25 @@ namespace Dune
typedef T MemberType;
enum
{
/**
* @brief The size of a union of Reference and MemberType.
*/
unionSize = ((sizeof(MemberType) < sizeof(Reference)) ?
sizeof(Reference) : sizeof(MemberType)),
/**
* @brief size requirement. At least one object has to
* @brief Size requirement. At least one object has to
* stored.
*/
size = (sizeof(MemberType) <= s && sizeof(Reference) <= s) ? s
: ((sizeof(MemberType) < sizeof(Reference)) ? sizeof(Reference)
: sizeof(MemberType)),
size = ((sizeof(MemberType) <= s && sizeof(Reference) <= s) ?
s : unionSize),
/**
* @brief The alignment that suits both the MemberType and
* the Reference (i.e. their least common multiple).
*/
alignment = Lcm<AlignmentOf<MemberType>::value,AlignmentOf<Reference>::value>::value,
/**
* @brief The aligned size of the type.
......@@ -79,9 +123,9 @@ namespace Dune
* This size is bigger than sizeof of the type and a multiple of
* the alignment requirement.
*/
alignedSize = (size % AlignmentOf<MemberType>::value == 0) ?
size : ((size / AlignmentOf<MemberType>::value + 1)
* AlignmentOf<MemberType>::value),
alignedSize = ((unionSize % alignment == 0) ?
unionSize :
((unionSize / alignment + 1) * alignment)),
/**
* @brief The size of each chunk memory chunk.
......@@ -90,15 +134,14 @@ namespace Dune
* an offset to handle the case that the pointer to the memory
* does not satisfy the alignment requirements.
*/
chunkSize = ((size % AlignmentOf<MemberType>::value == 0) ? size :
((size / AlignmentOf<MemberType>::value + 1)
* AlignmentOf<MemberType>::value))
+ AlignmentOf<MemberType>::value - 1,
chunkSize = ((size % alignment == 0) ?
size : ((size / alignment + 1)* alignment))
+ alignment - 1,
/**
* @brief The number of element each chunk can hold.
*/
elements = ((chunkSize - AlignmentOf<MemberType>::value + 1)/ alignedSize)
elements = ((chunkSize - alignment + 1)/ alignedSize)
};
private:
......@@ -126,9 +169,9 @@ namespace Dune
Chunk()
{
unsigned long lmemory = reinterpret_cast<unsigned long>(chunk_);
if(lmemory % AlignmentOf<MemberType>::value != 0)
lmemory = (lmemory / AlignmentOf<MemberType>::value + 1)
* AlignmentOf<MemberType>::value;
if(lmemory % alignment != 0)
lmemory = (lmemory / alignment + 1)
* alignment;
memory_ = reinterpret_cast<char *>(lmemory);
}
......@@ -146,20 +189,23 @@ namespace Dune
* @brief Get a new or recycled object
* @return A pointer to the object memory.
*/
inline void *allocate();
inline T *allocate();
/**
* @brief Free an object.
* @param o The pointer to memory block of the object.
*/
inline void free(void* o);
inline void print();
/**
* @brief Print elements in pool for debugging.
*/
inline void print(std::ostream& os);
private:
// Prevent Copying!
Pool(const Pool<MemberType,s>&);
void operator=(const Pool<MemberType,s>& pool) const;
/** @brief Grow our pool.*/
inline void grow();
......@@ -167,6 +213,9 @@ namespace Dune
Reference *head_;
/** @brief Our memory chunks. */
Chunk *chunks_;
/* @brief The number of currently allocated elements. */
size_t allocated_;
};
/**
......@@ -182,6 +231,8 @@ namespace Dune
template<class T, std::size_t s>
class PoolAllocator
{
friend std::ostream& std::operator<<<>(std::ostream&,PoolAllocator<T,s>&);
public:
/**
* @brief Type of the values we construct and allocate.
......@@ -217,11 +268,28 @@ namespace Dune
*/
typedef const T& const_reference;
/**
* @brief The size type.
*/
typedef std::size_t size_type;
/**
* @brief The difference_type.
*/
typedef std::ptrdiff_t difference_type;
/**
* @brief Constructor.
*/
inline PoolAllocator();
/**
* @brief Coopy Constructor.
*/
template<typename U, std::size_t u>
inline PoolAllocator(const PoolAllocator<U,u>&)
{};
/**
* @brief Allocates objects.
* @param n The number of objects to allocate. Has to be less
......@@ -267,7 +335,7 @@ namespace Dune
/**
* @brief Not correctly implemented, yet!
*/
inline int max_size(){ return 1;}
inline int max_size() const throw(){ return 1;}
/**
* @brief Rebind the allocator to another type.
......@@ -285,23 +353,119 @@ namespace Dune
static Pool<T,s> memoryPool_;
};
// specialization for void
template <std::size_t s>
class PoolAllocator<void,s>
{
public:
typedef void* pointer;
typedef const void* const_pointer;
// reference to void members are impossible.
typedef void value_type;
template <class U> struct rebind
{
typedef PoolAllocator<U,s> other;
};
template<typename T, std::size_t t>
PoolAllocator(const PoolAllocator<T,t>&)
{}
};
template<typename T1, std::size_t t1, typename T2, std::size_t t2>
bool operator==(const PoolAllocator<T1,t1>&, const PoolAllocator<T2,t2>&)
{
return false;
}
template<typename T1, std::size_t t1, typename T2, std::size_t t2>
bool operator!=(const PoolAllocator<T1,t1>&, const PoolAllocator<T2,t2>&)
{
return true;
}
template<typename T, std::size_t t1, std::size_t t2>
bool operator==(const PoolAllocator<T,t1>&, const PoolAllocator<T,t2>&)
{
return Pool<T,t1>::chunkSize == Pool<T,t2>::chunkSize;
}
template<typename T, std::size_t t1, std::size_t t2>
bool operator!=(const PoolAllocator<T,t1>&, const PoolAllocator<T,t2>&)
{
return Pool<T,t1>::chunkSize != Pool<T,t2>::chunkSize;
}
template<typename T, std::size_t t1, std::size_t t2>
bool operator==(const PoolAllocator<T,t1>&, const PoolAllocator<void,t2>&)
{
return false;
}
template<typename T, std::size_t t1, std::size_t t2>
bool operator!=(const PoolAllocator<T,t1>&, const PoolAllocator<void,t2>&)
{
return true;
}
template<typename T, std::size_t t1, std::size_t t2>
bool operator==(const PoolAllocator<void,t1>&, const PoolAllocator<T,t2>&)
{
return false;
}
template<typename T, std::size_t t1, std::size_t t2>
bool operator!=(const PoolAllocator<void,t1>&, const PoolAllocator<T,t2>&)
{
return true;
}
template<std::size_t t1, std::size_t t2>
bool operator==(const PoolAllocator<void,t1>&, const PoolAllocator<void,t2>&)
{
return true;
}
template<std::size_t t1, std::size_t t2>
bool operator!=(const PoolAllocator<void,t1>&, const PoolAllocator<void,t2>&)
{
return false;
}
template<class T, std::size_t S>
inline Pool<T,S>::Pool()
: head_(0), chunks_(0)
: head_(0), chunks_(0), allocated_(0)
{
IsTrue<sizeof(T)<=size>::yes();
IsTrue<sizeof(Reference)<=size>::yes();
IsTrue<sizeof(T)<=alignedSize>::yes();
IsTrue<sizeof(Reference)<=alignedSize>::yes();
IsTrue<sizeof(T)<=unionSize>::yes();
IsTrue<sizeof(Reference)<=unionSize>::yes();
IsTrue<unionSize<=alignedSize>::yes();
IsTrue<sizeof(T)<=chunkSize>::yes();
IsTrue<sizeof(Reference)<=chunkSize>::yes();
IsTrue<(chunkSize - (AlignmentOf<T>::value - 1)) % AlignmentOf<T>::value == 0>::yes();
IsTrue<(chunkSize - (alignment - 1)) % alignment == 0>::yes();
IsTrue<elements>=1>::yes();
IsTrue<elements*alignedSize<=chunkSize>::yes();
/*
std::cout<<"S="<<S<<" sizeof(MemberType)="<<sizeof(MemberType)<<" sizeof(Reference)="<<sizeof(Reference)
<<" alignment="<<alignment<<" unionSize="<<unionSize<<" size="<<size
<<" alignedSize="<<alignedSize<<" chunkSize="<<chunkSize<<" elements="<<elements<<std::endl;
*/
}
template<class T, std::size_t S>
inline Pool<T,S>::~Pool()
{
if(allocated_!=0)
std::cerr<<"There are still "<<allocated_<<" allocated elements by the pool "
<<static_cast<void*>(this)<<"! This is a memory leak and might result in segfaults"
<<std::endl;
// delete the allocated chunks.
Chunk *current=chunks_;
......@@ -314,14 +478,14 @@ namespace Dune
}
template<class T, std::size_t S>
inline void Pool<T,S>::print()
inline void Pool<T,S>::print(std::ostream& os)
{
Chunk* current=chunks_;
while(current) {
std::cout<<current<<" ";
os<<current<<" ";
current=current->next_;
}
std::cout<<current<<" ";
os<<current<<" ";
}
template<class T, std::size_t S>
......@@ -346,20 +510,25 @@ namespace Dune
template<class T, std::size_t S>
inline void Pool<T,S>::free(void* b)
{
Reference* freed = static_cast<Reference*>(b);
freed->next_ = head_;
head_ = freed;
if(b) {
Reference* freed = reinterpret_cast<Reference*>(b);
freed->next_ = head_;
head_ = freed;
--allocated_;
}else
std::cerr<< "Tried to free null pointer! "<<b<<std::endl;
}
template<class T, std::size_t S>
inline void* Pool<T,S>::allocate()
inline T* Pool<T,S>::allocate()
{
if(head_==0)
if(!head_)
grow();
Reference* p = head_;
head_ = p->next_;
return p;
++allocated_;
return reinterpret_cast<T*>(p);
}
template<class T, std::size_t s>
......@@ -373,20 +542,20 @@ namespace Dune
inline T* PoolAllocator<T,s>::allocate(std::size_t n, const T* hint)
{
assert(n==1); //<=(Pool<T,s>::elements));
return static_cast<T*>(memoryPool_.allocate());
return memoryPool_.allocate();
}
template<class T, std::size_t s>
inline void PoolAllocator<T,s>::deallocate(T* p, std::size_t n)
{
assert(n==1);
memoryPool_.free(p);
for(size_t i=0; i<n; i++)
memoryPool_.free(p++);
}
template<class T, std::size_t s>
inline void PoolAllocator<T,s>::construct(T* p, const T& value)
{
new (p) T(value);
::new (static_cast<void*>(p))T(value);
}
template<class T, std::size_t s>
......
......@@ -5,9 +5,11 @@
#define DUNE__SLLIST_HH
#include <memory>
#include <assert.h>
#include <cassert>
#include <config.h>
#include "iteratorfacades.hh"
#include <ostream>
#include <iostream>
namespace Dune
{
......@@ -66,8 +68,19 @@ namespace Dune
* @brief The mutable iterator of the list.
*/
typedef SLListConstIterator<T,A> const_iterator;
/**
* @brief Constructor.
*/
SLList();
/**
* @brief Destructor.
*
* Deallocates all elements in the list.
*/
~SLList();
/**
* @brief The type of the iterator capable of deletion
* and insertion.
......@@ -222,13 +235,37 @@ namespace Dune
};
/** @brief The first element in the list. */
//Element* head_;
/**
* @brief Delete the next element in the list.
* @param current Element whose next element should be deleted.
*/
void deleteNext(Element* current);
/**
* @brief Delete the next element in the list.
*
* If the template parameter watchForTail is true, it is checked whether
* the deleted element is the tail and therefore the tail must be updated.
* @param current Element whose next element should be deleted.
*/
template<bool watchForTail>
void deleteNext(Element* current);
/**
* @brief Insert an element after another one in the list.
* @param current The element after which we insert.
* @param item The item to insert.
*/
void insertAfter(Element* current, const T& item);
/** @brief Pseudo element before the first entry. */
Element beforeHead_;
/** @brief The last element in the list. */
/**
* @brief Pointer to he last element in the list.
*
* If list is empty this will point to beforeHead_
*/
Element* tail_;
/** @brief The allocator we use. */
......@@ -316,17 +353,8 @@ namespace Dune
*/
inline void insertAfter(const T& v) const
{
assert(current_ != 0 && list_ != 0);
typename SLList<T,A>::Element* added = list_->allocator_.allocate(1, 0);
added->item_ = v;
added->next_ = current_->next_;
current_->next_ = added;
if(current_==list_->tail_)
// We add a new tail to the list
list_->tail_=added;
++(list_->size_);
assert(list_ );
list_->insertAfter(current_, v);
}
/**
......@@ -336,16 +364,8 @@ namespace Dune
*/
inline void deleteNext() const
{
assert(current_->next_!=0 && list_!=0);
typename SLList<T,A>::Element* tmp =current_->next_;
current_->next_ = tmp->next_;
if(tmp==list_->tail_)
list_->tail_=current_;
list_->allocator_.destroy(tmp);
list_->allocator_.deallocate(tmp, 1);
--(list_->size_);
assert(list_);
list_->deleteNext(current_);
}
private:
......@@ -527,6 +547,35 @@ namespace Dune
/** @brief Iterator positioned at the current position. */
SLListIterator<T,A> iterator_;
};
} // namespace Dune
namespace std
{
template<typename T, typename A>
ostream& operator<<(ostream& os, const Dune::SLList<T,A> sllist)
{
typedef typename Dune::SLList<T,A>::const_iterator Iterator;
Iterator end = sllist.end();
Iterator current= sllist.begin();
os << "{ ";
if(current!=end) {
os<<*current<<" ("<<static_cast<const void*>(&(*current))<<")";
++current;
for(; current != end; ++current)
os<<", "<<*current<<" ("<<static_cast<const void*>(&(*current))<<")";
}
os<<"} ";
return os;
}
} //namespace std
namespace Dune
{
template<typename T, class A>
SLList<T,A>::Element::Element(const T& item)
: next_(0), item_(item)
......@@ -539,72 +588,132 @@ namespace Dune
template<typename T, class A>
SLList<T,A>::SLList()
: beforeHead_(), tail_(0), allocator_(), size_(0)
{}
: beforeHead_(), tail_(&beforeHead_), allocator_(), size_(0)
{
beforeHead_.next_=0;
assert(&beforeHead_==tail_);
assert(tail_->next_==0);
}
template<typename T, class A>
SLList<T,A>::~SLList()
{
clear();
std::cout<<"Destructor called! Pool="<<allocator_<<std::endl;
}
template<typename T, class A>
inline void SLList<T,A>::push_back(const T& item)
{
if(tail_!=0) {
tail_->next_ = allocator_.allocate(1, 0);
tail_ = tail_->next_;
tail_->item_=item;
tail_->next_=0;
}else{
beforeHead_.next_ = tail_ = allocator_.allocate(1, 0);
tail_->next_=0;
tail_->item_=item;
tail_->next_ = allocator_.allocate(1, 0);
tail_ = tail_->next_;
::new (static_cast<void*>(&(tail_->item_)))T(item);
tail_->next_=0;
assert(tail_->next_==0);
++size_;
}
template<typename T, class A>
inline void SLList<T,A>::insertAfter(Element* current, const T& item)
{
assert(current);
bool changeTail = (current == tail_);
// Save old next element
Element* tmp = current->next_;
assert(!changeTail || !tmp);
// Allocate space
current->next_ = allocator_.allocate(1, 0);
// Use copy constructor to initialize memory
::new(static_cast<void*>(&(current->next_->item_)))T(item);
// Set next element
current->next_->next_=tmp;
if(!current->next_->next_) {
// Update tail
assert(changeTail);
tail_ = current->next_;
}
++size_;
assert(!tail_->next_);
}
template<typename T, class A>
inline void SLList<T,A>::push_front(const T& item)
{
if(beforeHead_.next_==0) {
if(tail_ == &beforeHead_) {
// list was empty
beforeHead_.next_ = tail_ = allocator_.allocate(1, 0);
beforeHead_.next_->item_=item;
::new(static_cast<void*>(&beforeHead_.next_->item_))T(item);
beforeHead_.next_->next_=0;
}else{
Element* added = allocator_.allocate(1, 0);
added->item_=item;
::new(static_cast<void*>(&added->item_))T(item);
added->next_=beforeHead_.next_;
beforeHead_.next_=added;
}
assert(tail_->next_==0);
++size_;
}
template<typename T, class A>
inline void SLList<T,A>::pop_front()
inline void SLList<T,A>::deleteNext(Element* current)
{
assert(beforeHead_.next_!=0);
if(beforeHead_.next_ == tail_)
tail_ = 0;
Element* tmp = beforeHead_.next_;
beforeHead_.next_ = beforeHead_.next_->next_;
allocator_.destroy(tmp);
allocator_.deallocate(tmp, 1);
this->template deleteNext<true>(current);
}
template<typename T, class A>
template<bool watchForTail>
inline void SLList<T,A>::deleteNext(Element* current)
{
assert(current->next_);
Element* next = current->next_;
if(!watchForTail || next == tail_) {
// deleting last element changes tail!
tail_ = current;
}
current->next_ = next->next_;
next->item_.~T();
next->next_ = 0;
allocator_.deallocate(next, 1);
--size_;
assert(!watchForTail || &beforeHead_ != tail_ || size_==0);
}
template<typename T, class A>
inline void SLList<T,A>::pop_front()
{
deleteNext(&beforeHead_);
}
template<typename T, class A>
inline void SLList<T,A>::clear()
{
while(beforeHead_.next_ ) {
Element* current = beforeHead_.next_ ;
beforeHead_.next_ = current->next_;
allocator_.destroy(current);
allocator_.deallocate(current, 1);
this->template deleteNext<false>(&beforeHead_);
}
tail_ = 0;
#ifdef NDEBUG
size_=0;
#endif
assert(size_==0);
// update the tail!
tail_ = &beforeHead_;
}
template<typename T, class A>
inline bool SLList<T,A>::empty() const
{
return (beforeHead_.next_ == 0);
return (&beforeHead_ == tail_);
}
template<typename T, class A>
......
......@@ -27,7 +27,6 @@ int testPool()
//int chunkSize = Pool<T,size>::chunkSize;
//int alignedSize = Pool<T,size>::alignedSize;
char** fields= new char*[10];
unsigned long* oelements = new unsigned long[10*elements];
typedef typename Pool<T,size>::Chunk Chunk;
......@@ -35,7 +34,6 @@ int testPool()
//Fill 10 chunks
for(int chunk=0; chunk < 10; ++chunk) {
//std::cout<< std::endl<<"Chunk "<<chunk<<" ";
//fields[chunk] = new char[333];
unsigned long element = reinterpret_cast<unsigned long>(pool.allocate());
void* celement = reinterpret_cast<void*>(element);
//std::cout << element<<" "<< celement<<", "<<std::endl;
......@@ -87,10 +85,10 @@ int testPool()
}
}
//for(int chunk=0; chunk < 10; ++chunk)
//delete[] fields[chunk];
delete[] fields;
for(int i=0; i < elements*10; ++i)
pool.free(reinterpret_cast<T*>(oelements+i));
delete[] oelements;
return ret;
......@@ -125,15 +123,15 @@ int testPool()
int main(int argc, char **argv)
{
int ret=0;
/*
ret += testPool<int>();
ret+= testPool<double>();
ret += testPool<int>();
ret+= testPool<double>();
ret+= testPool<char>();
ret+= testPool<char>();
ret += testPool<Dune::FieldMatrix<double,10,10> >();
ret += testPool<Dune::FieldMatrix<double,10,10> >();
*/
std::cout<<AlignmentOf<UnAligned>::value<<" "<<sizeof(UnAligned)<<std::endl;
......
......@@ -10,21 +10,68 @@ class DoubleWrapper
public:
DoubleWrapper(double b)
: d(b)
{}
{
std::cout<<"Constructed "<<this<<std::endl;
}
DoubleWrapper()
: d()
{}
{
std::cout<<"Constructed "<<this<<std::endl;
}
operator double()
DoubleWrapper(const DoubleWrapper& other)
: d(other.d)
{
std::cout<<"Copied "<<this<<" from "<<&other<<std::endl;
}
~DoubleWrapper()
{
std::cout<<"Destructing "<<this<<std::endl;
}
operator double() const
{
return d;
}
bool operator==(const DoubleWrapper& other) const
{
return d == other.d;
}
bool operator!=(const DoubleWrapper& other) const
{
return d != other.d;
}
private:
double d;
};
typedef Dune::PoolAllocator<int,8*1024-16> IntAllocator;
//typedef std::allocator<int> IntAllocator;
typedef Dune::PoolAllocator<double,8*1024-16> DoubleAllocator;
//typedef std::allocator<double> DoubleAllocator;
typedef Dune::PoolAllocator<DoubleWrapper,8*1024-16> DoubleWAllocator;
//typedef std::allocator<DoubleWrapper> DoubleWAllocator;
template<typename T,class A>
int check(const Dune::SLList<T,A>& alist, const T* vals)
{
typedef typename Dune::SLList<T,A>::const_iterator iterator;
int i=0;
for(iterator iter = alist.begin(); iter != alist.end(); ++iter, i++) {
if( vals[i] != *iter ) {
std::cerr<<" List missmatch! "<<__FILE__<<":"<<__LINE__<<std::endl;
return 1;
}
}
return 0;
}
template<typename T,class A>
void randomizeListBack(Dune::SLList<T,A>& alist){
......@@ -34,8 +81,15 @@ void randomizeListBack(Dune::SLList<T,A>& alist){
int lowest=0, highest=1000, range=(highest-lowest)+1;
for(int i=0; i < 10; i++)
alist.push_back(T(range*(rand()/(RAND_MAX+1.0))));
T vals[10];
for(int i=0; i < 10; i++) {
T d = T(range*(rand()/(RAND_MAX+1.0)));
alist.push_back(d);
vals[i]=d;
}
check(alist, vals);
}
template<typename T,class A>
......@@ -43,16 +97,22 @@ void randomizeListFront(Dune::SLList<T,A>& alist){
using namespace Dune;
srand((unsigned)time(0));
T vals[10];
int lowest=0, highest=1000, range=(highest-lowest)+1;
for(int i=0; i < 10; i++)
alist.push_front((range*(rand()/(RAND_MAX+1.0))));
for(int i=0; i < 10; i++) {
T d = T(range*(rand()/(RAND_MAX+1.0)));
alist.push_front(d);
vals[9-i]=d;
}
check(alist, vals);
}
int testDelete()
{
typedef Dune::SLList<int,Dune::PoolAllocator<int,8*1024-16> > List;
typedef Dune::SLList<int,IntAllocator> List;
List alist;
alist.push_back(3);
......@@ -72,7 +132,7 @@ int testDelete()
++iter;
iter.remove();
if(iter!=alist.end()) {
std::cerr<<"delete next faild! "<<__FILE__<<":"<<__LINE__<<std::endl;
std::cerr<<"delete next failed! "<<__FILE__<<":"<<__LINE__<<std::endl;
return 1;
}
if(*(alist.tail())!=4) {
......@@ -82,9 +142,85 @@ int testDelete()
return 0;
}
int testEmpty()
{
typedef Dune::SLList<int,DoubleAllocator> List;
int ret = 0;
List alist;
if(!alist.empty()) {
std::cerr<<"Newly created list not empty! "<<__FILE__<<":"<<__LINE__<<std::endl;
ret++;
}
if(0 != alist.size()) {
std::cerr<<"Newly created list not empty! "<<__FILE__<<":"<<__LINE__<<std::endl;
ret++;
}
randomizeListBack(alist);
if(alist.empty()) {
std::cerr<<"Randomized list is empty! "<<__FILE__<<":"<<__LINE__<<std::endl;
ret++;
}
if(0 == alist.size()) {
std::cerr<<"Randomized list is empty! "<<__FILE__<<":"<<__LINE__<<std::endl;
ret++;
}
for(int elements=alist.size(); elements>0; --elements)
alist.pop_front();
if(!alist.empty()) {
std::cerr<<"Emptied list not empty! "<<__FILE__<<":"<<__LINE__<<std::endl;
ret++;
}
if(0 != alist.size()) {
std::cerr<<"Emptied list not empty! "<<__FILE__<<":"<<__LINE__<<std::endl;
ret++;
}
if(ret!=0)
// Skip next tests
return ret;
randomizeListFront(alist);
if(alist.empty()) {
std::cerr<<"Randomized list is empty! "<<__FILE__<<":"<<__LINE__<<std::endl;
ret++;
}
if(0 == alist.size()) {
std::cerr<<"Randomized list is empty! "<<__FILE__<<":"<<__LINE__<<std::endl;
ret++;
}
alist.clear();
if(!alist.empty()) {
std::cerr<<"Emptied list not empty! "<<__FILE__<<":"<<__LINE__<<std::endl;
ret++;
}
if(0 != alist.size()) {
std::cerr<<"Emptied list not empty! "<<__FILE__<<":"<<__LINE__<<std::endl;
ret++;
}
return ret;
}
int testInsert()
{
typedef Dune::SLList<int,Dune::PoolAllocator<int,8*1024-16> > List;
typedef Dune::SLList<int,IntAllocator> List;
//typedef Dune::SLList<int> List;
List alist;
alist.push_back(3);
......@@ -171,36 +307,48 @@ int testPushPop(){
using namespace Dune;
int ret=0;
Dune::SLList<int,PoolAllocator<int,8*1024-16> > alist;
Dune::SLList<int,IntAllocator> alist;
//std::cout<<"PushPop 1:"<<alist<<std::endl;
if(alist.begin() != alist.end()) {
ret++;
std::cout<<"For empty list begin and end iterator do not match! "<<__FILE__<<":"<<__LINE__<<std::endl;
std::cerr<<"For empty list begin and end iterator do not match! "<<__FILE__<<":"<<__LINE__<<std::endl;
ret++;
}
alist.push_back(1);
//std::cout<<"Push back 1: "<<alist<<std::endl;
if(*(alist.begin())!=1) {
std::cout<<"Entry should be 1! Push back failed! "<<__FILE__<<":"<<__LINE__<<std::endl;
std::cerr<<"Entry should be 1! Push back failed! "<<__FILE__<<":"<<__LINE__<<std::endl;
ret++;
}
alist.push_back(2);
//std::cout<<"Push back 2: "<<alist<<std::endl;
if(*(alist.begin())!=1) {
ret++;
std::cout<<"Entry should be 2! Push back failed! "<<__FILE__<<":"<<__LINE__<<std::endl;
std::cerr<<"Entry should be 2! Push back failed! "<<__FILE__<<":"<<__LINE__<<std::endl;
}
alist.push_front(3);
//std::cout<<"Push front 3: "<<alist<<std::endl;
if(*(alist.begin())!=3) {
ret++;
std::cout<<"Entry should be 3! Push front failed! "<<__FILE__<<":"<<__LINE__<<std::endl;
std::cerr<<"Entry should be 3! Push front failed! "<<__FILE__<<":"<<__LINE__<<std::endl;
}
alist.pop_front();
//std::cout<<*(alist.begin())<<" Pop front: "<<alist<<std::endl;
if(*(alist.begin())!=1) {
ret++;
std::cout<<"Entry should be 1! Push back failed! "<<__FILE__<<":"<<__LINE__<<std::endl;
std::cerr<<"Entry should be 1, but is "<<*(alist.begin())<<"! Push back failed! "<<__FILE__<<":"<<__LINE__<<std::endl;
}
return ret;
}
......@@ -209,16 +357,17 @@ int main()
{
int ret=0;
Dune::SLList<double> list;
Dune::SLList<double,Dune::PoolAllocator<double, 8*1024-20> > list1;
Dune::SLList<DoubleWrapper, Dune::PoolAllocator<DoubleWrapper, 8*1024-20> > list2;
//Dune::SLList<double> list;
Dune::SLList<double,DoubleAllocator> list, list1;
Dune::SLList<DoubleWrapper, DoubleWAllocator> list2;
randomizeListBack(list1);
randomizeListFront(list);
randomizeListFront(list2);
Printer<std::iterator_traits<Dune::SLList<double>::ModifyIterator>::value_type> print;
Printer<std::iterator_traits<Dune::SLList<double,DoubleAllocator>::ModifyIterator>::value_type> print;
Dune::SLList<double>::ModifyIterator lbegin = list.beginModify(), lend = list.endModify();
Dune::SLList<double,DoubleAllocator>::ModifyIterator lbegin = list.beginModify(), lend = list.endModify();
double& d = lbegin.dereference();
......@@ -232,19 +381,35 @@ int main()
*lbegin=5.0;
std::cout << "Testing ConstIterator "<<std::endl;
ret+=testConstIterator(lbegin, lend, print);
std::cout << "Testing Iterator "<<std::endl;
ret+=testIterator(list);
std::cout << "Testing Iterator "<<std::endl;
ret+=testIterator(list1);
std::cout<< " Test PushPop "<<std::endl;
ret+=testPushPop();
std::cout<<" Test OneBeforeBegin"<<std::endl;
ret+=testOneBeforeBegin(list1);
std::cout<< "test empty"<<std::endl;
ret+=testEmpty();
std::cout<< "test insert"<<std::endl;
ret+=testInsert();
std::cout<< "test delete"<<std::endl;
ret+=testDelete();
list.clear();
list1.clear();
list2.clear();
std::cout<<" randomize back"<<std::endl;
randomizeListBack(list);
std::cout<<" randomize front"<<std::endl;
randomizeListFront(list1);
exit(ret);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment