|      1 /* | 
        | 
|      2  *	botc source code | 
        | 
|      3  *	Copyright (C) 2012 Santeri `Dusk` Piippo | 
        | 
|      4  *	All rights reserved. | 
        | 
|      5  *	 | 
        | 
|      6  *	Redistribution and use in source and binary forms, with or without | 
        | 
|      7  *	modification, are permitted provided that the following conditions are met: | 
        | 
|      8  *	 | 
        | 
|      9  *	1. Redistributions of source code must retain the above copyright notice, | 
        | 
|     10  *	   this list of conditions and the following disclaimer. | 
        | 
|     11  *	2. Redistributions in binary form must reproduce the above copyright notice, | 
        | 
|     12  *	   this list of conditions and the following disclaimer in the documentation | 
        | 
|     13  *	   and/or other materials provided with the distribution. | 
        | 
|     14  *	3. Neither the name of the developer nor the names of its contributors may | 
        | 
|     15  *	   be used to endorse or promote products derived from this software without | 
        | 
|     16  *	   specific prior written permission. | 
        | 
|     17  *	4. Redistributions in any form must be accompanied by information on how to | 
        | 
|     18  *	   obtain complete source code for the software and any accompanying | 
        | 
|     19  *	   software that uses the software. The source code must either be included | 
        | 
|     20  *	   in the distribution or be available for no more than the cost of | 
        | 
|     21  *	   distribution plus a nominal fee, and must be freely redistributable | 
        | 
|     22  *	   under reasonable conditions. For an executable file, complete source | 
        | 
|     23  *	   code means the source code for all modules it contains. It does not | 
        | 
|     24  *	   include source code for modules or files that typically accompany the | 
        | 
|     25  *	   major components of the operating system on which the executable file | 
        | 
|     26  *	   runs. | 
        | 
|     27  *	 | 
        | 
|     28  *	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | 
        | 
|     29  *	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
        | 
|     30  *	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 
        | 
|     31  *	ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | 
        | 
|     32  *	LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 
        | 
|     33  *	CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 
        | 
|     34  *	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 
        | 
|     35  *	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 
        | 
|     36  *	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 
        | 
|     37  *	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 
        | 
|     38  *	POSSIBILITY OF SUCH DAMAGE. | 
        | 
|     39  */ | 
        | 
|     40  | 
        | 
|     41 #include <stdlib.h> | 
        | 
|     42 #include <stdio.h> | 
        | 
|     43 #include <string.h> | 
        | 
|     44 #include "common.h" | 
        | 
|     45  | 
        | 
|     46 #define ITERATE_SUBSCRIPTS(link) \ | 
        | 
|     47 	for (link = data; link; link = link->next) | 
        | 
|     48  | 
        | 
|     49 #define foreach_counter(NAME) \ | 
        | 
