Forum > General
Question about set implementations
(1/1)
dkettle:
Is there a package or library that implements sets of arbitrary data types (not just the built-in integer types)? I want to declare a set of records, something like this:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---MyRecordType = Record ... End; MySet = SomePkg.Set of MyRecordType;
If not, I'll just use an array and make sure that each element is unique. But it will save me time if something already exists.
Thanks.
jamie:
No, sets are more for compiler help to make your code readable , they can be stored because they do use space in memory of course but they won't do as you wish..
You can have an array of Tobjects as the base if you wish, in which case you need to create them but for that you could use a TLIST that already handles that..
You can also do the same using the OBJECT model and base it from a known type for the array, but it still needs to be dynamically created for it to work since you stated each element is going to be different..
But something tells me you are over complicating things.
You could have a Set field within each record too.
P.S
Look into using a Variant CASE within a record, that way they are all the same but can be used differently
PascalDragon:
--- Quote from: dkettle on June 06, 2021, 05:52:11 pm ---Is there a package or library that implements sets of arbitrary data types (not just the built-in integer types)? I want to declare a set of records, something like this:
--- End quote ---
You can use one of the generic types from Generics.Collections:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---type // alternatives are THashSet<>, TSortedSet<> or TSortedHashSet<> // in mode Delphi you need to remove the "specialize" MySet = specialize THashSet<MyRecordType>;
You then need to use the methods of the set class (all provided by the parent class TCustomSet<>) to add or remove elements.
marcov:
If you want a value type bitset that is also possible, but then you need to define the range of possibilities before using.
I distilled the below code from earlier posts on this forum:
--- Code: --- program bigvalueset;
{$mode objfpc}{$modeswitch advancedrecords}
type
generic TBigValueSet<T> = record
private
const
LOWER = Low(T);
UPPER = High(T) - LOWER;
SET_LEN = (Upper shr 5 + Ord(Upper and 31 <> 0)) + Ord(UPPER = 0);
type
TDWordBits = 0..31;
TDWordSet = set of TDWordBits;
PDWordSet = ^TDWordSet;
TSet = array[0..Pred(SET_LEN)] of DWord;
var
FSet: TSet;
class operator Initialize(var s: TBigValueSet);
public
procedure Include(aValue: T);
procedure Exclude(aValue: T);
class operator +(constref L, R: TBigValueSet): TBigValueSet;
class operator -(constref L, R: TBigValueSet): TBigValueSet;
class operator *(constref L, R: TBigValueSet): TBigValueSet;
class operator ><(constref L, R: TBigValueSet): TBigValueSet;
class operator =(constref L, R: TBigValueSet): Boolean;
class operator <=(constref L, R: TBigValueSet): Boolean;
class operator in (aValue: T; const aSet: TBigValueSet): Boolean;
end;
class operator TBigValueSet.Initialize(var s: TBigValueSet);
begin
s.FSet := Default(TSet);
end;
procedure TBigValueSet.Include(aValue: T);
begin
System.Include(PDWordSet(@FSet[(Integer(aValue) - LOWER) shr 5])^, (Integer(aValue) - LOWER) and 31);
end;
procedure TBigValueSet.Exclude(aValue: T);
begin
System.Exclude(PDWordSet(@FSet[(Integer(aValue) - LOWER) shr 5])^, (Integer(aValue) - LOWER) and 31);
end;
class operator TBigValueSet.+(constref L, R: TBigValueSet): TBigValueSet;
var
I: Integer;
begin
for I := 0 to Pred(SET_LEN) do
Result.FSet[I] := L.FSet[I] or R.FSet[I];
end;
class operator TBigValueSet.-(constref L, R: TBigValueSet): TBigValueSet;
var
I: Integer;
begin
for I := 0 to Pred(SET_LEN) do
Result.FSet[I] := L.FSet[I] and not R.FSet[I];
end;
class operator TBigValueSet.*(constref L, R: TBigValueSet): TBigValueSet;
var
I: Integer;
begin
for I := 0 to Pred(SET_LEN) do
Result.FSet[I] := L.FSet[I] and R.FSet[I];
end;
class operator TBigValueSet.><(constref L, R: TBigValueSet): TBigValueSet;
var
I: Integer;
begin
for I := 0 to Pred(SET_LEN) do
Result.FSet[I] := L.FSet[I] xor R.FSet[I];
end;
class operator TBigValueSet.=(constref L, R: TBigValueSet): Boolean; inline;
var
I: Integer;
begin
for I := 0 to Pred(SET_LEN) do
if L.FSet[I] <> R.FSet[I] then
exit(False);
Result := True;
end;
class operator TBigValueSet.<=(constref L, R: TBigValueSet): Boolean; inline;
var
I: Integer;
begin
for I := 0 to Pred(SET_LEN) do
if R.FSet[I] <> L.FSet[I] or R.FSet[I] then
exit(False);
Result := True;
end;
class operator TBigValueSet.in (aValue: T; const aSet: TBigValueSet): Boolean;
begin
Result := TDWordBits((Integer(aValue) - LOWER) and 31) in PDWordSet(@aSet.FSet[(Integer(aValue) - LOWER) shr 5])^;
end;
type
TMyRange = -1022..1023;
var
s, s2: specialize TBigValueSet<TMyRange>;
begin
WriteLn('SizeOf(s) = ', SizeOf(s));
s.Include(-5);
WriteLn('-5 in s = ', -5 in s);
s.Include(1022);
WriteLn('1022 in s = ', 1022 in s);
s2.Include(-15);
s2.Include(-900);
s2 := s2 + s;
WriteLn('-5 in s2 = ', -5 in s2);
WriteLn('-15 in s2 = ', -15 in s2);
WriteLn('-900 in s2 = ', -900 in s2);
WriteLn('1022 in s2 = ', 1022 in s2);
s2 := s2 - s2;
WriteLn('-5 in s2 = ', -5 in s2);
WriteLn('-15 in s2 = ', -15 in s2);
WriteLn('-900 in s2 = ', -900 in s2);
WriteLn('1022 in s2 = ', 1022 in s2);
end.
--- End code ---
dkettle:
--- Quote from: PascalDragon on June 07, 2021, 09:05:41 am ---
--- Quote from: dkettle on June 06, 2021, 05:52:11 pm ---Is there a package or library that implements sets of arbitrary data types (not just the built-in integer types)? I want to declare a set of records, something like this:
--- End quote ---
You can use one of the generic types from Generics.Collections:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---type // alternatives are THashSet<>, TSortedSet<> or TSortedHashSet<> // in mode Delphi you need to remove the "specialize" MySet = specialize THashSet<MyRecordType>;
You then need to use the methods of the set class (all provided by the parent class TCustomSet<>) to add or remove elements.
--- End quote ---
Thanks! I'll give it a try.
Navigation
[0] Message Index