home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.std.c++
- Path: sparky!uunet!mcsun!julienas!jussieu!shiva.jussieu.fr!kriss
- From: kriss@roll.ibp.fr (Christophe GROSJEAN)
- Subject: Re: C++ already *has* nested functions SO WHAT'S THE BEEF?
- In-Reply-To: maxtal@extro.ucc.su.OZ.AU's message of Wed, 23 Dec 1992 16:57:19 GMT
- Message-ID: <KRISS.92Dec24123825@roll.ibp.fr>
- Sender: news@jussieu.fr (Le Facteur)
- Nntp-Posting-Host: roll.ibp.fr
- Reply-To: grosjean@masi.ibp.fr
- Organization: Laboratoire MASI, Paris, France.
- References: <1992Dec21.080952.15309@netcom.com> <1992Dec23.165719.13021@ucc.su.OZ.AU>
- Date: Thu, 24 Dec 1992 11:38:25 GMT
- Lines: 226
-
- The following code shows another way of simulating nested functions.
- That's what I use right now, waiting for the removing of this restriction.
-
- I've read that GNU support nested functions, the compiler I use right know
- (G++ 2.3.2) does not seem to do it. Which version does it ?
-
- Sample (should say simple) code follow-up, with context. Use of templates is not
- relevant to the nested function problem.
-
- The syntax could be *much* simplified using macros. But stantard macro preprocessors
- are not powerful enough.
-
- First, anybody thought of removing the comma-as-separator restriction
- in the preprocessor in order you can choose the right one ?
- I had much trouble with that using macros with multi-arguments templated classes. 'cause of that.
-
- Second, overloading should be extended to macros in C++, seems homogeneous, and
- usefull.
-
- Third, in my case, what I would need is context vars, stacking vars in a first macro then
- using them in a second one, kind of parenthesing macros.
-
- --------- code follows -------------
-
- #include <iostream.h>
- #define TRUE 1
- #define FALSE 0
-
- template<class R, class T>
- class Func1
- {
- public:
- virtual R call(T o1) = 0;
- };
-
- void * ONULL = NULL;
-
- template<class DATA>
- class List
- {
- public:
- List(void) {init();}
- List(DATA o1){ init(); add(o1);}
- List(DATA o1, DATA o2){init(); add(o1); add(o2);}
- List(DATA o1, DATA o2, DATA o3){
- init(); add(o1); add(o2); add(o3);}
- List(DATA o1, DATA o2, DATA o3, DATA o4){
- init(); add(o1); add(o2); add(o3); add(o4);}
- void add(DATA o1){
- Link * tmp = new Link;
- tmp->next = head;
- tmp->data = o1;
- head = tmp;
- }
- void addAll(List<DATA> & c1) {
- class p : public Func1<void,DATA> {
- public:
- p(List<DATA> & c) : c(c) {}
- void call(DATA i) {c.add(i);}
- List<DATA> & c;
- } p(*this);
- c1.all(p);
- }
- void all(Func1<void,DATA> & p){
- Link * tmp;
- for(tmp=head;tmp != NULL;tmp=tmp->next)
- p.call(tmp->data);
- }
- DATA & any(Func1<int,DATA> & t){
- Link * tmp;
- for(tmp=head;tmp != NULL;tmp=tmp->next)
- if (t.call(tmp->data))
- return tmp->data;
- error = 1;
- return (DATA &)ONULL;
- }
- void unlink_any(Func1<int, DATA> & t){
- if (head == NULL){error = 1;return;}
- else{
- Link * tmp = head;
- if (t.call(tmp->data)){
- head = tmp->next;
- delete tmp;
- return;
- }
- else {
- Link * tmp2;
- for (tmp2 = tmp->next; tmp2 != NULL;tmp2=(tmp=tmp2)->next)
- if (t.call(tmp2->data)){
- tmp->next = tmp2->next;
- delete tmp2;
- return;
- }
- }
- }
- error = 1;
- return;
- }
- void unlink_all(Func1<int, DATA> & t){
- Link * tmp;
- Link * tmp2;
- tmp = head;
- head = NULL;
- while(tmp != NULL){
- tmp2 = tmp;
- tmp = tmp->next;
- if (t.call(tmp2->data))
- {
- delete tmp2;
- }
- {
- tmp2->next = head;
- head = tmp2;
- }
- }
- reverse();
- }
-
- int includes(Func1<int, DATA> & t){
- Link * tmp;
- for(tmp=head;tmp != NULL;tmp=tmp->next)
- if (t.call(tmp->data))
- return TRUE;
- return FALSE;
- }
-
- int occurencesOf(Func1<int, DATA> & t)
- {
- int nb = 0;
- for(Link * tmp=head;tmp != NULL;tmp=tmp->next)
- if( t.call(tmp->data)) nb++;
- return nb;
- }
-
- private:
- void init(void) { head = (Link *)NULL;}
- void reverse(){
- Link * tmp;
- Link * tmp2;
- tmp = head;
- head = NULL;
- while(tmp != NULL){
- tmp2 = tmp->next;
- tmp->next = head;
- head = tmp;
- tmp = tmp2;
- }
- }
- struct Link
- {
- Link * next;
- DATA data;
- } * head;
- int error;
- };
-
- int main()
- {
- class pint : public Func1<void,int>
- {
- public:
- pint(void) {}
- void call(int d) { cout << d << " "; }
- } pint;
- class pchar : public Func1<void,char>
- {
- public:
- pchar(void) {}
- void call(char d) { cout << d << " "; }
- } pchar;
-
-
- class t1 : public Func1<int,int>
- {
- public:
- t1(void) {}
- int call(int d) {return (d>=200);}
- } t1;
-
- int toto = 120;
-
- // Function reading context variable toto (value a this point)
- class t2 : public Func1<int,int>
- {
- public:
- t2(int toto) : toto(toto) {}
- int call(int d) {return (d > toto);}
- int toto;
- } t2(toto);
-
- // Function using context variable toto (whatever value)
- class t3 : public Func1<int,int>
- {
- public:
- t3(int & toto) : toto(toto) {}
- int call(int d) {return (d <= toto);}
- int & toto;
- } t3(toto);
-
- // Function modifying context variable max
- int max;
- class getmax : public Func1<void, int>
- {
- public:
- getmax(int & max) : max(max) {}
- void call(int d) { max = (max > d)?max:d; }
- int & max;
- } getmax(max);
-
- List<char> L3('A','B','C');
- List<int> L1(100,120,130), L2(200);
- L1.add(110); L2.add(210);
- L1.addAll(L2); L1.add(140); L1.add(150); L1.add(160);
- cout << "List L1 : "; L1.all(pint); cout << "\n";
- cout << "List L2 : "; L2.all(pint); cout << "\n";
- cout << "List L3 : "; L3.all(pchar); cout << "\n";
- toto = 140;
- cout << "First elt of L1 veryfying elt >= 200 : " << L1.any(t1) << "\n";
- cout << "First elt of L1 veryfying elt > toto (120) : " << L1.any(t2) << "\n";
- cout << "First elt of L1 veryfying elt <= toto (now=140) : " << L1.any(t3) << "\n";
- L1.all(getmax);
- cout << "Max elt of L1 : " << max << "\n";
-
- return 0;
- }
- -------- end of code --------
-