comp.lang.ada
 help / color / mirror / Atom feed
* Both Ada.Finalization.Limited_Controlled and Ada.Finalization.Controlled
@ 2014-07-25 18:09 Victor Porton
  2014-07-25 19:25 ` Victor Porton
  2014-07-25 19:52 ` Dmitry A. Kazakov
  0 siblings, 2 replies; 3+ messages in thread
From: Victor Porton @ 2014-07-25 18:09 UTC (permalink / raw)


I have implemented the following package to wrap pointers to C records:

with Ada.Finalization;

generic
   type Record_Type; -- It should be an untagged record for C compatibility
package RDF.Auxilary.Handled_Record is

   type Access_Type is access Record_Type
      with Convention=>C;

   -- It is logically abstract, but not exactly abstract in Ada sense.
   -- It can't be abstract because the function From_Handle returns this type.
   type Base_Object is new Ada.Finalization.Limited_Controlled with private;

   overriding procedure Initialize(Object: in out Base_Object);

   overriding procedure Finalize(Object: in out Base_Object);

   not overriding function Get_Handle(Object: Base_Object) return Access_Type with Inline;

   not overriding function From_Handle(Handle: Access_Type) return Base_Object with Inline;

   not overriding function Default_Handle(Object: Base_Object) return Access_Type;

   not overriding procedure Finalize_Handle(Object: Base_Object; Handle: Access_Type) is null;

private

   type Base_Object is new Ada.Finalization.Limited_Controlled with
      record
         Handle: Access_Type;
      end record;

end RDF.Auxilary.Handled_Record;

I think you guess what the body is, but if you don't look into
https://github.com/vporton/redland-bindings/blob/ada2012/ada/src/rdf-auxilary-handled_record.ads
https://github.com/vporton/redland-bindings/blob/ada2012/ada/src/rdf-auxilary-handled_record.adb

Now I want to create a similar generic package with

type Base_Object is new Ada.Finalization.Controlled with private;

and a function to create a copy handle:

function Copy(Handle: Access_Type) return Access_Type is null;

and

procedure Adjust(Object : in out Base_Object) is
begin
   if Object.Handle /= null
      Object.Handle = Copy (Object.Handle);
   end if;
end;

My question: Is it possible to implement without duplicating code for both
Ada.Finalization.Limited_Controlled and Ada.Finalization.Controlled?

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Both Ada.Finalization.Limited_Controlled and Ada.Finalization.Controlled
  2014-07-25 18:09 Both Ada.Finalization.Limited_Controlled and Ada.Finalization.Controlled Victor Porton
@ 2014-07-25 19:25 ` Victor Porton
  2014-07-25 19:52 ` Dmitry A. Kazakov
  1 sibling, 0 replies; 3+ messages in thread
From: Victor Porton @ 2014-07-25 19:25 UTC (permalink / raw)


Victor Porton wrote:

> I have implemented the following package to wrap pointers to C records:
> 
> with Ada.Finalization;
> 
> generic
>    type Record_Type; -- It should be an untagged record for C
>    compatibility
> package RDF.Auxilary.Handled_Record is
> 
>    type Access_Type is access Record_Type
>       with Convention=>C;
> 
>    -- It is logically abstract, but not exactly abstract in Ada sense.
>    -- It can't be abstract because the function From_Handle returns this
>    type. type Base_Object is new Ada.Finalization.Limited_Controlled with
>    private;
> 
>    overriding procedure Initialize(Object: in out Base_Object);
> 
>    overriding procedure Finalize(Object: in out Base_Object);
> 
>    not overriding function Get_Handle(Object: Base_Object) return
>    Access_Type with Inline;
> 
>    not overriding function From_Handle(Handle: Access_Type) return
>    Base_Object with Inline;
> 
>    not overriding function Default_Handle(Object: Base_Object) return
>    Access_Type;
> 
>    not overriding procedure Finalize_Handle(Object: Base_Object; Handle:
>    Access_Type) is null;
> 
> private
> 
>    type Base_Object is new Ada.Finalization.Limited_Controlled with
>       record
>          Handle: Access_Type;
>       end record;
> 
> end RDF.Auxilary.Handled_Record;
> 
> I think you guess what the body is, but if you don't look into
> https://github.com/vporton/redland-bindings/blob/ada2012/ada/src/rdf-auxilary-handled_record.ads
> https://github.com/vporton/redland-bindings/blob/ada2012/ada/src/rdf-auxilary-handled_record.adb
> 
> Now I want to create a similar generic package with
> 
> type Base_Object is new Ada.Finalization.Controlled with private;
> 
> and a function to create a copy handle:
> 
> function Copy(Handle: Access_Type) return Access_Type is null;
> 
> and
> 
> procedure Adjust(Object : in out Base_Object) is
> begin
>    if Object.Handle /= null
>       Object.Handle = Copy (Object.Handle);
>    end if;
> end;
> 
> My question: Is it possible to implement without duplicating code for both
> Ada.Finalization.Limited_Controlled and Ada.Finalization.Controlled?

Oh, I thought one of .Finalization.Limited_Controlled and 
Ada.Finalization.Controlled is a child of another.

This is not the case, so the code should be duplicated (not a big problem in 
practice, however).

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Both Ada.Finalization.Limited_Controlled and Ada.Finalization.Controlled
  2014-07-25 18:09 Both Ada.Finalization.Limited_Controlled and Ada.Finalization.Controlled Victor Porton
  2014-07-25 19:25 ` Victor Porton
@ 2014-07-25 19:52 ` Dmitry A. Kazakov
  1 sibling, 0 replies; 3+ messages in thread
From: Dmitry A. Kazakov @ 2014-07-25 19:52 UTC (permalink / raw)


On Fri, 25 Jul 2014 21:09 +0300, Victor Porton wrote:

> I have implemented the following package to wrap pointers to C records:

[...]

I don't understand the idea. There are two major cases of this:

1. You get some proxy object to the thing you have no control of. That is
the case with file handles, system resource handles, various IDs returned
from a library, void * stuff etc. These things are in general references to
something outside. Since you have no control of this you cannot copy it
[*]. The natural holder object for this is Limited_Controlled with Finalize
releasing the resource.

2. You are responsible for allocation of the structure, e.g. a text string
or a buffer passed to the library as a parameter. You simply place this
thing into a container, maybe as an aliased component, maybe not, because C
convention would pass most arguments by reference anyway. In this case it
could be Controlled, but there is little sense to copy it anyway. So
Limited_Controlled is OK here.

On top of this you may have Controlled handles to the Limited_Controller
wrappers. This is when you want to copy handles. Which is not a deep copy,
but creating another handle pointing to the same wrapper. For this you will
need some reference counting schema. There exists plenty ready to use
implementations in Ada (as generic packages). You could use them or take as
an inspiration.

-------------------
* Very rarely you indeed could copy, e.g. Windows' DuplicateHandle. But
that has no sense to do because it is still reference semantics. So you
could copy your handle as well, much easier and much more efficiently.

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

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2014-07-25 19:52 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-25 18:09 Both Ada.Finalization.Limited_Controlled and Ada.Finalization.Controlled Victor Porton
2014-07-25 19:25 ` Victor Porton
2014-07-25 19:52 ` Dmitry A. Kazakov

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