Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi XE2: How to use sets of integers with ordinal values > 255

All I want to do is to define a set of integers that may have values above 255, but I'm not seeing any good options. For instance:

with MyObject do Visible := Tag in [100, 155, 200..225, 240]; // Works just fine

but

with MyObject do Visible := Tag in [100, 201..212, 314, 820, 7006]; // Compiler error

I've gotten by with (often lengthy) conditional statements such as:

with MyObject do Visible := (Tag in [100, 202..212]) or (Tag = 314) or (Tag = 820) or (Tag = 7006);

but that seems ridiculous, and this is just a hard-coded example. What if I want to write a procedure and pass a set of integers whose values may be above 255? There HAS to be a better, more concise way of doing this.

like image 648
George DeLaMater Avatar asked Oct 15 '22 22:10

George DeLaMater


1 Answers

The base type of a Delphi set must be an ordinal type with at most 256 distinct values. Under the hood, such a variable has one bit for each possible value, so a variable of type set of Byte has size 256 bits = 32 bytes.

Suppose it were possible to create a variable of type set of Integer. There would be 232 = 4294967296 distinct integer values, so this variable must have 4294967296 bits. Hence, it would be of size 512 MB. That's a HUGE variable. Maybe you can put such a value on the stack in 100 years.

Consequently, if you truly need to work with (mathematical) sets of integers, you need a custom data structure; the built-in set types won't do. For instance, you could implement it as an advanced record. Then you can even overload the in operator to make it look like a true Pascal set!

Implementing such a slow and inefficient type is trivial, and that might be good enough for small sets. Implementing a general-purpose integer set data structure with efficient operations (membership test, subset tests, intersection, union, etc.) is more work. There might be third-party code available on the WWW (but StackOverflow is not the place for library recommendations).

If your needs are more modest, you can use a simple array of integers instead (TArray<Integer>). Maybe you don't need O(1) membership tests, subset tests, intersections, and unions?

like image 126
Andreas Rejbrand Avatar answered Oct 18 '22 13:10

Andreas Rejbrand