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

Last change on this file since 739 was 733, checked in by Maciej Komosinski, 7 years ago

Code formatting

  • Property svn:eol-style set to native
File size: 4.6 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
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{
18public:
19        int objects, allocations, copied, totalmem, usedmem;
20        SListStats():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:
40        int have, used, pos; // ile,zaj,poz
41        T *mem;
42        void 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
57        SListTempl(const SListTempl<T>& src) :have(0), used(0), pos(0), mem(0)
58        {
59                (*this) = src;
60        }
61        SListTempl() :have(0), used(0), pos(0), mem(0)
62        {}
63        ~SListTempl()
64        {
65#ifdef SLISTSTATS
66                SListStats::stats.objects++;
67                SListStats::stats.totalmem+=sizeof(T)*have;
68                SListStats::stats.usedmem+=sizeof(T)*used;
69#endif
70                hardclear();
71        }
72
73        void needSize(int s)
74        {
75                if (s > have) resize(s + 3 + s / 8);
76        }
77        void operator+=(const T& e) ///< append one element
78        {
79                append(e);
80        }
81        void operator-=(const T& e) ///< remove one element
82        {
83                int i; if ((i = find(e)) >= 0) remove(i);
84        }
85        void remove(int i, int n = 1) ///< remove n elements from position i
86        {
87                if ((i >= size()) || (i<0)) return;
88                if (i>(size() - n)) n = size() - i;
89                if (pos >= i) pos -= n;
90                memmove(mem + i, mem + i + n, sizeof(T)*(used - n - i));
91                used -= n;
92        }
93        void operator-=(int i) { remove(i); } ///< remove element from position i
94        T& operator()(int i) const ///< return element at position i
95        {
96                return mem[i];
97        }
98        bool hasMore() { return pos < size(); }
99        int operator==(const SListTempl<T>& l) const ///< compare list
100        {
101                if (size() != l.size()) return 0;
102                for (int i = 0; i<size(); i++) if (l.mem[i] != mem[i]) return 0;
103                return 1;
104        }
105        int find(const T& e) const ///< return position of element, or -1 if not found
106        {
107                for (int i = 0; i<size(); i++) if (mem[i] == e) return i;   return -1;
108        }
109        void append(const T& data) ///< add 1 element
110        {
111                needSize(size() + 1); mem[used++] = data;
112        }
113        void append(const T* data, int n) ///< add n elements
114        {
115                needSize(size() + n);
116                memcpy(mem + used, data, sizeof(T)*n);
117                used += n;
118        }
119        void insert(int p, T* data, int n) ///< insert n elements at position p
120        {
121                if (p>size()) p = size();
122                needSize(size() + n);
123                memmove(mem + p + n, mem + p, sizeof(T)*(size() - p));
124                memcpy(mem + p, data, sizeof(T)*n);
125                if (pos > p) pos += n;
126        }
127        void insert(int p, const T& data) ///< insert 1 element at position p
128        {
129                if (p > size()) p = size();
130                needSize(size() + 1);
131                memmove(mem + p + 1, mem + p, sizeof(T)*(size() - p));
132                if (pos > p) pos++;
133                mem[p] = data;
134                used++;
135        }
136        void set(int p, const T& d)
137        {
138                needSize(p + 1); mem[p] = d; if (used < (p + 1)) used = p + 1;
139        }
140        void setSize(int s)
141        {
142                needSize(s); used = s;
143        }
144        T& get(int i) const { return operator()(i); }
145        void clear() { used = 0; } ///< remove all elements
146        void hardclear() { resize(0); used = 0; } ///< remove all elements and free mem
147        int size() const { return used; } ///< list size
148        void operator=(const SListTempl<T>&src) ///duplicate
149        {
150                setSize(src.size());
151                memcpy(mem, src.mem, src.size()*sizeof(T));
152        }
153        void operator+=(const SListTempl<T>&src) ///< append src contents
154        {
155                needSize(size() + src.size());
156                memcpy(mem + used, src.mem, src.size()*sizeof(T));
157                used += src.used;
158        }
159        void trim(int newsiz)
160        {
161                if (newsiz < used) used = newsiz;
162        }
163};
164
165#define FOREACH(type,var,list) for(int _ ## var ## _i_=0,_ ## var ## _tmp_=0; _ ## var ## _i_==0;_ ## var ## _i_++) \
166                for(type var;((_ ## var ## _tmp_=(_ ## var ## _i_<list.size()))?(var=(type)list(_ ## var ## _i_)):0),_ ## var ## _tmp_;_ ## var ## _i_++)
167
168// usage example: FOREACH(char*,t,thelist) printf("t=%s\n",t);
169
170template<class T> class PtrListTempl : public SListTempl < T >
171{
172public:
173        T operator()(int i) const ///< return element at position i
174        {
175                if (i >= this->size()) return 0; else return this->mem[i];
176        }
177
178        T get(int i) const { return operator()(i); }
179        T& getref(int i) const { return SListTempl<T>::get(i); }
180};
181
182
183        typedef PtrListTempl<void*> SList;
184
185#endif
Note: See TracBrowser for help on using the repository browser.