|     50 	(int)(reinterpret_cast<int> (foreach_counter##NAME) / sizeof (foreach_counter##NAME)) | 
        | 
|     51 #define foreach(T,NAME,ARRAY) \ | 
        | 
|     52 	if (ARRAY.size() > 0) for (T NAME = ARRAY[0], *foreach_counter##NAME = 0; \ | 
        | 
|     53 		foreach_counter(NAME) < (int)(ARRAY.size()); \ | 
        | 
|     54 		NAME = ARRAY[reinterpret_cast<int> (++foreach_counter##NAME) / sizeof (foreach_counter##NAME)]) | 
        | 
|     55  | 
        | 
|     56 // Single element of an array | 
        | 
|     57 template <class T> class arrayElement { | 
        | 
|     58 public: | 
        | 
|     59 	T value; | 
        | 
|     60 	arrayElement<T>* next; | 
        | 
|     61 	 | 
        | 
|     62 	arrayElement () { | 
        | 
|     63 		next = NULL; | 
        | 
|     64 	} | 
        | 
|     65 }; | 
        | 
|     66  | 
        | 
|     67 // Dynamic array | 
        | 
|     68 template <class T> class array { | 
        | 
|     69 public: | 
        | 
|     70 	array () { | 
        | 
|     71 		data = NULL; | 
        | 
|     72 	} | 
        | 
|     73 	 | 
        | 
|     74 	array (T* stuff, unsigned int c) { | 
        | 
|     75 		printf ("%d elements\n", c); | 
        | 
|     76 		data = NULL; | 
        | 
|     77 		 | 
        | 
|     78 		for (unsigned int i = 0; i < c; i++) | 
        | 
|     79 			push (stuff[c]); | 
        | 
|     80 	} | 
        | 
|     81 	 | 
        | 
|     82 	~array () { | 
        | 
|     83 		if (data) | 
        | 
|     84 			deleteElement (data); | 
        | 
|     85 	} | 
        | 
|     86 	 | 
        | 
|     87 	void push (T stuff) { | 
        | 
|     88 		arrayElement<T>* e = new arrayElement<T>; | 
        | 
|     89 		e->value = stuff; | 
        | 
|     90 		e->next = NULL; | 
        | 
|     91 		 | 
        | 
|     92 		if (!data) { | 
        | 
|     93 			data = e; | 
        | 
|     94 			return; | 
        | 
|     95 		} | 
        | 
|     96 		 | 
        | 
|     97 		arrayElement<T>* link; | 
        | 
|     98 		for (link = data; link && link->next; link = link->next); | 
        | 
|     99 		link->next = e; | 
        | 
|    100 	} | 
        | 
|    101 	 | 
        | 
|    102 	T pop () { | 
        | 
|    103 		int pos = size() - 1; | 
        | 
|    104 		if (pos == -1) | 
        | 
|    105 			error ("array::pop: tried to pop an array with no elements\n"); | 
        | 
|    106 		T res = subscript (pos); | 
        | 
|    107 		remove (pos); | 
        | 
|    108 		return res; | 
        | 
|    109 	} | 
        | 
|    110 	 | 
        | 
|    111 	void remove (unsigned int pos) { | 
        | 
|    112 		if (!data) | 
        | 
|    113 			error ("tried to use remove on an array with no elements"); | 
        | 
|    114 		 | 
        | 
|    115 		if (pos == 0) { | 
        | 
|    116 			// special case for first element | 
        | 
|    117 			arrayElement<T>* first = data; | 
        | 
|    118 			data = data->next; | 
        | 
|    119 			delete first; | 
        | 
|    120 			return; | 
        | 
|    121 		} | 
        | 
|    122 		 | 
        | 
|    123 		arrayElement<T>* link = data; | 
        | 
|    124 		unsigned int x = 0; | 
        | 
|    125 		while (link->next) { | 
        | 
|    126 			if (x == pos - 1) | 
        | 
|    127 				break; | 
        | 
|    128 			link = link->next; | 
        | 
|    129 			x++; | 
        | 
|    130 		} | 
        | 
|    131 		if (!link) | 
        | 
|    132 			error ("no such element in array\n"); | 
        | 
|    133 		 | 
        | 
|    134 		arrayElement<T>* nextlink = link->next->next; | 
        | 
|    135 		delete link->next; | 
        | 
|    136 		link->next = nextlink; | 
        | 
|    137 	} | 
        | 
|    138 	 | 
        | 
|    139 	unsigned int size () { | 
        | 
|    140 		unsigned int x = 0; | 
        | 
|    141 		arrayElement<T>* link; | 
        | 
|    142 		ITERATE_SUBSCRIPTS(link) | 
        | 
|    143 			x++; | 
        | 
|    144 		return x; | 
        | 
|    145 	} | 
        | 
|    146 	 | 
        | 
|    147 	T& subscript (unsigned int i) { | 
        | 
|    148 		arrayElement<T>* link; | 
        | 
|    149 		unsigned int x = 0; | 
        | 
|    150 		ITERATE_SUBSCRIPTS(link) { | 
        | 
|    151 			if (x == i) | 
        | 
|    152 				return link->value; | 
        | 
|    153 			x++; | 
        | 
|    154 		} | 
        | 
|    155 		 | 
        | 
|    156 		error ("array: tried to access subscript %u in an array of %u elements\n", i, x); | 
        | 
|    157 		return data->value; | 
        | 
|    158 	} | 
        | 
|    159 	 | 
        | 
|    160 	T* out () { | 
        | 
|    161 		int s = size(); | 
        | 
|    162 		T* out = new T[s]; | 
        | 
|    163 		unsigned int x = 0; | 
        | 
|    164 		 | 
        | 
|    165 		arrayElement<T>* link; | 
        | 
|    166 		ITERATE_SUBSCRIPTS(link) { | 
        | 
|    167 			out[x] = link->value; | 
        | 
|    168 			x++; | 
        | 
|    169 		} | 
        | 
|    170 		 | 
        | 
|    171 		return out; | 
        | 
|    172 	} | 
        | 
|    173 	 | 
        | 
|    174 	T& operator [] (const unsigned int i) { | 
        | 
|    175 		return subscript (i); | 
        | 
|    176 	} | 
        | 
|    177 	 | 
        | 
|    178 	void operator << (const T stuff) { | 
        | 
|    179 		push (stuff); | 
        | 
|    180 	} | 
        | 
|    181 	 | 
        | 
|    182 private: | 
        | 
|    183 	void deleteElement (arrayElement<T>* e) { | 
        | 
|    184 		if (e->next) | 
        | 
|    185 			deleteElement (e->next); | 
        | 
|    186 		delete e; | 
        | 
|    187 	} | 
        | 
|    188 	 | 
        | 
|    189 	arrayElement<T>* data; | 
        | 
|    190 }; | 
        |