E.4.2 Example of Use of a Remote Access-to-Class-Wide Type
Examples
Example of using 
a remote access-to-class-wide type to achieve dynamic binding across 
active partitions: 
package Tapes is
   pragma Pure(Tapes);
   type Tape is abstract tagged limited private;
   -- Primitive dispatching operations where
   -- Tape is controlling operand
   procedure Copy (From, To : access Tape; Num_Recs : in Natural) is abstract;
   procedure Rewind (T : access Tape) is abstract;
   -- More operations
private
   type Tape is ...
end Tapes;
with Tapes;
package Name_Server is
   pragma Remote_Call_Interface;
   -- Dynamic binding to remote operations is achieved
   -- using the access-to-limited-class-wide type Tape_Ptr
   type Tape_Ptr is access all Tapes.Tape'Class;
   -- The following statically bound remote operations
   -- allow for a name-server capability in this example
   function  Find     (Name : String) return Tape_Ptr;
   procedure Register (Name : in String; T : in Tape_Ptr);
   procedure Remove   (T : in Tape_Ptr);
   -- More operations
end Name_Server;
package Tape_Driver is
  -- Declarations are not shown, they are irrelevant here
end Tape_Driver;
with Tapes, Name_Server;
package body Tape_Driver is
   type New_Tape is new Tapes.Tape with ...
   procedure Copy
    (From, To : access New_Tape; Num_Recs: in Natural) is
   begin
     . . .
   end Copy;
   procedure Rewind (T : access New_Tape) is
   begin
      . . .
   end Rewind;
   -- Objects remotely accessible through use
   -- of Name_Server operations
   Tape1, Tape2 : aliased New_Tape;
begin
   Name_Server.Register ("NINE-TRACK",  Tape1'Access);
   Name_Server.Register ("SEVEN-TRACK", Tape2'Access);
end Tape_Driver;
with Tapes, Name_Server;
-- Tape_Driver is not needed and thus not mentioned in the with_clause
procedure Tape_Client 
is
   T1, T2 : Name_Server.Tape_Ptr;
begin
   T1 := Name_Server.Find ("NINE-TRACK");
   T2 := Name_Server.Find ("SEVEN-TRACK");
   Tapes.Rewind (T1);
   Tapes.Rewind (T2);
   Tapes.Copy (T1, T2, 3);
end Tape_Client;
 
Notes on the example: 
This paragraph was 
deleted.
The package Tapes provides the necessary declarations 
of the type and its primitive operations.
Name_Server is a remote call interface package 
and is elaborated in a separate active partition to provide the necessary 
naming services (such as Register and Find) to the entire distributed 
program through remote subprogram calls.
Tape_Driver is a normal package that is elaborated 
in a partition configured on the processing node that is connected to 
the tape device(s). The abstract operations are overridden to support 
the locally declared tape devices (Tape1, Tape2). The package is not 
visible to its clients, but it exports the tape devices (as remote objects) 
through the services of the Name_Server. This allows for tape devices 
to be dynamically added, removed or replaced without requiring the modification 
of the clients' code.
The Tape_Client procedure references only declarations 
in the Tapes and Name_Server packages. Before using a tape for the first 
time, it needs to query the Name_Server for a system-wide identity for 
that tape. From then on, it can use that identity to access the tape 
device.
Values of remote access type Tape_Ptr include the 
necessary information to complete the remote dispatching operations that 
result from dereferencing the controlling operands T1 and T2.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe