-
Notifications
You must be signed in to change notification settings - Fork 10
/
Collections.pas
145 lines (129 loc) · 4.86 KB
/
Collections.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
...
class procedure TArray.Copy<T>(const Source: array of T; var Destination: array of T; SourceIndex, DestIndex, Count: NativeInt);
begin
CheckArrays(Pointer(@Source[0]), Pointer(@Destination[0]), SourceIndex, Length(Source), DestIndex, Length(Destination), Count);
if IsManagedType(T) then
System.CopyArray(Pointer(@Destination[DestIndex]), Pointer(@Source[SourceIndex]), TypeInfo(T), Count)
else
System.Move(Pointer(@Source[SourceIndex])^, Pointer(@Destination[DestIndex])^, Count * SizeOf(T));
end;
...
function TListHelper.GetElSize: Integer;
begin
Result := PDynArrayTypeInfo(PByte(FTypeInfo) + PDynArrayTypeInfo(FTypeInfo).name).elSize;
end;
function TListHelper.GetElType: Pointer;
begin
Result := PDynArrayTypeInfo(PByte(FTypeInfo) + PDynArrayTypeInfo(FTypeInfo).name).elType^;
end;
...
procedure TListHelper.InternalExchangeMRef(Index1, Index2: Integer; Kind: TTypeKind);
begin
case Kind of
TTypeKind.tkUString: DoExchangeString(Index1, Index2);
TTypeKind.tkInterface: DoExchangeInterface(Index1, Index2);
TTypeKind.tkVariant: DoExchangeVariant(Index1, Index2);
TTypeKind.tkDynArray: DoExchangeDynArray(Index1, Index2);
{$IF Defined(AUTOREFCOUNT)}
TTypeKind.tkClass: DoExchangeObject(Index1, Index2);
{$ENDIF}
{$IF not Defined(NEXTGEN)}
TTypeKind.tkLString: DoExchangeAnsiString(Index1, Index2);
TTypeKind.tkWString: DoExchangeWideString(Index1, Index2);
{$ENDIF}
end;
end;
...
procedure TListHelper.InternalExtractItemMRef(const Value; Kind: TTypeKind; out Item; Direction: Byte);
begin
case Kind of
TTypeKind.tkUString:
if Direction = Byte(TDirection.FromBeginning) then
DoExtractItemFwdString(Value, Item)
else
DoExtractItemRevString(Value, Item);
TTypeKind.tkInterface:
if Direction = Byte(TDirection.FromBeginning) then
DoExtractItemFwdInterface(Value, Item)
else
DoExtractItemRevInterface(Value, Item);
{$IF not Defined(NEXTGEN)}
TTypeKind.tkString:
if Direction = Byte(TDirection.FromBeginning) then
DoExtractItemFwdAnsiString(Value, Item)
else
DoExtractItemRevAnsiString(Value, Item);
TTypeKind.tkWString:
if Direction = Byte(TDirection.FromBeginning) then
DoExtractItemFwdWideString(Value, Item)
else
DoExtractItemRevWideString(Value, Item);
{$ENDIF}
{$IF Defined(AUTOREFCOUNT)}
TTypeKind.tkClass:
if Direction = Byte(TDirection.FromBeginning) then
DoExtractItemFwdObject(Value, Item)
else
DoExtractItemRevObject(Value, Item);
{$ENDIF}
end;
end;
...
procedure TListHelper.DoReverseMRef(Kind: TTypeKind);
var
b, e: Integer;
begin
b := 0;
e := FCount - 1;
while b < e do
begin
case Kind of
TTypeKind.tkUString: DoExchangeStringInline(b, e);
TTypeKind.tkInterface: DoExchangeInterfaceInline(b, e);
TTypeKind.tkDynArray: DoExchangeDynArrayInline(b, e);
TTypeKind.tkVariant: DoExchangeVariantInline(b, e);
{$IF not Defined(NEXTGEN)}
TTypeKind.tkLString: DoExchangeAnsiStringInline(b, e);
TTypeKind.tkWString: DoExchangeWideStringInline(b, e);
{$ENDIF}
{$IF Defined(AUTOREFCOUNT)}
TTypeKind.tkClass: DoExchangeObjectInline(b, e);
{$ENDIF}
end;
Inc(b);
Dec(e);
end;
end;
...
function TList<T>.InternalCompare(const Left, Right): Integer;
begin
Result := FComparer.Compare(T(Left), T(Right));
end;
procedure TList<T>.InternalNotify(const Item; Action: TCollectionNotification);
begin
Notify(T(Item), Action);
end;
function TList<T>.ItemValue(const Item: T): NativeInt;
begin
case SizeOf(T) of
1: Result := PByte(@Item)[0] shl 0;
2: Result := PByte(@Item)[0] shl 0 + PByte(@Item)[1] shl 8;
3: Result := PByte(@Item)[0] shl 0 + PByte(@Item)[1] shl 8 + PByte(@Item)[2] shl 16;
{$IF SizeOf(Pointer) <= 4}
4: Result := PByte(@Item)[0] shl 0 + PByte(@Item)[1] shl 8 + PByte(@Item)[2] shl 16 + PByte(@Item)[3] shl 24;
{$ELSE}
4: Result := PByte(@Item)[0] shl 0 + PByte(@Item)[1] shl 8 + PByte(@Item)[2] shl 16 + PByte(@Item)[3] shl 24;
5: Result := PByte(@Item)[0] shl 0 + PByte(@Item)[1] shl 8 + PByte(@Item)[2] shl 16 + PByte(@Item)[3] shl 24 +
NativeInt(PByte(@Item)[4]) shl 32;
6: Result := PByte(@Item)[0] shl 0 + PByte(@Item)[1] shl 8 + PByte(@Item)[2] shl 16 + PByte(@Item)[3] shl 24 +
NativeInt(PByte(@Item)[4]) shl 32 + NativeInt(PByte(@Item)[5]) shl 40;
7: Result := PByte(@Item)[0] shl 0 + PByte(@Item)[1] shl 8 + PByte(@Item)[2] shl 16 + PByte(@Item)[3] shl 24 +
NativeInt(PByte(@Item)[4]) shl 32 + NativeInt(PByte(@Item)[5]) shl 40 + NativeInt(PByte(@Item)[6]) shl 48;
else
Result := PByte(@Item)[0] shl 0 + PByte(@Item)[1] shl 8 + PByte(@Item)[2] shl 16 + PByte(@Item)[3] shl 24 +
NativeInt(PByte(@Item)[4]) shl 32 + NativeInt(PByte(@Item)[5]) shl 40 + NativeInt(PByte(@Item)[6]) shl 48 +
NativeInt(PByte(@Item)[7]) shl 56;
{$ENDIF}
end;
end;
...