How to set the value of an enum type?
Asked Answered
W

3

5

I have the following:

TDirection = (dirNorth, dirEast, dirSouth, dirWest);
TDirections = set of TDirection;

In a seperate class I have it declared as a property:

property Directions: TDirections read FDirections write FDirections;

What I want is to be able to treat them as if they were Booleans, so for example if dirNorth was True then it would be 1, if False it would be 0.

I am trying to imagine it as (1,0,0,0)

I think to check if a direction is True, I could use:

var
  IsTrue: Boolean;
begin
  IsTrue := (DirNorth in Directions);

Not sure if the above is correct or not, but then my other problem is how to change one of the directions to True or False?

I have now reached one of my confusion states :(

This is the last thing I tried to set the value but I am getting Illegal Expression (in Lazarus).

Directions(TDirection(DirNorth)) := True;
Wilmer answered 12/9, 2013 at 19:50 Comment(4)
Include(Directions, dirNorth); ?Daegal
and conversely, Exclude(Directions, dirNorth); to remove it again.Conterminous
Read the documentation for setsThistle
As Gerry Coll wrote in his comment of the answer bellow, include/exclude expect a set as var argument, hence you cannot pass a property.Gauguin
O
16

Directions is a set of elements of type TDirection.

To see if it contains dirNorth, do dirNorth in Directions. The result of using the in operator is a boolean; dirNorth in Directions is true iff the set Directions contains the element dirNorth.

To make sure dirNorth is included in Directions, do Directions := Directions + [dirNorth].

To make sure dirNorth is not included in Directions, do Directions := Directions - [dirNorth].

To set Directions to a particular value, simply assign: Directions := [dirNorth, dirSouth].

Formally, + computes the union of two sets; - computes the set difference of two sets. * computes the intersection of the two operands.

You also have the nice Include and Exclude functions: Include(Directions, dirNorth) does the same thing as Directions := Directions + [dirNorth]; Exclude(Directions, dirNorth) does the same thing as Directions := Directions - [dirNorth].

For example, if

type
  TAnimal = (aDog, aCat, aRat, aRabbit);
  TAnimalSet = set of TAnimal;
const
  MyAnimals = [aDog, aRat, aRabbit];
  YourAnimals = [aDog, aCat];

then

aDog in MyAnimals = true;
aCat in MyAnimals = false;
aRat in YourAnimals = false;
aCat in YourAnimals = true;

MyAnimals + YourAnimals = [aDog, aRat, aRabbit, aCat];
MyAnimals - YourAnimals = [aRat, aRabbit];
MyAnimals * YourAnimals = [aDog];

Implicit in my answer is the fact that the Delphi set type is modelled after the mathematical set. For more information about the Delphi set type, please refer to the official documentation.

Organography answered 12/9, 2013 at 19:54 Comment(2)
Note that you can't use Include and Exclude on properties - it will give a [DCC Error] XXXX.pas(200): E2064 Left side cannot be assigned to error, you have to use PropName + [element(s)Mathematical
This is all very helpful, but the first sentence should be "It's not possible to set the state of a set element directly without if/else" - because that was the question. This is really a missing feature, I think. As far as I understand it, the only improvement is writing a helper function, but it won't work with properties, just like Include/Exclude.Bridoon
B
1

You may add an item to a set by doing like this:

Include(Directions, dirNorth);

To remove it from the set:

Exclude(Diretions, dirNorth);

The help states that the result is the same as using the plus operator, but the code is more efficient.

Bidden answered 12/9, 2013 at 20:1 Comment(1)
As Gerry Coll wrote in his comment of the answer above, include/exclude expect a set as var argument, hence you cannot pass a property.Gauguin
B
0

Based on this helper, which doesn't work for properties, I created this one (requires XE6) - it can be used for variables and properties:

TGridOptionsHelper = record helper for TGridOptions
public
  ///  <summary>Sets a set element based on a Boolean value</summary>
  ///  <example>
  ///    with MyGrid do Options:= Options.SetOption(goEditing, False);
  ///    MyVariable.SetOption(goEditing, True);
  ///  </example>
  function SetOption(GridOption: TGridOption; const Value: Boolean): TGridOptions;
end;

function TGridOptionsHelper.SetOption(
  GridOption: TGridOption; const Value: Boolean): TGridOptions;
begin
  if Value then Include(Self, GridOption) else Exclude(Self, GridOption);
  Result:= Self;
end;
Bridoon answered 9/5, 2018 at 12:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.