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,FREEMAIL_FROM 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 Path: g2news1.google.com!news1.google.com!news.glorb.com!nntp.idg.pl!newsfeed.gazeta.pl!news.internetia.pl!newsfeed.tpinternet.pl!atlantis.news.tpi.pl!news.tpi.pl!not-for-mail From: "Robert Kawulak" Newsgroups: comp.lang.ada Subject: Re: Ada Popularity: Comparison of Ada/Charles with C++ STL (and Perl) Date: Thu, 30 Sep 2004 20:27:22 +0200 Organization: tp.internet - http://www.tpi.pl/ Message-ID: References: <41547dae$0$91007$39cecf19@news.twtelecom.net> <1g2d9xmnita9f.5ecju0eftkqw$.dlg@40tude.net> <87u4rkhddelw$.1uuoqhfyd2eay$.dlg@40tude.net> <415ad5be$0$74190$39cecf19@news.twtelecom.net> NNTP-Posting-Host: pe143.krakow.cvx.ppp.tpnet.pl X-Trace: nemesis.news.tpi.pl 1096570691 23603 213.76.40.143 (30 Sep 2004 18:58:11 GMT) X-Complaints-To: usenet@tpi.pl NNTP-Posting-Date: Thu, 30 Sep 2004 18:58:11 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.2180 X-MIMEOLE: Produced By Microsoft MimeOLE V6.00.2900.2180 X-RFC2646: Format=Flowed; Original Xref: g2news1.google.com comp.lang.ada:4453 Date: 2004-09-30T20:27:22+02:00 List-Id: Hi, >> I don't know about Ada, but in C++ you can, and such "templates > nesting" [...] > Of course, you can pass the type made available via an instantiation of a > generic package as the actual type of some other instantiation. The > container libraray for Ada 2005 (see AI-302) was specially designed to > allow a container as the element of another container. Thanks for clarification. So returning to what Dmitry has written: Dmitry > For instance, it is impossible to have generic programming Dmitry > on containers of containers. You cannot have a list of items of Dmitry > "array" types that are different instantiations. Because see above, Dmitry > you have no that common abstract predecessor. That "arrays" are not Dmitry > arrays, we are just fooling ourselves. I think I see now what Dmitry was trying to say: you cannot have a list of "arrays" such that one its element will be of type std::vector, the other of std::valarray and so on. Do I understand you well, Dmitry? If yes, then I admit: it can't be done directly. But it *doesn't* mean it's impossible! Have a look at this: /*************************************************/ #include using std::size_t; #include using std::list; #include using std::vector; #include using std::map; // STEP 1: // Helper template for getting element // and index type of an array type. ArrayTraits // is meant to be specialised for any concrete // array type. template struct ArrayTraits { typedef ArrayT ArrayType; }; // struct ArrayTraits<> // Specialisation for std::vector<> template struct ArrayTraits< vector > { typedef typename vector ArrayType; typedef typename ArrayType::value_type ElementType; typedef typename ArrayType::size_type IndexType; }; // struct ArrayTraits< vector > // Specialisation for std::map<> template struct ArrayTraits< map > { typedef typename map ArrayType; typedef typename ArrayType::mapped_type ElementType; typedef typename ArrayType::key_type IndexType; }; // struct ArrayTraits< map > // Specialisation for C-style arrays template struct ArrayTraits { typedef ElementT ArrayType[]; typedef ElementT ElementType; typedef size_t IndexType; }; // struct ArrayTraits // STEP 2: // Abstract base class for the wrapper of any // array type (here we assume that array type // is any type having [] operator) template struct ArrayWrapperBase { virtual ElementType & operator [] (const IndexType & ) = 0; // ...Possibly some other array-specific operations... virtual ~ArrayWrapperBase() {} }; // struct ArrayWrapperBase<> // STEP 3: // The wrapper class template template struct ArrayWrapper: public ArrayWrapperBase< typename ArrayTraits::ElementType, typename ArrayTraits::IndexType > { typedef typename ArrayTraits::ElementType ElementType; typedef typename ArrayTraits::IndexType IndexType; ArrayType & mArray; // reference to actual array object ArrayWrapper(ArrayType & A): mArray(A) {} ElementType & operator [] (const IndexType & i) { return mArray[i]; }; }; // struct ArrayWrapper<> // STEP 4: // Use! int main() { vector AVector(10); ArrayWrapper< vector > WrappedVector(AVector); map AMap; ArrayWrapper< map > WrappedMap(AMap); int AnArray[10]; ArrayWrapper< int[] > WrappedArray(AnArray); typedef list *> ListOfArrays; ListOfArrays MyList; // list of arrays of any kind holding ints // creme de la creme: MyList.push_back(&WrappedVector); MyList.push_back(&WrappedMap); MyList.push_back(&WrappedArray); // the three instructions are equivalent: AVector[7] = 27182; WrappedVector[7] = 27182; (*MyList.front())[7] = 27182; // setting 5-th element of every array to 31415: for(ListOfArrays::iterator i = MyList.begin(); i != MyList.end(); i++) (**i)[4] = 31415; } // main() /*************************************************/ Long and complicated? Indeed. But on the other hand I have never heard of anybody who needed this. Yet it's possible ;-). Best regards, Robert Kawulak