core/CellArray.h
author Scott Ehlert <ds@alliedmods.net>
Wed Aug 15 06:19:30 2007 +0000 (2007-08-15)
changeset 1330 ab94316bb52b
parent 1231 17badaf66ce4
child 1664 e054be79e28a
permissions -rw-r--r--
Updated license headers on virtually all files with extremely minor changes in the name of some sort of strange consistency.
All plugin and include file headers also have been changed to say about GPL3 instead of GPL2.

(This day shall henceforth be known as the Eighty Column Massacre of '07)
dvander@1156
     1
/**
dvander@1156
     2
 * vim: set ts=4 :
ds@1330
     3
 * =============================================================================
dvander@1231
     4
 * SourceMod
dvander@1231
     5
 * Copyright (C) 2004-2007 AlliedModders LLC.  All rights reserved.
ds@1330
     6
 * =============================================================================
dvander@1156
     7
 *
ds@1330
     8
 * This program is free software; you can redistribute it and/or modify it under
ds@1330
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330
    10
 * Free Software Foundation.
dvander@1231
    11
 * 
ds@1330
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ds@1330
    15
 * details.
dvander@1231
    16
 *
ds@1330
    17
 * You should have received a copy of the GNU General Public License along with
ds@1330
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@1231
    19
 *
ds@1330
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
ds@1330
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ds@1330
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
ds@1330
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330
    27
 * or <http://www.sourcemod.net/license.php>.
dvander@1156
    28
 *
dvander@1156
    29
 * Version: $Id$
dvander@1156
    30
 */
dvander@1156
    31
dvander@1156
    32
#include <malloc.h>
dvander@1156
    33
#include <string.h>
dvander@1156
    34
dvander@1156
    35
class CellArray
dvander@1156
    36
{
dvander@1156
    37
public:
dvander@1156
    38
	CellArray(size_t blocksize) : m_Data(NULL), m_BlockSize(blocksize), m_AllocSize(0), m_Size(0)
dvander@1156
    39
	{
dvander@1156
    40
	}
dvander@1156
    41
	~CellArray()
dvander@1156
    42
	{
dvander@1156
    43
		free(m_Data);
dvander@1156
    44
	}
dvander@1156
    45
	size_t size() const
dvander@1156
    46
	{
dvander@1156
    47
		return m_Size;
dvander@1156
    48
	}
dvander@1156
    49
	cell_t *push()
dvander@1156
    50
	{
dvander@1156
    51
		if (!GrowIfNeeded(1))
dvander@1156
    52
		{
dvander@1156
    53
			return NULL;
dvander@1156
    54
		}
dvander@1156
    55
		cell_t *arr = &m_Data[m_Size * m_BlockSize];
dvander@1156
    56
		m_Size++;
dvander@1156
    57
		return arr;
dvander@1156
    58
	}
dvander@1156
    59
	cell_t *at(size_t b) const
dvander@1156
    60
	{
dvander@1156
    61
		return &m_Data[b * m_BlockSize];
dvander@1156
    62
	}
dvander@1156
    63
	size_t blocksize() const
dvander@1156
    64
	{
dvander@1156
    65
		return m_BlockSize;
dvander@1156
    66
	}
dvander@1156
    67
	void clear()
dvander@1156
    68
	{
dvander@1156
    69
		m_Size = 0;
dvander@1156
    70
	}
dvander@1156
    71
	bool swap(size_t item1, size_t item2)
dvander@1156
    72
	{
dvander@1156
    73
		/* Make sure there is extra space available */
dvander@1156
    74
		if (!GrowIfNeeded(1))
dvander@1156
    75
		{
dvander@1156
    76
			return false;
dvander@1156
    77
		}
dvander@1156
    78
dvander@1156
    79
		cell_t *pri = at(item1);
dvander@1156
    80
		cell_t *alt = at(item2);
dvander@1156
    81
dvander@1156
    82
		/* Get our temporary array 1 after the limit */
dvander@1156
    83
		cell_t *temp = &m_Data[m_Size * m_BlockSize];
dvander@1156
    84
dvander@1156
    85
		memcpy(temp, pri, sizeof(cell_t) * m_BlockSize);
dvander@1156
    86
		memcpy(pri, alt, sizeof(cell_t) * m_BlockSize);
dvander@1156
    87
		memcpy(alt, temp, sizeof(cell_t) * m_BlockSize);
dvander@1156
    88
dvander@1156
    89
		return true;
dvander@1156
    90
	}
dvander@1156
    91
	void remove(size_t index)
dvander@1156
    92
	{
dvander@1156
    93
		/* If we're at the end, take the easy way out */
dvander@1156
    94
		if (index == m_Size - 1)
dvander@1156
    95
		{
dvander@1156
    96
			m_Size--;
dvander@1156
    97
			return;
dvander@1156
    98
		}
dvander@1156
    99
dvander@1156
   100
		/* Otherwise, it's time to move stuff! */
dvander@1156
   101
		size_t remaining_indexes = (m_Size - 1) - index;
dvander@1156
   102
		cell_t *src = at(index + 1);
dvander@1156
   103
		cell_t *dest = at(index);
dvander@1156
   104
		memmove(dest, src, sizeof(cell_t) * m_BlockSize * remaining_indexes);
dvander@1156
   105
dvander@1156
   106
		m_Size--;
dvander@1156
   107
	}
dvander@1156
   108
	cell_t *insert_at(size_t index)
dvander@1156
   109
	{
dvander@1156
   110
		/* Make sure it'll fit */
dvander@1156
   111
		if (!GrowIfNeeded(1))
dvander@1156
   112
		{
dvander@1156
   113
			return NULL;
dvander@1156
   114
		}
dvander@1156
   115
dvander@1156
   116
		/* move everything up */
dvander@1156
   117
		cell_t *src = at(index);
dvander@1156
   118
		cell_t *dst = at(index + 1);
dvander@1156
   119
		memmove(dst, src, sizeof(cell_t) * m_BlockSize * m_Size);
dvander@1156
   120
dvander@1156
   121
		m_Size++;
dvander@1156
   122
dvander@1156
   123
		return src;
dvander@1156
   124
	}
dvander@1156
   125
	bool resize(size_t count)
dvander@1156
   126
	{
dvander@1156
   127
		if (count <= m_Size)
dvander@1156
   128
		{
dvander@1156
   129
			m_Size = count;
dvander@1156
   130
			return true;
dvander@1156
   131
		}
teame06@1198
   132
teame06@1198
   133
		if(!GrowIfNeeded(count - m_Size))
teame06@1198
   134
		{
teame06@1198
   135
			return false;
teame06@1198
   136
		}
teame06@1198
   137
teame06@1198
   138
		m_Size = count;
teame06@1198
   139
		return true;
dvander@1156
   140
	}
dvander@1156
   141
private:
dvander@1156
   142
	bool GrowIfNeeded(size_t count)
dvander@1156
   143
	{
dvander@1156
   144
		/* Shortcut out if we can store this */
dvander@1156
   145
		if (m_Size + count <= m_AllocSize)
dvander@1156
   146
		{
dvander@1156
   147
			return true;
dvander@1156
   148
		}
dvander@1156
   149
		/* Set a base allocation size of 8 items */
dvander@1156
   150
		if (!m_AllocSize)
dvander@1156
   151
		{
dvander@1156
   152
			m_AllocSize = 8;
dvander@1156
   153
		}
dvander@1156
   154
		/* If it's not enough, keep doubling */
dvander@1156
   155
		while (m_Size + count > m_AllocSize)
dvander@1156
   156
		{
dvander@1156
   157
			m_AllocSize *= 2;
dvander@1156
   158
		}
dvander@1156
   159
		/* finally, allocate the new block */
dvander@1156
   160
		if (m_Data)
dvander@1156
   161
		{
dvander@1156
   162
			m_Data = (cell_t *)realloc(m_Data, sizeof(cell_t) * m_BlockSize * m_AllocSize);
dvander@1156
   163
		} else {
dvander@1156
   164
			m_Data = (cell_t *)malloc(sizeof(cell_t) * m_BlockSize * m_AllocSize);
dvander@1156
   165
		}
dvander@1156
   166
		return (m_Data != NULL);
dvander@1156
   167
	}
dvander@1156
   168
private:
dvander@1156
   169
	cell_t *m_Data;
dvander@1156
   170
	size_t m_BlockSize;
dvander@1156
   171
	size_t m_AllocSize;
dvander@1156
   172
	size_t m_Size;
dvander@1156
   173
};