Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

set of WideChar: Sets may have at most 256 elements

I have this line:

const
  MY_SET: set of WideChar = [WideChar('A')..WideChar('Z')];

The above does not compile, with error:

[Error] Sets may have at most 256 elements

But this line does compile ok:

var WS: WideString;
if WS[1] in [WideChar('A')..WideChar('Z')] then...

And this also compiles ok:

const
  MY_SET = [WideChar('A')..WideChar('Z'), WideChar('a')..WideChar('z')];
  ...
  if WS[1] in MY_SET then...

Why is that?

EDIT: My question is why if WS[1] in [WideChar('A')..WideChar('Z')] compiles? and why MY_SET = [WideChar('A')..WideChar('Z'), WideChar('a')..WideChar('z')]; compiles? aren't they also need to apply to the set rules?

like image 767
zig Avatar asked Jun 21 '16 05:06

zig


2 Answers

A valid set has to obey two rules:

  1. Each element in a set must have an ordinal value less than 256.
  2. The set must not have more than 256 elements.
MY_SET: set of WideChar = [WideChar('A')..WideChar('Z')];

Here you declare a set type (Set of WideChar) which has more than 256 elements -> Compiler error.

if WS[1] in [WideChar('A')..WideChar('Z')]

Here, the compiler sees WideChar('A') as an ordinal value. This value and all other values in the set are below 256. This is ok with rule 1.

The number of unique elements are also within limits (Ord('Z')-Ord('A')+1), so the 2nd rules passes.

MY_SET = [WideChar('A')..WideChar('Z'), WideChar('a')..WideChar('z')];

Here you declare a set that also fulfills the requirements as above. Note that the compiler sees this as a set of ordinal values, not as a set of WideChar.

like image 123
LU RD Avatar answered Nov 05 '22 20:11

LU RD


A set can have no more than 256 elements.
Even with so few elements the set already uses 32 bytes.

From the documentation:

A set is a bit array where each bit indicates whether an element is in the set or not. The maximum number of elements in a set is 256, so a set never occupies more than 32 bytes. The number of bytes occupied by a particular set is equal to

(Max div 8) - (Min div 8) + 1

For this reason only sets of byte, (ansi)char, boolean and enumerations with fewer than 257 elements are possible.
Because widechar uses 2 bytes it can have 65536 possible values.
A set of widechar would take up 8Kb, too large to be practical.

type
  Capitals = 'A'..'Z';

const
  MY_SET: set of Capitals = [WideChar('A')..WideChar('Z')];

Will compile and work the same.

It does seem a bit silly to use widechar if your code ignores unicode.
As written only the English capitals are recognized, you do not take into account different locales.

In this case it would be better to use code like

if (AWideChar >= 'A') and (AWideChar <= 'Z') ....

That will work no matter how many chars fall in between.
Obviously you can encapsulate this in a function to save on typing.

If you insist on having large sets, see this answer: https://stackoverflow.com/a/2281327/650492

like image 2
Johan Avatar answered Nov 05 '22 19:11

Johan