// This file is a part of Framsticks GDK library. // Copyright (C) 2002-2006 Szymon Ulatowski. See LICENSE.txt for details. // Refer to http://www.frams.alife.pl/ for further information. #ifndef _LIST_H_ #define _LIST_H_ #include #include #include "nonstd.h" //#define SLISTSTATS #ifdef SLISTSTATS #include class SListStats { public: int objects, allocations, copied, totalmem, usedmem; SListStats():objects(0),allocations(0),copied(0),totalmem(0),usedmem() {} ~SListStats() { printf("------------------------\n" " SListStats:\n" " objects = %ld\n" " allocations = %ld\n" " copied = %ld\n" " total mem = %ld\n" " usage = %ld %%\n" "------------------------\n", objects,allocations,copied,totalmem,(usedmem*100)/totalmem); } }; #endif template class SListTempl { protected: int have,used,pos; // ile,zaj,poz T *mem; void resize(int x) { if (mem || x) { mem=(T*)realloc(mem,x*sizeof(T)); #ifdef SLISTSTATS SListStats::stats.allocations++; SListStats::stats.copied+=sizeof(T)*min(x,have); #endif } have=x; } public: SListTempl(const SListTempl& src):have(0),used(0),mem(0),pos(0) {(*this)=src;} SListTempl():have(0),used(0),mem(0),pos(0) {} ~SListTempl() { #ifdef SLISTSTATS SListStats::stats.objects++; SListStats::stats.totalmem+=sizeof(T)*have; SListStats::stats.usedmem+=sizeof(T)*used; #endif hardclear(); } void needSize(int s) { if (s>have) resize(s+3+s/8); } void operator+=(const T& e) ///< append one element {append(e);} void operator-=(const T& e) ///< remove one element {int i; if ((i=find(e))>=0) remove(i);} void remove(int i,int n=1) ///< remove n elements from position i { if ((i>=size())||(i<0)) return; if (i>(size()-n)) n=size()-i; if (pos>=i) pos-=n; memmove(mem+i,mem+i+n,sizeof(T)*(used-n-i)); used-=n; } void operator-=(int i) {remove(i);} ///< remove element from position i T& operator()(int i) const ///< return element at position i {return mem[i];} bool hasMore() {return pos& l) const ///< compare list { if (size() != l.size()) return 0; for (int i=0;isize()) p=size(); needSize(size()+n); memmove(mem+p+n,mem+p,sizeof(T)*(size()-p)); memcpy(mem+p,data,sizeof(T)*n); if (pos>p) pos+=n; } void insert(int p,const T& data) ///< insert 1 element at position p { if (p>size()) p=size(); needSize(size()+1); memmove(mem+p+1,mem+p,sizeof(T)*(size()-p)); if (pos>p) pos++; mem[p]=data; used++; } void set(int p,const T& d) { needSize(p+1); mem[p]=d; if (used<(p+1)) used=p+1;} void setSize(int s) { needSize(s); used=s;} T& get(int i) const {return operator()(i);} T& get() {return operator()();} void clear() {used=0;} ///< remove all elements void hardclear() {resize(0); used=0;} ///< remove all elements and free mem int size() const {return used;} ///< list size int operator!() {return used;} ///< list size void operator=(const SListTempl&src) ///duplicate { setSize(src.size()); memcpy(mem, src.mem, src.size()*sizeof(T)); } void operator+=(const SListTempl&src) ///< append src contents { needSize(size()+src.size()); memcpy(mem+used, src.mem, src.size()*sizeof(T)); used+=src.used; } void trim(int newsiz) {if (newsiz class PtrListTempl: public SListTempl { public: T operator()() ///< return next element {if (this->pos>=this->size()) return 0; else return this->mem[this->pos++];} T operator()(int i) const ///< return element at position i {if (i>=this->size()) return 0; else return this->mem[i];} T get(int i) const {return operator()(i);} T get() {return operator()();} }; typedef PtrListTempl SList; #endif