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

Last change on this file since 1040 was 793, checked in by Maciej Komosinski, 3 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-2018  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;
108                return -1;
109        }
110        void append(const T& data) ///< add 1 element
111        {
112                needSize(size() + 1); mem[used++] = data;
113        }
114        void append(const T* data, int n) ///< add n elements
115        {
116                needSize(size() + n);
117                memcpy(mem + used, data, sizeof(T)*n);
118                used += n;
119        }
120        void insert(int p, T* data, int n) ///< insert n elements at position p
121        {
122                if (p>size()) p = size();
123                needSize(size() + n);
124                memmove(mem + p + n, mem + p, sizeof(T)*(size() - p));
125                memcpy(mem + p, data, sizeof(T)*n);
126                if (pos > p) pos += n;
127        }
128        void insert(int p, const T& data) ///< insert 1 element at position p
129        {
130                if (p > size()) p = size();
131                needSize(size() + 1);
132                memmove(mem + p + 1, mem + p, sizeof(T)*(size() - p));
133                if (pos > p) pos++;
134                mem[p] = data;
135                used++;
136        }
137        void set(int p, const T& d)
138        {
139                needSize(p + 1); mem[p] = d; if (used < (p + 1)) used = p + 1;
140        }
141        void setSize(int s)
142        {
143                needSize(s); used = s;
144        }
145        T& get(int i) const { return operator()(i); }
146        void clear() { used = 0; } ///< remove all elements
147        void hardclear() { resize(0); used = 0; } ///< remove all elements and free mem
148        int size() const { return used; } ///< list size
149        void operator=(const SListTempl<T>&src) ///duplicate
150        {
151                setSize(src.size());
152                memcpy(mem, src.mem, src.size()*sizeof(T));
153        }
154        void operator+=(const SListTempl<T>&src) ///< append src contents
155        {
156                needSize(size() + src.size());
157                memcpy(mem + used, src.mem, src.size()*sizeof(T));
158                used += src.used;
159        }
160        void trim(int newsiz)
161        {
162                if (newsiz < used) used = newsiz;
163        }
164};
165
166#define FOREACH(type,var,list) for(int _ ## var ## _i_=0,_ ## var ## _tmp_=0; _ ## var ## _i_==0;_ ## var ## _i_++) \
167                for(type var;((_ ## var ## _tmp_=(_ ## var ## _i_<list.size()))?(var=(type)list(_ ## var ## _i_)):0),_ ## var ## _tmp_;_ ## var ## _i_++)
168
169// usage example: FOREACH(char*,t,thelist) printf("t=%s\n",t);
170
171template<class T> class PtrListTempl : public SListTempl < T >
172{
173public:
174        T operator()(int i) const ///< return element at position i
175        {
176                if (i >= this->size()) return 0; else return this->mem[i];
177        }
178
179        T get(int i) const { return operator()(i); }
180        T& getref(int i) const { return SListTempl<T>::get(i); }
181};
182
183
184        typedef PtrListTempl<void*> SList;
185
186#endif
Note: See TracBrowser for help on using the repository browser.