IsArray(), IsList() and IsMap()

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User_Russian
Addict
Addict
Posts: 1443
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

IsArray(), IsList() and IsMap()

Post by User_Russian »

I suggest adding the functions of checking the validity of the array, list and map.

Code: Select all

Procedure Proc(Array a(1), List l(), Map m())
  
  If IsArray(a())
    ; This code will be executed if the Array is valid.
  EndIf
  
  If IsList(l())
    ; This code will be executed if the List is valid.
  EndIf
  
  If IsMap(m())
    ; This code will be executed if the Map is valid.
  EndIf
  
EndProcedure


Proc(0, 0, 0)

Code: Select all

NewList l()

FreeList(l())

If IsList(l()) = 0
  NewList l()
EndIf
Functions IsArray(), IsList() and IsMap() return the pointer to an array, list or map.
Or 0 if they are not valid.
User avatar
jacdelad
Addict
Addict
Posts: 1431
Joined: Wed Feb 03, 2021 12:46 pm
Location: Planet Riesa
Contact:

Re: IsArray(), IsList() and IsMap()

Post by jacdelad »

This would cause problems in procedures, because you already have to define the type in the procedure header (unless you use addresses).
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: IsArray(), IsList() and IsMap()

Post by BarryG »

Wouldn't ArraySize(), ListSize(), and MapSize() be good enough to detect if they've been used? ArraySize() returns -1 if the array doesn't exist, so that'll definitely work; and ListSize() and MapSize() both return 0 if they don't contain any elements. But I don't know what your code is doing, so maybe they're not the solution you're looking for.
User_Russian
Addict
Addict
Posts: 1443
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Re: IsArray(), IsList() and IsMap()

Post by User_Russian »

BarryG wrote: Wed Jun 22, 2022 9:52 pmListSize() and MapSize() both return 0
The debugger reports an error. If disable the debugger, the application crashes.

Code: Select all

NewList l()
NewMap m()

FreeList(l())
FreeMap(m())

x = ListSize(l())
y = MapSize(m())
Debug x
Debug y
AZJIO
Addict
Addict
Posts: 1315
Joined: Sun May 14, 2017 1:48 am

Re: IsArray(), IsList() and IsMap()

Post by AZJIO »

We have a pointer and a type (array, list, map) of how the pointer relates to the data. That is, we ourselves give the type. If you need to check the type, then the data must contain at the beginning the data bytes (1, 2, 3), which determines what the data is. Someone will break the program if he tried to access the data directly. For example, the Arr.s{1}(5) array will contain 6 elements one after the other, one character at a time, and you can take the data by pointer with a shift. If you add a flag to the beginning of the array that defines the data, then accessing the pointer with a shift will be broken.
User avatar
Regenduft
Enthusiast
Enthusiast
Posts: 121
Joined: Mon Mar 02, 2009 9:20 pm
Location: Germany

Re: IsArray(), IsList() and IsMap()

Post by Regenduft »

My workaround for linked lists and maps. Works with ASM and C backend on x64 and on x86:

Code: Select all

EnableExplicit


CompilerIf #PB_Compiler_Processor <> #PB_Processor_x64 And 
           #PB_Compiler_Processor <> #PB_Processor_x86
  CompilerWarning "Only tested on x64 and x86. Maybe NOT working correctly"
CompilerEndIf


Procedure.i ProcIsListOrMap(*ListOrMap.Integer)
  CompilerSelect #PB_Compiler_Backend
      
    CompilerCase #PB_Backend_Asm
      ProcedureReturn *ListOrMap
      
    CompilerCase #PB_Backend_C
      ProcedureReturn *ListOrMap\i
      
    CompilerDefault
      CompilerError "ASM or C backend expected"
      
  CompilerEndSelect
EndProcedure


Prototype.i ProtoIsList(List List())
Global IsList.ProtoIsList = @ProcIsListOrMap()

Prototype.i ProtoIsMap(Map Map())
Global IsMap.ProtoIsMap = @ProcIsListOrMap()


; "IsArray()" does NOT work!
; "ArraySize()=-1" DOES work!
Prototype.i ProtoIsArray(Array Array(1))         ;<-- Does NOT work (ASM)!
Global IsArray.ProtoIsArray = @ProcIsListOrMap() ;<-- Does NOT work (ASM)!


If #True
  Global NewList ListA()
  Global NewMap MapA()
  Global Dim ArrayA(123)
EndIf

If #False
  Global NewList ListB()
  Global NewMap MapB()
  Global Dim ArrayB(123)
EndIf


Debug "IsList(ListA()) = " + IsList(ListA())
Debug "IsMap(MapA()) = " + IsMap(MapA())
Debug "IsArray(ArrayA()) = " + IsArray(ArrayA())
Debug "ArraySize(ArrayA()) = " + ArraySize(ArrayA())

Debug ""

Debug "IsList(ListB()) = " + IsList(ListB())
Debug "IsMap(MapB()) = " + IsMap(MapB())
Debug "IsArray(ArrayB()) = " + IsArray(ArrayB()) + " <-- See? Does NOT work! (ASM)"
Debug "ArraySize(ArrayB()) = " + ArraySize(ArrayB()) + " <-- But this DOES work! (always)"

Debug ""
Debug "...free ListA(), MapA(), ArrayA()..."
FreeList(ListA())
FreeMap(MapA())
FreeArray(ArrayA())
Debug ""

Debug "IsList(ListA()) = " + IsList(ListA())
Debug "IsMap(MapA()) = " + IsMap(MapA())
Debug "IsArray(ArrayA()) = " + IsArray(ArrayA()) + " <-- See? Does NOT work! (ASM)"
Debug "ArraySize(ArrayA()) = " + ArraySize(ArrayA()) + " <-- But this DOES work! (always)"
Post Reply