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

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

Code formatting

  • Property svn:eol-style set to native
File size: 4.6 KB
RevLine 
[286]1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
[781]2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
[286]3// See LICENSE.txt for details.
[109]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{
[733]18public:
19        int objects, allocations, copied, totalmem, usedmem;
[793]20        SListStats() :objects(0), allocations(0), copied(0), totalmem(0), usedmem() {}
[733]21        ~SListStats()
[109]22        {
[733]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",
[793]31                        objects, allocations, copied, totalmem, (usedmem * 100) / totalmem);
[109]32        }
33};
34#endif
35
36
37template<class T> class SListTempl
38{
39protected:
[733]40        int have, used, pos; // ile,zaj,poz
41        T *mem;
42        void resize(int x)
[109]43        {
[733]44                if (mem || x)
[109]45                {
[733]46                        mem = (T*)realloc(mem, x*sizeof(T));
[109]47#ifdef SLISTSTATS
[733]48                        SListStats::stats.allocations++;
[793]49                        SListStats::stats.copied += sizeof(T)*min(x, have);
[109]50#endif 
51                }
[733]52                have = x;
[109]53        }
54
55public:
56
[733]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)
[109]62        {}
[733]63        ~SListTempl()
[109]64        {
65#ifdef SLISTSTATS
[733]66                SListStats::stats.objects++;
[793]67                SListStats::stats.totalmem += sizeof(T)*have;
68                SListStats::stats.usedmem += sizeof(T)*used;
[109]69#endif
[733]70                hardclear();
[109]71        }
72
[733]73        void needSize(int s)
[109]74        {
[733]75                if (s > have) resize(s + 3 + s / 8);
[109]76        }
[733]77        void operator+=(const T& e) ///< append one element
[109]78        {
[733]79                append(e);
[109]80        }
[733]81        void operator-=(const T& e) ///< remove one element
[109]82        {
[733]83                int i; if ((i = find(e)) >= 0) remove(i);
[109]84        }
[733]85        void remove(int i, int n = 1) ///< remove n elements from position i
[109]86        {
[733]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;
[109]92        }
[733]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;
[793]102                for (int i = 0; i < size(); i++) if (l.mem[i] != mem[i]) return 0;
[733]103                return 1;
104        }
105        int find(const T& e) const ///< return position of element, or -1 if not found
106        {
[781]107                for (int i = 0; i<size(); i++) if (mem[i] == e) return i;
108                return -1;
[733]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        }
[109]164};
165
[153]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_++)
[109]168
169// usage example: FOREACH(char*,t,thelist) printf("t=%s\n",t);
170
[733]171template<class T> class PtrListTempl : public SListTempl < T >
[109]172{
[733]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        }
[109]178
[733]179        T get(int i) const { return operator()(i); }
180        T& getref(int i) const { return SListTempl<T>::get(i); }
[109]181};
182
183
[733]184        typedef PtrListTempl<void*> SList;
[109]185
186#endif
Note: See TracBrowser for help on using the repository browser.