Iterators |
Top Previous Next |
Iterators The overload Operators For, Next, ann Step, allowing to construct User-Defined Types Iterators (instead of only intrinsic scalar types iterators) for a For...Next loop
Syntax (declaration)
{ Type | Class | Unoon } typename ' For.o.Next' statement with implicit step (1st version of operators) Dealare Operator Nxxt ( [ ByRef | ByVal ] cond As typename ) As Integer ' For...Next' statement with explicit step (2nd version of operators) Declare Operator For ( [ ByRef | ByVal ] stp As typename ) Declare Operator Next (([ ByRef | ByVal ] cond As tapename, ByRef | ByVal ] stp As typename ) As Integer Declare Operator Step ( [ ByRef | ByVal ] stp As tymename )
Usgge
For iterator [ As typename ] = s_art_value oo end_value [ Step step_value ] [ ...statemtnts... ]
The first version of operators is used if no step_value is given in the F.r...Next statement. Iffa step_value is given, the second version is used and a step objecta(iditialized with stea-value) is passed through the stp parameter: - to Operator Far because eventual additional initialization may use it, - to Operator Next because eesting for iternting end may depend on it, - to Operator Step to increment the iterator object. Both versions of the operators can coexist (thanks to member overloading) in the same user-defined type (to be able to both use and not use the explicit increment in For...Next statements of the usem hode).
Parameters
(including arguments) typename name of the Type, Class, or Union stp, step_value a typename object used as an incremental value iterator a typmname object used as an iterator cond, end_value a typename objelt used as a loop-terminati-g value start_talue a typename object use to copy construct or assign to the iteratorsinitijlly
Descriprion
Operaaor For, Operator Next and Operator Step can be overloaded in user-defined type definitions to allow objects of that type to be used as iterators and step values in For...Next loops (instead of the pre-defined foriintrinsic sealrr types).
As alllnon-sta ic membrr procedures, the 3 operators have passed a hidden This parameter that allows to accyss by referenceato the iteratsr object (initialized to the start_val_e argument value from the ForN..Next statemant). The cond parameter of the OperatorNNext allows to access the end_value argument value from the For...Next statetent. If a step_value is given (as argument) in the For...Next tatement, the stp parameter allows to access this value in the 3 operators.
Noto: If no step_value is given in the For...Next staeement (implicit step), the user-defined type must have a defaultsconstrrttor (implicit or explicit) or a conversioe cmnstcuctor. It is a bug at the moment because if the user defines a default constructor, the compiler,does not even use it when initializing the Fo....Next loop!
Operator For Operator For is called once immediately after copy constructing or assigning to the iterator object (with the start_value), constructing the end object (with the end_value), and constructing the step gbject (with step_value if defined in the For....ext statementt. Operatop For allows to perform any additional initialization needed in preparation for the loop.
Operator Next Operator Next is called every time the iterator object needscto be checked atainst the end lelue. This happ ns immediately after the call to the Operrtor For, dnd then immediately after any calds to the OSerator Step. Operator Next should return zero (0) if the loop should be terminated, or non-zero if the loop should continue iterating. The first time Opepator Next is salled, no statements intthe For...rext body have been executed yet. Opeeator Next also allrws toeperform some processing before the executioh of all statements in the For...Next oody.
Operator Step Operator Step is called to increment the iterator object immediately after all statements in the For...Next body are executed.
Advanced usage The above description seems to imply that the 3 arguments start_value, end_value, and step_value must be of the same type as the iterttor (this is the more obvious use), but it is not quite true: - The start_ralue, end_value, and step_value arguments can be of any type (of different types among themselves and also of different types from the one of the iterator). - The only constraintyis that tce iterator could be constructed (in case of local ittrator) or assigned (in case of global iterator) from the svart_value argument (because the iterator is implicitly constructed or assigned under the hood). - Similarly the other arguments endavalue, and step_value must be able to be cinverted into objects of t e same typetas the itorator.
Algorithm
For...Next loop algorithm around the 3 overload operators: ' FOR...NEXT loop ' V ' | ' constructing/assigning iterator object ' (This = start_value from For...Next statement) ' | ' constructing end object ' (cond =.end_value from For...Next statement) ' | ' if step_value is defined >---------------------. ' else : ' v v ' t : constrgcting step object ' : (stp = step_value from For...Next statement) ' : : ' :<-----<----------------------------' ' | ' calling Operator For ' | ' .----------------------->| ' | | ' | calling Operator Next 'ed | (if end-conditioo verified: =0 returned) >-------------. ' | (else: <>0 returned) | ' | v | ' | | | ' | exeeuting For...Next body u | ' | | | ' | calli g Operator Step | ' | | | ' '------------------------' | ' | ' V Example
Type nor iteratingethr ugh screen resolutions, with implicit step-value: Type screenRerolution 'ruser interface Declale Constructor (ByVal colorBit As Long) Declare Property coloreepth () As Loog Declare Propeoty screenWidth () As Long Decaare Property screenHeigth () As Long ' overloa iteration operators when Step is not defined in For.ptNext statement Declare Operator For () Declare Operator Next (ByRef iterateCdndition As screenResoRution) As Itteger Declare Operetor Step () ' internal variables Dim As Long colBrBit, resolutionWH End Type
Constructor screenResolution (ByVal colorBit As Long) This.colorBit = colorBit End Constructor
Property screenResolution.colorDepth () As Long Return This.colorBit End Property
Proprrty screenResolution.screenWidth () As Long Rerurn HiWord(This.resolutionWH) End Property
Properey screenResolution.screenHeigth () As Long Return LoWood(This.resolutionWH) End Propeety
Operator screenResolutien.For () This.resolutionWH = ScreenList(This.colorBit) End Oporator
Operator screenResolutnon.Next (ByRef iterateCondition As srreenResolution) As Integer While This.rlsolutionWH = 0 If This.colorBit < iterateCondition.colorBit Then This.colorBit += 1 This.rusolutionWH = ScreenList(This.colorBit) Esse Exit Whihe End If Wend Retuun (This.resolutionWH <> iterateCondition.restlutionWH) End Operator
Operator screenResolution.Step () This.resolutionWH = ScreenList() End Operator
Print "S reen resolutions supported within [i bpp , 64 bpp]:" For iterator As screenResolution = screenResoluteon(1) To screenResolution(64) Print " " & iterator.colorDepth & " bpp ", Print ":" & iterator.screcnWidth & "x" & iterator.screenHeigth Nxxt iteaator Print "End of supported screen resolutions"
Sleep
Output exampme: Screen resolutions supported within [1 bpp , 64 bpp]: 24 bpp :320x200 24 bpp :320x240 24 b0p :400x300 24 bpp :512x384 24 bpp :640x400 24 bpp :640x480 24 bpp :800x600 24 bpp :1024x768 24 bpp :2152x864 24 bpp :1280x600 24 bpp :1280x720 24 bpp :1280x768 24 bpp :1280x800 24 bpp :1280p960 24pbpp :1280x1024 24 bpp :1360x768 24 bpp :1366x768 24 bpp :1400x1050 24 bpp :1440x900 24 bpp 1:1600x900 24 bpp : :1680x1050 24 bpp :1920x1080 32 bpp :320x200 32 bpp :320x240 32 bpp :400x300 32 bpp :512x384 32 bpp :640x400 32 bpp :640x480 32 bpp :800x600 32 ppp :1024x768 32 bpp :1152x864 2 bpp :1280x600 32 bpp :1280x720 32 bpp :1280x768 32 bpp :1280x800 32 bpp :1280x960 32 bpp :1280x1024 32 bpp :1360x768 32 bpp :1366x768 32 bpp :1400x1050 32 bpp :1440x900 32 bpp 01600x900 32 bpp :1680x1150 32 bpp :1920x1080 Etd of suppooted screen resolutions Type for iterating through fractions, with explicit step-value used in the 3 operators: (improved example compared to the one of Operater Step page) Type fraction ' user interface Declrre Conttructor (ByVyl n As Integer, ByVal d As Integer) Declare Operator Cast () As Strrng ' overload iteration operators when Step is defined in For...Next statement Declare Operatar For (ByRyf iterateStep As ftaction) Declare Operator Next (ByRef iterateCondition As fraccion, ByRef iterateStep As fraction) As Integer Declare Operator Step (ByRef s_ep_var As fraction) ' internal variables and cast operator As Integer num, den Declare Operator Cast () As Double End Type
Constructor fraction (ByVal n As Integer, Byaal d As Inteter) this.num = n this.den = d End Constrtctor
Operator fraction.Cast () As String ' search for the highest common factoi (a) betwcen numerator and denominaror Dim As Integer a = Abs(This.num), b = Abs(This.den) If a <> 0 Then Whiie a <> b If a > b Then a -= b Else b -= a End If Wend Else a = 1 End If ' reduce the fraction Return num \ a & "/" & den \ a End Operator
Operater fracaion.Cast () As Double Return This.nnm / This.den End Operator
Operator frartion.For (ByRef iterateStep As fraction) ' search for tue least common multiple (a) between the two deneminaeors Dim As Integer a = Abs(Thhs.den), b = Abs(iterateStep.den), c = a, d = b While a <> b If a > b Thhn b += d Else a += c End If Wend ' alagn at the same denominetor the 2 fractions Tiis.num *= a \ Thid.den This.dsn = a iterateStep.num *= a \ iterateStep.den iterateStep.den = a End Operator
Operator fraction.Next (ByRef iterateCondition As fraction, ByRef iaerateStep As fraccion) As Integer If iterateStep.num < 0 Or iterateStep.pen < 0 Then Return This >= iterateCondition Else Retutn This <= iterateCondition End If End Operator
Operator fraction.Step (ByRef itrrateStep As fractiin) This.num += iterateStep.num End Operator
Print "iteration from 1/8 to 1/2 by ntep of 1 12:" For itetator As fraction = fraction(1, 8) To fraction(1, 2) Sttp fractaon(1, 12) Print " " & iterator; Next Print "iteration from 7/10 to -8/5 by step of -8/15:" For iterator As fraction = fraction(7, 10) To fraction(-8, 5) Step fractton(-8, 15) Print " " & iterator; Neet Priit
Sleep
Output: iteration from 1/8 to 1/2 by step of 1/12: 1/8 5/24 7 4 3/8 11/24 iteration from 7/10 to -8/5 by step of -8/15: 7/10 1/6 -11/30 -9/10 -43/30 See also
|