1-- C392008.A
2--
3--                             Grant of Unlimited Rights
4--
5--     Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
6--     F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
7--     unlimited rights in the software and documentation contained herein.
8--     Unlimited rights are defined in DFAR 252.227-7013(a)(19).  By making
9--     this public release, the Government intends to confer upon all
10--     recipients unlimited rights  equal to those held by the Government.
11--     These rights include rights to use, duplicate, release or disclose the
12--     released technical data and computer software in whole or in part, in
13--     any manner and for any purpose whatsoever, and to have or permit others
14--     to do so.
15--
16--                                    DISCLAIMER
17--
18--     ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
19--     DISCLOSED ARE AS IS.  THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
20--     WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
21--     SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
22--     OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
23--     PARTICULAR PURPOSE OF SAID MATERIAL.
24--*
25--
26-- OBJECTIVE:
27--      Check that the use of a class-wide formal parameter allows for the
28--      proper dispatching of objects to the appropriate implementation of
29--      a primitive operation.  Check this for the case where the root tagged
30--      type is defined in a package and the extended type is defined in a
31--      dependent package.
32--
33-- TEST DESCRIPTION:
34--      Declare a root tagged type, and some associated primitive operations,
35--      in a visible library package.
36--      Extend the root type in another visible library package, and override
37--      one or more primitive operations, inheriting the other primitive
38--      operations from the root type.
39--      Derive from the extended type in yet another visible library package,
40--      again overriding some primitive operations and inheriting others
41--      (including some that the parent inherited).
42--      Define subprograms with class-wide parameters, inside of which is a
43--      call on a dispatching primitive operation.  These primitive
44--      operations modify the objects of the specific class passed as actuals
45--      to the class-wide formal parameter (class-wide formal parameter has
46--      mode IN OUT).
47--
48-- The following hierarchy of tagged types and primitive operations is
49-- utilized in this test:
50--
51--   package Bank
52--      type Account (root)
53--            |
54--            | Operations
55--            |     proc Deposit
56--            |     proc Withdrawal
57--            |     func Balance
58--            |     proc Service_Charge
59--            |     proc Add_Interest
60--            |     proc Open
61--            |
62--   package Checking
63--      type Account (extended from Bank.Account)
64--            |
65--            | Operations
66--            |     proc Deposit         (inherited)
67--            |     proc Withdrawal      (inherited)
68--            |     func Balance         (inherited)
69--            |     proc Service_Charge  (inherited)
70--            |     proc Add_Interest    (inherited)
71--            |     proc Open            (overridden)
72--            |
73--   package Interest_Checking
74--      type Account (extended from Checking.Account)
75--            |
76--            | Operations
77--            |     proc Deposit         (inherited twice - Bank.Acct.)
78--            |     proc Withdrawal      (inherited twice - Bank.Acct.)
79--            |     func Balance         (inherited twice - Bank.Acct.)
80--            |     proc Service_Charge  (inherited twice - Bank.Acct.)
81--            |     proc Add_Interest    (overridden)
82--            |     proc Open            (overridden)
83--            |
84--
85-- In this test, we are concerned with the following selection of dispatching
86-- calls, accomplished with the use of a Bank.Account'Class IN OUT formal
87-- parameter :
88--
89--                \ Type
90--        Prim. Op \  Bank.Account  Checking.Account Interest_Checking.Account
91--                  \---------------------------------------------------------
92
93--   Service_Charge |      X                X                 X
94--   Add_Interest   |      X                X                 X
95--   Open           |      X                X                 X
96--
97--
98--
99-- The location of the declaration of the root and derivation of extended
100-- types will be varied over a series of tests.  Locations of declaration
101-- and derivation for a particular test are marked with an asterisk (*).
102--
103-- Root type:
104--
105--    *  Declared in package.
106--       Declared in generic package.
107--
108-- Extended types:
109--
110--       Derived in parent location.
111--       Derived in a nested package.
112--       Derived in a nested subprogram.
113--       Derived in a nested generic package.
114--    *  Derived in a separate package.
115--       Derived in a separate visible child package.
116--       Derived in a separate private child package.
117--
118-- Primitive Operations:
119--
120--    *  Procedures with same parameter profile.
121--       Procedures with different parameter profile.
122--       Functions with same parameter profile.
123--       Functions with different parameter profile.
124--       Mixture of Procedures and Functions.
125--
126--
127-- TEST FILES:
128--      This test depends on the following foundation code:
129--
130--         C392008_0.A
131--
132--
133-- CHANGE HISTORY:
134--      06 Dec 94   SAIC    ACVC 2.0
135--      20 Nov 95   SAIC    C392B04 became C392008 for ACVC 2.0.1
136--
137--!
138
139----------------------------------------------------------------- C392008_0
140
141package C392008_0 is           -- package Bank
142
143  type Dollar_Amount is range -30_000..30_000;
144
145   type Account is tagged
146      record
147        Current_Balance: Dollar_Amount;
148      end record;
149
150   -- Primitive operations.
151
152   procedure Deposit        (A : in out Account;
153                             X : in     Dollar_Amount);
154   procedure Withdrawal     (A : in out Account;
155                             X : in     Dollar_Amount);
156   function  Balance        (A : in     Account) return Dollar_Amount;
157   procedure Service_Charge (A : in out Account);
158   procedure Add_Interest   (A : in out Account);
159   procedure Open           (A : in out Account);
160
161end C392008_0;
162
163-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
164
165package body C392008_0 is
166
167   -- Primitive operations for type Account.
168
169   procedure Deposit (A : in out Account;
170                      X : in     Dollar_Amount) is
171   begin
172      A.Current_Balance := A.Current_Balance + X;
173   end Deposit;
174
175   procedure Withdrawal(A : in out Account;
176                        X : in     Dollar_Amount) is
177   begin
178      A.Current_Balance := A.Current_Balance - X;
179   end Withdrawal;
180
181   function  Balance (A : in     Account) return Dollar_Amount is
182   begin
183      return (A.Current_Balance);
184   end Balance;
185
186   procedure Service_Charge (A : in out Account) is
187   begin
188      A.Current_Balance := A.Current_Balance - 5_00;
189   end Service_Charge;
190
191   procedure Add_Interest (A : in out Account) is
192      Interest_On_Account : Dollar_Amount := 0_00;
193   begin
194      A.Current_Balance := A.Current_Balance + Interest_On_Account;
195   end Add_Interest;
196
197   procedure Open (A : in out Account) is
198      Initial_Deposit : Dollar_Amount := 10_00;
199   begin
200      A.Current_Balance := Initial_Deposit;
201   end Open;
202
203end C392008_0;
204
205----------------------------------------------------------------- C392008_1
206
207with C392008_0;              -- package Bank
208
209package C392008_1 is      -- package Checking
210
211   package Bank renames C392008_0;
212
213   type Account is new Bank.Account with
214      record
215         Overdraft_Fee : Bank.Dollar_Amount;
216      end record;
217
218   -- Overridden primitive operation.
219
220   procedure Open (A : in out Account);
221
222   -- Inherited primitive operations.
223   -- procedure Deposit        (A : in out Account;
224   --                           X : in     Bank.Dollar_Amount);
225   -- procedure Withdrawal     (A : in out Account;
226   --                           X : in     Bank.Dollar_Amount);
227   -- function  Balance        (A : in     Account) return Bank.Dollar_Amount;
228   -- procedure Service_Charge (A : in out Account);
229   -- procedure Add_Interest   (A : in out Account);
230
231end C392008_1;
232
233-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
234
235package body C392008_1 is
236
237   -- Overridden primitive operation.
238
239   procedure Open (A : in out Account) is
240      Check_Guarantee : Bank.Dollar_Amount := 10_00;
241      Initial_Deposit : Bank.Dollar_Amount := 20_00;
242   begin
243      A.Current_Balance := Initial_Deposit;
244      A.Overdraft_Fee   := Check_Guarantee;
245   end Open;
246
247end C392008_1;
248
249----------------------------------------------------------------- C392008_2
250
251with C392008_0;             -- with Bank;
252with C392008_1;          -- with Checking;
253
254package C392008_2 is     -- package Interest_Checking
255
256   package Bank     renames C392008_0;
257   package Checking renames C392008_1;
258
259   subtype Interest_Rate is Bank.Dollar_Amount range 0..100; -- was digits 4;
260
261   Current_Rate : Interest_Rate := 0_02;
262
263   type Account is new Checking.Account with
264      record
265         Rate : Interest_Rate;
266      end record;
267
268   -- Overridden primitive operations.
269
270   procedure Add_Interest (A : in out Account);
271   procedure Open         (A : in out Account);
272
273   -- "Twice" inherited primitive operations (from Bank.Account)
274   -- procedure Deposit        (A : in out Account;
275   --                           X : in     Bank.Dollar_Amount);
276   -- procedure Withdrawal     (A : in out Account;
277   --                           X : in     Bank.Dollar_Amount);
278   -- function  Balance        (A : in     Account) return Bank.Dollar_Amount;
279   -- procedure Service_Charge (A : in out Account);
280
281end C392008_2;
282
283-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
284
285package body C392008_2 is
286
287   -- Overridden primitive operations.
288
289   procedure Add_Interest (A : in out Account) is
290      Interest_On_Account : Bank.Dollar_Amount
291        := Bank.Dollar_Amount( Bank."*"( A.Current_Balance, A.Rate ));
292   begin
293      A.Current_Balance := Bank."+"( A.Current_Balance, Interest_On_Account);
294   end Add_Interest;
295
296   procedure Open (A : in out Account) is
297      Initial_Deposit : Bank.Dollar_Amount := 30_00;
298   begin
299      Checking.Open (Checking.Account (A));
300      A.Current_Balance := Initial_Deposit;
301      A.Rate            := Current_Rate;
302   end Open;
303
304end C392008_2;
305
306------------------------------------------------------------------- C392008
307
308with C392008_0;    use C392008_0;          -- package Bank
309with C392008_1;    use C392008_1;        -- package Checking;
310with C392008_2;    use C392008_2;        -- package Interest_Checking;
311with Report;
312
313procedure C392008 is
314
315   package Bank              renames C392008_0;
316   package Checking          renames C392008_1;
317   package Interest_Checking renames C392008_2;
318
319   B_Acct  : Bank.Account;
320   C_Acct  : Checking.Account;
321   IC_Acct : Interest_Checking.Account;
322
323   --
324   -- Define procedures with class-wide formal parameters of mode IN OUT.
325   --
326
327   -- This procedure will perform a dispatching call on the
328   -- overridden primitive operation Open.
329
330   procedure New_Account (Acct : in out Bank.Account'Class) is
331   begin
332      Open (Acct);  -- Dispatch according to tag of class-wide parameter.
333   end New_Account;
334
335   -- This procedure will perform a dispatching call on the inherited
336   -- primitive operation (for all types derived from the root Bank.Account)
337   -- Service_Charge.
338
339   procedure Apply_Service_Charge (Acct: in out Bank.Account'Class) is
340   begin
341      Service_Charge (Acct);  -- Dispatch according to tag of class-wide parm.
342   end Apply_Service_Charge;
343
344   -- This procedure will perform a dispatching call on the
345   -- inherited/overridden primitive operation Add_Interest.
346
347   procedure Annual_Interest (Acct: in out Bank.Account'Class) is
348   begin
349      Add_Interest (Acct);  -- Dispatch according to tag of class-wide parm.
350   end Annual_Interest;
351
352begin
353
354   Report.Test ("C392008",  "Check that the use of a class-wide formal "    &
355                            "parameter allows for the proper dispatching "  &
356                            "of objects to the appropriate implementation " &
357                            "of a primitive operation");
358
359   -- Check the dispatch to primitive operations overridden for each
360   -- extended type.
361   New_Account (B_Acct);
362   New_Account (C_Acct);
363   New_Account (IC_Acct);
364
365   if (B_Acct.Current_Balance  /= 10_00) or
366      (C_Acct.Current_Balance  /= 20_00) or
367      (IC_Acct.Current_Balance /= 30_00)
368   then
369      Report.Failed ("Failed dispatch to multiply overridden prim. oper.");
370   end if;
371
372
373   Annual_Interest (B_Acct);
374   Annual_Interest (C_Acct);
375   Annual_Interest (IC_Acct); -- Check the dispatch to primitive operation
376                              -- overridden from a parent type which inherited
377                              -- the operation from the root type.
378   if (B_Acct.Current_Balance  /= 10_00) or
379      (C_Acct.Current_Balance  /= 20_00) or
380      (IC_Acct.Current_Balance /= 90_00)
381   then
382      Report.Failed ("Failed dispatch to overridden primitive operation");
383   end if;
384
385
386   Apply_Service_Charge (Acct => B_Acct);
387   Apply_Service_Charge (Acct => C_Acct);
388   Apply_Service_Charge (Acct => IC_Acct); -- Check the dispatch to a
389                                           -- primitive operation twice
390                                           -- inherited from the root
391                                           -- tagged type.
392   if (B_Acct.Current_Balance  /=  5_00) or
393      (C_Acct.Current_Balance  /= 15_00) or
394      (IC_Acct.Current_Balance /= 85_00)
395   then
396      Report.Failed ("Failed dispatch to Apply_Service_Charge");
397   end if;
398
399   Report.Result;
400
401end C392008;
402