Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2013-10

Sets as array index?

6 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Jürgen Hestermann

I have a declaration like this:

type TagType       = (tag1,tag2,tag3,tag4,tag5);
         TagSetType = set of TagType;

I now want to store numbers for each of the 2^n possible set settings [tag1,tag2,tag3,tag4,tag5]
[tag1,tag2,tag3,tag4 ]
[tag1,tag2,tag3 ,tag5]
.. and so on...

so I declared this array:

type TagSetArrayType = array[0..(1 shl (ord(High(TagSetTyp))+1))-1] of  integer;

My question:
Is it possible to retrieve the corresponding array index directly from a set variable? For example, if I have

var TagSet     : TagSetType;
var TagArray  : TagSetArrayType;
var I                 : Integer;

I want to do something like this (which is not directly possible but maybe by some other way?):

I := TagArray[TagSet];
I := TagArray[[tag1,tag5]];
or
I := TagArray[ord(TagSet)];
I := TagArray[ord([tag1,tag5])];

I think that the compiler somehow needs to generate the bit mask for [tag1,tag5] internally anyway so maybe it's available by some function to the programmer?

Reply by email

Jürgen Hestermann
to Jürgen Hestermann
Jürgen Hestermann wrote 10 lines
I want to do something like this (which is not directly possible but maybe by some other way?): I := TagArray[TagSet]; I := TagArray[[tag1,tag5]]; or I := TagArray[ord(TagSet)]; I := TagArray[ord([tag1,tag5])]; I think that the compiler somehow needs to generate the bit mask for [tag1,tag5] internally anyway so maybe it's available by some function to the programmer?

First: Why does it take 3 days until my mail arrives in the list?

Second: I already found out myself how to do what I want:

I := TagArray[byte(TagSet)];
I := TagArray[byte([tag1,tag5])];

Although, when extending the set above 8 elements
I manually need to change it to

I := TagArray[word(TagSet)];
I := TagArray[word([tag1,tag5])];

Reply by email

Sven Barth
to Jürgen Hestermann
"Jürgen Hestermann" wrote
Am 2013-10-12 14:07, schrieb Jürgen Hestermann: > I want to do something like this (which is not directly possible but

maybe by some other way?):

Show quoted text 8 lines
> > I := TagArray[TagSet]; > I := TagArray[[tag1,tag5]]; > or > I := TagArray[ord(TagSet)]; > I := TagArray[ord([tag1,tag5])]; > > I think that the compiler somehow needs to generate the bit mask for

[tag1,tag5]

> internally anyway so maybe it's available by some function to the

programmer?

First: Why does it take 3 days until my mail arrives in the list?

Problems with DNS on the mailing list server.

Regards,
Sven

Reply by email

leledumbo
to Jürgen Hestermann: I have a declaration like this: type TagType = (tag1,tag2,tag3,tag4,tag5);…
I := TagArray[TagSet];
I := TagArray[[tag1,tag5]];
or
I := TagArray[ord(TagSet)];
I := TagArray[ord([tag1,tag5])];

It's unclear what you expect from such statements. I think you better explain the high level problem, I smell a misdesign in the solution.

View this message in context: http://free-pascal-general.1045716.n5.nabble.com/Sets-as-array-index-tp5717082p5717095.html Sent from the Free Pascal - General mailing list .

Reply by email

Jürgen Hestermann
to leledumbo
leledumbo wrote
I := TagArray[ord(TagSet)]; I := TagArray[ord([tag1,tag5])]; It's unclear what you expect from such statements. I think you better explain the high level problem, I smell a misdesign in the solution.

Yes, there is always the danger of overcomplicating things. But I think in this case it makes sense.

I have a file manager that logs whole directory branches. Files can have attributes like "Tagged" or "matching filter mask". There can be even more attributes like multiple tag sets or whatever:

type FlagType     = (Tagged,FileMaskMatch);
      FlagSetType  = set of FlagTyp;

I now want to store the number of files and the bytes for each directory branch. All possible set combination need to be considered because I may show all files that:

are tagged = [Tagged]
match a filter mask = [FileMaskMatch] are tagged AND match a filter mask = [Tagged,FileMaskMatch] all files = []

This makes 4 possible combinations but for a 3rd attribute I already have 8 and yet another doubles it to 16.

For each of these possible sets I want to store:

FileSumtype  = record
                Number : Cardinal;
                Bytes  : QWord;
                end; // of record

with

type BranchSumType = array[0..(1 shl (ord(High(FlagSetTyp))+1))-1] of FileSumType; // 0..2^n-1

I can now use a set variable

var FlagSet : FlagSetType;

to store what I want to display and use this variable for indexing the array

var BranchSum : BranchSumType;

when storing file information I can store them for all set combinations:

BranchSum[byte([                    ])].Number := ...;
BranchSum[byte([                    ])].Byte   := ...;
BranchSum[byte([       FileMaskMatch])].Number := ...;
BranchSum[byte([       FileMaskMatch])].Byte   := ...;
BranchSum[byte([Tagged              ])].Number := ...;
BranchSum[byte([Tagged              ])].Byte   := ...;
BranchSum[byte([Tagged,FileMaskMatch])].Number := ...;
BranchSum[byte([Tagged,FileMaskMatch])].Byte   := ...;

This is convenient as I need to use procedures to propagate these numbers up in the tree, but not always all of them (because not all of them change when I only change the filter mask).

So I can use a FileSet variable as parameter for a procedure and index the array with it:

procedure PropagateUp(const F : FileSetType; const Values : FileSumType);
begin
..
BranchSum[byte(F)] := Values[byte(F)];
..
end;

So far this works fine and is quite fast.

Reply by email