From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,a3736685ef876ab2 X-Google-Attributes: gid103376,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news2.google.com!newsfeed.stanford.edu!sn-xt-sjc-02!sn-xt-sjc-08!sn-post-sjc-01!supernews.com!corp.supernews.com!not-for-mail From: Matthew Heaney Newsgroups: comp.lang.ada Subject: Re: OO Style with Ada Containers Date: Wed, 21 Nov 2007 04:51:23 +0000 Organization: Posted via Supernews, http://www.supernews.com Message-ID: References: <1195082906.420079.195000@d55g2000hsg.googlegroups.com> <1s27rv0gt4ujj$.3e2k326rp54d.dlg@40tude.net> <60e46dc9-d8ca-4f47-9e8a-f90a7d45e752@w28g2000hsf.googlegroups.com> <0319d921-4457-4b47-87f2-3f310aaa3d93@o6g2000hsd.googlegroups.com> <5076f153-d879-43dd-b2c8-ad61eeea241d@d61g2000hsa.googlegroups.com> <4182086a-2968-4c42-b08a-1a30b05fcf63@c29g2000hsa.googlegroups.com> <400347d7-aa93-4175-a3dc-e415ad0d9ca3@i29g2000prf.googlegroups.com> User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1 (windows-nt) Cancel-Lock: sha1:LM+VvvxE9Z33Zw15FXPzpZ4T094= MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Complaints-To: abuse@supernews.com Xref: g2news1.google.com comp.lang.ada:18545 Date: 2007-11-21T04:51:23+00:00 List-Id: Maciej Sobczak writes: > You cannot do arithmetics with cursors. They don't have appropriate > operators and the examples you shown work with indices, not with > cursors. Cursors themselves can be only incremented and decremented. Actually, I thought about this more and concluded it doesn't matter that much. C++ requires a uniform interface to allow the instantiation to happen, because of the way it binds operations (by name). But in Ada you can build a type adapter on-the-fly (that's the locally declared subprogram stuff, which you must often do anyway), and furthermore the actual name can differ from the formal. So not having cursor-based arithmetic isn't such a great loss, since you can always instantiate the algorithm using the index subtype instead of using the cursor (as I showed earlier, to pass an array to a generic algorithm). Here's the first method using a package that synthesizes cursor-based arithmetic operators: procedure Op (V : Vector) is package Cursor_Ops is new Vector_Cursor_Operations (Integer_Vectors, V'Access); use Cursor_Ops; procedure Sort is new Generic_Sort (Cursor_Type => Cursor, Element_Type => Integer, Index_Type => Positive); M : Cursor := V.First + (No_Element - V.First) / 2; begin Sort (V.First, M); Sort (M, No_Element); end Op; Here's the second method that uses the index subtype to instantiate the generic sort algorithm: procedure Op2 (V : Vector) is function Element (I : Index_Type'Base) return Integer is begin return V.Element (I); end; procedure Sort is new Generic_Sort (Cursor_Type => Integer'Base, -- or possibly Extended_Index Element_Type => Integer, Index_Type => Positive); M : Extended_Index := V.First_Index + Count_Type'Pos (V.Length / 2); begin Sort (V.First_Index, M); Sort (M, V.First_Index + Count_Type'Pos (V.Length)); end Op2; It's not that much different. If you feel strongly that vector cursors should support some kind of arithmetic, then you might want to post a message to the ada-comment list so that the request gets logged, and eventually put on the ARG agenda. Cheers, Matt --STX with Ada.Containers.Vectors; use Ada.Containers; package Test_Vector_Operations is pragma Preelaborate; package Integer_Vectors is new Vectors (Positive, Integer); use Integer_Vectors; procedure Op (V : Vector); procedure Op2 (V : Vector); end Test_Vector_Operations; with Vector_Cursor_Operations; with Generic_Sort; package body Test_Vector_Operations is procedure Op (V : Vector) is package Cursor_Ops is new Vector_Cursor_Operations (Integer_Vectors, V'Access); use Cursor_Ops; procedure Sort is new Generic_Sort (Cursor_Type => Cursor, Element_Type => Integer, Index_Type => Positive); M : Cursor := V.First + (No_Element - V.First) / 2; begin Sort (V.First, M); Sort (M, No_Element); end Op; procedure Op2 (V : Vector) is function Element (I : Index_Type'Base) return Integer is begin return V.Element (I); end; procedure Sort is new Generic_Sort (Cursor_Type => Integer'Base, Element_Type => Integer, Index_Type => Positive); M : Extended_Index := V.First_Index + Count_Type'Pos (V.Length / 2); begin Sort (V.First_Index, M); Sort (M, V.First_Index + Count_Type'Pos (V.Length)); end Op2; end Test_Vector_Operations; generic type Cursor_Type is private; type Element_Type is private; type Index_Type is (<>); with function Element (C : Cursor_Type) return Element_Type is <>; with function "+" (C : Cursor_Type; I : Index_Type'Base) return Cursor_Type is <>; with function "-" (L, R : Cursor_Type) return Index_Type'Base is <>; procedure Generic_Sort (First, Back : Cursor_Type); pragma Pure (Generic_Sort); procedure Generic_Sort (First, Back : Cursor_Type) is begin null; end Generic_Sort; with Ada.Containers.Vectors; use Ada.Containers; generic with package Vector_Types is new Vectors (<>); use Vector_Types; V : access constant Vector; package Vector_Cursor_Operations is pragma Preelaborate; function "+" (L : Cursor; R : Index_Type'Base) return Cursor; function "-" (L, R : Cursor) return Index_Type'Base; end Vector_Cursor_Operations; package body Vector_Cursor_Operations is function "+" (L : Cursor; R : Index_Type'Base) return Cursor is I : Index_Type'Base; begin if Has_Element (L) then I := To_Index (L); else I := V.Last_Index + 1; end if; I := I + R; return To_Cursor (V.all, I); end "+"; function "-" (L, R : Cursor) return Index_Type'Base is I, J : Index_Type'Base; begin if Has_Element (L) then I := To_Index (L); else I := V.Last_Index + 1; end if; if Has_Element (R) then J := To_Index (R); else J := V.Last_Index + 1; end if; return I - J; end "-"; end Vector_Cursor_Operations;