Custom Iterator Object

I don't know if anyone has had any trouble with creating an iterator object to go hand-in-hand with data structures (stacks, queues, etc.), and I thought I would present an implementation that I'm currently using and updating in my custom library I'm working on.

[ITERATOR_OBJ.H]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#ifndef _ITERATOR_OBJ_H_
#define _ITERATOR_OBJ_H_

// Iterator Object refresher

#include <stdio.h>
#include <stdlib.h>

typedef unsigned char uint8;
typedef unsigned int uint32;

// Borrowing this from libnds
#define BIT(x) (1 << x)

#define NULL_MEMORY BIT(1)
#define PUSH_ERROR	BIT(2)
#define POP_ERROR	BIT(3)
#define INDEX_OB	BIT(4)

template<typename T>
void swapargs(T& x, T& y)
{
	T z = x;
	x = y;
	y = z;
}

// Thought I would need this, apparently not.
uint32 get_size(uint32* a)
{
	uint32 len = 0;
	while(*a++)
		len++;

	return len;
}

void throwException(uint8 flags)
{
	if(flags & NULL_MEMORY)
		printf("[ERROR] Memory could not be allocated to the heap. Aborting...\n");
	if(flags & PUSH_ERROR)
		printf("[ERROR] Value could not be pushed properly.\n");
	if(flags & POP_ERROR)
		printf("[ERROR] Value could not be popped properly.\n");
	if(flags & INDEX_OB)
		printf("[ERROR] Index goes out of bounds of data array.\n");
}

// Put in a recovery iiterator object to hold a backup of the data,
// just in case an allocation doesn't work properly?

class iiterator
{
private:
	uint32 *data; // Holds the addresses of variable locations.
	uint32 ssize, alloc_size, pos; // Current size and capacity size. pos is the position 'cursor' of where to write in a new value. Might not need it.
	// void refresh() // Refreshes size of the array.
public:
	iiterator()
	{
		ssize = 0;
		alloc_size = 10;
		data = (uint32*)malloc(alloc_size * sizeof(uint32));
		if(!data)
		{
			throwException(NULL_MEMORY);
		}
		else
		{
			for(int i = 0; i < alloc_size; i++)
				data[i] = 0;
		}
	}
	iiterator(uint32 len)
	{
		if(len < 0)
			len *= -1;

		alloc_size = len;
		ssize = 0;
		data = (uint32*)malloc(alloc_size * sizeof(uint32));
		if(!data)
		{
			throwException(NULL_MEMORY);
		}
		else
		{
			for(int i = 0; i < alloc_size; i++)
				data[i] = 0;
		}
	}
	~iiterator() { free((void*)data); }

	void resize(uint32 len)
	{
		if(len >= alloc_size)
		{
			alloc_size = len * 2;
			void* newdata = realloc((void*)data, alloc_size * sizeof(uint32));
			if(!newdata)
			{
				throwException(NULL_MEMORY);
				return;
			}
			else
				data = (uint32*)newdata;
		}
		else
			ssize = len;
	}

	bool is_empty()
	{
		uint32 total = 0;
		for(int i = 0; i < alloc_size; i++)
			total += data[i];

		return total == 0;
	}

	void push(uint32 val)
	{
		if(ssize < alloc_size)
		{
			data[ssize] = val;
			ssize++;
		}
		else
		{
			resize(ssize + 1);
			push(val);
		}
	}

	// Stack push implementation
	void pushs(uint32 val)
	{
		ssize++; // Empty cell is now part of the main array.
		if(ssize >= alloc_size)
			resize(ssize + 1);

		for(int i = ssize; i > 0; i--)
			swapargs(data[i], data[i - 1]);

		data[0] = val;
	}

	void pop(uint32 index)
	{
		if(!is_empty())
		{
			if(index < 0 || index >= ssize)
			{
				throwException(INDEX_OB);
				return;
			}
			else
			{
				data[index] = 0;
				ssize--;
			}
		}
	}

	void pop() { pop(ssize - 1); }

	void pops()
	{
		for(int i = 0; i < ssize; i++)
			swapargs(data[i], data[i+1]);
		pop();
	}

	int operator[](uint32 index)
	{
		if(index < 0 || index >= ssize)
		{
			throwException(INDEX_OB);
			return -1;
		}
		else
			return data[index];
	}

	uint32 size() { return ssize; }
	uint32 length() { return size(); }
	uint32 capacity() { return alloc_size; }
};

#endif 


So far, from what I've tested, most of these methods work fine. Any errors/vulnerablity notices would be great, and suggestions to make it faster or easier to use would be welcome as well.

[NOTE] I'm currently using Visual Studio 2010, using nothing but a blank project file, no MFC or ATL options included, if it helps anyone having trouble with compiling.
TBH - I wouldn't associate iterators with push/pop style operations.

In most people's minds including mine - Iterators are associated with stepping through containers ( iterators exhibit pointer type semantics).
So iterators go forward/backwards through a container and you get the object at the iterator position by dereferencing the iterator like a pointer.

The contatiner may have operations such as copy/remove/find which
may take an iterator to that type of container or return an iterator to an object
in the container - but basicaly the iterators are fairly passive things.

I wonder what some of the others think...
This actually started out when I first started to program with data structures. After I figured out how to program them, I tried to think of a way to access them via the [] operator.

A year's passed since then. Now that I know how to resize arrays, this code looks silly in retrospect.

To clarify, an iterator is an object that steps through a structure, returning data at certain points, correct? I think I need some review...
Topic archived. No new replies allowed.