source: cpp/gdk/list.h @ 100

Last change on this file since 100 was 66, checked in by Maciej Komosinski, 14 years ago

set 'eol-style' to 'native'

  • Property svn:eol-style set to native
File size: 4.4 KB
Line 
1// This file is a part of the Framsticks GDK library.
2// Copyright (C) 2002-2011  Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.framsticks.com/ for further information.
4
5#ifndef _LIST_H_
6#define _LIST_H_
7
8#include <stdlib.h>
9#include <string.h>
10#include "nonstd.h"
11
12//#define SLISTSTATS
13
14#ifdef SLISTSTATS
15#include <stdio.h>
16class SListStats
17{
18  public:
19int objects, allocations, copied, totalmem, usedmem;
20SListStats():objects(0),allocations(0),copied(0),totalmem(0),usedmem() {}
21~SListStats()
22        {
23        printf("------------------------\n"
24               " SListStats:\n"
25               " objects     = %ld\n"
26               " allocations = %ld\n"
27               " copied      = %ld\n"
28               " total mem   = %ld\n"
29               " usage       = %ld %%\n"
30               "------------------------\n",
31               objects,allocations,copied,totalmem,(usedmem*100)/totalmem);
32        }
33};
34#endif
35
36
37template<class T> class SListTempl
38{
39protected:
40int have,used,pos; // ile,zaj,poz
41T *mem;
42void resize(int x)
43        {
44        if (mem || x)
45                {
46                mem=(T*)realloc(mem,x*sizeof(T));
47#ifdef SLISTSTATS
48                SListStats::stats.allocations++;
49                SListStats::stats.copied+=sizeof(T)*min(x,have);
50#endif 
51                }
52        have=x;
53        }
54
55public:
56
57SListTempl(const SListTempl<T>& src):have(0),used(0),mem(0),pos(0)
58        {(*this)=src;}
59SListTempl():have(0),used(0),mem(0),pos(0)
60        {}
61~SListTempl()
62        {
63#ifdef SLISTSTATS
64        SListStats::stats.objects++;
65        SListStats::stats.totalmem+=sizeof(T)*have;
66        SListStats::stats.usedmem+=sizeof(T)*used;
67#endif
68        hardclear();
69        }
70
71void needSize(int s)
72        { if (s>have) resize(s+3+s/8); }
73void operator+=(const T& e) ///< append one element
74 {append(e);}
75void operator-=(const T& e) ///< remove one element
76 {int i; if ((i=find(e))>=0) remove(i);}
77void remove(int i,int n=1) ///< remove n elements from position i
78        {
79        if ((i>=size())||(i<0)) return;
80        if (i>(size()-n)) n=size()-i;
81        if (pos>=i) pos-=n;
82        memmove(mem+i,mem+i+n,sizeof(T)*(used-n-i));
83        used-=n;
84        }
85void operator-=(int i) {remove(i);} ///< remove element from position i
86T& operator()(int i) const ///< return element at position i
87        {return mem[i];}
88bool hasMore() {return pos<size();}
89T& operator()() ///< return next element
90        { return mem[pos++];}
91int operator==(const SListTempl<T>& l) const ///< compare list
92 {
93 if (size() != l.size()) return 0;
94 for (int i=0;i<size();i++) if (l.mem[i] != mem[i]) return 0;
95 return 1;
96 }
97int find(const T& e) const ///< return position of element, or -1 if not found
98        { for (int i=0;i<size();i++) if (mem[i]==e) return i;   return -1; }
99int start() {return pos=0;} ///< start iteration throgh list
100void append(const T& data) ///< add 1 element
101        {needSize(size()+1); mem[used++]=data;}
102void append(const T* data,int n) ///< add n elements
103        {
104        needSize(size()+n);
105        memcpy(mem+used,data,sizeof(T)*n);
106        used+=n;
107        }
108void insert(int p,T* data,int n) ///< insert n elements at position p
109        {
110        if (p>size()) p=size();
111        needSize(size()+n);
112        memmove(mem+p+n,mem+p,sizeof(T)*(size()-p));
113        memcpy(mem+p,data,sizeof(T)*n);
114        if (pos>p) pos+=n;
115        }
116void insert(int p,const T& data) ///< insert 1 element at position p
117        {
118        if (p>size()) p=size();
119        needSize(size()+1);
120        memmove(mem+p+1,mem+p,sizeof(T)*(size()-p));
121        if (pos>p) pos++;
122        mem[p]=data;
123        used++;
124        }
125void set(int p,const T& d)
126        { needSize(p+1); mem[p]=d; if (used<(p+1)) used=p+1;}
127void setSize(int s)
128        { needSize(s); used=s;}
129T& get(int i) const {return operator()(i);}
130T& get() {return operator()();}
131void clear() {used=0;} ///< remove all elements
132void hardclear() {resize(0); used=0;} ///< remove all elements and free mem
133int size() const {return used;} ///< list size
134int operator!() {return used;} ///< list size
135void operator=(const SListTempl<T>&src) ///duplicate
136 {
137 setSize(src.size());
138 memcpy(mem, src.mem, src.size()*sizeof(T));
139 }
140void operator+=(const SListTempl<T>&src) ///< append src contents
141 {
142 needSize(size()+src.size());
143 memcpy(mem+used, src.mem, src.size()*sizeof(T));
144 used+=src.used;
145 }
146void trim(int newsiz)
147        {if (newsiz<used) used=newsiz;}
148};
149
150#define FOREACH(type,var,list) for(type var=(type)list.start();var=(type)list();)
151
152// usage example: FOREACH(char*,t,thelist) printf("t=%s\n",t);
153
154template<class T> class PtrListTempl: public SListTempl<T>
155{
156   public:
157T operator()() ///< return next element
158     {if (this->pos>=this->size()) return 0; else return
159this->mem[this->pos++];}
160
161T operator()(int i) const ///< return element at position i
162     {if (i>=this->size()) return 0; else return this->mem[i];}
163
164T get(int i) const {return operator()(i);}
165T get() {return operator()();}
166};
167
168
169typedef PtrListTempl<void*> SList;
170
171#endif
Note: See TracBrowser for help on using the repository browser.