File: tmoperator8.pp

package info (click to toggle)
fpc 3.2.2%2Bdfsg-49
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 341,452 kB
  • sloc: pascal: 3,820,194; xml: 194,356; ansic: 9,637; asm: 8,482; java: 5,346; sh: 4,813; yacc: 3,956; makefile: 2,705; lex: 2,661; javascript: 2,454; sql: 929; php: 474; cpp: 145; perl: 136; sed: 132; csh: 34; tcl: 7
file content (148 lines) | stat: -rw-r--r-- 3,100 bytes parent folder | download | duplicates (5)
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
145
146
147
148
program tmoperator8;

{$MODE DELPHI}

type
  TCopyState = (csNone, csSource, csDest);
  PFoo = ^TFoo;
  TFoo = record
  private
    class operator Initialize(var aFoo: TFoo);
    class operator Finalize(var aFoo: TFoo);
    class operator AddRef(var aFoo: TFoo);
    class operator Copy(constref aSrc: TFoo; var aDst: TFoo);
  public
    CopyState: TCopyState;
    Ref: Boolean;
    F, Test: Integer;
  end;

  TFooArray = array of TFoo;

procedure TestFoo(const AValue: TFoo; AF, ATest: Integer; ARef: Boolean; ACopyState: TCopyState);
begin
  WriteLn('    AValue.F = ', AValue.F);
  if AValue.F <> AF then
    Halt(1);
  WriteLn('    AValue.Test = ', AValue.Test);
  if AValue.Test <> ATest then
    Halt(2);
  WriteLn('    AValue.Ref = ', AValue.Ref);
  if AValue.Ref <> ARef then
    Halt(4);
  WriteLn('    AValue.CopyState = ', Ord(AValue.CopyState));
  if AValue.CopyState <> ACopyState then
    Halt(3);
end;

class operator TFoo.Initialize(var aFoo: TFoo);
begin
  WriteLn('TFoo.Initialize');
  aFoo.F := 1;
  aFoo.Ref := False;
  aFoo.Test := 0;
  aFoo.CopyState := csNone;
end;

class operator TFoo.Finalize(var aFoo: TFoo);
begin
  WriteLn('TFoo.Finalize');
  if (aFoo.F <> 2) and not ((aFoo.F = 3) and aFoo.Ref) then
    Halt(5);
  aFoo.F := 4;
end;

class operator TFoo.AddRef(var aFoo: TFoo);
begin
  WriteLn('TFoo.AddRef');
  aFoo.F := 3;
  aFoo.Test := aFoo.Test + 1;
  aFoo.Ref := True;
end;

class operator TFoo.Copy(constref aSrc: TFoo; var aDst: TFoo);
var
  LSrc: PFoo;
begin
  WriteLn('TFoo.Copy');
  LSrc := @aSrc;
  LSrc.CopyState := csSource;
  aDst.CopyState := csDest;
  aDst.Test := aSrc.Test + 1;
  aDst.F := aSrc.F;
end;

procedure TestValue(Value: TFoo);
begin
  writeln('  *Test without modifier:');
  TestFoo(Value, 3, 1, True, csNone);
end;

procedure TestOut(out Value: TFoo);
begin
  WriteLn('  *Test out modifier:');
  TestFoo(Value, 1, 0, False, csNone);
  Value.F := 2;
end;

procedure TestVar(var Value: TFoo);
begin
  writeln('  *Test var modifier:');
  TestFoo(Value, 2, 0, False, csNone);
end;

procedure TestConst(const Value: TFoo);
begin
  writeln('  *Test const modifier:');
  TestFoo(Value, 2, 0, False, csNone);
end;

procedure TestConstref(constref Value: TFoo);
begin
  WriteLn('  *Test constref modifier:');
  TestFoo(Value, 2, 0, False, csNone);
end;

procedure Test;
var
  Foos: TFooArray;
  Foos2: TFooArray;
  A, B, C: TFoo;
  i: Integer;
begin
  WriteLn('*** Test for variable copy');
  TestFoo(B, 1, 0, False, csNone);
  B.F := 2;
  A := B;
  TestFoo(B, 2, 0, False, csSource);
  TestFoo(A, 2, 1, False, csDest);

  WriteLn('*** Test for Copy(dyn array)');
  SetLength(Foos, 5);
  for i := 0 to 4 do
  begin
    Foos[i].F := 2;
    Foos[i].Test := i;
  end;

  Foos2 := Copy(Foos);

  for i := 0 to 4 do
  begin
    TestFoo(Foos[i], 2, i, False, csNone);
    TestFoo(Foos2[i], 3, i + 1, True, csNone);
  end;

  WriteLn('*** Test for parameters modifiers');
  TestValue(C);
  C.F := 2; // reset F to pass finalize before out parameter
  TestOut(C);
  TestVar(C);
  TestConst(C);
  TestConstref(C);
end;

begin
  Test;
  WriteLn('end');
end.