How to optimise out FindLink() from Eachin loop?

BlitzMax Forums/BlitzMax Programming/How to optimise out FindLink() from Eachin loop?

Type List Extends TList
	Field Enum:TListEnum

	Method ObjectEnumerator:TListEnum()
		enum=New TListEnum
		enum._link=_head._succ
		Return enum
	End Method

	Method CurrentLink:TLink()
		Return enum._link._pred
	End Method
End Type


;)

I'd leave it at using it for reading data, not modifying _pred/ _succ handles. I've tried. it didn't work very well. I wrote my own different style list:

Strict

Framework brl.blitz
Import brl.linkedlist
Import brl.standardio

Type Node
	Field Nxt:node, Prv:node
	Field Value:Object
	Field Parent:Group

	Method MoveFirst()
		If parent.head=Self Then Return
		If parent.tail=Self Then
			parent.tail=prv
		Else
			prv.nxt=nxt
			nxt.prv=prv
			prv=parent.tail
			nxt=parent.head
		EndIf
		parent.head=Self
	End Method
	
	Method MoveLast()
		If parent.Tail=Self Then Return
		If parent.head=Self Then
			parent.head=nxt
		Else
			prv.nxt=nxt
			nxt.prv=prv
			prv=parent.tail
			nxt=parent.head
		EndIf
		parent.tail=Self
	End Method
	
	Method Move(g:group)
		If prv Then prv.nxt=nxt
		If nxt Then nxt.prv=prv
		If g.head Then g.head.prv=Self
		If g.tail Then g.tail.nxt=Self
		nxt=g.head
		prv=g.tail
		parent=g
		If g.head=Null Then g.head=Self
		g.tail=Self
	End Method
End Type

Rem test
Local g:group=New group
g.AddLast("Function poo")
g.AddLast(" Print ~qhi~q")
g.AddLast("Function hi")
g.AddLast("End Function")
g.AddLast("End Function")

For Local n:node=EachIn g
'	Print String(n.Value)
	If (String(n.Value))[0..8]="Function" Then g.Startnewgroup(g.enum.current,(String(n.Value))[9..])
	If (String(n.Value))[0..12]="End Function" Then g.EndGroup(g.enum.current)
Next

For Local g2:node=EachIn g
	If group(g2) Then
		For Local n:node=EachIn group(g2)
			If group(n) Then
			Else
				Print String(n.value)
			EndIf
		Next
	Else
		Print String(g2.value)
	EndIf
Next
EndRem

Type Group Extends Node
	Field Head:node, Tail:node
	Field Enum:GroupEnum	
	Field s:stack
	
	Function FromArray:Group(o:Object[], val:Object=Null)
		Local g:group=New group
		g.value=val
		Local n:node=New node,pn:node=n
		g.Head=n
		n.Value=o[0]
		n.parent=g
		For Local i=1 Until o.length
			n:node=New node
			n.parent=g
			n.Value=o[i]
			pn.Nxt=n
			n.Prv=pn
			pn=n
		Next
		g.Tail=n
		n.nxt=g.Head
		Return g
	End Function
	
	Function FromTList:Group(l:TList, val:Object=Null)
		Local g:group=New group
		g.value=val
		Local n:node=New node, pn:node=n
		g.head=n
		Local o:Object
		For o=EachIn l
			n.parent=g
			n.Value=o
			pn.nxt=n
			n.prv=pn
			pn=n
			n:node=New node
		Next
		n.parent=g
		n.Value=o
		pn.nxt=n
		n.prv=pn
		g.Tail=n
		n.nxt=g.head
		Return g
	End Function

	Method New()
		s=New Stack
	End Method

	Method Delete()
		Remove
		Head.nxt=Null
		Head.prv=Null
		Tail.nxt=Null
		Tail.prv=Null
		Head=Null
		Tail=Null
	End Method
	
	Method Contains(val:Object)
		Local t:GroupEnum=enum
		enum=Null
		For Local n:node=EachIn Self
			If n.Value=val Then Return 1
		Next
		enum=t
		Return 0
	End Method
	
	Method Remove()
		For Local n:Node=EachIn Self
			n.prv.nxt=Null
			n.prv=Null
		Next
	End Method
	
	Method First:Node()
		Return head
	End Method
	
	Method Last:Node()
		Return tail
	End Method
	
	Method AddLast:Node(val:Object)
		Local n:node=New node
		n.value=val
		n.move(Self)
		Return n
	End Method
	
	Method AddFirst:Node(val:Object)
		Local n:node=New node
		n.value=n
		n.move(Self)
		n.movefirst()
		Return n
	End Method
	
	Method Startnewgroup(n:node, val:Object=Null)
		Local gs:GroupStarter=New GroupStarter
		gs.v=val
		gs.n=n
		s.Push(gs)
	End Method
	
	Method EndGroup:Group(n:node)
		Local gs:groupstarter=groupstarter(s.pop())
		Return GroupRange(gs.n,n,gs.v)
	End Method
	
	Method GroupRange:group(start:node,en:node, val:Object=Null)
		start.prv.nxt=en.nxt
		en.nxt.prv=start.prv
		Local g:group=New group
		start.prv=en
		If en=enum.current Then If enum.current.nxt<>Null Then enum.current=enum.current.nxt Else enum.current=Null
		en.nxt=start
		g.head=start
		g.tail=en
		g.move(Self)
		Return g
	End Method
	
	Method ObjectEnumerator:GroupEnum()
		If enum=Null Then
			Enum=GroupEnum.Create(Self)
		ElseIf 0=Enum.HasNext() Then
			Enum=GroupEnum.Create(Self)
		EndIf
		Return Enum
	End Method
End Type

Type GroupStarter
	Field v:Object,n:node
End Type

Type GroupEnum
	Field gr:group
	Field Current:Node
	Field qwerty:Byte
	
	Function Create:GroupEnum(g:group)
		Local ge:groupenum=New groupenum
		ge.gr=g
		If g.head<>Null Then ge.Current=g.head
		Return ge
	End Function
	
	Method HasNext()
		If current Then Return Current.nxt<>gr.head Else Return 0
	End Method
	
	Method NextObject:Object()
		If current<>gr.head Then current=current.nxt ElseIf qwerty Then current=current.nxt Else qwerty=1
		Return current
	End Method
End Type

'LIFO stack
Type Stack
	Field frst:StackElement
	
	Method Push(v:Object)
		Local se:stackelement=New stackelement
		se.nxt=frst
		se.value=v
		frst=se
	End Method
	
	Method Pop:Object()
		Local t:Object=frst.Value
		frst=frst.nxt
		Return t
	End Method
End Type

Type StackElement
	Field nxt:StackElement
	Field Value:Object
End Type


Enum is public, so just access Enum.Current.