comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Comparing Access Types
Date: Thu, 9 Nov 2017 09:33:49 +0100
Date: 2017-11-09T09:33:49+01:00	[thread overview]
Message-ID: <ou13tc$2de$1@gioia.aioe.org> (raw)
In-Reply-To: b3976d73-296f-4958-bfb2-26bf49901a48@googlegroups.com

On 09/11/2017 06:37, Jere wrote:
> I have a package which uses a type to wrap an access type.  I thought it
> might be nice to provide the basic comparison functions, "=", "<", ">", etc.
> but access types can only be compared using "=" and "/=".  I figured that
> way, my types could be used in some sort of sorted container, like a map.
> 
> I want to keep the incomplete type for other reasons, so that seems to limit
> my options.
> 
> 1.  Address_To_Access_Conversions is out (cannot use an incomplete type)
> 2.  I cannot simply do var.all'Address (Again, incomplete type)

Of course you can.

> Is there some way to do this within the Ada standard or am I hamstrung
> due to the incomplete type specification?
> 
> Also, why weren't <, >, <=, >= provided for access types.  Even if the
> representation of an Access type is implementation defined, surely
> those operators could have been defined.

No, in general case it cannot, in the spirit of the semantics that A < B 
if the physical machine address of A < B. Actually even equality cannot 
be for segmented memory but it felt good enough.

> A toned down example:
> 
> generic
>     type Item_Type(<>);
>     type Item_Access is access Item_Type;
> package My_Package is
> 
>     type Some_Type is record
>        Reference : Item_Access := null;
>     end record;
> 
>     function "<" (Left,Right : Some_Type) return Boolean;
> 
> end My_Package;
> 
> package body My_Package is
> 
> function "<" (Left,Right : Some_Type) return Boolean is
> begin
>     return Left.Reference < Right.Reference;  --fails to compile
> end "<";

You have two options:

1. Compare addresses, e.g.

with System; use System;

function "<" (Left,Right : Some_Type) return Boolean is
begin
    return (  Right.Reference /= null
           and then
              (  Left.Reference = null
              or else
                 Left.Reference.all'Address < Right.Reference.all'Address
           )  );
end "<";

2. A better way is to use the native object's order:

generic
    type Item_Type(<>);
    type Item_Access is access Item_Type;
    with function "=" (Left, Right : Item_Type) return Boolean is <>;
    with function "<" (Left, Right : Item_Type) return Boolean is <>;
package My_Package is

function "<" (Left,Right : Some_Type) return Boolean is
begin
    return (  Right.Reference /= null
           and then
              (  Left.Reference = null
              or else
                 Left.Reference.all < Right.Reference.all
           )  );
end "<";

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

  parent reply	other threads:[~2017-11-09  8:33 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-09  5:37 Comparing Access Types Jere
2017-11-09  8:29 ` Simon Wright
2017-11-09  8:33 ` Dmitry A. Kazakov [this message]
2017-11-09 22:38   ` Robert A Duff
2017-11-10  8:35     ` Dmitry A. Kazakov
2017-11-10 15:11       ` Jere
2017-11-10 16:05       ` Robert A Duff
2017-11-10 16:30         ` Robert A Duff
2017-11-16  1:17           ` Randy Brukardt
2017-11-18 22:01             ` Robert A Duff
2017-11-20 22:25               ` Randy Brukardt
2017-11-21  0:30                 ` Shark8
2017-11-21  8:57                   ` Dmitry A. Kazakov
2017-11-22  1:01                     ` Randy Brukardt
2017-11-10 15:20     ` Jere
2017-11-10 16:00       ` Robert A Duff
2017-11-10 16:22         ` Jere
2017-11-10 15:06   ` Jere
2017-11-16  1:21     ` Randy Brukardt
2017-11-16  1:13 ` Randy Brukardt
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox