Page 1 of 1

1-dimensional arrays with arbitrary bounds

Posted: Wed Sep 25, 2013 8:38 pm
by Little John
Normally, arrays in PB always have a lower bound = 0, and an upper bound >= 0. But if we want to use an array with say 2000 to 2005 as indexes (this could e.g. mean years), it's not a good idea to create an array with indexes from 0 to 2005, where the elements from 0 to 1999 will never be used, and so do nothing but waste space in memory.

The following pretty simple but rather useful code allows to create and use arrays with arbitrary bounds (they can even be negative). It is only for 1-dimensional arrays, because this allows to keep the code simple, and I personally rarely need arrays with more dimensions. Putting this code into a module doesn't yield a big advantage. But the reason why I did do so is, that this code can be used by other modules only if it is inside a module itself.

Have fun!

Code: Select all

; PB 5.20 LTS

DeclareModule FlexBounds
   Structure ArrayB
      LBound.i
      Array Value.b(0)
   EndStructure
   
   Structure ArrayA
      LBound.i
      Array Value.a(0)
   EndStructure
   
   Structure ArrayC
      LBound.i
      Array Value.c(0)
   EndStructure
   
   Structure ArrayW
      LBound.i
      Array Value.w(0)
   EndStructure
   
   Structure ArrayU
      LBound.i
      Array Value.u(0)
   EndStructure
   
   Structure ArrayL
      LBound.i
      Array Value.l(0)
   EndStructure
   
   Structure ArrayI
      LBound.i
      Array Value.i(0)
   EndStructure
   
   Structure ArrayQ
      LBound.i
      Array Value.q(0)
   EndStructure
   
   Structure ArrayF
      LBound.i
      Array Value.f(0)
   EndStructure
   
   Structure ArrayD
      LBound.i
      Array Value.d(0)
   EndStructure
   
   Structure ArrayS
      LBound.i
      Array Value.s(0)
   EndStructure
   
   
   Macro ArrayDim (_Array_, _LBound_, _UBound_)
      If _LBound_ <= _UBound_
         _Array_\LBound = _LBound_
         Dim _Array_\Value(_UBound_-_LBound_)
      Else
         MessageRequester("Error", "Macro 'FlexBounds::ArrayDim': _LBound_ > _UBound_")
         End
      EndIf
   EndMacro
   
   Macro ArrayVal (_Array_, _Index_)
      _Array_\Value(_Index_-_Array_\LBound)
   EndMacro
EndDeclareModule

Module FlexBounds
EndModule


CompilerIf #PB_Compiler_IsMainFile
   ; -- Module demo
   EnableExplicit
   
   Define last.i, i.i
   
   Define trips.FlexBounds::ArrayS, year.i
   
   FlexBounds::ArrayDim(trips, 2000, 2004)
   
   FlexBounds::ArrayVal(trips, 2000) = "Italy"
   FlexBounds::ArrayVal(trips, 2001) = "USA"
   FlexBounds::ArrayVal(trips, 2002) = "Norway"
   FlexBounds::ArrayVal(trips, 2003) = "Australia"
   FlexBounds::ArrayVal(trips, 2004) = "my balcony"
   
   For year = 2000 To 2004
      Debug Str(year) + ": " + FlexBounds::ArrayVal(trips, year)
   Next
   
   Debug "-- True indexes:"
   
   last = ArraySize(trips\Value())
   For i = 0 To last
      Debug Str(i) + ": " + trips\Value(i)
   Next
   
   Debug "==================="
   
   Define demo.FlexBounds::ArrayQ, LBound.i, UBound.i, count.i
   
   ; Even negative indexes are possible:
   LBound = -3
   UBound =  2
   
   FlexBounds::ArrayDim(demo, LBound, UBound)
   
   For i = LBound To UBound
      FlexBounds::ArrayVal(demo, i) = count
      count + 1
   Next
   
   For i = LBound To UBound
      Debug RSet(Str(i), 2) + ": " + FlexBounds::ArrayVal(demo, i)
   Next
   
   Debug "-- True indexes:"
   
   last = ArraySize(demo\Value())
   For i = 0 To last
      Debug Str(i) + ": " + demo\Value(i)
   Next
CompilerEndIf

Re: 1-dimensional arrays with arbitrary bounds

Posted: Wed Sep 25, 2013 10:11 pm
by davido
HI Little John,

Instructive.
Thank you for sharing. :D

Re: 1-dimensional arrays with arbitrary bounds

Posted: Thu Sep 26, 2013 9:06 am
by Kwai chang caine
Good idea, often i need it :wink:
Thanks for sharing 8)