Sign in Join
Wiki copytemporary

Revision 1 of 1, by Kirinn on 7-16-2022. The page as it is now.

Set

Back to data types.

Back to Reserved words.

Introduction

A Set encodes many values from an enumeration into an Ordinal type.

For example let's consider this enumeration:

pascal
  TSpeed = (spVerySlow,spSlow,spAverage,spFast,spVeryFast);

And this set:

pascal
  TPossibleSpeeds = set of TSpeed

Constant instances of TPossibleSpeeds can be defined using brackets to hold set elements:

pascal
  const
    RatherSlow = [spVerySlow,spSlow];
    RatherFast = [spFast,spVeryFast];

RatherSlow and RatherFast are some Set of TSpeed.

Manipulating sets

You can assign a set's contents directly:

pascal
  var
    SomeSpeeds: TPossibleSpeeds = [spAverage];
  begin
    SomeSpeeds := [spSlow,spVerySlow];
  end;

Two functions defined in the RTL System unit are used to manipulate set elements individually: Include(ASet,AValue) and Exclude(ASet,AValue).

pascal
  var
    SomeSpeeds: TPossibleSpeeds;
  begin
    SomeSpeeds := [];
    Include(SomeSpeeds,spVerySlow);
    Include(SomeSpeeds,spVeryFast);
  end;

Sets cannot be directly manipulated if they are published. You usually have to make a local copy, change the local copy and then to call the setter.

pascal
  procedure TSomething.DoSomething(Sender: TFarObject);
  var
    LocalCopy: TPossibleSpeeds;
  begin
    LocalCopy := Sender.PossibleSpeeds; // getter to local
    Include(LocalCopy,spVerySlow);
    Sender.PossibleSpeeds := LocalCopy; // local to setter.
  end;

The reserved word in is also used to test if a value is in a set. It's usually used in this fashion:

pascal
  var
    CanBeSlow: Boolean;
  const
    SomeSpeeds = [Low(TSpeed)..High(TSpeed)];
  begin
    CanBeSlow := (spVerySlow in SomeSpeeds) or (spSlow in SomeSpeeds);
  end;

Empty square brackets represent an empty set. You can test if a set currently contains no values at all by comparing against an empty set:

pascal
  var
    SomeSpeeds: TPossibleSpeeds;
  begin
    if SomeSpeeds = [] then SomeSpeeds := [spAverage];
  end;

Bitmasks

Sets can be used to create bitmasks as shown in the example.

pascal
(*
  The set [FLAG_A, FLAG_C] will be stored like this:
  
  TFlags :   0000'0101
                   │││
  FLAG_C ──────────┘││
  FLAG_B ───────────┘│
  FLAG_A ────────────┘
*)

type
  TFlag = (FLAG_A, FLAG_B, FLAG_C);
  TFlags = set of TFlag;

var
  Flags: TFlags;

[..]
  Flags:= [FLAG_A, FLAG_C];
  if FLAG_A in Flags then ..  // check FLAG_A is set in flags variable

From the Free Pascal wiki, page "Set", as it stood on 2022-07-16 after a change by Kirinn, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.