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,243dc2fb696a49cd X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit From: Brian May Newsgroups: comp.lang.ada Subject: Re: Ada Popularity: Comparison of Ada/Charles with C++ STL (and Perl) References: <1636756.M7hCqjsVMv@linux1.krischik.com> <415c36c0$0$91010$39cecf19@news.twtelecom.net> <4c2ec8a8.0410012335.dcf9001@posting.google.com> Date: Sun, 03 Oct 2004 12:17:54 +1000 Message-ID: User-Agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux) Cancel-Lock: sha1:T0j9B+FjZM01pVJ1hqUJTbZDUIw= MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii NNTP-Posting-Host: dsl-202-173-153-89.vic.westnet.com.au X-Trace: news.melbourne.pipenetworks.com 1096769863 202.173.153.89 (3 Oct 2004 12:17:43 +1000) X-Complaints-To: abuse@pipenetworks.com X-Abuse-Info: Please forward all headers to enable your complaint to be properly processed. Path: g2news1.google.com!news1.google.com!news.glorb.com!newsfeed-east.nntpserver.com!nntpserver.com!news1.optus.net.au!optus!news.mel.connect.com.au!news-north.connect.com.au!news-south.connect.com.au!news.alphalink.com.au!news.melbourne.pipenetworks.com!not-for-mail Xref: g2news1.google.com comp.lang.ada:4589 Date: 2004-10-03T12:17:54+10:00 List-Id: >>>>> "Kevin" == Kevin Cline writes: Kevin> template Kevin> class DatabaseMap Kevin> { Kevin> vector entries; Kevin> ... Kevin> template Kevin> DatabaseMap& insert(Column c, MemberType Kevin> RecordType::*member_pointer) Kevin> { Kevin> entries.push_back(new ColumnMemberMap Kevin> (c, member_pointer)); Kevin> return this; Kevin> } Kevin> } Ok. So thinking out aloud, if I got this correct, your example of: dbmap order_map; order_map.insert("ORDER.NUMBER", &Order::number) .insert("ORDER.CUSTOMER", &Order::customer_number) .insert("ORDER.ACCEPTED", &Order::acceptance_date) .insert("ORDER.PROMISED", &Order::promised_ship_date) ... Would be equivalent to: vector entries; entries[0] := new ColumnMemberMap("ORDER.NUMBER",i &Order::number) entries[1] := new ColumnMemberMap("ORDER.CUSTOMER",i &Order::customer_number); entries[2] := new ColumnMemberMap("ORDER.ACCEPT",i &Order::acceptance_date); entries[3] := new ColumnMemberMap("ORDER.PROMISED",i &Order::promised_ship_date); vector entries; What is the relationship between ColumnMemberMap and ColumnMap? I might assume: typedef ColumnType *ColumnMap; /* ColumnMap points to ColumnType */ class ColumnType { }; template class ColumnMemberMap : XYZ { ColumnMemberMap(Column c, MemberType RecordType::*member_pointer) { ... } }; If so, I think this could be done in Ada (yes, this is messy, it has gone through several revisions, it could be tidied up): declare -- holds the data type Column_Type is tagged private; type Column_Access is access all Column_Type'Class; generic type Member_Type is private; package Members type Column_Type is new Column_Type with private; procedure Set(Column : Column_Type, Member : Member_Type); function Get(Column : Column_Type) return Member_Type; private ... end Members; ... -- function to retrieve the data package Integer_Members is new Members(MyInteger); package Date_Members is new Members(MyDate); -- returns new Integer_Members.Column_Type if Integer -- returns new Date_Members.Column_Type if Date -- etc function Get(dbreader : dbreader_type; C : Unbounded_String) return Column_Access; ... type Index_Type is (Number, Customer_Number, Acceptance_Date, Promised_Ship_Date, ...); type Order_Map_Type is array (Index_Type) of Unbounded_String; type Order_Type is array (Index_Type) of Column_Access; Order_Map : Order_Map_Type; Order : Order; begin Order_Map := ( Number => +"ORDER.NUMBER", Customer_Number => +"ORDER.CUSTOMER", Acceptance_Date => +"ORDER.ACCEPTANCE", Promised_Ship_Date => +"ORDER.PROMISED", ... ); for I in Order_Map'Range loop declare C : constant Unbounded_String := Order_Map(I); D : constant Column_Access := Get(dbreader,C); begin Order(I) := D; end; end loop; end; In a real application, I would split this out into other functions, like you have. Presumably "Get" would already be defined and the one function would get an access type to any type. This might not be what you anticipated, but my imagination is running out right now. The only disadvantage I can immediately see is that setting/retrieving values would require some sort of (perhaps ugly) cast, also meaning run-time type checks would be used, not compile-time type checks (unless you have a per field conversion function, which would increase complexity). Disclaimer: NOT TESTED!!! Hopefully this makes some sort of sense, other then proving me insane ;-) -- Brian May