source: cpp/frams/util/list.h @ 153

Last change on this file since 153 was 153, checked in by sz, 10 years ago

SList container iteration: FOREACH() macro now creates local variable for maintaining the loop, removed the obsolete SList iteration implementation, replaced some unnecessarily complex for() with FOREACH()

  • Property svn:eol-style set to native
File size: 4.4 KB
Line 
1// This file is a part of the Framsticks GDK.
2// Copyright (C) 2002-2014  Maciej Komosinski and 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 <common/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),pos(0),mem(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();}
89int operator==(const SListTempl<T>& l) const ///< compare list
90 {
91 if (size() != l.size()) return 0;
92 for (int i=0;i<size();i++) if (l.mem[i] != mem[i]) return 0;
93 return 1;
94 }
95int find(const T& e) const ///< return position of element, or -1 if not found
96        { for (int i=0;i<size();i++) if (mem[i]==e) return i;   return -1; }
97void append(const T& data) ///< add 1 element
98        {needSize(size()+1); mem[used++]=data;}
99void append(const T* data,int n) ///< add n elements
100        {
101        needSize(size()+n);
102        memcpy(mem+used,data,sizeof(T)*n);
103        used+=n;
104        }
105void insert(int p,T* data,int n) ///< insert n elements at position p
106        {
107        if (p>size()) p=size();
108        needSize(size()+n);
109        memmove(mem+p+n,mem+p,sizeof(T)*(size()-p));
110        memcpy(mem+p,data,sizeof(T)*n);
111        if (pos>p) pos+=n;
112        }
113void insert(int p,const T& data) ///< insert 1 element at position p
114        {
115        if (p>size()) p=size();
116        needSize(size()+1);
117        memmove(mem+p+1,mem+p,sizeof(T)*(size()-p));
118        if (pos>p) pos++;
119        mem[p]=data;
120        used++;
121        }
122void set(int p,const T& d)
123        { needSize(p+1); mem[p]=d; if (used<(p+1)) used=p+1;}
124void setSize(int s)
125        { needSize(s); used=s;}
126T& get(int i) const {return operator()(i);}
127void clear() {used=0;} ///< remove all elements
128void hardclear() {resize(0); used=0;} ///< remove all elements and free mem
129int size() const {return used;} ///< list size
130int operator!() {return used;} ///< list size
131void operator=(const SListTempl<T>&src) ///duplicate
132 {
133 setSize(src.size());
134 memcpy(mem, src.mem, src.size()*sizeof(T));
135 }
136void operator+=(const SListTempl<T>&src) ///< append src contents
137 {
138 needSize(size()+src.size());
139 memcpy(mem+used, src.mem, src.size()*sizeof(T));
140 used+=src.used;
141 }
142void trim(int newsiz)
143        {if (newsiz<used) used=newsiz;}
144};
145
146#define FOREACH(type,var,list) for(int _ ## var ## _i_=0,_ ## var ## _tmp_=0; _ ## var ## _i_==0;_ ## var ## _i_++) \
147                for(type var;((_ ## var ## _tmp_=(_ ## var ## _i_<list.size()))?(var=(type)list(_ ## var ## _i_)):0),_ ## var ## _tmp_;_ ## var ## _i_++)
148
149// usage example: FOREACH(char*,t,thelist) printf("t=%s\n",t);
150
151template<class T> class PtrListTempl: public SListTempl<T>
152{
153   public:
154T operator()(int i) const ///< return element at position i
155     {if (i>=this->size()) return 0; else return this->mem[i];}
156
157T get(int i) const {return operator()(i);}
158T& getref(int i) const {return SListTempl<T>::get(i);}
159};
160
161
162typedef PtrListTempl<void*> SList;
163
164#endif
Note: See TracBrowser for help on using the repository browser.