home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / comp / std / cplus / 1913 < prev    next >
Encoding:
Text File  |  1992-12-24  |  5.5 KB  |  241 lines

  1. Newsgroups: comp.std.c++
  2. Path: sparky!uunet!mcsun!julienas!jussieu!shiva.jussieu.fr!kriss
  3. From: kriss@roll.ibp.fr (Christophe GROSJEAN)
  4. Subject: Re: C++ already *has* nested functions SO WHAT'S THE BEEF?
  5. In-Reply-To: maxtal@extro.ucc.su.OZ.AU's message of Wed, 23 Dec 1992 16:57:19 GMT
  6. Message-ID: <KRISS.92Dec24123825@roll.ibp.fr>
  7. Sender: news@jussieu.fr (Le Facteur)
  8. Nntp-Posting-Host: roll.ibp.fr
  9. Reply-To: grosjean@masi.ibp.fr
  10. Organization: Laboratoire MASI, Paris, France.
  11. References: <1992Dec21.080952.15309@netcom.com> <1992Dec23.165719.13021@ucc.su.OZ.AU>
  12. Date: Thu, 24 Dec 1992 11:38:25 GMT
  13. Lines: 226
  14.  
  15. The following code shows another way of simulating nested functions.
  16. That's what I use right now, waiting for the removing of this restriction.
  17.  
  18. I've read that GNU support nested functions, the compiler I use right know
  19. (G++ 2.3.2) does not seem to do it. Which version does it ?
  20.  
  21. Sample (should say simple) code follow-up, with context. Use of templates is not
  22. relevant to the nested function problem.
  23.  
  24. The syntax could be *much* simplified using macros. But stantard macro preprocessors
  25. are not powerful enough.
  26.  
  27. First, anybody thought of removing the comma-as-separator restriction
  28. in the preprocessor in order you can choose the right one ?
  29. I had much trouble with that using macros with multi-arguments templated classes. 'cause of that.
  30.  
  31. Second, overloading should be extended to macros in C++, seems homogeneous, and
  32. usefull.
  33.  
  34. Third, in my case, what I would need is context vars, stacking vars in a first macro then
  35. using them in a second one, kind of parenthesing macros.
  36.  
  37. --------- code follows -------------
  38.  
  39. #include <iostream.h>
  40. #define TRUE 1
  41. #define FALSE 0
  42.  
  43. template<class R, class T>
  44. class Func1
  45. {
  46.     public:
  47.     virtual R call(T o1) = 0;
  48. };
  49.  
  50. void * ONULL = NULL;
  51.  
  52. template<class DATA>
  53. class List
  54. {
  55.     public:
  56.     List(void) {init();}
  57.     List(DATA o1){ init(); add(o1);}
  58.     List(DATA o1, DATA o2){init(); add(o1); add(o2);}
  59.     List(DATA o1, DATA o2, DATA o3){
  60.         init(); add(o1); add(o2); add(o3);}
  61.     List(DATA o1, DATA o2, DATA o3, DATA o4){
  62.         init(); add(o1); add(o2); add(o3); add(o4);}
  63.     void add(DATA o1){
  64.         Link * tmp = new Link;
  65.         tmp->next = head;
  66.         tmp->data = o1;
  67.         head = tmp;
  68.     }
  69.     void addAll(List<DATA> & c1) {
  70.         class p : public Func1<void,DATA> {
  71.             public:
  72.             p(List<DATA> & c) : c(c) {}
  73.             void call(DATA i) {c.add(i);}
  74.             List<DATA> & c;
  75.         } p(*this);
  76.         c1.all(p);
  77.     }
  78.     void all(Func1<void,DATA> & p){
  79.         Link * tmp;
  80.         for(tmp=head;tmp != NULL;tmp=tmp->next)
  81.             p.call(tmp->data);
  82.     }
  83.     DATA & any(Func1<int,DATA> & t){
  84.         Link * tmp;
  85.         for(tmp=head;tmp != NULL;tmp=tmp->next)
  86.             if (t.call(tmp->data))
  87.                 return tmp->data;
  88.         error = 1;
  89.         return (DATA &)ONULL;
  90.     }
  91.     void unlink_any(Func1<int, DATA> & t){
  92.         if (head == NULL){error = 1;return;}
  93.         else{
  94.             Link * tmp = head;
  95.             if (t.call(tmp->data)){
  96.                 head = tmp->next;
  97.                 delete tmp;
  98.                 return;
  99.             }
  100.             else {
  101.                 Link * tmp2;
  102.                 for (tmp2 = tmp->next; tmp2 != NULL;tmp2=(tmp=tmp2)->next)
  103.                     if (t.call(tmp2->data)){
  104.                         tmp->next = tmp2->next;
  105.                         delete tmp2;
  106.                         return;
  107.                     }
  108.             }
  109.         }
  110.         error = 1;
  111.         return;
  112.     }
  113.     void unlink_all(Func1<int, DATA> & t){
  114.         Link * tmp;
  115.         Link * tmp2;
  116.         tmp = head;
  117.         head = NULL;
  118.         while(tmp != NULL){
  119.             tmp2 = tmp;
  120.             tmp = tmp->next;
  121.             if (t.call(tmp2->data))
  122.             {
  123.                 delete tmp2;
  124.             }
  125.         {
  126.             tmp2->next = head;
  127.             head = tmp2;
  128.         }
  129.         }
  130.         reverse();
  131.     }
  132.  
  133.     int includes(Func1<int, DATA> & t){
  134.         Link * tmp;
  135.         for(tmp=head;tmp != NULL;tmp=tmp->next)
  136.             if (t.call(tmp->data))
  137.                 return TRUE;
  138.         return FALSE;
  139.     }
  140.  
  141.     int occurencesOf(Func1<int, DATA> & t)
  142.     {
  143.         int nb = 0;
  144.         for(Link * tmp=head;tmp != NULL;tmp=tmp->next)
  145.             if( t.call(tmp->data)) nb++;
  146.         return nb;
  147.     }
  148.     
  149.  private:
  150.     void init(void) { head = (Link *)NULL;}
  151.     void reverse(){
  152.         Link * tmp;
  153.         Link * tmp2;
  154.         tmp = head;
  155.         head = NULL;
  156.         while(tmp != NULL){
  157.             tmp2 = tmp->next;
  158.             tmp->next = head;
  159.             head = tmp;
  160.             tmp = tmp2;
  161.         }
  162.     }
  163.     struct Link
  164.     {
  165.         Link * next;
  166.         DATA data;
  167.     } * head;
  168.     int error;
  169.  };
  170.  
  171. int main()
  172. {
  173.     class pint : public Func1<void,int>
  174.     {
  175.         public:
  176.         pint(void) {}
  177.         void call(int d) { cout << d << " "; }
  178.     } pint;
  179.     class pchar : public Func1<void,char>
  180.     {
  181.         public:
  182.         pchar(void) {}
  183.         void call(char d) { cout << d << " "; }
  184.     } pchar;
  185.  
  186.     
  187.     class t1 : public Func1<int,int>
  188.     {
  189.         public:
  190.         t1(void) {}
  191.         int call(int d) {return (d>=200);}
  192.     } t1;
  193.     
  194.     int toto = 120;
  195.     
  196. // Function reading context variable toto (value a this point)
  197.     class t2 : public Func1<int,int>
  198.     {
  199.         public:
  200.         t2(int toto) : toto(toto) {}
  201.         int call(int d) {return (d > toto);}
  202.         int toto;
  203.     } t2(toto);
  204.     
  205.     // Function using context variable toto (whatever value)
  206.     class t3 : public Func1<int,int>
  207.     {
  208.         public:
  209.         t3(int & toto) : toto(toto) {}
  210.         int call(int d) {return (d <= toto);}
  211.         int & toto;
  212.     } t3(toto);
  213.     
  214.     // Function modifying context variable max
  215.     int max;
  216.     class getmax : public Func1<void, int>
  217.     {
  218.         public:
  219.         getmax(int & max) : max(max) {}
  220.         void call(int d) { max = (max > d)?max:d; }
  221.         int & max;
  222.     } getmax(max);
  223.     
  224.     List<char> L3('A','B','C');
  225.     List<int> L1(100,120,130), L2(200);
  226.     L1.add(110); L2.add(210);
  227.     L1.addAll(L2); L1.add(140); L1.add(150); L1.add(160);
  228.     cout << "List L1 : "; L1.all(pint); cout << "\n";
  229.     cout << "List L2 : "; L2.all(pint); cout << "\n";
  230.     cout << "List L3 : "; L3.all(pchar); cout << "\n";
  231.     toto = 140;
  232.     cout << "First elt of L1 veryfying elt >= 200 : " << L1.any(t1) << "\n";
  233.     cout << "First elt of L1 veryfying elt > toto (120) : " << L1.any(t2) << "\n";
  234.     cout << "First elt of L1 veryfying elt <= toto (now=140) : " << L1.any(t3) << "\n";
  235.     L1.all(getmax);
  236.     cout << "Max elt of L1 : " << max << "\n";
  237.     
  238.     return 0;
  239. }
  240. -------- end of code --------
  241.