You know, I really hate the STL.
Here's a lame class (ATC) that you can use to implement ITERATOR under masm.
An Iterator is a kind of abstraction of a Pointer - it's a class that provides an array of Pointers as well as some code to manage the array (per instance of the class).

Before you can use it, you will need to add the following macro to your ATC (class.inc) file..
remalloc macro pmem:REQ, How:REQ
invoke HeapReAlloc,HEAP1,HEAP_ZERO_MEMORY,pmem, How
exitm <eax>
endm

This class could do with some more work, and I am open to suggestions and/or code submissions to improve this class further (for example, there's no bounds checking at the moment).

Have a nice day :)



;===================
;Homer's Iterator Class
;===================
;STL == HELL ON A HOBBY HORSE

;Base Class - Does not inherit
;Provides a dynamically growable array of dwords
;(ostensibly meant to hold Pointers to other objects)
;as well as some Access methods.
;DANGER, WILL ROBINSON !!
;This class does not support insertion/deletion of array elements

class CLITerator, ,C++ compatible
virtual begin ;returns address of first dword in array
virtual end ;returns address of last dword in array
virtual read ;reads dword value from array
virtual write ;writes dword value to array
virtual grow ;reallocates the arrayspace to (usually) larger size
long pArraySpace ;pointer to our array of dwords
long CurrentSize ;current size of array in Bytes
long MaxSize
endclass

;======================================
;CONSTRUCTOR
;Allocates one page (4kb) minimal arrayspace
CLITerator_CLITerator proc
mov [ecx].CLITerator.MaxSize,4096
mov [ecx].CLITerator.pArraySpace, malloc (4096)
ret
CLITerator_CLITerator endp
;======================================
;DESTRUCTOR
;Free the array
CLITerator_$CLITerator proc
free [ecx].CLITerator.pArraySpace
CLITerator_$CLITerator endp
;======================================
;Return the address of first dword in array
CLITerator_begin proc
return [ecx].CLITerator.pArraySpace
CLITerator_begin endp
;======================================
;Return the address of LAST dword in array
CLITerator_end proc
.if [ecx].CLITerator.CurrentSize>=4
mov eax,[ecx].CLITerator.CurrentSize
add eax, [ecx].CLITerator.pArraySpace
sub eax,4
ret
.endif
return [ecx].CLITerator.pArraySpace
CLITerator_end endp
;======================================
CLITerator_grow proc cbNewSize
mov [ecx].CLITerator.pArraySpace, remalloc ([ecx].CLITerator.pArraySpace, cbNewSize)
ret
CLITerator_Grow endp
;======================================
;Read the Nth DWORD from Array
CLITerator_read proc n
mov eax,[ecx].CLITerator.pArraySpace
return dword ptr [eax+n*4]
CLITerator_read endp
;======================================
;Write to the Nth DWORD in Array
CLITerator_write proc n, xxx
mov eax,[ecx].CLITerator.pArraySpace
mov dword ptr [eax+n*4], xxx
ret
CLITerator_write endp
;======================================
Posted on 2004-04-13 06:05:18 by Homer
OK Now I've started USING this class already.
Here, I've added the most useful class method so far:
the STL ITERATOR push_back method WOOHOOOO :)
All it does is write a dword to the end of the array,
and growing the array on demand when required...
don't forget to add this line to the Class Definition !
virtual push_back:darth

Note that I chose NOT to use the CLITerator_write method in oder to write the data to the array - we should not use OOP just for the sake of using it - we should avoid unnecessary call overhead, or we should code in kiddieskript instead, yes?



CLITerator_push_back proc darth
mov eax,[ecx].CLITerator.CurrentSize
add eax,4
.if eax>[ecx].CLITerator.MaxSize
icall ecx, CLITerator, grow, eax
.endif
push eax
icall ecx, CLITerator, end
pop ebx
mov [ecx].CLITerator.CurrentSize,ebx
mov dword ptr[eax],darth
ret
CLITerator_push_back endp


Happy Days :)
Posted on 2004-04-13 09:41:11 by Homer
Is this a container or an iterator, or both? I think it might benefit from a name change to vector_iterator or something.
Posted on 2004-04-13 18:02:12 by iblis
I have "slightly" edited your tread titles so that i will not look like something offensive
Sorry but automated content scanners block such words
Posted on 2004-04-13 23:31:11 by BogdanOntanu
If someone could figure out how to do inline expansion, I bet you could get rid of a lot more call overhead.
Posted on 2004-04-14 07:57:44 by ThoughtCriminal
iblis - STL internally manages dynamic arrays of elements of arbitrary size, this is merely my own interpretation of the same, meant to be as generic as possible and inherited by higher classes. I have provided an initial 4k page of space which is growable on demand, which is meant to hold N pointers to "anything you like" basically, and provided some randomaccess methods of accessing the pointers (or whatever dwords u otherwise choose to store)... as generic as possible, with the caveat that data is dword-sized only.
Since I've written it as an atc baseclass, we can either create as many instances of the class object as we choose ( i mean actual # of dynamic arrays here, not # of entries, of course), or simply inherit in higher classes.

ThoughtCriminal - that's pretty much what happens in atc - most of the work is done by compiletime macros rather than active code :)
Posted on 2004-05-19 08:55:27 by Homer
homer, have you implemented an interator or a vector container? :confused:

Afaik, the iterator is only the (generic) accessor used to traverse the elements in a container - yours look more like the actual container? :confused: . Something like STL would probably be pwetty hawd to set up in (m)assembly, at least without some form of preprocessor.
Posted on 2004-05-19 09:08:29 by f0dder
f0dder - I simply haven't provided any object-specific methods here in this example. I have deliberately left it naked.
I guess you are right, in this form it's not really an iterator yet, it's just meant to be simple and readable, as an example of how to write classes with atc and masm, with regards to support-classes encountered in C++ sourcecode.
Posted on 2004-05-19 09:12:32 by Homer