Enumeration mit 2er-Potenzen

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Enumeration mit 2er-Potenzen

Beitrag von RSBasic »

@c4s
Du brauchst z.B. PB 5.20, damit es funktioniert.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
c4s
Beiträge: 1235
Registriert: 19.09.2007 22:18

Re: Enumeration mit 2er-Potenzen

Beitrag von c4s »

@RSBasic
Ja, habe ich auch gerade festgestellt (siehe Edit). Bei Demivec stand aber "für 5.11"... ;)
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: Enumeration mit 2er-Potenzen

Beitrag von CSHW89 »

Ja 5.11 war leider genau die Version, in der beides nicht funktioniert hatte. Die erste nicht, weil Vergleiche nur noch mit Bool funktionierten, und die zweite nicht, weil Bool(const = const) nicht zur Compilezeit berechnet wurde, sondern erst zur Laufzeit. Somit war Bool(const = const) für den Compiler keine Konstante, und konnte deshalb auch nicht einer Konstanten zugewiesen werden.

Aber Fred hat zum Glück mein Wunsch zur 5.20 umgesetzt :D

lg Kevin
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Benutzeravatar
Regenduft
Beiträge: 574
Registriert: 25.03.2008 15:07
Wohnort: THE LÄÄÄND!

Re: Enumeration mit 2er-Potenzen

Beitrag von Regenduft »

Schöne Lösung! Ich hatte das nur mit CompilerIf hinbekommen, was allerdings den Vorteil hat, dass man sich die 1 beim Enumeration sparen kann (bzw. muss).

Code: Alles auswählen

Macro EnumFlag(Konstante)
  CompilerIf #PB_Compiler_EnumerationValue > 0 : Konstante = (#PB_Compiler_EnumerationValue-1)<<1 : CompilerElse : Konstante = 1 : CompilerEndIf
EndMacro

Enumeration
  EnumFlag(#a)
  EnumFlag(#b)
  EnumFlag(#c)
  EnumFlag(#d)
EndEnumeration

Debug #a
Debug #b
Debug #c
Debug #d
CSHW89 hat geschrieben:Aber Fred hat zum Glück mein Wunsch zur 5.20 umgesetzt :D
Was? Gibt's das jetzt nativ? Wo? Wie? Ich finde nichts... Bin ich wieder zu blind oder zu blöd zum Suchen (oder beides)? :?
PureBasic 5.73 LTE x86/x64 | Windows 7 (x64)
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: Enumeration mit 2er-Potenzen

Beitrag von CSHW89 »

Regenduft hat geschrieben:CSHW89 hat geschrieben:
Aber Fred hat zum Glück mein Wunsch zur 5.20 umgesetzt :D
Was? Gibt's das jetzt nativ? Wo? Wie? Ich finde nichts... Bin ich wieder zu blind oder zu blöd zum Suchen (oder beides)? :?
Es ging um das Auswerten von Bool() zur Compilezeit. Soetwas hatte vor 5.20 nicht funktioniert:

Code: Alles auswählen

#const = Bool(#c1 = #c2)
Ich benutze halt diese Variante, die in der Zeit zwischen PB 5.10 und PB 5.20 nicht funktionierte:

Code: Alles auswählen

Macro enum2pow(_const_)
  _const_ = (Bool(#PB_Compiler_EnumerationValue=1) + Bool(#PB_Compiler_EnumerationValue>1) * ((#PB_Compiler_EnumerationValue-1)<<1))
EndMacro
Mir war vor allem wichtig, dass die Zeilen zwischen Enumerate/EndEnumerate gleich aussehen. Das man also für die erste Konstante keine andere Form wählen muss.

Aber das mit dem CompileIf ist natürlich auch ne gute Idee. Hätte ich mal vorher drauf kommen sollen :D

lg Kevin
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Benutzeravatar
Regenduft
Beiträge: 574
Registriert: 25.03.2008 15:07
Wohnort: THE LÄÄÄND!

Re: Enumeration mit 2er-Potenzen

Beitrag von Regenduft »

Achso, dann hatte ich das falsch verstanden.

Bei meiner ersten Lösung hatte ich mir auch total das Hirn zermartert! Am Ende, als ich die einfachere Lösung fand, sah das so einfach aus, dass ich mich gar nicht getraut hatte es zu posten.

Es folgt mein erster Versuch... total umständlich... aber es funktioniert... halbwegs... :lol:
Zwischen "DoFlagging" dürfen keine Leerzeilen stehen. Ist ein gutes Beispiel, dass man nicht krampfhaft an einem Lösungsansatz festhalten sollte! Ich hatte da vermutlich mehr Zeit hinein gesteckt wie in alle manuellen "Flaggereien" zusammen. Ist wirklich ziemlich alt... Es darf gelacht werden!

Code: Alles auswählen

;{ Flagging-Makros
  Macro FlaggingQuote
    "
  EndMacro
  Macro StartFlagging(EnumerationName, Bytes = 0)
    CompilerIf Defined(StartFlagging_#EnumerationName, #PB_Constant)
      CompilerError "Flagging-Name bereits vergeben: "+FlaggingQuote#EnumerationName#FlaggingQuote
    CompilerEndIf
    CompilerIf Bytes > 0
      #FlagBytes_#EnumerationName = Bytes
      #FlagBytes_#EnumerationName$ = FlaggingQuote#Bytes#FlaggingQuote
    CompilerEndIf
    #StartFlagging_#EnumerationName = #PB_Compiler_Line + 1
  EndMacro
  Macro DoFlagging(EnumerationName, FlagName)
    CompilerIf Defined(StartFlagging_#EnumerationName, #PB_Constant) = 0
      CompilerError "StartFlagging fehlt: "+FlaggingQuote#EnumerationName#FlaggingQuote
    CompilerEndIf
    CompilerIf Defined(StopFlagging_#EnumerationName, #PB_Constant)
      CompilerError "Flagging bereits gestoppt: "+FlaggingQuote#EnumerationName#FlaggingQuote
    CompilerEndIf
    CompilerIf Defined(Flag_#EnumerationName#_#FlagName, #PB_Constant)
      CompilerError "Flag existiert bereits: "+FlaggingQuote#EnumerationName#FlaggingQuote
    CompilerEndIf
    ;===============================================================================================
    #Flag_#EnumerationName#_#FlagName = 1 << ( #PB_Compiler_Line - #StartFlagging_#EnumerationName )
    ;===============================================================================================
    CompilerIf Defined(FlagBytes_#EnumerationName, #PB_Constant)
      CompilerIf #Flag_#EnumerationName#_#FlagName > 1 << ( #FlagBytes_#EnumerationName << 3 - 1)
        CompilerError "Flagging auf "+#FlagBytes_#EnumerationName$+" Byte begrenzt"
      CompilerEndIf
    CompilerEndIf
  EndMacro
  Macro StopFlagging(EnumerationName)
    CompilerIf Defined(StartFlagging_#EnumerationName, #PB_Constant) = 0
      CompilerError "StartFlagging fehlt: "+FlaggingQuote#EnumerationName#FlaggingQuote
    CompilerEndIf
    CompilerIf #StartFlagging_#EnumerationName = #PB_Compiler_Line
      CompilerError "leerer Flagging-Block: "+FlaggingQuote#EnumerationName#FlaggingQuote
    CompilerEndIf
    CompilerIf Defined(StopFlagging_#EnumerationName, #PB_Constant)
      CompilerError "Flagging bereits gestoppt: "+FlaggingQuote#EnumerationName#FlaggingQuote
    CompilerEndIf
    #StopFlagging_#EnumerationName = #PB_Compiler_Line - #StartFlagging_#EnumerationName
  EndMacro
;} Ende Flagging-Makros

StartFlagging(Foo)
  DoFlagging(Foo, a)
  DoFlagging(Foo, b)
  DoFlagging(Foo, c)
  DoFlagging(Foo, d)
StopFlagging(Foo)

Debug #Flag_Foo_a
Debug #Flag_Foo_b
Debug #Flag_Foo_c
Debug #Flag_Foo_d
PureBasic 5.73 LTE x86/x64 | Windows 7 (x64)
Antworten