IIFs & Tricks

Share your advanced PureBasic knowledge/code with the community.
User avatar
Piero
Addict
Addict
Posts: 923
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

IIFs & Tricks

Post by Piero »

I think/hope this deserves a place here (Wise Admins permitting…)
It's not for EXTREME speed; just for convenience…
ANY suggestion/critic Welcome!

Code: Select all

Procedure.d priifn(e,t.d,f.d) ; "temporary Double" for non-String types
   If e : ProcedureReturn t : EndIf : ProcedureReturn f
EndProcedure

Procedure.s priifs(e,s.s,d.s)
   ProcedureReturn StringField(s,Bool(Not(e))+1,d)
EndProcedure

Macro IIFn(e,t,f) ; IIFn(true?, trueNumber, falseNumber)
   priifn(Bool(e),t,f)
EndMacro

#iifsdelim="|"
Macro IIFs(e,s,delim=#iifsdelim) ; IIFs(true?, "trueString|falseString")
   priifs(Bool(e),s,delim) ; delimiter can be multi-characters
EndMacro

Macro IIF(e,t,f) ; IIF(a=b?, x=1, s="y")
   If Bool(e) : t : Else : f : EndIf ; Bool just in case
EndMacro

CompilerIf #PB_Compiler_Debugger
   Macro dq : "
   EndMacro
   Macro diifexpr(e,s,i="is") ; "non-blocking assert" (no CallDebugger)
      Debug ~"File: \""+#PB_Compiler_Filename+
         ~"\"\nLine "+ #PB_Compiler_Line + ~": \""+ dq#e#dq +~"\" "+i+" "+ IIFs(e,s)
   EndMacro
   Macro BadAssert(e,t="") ; blocking if true
      If e
         Debug ~"File: \""+#PB_Compiler_Filename+
            ~"\"\nLine "+ #PB_Compiler_Line + ~": \""+ dq#e#dq +~"\" is true! "+t
         CallDebugger
      EndIf
   EndMacro
CompilerElse
   Macro diifexpr(e,s,i=""):EndMacro
   Macro BadAssert(e,t=""):EndMacro
CompilerEndIf

BadAssert(x<>0,x) ; x should be 0 (and is also integer) by default
Debug ~"--- IIFs ---\n"

x=10 : Debug "x = "+x
Debug ""+x+" Point"+ IIFs(Not(x=1), "s") ; also IIFs(x<>1,"s")
Debug ""+x+" is "+ IIFs(x&1, "Odd|Even")
diifexpr(1&#False Or x/(x-8)=5, "true|not true!")
Debug ""
x=1 : Debug "x = "+x
Debug ""+x+" Point"+ IIFs(x=1, "|s") ; empty StringField

Debug ~"\n--- IIFn ---\n"

Debug    IIFn(1=0, 11, 10) ; it's Double, but…
Debug ""+IIFn(1=0, 11, 10) ; becomes Integer on a "string"
x = IIFn(1=0, %1011, $F-4-x) ; becomes type of x (Integer in this case)
Debug x
User avatar
Piero
Addict
Addict
Posts: 923
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Thanks!

Post by Piero »

Code: Select all

; Version 0.2.1

; SPECIAL THANKS to SMaag for:
; https://www.purebasic.fr/english/viewtopic.php?p=644807#p644807
; …and consequently also to Sicro for:
; https://github.com/SicroAtGit/PB-CodeArchiv-Rebirth/blob/master/PB-IDE-Tools/DisplayCCode.pb

;-CONVENIENCE IIFS:
Macro IIFn(e,t,f) ; IIFn(true?, trueNumber, falseNumber)
   priifn(Bool(e),t,f)
EndMacro
Procedure.d priifn(e,t.d,f.d) ; for IIFn: "temporary Double" for non-String types
   If e : ProcedureReturn t : EndIf : ProcedureReturn f
EndProcedure

#iifsdelim="|"
Macro IIFs(e,s,delim=#iifsdelim) ; IIFs(true?, "trueString|falseString")
   priifs(Bool(e),s,delim) ; delimiter can be multi-characters
EndMacro
Procedure.s priifs(e,s.s,d.s) ; for IIFs
   ProcedureReturn StringField(s,Bool(Not(e))+1,d)
EndProcedure

;-FOR MORE SPEED/OPTIMIZATION:
Macro IIFss(e,t,f) ; IIFss(true?, "trueString", "falseString") ; FAST
      priifss(Bool(e),@t,@f) ; PeekS(@t,-Bool(e))+PeekS(@f,-~Bool(e)&1)
EndMacro
Procedure.s priifss(e,*t,*f) ; for IIFss
   ProcedureReturn PeekS(*t,-Bool(e))+PeekS(*f,-~Bool(e)&1)
EndProcedure

Macro IIFnn(e,t,f) ; IIFnn(true?, trueNumber, falseNumber) ; FAST
   t*Bool(e)+f*Bool(~Bool(e)&1) ; Bool just in case for procedures…
EndMacro

;-FOR GENERAL USE:
Macro IIF(e,t,f) ; IIF(a=b?, x=1, s="y")
   If e : t : Else : f : EndIf
EndMacro

;-FOR DEBUG:
CompilerIf #PB_Compiler_Debugger
   Macro dq : "
   EndMacro
   Macro diifexpr(e,s,i="is") ; "non-blocking assert" (no CallDebugger)
      Debug ~"File: \""+#PB_Compiler_Filename+
         ~"\"\nLine "+ #PB_Compiler_Line + ~": \""+ dq#e#dq +~"\" "+i+" "+ IIFs(e,s)
   EndMacro
   Macro BadAssert(e,t="") ; blocking if true
      If e
         Debug ~"File: \""+#PB_Compiler_Filename+
            ~"\"\nLine "+ #PB_Compiler_Line + ~": \""+ dq#e#dq +~"\" is true! "+t
         CallDebugger
      EndIf
   EndMacro
CompilerElse
   Macro diifexpr(e,s,i=""):EndMacro
   Macro BadAssert(e,t=""):EndMacro
CompilerEndIf

;-TESTS:
DisableExplicit ; NOT enabled, because I'm BAD >:)
BadAssert(x<>0,x) ; x should be 0 (and is also integer) by default
Debug ~"--- IIFs ---\n"

x=10 : Debug "x = "+x
Debug ""+x+" Point"+ IIFs(Not(x=1), "s")
Debug ""+x+" is "+ IIFs(x&1, "Odd|Even")
diifexpr(1&#False Or x/(x-8)=5, "true|not true!")
Debug""
x=1 : Debug "x = "+x
Debug ""+x+" Point"+ IIFs(x=1, "|s") ; empty StringField
Debug ""+x+" Point"+ IIFss(x<>1, "s","")

Debug ~"\n--- IIFn ---\n"

Debug    IIFn(1=0, 11, 10) ; it's Double, but…
Debug ""+IIFn(1=0, 11, 10) ; becomes Integer on a "string" (IIFnn wouldn't work)
x = IIFn(1=0, %1011, $F-4-x) ; becomes type of x (Integer in this case)
Debug x

; End 0 ; stop here (optionally returning an exit code)…
DebugLevel 1 ; just for fun (not very appropriate for speed tests…)
Debug ~"\n--- APPROXIMATIVE SPEED TESTS: ---\n" ,1

t=1000000 ; 1 million

StartTime.q = ElapsedMilliseconds()
For k=0 to t
   x = IIFn(1=0, 1, 2)
Next
Debug "IIFn: "+str(ElapsedMilliseconds() - StartTime) ,1
StartTime.q = ElapsedMilliseconds()
For k=0 to t
   x = IIFnn(1=0, 1, 2)
Next
Debug "IIFnn: "+str(ElapsedMilliseconds() - StartTime) ,1

StartTime.q = ElapsedMilliseconds()
For k=0 to t
   s.s = IIFs(1=0, "1|2")
Next
Debug ~"\nIIFs: "+str(ElapsedMilliseconds() - StartTime) ,1
StartTime.q = ElapsedMilliseconds()
For k=0 to t
   s.s = IIFss(1=0, "1","2")
Next
Debug "IIFss: "+str(ElapsedMilliseconds() - StartTime) , 1
Post Reply