AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Größe von SETs festlegen

Ein Thema von himitsu · begonnen am 6. Mai 2008 · letzter Beitrag vom 9. Mär 2024
Antwort Antwort
Seite 2 von 3     12 3      
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#11

Re: Größe von SETs festlegen

  Alt 6. Mai 2008, 11:57
Wenn z.B. das SET nur 1 Byte groß ist, aber die WinAPI-Funktion ein SET in Integergröße erwartet, dann sind die höheren 3 Byte unbestimmt
und da Delphi diese 3 Byte nicht setzt, erhält am Ende der Parameter, welcher an die WinAPI übergeben wurde 24 Bits mit unvorhersagbaren Werten


hmmm, sowas hatte ich doch früher schonmal gamacht ...
Delphi-Quellcode:
Type
  LOCKTYPE = Type _INT; // nicht wundern ... _INT entspricht [msdn:8a2af38416]INT[/msdn:8a2af38416]
                         // es gab aber Probleme mit der Delphi-Funktion Int
Const
  // LOCKTYPE values
  LOCK_WRITE = LOCKTYPE(1);
  LOCK_EXCLUSIVE = LOCKTYPE(2);
  LOCK_ONLYONCE = LOCKTYPE(4);
nur gab es da ein paar kleine Probleme ... vorallem da wo in einem Parameter verschiedene Typen gemischt werden können.
z.B. FILE_ATTRIBUTE_* und FILE_FLAG_*



nja, was mir grad noch aufgefallen ist, als SET würde man die Konstanten ja auch nichtmehr MSDN/C-typisch per "or" ( "|" ) verknüpfen können
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von nicodex
nicodex

Registriert seit: 2. Jan 2008
Ort: Darmstadt
286 Beiträge
 
Delphi 2007 Professional
 
#12

Re: Größe von SETs festlegen

  Alt 6. Mai 2008, 12:12
Zitat von himitsu:
nur gab es da ein paar kleine Probleme ... vorallem da wo in einem Parameter verschiedene Typen gemischt werden können.
z.B. FILE_ATTRIBUTE_* und FILE_FLAG_*
Das liegt an der Definition eines neuen, "nicht kompatiblen" Typs (= type Basistyp).

Zitat von himitsu:
als SET würde man die Konstanten ja auch nichtmehr MSDN/C-typisch per "and" ( "|" ) verknüpfen können
Du meinst "or"
Jupp, dann könnte/müsste man nur noch die Sets verwenden (was man in diversen Fällen nicht möchte, da diese in Delphi streng typisiert sind - oder weil es sich gar nicht über ein Set abbilden lässt).
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#13

Re: Größe von SETs festlegen

  Alt 6. Mai 2008, 12:24
Ups "or"

dann geht's halt nicht anders,
aber was solls ... nja, manchmal ist die strenge Typisierung auch garnicht sooo schlecht
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#14

AW: Größe von SETs festlegen

  Alt 3. Mär 2024, 01:30
Bloß mal zur Rücksicherung.

Es gibt hierfür immernoch keine wirkliche Lösung, für ein {$MINSETSIZE}, oder hab ich's nur übersehn?


Ich Schreib grade mal ein paar Sachen mir zusammen, um bald das neue Quality-Portal mit Millionen Bugreports in die Knie zu zwingen ... je länger sie brauchen, um so schlimmer wird es.
Und auf der Suche über meinen eigenen uralten Thread gestolpert ... echt mal, bald 20 Jahre, aber immernoch nichts.

Ich würde ja auch nochmal im Quality suchen (bin der Meinung dort gab es schon was), aber QC ist tot/gelöscht und das Quality ist seit Gestern auch mal wieder garnicht erreichbar/einloggbar.


Benötige mal wieder ein SET mit zwei Werten, welches aber dennoch Integer groß ist.
Das geht sehr einfach, mit dummy=31 am Ende, aber dann ist ja sowas wie SetToString im Arsch.
$2B or not $2B

Geändert von himitsu ( 3. Mär 2024 um 01:34 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#15

AW: Größe von SETs festlegen

  Alt 3. Mär 2024, 10:10
Delphi-Quellcode:
type
  TEnum = (one, two);
  TEnums = set of TEnum;

type
  TWindowsEnums = record
    class operator Implicit(A: TEnums): TWindowsEnums; overload;
  case Integer of
    0: (Enums: TEnums);
    1: (Fake: set of 0..31);
  end;

class operator TWindowsEnums.Implicit(A: TEnums): TWindowsEnums;
begin
  Result.Fake := [];
  Result.Enums := A;
end;

procedure MyWindowsProc(Par: TWindowsEnums);
begin
  Write('TWindowsEnums: ');
  var sep := '(';
  for var enum in Par.Fake do begin
    Write(sep, enum);
    sep := ',';
  end;
  Writeln(')');
end;

procedure Test;
var
  Enums: TEnums;
begin
  Writeln('Sizeof(TEnum)=', Sizeof(TEnum));
  Writeln('Sizeof(TWindowsEnums)=', Sizeof(TWindowsEnums));
  Enums := [one, two];
  MyWindowsProc(Enums);
end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#16

AW: Größe von SETs festlegen

  Alt 3. Mär 2024, 14:43
Maaa, es wäre jetzt zu einfach gewesen.
Delphi-Quellcode:
type
  TWindowsSet<T> = record
    class operator Implicit(A: T): TWindowsSet<T>;
  case Integer of
    0: (TheSet: T);
    1: (Aligned: Integer);
  end;
Aber neeeeeeeeee.




Code:
type
  TMyEnum = (one, two);
  TMySet = set of TMyEnum;

  TMyRecord = record
    Field: Integer;
  end;

  TMyManagedRec = record
    Field: string;
  end;

  TMyRecordCon = record
    //constructor Create; // [dcc32 Fehler] E2394 Parameterlose Konstruktoren sind für Record-Typen nicht zulässig
    constructor Create(i: Integer);
  end;

  TMyClass = class
    constructor Create;
  end;

  TMyProcedure = procedure;
  TMyMethod   = procedure of object;
  TMyReference = reference to procedure;

  TWithConstructor<T: constructor> = record
  end;

  TWithClass<T: class> = record
  end;

  TWithRecord<T: record> = record
  end;

  //TTheRecord = TWithConstructor<TMyRecord>;     // [dcc32 Fehler] E2513 Typparameter 'T' muss parameterlosen Konstruktor haben
  //TTheRecord2 = TWithConstructor<TMyRecordCon>;  // [dcc32 Fehler] E2513 Typparameter 'T' muss parameterlosen Konstruktor haben
  TTheConClass = TWithConstructor<TObject>;       // äähhhhhm, eigentlich hat TMyRecordC Einen, sber mit Klassen geht es
  TTheClass    = TWithClass<TObject>;             // class = constructor, aber hier wenigstens eindeutg
  TTheRecord   = TWithRecord<TMyRecord>;          // jupp
  TTheManaged  = TWithRecord<TMyManagedRec>;      // jupp
  //TTheSet    = TWithRecord<TMySet>;             // [dcc32 Fehler] E2512 Typparameter 'T' muss ein nicht-nullable Wertetyp sein
  TTheEnum     = TWithRecord<TMyEnum>;            //
  TTheBoolean  = TWithRecord<Boolean>;            //
  TTheInteger  = TWithRecord<Integer>;            //
  //TTheStatic = TWithRecord<IntegerArray>;       // [dcc32 Fehler] E2512 Typparameter 'T' muss ein nicht-nullable Wertetyp sein : ein Integer geht, aber Viele nicht?
  //TThePointer = TWithRecord<Pointer>;            // [dcc32 Fehler] E2512 Typparameter 'T' muss ein nicht-nullable Wertetyp sein : Pointer und Integer sind doch das "Gleiche" ?
  //TTheShort  = TWithRecord<ShortString>;        // [dcc32 Fehler] E2512 Typparameter 'T' muss ein nicht-nullable Wertetyp sein : ein Record, bzw. statisches Array und ist doch das Gleiche, wie ein ShortString
  //TTheString = TWithRecord<String>;             // [dcc32 Fehler] E2512 Typparameter 'T' muss ein nicht-nullable Wertetyp sein : OK, das ist ein Managed-Type
  //TTheArray  = TWithRecord<TBytes>;             // [dcc32 Fehler] E2512 Typparameter 'T' muss ein nicht-nullable Wertetyp sein : OK, Managed wie beim String

  //TTheProc   = TWithRecord<TMyProcedure>;       // [dcc32 Fehler] E2512 Typparameter 'T' muss ein nicht-nullable Wertetyp sein : eigentlich wie ein Pointer/Integer
  //TTheMethod = TWithRecord<TMyMethod>;          // [dcc32 Fehler] E2512 Typparameter 'T' muss ein nicht-nullable Wertetyp sein : wie ein Pointer, außer wenn ARC aktiv (eventuell managed)
  //TTheRef    = TWithRecord<TMyReference>;       // [dcc32 Fehler] E2512 Typparameter 'T' muss ein nicht-nullable Wertetyp sein : das ist ein Interface (immer managed)

  {
  TWindowsSet<T> = record
    class operator Implicit(A: T): TWindowsSet<T>;
  case Integer of
    0: (TheSet: T); // [dcc32 Fehler] E2569 Typparameter 'T' benötigt evtl. Finalisierung - im varianten Record nicht zulässig. Verwenden Sie die RECORD-Einschränkung
    1: (Aligned: Integer);
  end;
  }

  TWindowsSet<T: record> = record
    class operator Implicit(A: T): TWindowsSet<T>;
  case Integer of
    0: (TheSet: T);
    1: (Aligned: Integer);
  end;

  TEnum4  = TWindowsSet<TEnum>;  // kompiliert, aber ist eigentlich falsch
  //TSet4 = TWindowsSet<TSet>;   // [dcc32 Fehler] E2512 Typparameter 'T' muss ein nicht-nullable Wertetyp sein

  //TWindowsEnumSet<T:ordinal> = record                       // [dcc32 Fehler] Unit2.pas(47): E2003 Undeklarierter Bezeichner: 'ordinal'
  TWindowsEnumSet<T: record> = record
    type TSet = set of T;                                     // [dcc32 Fehler] E2001 Ordinaltyp erforderlich
    class operator Implicit(A: set of T): TWindowsEnumSet<T>; // [dcc32 Fehler] E2029 Bezeichner erwartet, aber 'SET' gefunden
    class operator Implicit(A: TSet): TWindowsEnumSet<T>;     // geht nicht, da das TSet fehlt
  case Integer of
    0: (TheSet: TSet);
    1: (Aligned: Integer);
  end;

https://docwiki.embarcadero.com/RADS...isierte_Typen)
Code:
<T>                            keine Einschränkung
<T, T2>                        keine Einschränkung
<T: IInterface; T2>            Interace welches Dieses implementieren muß
<T: IInterface,IIntf,...; T2>  Interace welches Diese implementieren muß
<T: TObject; T2>               Klasse oder Nachfahr
<T: constructor; T2>           muß einen Konstrutor enthalten, also Klassen (keine Records, obwohl Die auch Einen haben können)
<T: class; T2>                 nur Klassen
<T: record; T2>                nur records und "einfache" Typen
also im Prinzip fehlt ja Vieles
"ordinal", wo wirklich nur ordinale Typen rein passen
"simple" für einfache Typen (keine Records, inkl. noneManaged)
"noneManaged", wo keine LongStrings, Variants, Interfaces und dynamische Arrays rein dürfen, sowie keine CustomManagedRecords und ARC, und ebenso keine Records/StaticArrays, wo sowas drin ist
"array", nja, halt bloß Arrays
"array,managed", bloß dynamische Arrays
"array,noneManaged", bloß statische Arrays
"array,****" ... ähhhh ja, statische Arrays, welche aber Managed-Zeugs enthalten dürfen?
OK, dann halt "array", "staticArray" und "dynamicArray" (mit anderem kombinierbar, für die Felder)
$2B or not $2B

Geändert von himitsu ( 3. Mär 2024 um 14:45 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#17

AW: Größe von SETs festlegen

  Alt 3. Mär 2024, 15:01
Maaa, es wäre jetzt zu einfach gewesen.
Na ja, deine Anforderung war ja aber auch lediglich:
Benötige mal wieder ein SET mit zwei Werten, welches aber dennoch Integer groß ist.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#18

AW: Größe von SETs festlegen

  Alt 3. Mär 2024, 15:11
Wäre aber auch zu einfach, wenn es das SET selbst könnte.
$2B or not $2B
  Mit Zitat antworten Zitat
Dennis07

Registriert seit: 19. Sep 2011
Ort: Deutschland
488 Beiträge
 
Delphi 11 Alexandria
 
#19

AW: Größe von SETs festlegen

  Alt 8. Mär 2024, 17:43
Habe dazu vor Jahren mal einen Typen erstellt und veröffentlicht. So, wie ich das sehe, ist es wohl noch immer die beste implementierung, die es öffentlich gibt:

https://github.com/Manhunter07/CustomSets

Delphi-Quellcode:
uses Sets;

type TLargeNumber: 100000 .. 109999;
var Numbers: TSet<TLargeNumber>

begin
  Numbers := [100572, 100285];
end
Dennis

Geändert von Dennis07 ( 8. Mär 2024 um 17:49 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#20

AW: Größe von SETs festlegen

  Alt 8. Mär 2024, 18:35
Das hilft hier nur leider absolut nichts, da es eben kein SET ist ... da sind die Daten intern in einem Pointer (ByteArray) versteckt.
Somit leider inkompatibel und nicht verwendbar, um eine bestehende API von C++ (Windows) nach Delphi zu portieren.

Mit einen überladen Record ginge es, womöglich noch mit impliziten Casts, aber da es generisch nicht funktioniert, müsste man jeden einzelnen Typen das neu deklarieren/implementieren, was einen Albtraum an Code ergäbt,
obwohl ja einfach nur sowas wie {$MinEnumSize} fehlt, bloß halt auch für Sets.
$2B or not $2B

Geändert von himitsu ( 8. Mär 2024 um 18:38 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:48 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz